mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
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 // FREEBIE
This commit is contained in:
parent
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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user