diff --git a/.circleci/config.yml b/.circleci/config.yml index d01ba41737..c52f8ec408 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -107,11 +107,19 @@ jobs: keys: - v1-dependencies-{{ checksum "frontend/deps.edn"}}-{{ checksum "frontend/yarn.lock" }} + - run: + name: "install dependencies" + working_directory: "./frontend" + # We install playwright here because the dependent tasks + # uses the same cache as this task so we prepopulate it + command: | + yarn install + yarn run playwright install chromium + - run: name: "lint scss on frontend" working_directory: "./frontend" command: | - yarn install yarn run lint:scss - run: @@ -125,6 +133,7 @@ jobs: - ~/.m2 - ~/.yarn - ~/.gitlibs + - ~/.cache/ms-playwright key: v1-dependencies-{{ checksum "frontend/deps.edn"}}-{{ checksum "frontend/yarn.lock" }} test-components: diff --git a/frontend/src/app/main.cljs b/frontend/src/app/main.cljs index 809f1bce33..9841652bfd 100644 --- a/frontend/src/app/main.cljs +++ b/frontend/src/app/main.cljs @@ -27,7 +27,6 @@ [app.plugins :as plugins] [app.util.dom :as dom] [app.util.i18n :as i18n] - [app.util.theme :as theme] [beicon.v2.core :as rx] [debug] [features] @@ -96,8 +95,7 @@ (cur/init-styles) (thr/init!) (init-ui) - (st/emit! (theme/initialize) - (plugins/initialize) + (st/emit! (plugins/initialize) (initialize))) (defn ^:export reinit diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index 8a55c93573..d5c63a97c5 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -28,7 +28,6 @@ [app.main.ui.onboarding.team-choice :refer [onboarding-team-modal]] [app.main.ui.releases :refer [release-notes-modal]] [app.main.ui.static :as static] - [app.util.dom :as dom] [app.util.i18n :refer [tr]] [app.util.theme :as theme] [beicon.v2.core :as rx] @@ -358,13 +357,10 @@ [] (let [route (mf/deref refs/route) edata (mf/deref refs/exception) - profile (mf/deref refs/profile) - profile-theme (:theme profile) - system-theme (mf/deref theme/preferred-color-scheme)] + profile (mf/deref refs/profile)] - (mf/with-effect [profile-theme system-theme] - (dom/set-html-theme-color - (if (= profile-theme "system") system-theme profile-theme))) + ;; initialize themes + (theme/use-initialize profile) [:& (mf/provider ctx/current-route) {:value route} [:& (mf/provider ctx/current-profile) {:value profile} diff --git a/frontend/src/app/main/ui/settings/options.cljs b/frontend/src/app/main/ui/settings/options.cljs index 5efb157d9b..5d3ff406e9 100644 --- a/frontend/src/app/main/ui/settings/options.cljs +++ b/frontend/src/app/main/ui/settings/options.cljs @@ -14,6 +14,7 @@ [app.main.ui.components.forms :as fm] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] + [app.util.theme :as theme] [rumext.v2 :as mf])) (def ^:private schema:options-form @@ -37,6 +38,7 @@ (let [profile (mf/deref refs/profile) initial (mf/with-memo [profile] (update profile :lang #(or % ""))) + form (fm/use-form :schema schema:options-form :initial initial)] @@ -58,7 +60,7 @@ [:div {:class (stl/css :fields-row)} [:& fm/select {:label (tr "dashboard.select-ui-theme") :name :theme - :default "default" + :default theme/default :options [{:label (tr "dashboard.select-ui-theme.dark") :value "dark"} {:label (tr "dashboard.select-ui-theme.light") :value "light"} {:label (tr "dashboard.select-ui-theme.system") :value "system"}] diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index e150c44d6c..b629631de1 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -70,17 +70,6 @@ [^string title] (set! (.-title globals/document) title)) -(defn set-html-lang! - [^string lang] - (.setAttribute (.querySelector js/document "html") "lang" lang)) - -(defn set-html-theme-color - [^string color] - (let [node (.querySelector js/document "body") - class (if (= color "dark") "default" "light")] - (.removeAttribute node "class") - (.add ^js (.-classList ^js node) class))) - (defn set-page-style! [styles] (let [node (first (get-elements-by-tag globals/document "head")) diff --git a/frontend/src/app/util/theme.cljs b/frontend/src/app/util/theme.cljs index de3a25a813..eb5723b85c 100644 --- a/frontend/src/app/util/theme.cljs +++ b/frontend/src/app/util/theme.cljs @@ -6,33 +6,37 @@ (ns app.util.theme (:require + [app.common.data :as d] [app.util.globals :as globals] [beicon.v2.core :as rx] - [potok.v2.core :as ptk])) + [rumext.v2 :as mf])) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Set the preferred color scheme based on the user's system settings. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defonce ^:private color-scheme-mq +(defonce ^:private color-scheme-media-query (.matchMedia globals/window "(prefers-color-scheme: dark)")) -;; This atom is referenced in app.main.ui.app -(defonce preferred-color-scheme - (atom (if (.-matches color-scheme-mq) "dark" "light"))) +(def ^:const default "dark") -(defonce prefers-color-scheme-sub - (let [sub (rx/behavior-subject "dark") - ob (->> (rx/from-event color-scheme-mq "change") - (rx/map #(if (.-matches %) "dark" "light")))] - (rx/sub! ob sub) - sub)) +(defn- set-color-scheme + [^string color] -(defn initialize - [] - (ptk/reify ::initialize - ptk/WatchEvent - (watch [_ _ _] - (->> prefers-color-scheme-sub - (rx/map #(reset! preferred-color-scheme %)))))) \ No newline at end of file + (let [node (.querySelector js/document "body") + class (if (= color "dark") "default" "light")] + (.removeAttribute node "class") + (.add ^js (.-classList ^js node) class))) + +(defn use-initialize + [{profile-theme :theme}] + (let [system-theme* (mf/use-state #(if (.-matches color-scheme-media-query) "dark" "light")) + system-theme (deref system-theme*)] + + (mf/with-effect [] + (let [s (->> (rx/from-event color-scheme-media-query "change") + (rx/map #(if (.-matches %) "dark" "light")) + (rx/subs! #(reset! system-theme* %)))] + (fn [] + (rx/dispose! s)))) + + (mf/with-effect [system-theme profile-theme] + (set-color-scheme + (if (= profile-theme "system") system-theme + (d/nilv profile-theme "dark"))))))