Skip to content

feat: Themes - #75

Merged
keenthekeen merged 18 commits into
masterfrom
themes
Oct 11, 2026
Merged

keenthekeen merged 18 commits into
masterfrom
themes

Conversation

@Punnawit9285

Copy link
Copy Markdown
Member

This should solve issue #14

Replaces the fixed colours with semantic --flick-* tokens that a theme fills in. A theme sets a few colours, and the palette works out the rest, including readable text on every background.

Themes.demo.mov

This is rework for #52 no hard-coded colours and no colour-specific names.
(I took all advices from P'Ken in there, thanks again kub!)

  • Theme menu: in the home, year and course toolbars and on the welcome page. It offers Light, Dark, System (follows the device) and Custom.

  • Theme editor:

    • Ready-made themes: the MDCU color themes and seven colour templates.
    • Primary, Secondary and Background colours, each changing only itself.
  • Background picture:

    • Kept on the device in IndexedDB and never uploaded.
    • You can add several pictures and show one or run them as a slideshow (every 1 minute to 1 day, in order or shuffled).
    • Deleting a picture asks first.
  • Pages: the course, year, welcome and home pages use the tokens instead of fixed colours. Year colours come from the theme as var(--flick-series-N).

  • Sync: the theme and saved colours sync across devices through FlickMan's v1/user_settings. Pictures stay on the device.

  • Restore default settings: puts the theme back to plain light, through RestoreDefaultsService. This works without the settings PR too.

P.S.

Merging: this can be merged alone or with the settings and heatmap PRs, in any order. The files they share (user-sync.service.ts and its spec, the ManService additions and restore-defaults.service.ts) are identical on every branch. Where the branches edit the same page, they change different lines. I checked every combination on master: none of them conflict, and lint, build and tests all pass.

Needs docchula/FlickMan#23 for sync. Until it's deployed, sync turns itself off after the first failed read, and the theme is saved on the device only.

Replaces #52.

Punnawit9285 and others added 18 commits September 5, 2026 10:30
Replace the fixed palette with semantic tokens that a theme definition fills in,
so colours come from data rather than from rules scattered through the
stylesheets. A theme sets an accent and a surface, and the palette derives the
rest, including the contrasting text colour for each generated background.

Adds an appearance menu for choosing a mode, an editor for adjusting a custom
theme, and an optional background image kept on the device that uploaded it.
Preferences are stored per user and applied before first paint so the page does
not flash the previous colours.

Course, list, welcome and home pages read the tokens instead of hard-coded
values, which is what lets a theme restyle them without touching each page.
- Light, dark and fill shades for a custom theme, remembered per colour and template
- Save and delete colours on the device, beside the pre-made templates
- Pin the pre-made pink theme to its exact palette as template data
- Softer course colours, with one label colour across the row
- Animate theme changes on a single clock by registering the colour variables
- Colour ion-list-header from the theme
- Fix contrast helpers moving the wrong way, and judging contrast before rounding
- Fix flat surfaces on a page filled with the theme colour
The theme and saved colours travel in the account's userSettings
document; the newest device wins. The picture stays on the device that
chose it. Edits are sent once they settle, so dragging a slider or a
colour picker costs one write.

Also show the selected shade and fit on iOS, where the chosen segment is
filled with the same colour as its label.
The interval is remembered on the device, so reloading the page no
longer starts it again. That puts a hard ceiling of 48 study writes per
device per day; what is held back is still sent on the next open.
Restore default settings in the settings sheet now resets the theme as
well: light mode, the default colours, and no background picture. The
signal comes through RestoreDefaultsService, a file shared byte for byte
with the settings branch, so neither branch depends on the other.
Adding a picture no longer clears out the last one. Every picture stays
in a folder on the device until the user deletes it, which the editor
asks to confirm; restoring defaults or resetting the theme only stops
showing it. The editor shows the folder as thumbnails, takes several
pictures at once, and offers None, Picture or Slideshow, as Windows does
for the desktop.

The slideshow changes picture every 1 minute to 1 day, in the order the
pictures were added or shuffled, with each picture shown once per round
and never twice running. Timing is anchored to when it was started, so
a reload lands on the same picture and a hidden tab catches up when it
returns. Each change fades the old picture out and the new one in,
except with reduced motion.

Like the pictures, these choices stay on the device and are not synced.
A theme saved with a picture before this change comes back showing it.
The editor opens as a sheet that stops at 90% of the screen, but its
content was laid out for the full height, so the last part could never
be scrolled into view. With expandToScroll off the content scrolls
within the sheet at any height.
The colours did not do what they said. "Secondary" was the accent, and
picking it also re-derived the page, flipped the shade and threw away
the page colour; dragging the picker across light and dark made the
page jump between shades. A dark page colour on the light shade was
drawn with the light palette's roles and course colours.

Each colour now changes only itself. Primary is the accent: buttons,
links, switches and the heatmap. Secondary is its own colour, or Auto
to follow the primary. Background is Light or Dark, tinted with the
primary, or any colour used exactly. Whether text is dark or light
follows the page, so a dark page always gets a dark palette. Light and
Dark now always tint rather than turning the primary itself into the
page when it happens to be that light or dark.

The editor goes from eight sections to three: the ready-made themes,
now named, one palette for whichever colour is being set, with the
quick and saved colours together, and the background picture. The
separate shade, plain-mode and saved-colour sections are gone, along
with the per-colour shade memory that only the shade control used.
…ates

Light and Dark now sit under the Primary colour with a hint that they only shape the custom theme; the app's own modes stay in the theme menu. Background offers Auto to hand the page back to the primary colour. Adds Red, Orange, Gold, Teal, Blue, Purple and Slate templates in their own row, with swatches showing page and accent.
- remove custom theme shade hint text
- restore plain light mode on reset theme preference
- remove Green & Pink preset and keep Pink & Green
- rename brand preset group to MDCU
Master's tests expected colorByFolderName to return fixed hex colours.
On this branch the year colours come from the theme as
var(--flick-series-N) tokens, so the tests check the token for each
case instead, and that each colour comes with its text colour. The
values the standard themes give those tokens are checked in
palette.spec.ts.
…branch

- re-anchor theme menu button in home, list and course toolbars
- adjust global theme rules to avoid overlaps with settings stylesheets
…ontrols

- wrap slideshow and image adjustment controls in .control-card with borders and rounded corners
- restore generous horizontal inset padding to .control-item
- set labelPlacement and justify attributes on select and toggle
- align popover menu inward with popoverOptions
- improve hint typography and spacing
- read and save the synced settings through FlickMan's v1/user_settings, so no Firestore rule is needed
- wait for the ID token before the first read, so sync is not switched off while sign-in finishes
- add getUserSettings and saveUserSettings to ManService
# Conflicts:
#	src/app/home/home.page.scss
#	src/app/home/home.page.ts
#	src/helpers.spec.ts
Ionic 9 (#74) dropped @ionic/angular/standalone, so the theme menu and
editor now import from @ionic/angular like the rest of the app.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@keenthekeen
keenthekeen merged commit 4c41f25 into master Oct 11, 2026
4 checks passed
@keenthekeen
keenthekeen deleted the themes branch October 11, 2026 10:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants