kopia lustrzana https://github.com/ryukoposting/Signal-Android
use Locale from DynamicLanguage for displaying dates
1) fixed DateUtils to use SimpleDateFormat for everything because it respects Locale 2) added getCurrentLocale() method to DynamicLanguage 3) allow PassphraseRequiredActionBarActivity.initFragment() to accept a Locale 4) updated classes that depend on DateUtils to pass down Locale from DynamicLanguage Fixes #2684 Closes #2725 // FREEBIEfork-5.53.8
rodzic
424a463b21
commit
d8521637bb
|
@ -173,7 +173,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
setContentView(R.layout.conversation_activity);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
fragment = initFragment(R.id.fragment_content, new ConversationFragment(), masterSecret);
|
||||
fragment = initFragment(R.id.fragment_content, new ConversationFragment(), masterSecret, dynamicLanguage.getCurrentLocale());
|
||||
|
||||
initializeReceivers();
|
||||
initializeViews();
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.thoughtcrime.securesms;
|
|||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -36,6 +35,7 @@ import org.thoughtcrime.securesms.util.LRUCache;
|
|||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -64,16 +64,19 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
|||
private final SelectionClickListener selectionClickListener;
|
||||
private final Context context;
|
||||
private final MasterSecret masterSecret;
|
||||
private final Locale locale;
|
||||
private final boolean groupThread;
|
||||
private final boolean pushDestination;
|
||||
private final LayoutInflater inflater;
|
||||
|
||||
public ConversationAdapter(Context context, MasterSecret masterSecret, SelectionClickListener selectionClickListener,
|
||||
boolean groupThread, boolean pushDestination)
|
||||
public ConversationAdapter(Context context, MasterSecret masterSecret, Locale locale,
|
||||
SelectionClickListener selectionClickListener, boolean groupThread,
|
||||
boolean pushDestination)
|
||||
{
|
||||
super(context, null, 0);
|
||||
this.context = context;
|
||||
this.masterSecret = masterSecret;
|
||||
this.locale = locale;
|
||||
this.selectionClickListener = selectionClickListener;
|
||||
this.groupThread = groupThread;
|
||||
this.pushDestination = pushDestination;
|
||||
|
@ -87,7 +90,7 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
|
|||
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
|
||||
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
|
||||
|
||||
item.set(masterSecret, messageRecord, batchSelected, selectionClickListener,
|
||||
item.set(masterSecret, messageRecord, locale, batchSelected, selectionClickListener,
|
||||
groupThread, pushDestination);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.thoughtcrime.securesms.util.SaveAttachmentTask.Attachment;
|
|||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ConversationFragment extends ListFragment
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>
|
||||
|
@ -60,11 +61,13 @@ public class ConversationFragment extends ListFragment
|
|||
private Recipients recipients;
|
||||
private long threadId;
|
||||
private ActionMode actionMode;
|
||||
private Locale locale;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
this.masterSecret = getArguments().getParcelable("master_secret");
|
||||
this.locale = (Locale) getArguments().getSerializable(PassphraseRequiredActionBarActivity.LOCALE_EXTRA);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -116,7 +119,7 @@ public class ConversationFragment extends ListFragment
|
|||
|
||||
private void initializeListAdapter() {
|
||||
if (this.recipients != null && this.threadId != -1) {
|
||||
this.setListAdapter(new ConversationAdapter(getActivity(), masterSecret, selectionClickListener,
|
||||
this.setListAdapter(new ConversationAdapter(getActivity(), masterSecret, locale, selectionClickListener,
|
||||
(!this.recipients.isSingleRecipient()) || this.recipients.isGroupRecipient(),
|
||||
DirectoryHelper.isPushDestination(getActivity(), this.recipients)));
|
||||
getListView().setRecyclerListener((ConversationAdapter)getListAdapter());
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.Emoji;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -73,6 +74,7 @@ public class ConversationItem extends LinearLayout {
|
|||
|
||||
private MessageRecord messageRecord;
|
||||
private MasterSecret masterSecret;
|
||||
private Locale locale;
|
||||
private boolean groupThread;
|
||||
private boolean pushDestination;
|
||||
|
||||
|
@ -138,12 +140,14 @@ public class ConversationItem extends LinearLayout {
|
|||
|
||||
public void set(@NonNull MasterSecret masterSecret,
|
||||
@NonNull MessageRecord messageRecord,
|
||||
@NonNull Locale locale,
|
||||
@NonNull Set<MessageRecord> batchSelected,
|
||||
@NonNull SelectionClickListener selectionClickListener,
|
||||
boolean groupThread, boolean pushDestination)
|
||||
{
|
||||
this.masterSecret = masterSecret;
|
||||
this.messageRecord = messageRecord;
|
||||
this.locale = locale;
|
||||
this.batchSelected = batchSelected;
|
||||
this.selectionClickListener = selectionClickListener;
|
||||
this.groupThread = groupThread;
|
||||
|
@ -287,7 +291,7 @@ public class ConversationItem extends LinearLayout {
|
|||
if (messageRecord.isPush()) timestamp = messageRecord.getDateSent();
|
||||
else timestamp = messageRecord.getDateReceived();
|
||||
|
||||
dateText.setText(DateUtils.getExtendedRelativeTimeSpanString(getContext(), timestamp));
|
||||
dateText.setText(DateUtils.getExtendedRelativeTimeSpanString(getContext(), locale, timestamp));
|
||||
}
|
||||
|
||||
private void setFailedStatusIcons() {
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.thoughtcrime.securesms.util.DynamicLanguage;
|
|||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
||||
public class ConversationListActivity extends PassphraseRequiredActionBarActivity
|
||||
implements ConversationListFragment.ConversationSelectedListener
|
||||
{
|
||||
|
@ -67,7 +66,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
|||
|
||||
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
|
||||
getSupportActionBar().setTitle(R.string.app_name);
|
||||
fragment = initFragment(android.R.id.content, new ConversationListFragment(), masterSecret);
|
||||
fragment = initFragment(android.R.id.content, new ConversationListFragment(), masterSecret, dynamicLanguage.getCurrentLocale());
|
||||
|
||||
initializeContactUpdatesReceiver();
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -47,6 +48,7 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
|||
|
||||
private final ThreadDatabase threadDatabase;
|
||||
private final MasterCipher masterCipher;
|
||||
private final Locale locale;
|
||||
private final Context context;
|
||||
private final LayoutInflater inflater;
|
||||
private final ItemClickListener clickListener;
|
||||
|
@ -80,12 +82,14 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
|||
|
||||
public ConversationListAdapter(@NonNull Context context,
|
||||
@NonNull MasterSecret masterSecret,
|
||||
@NonNull Locale locale,
|
||||
@Nullable Cursor cursor,
|
||||
@Nullable ItemClickListener clickListener) {
|
||||
super(context, cursor);
|
||||
this.masterCipher = new MasterCipher(masterSecret);
|
||||
this.context = context;
|
||||
this.threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
this.locale = locale;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.clickListener = clickListener;
|
||||
}
|
||||
|
@ -101,7 +105,7 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
|||
ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor, masterCipher);
|
||||
ThreadRecord record = reader.getCurrent();
|
||||
|
||||
viewHolder.getItem().set(record, batchSet, batchMode);
|
||||
viewHolder.getItem().set(record, locale, batchSet, batchMode);
|
||||
}
|
||||
|
||||
public void toggleThreadInBatchSet(long threadId) {
|
||||
|
|
|
@ -56,24 +56,26 @@ import org.thoughtcrime.securesms.database.loaders.ConversationListLoader;
|
|||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class ConversationListFragment extends Fragment
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>, ActionMode.Callback, ItemClickListener
|
||||
{
|
||||
|
||||
private MasterSecret masterSecret;
|
||||
private ActionMode actionMode;
|
||||
private RecyclerView list;
|
||||
private ReminderView reminderView;
|
||||
private FloatingActionButton fab;
|
||||
private Locale locale;
|
||||
private String queryFilter = "";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
masterSecret = getArguments().getParcelable("master_secret");
|
||||
locale = (Locale) getArguments().getSerializable(PassphraseRequiredActionBarActivity.LOCALE_EXTRA);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -140,7 +142,7 @@ public class ConversationListFragment extends Fragment
|
|||
}
|
||||
|
||||
private void initializeListAdapter() {
|
||||
list.setAdapter(new ConversationListAdapter(getActivity(), masterSecret, null, this));
|
||||
list.setAdapter(new ConversationListAdapter(getActivity(), masterSecret, locale, null, this));
|
||||
list.setRecyclerListener(new RecyclerListener() {
|
||||
@Override
|
||||
public void onViewRecycled(ViewHolder holder) {
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.util.DateUtils;
|
|||
import org.thoughtcrime.securesms.util.Emoji;
|
||||
import org.thoughtcrime.securesms.util.RecipientViewUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.thoughtcrime.securesms.util.SpanUtil.color;
|
||||
|
@ -86,7 +87,7 @@ public class ConversationListItem extends RelativeLayout
|
|||
initializeContactWidgetVisibility();
|
||||
}
|
||||
|
||||
public void set(ThreadRecord thread, Set<Long> selectedThreads, boolean batchMode) {
|
||||
public void set(ThreadRecord thread, Locale locale, Set<Long> selectedThreads, boolean batchMode) {
|
||||
this.selectedThreads = selectedThreads;
|
||||
this.recipients = thread.getRecipients();
|
||||
this.threadId = thread.getThreadId();
|
||||
|
@ -103,7 +104,7 @@ public class ConversationListItem extends RelativeLayout
|
|||
this.subjectView.setTypeface(read ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
|
||||
|
||||
if (thread.getDate() > 0) {
|
||||
CharSequence date = DateUtils.getBriefRelativeTimeSpanString(context, thread.getDate());
|
||||
CharSequence date = DateUtils.getBriefRelativeTimeSpanString(context, locale, thread.getDate());
|
||||
dateView.setText(read ? date : color(getResources().getColor(R.color.textsecure_primary), date));
|
||||
dateView.setTypeface(read ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import java.sql.Date;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author Jake McGinty
|
||||
|
@ -147,7 +148,8 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
|
|||
sentDate.setText("-");
|
||||
receivedContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
SimpleDateFormat dateFormatter = DateUtils.getDetailedDateFormatter(this);
|
||||
Locale dateLocale = dynamicLanguage.getCurrentLocale();
|
||||
SimpleDateFormat dateFormatter = DateUtils.getDetailedDateFormatter(this, dateLocale);
|
||||
sentDate.setText(dateFormatter.format(new Date(messageRecord.getDateSent())));
|
||||
|
||||
if (messageRecord.getDateReceived() != messageRecord.getDateSent() && !messageRecord.isOutgoing()) {
|
||||
|
@ -169,7 +171,8 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
|
|||
toFromRes = R.string.message_details_header__from;
|
||||
}
|
||||
toFrom.setText(toFromRes);
|
||||
conversationItem.set(masterSecret, messageRecord, new HashSet<MessageRecord>(), new NullSelectionListener(),
|
||||
conversationItem.set(masterSecret, messageRecord, dynamicLanguage.getCurrentLocale(),
|
||||
new HashSet<MessageRecord>(), new NullSelectionListener(),
|
||||
recipients != messageRecord.getRecipients(),
|
||||
DirectoryHelper.isPushDestination(this, recipients));
|
||||
recipientsList.setAdapter(new MessageDetailsRecipientAdapter(this, masterSecret, messageRecord,
|
||||
|
|
|
@ -19,9 +19,13 @@ import org.thoughtcrime.securesms.service.KeyCachingService;
|
|||
import org.thoughtcrime.securesms.service.MessageRetrievalService;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarActivity implements MasterSecretListener {
|
||||
private static final String TAG = PassphraseRequiredActionBarActivity.class.getSimpleName();
|
||||
|
||||
public static final String LOCALE_EXTRA = "locale_extra";
|
||||
|
||||
private static final int STATE_NORMAL = 0;
|
||||
private static final int STATE_CREATE_PASSPHRASE = 1;
|
||||
private static final int STATE_PROMPT_PASSPHRASE = 2;
|
||||
|
@ -78,9 +82,12 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
|
|||
|
||||
protected <T extends Fragment> T initFragment(@IdRes int target,
|
||||
@NonNull T fragment,
|
||||
@NonNull MasterSecret masterSecret) {
|
||||
@NonNull MasterSecret masterSecret,
|
||||
@Nullable Locale locale) {
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable("master_secret", masterSecret);
|
||||
args.putSerializable(LOCALE_EXTRA, locale);
|
||||
|
||||
fragment.setArguments(args);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(target, fragment)
|
||||
|
@ -88,6 +95,12 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
|
|||
return fragment;
|
||||
}
|
||||
|
||||
protected <T extends Fragment> T initFragment(@IdRes int target,
|
||||
@NonNull T fragment,
|
||||
@NonNull MasterSecret masterSecret) {
|
||||
return initFragment(target, fragment, masterSecret, null);
|
||||
}
|
||||
|
||||
private void routeApplicationState(MasterSecret masterSecret) {
|
||||
Intent intent = getIntentForState(masterSecret, getApplicationState(masterSecret));
|
||||
if (intent != null) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Locale;
|
|||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
|
@ -39,7 +40,12 @@ public class DateUtils extends android.text.format.DateUtils {
|
|||
return (int) to.convert(System.currentTimeMillis() - millis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public static String getBriefRelativeTimeSpanString(final Context c, final long timestamp) {
|
||||
private static String getFormattedDateTime(long time, String template, Locale locale) {
|
||||
String localizedPattern = new SimpleDateFormat(template, locale).toLocalizedPattern();
|
||||
return new SimpleDateFormat(localizedPattern, locale).format(new Date(time));
|
||||
}
|
||||
|
||||
public static String getBriefRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
||||
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
|
||||
return c.getString(R.string.DateUtils_now);
|
||||
} else if (isWithin(timestamp, 1, TimeUnit.HOURS)) {
|
||||
|
@ -49,34 +55,34 @@ public class DateUtils extends android.text.format.DateUtils {
|
|||
int hours = convertDelta(timestamp, TimeUnit.HOURS);
|
||||
return c.getResources().getQuantityString(R.plurals.hours_ago, hours, hours);
|
||||
} else if (isWithin(timestamp, 6, TimeUnit.DAYS)) {
|
||||
return formatDateTime(c, timestamp, DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_WEEKDAY);
|
||||
return getFormattedDateTime(timestamp, "EEE", locale);
|
||||
} else if (isWithin(timestamp, 365, TimeUnit.DAYS)) {
|
||||
return formatDateTime(c, timestamp, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL);
|
||||
return getFormattedDateTime(timestamp, "MMM d", locale);
|
||||
} else {
|
||||
return formatDateTime(c, timestamp, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);
|
||||
return getFormattedDateTime(timestamp, "MMM d, yyyy", locale);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getExtendedRelativeTimeSpanString(final Context c, final long timestamp) {
|
||||
public static String getExtendedRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
||||
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
|
||||
return c.getString(R.string.DateUtils_now);
|
||||
} else if (isWithin(timestamp, 1, TimeUnit.HOURS)) {
|
||||
int mins = (int)TimeUnit.MINUTES.convert(System.currentTimeMillis() - timestamp, TimeUnit.MILLISECONDS);
|
||||
return c.getResources().getQuantityString(R.plurals.minutes_ago, mins, mins);
|
||||
} else {
|
||||
int formatFlags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_TIME;
|
||||
if (isWithin(timestamp, 6, TimeUnit.DAYS)) {
|
||||
formatFlags |= DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_WEEKDAY;
|
||||
} else if (isWithin(timestamp, 365, TimeUnit.DAYS)) {
|
||||
formatFlags |= DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL;
|
||||
} else {
|
||||
formatFlags |= DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL;
|
||||
}
|
||||
return DateUtils.formatDateTime(c, timestamp, formatFlags);
|
||||
StringBuilder format = new StringBuilder();
|
||||
if (isWithin(timestamp, 6, TimeUnit.DAYS)) format.append("EEE ");
|
||||
else if (isWithin(timestamp, 365, TimeUnit.DAYS)) format.append("MMM d, ");
|
||||
else format.append("MMM d, yyyy, ");
|
||||
|
||||
if (DateFormat.is24HourFormat(c)) format.append("HH:mm");
|
||||
else format.append("hh:mm a");
|
||||
|
||||
return getFormattedDateTime(timestamp, format.toString(), locale);
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleDateFormat getDetailedDateFormatter(Context context) {
|
||||
public static SimpleDateFormat getDetailedDateFormatter(Context context, Locale locale) {
|
||||
String dateFormatPattern;
|
||||
|
||||
if (DateFormat.is24HourFormat(context)) {
|
||||
|
@ -85,7 +91,7 @@ public class DateUtils extends android.text.format.DateUtils {
|
|||
dateFormatPattern = "MMM d, yyyy hh:mm:ss a zzz";
|
||||
}
|
||||
|
||||
return new SimpleDateFormat(dateFormatPattern, Locale.getDefault());
|
||||
return new SimpleDateFormat(dateFormatPattern, locale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,10 @@ public class DynamicLanguage {
|
|||
setContextLocale(service, currentLocale);
|
||||
}
|
||||
|
||||
public Locale getCurrentLocale() {
|
||||
return currentLocale;
|
||||
}
|
||||
|
||||
private static void setContextLocale(Context context, Locale selectedLocale) {
|
||||
Configuration configuration = context.getResources().getConfiguration();
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue