SPEC v0.30 and v0.31: manual update check (D-140), Android Insights (D-141 to D-143)
Build Kvitt images / build (push) Failing after 3h14m40s
Build Kvitt images / build (push) Failing after 3h14m40s
v0.30: D-140 S-22 "Check for update" calls UpdateRepository.checkNow(), which always asks
GET /apk/latest and restarts the 6-hour window (AC-16.2, AC-16.6, S-22, §14.2.4).
v0.31: D-141 InsightsRepository UI contract (§14.2.4); D-142 Insights placement and loading
on S-11; D-143 display rules; design-spec S-11 "Insights" and §3.10; strings.csv 588 rows
(16 analytics_insights_* keys), web dictionaries regenerated; §11.2 W0 and W6 landed.
HANDOFF: state at 1c9856b, Pi image deploy step, numbering (D-144..D-155 reserved, next v0.32).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
+38
-1
@@ -611,6 +611,7 @@ TalkBack: "Konto: Vardag. Dubbeltryck för att byta konto"; "Datum: idag"; "Beta
|
||||
* Range average (`averageOre`): a 1.5 dp dashed line (6 dp on, 4 dp off) across the plot at 75 % opacity of `color`, with its amount in whole kronor at the right end in `chartAxis` typography and the same colour.
|
||||
* Moving average (`movingAverage`, one value per point): a 1.5 dp line in `chart-axis-label` at 85 %.
|
||||
* A single bucket shows one centred point and no average lines; a range without spending shows only the 0 baseline (D-068).
|
||||
* Reused by S-11's Insights (D-143) with server-provided overlays: one point per whole month of E-34, `averageOre` is the trend's `average` and `movingAverage` its per-point moving average, both taken from the server, not computed on the phone; omitted when the average is 0 or there is one point.
|
||||
* Not interactive. TalkBack: the chart is one node reading `summary` (`analytics_summary_line`, or `analytics_summary_line_single` for one bucket).
|
||||
|
||||
**`LineLegend(items, color)`**: wrapping row as `ChartLegend`; each item a 16 × 10 dp line swatch in its line's style (solid series in `color`, dashed average, thin neutral moving average) + label (12 / 16 sp weight 500 `on-surface-variant`): the series name, "Snitt" (`analytics_average`), "Glidande snitt (3)" (`analytics_moving_average`). Decorative for TalkBack (the summary names the lines).
|
||||
@@ -944,6 +945,7 @@ Full screen (§13.2), works offline (AC-8.2). The flow and the category rule are
|
||||
3. `ChartCard` "Utgifter över tid": `StackedBarChart` grouped by the group-by toggle, `ChartLegend`.
|
||||
4. `ChartCard` "Per kategori": `BreakdownList` of categories.
|
||||
5. `ChartCard` "Per konto": `BreakdownList` of accounts (archived included with badge, AC-14.9).
|
||||
6. The Insights section (below, D-142, D-143), after "Per konto" or after the empty state.
|
||||
|
||||
**States**
|
||||
|
||||
@@ -959,12 +961,47 @@ Full screen (§13.2), works offline (AC-8.2). The flow and the category rule are
|
||||
* Period chip → menu of the presets (AC-14.2: "Denna månad", "Senaste 3 mån", "Senaste 6 mån", "Senaste 12 mån", "I år", "All tid", "Anpassad…"); "Anpassad…" opens the Material date range picker; "Använd" is enabled only with both dates (AnalyticsState note in §14.2.4).
|
||||
* Toggles re-query immediately; the filter survives tab switches within the session.
|
||||
* Bar → S-12 for that bucket (all groups); breakdown row → S-12 for that category or account over the range (AC-14.8).
|
||||
* Settlements are never counted (AC-14.6). Works offline.
|
||||
* Settlements are never counted (AC-14.6). Works offline (the Insights section below is online only).
|
||||
|
||||
**TalkBack**: chart summary sentences as §3.10; each bar and row a node; toggles are radio groups.
|
||||
|
||||
**200 %**: `S-11-analytics-200`.
|
||||
|
||||
#### Insights (D-142, D-143)
|
||||
|
||||
The server's trends and forecast (E-34, E-35, D-133), online only (§9.9), below S-11's local analytics. It follows S-11's measure toggle (Hushållet / Min del) and always covers the last 6 whole months, whatever S-11's period and granularity; group-by does not apply.
|
||||
|
||||
**Layout** (same column and gap as S-11):
|
||||
1. `SectionHeader` "Insikter" and a caption in body-small `on-surface-variant`: "Senaste 6 hela månaderna · Hushållet" ("· Min del" for my share; `analytics_insights_caption`).
|
||||
2. Banner when needed: offline `NeedsConnectionBanner` "Insikterna räknas fram på servern. Anslut till internet för att se dem." (`analytics_insights_offline_body`); after a failure an error `Banner` (`cloud_off`) "Kunde inte nå servern" for `network`, else the code's text, with the text button "Försök igen" (`refresh`). The last data of this session stays visible under either banner.
|
||||
3. `ChartCard` "Utgifter per månad" (`analytics_insights_trend`): the household or my-share trend as `SpendLineChart` (§3.10) in `primary`, with the server's average and moving average and `LineLegend` (series named "Hushållet" / "Min del", "Snitt", "Glidande snitt (3)"); then body-small `on-surface-variant`: "Snitt <X> i månaden · September 2026: 12 % över snittet" (`analytics_insights_average_per_month` joined by " · " with D-128's `analytics_vs_average_*`), and "Hittills i oktober 2026: <X>" (`analytics_insights_so_far`).
|
||||
4. `ChartCard` "Kategorier per månad" (`analytics_insights_categories`): the open category's chart as in 3, in its category colour, then a radio list of the categories in the server's order (total descending): rows of at least the touch target, `CategoryTile` 32, name (body-large, one line, ellipsis) over "Snitt <X> i månaden", and on the right the last whole month against the average, "+12 %" / "−8 %" / "0 %" (`analytics_insights_change_up`, `_change_down`; label-large muted; none when the average is 0); the open row has a `secondary-container` fill. The open category defaults to the first (the largest total); category ids the phone does not hold are left out.
|
||||
5. With no spending in the 6 months, none this month and no category listed, one card "Inga utgifter de senaste 6 hela månaderna" (`analytics_insights_no_spending`, plural) replaces 3 and 4.
|
||||
6. "Prognos" (title-medium, `analytics_insights_forecast`) over the caption "Återkommande utgifter som förfaller, plus snittet av övriga utgifter de senaste 3 månaderna" (`analytics_insights_forecast_caption`, plural; 3 is D-128's window).
|
||||
7. One card per account in the server's order (archived included): `AccountTile` 32 (muted when archived), the name (title-medium, ellipsis) over "Hittills i oktober 2026: <X>", the "Arkiverat" badge when archived; then the two next months as rows: "November 2026" (body-large) over "Återkommande <X> + snitt <Y>" (`analytics_insights_forecast_parts`), the forecast as `MoneyText(Medium)` on the right. An account with nothing this month and both forecasts 0 shows one line "Inga återkommande utgifter och inga utgifter på sistone" (`analytics_insights_forecast_none`) instead of the rows. Accounts the phone does not hold are left out.
|
||||
|
||||
**Loading**: both reads run in parallel when S-11 opens, when the measure changes to one without data, when the phone comes online, and on "Försök igen"; each measure's data is kept in memory while S-11 is on the back stack, nothing is stored. Before the first data, skeleton cards (a chart card "Utgifter per månad" and an account card with two month rows), read as "Hämtar insikter" (`analytics_insights_loading`).
|
||||
|
||||
**States** (goldens `s11_insights_<state>` in `sv_light`, `sv_dark`, `en_light`, plus `s11_insights_long_sv_light_200`):
|
||||
|
||||
| Golden | State | What differs |
|
||||
|---|---|---|
|
||||
| `loaded` | loaded | household; caption, "Utgifter per månad" with average and moving average |
|
||||
| `loaded_scrolled` | loaded, scrolled | the category chart and list, "Prognos" and the account cards |
|
||||
| `category` | another category open | the chosen category's chart and the selected row |
|
||||
| `my_share` | my share | caption "· Min del", series "Min del" |
|
||||
| `loading` | loading | skeleton cards, no data yet |
|
||||
| `offline` | offline, no data | the "Kräver anslutning" banner only |
|
||||
| `offline_kept` | offline after a load | the banner over the last data |
|
||||
| `unreachable` | failed after a load | error banner with "Försök igen" over the last data |
|
||||
| `unreachable_empty` | failed, no data | the error banner only |
|
||||
| `empty` | no spending | one "Inga utgifter de senaste 6 hela månaderna" card; accounts with the one-line forecast |
|
||||
| `long` | long names and amounts | ellipsized names, whole amounts |
|
||||
| `long_scrolled` | long, scrolled | the forecast cards with long names |
|
||||
| `screen` | whole S-11 | the section below "Per konto" in the S-11 screen |
|
||||
|
||||
**TalkBack**: each chart is one node with D-128's summary sentence (`analytics_summary_line`); category rows are a radio group; each forecast month is one node, "November 2026: <forecast> kronor, återkommande <X> kronor, snitt <Y> kronor" (`analytics_insights_forecast_month_spoken`); the account header row is merged; the skeleton reads "Hämtar insikter".
|
||||
|
||||
### S-12 Analytics drill-down (`:feature:analytics`)
|
||||
|
||||
**Layout** (app bar: back, title formatted from the drill-down arguments: "Mat & hushåll, oktober 2026" / "Vardag, v. 41" / "Oktober 2026" / "Mat & hushåll, maj–okt 2026"; one line, ellipsis; column gap 10):
|
||||
|
||||
@@ -448,6 +448,25 @@ analytics_vs_average_on,%1$s: on average,%1$s: på snittet,module=analytics; S-1
|
||||
analytics_summary_line,"%1$s over time, %2$s: from %3$s in %4$s to %5$s in %6$s, %7$s in total, average %8$s.","%1$s över tid, %2$s: från %3$s i %4$s till %5$s i %6$s, totalt %7$s, snitt %8$s.",module=analytics; TalkBack summary of the S-12 line chart: group; range; first and last bucket; total; average (D-128)
|
||||
analytics_summary_line_single,"%1$s over time, %2$s: %3$s in total.","%1$s över tid, %2$s: totalt %3$s.",module=analytics; TalkBack summary of the S-12 line chart with one bucket (D-128)
|
||||
analytics_range_apply,Apply,Använd,module=analytics; confirm button of the custom range picker; M7e
|
||||
analytics_insights_title,Insights,Insikter,module=analytics; S-11 Insights section heading (D-142)
|
||||
analytics_insights_caption:one,Last %1$d whole month · %2$s,Senaste %1$d hela månaden · %2$s,module=analytics; plural one; S-11 Insights caption: whole months; %2$s the measure (Hushållet / Min del) (D-142)
|
||||
analytics_insights_caption:other,Last %1$d whole months · %2$s,Senaste %1$d hela månaderna · %2$s,module=analytics; plural other
|
||||
analytics_insights_offline_body,Insights are calculated on the server. Connect to the internet to see them.,Insikterna räknas fram på servern. Anslut till internet för att se dem.,module=analytics; S-11 Insights NeedsConnectionBanner text when offline (D-142)
|
||||
analytics_insights_loading,Loading insights,Hämtar insikter,module=analytics; TalkBack label of the Insights skeleton (D-142)
|
||||
analytics_insights_trend,Spending per month,Utgifter per månad,module=analytics; ChartCard title of the household or my-share trend (D-143)
|
||||
analytics_insights_categories,Categories per month,Kategorier per månad,module=analytics; ChartCard title of the per-category trends (D-143)
|
||||
analytics_insights_average_per_month,Average %1$s a month,Snitt %1$s i månaden,module=analytics; %1$s the server's monthly average (D-143)
|
||||
analytics_insights_so_far,So far in %1$s: %2$s,Hittills i %1$s: %2$s,module=analytics; %1$s the current month (lowercase month and year); %2$s its spend so far (D-143)
|
||||
analytics_insights_change_up,+%1$s,+%1$s,module=analytics; category row: last whole month above the average; %1$s a percent (D-143)
|
||||
analytics_insights_change_down,−%1$s,−%1$s,module=analytics; category row: last whole month below the average (U+2212 minus); %1$s a percent (D-143)
|
||||
analytics_insights_no_spending:one,No spending in the last %1$d whole month,Inga utgifter den senaste %1$d hela månaden,module=analytics; plural one; replaces the Insights charts when nothing was spent (D-143)
|
||||
analytics_insights_no_spending:other,No spending in the last %1$d whole months,Inga utgifter de senaste %1$d hela månaderna,module=analytics; plural other
|
||||
analytics_insights_forecast,Forecast,Prognos,module=analytics; Insights forecast heading (D-143)
|
||||
analytics_insights_forecast_caption:one,"Recurring expenses due, plus the average of other spending in the last %1$d month","Återkommande utgifter som förfaller, plus snittet av övriga utgifter den senaste %1$d månaden",module=analytics; plural one; how the forecast is made; %1$d the baseline window in months (D-128's 3) (D-143)
|
||||
analytics_insights_forecast_caption:other,"Recurring expenses due, plus the average of other spending in the last %1$d months","Återkommande utgifter som förfaller, plus snittet av övriga utgifter de senaste %1$d månaderna",module=analytics; plural other
|
||||
analytics_insights_forecast_parts,Recurring %1$s + average %2$s,Återkommande %1$s + snitt %2$s,module=analytics; forecast month row: %1$s recurring due; %2$s the baseline average (D-143)
|
||||
analytics_insights_forecast_none,No recurring expenses and no recent spending,Inga återkommande utgifter och inga utgifter på sistone,module=analytics; forecast card of an account with nothing to forecast (D-143)
|
||||
analytics_insights_forecast_month_spoken,"%1$s: %2$s, recurring %3$s, average %4$s","%1$s: %2$s, återkommande %3$s, snitt %4$s",module=analytics; TalkBack per forecast month: month; forecast; recurring; average (D-143)
|
||||
settings_profile_offline_banner,Needs connection. Your profile can only be changed online.,Kräver anslutning. Profilen kan bara ändras när telefonen är online.,module=settings
|
||||
settings_title,Settings,Inställningar,module=settings
|
||||
settings_role_admin,You · Admin,Du · Administratör,module=settings; S-13 own row when the viewer is the admin
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 156 and column 79.
|
Reference in New Issue
Block a user