From 296554feaef798b3778deafc9d940939e21696c3 Mon Sep 17 00:00:00 2001 From: Ben White Date: Wed, 20 Dec 2023 15:50:03 +0100 Subject: [PATCH] feat: Change default theme to light (#19444) --- .../src/layout/navigation-3000/themeLogic.ts | 18 +++++++++------ .../CommandPalette/commandPaletteLogic.tsx | 2 +- .../scenes/settings/user/ThemeSwitcher.tsx | 6 ++--- frontend/src/scenes/userLogic.ts | 9 +++++++- frontend/src/types.ts | 5 +++-- latest_migrations.manifest | 4 ++-- .../migrations/0378_alter_user_theme_mode.py | 22 +++++++++++++++++++ posthog/models/user.py | 1 + 8 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 posthog/migrations/0378_alter_user_theme_mode.py diff --git a/frontend/src/layout/navigation-3000/themeLogic.ts b/frontend/src/layout/navigation-3000/themeLogic.ts index 22b482d34662c..205e56aa099ce 100644 --- a/frontend/src/layout/navigation-3000/themeLogic.ts +++ b/frontend/src/layout/navigation-3000/themeLogic.ts @@ -9,7 +9,7 @@ import type { themeLogicType } from './themeLogicType' export const themeLogic = kea([ path(['layout', 'navigation-3000', 'themeLogic']), connect({ - values: [featureFlagLogic, ['featureFlags'], userLogic, ['user']], + values: [featureFlagLogic, ['featureFlags'], userLogic, ['themeMode']], }), actions({ syncDarkModePreference: (darkModePreference: boolean) => ({ darkModePreference }), @@ -24,8 +24,8 @@ export const themeLogic = kea([ }), selectors({ isDarkModeOn: [ - (s) => [s.user, s.darkModeSystemPreference, s.featureFlags, sceneLogic.selectors.sceneConfig], - (user, darkModeSystemPreference, featureFlags, sceneConfig) => { + (s) => [s.themeMode, s.darkModeSystemPreference, s.featureFlags, sceneLogic.selectors.sceneConfig], + (themeMode, darkModeSystemPreference, featureFlags, sceneConfig) => { // NOTE: Unauthenticated users always get the light mode until we have full support across onboarding flows if ( sceneConfig?.layout === 'plain' || @@ -34,12 +34,16 @@ export const themeLogic = kea([ ) { return false } + // Dark mode is a PostHog 3000 feature - // User-saved preference is used when set, oterwise we fall back to the system value + if (featureFlags[FEATURE_FLAGS.POSTHOG_3000] !== 'test') { + return false + } + return featureFlags[FEATURE_FLAGS.POSTHOG_3000] === 'test' - ? user?.theme_mode - ? user.theme_mode === 'dark' - : darkModeSystemPreference + ? themeMode === 'system' + ? darkModeSystemPreference + : themeMode === 'dark' : false }, ], diff --git a/frontend/src/lib/components/CommandPalette/commandPaletteLogic.tsx b/frontend/src/lib/components/CommandPalette/commandPaletteLogic.tsx index 3ccf73e40286a..27eaae39e8774 100644 --- a/frontend/src/lib/components/CommandPalette/commandPaletteLogic.tsx +++ b/frontend/src/lib/components/CommandPalette/commandPaletteLogic.tsx @@ -927,7 +927,7 @@ export const commandPaletteLogic = kea([ icon: IconLaptop, display: 'Sync with system preferences', executor: () => { - actions.updateUser({ theme_mode: null }) + actions.updateUser({ theme_mode: 'system' }) }, }, ], diff --git a/frontend/src/scenes/settings/user/ThemeSwitcher.tsx b/frontend/src/scenes/settings/user/ThemeSwitcher.tsx index 106713a616793..a96feb61c8f48 100644 --- a/frontend/src/scenes/settings/user/ThemeSwitcher.tsx +++ b/frontend/src/scenes/settings/user/ThemeSwitcher.tsx @@ -7,17 +7,17 @@ export function ThemeSwitcher({ onlyLabel, ...props }: Partial> & { onlyLabel?: boolean }): JSX.Element { - const { user } = useValues(userLogic) + const { themeMode } = useValues(userLogic) const { updateUser } = useActions(userLogic) return ( , value: null, label: `Sync with system` }, + { icon: , value: 'system', label: `Sync with system` }, { icon: , value: 'light', label: 'Light mode' }, { icon: , value: 'dark', label: 'Dark mode' }, ]} - value={user?.theme_mode} + value={themeMode} renderButtonContent={(leaf) => { const labelText = leaf ? leaf.label : 'Sync with system' return onlyLabel ? ( diff --git a/frontend/src/scenes/userLogic.ts b/frontend/src/scenes/userLogic.ts index 7bc8275f8594c..d3673d9718c33 100644 --- a/frontend/src/scenes/userLogic.ts +++ b/frontend/src/scenes/userLogic.ts @@ -8,7 +8,7 @@ import { lemonToast } from 'lib/lemon-ui/lemonToast' import { getAppContext } from 'lib/utils/getAppContext' import posthog from 'posthog-js' -import { AvailableFeature, OrganizationBasicType, ProductKey, UserType } from '~/types' +import { AvailableFeature, OrganizationBasicType, ProductKey, UserTheme, UserType } from '~/types' import type { userLogicType } from './userLogicType' @@ -232,6 +232,13 @@ export const userLogic = kea([ ) || [] : [], ], + + themeMode: [ + (s) => [s.user], + (user): UserTheme => { + return user?.theme_mode || 'light' + }, + ], }), afterMount(({ actions }) => { const preloadedUser = getAppContext()?.current_user diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 74dd4c96380fd..31fd16548269b 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -165,6 +165,8 @@ export interface SceneDashboardChoice { dashboard: number | DashboardBasicType } +export type UserTheme = 'light' | 'dark' | 'system' + /** Full User model. */ export interface UserType extends UserBaseType { date_joined: string @@ -186,8 +188,7 @@ export interface UserType extends UserBaseType { has_social_auth: boolean has_seen_product_intro_for?: Record scene_personalisation?: SceneDashboardChoice[] - /** Null means "sync with system". */ - theme_mode: 'light' | 'dark' | null + theme_mode?: UserTheme | null } export interface NotificationSettings { diff --git a/latest_migrations.manifest b/latest_migrations.manifest index 13510a650acfe..5a6f653aeef6e 100644 --- a/latest_migrations.manifest +++ b/latest_migrations.manifest @@ -5,7 +5,7 @@ contenttypes: 0002_remove_content_type_name ee: 0015_add_verified_properties otp_static: 0002_throttling otp_totp: 0002_auto_20190420_0723 -posthog: 0377_flatpersonoverride +posthog: 0378_alter_user_theme_mode sessions: 0001_initial social_django: 0010_uid_db_index -two_factor: 0007_auto_20201201_1019 \ No newline at end of file +two_factor: 0007_auto_20201201_1019 diff --git a/posthog/migrations/0378_alter_user_theme_mode.py b/posthog/migrations/0378_alter_user_theme_mode.py new file mode 100644 index 0000000000000..fca384ae53435 --- /dev/null +++ b/posthog/migrations/0378_alter_user_theme_mode.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2.19 on 2023-12-20 12:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("posthog", "0377_flatpersonoverride"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="theme_mode", + field=models.CharField( + blank=True, + choices=[("light", "Light"), ("dark", "Dark"), ("system", "System")], + max_length=20, + null=True, + ), + ), + ] diff --git a/posthog/models/user.py b/posthog/models/user.py index 331f0089f72fe..17a7e176a71bc 100644 --- a/posthog/models/user.py +++ b/posthog/models/user.py @@ -118,6 +118,7 @@ def events_column_config_default() -> Dict[str, Any]: class ThemeMode(models.TextChoices): LIGHT = "light", "Light" DARK = "dark", "Dark" + SYSTEM = "system", "System" class User(AbstractUser, UUIDClassicModel):