From 427b7c755747bf5f6a2aaec64c76019e4cafd447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 12 Oct 2024 23:24:14 +0100 Subject: [PATCH] Activity details: Refactor header --- .../activities/ActivitySummaryDetail.java | 211 +++++++++--------- .../gadgetbridge/model/ActivityListItem.java | 19 +- .../gadgetbridge/util/DateTimeUtils.java | 38 ++++ .../res/layout/activity_summary_details.xml | 186 +++++---------- .../menu/activity_take_screenshot_menu.xml | 24 +- app/src/main/res/values/strings.xml | 2 + 6 files changed, 222 insertions(+), 258 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java index fbf168a94..996b03198 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java @@ -22,7 +22,6 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries. import android.annotation.SuppressLint; import android.content.ActivityNotFoundException; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; @@ -31,6 +30,7 @@ import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.text.InputType; +import android.text.format.DateUtils; import android.util.TypedValue; import android.view.Gravity; import android.view.Menu; @@ -44,6 +44,7 @@ import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.FrameLayout; +import androidx.appcompat.app.ActionBar; import androidx.gridlayout.widget.GridLayout; import android.widget.ImageView; @@ -102,7 +103,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity { private static final Logger LOG = LoggerFactory.getLogger(ActivitySummaryDetail.class); BaseActivitySummary currentItem = null; private GBDevice gbDevice; - private int alternateColor; private Menu mOptionsMenu; List filesGpxList = new ArrayList<>(); int selectedGpxIndex; @@ -155,7 +155,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity { final ActivitySummaryItems items = new ActivitySummaryItems(this, gbDevice, activityFilter, dateFromFilter, dateToFilter, nameContainsFilter, deviceFilter, itemsFilter); final ScrollView layout = findViewById(R.id.activity_summary_detail_scroll_layout); //final LinearLayout layout = findViewById(R.id.activity_summary_detail_relative_layout); - alternateColor = getAlternateColor(this); final Animation animFadeRight; final Animation animFadeLeft; @@ -227,99 +226,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity { return false; } }); - - ImageView activity_summary_detail_edit_name_image = findViewById(R.id.activity_summary_detail_edit_name); - activity_summary_detail_edit_name_image.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final EditText input = new EditText(ActivitySummaryDetail.this); - input.setInputType(InputType.TYPE_CLASS_TEXT); - String name = currentItem.getName(); - input.setText((name != null) ? name : ""); - FrameLayout container = new FrameLayout(ActivitySummaryDetail.this); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - params.leftMargin = getResources().getDimensionPixelSize(R.dimen.dialog_margin); - params.rightMargin = getResources().getDimensionPixelSize(R.dimen.dialog_margin); - input.setLayoutParams(params); - container.addView(input); - - new MaterialAlertDialogBuilder(ActivitySummaryDetail.this) - .setView(container) - .setCancelable(true) - .setTitle(ActivitySummaryDetail.this.getString(R.string.activity_summary_edit_name_title)) - .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - String name = input.getText().toString(); - if (name.length() < 1) name = null; - currentItem.setName(name); - currentItem.update(); - makeSummaryHeader(currentItem); - makeSummaryContent(currentItem); - } - }) - .setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // do nothing - } - }) - .show(); - } - }); - ImageView activity_summary_detail_edit_gps = findViewById(R.id.activity_summary_detail_edit_gps); - activity_summary_detail_edit_gps.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View view) { - export_path = get_path(); - filesGpxList = get_gpx_file_list(); - - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ActivitySummaryDetail.this); - builder.setTitle(R.string.activity_summary_detail_select_gpx_track); - ArrayAdapter directory_listing = new ArrayAdapter(ActivitySummaryDetail.this, android.R.layout.simple_list_item_1, filesGpxList); - builder.setSingleChoiceItems(directory_listing, 0, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - selectedGpxIndex = which; - selectedGpxFile = export_path + "/" + filesGpxList.get(selectedGpxIndex); - String message = String.format("%s %s?", getString(R.string.set), filesGpxList.get(selectedGpxIndex)); - if (selectedGpxIndex == 0) { - selectedGpxFile = null; - message = String.format("%s?", getString(R.string.activity_summary_detail_clear_gpx_track)); - } - - new MaterialAlertDialogBuilder(ActivitySummaryDetail.this) - .setCancelable(true) - .setIcon(R.drawable.ic_warning) - .setTitle(R.string.activity_summary_detail_editing_gpx_track) - .setMessage(message) - .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - currentItem.setGpxTrack(selectedGpxFile); - currentItem.update(); - if (itemHasGps()) { - showGpsCanvas(); - activitySummariesGpsFragment.set_data(getTrackFile()); - } else { - hideGpsCanvas(); - } - } - }) - .setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }) - .show(); - dialog.dismiss(); - } - }); - AlertDialog dialog = builder.create(); - dialog.show(); - } - }); } private void makeSummaryHeader(BaseActivitySummary item) { @@ -328,32 +234,45 @@ public class ActivitySummaryDetail extends AbstractGBActivity { String activityname = item.getName(); Date starttime = item.getStartTime(); Date endtime = item.getEndTime(); - String starttimeS = String.format("%s, %s", DateTimeUtils.formatDate(starttime), DateTimeUtils.formatTime(starttime.getHours(), starttime.getMinutes())); - String endtimeS = String.format("%s, %s", DateTimeUtils.formatDate(endtime), DateTimeUtils.formatTime(endtime.getHours(), endtime.getMinutes())); String durationhms = DateTimeUtils.formatDurationHoursMinutes((endtime.getTime() - starttime.getTime()), TimeUnit.MILLISECONDS); ImageView activity_icon = findViewById(R.id.item_image); activity_icon.setImageResource(ActivityKind.fromCode(item.getActivityKind()).getIcon()); - TextView activity_kind = findViewById(R.id.activitykind); - activity_kind.setText(activitykindname); + final ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setTitle(activitykindname); + } TextView activity_name = findViewById(R.id.activityname); activity_name.setText(activityname); - if (StringUtils.isBlank(activityname)) { activity_name.setVisibility(View.GONE); } else { activity_name.setVisibility(View.VISIBLE); } - TextView start_time = findViewById(R.id.starttime); - start_time.setText(starttimeS); - TextView end_time = findViewById(R.id.endtime); - end_time.setText(endtimeS); - TextView activity_duration = findViewById(R.id.duration); - activity_duration.setText(durationhms); + TextView activityDateTextView = findViewById(R.id.activitydate); + final Context context = activityDateTextView.getContext(); + final String timeString; + if (DateTimeUtils.isSameDay(starttime, endtime)) { + timeString = context.getString( + R.string.date_placeholders__start_time__end_time, + DateTimeUtils.formatDateTimeRelative(context, starttime), + DateTimeUtils.formatTime(endtime.getHours(), endtime.getMinutes()) + ); + } else { + timeString = context.getString( + R.string.date_placeholders__start_time__end_time, + DateTimeUtils.formatDateTimeRelative(context, starttime), + DateTimeUtils.formatDateTimeRelative(context, endtime) + ); + } + activityDateTextView.setText(timeString); + + TextView activityTimeTextView = findViewById(R.id.activityduration); + activityTimeTextView.setText(durationhms); } private void refreshFromCurrentItem() { @@ -439,7 +358,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity { TextView label_field = new TextView(ActivitySummaryDetail.this); label_field.setId(View.generateViewId()); label_field.setTextSize(18); - label_field.setPadding(dpToPx(8), dpToPx(20), 0, dpToPx(20)); + label_field.setPaddingRelative(dpToPx(16), dpToPx(16), 0, dpToPx(16)); label_field.setTypeface(null, Typeface.BOLD); label_field.setText(workoutValueFormatter.getStringResourceByName(groupKey)); label_row.addView(label_field); @@ -534,10 +453,86 @@ public class ActivitySummaryDetail extends AbstractGBActivity { } else if (itemId == R.id.activity_action_dev_share_json_details) { shareJsonDetails(ActivitySummaryDetail.this, currentItem); return true; + } else if (itemId == R.id.activity_summary_detail_action_edit_name) { + editLabel(); + return true; + } else if (itemId == R.id.activity_summary_detail_action_edit_gps) { + editGps(); + return true; } return super.onOptionsItemSelected(item); } + private void editLabel() { + final EditText input = new EditText(ActivitySummaryDetail.this); + input.setInputType(InputType.TYPE_CLASS_TEXT); + String name = currentItem.getName(); + input.setText((name != null) ? name : ""); + FrameLayout container = new FrameLayout(ActivitySummaryDetail.this); + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.leftMargin = getResources().getDimensionPixelSize(R.dimen.dialog_margin); + params.rightMargin = getResources().getDimensionPixelSize(R.dimen.dialog_margin); + input.setLayoutParams(params); + container.addView(input); + + new MaterialAlertDialogBuilder(ActivitySummaryDetail.this) + .setView(container) + .setCancelable(true) + .setTitle(ActivitySummaryDetail.this.getString(R.string.activity_summary_edit_name_title)) + .setPositiveButton(R.string.ok, (dialog, which) -> { + String name1 = input.getText().toString(); + if (name1.isEmpty()) name1 = null; + currentItem.setName(name1); + currentItem.update(); + makeSummaryHeader(currentItem); + makeSummaryContent(currentItem); + }) + .setNegativeButton(R.string.Cancel, (dialog, which) -> { + // do nothing + }) + .show(); + } + + private void editGps() { + export_path = get_path(); + filesGpxList = get_gpx_file_list(); + + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ActivitySummaryDetail.this); + builder.setTitle(R.string.activity_summary_detail_select_gpx_track); + ArrayAdapter directory_listing = new ArrayAdapter<>(ActivitySummaryDetail.this, android.R.layout.simple_list_item_1, filesGpxList); + builder.setSingleChoiceItems(directory_listing, 0, (dialog, which) -> { + selectedGpxIndex = which; + selectedGpxFile = export_path + "/" + filesGpxList.get(selectedGpxIndex); + String message = String.format("%s %s?", getString(R.string.set), filesGpxList.get(selectedGpxIndex)); + if (selectedGpxIndex == 0) { + selectedGpxFile = null; + message = String.format("%s?", getString(R.string.activity_summary_detail_clear_gpx_track)); + } + + new MaterialAlertDialogBuilder(ActivitySummaryDetail.this) + .setCancelable(true) + .setIcon(R.drawable.ic_warning) + .setTitle(R.string.activity_summary_detail_editing_gpx_track) + .setMessage(message) + .setPositiveButton(R.string.ok, (dialog1, which1) -> { + currentItem.setGpxTrack(selectedGpxFile); + currentItem.update(); + if (itemHasGps()) { + showGpsCanvas(); + activitySummariesGpsFragment.set_data(getTrackFile()); + } else { + hideGpsCanvas(); + } + }) + .setNegativeButton(R.string.Cancel, (dialog2, which2) -> { + }) + .show(); + dialog.dismiss(); + }); + AlertDialog dialog = builder.create(); + dialog.show(); + } + private void take_share_screenshot(Context context) { final ScrollView layout = findViewById(R.id.activity_summary_detail_scroll_layout); final int width = layout.getChildAt(0).getWidth(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityListItem.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityListItem.java index eca625e4d..0c6c16d8d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityListItem.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityListItem.java @@ -131,7 +131,7 @@ public class ActivityListItem { } if (date != null) { - dateLabel.setText(formatDate(date)); + dateLabel.setText(DateTimeUtils.formatDateTimeRelative(rootView.getContext(), date)); dateLabel.setVisibility(View.VISIBLE); } else { dateLabel.setVisibility(View.GONE); @@ -162,23 +162,6 @@ public class ActivityListItem { } } - private String formatDate(final Date date) { - if (date != null) { - final String activityDay; - if (DateUtils.isToday(date.getTime())) { - activityDay = rootView.getContext().getString(R.string.activity_summary_today); - } else if (DateTimeUtils.isYesterday(date)) { - activityDay = rootView.getContext().getString(R.string.activity_summary_yesterday); - } else { - activityDay = DateTimeUtils.formatDate(date, DateUtils.FORMAT_SHOW_WEEKDAY); - } - final String activityTime = DateTimeUtils.formatTime(date.getHours(), date.getMinutes()); - return String.format("%s, %s", activityDay, activityTime); - } - - return rootView.getContext().getString(R.string.unknown); - } - public static int getThemedColor(Context context, int resid) { TypedValue typedValue = new TypedValue(); Resources.Theme theme = context.getTheme(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java index 80f402c4b..652a13e15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java @@ -17,6 +17,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.util; +import android.content.Context; import android.text.format.DateUtils; import com.github.pfichtner.durationformatter.DurationFormatter; @@ -34,6 +35,7 @@ import java.util.TimeZone; import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.R; public class DateTimeUtils { private static SimpleDateFormat DAY_STORAGE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US); @@ -256,6 +258,22 @@ public class DateTimeUtils { && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH); } + /** + * Determine whether two Date instances are on the same day + * + * @param date1 The first date to compare + * @param date2 The second date to compare + * @return true if the Date instances are on the same day + */ + public static boolean isSameDay(Date date1, Date date2) { + final Calendar calendar1 = GregorianCalendar.getInstance(); + calendar1.setTime(date1); + final Calendar calendar2 = GregorianCalendar.getInstance(); + calendar2.setTime(date2); + + return isSameDay(calendar1, calendar2); + } + /** * Determine whether two Calendar instances are in the same month * @@ -267,4 +285,24 @@ public class DateTimeUtils { return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH); } + + public static String formatDateRelative(final Context context, final Date date) { + if (DateUtils.isToday(date.getTime())) { + return context.getString(R.string.activity_summary_today); + } else if (DateTimeUtils.isYesterday(date)) { + return context.getString(R.string.activity_summary_yesterday); + } else { + return DateTimeUtils.formatDate(date, DateUtils.FORMAT_SHOW_WEEKDAY); + } + } + + public static String formatDateTimeRelative(final Context context, final Date date) { + if (date != null) { + final String activityDay = formatDateRelative(context, date); + final String activityTime = DateTimeUtils.formatTime(date.getHours(), date.getMinutes()); + return context.getString(R.string.date_placeholders__date__time, activityDay, activityTime); + } + + return context.getString(R.string.unknown); + } } diff --git a/app/src/main/res/layout/activity_summary_details.xml b/app/src/main/res/layout/activity_summary_details.xml index 56c90f576..4f7106b29 100644 --- a/app/src/main/res/layout/activity_summary_details.xml +++ b/app/src/main/res/layout/activity_summary_details.xml @@ -1,5 +1,6 @@ - + android:orientation="vertical"> - - + android:layout_marginBottom="8dp" + android:orientation="horizontal"> - - - - - - - - - - - - + android:text="Activity Name" + android:textSize="16sp" + tools:ignore="HardcodedText" /> - + - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + android:orientation="vertical" /> + android:layout_height="300dp" /> + android:layout_height="300dp" /> diff --git a/app/src/main/res/menu/activity_take_screenshot_menu.xml b/app/src/main/res/menu/activity_take_screenshot_menu.xml index 4b972a5d4..d87cc95f7 100644 --- a/app/src/main/res/menu/activity_take_screenshot_menu.xml +++ b/app/src/main/res/menu/activity_take_screenshot_menu.xml @@ -2,6 +2,28 @@ + + + + + + + + + - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4ad4e11f3..2350702da 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1012,6 +1012,8 @@ Awake AVG - --:-- + %1s, %1s + %1s - %2s Lowest HR Highest HR Transition