From b43d0dde203e4b744a7639d0bb8cb4da06905313 Mon Sep 17 00:00:00 2001 From: Devon Doyle Date: Sun, 7 Sep 2025 00:33:37 -0400 Subject: [PATCH] Add custom theming (#2081) Adds support for user-created custom themes. Custom theme interface is tucked into the global settings in a non-invasive manner to avoid major design changes. Builds on the theme structure established by the dark theme update. image image Here's a few examples of what teams could do, using a few color schemes from local teams. Imagine the possibilities! image image image image image image Looking for high contrast? Just moments away: image --- photon-client/src/App.vue | 9 +- .../components/app/photon-camera-stream.vue | 4 +- .../src/components/app/photon-sidebar.vue | 17 +- .../src/components/cameras/CamerasView.vue | 9 +- .../src/components/common/pv-loading.vue | 205 ++++++++++++++++++ .../components/dashboard/StreamConfigCard.vue | 4 +- .../components/settings/NetworkingCard.vue | 115 +++++++++- photon-client/src/lib/ThemeManager.ts | 65 ++++++ photon-client/src/plugins/vuetify.ts | 7 +- 9 files changed, 397 insertions(+), 38 deletions(-) create mode 100644 photon-client/src/components/common/pv-loading.vue create mode 100644 photon-client/src/lib/ThemeManager.ts diff --git a/photon-client/src/App.vue b/photon-client/src/App.vue index 07b145a00..f24875a0c 100644 --- a/photon-client/src/App.vue +++ b/photon-client/src/App.vue @@ -3,10 +3,12 @@ import { useStateStore } from "@/stores/StateStore"; import { useSettingsStore } from "@/stores/settings/GeneralSettingsStore"; import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore"; import { AutoReconnectingWebsocket } from "@/lib/AutoReconnectingWebsocket"; -import { inject } from "vue"; +import { inject, onBeforeMount } from "vue"; import PhotonSidebar from "@/components/app/photon-sidebar.vue"; import PhotonLogView from "@/components/app/photon-log-view.vue"; import PhotonErrorSnackbar from "@/components/app/photon-error-snackbar.vue"; +import { useTheme } from "vuetify"; +import { restoreThemeConfig } from "@/lib/ThemeManager"; const is_demo = import.meta.env.MODE === "demo"; if (!is_demo) { @@ -50,6 +52,11 @@ if (!is_demo) { ); useStateStore().$patch({ websocket: websocket }); } + +const theme = useTheme(); +onBeforeMount(() => { + restoreThemeConfig(theme); +});