🦉 Feature: configurable preset for users:

- twitter emoji
 - useSystemTheme
 - themeId
This commit is contained in:
2026-04-15 18:01:28 +02:00
parent 5423e8bb7a
commit 8c892f14f8
5 changed files with 39 additions and 15 deletions

27
package-lock.json generated
View File

@@ -6041,7 +6041,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"devOptional": true
"optional": true
},
"node_modules/acorn": {
"version": "8.14.0",
@@ -6885,7 +6885,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"devOptional": true,
"optional": true,
"engines": {
"node": ">=10"
}
@@ -9498,7 +9498,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"devOptional": true,
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
@@ -9510,7 +9510,7 @@
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"devOptional": true,
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -9522,7 +9522,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
"optional": true
},
"node_modules/fs.realpath": {
"version": "1.0.0",
@@ -10448,6 +10448,7 @@
"integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
"dev": true,
"license": "ISC",
"optional": true,
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
@@ -12284,7 +12285,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"devOptional": true,
"optional": true,
"engines": {
"node": ">=8"
}
@@ -12293,7 +12294,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"devOptional": true,
"optional": true,
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
@@ -12306,7 +12307,7 @@
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"devOptional": true,
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -12318,13 +12319,13 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
"optional": true
},
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"devOptional": true,
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
@@ -12465,7 +12466,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"devOptional": true,
"optional": true,
"dependencies": {
"abbrev": "1"
},
@@ -17414,7 +17415,7 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"devOptional": true,
"optional": true,
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -17431,7 +17432,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
"optional": true
},
"node_modules/temp-dir": {
"version": "2.0.0",

View File

@@ -18,6 +18,8 @@ export type ClientConfig = {
};
hashRouter?: HashRouterConfig;
defaultSettings?: Record<string, unknown>;
};
const ClientConfigContext = createContext<ClientConfig | null>(null);

View File

@@ -12,6 +12,7 @@ import { FeatureCheck } from './FeatureCheck';
import { createRouter } from './Router';
import { ScreenSizeProvider, useScreenSize } from '../hooks/useScreenSize';
import { useCompositionEndTracking } from '../hooks/useComposingCheck';
import { ConfigSettingsApply } from '../../owl/components/ConfigSettingsApply';
const queryClient = new QueryClient();
@@ -37,6 +38,7 @@ function App() {
<ClientConfigProvider value={clientConfig}>
<QueryClientProvider client={queryClient}>
<JotaiProvider>
<ConfigSettingsApply />
<RouterProvider router={createRouter(clientConfig, screenSize)} />
</JotaiProvider>
<ReactQueryDevtools initialIsOpen={false} />

View File

@@ -83,11 +83,12 @@ const defaultSettings: Settings = {
developerTools: false,
};
export const getSettings = () => {
export const getSettings = (configDefaults?: Partial<Settings>) => {
const settings = localStorage.getItem(STORAGE_KEY);
if (settings === null) return defaultSettings;
if (settings === null) return { ...defaultSettings, ...configDefaults };
return {
...defaultSettings,
...configDefaults,
...(JSON.parse(settings) as Settings),
};
};

View File

@@ -0,0 +1,18 @@
import { useEffect, useRef } from 'react';
import { useAtom } from 'jotai';
import { useClientConfig } from '../../app/hooks/useClientConfig';
import { settingsAtom, getSettings, Settings } from '../../app/state/settings';
export function ConfigSettingsApply() {
const { defaultSettings: configDefaults } = useClientConfig();
const [, setSettings] = useAtom(settingsAtom);
const applied = useRef(false);
useEffect(() => {
if (applied.current || !configDefaults) return;
applied.current = true;
setSettings(getSettings(configDefaults as Partial<Settings>));
}, [configDefaults, setSettings]);
return null;
}