mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
fix: don't offer to re-share an already-published workout
My Fitness builds its log from both Health Connect and the user's own kind 1301 events, but every row in Recent workouts carried a "Share this workout" button. On a relay-sourced entry that opened the composer prefilled and one tap from publishing a second kind 1301 for the same effort. WorkoutOrigin already recorded where each workout came from and nothing read it; the button is now gated on it. Also tidies the dashboard's copy and its empty cells: - This week showed "0 kcal" (and would show "0.0 mi" for a strength-only week) where the weekly-average card already omits metrics the window has none of. Distance and calories now appear only when this week or last week has one, so a drop to zero still renders its trend. - The footer note explained the four-week window as a Health Connect limit and claimed nothing leaves the phone. Neither holds once the log is fed by published events, which by definition already left. - Drops my_fitness_unavailable, unused since the log stopped depending on Health Connect, so it isn't sent out for translation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c5526f3575
commit
ec8a5fa573
+62
-38
@@ -56,6 +56,7 @@ import androidx.lifecycle.compose.LifecycleResumeEffect
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.vitorpamplona.amethyst.commons.fitness.DetectedWorkout
|
import com.vitorpamplona.amethyst.commons.fitness.DetectedWorkout
|
||||||
|
import com.vitorpamplona.amethyst.commons.fitness.WorkoutOrigin
|
||||||
import com.vitorpamplona.amethyst.commons.fitness.WorkoutStats
|
import com.vitorpamplona.amethyst.commons.fitness.WorkoutStats
|
||||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||||
@@ -284,34 +285,50 @@ private fun ThisWeekCard(
|
|||||||
miles: Boolean,
|
miles: Boolean,
|
||||||
) {
|
) {
|
||||||
SectionCard(stringRes(Res.string.my_fitness_this_week)) {
|
SectionCard(stringRes(Res.string.my_fitness_this_week)) {
|
||||||
StatGrid(
|
// Workouts and time are always worth a cell. Distance and calories are not: a week of
|
||||||
listOf(
|
// strength work has neither, and a column of zeroes reads as missing data rather than
|
||||||
StatCell(
|
// as "this activity doesn't have that metric". Last week still counts, so a drop to
|
||||||
stringRes(Res.string.my_fitness_workouts),
|
// zero keeps its cell and shows the fall.
|
||||||
report.thisWeek.workoutCount.toString(),
|
val cells =
|
||||||
null,
|
buildList {
|
||||||
WorkoutStats.percentChange(report.thisWeek.workoutCount.toDouble(), report.previousWeek.workoutCount.toDouble()),
|
add(
|
||||||
),
|
StatCell(
|
||||||
StatCell(
|
stringRes(Res.string.my_fitness_workouts),
|
||||||
stringRes(Res.string.my_fitness_time),
|
report.thisWeek.workoutCount.toString(),
|
||||||
formatDuration(report.thisWeek.durationSeconds),
|
null,
|
||||||
null,
|
WorkoutStats.percentChange(report.thisWeek.workoutCount.toDouble(), report.previousWeek.workoutCount.toDouble()),
|
||||||
WorkoutStats.percentChange(report.thisWeek.durationSeconds.toDouble(), report.previousWeek.durationSeconds.toDouble()),
|
),
|
||||||
),
|
)
|
||||||
StatCell(
|
add(
|
||||||
stringRes(Res.string.my_fitness_distance),
|
StatCell(
|
||||||
formatDistanceValue(report.thisWeek.distanceMeters, miles),
|
stringRes(Res.string.my_fitness_time),
|
||||||
distanceUnit(miles),
|
formatDuration(report.thisWeek.durationSeconds),
|
||||||
WorkoutStats.percentChange(report.thisWeek.distanceMeters, report.previousWeek.distanceMeters),
|
null,
|
||||||
),
|
WorkoutStats.percentChange(report.thisWeek.durationSeconds.toDouble(), report.previousWeek.durationSeconds.toDouble()),
|
||||||
StatCell(
|
),
|
||||||
stringRes(Res.string.my_fitness_calories),
|
)
|
||||||
report.thisWeek.calories.toString(),
|
if (report.thisWeek.distanceMeters > 0 || report.previousWeek.distanceMeters > 0) {
|
||||||
stringRes(Res.string.my_fitness_unit_kcal),
|
add(
|
||||||
WorkoutStats.percentChange(report.thisWeek.calories.toDouble(), report.previousWeek.calories.toDouble()),
|
StatCell(
|
||||||
),
|
stringRes(Res.string.my_fitness_distance),
|
||||||
),
|
formatDistanceValue(report.thisWeek.distanceMeters, miles),
|
||||||
)
|
distanceUnit(miles),
|
||||||
|
WorkoutStats.percentChange(report.thisWeek.distanceMeters, report.previousWeek.distanceMeters),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (report.thisWeek.calories > 0 || report.previousWeek.calories > 0) {
|
||||||
|
add(
|
||||||
|
StatCell(
|
||||||
|
stringRes(Res.string.my_fitness_calories),
|
||||||
|
report.thisWeek.calories.toString(),
|
||||||
|
stringRes(Res.string.my_fitness_unit_kcal),
|
||||||
|
WorkoutStats.percentChange(report.thisWeek.calories.toDouble(), report.previousWeek.calories.toDouble()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatGrid(cells)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,14 +350,16 @@ private fun WindowTotalsCard(
|
|||||||
val cells =
|
val cells =
|
||||||
buildList {
|
buildList {
|
||||||
add(StatCell(stringRes(Res.string.my_fitness_time), formatDuration(report.weeklyAverage.durationSeconds), null, null))
|
add(StatCell(stringRes(Res.string.my_fitness_time), formatDuration(report.weeklyAverage.durationSeconds), null, null))
|
||||||
add(
|
if (report.windowTotals.distanceMeters > 0) {
|
||||||
StatCell(
|
add(
|
||||||
stringRes(Res.string.my_fitness_distance),
|
StatCell(
|
||||||
formatDistanceValue(report.weeklyAverage.distanceMeters, miles),
|
stringRes(Res.string.my_fitness_distance),
|
||||||
distanceUnit(miles),
|
formatDistanceValue(report.weeklyAverage.distanceMeters, miles),
|
||||||
null,
|
distanceUnit(miles),
|
||||||
),
|
null,
|
||||||
)
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
if (report.windowTotals.steps > 0) {
|
if (report.windowTotals.steps > 0) {
|
||||||
add(StatCell(stringRes(Res.string.my_fitness_steps), report.weeklyAverage.steps.toString(), null, null))
|
add(StatCell(stringRes(Res.string.my_fitness_steps), report.weeklyAverage.steps.toString(), null, null))
|
||||||
}
|
}
|
||||||
@@ -492,8 +511,13 @@ private fun RecentWorkouts(
|
|||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
)
|
)
|
||||||
TextButton(onClick = { onShare(workout, label) }) {
|
// Only what is still unpublished can be shared. A workout that came
|
||||||
Text(stringRes(Res.string.my_fitness_share), style = MaterialTheme.typography.labelMedium)
|
// back from the relays is already posted: offering to share it again
|
||||||
|
// would publish a second kind 1301 for the same effort.
|
||||||
|
if (workout.origin != WorkoutOrigin.PUBLISHED) {
|
||||||
|
TextButton(onClick = { onShare(workout, label) }) {
|
||||||
|
Text(stringRes(Res.string.my_fitness_share), style = MaterialTheme.typography.labelMedium)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -685,7 +685,7 @@
|
|||||||
<string name="health_connect_rationale_privacy_policy">Read the full privacy policy</string>
|
<string name="health_connect_rationale_privacy_policy">Read the full privacy policy</string>
|
||||||
<string name="my_fitness_title">My Fitness</string>
|
<string name="my_fitness_title">My Fitness</string>
|
||||||
<string name="my_fitness_window">Last 4 weeks</string>
|
<string name="my_fitness_window">Last 4 weeks</string>
|
||||||
<string name="my_fitness_window_note">Health Connect serves the last 30 days, so Amethyst summarises four whole weeks. Nothing here leaves your phone.</string>
|
<string name="my_fitness_window_note">The last four whole weeks of your training: the workouts you have published, plus anything Health Connect records on this phone. Amethyst works the summary out on the device and publishes none of it.</string>
|
||||||
<string name="my_fitness_this_week">This week</string>
|
<string name="my_fitness_this_week">This week</string>
|
||||||
<string name="my_fitness_vs_last_week">vs last week</string>
|
<string name="my_fitness_vs_last_week">vs last week</string>
|
||||||
<string name="my_fitness_weekly_average">Weekly average</string>
|
<string name="my_fitness_weekly_average">Weekly average</string>
|
||||||
@@ -708,7 +708,6 @@
|
|||||||
<string name="my_fitness_best_highest_heart_rate">Highest heart rate</string>
|
<string name="my_fitness_best_highest_heart_rate">Highest heart rate</string>
|
||||||
<string name="my_fitness_recent">Recent workouts</string>
|
<string name="my_fitness_recent">Recent workouts</string>
|
||||||
<string name="my_fitness_empty">Nothing logged in the last 4 weeks. Workouts you post, and any your watch records, show up here.</string>
|
<string name="my_fitness_empty">Nothing logged in the last 4 weeks. Workouts you post, and any your watch records, show up here.</string>
|
||||||
<string name="my_fitness_unavailable">Health Connect is not available on this device, so Amethyst has no workouts to summarise.</string>
|
|
||||||
<string name="my_fitness_connect_title">Track your training</string>
|
<string name="my_fitness_connect_title">Track your training</string>
|
||||||
<string name="my_fitness_connect_message">Connect Health Connect to see your weekly totals, week-over-week trend, best efforts and training streak. Everything stays on your phone.</string>
|
<string name="my_fitness_connect_message">Connect Health Connect to see your weekly totals, week-over-week trend, best efforts and training streak. Everything stays on your phone.</string>
|
||||||
<string name="my_fitness_connect_banner">Connect Health Connect to add the workouts your watch records, with heart rate, steps and climb.</string>
|
<string name="my_fitness_connect_banner">Connect Health Connect to add the workouts your watch records, with heart rate, steps and climb.</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user