mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 00:16:59 +00:00
feat: always-on service cost card with a link to notification settings
The uptime row told users the service ran, not what it cost — and the setting to turn it off lives three screens away. The resource screen now shows a dedicated card (only while the service has run this week) that frames the cost in decision terms: running time and restarts, the relay connections it held while the app was closed, and the measured background battery drain — with a button straight to notification settings where the delivery method can be changed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016RJ8EAsdkHx5WHHU2eQJ1P
This commit is contained in:
+53
-4
@@ -39,6 +39,7 @@ import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -51,6 +52,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
@@ -65,6 +67,7 @@ import com.vitorpamplona.amethyst.service.resourceusage.ResourceUsageReportAssem
|
||||
import com.vitorpamplona.amethyst.service.resourceusage.ResourceUsageReportAssembler.Companion.formatDurationMs
|
||||
import com.vitorpamplona.amethyst.service.resourceusage.UsageSummary
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.routeToMessage
|
||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
@@ -140,6 +143,7 @@ fun ResourceUsageScreen(
|
||||
}
|
||||
SubsystemSection(weekSummary)
|
||||
ActivitySection(weekSummary)
|
||||
AlwaysOnServiceSection(weekSummary, nav)
|
||||
MemorySection(memory)
|
||||
SendReportSection(accountViewModel, nav, loaded, today, memory)
|
||||
}
|
||||
@@ -310,10 +314,6 @@ private fun ActivitySection(s: UsageSummary) {
|
||||
SettingsDivider()
|
||||
MetricRow(R.string.resource_usage_tor, formatDurationMs(s.torMs))
|
||||
}
|
||||
if (s.alwaysOnMs > 0) {
|
||||
SettingsDivider()
|
||||
MetricRow(R.string.resource_usage_always_on, formatDurationMs(s.alwaysOnMs))
|
||||
}
|
||||
if (s.callMs > 0) {
|
||||
SettingsDivider()
|
||||
MetricRow(R.string.resource_usage_calls, formatDurationMs(s.callMs))
|
||||
@@ -400,6 +400,55 @@ private fun MemorySection(memory: MemorySnapshot?) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decision-support card for the always-on notification service — the one
|
||||
* background consumer users can directly turn off. Shows what the service
|
||||
* actually costs in the last 7 days (uptime, the relay connections it holds
|
||||
* while the app is closed, and the measured background battery drain) and
|
||||
* links straight to the setting that controls it.
|
||||
*/
|
||||
@Composable
|
||||
private fun AlwaysOnServiceSection(
|
||||
s: UsageSummary,
|
||||
nav: INav,
|
||||
) {
|
||||
if (s.alwaysOnMs <= 0) return
|
||||
val starts = s.alwaysOnStarts.toInt()
|
||||
SettingsSection(R.string.resource_usage_alwayson_section) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.resource_usage_alwayson_explanation),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
MetricRow(
|
||||
R.string.resource_usage_alwayson_uptime,
|
||||
"${formatDurationMs(s.alwaysOnMs)} · ${pluralStringResource(R.plurals.resource_usage_alwayson_starts, starts, starts)}",
|
||||
)
|
||||
SettingsDivider()
|
||||
MetricRow(
|
||||
R.string.resource_usage_alwayson_bg_relay,
|
||||
formatConnHours(s.relayConnMsMobileBg + s.relayConnMsWifiBg),
|
||||
)
|
||||
if (s.batteryDrainBg > 0) {
|
||||
SettingsDivider()
|
||||
MetricRow(R.string.resource_usage_alwayson_battery, "${s.batteryDrainBg}%")
|
||||
}
|
||||
Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)) {
|
||||
TextButton(
|
||||
onClick = { nav.nav(Route.NotificationSettings) },
|
||||
modifier = Modifier.align(Alignment.End),
|
||||
) {
|
||||
Text(stringRes(R.string.resource_usage_alwayson_settings_button))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SendReportSection(
|
||||
accountViewModel: AccountViewModel,
|
||||
|
||||
@@ -3213,11 +3213,20 @@
|
||||
<string name="resource_usage_remote_signs">Remote signatures</string>
|
||||
<string name="resource_usage_pow">Proof-of-work mining</string>
|
||||
<string name="resource_usage_tor">Tor uptime</string>
|
||||
<string name="resource_usage_always_on">Always-on notification service</string>
|
||||
<string name="resource_usage_calls">Time in calls</string>
|
||||
<string name="resource_usage_nests">Time in audio rooms</string>
|
||||
<string name="resource_usage_location">Location listening</string>
|
||||
<string name="resource_usage_battery_drain">Battery used (in app / background)</string>
|
||||
<string name="resource_usage_alwayson_section">Background notification service</string>
|
||||
<string name="resource_usage_alwayson_explanation">Keeps connections to your relays open while the app is closed, so notifications arrive without Google’s push servers. While enabled, this is usually the largest background battery cost. If battery matters more to you than instant notifications, you can change the delivery method or turn it off.</string>
|
||||
<string name="resource_usage_alwayson_uptime">Running time</string>
|
||||
<plurals name="resource_usage_alwayson_starts">
|
||||
<item quantity="one">%1$d start</item>
|
||||
<item quantity="other">%1$d starts</item>
|
||||
</plurals>
|
||||
<string name="resource_usage_alwayson_bg_relay">Relay connections held while closed</string>
|
||||
<string name="resource_usage_alwayson_battery">Battery drained meanwhile (whole device)</string>
|
||||
<string name="resource_usage_alwayson_settings_button">Change notification settings</string>
|
||||
<string name="resource_usage_by_subsystem">Data by feature (7 days)</string>
|
||||
<string name="resource_usage_subsystem_relay">Relay sync</string>
|
||||
<string name="resource_usage_subsystem_image">Images</string>
|
||||
|
||||
Reference in New Issue
Block a user