Skip to content

feat: per-user dynamic theme - #248

Draft
HammadYousaf01 wants to merge 1 commit into
releasefrom
feat/dynamic-theme
Draft

HammadYousaf01 wants to merge 1 commit into
releasefrom
feat/dynamic-theme

Conversation

@HammadYousaf01

Copy link
Copy Markdown
Collaborator

This PR adds dynamic theming for Indigo, which allows a user to customize their own theme.

Users can now choose between Light and Dark presets and customise five core colors from their Profile settings. Their preferences are saved per user, per preset, and follow them across devices.

What changed

  • Added the new indigo_theme Django app and /api/indigo/v1/theme/ API.
  • Added theme controls to the Account MFE (Plugin slots, might need to be updated when Frontend-base lands)
  • Applied dynamic colours across all MFEs.
  • Hidden the existing header light/dark toggle while dynamic theming is enabled.
  • Added the INDIGO_ENABLE_DYNAMIC_THEME runtime flag, enabled by default.

Learners can pick a Light or Dark preset and personalise five core
Paragon colours from a new "Theme" block in the Profile Information
section of the Account MFE. The choice follows them across devices and
is applied without rebuilding any image.

The new indigo_theme Django app stores the presets and each learner's
preset and colour overrides, and serves them from /api/indigo/v1/theme/.
It is installed into the openedx image and registers itself as a plugin
app, so no edx-platform settings patch is needed. Overrides are kept per
preset, so a colour chosen for Light does not affect Dark.

In the MFEs, IndigoTheme.jsx fetches the theme once per page load,
derives the Paragon shade scales that the compiled brand CSS bakes in as
literal hex, and writes everything into a single style element as :root
custom properties. A username-stamped localStorage cache is applied
before the app boots so there is no flash, and is dropped as soon as the
JWT cookie is missing or names another user.

Legacy LMS pages and the courseware iframe are covered by
dynamic-theme.js, a sibling of dark-theme.js in the LMS theme bundles.
Their stylesheets are compiled from SASS with literal colours, so the
script rewrites the matching declarations in place rather than appending
an override sheet, which would change the cascade.

The appearance choice is saved as soon as it is picked; colours are
previewed live and stored with the "Save" button. The header light/dark
toggle is hidden while the feature is on, since the preset choice
replaces it.

Controlled by INDIGO_ENABLE_DYNAMIC_THEME (default: true). Turning it
off needs no image rebuild: the flag is read at runtime, the block and
the requests disappear, the cached styles are cleared and the header
toggle comes back.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

3 participants