Add absolute/relative time format setting

* Added setting to toggle precise date as default display

* Applied spotless

* Improved time format setting with a ListPreference

* Fixed default time format value in list preference

Co-authored-by: Rémi Rigal <remi.rigal@orange.com>
This commit is contained in:
RemiRigal
2021-02-14 09:51:19 +01:00
committed by GitHub
parent 107810dcb7
commit 21e49d0852
5 changed files with 66 additions and 15 deletions

View File

@@ -3,6 +3,8 @@ package com.github.gotify.messages;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.text.format.DateUtils;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -12,6 +14,7 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@@ -26,9 +29,10 @@ import io.noties.markwon.core.CorePlugin;
import io.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.image.picasso.PicassoImagesPlugin; import io.noties.markwon.image.picasso.PicassoImagesPlugin;
import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.movement.MovementMethodPlugin;
import java.text.DateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import org.threeten.bp.OffsetDateTime; import org.threeten.bp.OffsetDateTime;
import org.threeten.bp.temporal.ChronoUnit;
public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.ViewHolder> { public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.ViewHolder> {
@@ -39,6 +43,9 @@ public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.
private Settings settings; private Settings settings;
private Markwon markwon; private Markwon markwon;
private final String TIME_FORMAT_RELATIVE;
private final String TIME_FORMAT_PREFS_KEY;
ListMessageAdapter( ListMessageAdapter(
Context context, Context context,
Settings settings, Settings settings,
@@ -59,6 +66,10 @@ public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.
.usePlugin(PicassoImagesPlugin.create(picasso)) .usePlugin(PicassoImagesPlugin.create(picasso))
.usePlugin(TablePlugin.create(context)) .usePlugin(TablePlugin.create(context))
.build(); .build();
TIME_FORMAT_RELATIVE =
context.getResources().getString(R.string.time_format_value_relative);
TIME_FORMAT_PREFS_KEY = context.getResources().getString(R.string.setting_key_time_format);
} }
public List<MessageWithImage> getItems() { public List<MessageWithImage> getItems() {
@@ -94,8 +105,10 @@ public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.
.placeholder(R.drawable.ic_placeholder) .placeholder(R.drawable.ic_placeholder)
.into(holder.image); .into(holder.image);
holder.setDateTime(message.message.getDate()); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
holder.date.setOnClickListener((ignored) -> holder.switchPreciseDate()); String timeFormat = prefs.getString(TIME_FORMAT_PREFS_KEY, TIME_FORMAT_RELATIVE);
holder.setDateTime(message.message.getDate(), timeFormat.equals(TIME_FORMAT_RELATIVE));
holder.date.setOnClickListener((ignored) -> holder.switchTimeFormat());
holder.delete.setOnClickListener( holder.delete.setOnClickListener(
(ignored) -> delete.delete(holder.getAdapterPosition(), message.message, false)); (ignored) -> delete.delete(holder.getAdapterPosition(), message.message, false));
@@ -128,35 +141,45 @@ public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.
@BindView(R.id.message_delete) @BindView(R.id.message_delete)
ImageButton delete; ImageButton delete;
private boolean preciseDate; private boolean relativeTimeFormat;
private OffsetDateTime dateTime; private OffsetDateTime dateTime;
ViewHolder(final View view) { ViewHolder(final View view) {
super(view); super(view);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
preciseDate = false; relativeTimeFormat = true;
dateTime = null; dateTime = null;
enableCopyToClipboard(); enableCopyToClipboard();
} }
void switchPreciseDate() { void switchTimeFormat() {
preciseDate = !preciseDate; relativeTimeFormat = !relativeTimeFormat;
updateDate(); updateDate();
} }
void setDateTime(OffsetDateTime dateTime) { void setDateTime(OffsetDateTime dateTime, boolean relativeTimeFormatPreference) {
this.dateTime = dateTime; this.dateTime = dateTime;
preciseDate = false; relativeTimeFormat = relativeTimeFormatPreference;
updateDate(); updateDate();
} }
void updateDate() { void updateDate() {
String text = "?"; String text = "?";
if (dateTime != null) { if (dateTime != null) {
if (preciseDate) { if (relativeTimeFormat) {
text = dateTime.truncatedTo(ChronoUnit.SECONDS).toString(); // Relative time format
} else {
text = Utils.dateToRelative(dateTime); text = Utils.dateToRelative(dateTime);
} else {
// Absolute time format
long time = dateTime.toInstant().toEpochMilli();
Date date = new Date(time);
if (DateUtils.isToday(time)) {
text = DateFormat.getTimeInstance(DateFormat.SHORT).format(date);
} else {
text =
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT)
.format(date);
}
} }
} }
date.setText(text); date.setText(text);

View File

@@ -123,6 +123,8 @@ public class MessagesActivity extends AppCompatActivity
private PicassoHandler picassoHandler; private PicassoHandler picassoHandler;
private ListMessageAdapter listMessageAdapter;
// we need to keep the target references otherwise they get gc'ed before they can be called. // we need to keep the target references otherwise they get gc'ed before they can be called.
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private final List<Target> targetReferences = new ArrayList<>(); private final List<Target> targetReferences = new ArrayList<>();
@@ -150,7 +152,7 @@ public class MessagesActivity extends AppCompatActivity
DividerItemDecoration dividerItemDecoration = DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration( new DividerItemDecoration(
messagesView.getContext(), layoutManager.getOrientation()); messagesView.getContext(), layoutManager.getOrientation());
ListMessageAdapter adapter = listMessageAdapter =
new ListMessageAdapter( new ListMessageAdapter(
this, settings, picassoHandler.get(), emptyList(), this::scheduleDeletion); this, settings, picassoHandler.get(), emptyList(), this::scheduleDeletion);
@@ -158,9 +160,10 @@ public class MessagesActivity extends AppCompatActivity
messagesView.setHasFixedSize(true); messagesView.setHasFixedSize(true);
messagesView.setLayoutManager(layoutManager); messagesView.setLayoutManager(layoutManager);
messagesView.addOnScrollListener(new MessageListOnScrollListener()); messagesView.addOnScrollListener(new MessageListOnScrollListener());
messagesView.setAdapter(adapter); messagesView.setAdapter(listMessageAdapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(adapter)); ItemTouchHelper itemTouchHelper =
new ItemTouchHelper(new SwipeToDeleteCallback(listMessageAdapter));
itemTouchHelper.attachToRecyclerView(messagesView); itemTouchHelper.attachToRecyclerView(messagesView);
swipeRefreshLayout.setOnRefreshListener(this::onRefresh); swipeRefreshLayout.setOnRefreshListener(this::onRefresh);
@@ -357,6 +360,8 @@ public class MessagesActivity extends AppCompatActivity
} }
} }
listMessageAdapter.notifyDataSetChanged();
navigationView.getMenu().findItem(selectedIndex).setChecked(true); navigationView.getMenu().findItem(selectedIndex).setChecked(true);
super.onResume(); super.onResume();
} }

View File

@@ -1,4 +1,5 @@
<resources> <resources>
<!-- Theme -->
<string-array name="mode"> <string-array name="mode">
<item>@string/theme_light</item> <item>@string/theme_light</item>
<item>@string/theme_dark</item> <item>@string/theme_dark</item>
@@ -7,4 +8,17 @@
<string name="theme_light">Light</string> <string name="theme_light">Light</string>
<string name="theme_dark">Dark</string> <string name="theme_dark">Dark</string>
<string name="theme_default">System Default</string> <string name="theme_default">System Default</string>
<!-- Time Format -->
<string-array name="time_format_entries">
<item>@string/time_format_entry_absolute</item>
<item>@string/time_format_entry_relative</item>
</string-array>
<string name="time_format_entry_absolute">Absolute time</string>
<string name="time_format_entry_relative">Relative time</string>
<string-array name="time_format_values">
<item>@string/time_format_value_absolute</item>
<item>@string/time_format_value_relative</item>
</string-array>
<string name="time_format_value_absolute">time_format_absolute</string>
<string name="time_format_value_relative">time_format_relative</string>
</resources> </resources>

View File

@@ -72,6 +72,8 @@
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="setting_theme">Theme</string> <string name="setting_theme">Theme</string>
<string name="setting_key_theme">theme</string> <string name="setting_key_theme">theme</string>
<string name="setting_time_format">Time format</string>
<string name="setting_key_time_format">time_format</string>
<string name="push_message">Push message</string> <string name="push_message">Push message</string>
<string name="appListDescription">App:</string> <string name="appListDescription">App:</string>
<string name="priorityDescription">Priority:</string> <string name="priorityDescription">Priority:</string>

View File

@@ -8,6 +8,13 @@
android:entryValues="@array/mode" android:entryValues="@array/mode"
android:key="@string/setting_key_theme" android:key="@string/setting_key_theme"
android:title="@string/setting_theme" /> android:title="@string/setting_theme" />
<ListPreference
android:defaultValue="@string/time_format_value_relative"
android:entries="@array/time_format_entries"
android:entryValues="@array/time_format_values"
android:key="@string/setting_key_time_format"
android:title="@string/setting_time_format"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>