mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-27 02:55:50 +01:00
Dashboard: Add option to show yesterday's data in Today widget
This commit is contained in:
parent
7d15859737
commit
52798393a4
@ -69,6 +69,9 @@ public class DashboardPreferencesActivity extends AbstractSettingsActivityV2 {
|
|||||||
"dashboard_cards_enabled",
|
"dashboard_cards_enabled",
|
||||||
"pref_dashboard_widgets_order",
|
"pref_dashboard_widgets_order",
|
||||||
"dashboard_widget_today_24h",
|
"dashboard_widget_today_24h",
|
||||||
|
"dashboard_widget_today_24h_upside_down",
|
||||||
|
"dashboard_widget_today_show_yesterday",
|
||||||
|
"dashboard_widget_today_time_indicator",
|
||||||
"dashboard_widget_today_2columns",
|
"dashboard_widget_today_2columns",
|
||||||
"dashboard_widget_today_legend",
|
"dashboard_widget_today_legend",
|
||||||
"dashboard_widget_today_hr_interval",
|
"dashboard_widget_today_hr_interval",
|
||||||
|
@ -58,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DashboardUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.DashboardUtils;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,9 +140,11 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
private void draw() {
|
private void draw() {
|
||||||
Prefs prefs = GBApplication.getPrefs();
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
boolean upsideDown24h = prefs.getBoolean("dashboard_widget_today_24h_upside_down", false);
|
boolean upsideDown24h = prefs.getBoolean("dashboard_widget_today_24h_upside_down", false);
|
||||||
|
boolean showYesterday = prefs.getBoolean("dashboard_widget_today_show_yesterday", false);
|
||||||
|
|
||||||
// Prepare circular chart
|
// Prepare circular chart
|
||||||
long midDaySecond = dashboardData.timeFrom + (12 * 60 * 60);
|
long currentDayStart = dashboardData.timeTo - 86400;
|
||||||
|
long midDaySecond = currentDayStart + (12 * 60 * 60);
|
||||||
int width = Resources.getSystem().getDisplayMetrics().widthPixels;
|
int width = Resources.getSystem().getDisplayMetrics().widthPixels;
|
||||||
int height = width;
|
int height = width;
|
||||||
int barWidth = Math.round(width * 0.08f);
|
int barWidth = Math.round(width * 0.08f);
|
||||||
@ -231,11 +234,24 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
// Draw generalized activities on circular chart
|
// Draw generalized activities on circular chart
|
||||||
long secondIndex = dashboardData.timeFrom;
|
long secondIndex = dashboardData.timeFrom;
|
||||||
long currentTime = Calendar.getInstance().getTimeInMillis() / 1000;
|
long currentTime = Calendar.getInstance().getTimeInMillis() / 1000;
|
||||||
|
boolean dayIsToday = !(dashboardData.timeTo < currentTime);
|
||||||
int startAngle = mode_24h && upsideDown24h ? 90 : 270;
|
int startAngle = mode_24h && upsideDown24h ? 90 : 270;
|
||||||
synchronized (dashboardData.generalizedActivities) {
|
synchronized (dashboardData.generalizedActivities) {
|
||||||
for (DashboardFragment.DashboardData.GeneralizedActivity activity : dashboardData.generalizedActivities) {
|
for (DashboardFragment.DashboardData.GeneralizedActivity activity : dashboardData.generalizedActivities) {
|
||||||
// Determine margin depending on 24h/12h mode
|
// Determine margin
|
||||||
float margin = (mode_24h || activity.timeFrom >= midDaySecond) ? outerCircleMargin : innerCircleMargin;
|
float margin = innerCircleMargin;
|
||||||
|
if (mode_24h || activity.timeFrom >= midDaySecond) {
|
||||||
|
margin = outerCircleMargin;
|
||||||
|
}
|
||||||
|
if (!mode_24h && showYesterday && dayIsToday) {
|
||||||
|
if (activity.timeFrom < currentDayStart && activity.timeFrom > midDaySecond - 86400) {
|
||||||
|
margin = outerCircleMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Skip activities from before 24h ago (to prevent double drawing the same position)
|
||||||
|
if (showYesterday && dayIsToday && (activity.timeTo < currentTime - 86400)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Draw inactive slices
|
// Draw inactive slices
|
||||||
if (!mode_24h && secondIndex < midDaySecond && activity.timeFrom >= midDaySecond) {
|
if (!mode_24h && secondIndex < midDaySecond && activity.timeFrom >= midDaySecond) {
|
||||||
paint.setStrokeWidth(barWidth / 3f);
|
paint.setStrokeWidth(barWidth / 3f);
|
||||||
@ -253,39 +269,70 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
if (activity.activityKind == ActivityKind.NOT_MEASURED) {
|
if (activity.activityKind == ActivityKind.NOT_MEASURED) {
|
||||||
paint.setStrokeWidth(barWidth / 3f);
|
paint.setStrokeWidth(barWidth / 3f);
|
||||||
paint.setColor(color_worn);
|
paint.setColor(color_worn);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.NOT_WORN) {
|
} else if (activity.activityKind == ActivityKind.NOT_WORN) {
|
||||||
paint.setStrokeWidth(barWidth / 3f);
|
paint.setStrokeWidth(barWidth / 3f);
|
||||||
paint.setColor(color_not_worn);
|
paint.setColor(color_not_worn);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.LIGHT_SLEEP || activity.activityKind == ActivityKind.SLEEP_ANY) {
|
} else if (activity.activityKind == ActivityKind.LIGHT_SLEEP || activity.activityKind == ActivityKind.SLEEP_ANY) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_light_sleep);
|
paint.setColor(color_light_sleep);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.REM_SLEEP) {
|
} else if (activity.activityKind == ActivityKind.REM_SLEEP) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_rem_sleep);
|
paint.setColor(color_rem_sleep);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.DEEP_SLEEP) {
|
} else if (activity.activityKind == ActivityKind.DEEP_SLEEP) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_deep_sleep);
|
paint.setColor(color_deep_sleep);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.AWAKE_SLEEP) {
|
} else if (activity.activityKind == ActivityKind.AWAKE_SLEEP) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_awake_sleep);
|
paint.setColor(color_awake_sleep);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.EXERCISE) {
|
} else if (activity.activityKind == ActivityKind.EXERCISE) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_exercise);
|
paint.setColor(color_exercise);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else {
|
} else {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_activity);
|
paint.setColor(color_activity);
|
||||||
|
if (showYesterday && dayIsToday && activity.timeFrom < currentDayStart) {
|
||||||
|
paint.setAlpha(64);
|
||||||
|
}
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
}
|
}
|
||||||
secondIndex = activity.timeTo;
|
secondIndex = activity.timeTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Draw indicator for current time
|
||||||
|
if (prefs.getBoolean("dashboard_widget_today_time_indicator", false) && currentTime < dashboardData.timeTo) {
|
||||||
|
float margin = (mode_24h || currentTime >= midDaySecond) ? outerCircleMargin : innerCircleMargin;
|
||||||
|
paint.setStrokeWidth(barWidth);
|
||||||
|
paint.setColor(GBApplication.getTextColor(requireContext()));
|
||||||
|
canvas.drawArc(margin, margin, width - margin, height - margin, startAngle + (currentTime - dashboardData.timeFrom) / degreeFactor, 300 / degreeFactor, false, paint);
|
||||||
|
}
|
||||||
// Fill remaining time until current time in 12h mode before midday
|
// Fill remaining time until current time in 12h mode before midday
|
||||||
if (!mode_24h && currentTime < midDaySecond) {
|
if (!mode_24h && currentTime < midDaySecond) {
|
||||||
// Fill inner bar up until current time
|
// Fill inner bar up until current time
|
||||||
@ -332,6 +379,17 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
|
|
||||||
protected void fillData() {
|
protected void fillData() {
|
||||||
if (todayView == null) return;
|
if (todayView == null) return;
|
||||||
|
|
||||||
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
|
if (prefs.getBoolean("dashboard_widget_today_show_yesterday", false)) {
|
||||||
|
Calendar today = Calendar.getInstance();
|
||||||
|
Calendar dashboardDate = Calendar.getInstance();
|
||||||
|
dashboardDate.setTimeInMillis((dashboardData.timeFrom + 1) * 1000L);
|
||||||
|
if (DateTimeUtils.isSameDay(today, dashboardDate)) {
|
||||||
|
dashboardData.timeFrom -= 86400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
todayView.post(new Runnable() {
|
todayView.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -344,6 +402,9 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
private class FillDataAsyncTask extends AsyncTask<Void, Void, Void> {
|
private class FillDataAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||||
private final TreeMap<Long, ActivityKind> activityTimestamps = new TreeMap<>();
|
private final TreeMap<Long, ActivityKind> activityTimestamps = new TreeMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add per-second activities to `activityTimestamps`
|
||||||
|
*/
|
||||||
private void addActivity(long timeFrom, long timeTo, ActivityKind activityKind) {
|
private void addActivity(long timeFrom, long timeTo, ActivityKind activityKind) {
|
||||||
for (long i = timeFrom; i <= timeTo; i++) {
|
for (long i = timeFrom; i <= timeTo; i++) {
|
||||||
// If the current timestamp isn't saved yet, do so immediately
|
// If the current timestamp isn't saved yet, do so immediately
|
||||||
@ -403,6 +464,9 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add NOT_MEASURED (worn) activities for every successful heart rate measurement
|
||||||
|
*/
|
||||||
private void calculateWornSessions(List<ActivitySample> samples) {
|
private void calculateWornSessions(List<ActivitySample> samples) {
|
||||||
int firstTimestamp = 0;
|
int firstTimestamp = 0;
|
||||||
int lastTimestamp = 0;
|
int lastTimestamp = 0;
|
||||||
@ -435,13 +499,25 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge per-second activities from `activityTimestamps` into generalized activity ranges
|
||||||
|
* with minute-based resolution
|
||||||
|
*/
|
||||||
private void createGeneralizedActivities() {
|
private void createGeneralizedActivities() {
|
||||||
|
long currentTime = Calendar.getInstance().getTimeInMillis() / 1000;
|
||||||
|
long midDaySecond = dashboardData.timeTo - (12 * 60 * 60);
|
||||||
DashboardFragment.DashboardData.GeneralizedActivity previous = null;
|
DashboardFragment.DashboardData.GeneralizedActivity previous = null;
|
||||||
long midDaySecond = dashboardData.timeFrom + (12 * 60 * 60);
|
|
||||||
for (Map.Entry<Long, ActivityKind> activity : activityTimestamps.entrySet()) {
|
for (Map.Entry<Long, ActivityKind> activity : activityTimestamps.entrySet()) {
|
||||||
long timestamp = activity.getKey();
|
long timestamp = activity.getKey();
|
||||||
ActivityKind activityKind = activity.getValue();
|
ActivityKind activityKind = activity.getValue();
|
||||||
if (previous == null || previous.activityKind != activityKind || (!mode_24h && timestamp == midDaySecond) || previous.timeTo < timestamp - 60) {
|
// Start a new merged activity on certain conditions
|
||||||
|
if (previous == null ||
|
||||||
|
previous.activityKind != activityKind ||
|
||||||
|
(!mode_24h && timestamp == midDaySecond) ||
|
||||||
|
(!mode_24h && timestamp == midDaySecond - 86400) ||
|
||||||
|
timestamp == dashboardData.timeTo - 86400 ||
|
||||||
|
timestamp == currentTime - 86400 ||
|
||||||
|
previous.timeTo < timestamp - 60) {
|
||||||
previous = new DashboardFragment.DashboardData.GeneralizedActivity(activityKind, timestamp, timestamp);
|
previous = new DashboardFragment.DashboardData.GeneralizedActivity(activityKind, timestamp, timestamp);
|
||||||
dashboardData.generalizedActivities.add(previous);
|
dashboardData.generalizedActivities.add(previous);
|
||||||
} else {
|
} else {
|
||||||
@ -494,6 +570,8 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
for (ActivitySession session : stepSessions) {
|
for (ActivitySession session : stepSessions) {
|
||||||
addActivity(session.getStartTime().getTime() / 1000, session.getEndTime().getTime() / 1000, ActivityKind.ACTIVITY);
|
addActivity(session.getStartTime().getTime() / 1000, session.getEndTime().getTime() / 1000, ActivityKind.ACTIVITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merge per-second activities
|
||||||
createGeneralizedActivities();
|
createGeneralizedActivities();
|
||||||
|
|
||||||
final long nanoEnd = System.nanoTime();
|
final long nanoEnd = System.nanoTime();
|
||||||
|
@ -3326,4 +3326,8 @@
|
|||||||
<string name="error_no_cycling_sensor_found">no cycling sensor found</string>
|
<string name="error_no_cycling_sensor_found">no cycling sensor found</string>
|
||||||
<string name="contact_birthday">%1s\'s birthday</string>
|
<string name="contact_birthday">%1s\'s birthday</string>
|
||||||
<string name="birthdays">Birthdays</string>
|
<string name="birthdays">Birthdays</string>
|
||||||
|
<string name="pref_dashboard_widget_today_yesterday_data_title">Data from yesterday</string>
|
||||||
|
<string name="pref_dashboard_widget_today_yesterday_data_summary">Show data from yesterday dimmed between the current time and midnight</string>
|
||||||
|
<string name="pref_dashboard_widget_today_time_indicator_title">Current time indicator</string>
|
||||||
|
<string name="pref_dashboard_widget_today_time_indicator_summary">Show an indicator at the current time, to visually separate data from yesterday and today</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -54,6 +54,20 @@
|
|||||||
android:title="@string/pref_dashboard_widget_today_upside_down_title"
|
android:title="@string/pref_dashboard_widget_today_upside_down_title"
|
||||||
android:summary="@string/pref_dashboard_widget_today_upside_down_summary"
|
android:summary="@string/pref_dashboard_widget_today_upside_down_summary"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="dashboard_widget_today_show_yesterday"
|
||||||
|
android:layout="@layout/preference_checkbox"
|
||||||
|
android:title="@string/pref_dashboard_widget_today_yesterday_data_title"
|
||||||
|
android:summary="@string/pref_dashboard_widget_today_yesterday_data_summary"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="dashboard_widget_today_time_indicator"
|
||||||
|
android:layout="@layout/preference_checkbox"
|
||||||
|
android:title="@string/pref_dashboard_widget_today_time_indicator_title"
|
||||||
|
android:summary="@string/pref_dashboard_widget_today_time_indicator_summary"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="dashboard_widget_today_2columns"
|
android:key="dashboard_widget_today_2columns"
|
||||||
|
Loading…
Reference in New Issue
Block a user