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

Add frontend "color mode" state to the ui cookie #4308

Open
zackkrida opened this issue May 10, 2024 · 0 comments
Open

Add frontend "color mode" state to the ui cookie #4308

zackkrida opened this issue May 10, 2024 · 0 comments
Labels
💻 aspect: code Concerns the software code in the repository 🌟 goal: addition Addition of new feature 🟨 priority: medium Not blocking but should be addressed soon 🧱 stack: frontend Related to the Nuxt frontend

Comments

@zackkrida
Copy link
Member

zackkrida commented May 10, 2024

This issue is part of the Dark Mode project: #3592. Please see the implementation plan for additional detail and context.

Important

The implementation plan originally specified storing a systemValue representing the actual media query value of "prefers-color-scheme" in the color mode state. This was deemed unnecessary and removed in this issue.

The implementation plan also called for, eventually, adding detection in our infrastructure to bypass caching when a dark/light mode cookie was present for the user. By using the existing ui cookie, we bypass the need for any infrastructure changes here.

Update the frontend UI store to include a colorMode. This is a representation of whether the site should display in "light", "dark", or "system" (the default) color mode. We need functionality to:

  • Retrieve the current color mode from the ui cookie. Override this preference if the force_dark_mode feature flag from Add a feature flag to force dark mode #4303 is on.
  • Set the color mode, saving it to the ui cookie. The eventual dark mode UI toggle will use this method.
  • Additionally, the mechanism to set the body class .light-mode or .dark-mode added in Add a feature flag to force dark mode #4303 needs to be updated to read from the ui store.

Here is a diff that should represent the necessary changes to the store and cookie. Please update tests as well to accompany these changes.

diff --git a/frontend/src/stores/ui.ts b/frontend/src/stores/ui.ts
index 6c09abb64..650f5548a 100644
--- a/frontend/src/stores/ui.ts
+++ b/frontend/src/stores/ui.ts
@@ -8,10 +8,14 @@ import { ALL_SCREEN_SIZES } from "~/constants/screens"
 import { cookieOptions } from "~/utils/cookies"
 import { needsTranslationBanner } from "~/utils/translation-banner"
 
+import { useFeatureFlagStore } from "./feature-flag"
+
 import type { LocaleObject } from "@nuxtjs/i18n"
 
 const desktopBreakpoints: RealBreakpoint[] = ["2xl", "xl", "lg"]
 
+type ColorMode = "dark" | "light" | "system"
+
 export interface UiState {
   /**
    * whether to show the instructions snackbar.
@@ -47,6 +51,8 @@ export interface UiState {
   shouldBlurSensitive: boolean
   /* A list of sensitive single result UUIDs the user has opted-into seeing */
   revealedSensitiveResults: string[]
+  /* Whether the UI is using dark, light, or system mode */
+  colorMode: ColorMode
 }
 
 export const breakpoints = Object.keys(ALL_SCREEN_SIZES)
@@ -61,6 +67,7 @@ export const useUiStore = defineStore("ui", {
     dismissedBanners: [],
     shouldBlurSensitive: true,
     revealedSensitiveResults: [],
+    colorMode: "system",
   }),
 
   getters: {
@@ -70,6 +77,7 @@ export const useUiStore = defineStore("ui", {
         isFilterDismissed: state.isFilterDismissed,
         breakpoint: state.breakpoint,
         dismissedBanners: Array.from(this.dismissedBanners),
+        colorMode: state.colorMode,
       }
     },
     areInstructionsVisible(state): boolean {
@@ -125,6 +133,14 @@ export const useUiStore = defineStore("ui", {
     shouldShowAnalyticsBanner(): boolean {
       return !this.dismissedBanners.includes("analytics")
     },
+    currentColorMode(state): ColorMode {
+      const featureFlagStore = useFeatureFlagStore()
+      if (featureFlagStore.isOn("force_dark_mode")) {
+        return "dark"
+      }
+      // Return the cookie value otherwise
+      return state.colorMode
+    },
   },
 
   actions: {
@@ -176,6 +192,13 @@ export const useUiStore = defineStore("ui", {
         this.dismissedBanners = cookies.dismissedBanners
       }
 
+      if (
+        typeof cookies.colorMode === "string" &&
+        ["dark", "light", "system"].includes(cookies.colorMode)
+      ) {
+        this.colorMode = cookies.colorMode as ColorMode
+      }
+
       this.writeToCookie()
     },
     /**
@@ -255,5 +278,9 @@ export const useUiStore = defineStore("ui", {
       this.shouldBlurSensitive = value
       this.revealedSensitiveResults = []
     },
+    setColorMode(preference: "dark" | "light" | "system") {
+      this.colorMode = preference
+      this.writeToCookie()
+    },
   },
 })
diff --git a/frontend/src/types/cookies.ts b/frontend/src/types/cookies.ts
index b64d419ca..6acd86e72 100644
--- a/frontend/src/types/cookies.ts
+++ b/frontend/src/types/cookies.ts
@@ -39,6 +39,10 @@ export interface OpenverseCookieState {
      * The list of ids of dismissed banners.
      */
     dismissedBanners?: BannerId[]
+    /**
+     * A string representing the color scheme the site should use.
+     */
+    colorMode?: string
   }
   /**
    * The state of the persistent feature flags.
@zackkrida zackkrida added 🟨 priority: medium Not blocking but should be addressed soon 🌟 goal: addition Addition of new feature 💻 aspect: code Concerns the software code in the repository 🧱 stack: frontend Related to the Nuxt frontend labels May 10, 2024
@zackkrida zackkrida added this to the Dark Mode B - Toggle milestone May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💻 aspect: code Concerns the software code in the repository 🌟 goal: addition Addition of new feature 🟨 priority: medium Not blocking but should be addressed soon 🧱 stack: frontend Related to the Nuxt frontend
Projects
Status: 📋 Backlog
Development

No branches or pull requests

1 participant