Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gear_menu: Add theme switcher to the gear menu popover. #30334

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

sayamsamal
Copy link
Collaborator

@sayamsamal sayamsamal commented Jun 6, 2024

This PR improves the theme experience for spectators by:

  • Adding a Theme Switcher: Replaces separate light/dark theme options with the new 3-way theme switcher in the gear menu popover, standardizing theme selection across the app.
  • Updating the Realm Logo: Ensures the realm logo dynamically updates on theme change without requiring a page reload.
  • Supporting Automatic Color Scheme: Implements automatic color scheme support by storing the user's preference in local storage, mirroring the light/dark theme functionality.

Fixes: #30318

Screenshots and screen captures:

Desc Before After
Light Mode gear-menu-before-light gear-menu-after-light
Dark Mode gear-menu-before-dark gear-menu-after-dark
Dynamic Realm Logo on theme change realm-icon-before realm-icon-after
Self-review checklist
  • Self-reviewed the changes for clarity and maintainability
    (variable names, code reuse, readability, etc.).

Communicate decisions, questions, and potential concerns.

  • Explains differences from previous plans (e.g., issue description).
  • Highlights technical choices and bugs encountered.
  • Calls out remaining decisions and concerns.
  • Automated tests verify logic where appropriate.

Individual commits are ready for review (see commit discipline).

  • Each commit is a coherent idea.
  • Commit message(s) explain reasoning and motivation for changes.

Completed manual review and testing of the following:

  • Visual appearance of the changes.
  • Responsiveness and internationalization.
  • Strings and tooltips.
  • End-to-end functionality of buttons, interactions and flows.
  • Corner cases, error conditions, and easily imagined bugs.

@zulipbot zulipbot added size: L area: public access Issues related to logged-out access in Zulip priority: high labels Jun 6, 2024
Copy link

sentry-io bot commented Jun 6, 2024

🔍 Existing Issues For Review

Your pull request is modifying functions with the following pre-existing issues:

📄 File: web/src/ui_init.js

Function Unhandled Issue
initialize_everything Error: Unknown user_id in get_by_user_id: 31266 g...
Event Count: 9 Affected Users: 3
initialize_everything TypeError: p()("input.stream-list-filter").expectOne is not a function. (In 'p()("input.stream-list-filter")... ...
Event Count: 2 Affected Users: 3
initialize_everything ReferenceError: Can't find variable: ResizeObserver compose_setup(src/compose_set...
Event Count: 1 Affected Users: 2

Did you find this useful? React with a 👍 or 👎

@sayamsamal sayamsamal requested a review from amanagr June 6, 2024 10:40
@sayamsamal sayamsamal added the maintainer review PR is ready for review by Zulip maintainers. label Jun 6, 2024
@sayamsamal
Copy link
Collaborator Author

@amanagr Could you please review this PR? Thanks!

@@ -22,9 +24,17 @@ export function disable(): void {
const ls = localstorage();
ls.set("spectator-theme-preference", "light");
user_settings.color_scheme = settings_config.color_scheme_values.day.code;
realm_logo.render();
}
}

export function default_preference_checker(): void {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rename this function and library? dark_theme.default_preference_checker is a weird thing to call.

I would prefer it to be called theme.use_system_default instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's open a czo thread to weight in opinion from others.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened a CZO thread discussing this idea, thanks!

Comment on lines 35 to 38
const ls = localstorage();
ls.set("spectator-theme-preference", "automatic");
user_settings.color_scheme = settings_config.color_scheme_values.automatic.code;
realm_logo.render();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's extract this into a function since it seems like it would make this easier to look at and of course has the benefit of DRY.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted this and other such methods for setting spectator theme into dark_theme.set_theme_for_spectator().

Comment on lines 166 to 175
const theme_code = Number.parseInt($(e.currentTarget).attr("data-theme-code"), 10);
requestAnimationFrame(() => {
dark_theme.disable();
if (theme_code === settings_config.color_scheme_values.night.code) {
dark_theme.enable();
} else if (theme_code === settings_config.color_scheme_values.day.code) {
dark_theme.disable();
} else {
dark_theme.default_preference_checker();
}
message_lists.update_recipient_bar_background_color();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this call inside dark_theme and calling it in the server events dispatch path too.

Copy link
Collaborator Author

@sayamsamal sayamsamal Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the CSS class logic into dark_theme.set_theme() and added dark_theme.set_theme_and_update(), which calls set_theme() and also calls the realm logo and recipient bar update methods. The idea is that all theme switchers and commands call dark_theme.set_theme_and_update(), which will set the theme and also update the necessary elements. While dark_theme.set_theme() is used in ui_init.js to only set the theme via the CSS classes, since the theme is set before the message list and the realm logo are initialised.

@@ -12,6 +13,7 @@ export function enable(): void {
const ls = localstorage();
ls.set("spectator-theme-preference", "dark");
user_settings.color_scheme = settings_config.color_scheme_values.night.code;
realm_logo.render();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering why we don't need realm_logo.render(); call for logged-in users and it seems like we do, so we move the call inside these enable/ disable functions as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks! Moved realm_logo.render() along with message_lists.update_recipient_bar_background_color() into dark_theme module.

@amanagr
Copy link
Member

amanagr commented Jun 6, 2024

@sayamsamal thanks for working on this! Looks like this library and the code surrounding it needs some long due cleanup. Let's make it happen!

sayamsamal and others added 7 commits June 20, 2024 01:13
Similar to the light/dark theme support for the spectators, this adds
the automatic color scheme support by storing the user's preference
in the local storage.
Before this, the realm logo was not being updated instantly when the
theme was changed through the gear menu, and instead required a page
reload to take effect.
Standardize theme selection across the web app by replacing separate
light/dark theme menu options being used in the spectator view with the
new 3-way theme switcher.

Fixes zulip#30318.
This commit centralizes the logic for setting a user's theme preference,
both for regular users and spectators, into the `dark_theme.ts` module.
This simplifies theme handling throughout the codebase and ensures that
the theme is set consistently across all modules.

Instead of relying on various call sites to update the recipient bar's
background color and switch between the light/dark realm logo after a
theme change, this commit modifies the `set_theme_and_update` function
to include these calls after every theme change. Before this commit,
some modules used to update the realm logo after a theme change, while
others did not. This led to inconsistencies in the UI depending on
which method was used to change the theme.
The dark_theme module now contains logic for light, dark, and automatic
theme switching. Thus, we rename it a more generic name, `theme.ts`.
As a follow-up to the previous commit renaming the `dark_theme.ts`
module to `theme.ts`, this commit renames the following functions:
- `enable` -> `set_dark_theme`
- `disable` -> `set_light_theme`
- `default_preference_checker` -> `set_automatic_theme`
This commit standardizes the naming of the day and night themes to light
and dark, respectively. This makes the codebase more consistent with
the naming used in the settings and the user interface.
@zulipbot
Copy link
Member

Heads up @sayamsamal, we just merged some commits that conflict with the changes you made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the upstream/main branch and resolve your pull request's merge conflicts accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: public access Issues related to logged-out access in Zulip has conflicts maintainer review PR is ready for review by Zulip maintainers. priority: high size: XL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement automatic theme switcher for spectators
3 participants