dark_theme: Refactor and consolidate theme setting logic.

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.
This commit is contained in:
Sayam Samal 2024-06-10 15:34:01 +05:30 committed by Tim Abbott
parent b616f013f0
commit 05c61037c8
6 changed files with 69 additions and 78 deletions

View File

@ -1,40 +1,64 @@
import $ from "jquery";
import {localstorage} from "./localstorage";
import {page_params} from "./page_params";
import * as message_lists from "./message_lists";
import * as realm_logo from "./realm_logo";
import * as settings_config from "./settings_config";
import {user_settings} from "./user_settings";
export function enable(): void {
const ls = localstorage();
function enable(): void {
$(":root").removeClass("color-scheme-automatic").addClass("dark-theme");
if (page_params.is_spectator) {
const ls = localstorage();
ls.set("spectator-theme-preference", "dark");
user_settings.color_scheme = settings_config.color_scheme_values.night.code;
realm_logo.render();
}
}
export function disable(): void {
function disable(): void {
$(":root").removeClass("color-scheme-automatic").removeClass("dark-theme");
if (page_params.is_spectator) {
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 {
function default_preference_checker(): void {
$(":root").removeClass("dark-theme").addClass("color-scheme-automatic");
}
if (page_params.is_spectator) {
const ls = localstorage();
ls.set("spectator-theme-preference", "automatic");
user_settings.color_scheme = settings_config.color_scheme_values.automatic.code;
realm_logo.render();
export function set_theme(color_scheme: number): void {
if (color_scheme === settings_config.color_scheme_values.night.code) {
enable();
} else if (color_scheme === settings_config.color_scheme_values.day.code) {
disable();
} else {
// If the color_scheme_code is not valid, fallback to automatic.
default_preference_checker();
}
}
export function set_theme_and_update(color_scheme: number): void {
set_theme(color_scheme);
// We cannot update recipient bar color and the realm logo variant
// using `set_theme` since that function is being called in the
// `ui_init` module before message_lists and realm_logo are initialized
// and the order cannot be changed.
message_lists.update_recipient_bar_background_color();
realm_logo.render();
}
function get_theme_for_spectator(): number {
// If the spectator has not set a theme preference, fallback to automatic.
return (
Number(ls.get("spectator-theme-preference")) ||
settings_config.color_scheme_values.automatic.code
);
}
export function set_theme_for_spectator(color_scheme: number): void {
// Since we don't have events for spectators and handle the theme using
// localstorage, the theme change does not reflect across tabs.
ls.set("spectator-theme-preference", color_scheme);
user_settings.color_scheme = color_scheme;
set_theme_and_update(color_scheme);
}
export function initialize_theme_for_spectator(): void {
const color_scheme = get_theme_for_spectator();
user_settings.color_scheme = color_scheme;
set_theme(color_scheme);
}

View File

@ -6,11 +6,9 @@ import render_navbar_gear_menu_popover from "../templates/popovers/navbar/navbar
import * as blueslip from "./blueslip";
import * as channel from "./channel";
import * as dark_theme from "./dark_theme";
import * as message_lists from "./message_lists";
import * as popover_menus from "./popover_menus";
import * as popover_menus_data from "./popover_menus_data";
import * as popovers from "./popovers";
import * as settings_config from "./settings_config";
import * as settings_preferences from "./settings_preferences";
import {parse_html} from "./ui_util";
@ -158,21 +156,10 @@ export function initialize() {
settings_preferences.launch_default_language_setting_modal();
});
// We cannot update recipient bar color using dark_theme.enable/disable due to
// it being called before message lists are initialized and the order cannot be changed.
// Also, since these buttons are only visible for spectators which doesn't have events,
// if theme is changed in a different tab, the theme of this tab remains the same.
$popper.on("change", "input[name='theme-select']", (e) => {
const theme_code = Number.parseInt($(e.currentTarget).attr("data-theme-code"), 10);
requestAnimationFrame(() => {
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();
dark_theme.set_theme_for_spectator(theme_code);
});
});
},

View File

@ -791,17 +791,7 @@ export function dispatch_normal_event(event) {
}
if (event.property === "color_scheme") {
requestAnimationFrame(() => {
if (event.value === settings_config.color_scheme_values.night.code) {
dark_theme.enable();
realm_logo.render();
} else if (event.value === settings_config.color_scheme_values.day.code) {
dark_theme.disable();
realm_logo.render();
} else {
dark_theme.default_preference_checker();
realm_logo.render();
}
message_lists.update_recipient_bar_background_color();
dark_theme.set_theme_and_update(event.value);
});
}
if (event.property === "starred_message_counts") {

View File

@ -58,7 +58,6 @@ import * as left_sidebar_navigation_area_popovers from "./left_sidebar_navigatio
import * as lightbox from "./lightbox";
import * as linkifiers from "./linkifiers";
import * as local_message from "./local_message";
import {localstorage} from "./localstorage";
import * as markdown from "./markdown";
import * as markdown_config from "./markdown_config";
import * as message_actions_popover from "./message_actions_popover";
@ -423,15 +422,7 @@ export function initialize_everything(state_data) {
sidebar_ui.restore_sidebar_toggle_status();
information_density.initialize();
if (page_params.is_spectator) {
const ls = localstorage();
const preferred_theme = ls.get("spectator-theme-preference");
if (preferred_theme === "dark") {
dark_theme.enable();
} else if (preferred_theme === "light") {
dark_theme.disable();
} else {
dark_theme.default_preference_checker();
}
dark_theme.initialize_theme_for_spectator();
}
i18n.initialize({language_list: page_params.language_list});

View File

@ -7,7 +7,7 @@ import * as dark_theme from "./dark_theme";
import * as feedback_widget from "./feedback_widget";
import {$t} from "./i18n";
import * as markdown from "./markdown";
import * as message_lists from "./message_lists";
import * as settings_config from "./settings_config";
/*
@ -68,8 +68,7 @@ export function switch_to_light_theme(): void {
on_success(raw_data) {
const data = data_schema.parse(raw_data);
requestAnimationFrame(() => {
dark_theme.disable();
message_lists.update_recipient_bar_background_color();
dark_theme.set_theme_and_update(settings_config.color_scheme_values.day.code);
});
feedback_widget.show({
populate($container) {
@ -94,8 +93,7 @@ export function switch_to_dark_theme(): void {
on_success(raw_data) {
const data = data_schema.parse(raw_data);
requestAnimationFrame(() => {
dark_theme.enable();
message_lists.update_recipient_bar_background_color();
dark_theme.set_theme_and_update(settings_config.color_scheme_values.night.code);
});
feedback_widget.show({
populate($container) {

View File

@ -965,26 +965,37 @@ run_test("user_settings", ({override}) => {
dispatch(event);
assert_same(user_settings.web_line_height_percent, 130);
override(realm_logo, "render", noop);
{
const stub = make_stub();
event = event_fixtures.user_settings__color_scheme_automatic;
user_settings.color_scheme = 2;
override(dark_theme, "set_theme_and_update", stub.f); // automatically checks if called
dispatch(event);
const args = stub.get_args("color_scheme_code");
assert.equal(stub.num_calls, 1);
assert.equal(user_settings.color_scheme, args.color_scheme_code);
}
{
const stub = make_stub();
event = event_fixtures.user_settings__color_scheme_dark;
user_settings.color_scheme = 1;
override(dark_theme, "enable", stub.f); // automatically checks if called
override(dark_theme, "set_theme_and_update", stub.f); // automatically checks if called
dispatch(event);
const args = stub.get_args("color_scheme_code");
assert.equal(stub.num_calls, 1);
assert.equal(user_settings.color_scheme, 2);
assert.equal(user_settings.color_scheme, args.color_scheme_code);
}
{
const stub = make_stub();
event = event_fixtures.user_settings__color_scheme_light;
user_settings.color_scheme = 1;
override(dark_theme, "disable", stub.f); // automatically checks if called
override(dark_theme, "set_theme_and_update", stub.f); // automatically checks if called
dispatch(event);
const args = stub.get_args("color_scheme_code");
assert.equal(stub.num_calls, 1);
assert.equal(user_settings.color_scheme, 3);
assert.equal(user_settings.color_scheme, args.color_scheme_code);
}
{
@ -1008,16 +1019,6 @@ run_test("user_settings", ({override}) => {
assert.equal(user_settings.web_home_view, "inbox");
}
{
const stub = make_stub();
event = event_fixtures.user_settings__color_scheme_automatic;
user_settings.color_scheme = 2;
override(dark_theme, "default_preference_checker", stub.f); // automatically checks if called
dispatch(event);
assert.equal(stub.num_calls, 1);
assert.equal(user_settings.color_scheme, 1);
}
{
const stub = make_stub();
event = event_fixtures.user_settings__emojiset;