@oxy.so/services 13.2.0 → 13.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/lib/commonjs/ui/client.js +13 -0
  2. package/lib/commonjs/ui/client.js.map +1 -1
  3. package/lib/commonjs/ui/hooks/useAccountTheme.js +182 -0
  4. package/lib/commonjs/ui/hooks/useAccountTheme.js.map +1 -0
  5. package/lib/commonjs/ui/hooks/useFileDownloadUrl.js +64 -44
  6. package/lib/commonjs/ui/hooks/useFileDownloadUrl.js.map +1 -1
  7. package/lib/module/ui/client.js +1 -0
  8. package/lib/module/ui/client.js.map +1 -1
  9. package/lib/module/ui/hooks/useAccountTheme.js +178 -0
  10. package/lib/module/ui/hooks/useAccountTheme.js.map +1 -0
  11. package/lib/module/ui/hooks/useFileDownloadUrl.js +64 -44
  12. package/lib/module/ui/hooks/useFileDownloadUrl.js.map +1 -1
  13. package/lib/typescript/commonjs/ui/client.d.ts +2 -0
  14. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  15. package/lib/typescript/commonjs/ui/hooks/useAccountTheme.d.ts +47 -0
  16. package/lib/typescript/commonjs/ui/hooks/useAccountTheme.d.ts.map +1 -0
  17. package/lib/typescript/commonjs/ui/hooks/useFileDownloadUrl.d.ts +10 -4
  18. package/lib/typescript/commonjs/ui/hooks/useFileDownloadUrl.d.ts.map +1 -1
  19. package/lib/typescript/module/ui/client.d.ts +2 -0
  20. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  21. package/lib/typescript/module/ui/hooks/useAccountTheme.d.ts +47 -0
  22. package/lib/typescript/module/ui/hooks/useAccountTheme.d.ts.map +1 -0
  23. package/lib/typescript/module/ui/hooks/useFileDownloadUrl.d.ts +10 -4
  24. package/lib/typescript/module/ui/hooks/useFileDownloadUrl.d.ts.map +1 -1
  25. package/package.json +4 -4
  26. package/src/ui/client.ts +2 -0
  27. package/src/ui/hooks/useAccountTheme.ts +177 -0
  28. package/src/ui/hooks/useFileDownloadUrl.ts +59 -49
@@ -255,6 +255,18 @@ Object.defineProperty(exports, "useAccountColorSave", {
255
255
  return _useAccountColor.useAccountColorSave;
256
256
  }
257
257
  });
258
+ Object.defineProperty(exports, "useAccountTheme", {
259
+ enumerable: true,
260
+ get: function () {
261
+ return _useAccountTheme.useAccountTheme;
262
+ }
263
+ });
264
+ Object.defineProperty(exports, "useAccountThemeControls", {
265
+ enumerable: true,
266
+ get: function () {
267
+ return _useAccountTheme.useAccountThemeControls;
268
+ }
269
+ });
258
270
  Object.defineProperty(exports, "useAppAssertion", {
259
271
  enumerable: true,
260
272
  get: function () {
@@ -426,6 +438,7 @@ var _OxyPayButton = _interopRequireDefault(require("./components/OxyPayButton.js
426
438
  var _OxyContext = require("./context/OxyContext.js");
427
439
  var _useAuth = require("./hooks/useAuth.js");
428
440
  var _useAccountColor = require("./hooks/useAccountColor.js");
441
+ var _useAccountTheme = require("./hooks/useAccountTheme.js");
429
442
  var _AppAssertionContext = require("./appAssertion/AppAssertionContext.js");
430
443
  var _productAnalytics = require("./analytics/productAnalytics.js");
431
444
  var _useFollow = require("./hooks/useFollow.js");
@@ -1 +1 @@
1
- {"version":3,"names":["require","_OxyProvider","_interopRequireDefault","_OxySignInButton","_OxyAuthPrompt","_LogoIcon","_LogoText","_FollowButton","_FollowTargetButton","_followLabels","_ProfileButton","_PeableButton","_OxyPayButton","_OxyContext","_useAuth","_useAccountColor","_AppAssertionContext","_productAnalytics","_useFollow","_useFollowTarget","_useSupervision","_useAccountQueries","_useStorage","_useOxyEvent","_useAccountMutations","_useFileDownloadUrl","_useMutationStatus","_useOnlineStatus","_useDisplayCurrency","_useDisplayPrice","_DisplayCurrencySelector","_followRules","_queryKeys","_userCache","_authStore","_errorHandlers","e","__esModule","default"],"sourceRoot":"../../../src","sources":["ui/client.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeAA,OAAA;AAGA,IAAAC,YAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,gBAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,cAAA,GAAAF,sBAAA,CAAAF,OAAA;AAEA,IAAAK,SAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AACA,IAAAO,aAAA,GAAAL,sBAAA,CAAAF,OAAA;AAMA,IAAAQ,mBAAA,GAAAR,OAAA;AAGA,IAAAS,aAAA,GAAAT,OAAA;AAEA,IAAAU,cAAA,GAAAR,sBAAA,CAAAF,OAAA;AAEA,IAAAW,aAAA,GAAAT,sBAAA,CAAAF,OAAA;AAGA,IAAAY,aAAA,GAAAV,sBAAA,CAAAF,OAAA;AAKA,IAAAa,WAAA,GAAAb,OAAA;AAGA,IAAAc,QAAA,GAAAd,OAAA;AACA,IAAAe,gBAAA,GAAAf,OAAA;AAQA,IAAAgB,oBAAA,GAAAhB,OAAA;AAOA,IAAAiB,iBAAA,GAAAjB,OAAA;AAEA,IAAAkB,UAAA,GAAAlB,OAAA;AACA,IAAAmB,gBAAA,GAAAnB,OAAA;AACA,IAAAoB,eAAA,GAAApB,OAAA;AAEA,IAAAqB,kBAAA,GAAArB,OAAA;AAOA,IAAAsB,WAAA,GAAAtB,OAAA;AAGA,IAAAuB,YAAA,GAAAvB,OAAA;AAKA,IAAAwB,oBAAA,GAAAxB,OAAA;AAKA,IAAAyB,mBAAA,GAAAzB,OAAA;AACA,IAAA0B,kBAAA,GAAA1B,OAAA;AAEA,IAAA2B,gBAAA,GAAA3B,OAAA;AACA,IAAA4B,mBAAA,GAAA5B,OAAA;AACA,IAAA6B,gBAAA,GAAA7B,OAAA;AACA,IAAA8B,wBAAA,GAAA9B,OAAA;AAOA,IAAA+B,YAAA,GAAA/B,OAAA;AAQA,IAAAgC,UAAA,GAAAhC,OAAA;AAaA,IAAAiC,UAAA,GAAAjC,OAAA;AAcA,IAAAkC,UAAA,GAAAlC,OAAA;AAGA,IAAAmC,cAAA,GAAAnC,OAAA;AAK+B,SAAAE,uBAAAkC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA","ignoreList":[]}
1
+ {"version":3,"names":["require","_OxyProvider","_interopRequireDefault","_OxySignInButton","_OxyAuthPrompt","_LogoIcon","_LogoText","_FollowButton","_FollowTargetButton","_followLabels","_ProfileButton","_PeableButton","_OxyPayButton","_OxyContext","_useAuth","_useAccountColor","_useAccountTheme","_AppAssertionContext","_productAnalytics","_useFollow","_useFollowTarget","_useSupervision","_useAccountQueries","_useStorage","_useOxyEvent","_useAccountMutations","_useFileDownloadUrl","_useMutationStatus","_useOnlineStatus","_useDisplayCurrency","_useDisplayPrice","_DisplayCurrencySelector","_followRules","_queryKeys","_userCache","_authStore","_errorHandlers","e","__esModule","default"],"sourceRoot":"../../../src","sources":["ui/client.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeAA,OAAA;AAGA,IAAAC,YAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,gBAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,cAAA,GAAAF,sBAAA,CAAAF,OAAA;AAEA,IAAAK,SAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AACA,IAAAO,aAAA,GAAAL,sBAAA,CAAAF,OAAA;AAMA,IAAAQ,mBAAA,GAAAR,OAAA;AAGA,IAAAS,aAAA,GAAAT,OAAA;AAEA,IAAAU,cAAA,GAAAR,sBAAA,CAAAF,OAAA;AAEA,IAAAW,aAAA,GAAAT,sBAAA,CAAAF,OAAA;AAGA,IAAAY,aAAA,GAAAV,sBAAA,CAAAF,OAAA;AAKA,IAAAa,WAAA,GAAAb,OAAA;AAGA,IAAAc,QAAA,GAAAd,OAAA;AACA,IAAAe,gBAAA,GAAAf,OAAA;AAMA,IAAAgB,gBAAA,GAAAhB,OAAA;AAIA,IAAAiB,oBAAA,GAAAjB,OAAA;AAOA,IAAAkB,iBAAA,GAAAlB,OAAA;AAEA,IAAAmB,UAAA,GAAAnB,OAAA;AACA,IAAAoB,gBAAA,GAAApB,OAAA;AACA,IAAAqB,eAAA,GAAArB,OAAA;AAEA,IAAAsB,kBAAA,GAAAtB,OAAA;AAOA,IAAAuB,WAAA,GAAAvB,OAAA;AAGA,IAAAwB,YAAA,GAAAxB,OAAA;AAKA,IAAAyB,oBAAA,GAAAzB,OAAA;AAKA,IAAA0B,mBAAA,GAAA1B,OAAA;AACA,IAAA2B,kBAAA,GAAA3B,OAAA;AAEA,IAAA4B,gBAAA,GAAA5B,OAAA;AACA,IAAA6B,mBAAA,GAAA7B,OAAA;AACA,IAAA8B,gBAAA,GAAA9B,OAAA;AACA,IAAA+B,wBAAA,GAAA/B,OAAA;AAOA,IAAAgC,YAAA,GAAAhC,OAAA;AAQA,IAAAiC,UAAA,GAAAjC,OAAA;AAaA,IAAAkC,UAAA,GAAAlC,OAAA;AAcA,IAAAmC,UAAA,GAAAnC,OAAA;AAGA,IAAAoC,cAAA,GAAApC,OAAA;AAK+B,SAAAE,uBAAAmC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA","ignoreList":[]}
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useAccountTheme = useAccountTheme;
7
+ exports.useAccountThemeControls = useAccountThemeControls;
8
+ var _react = require("react");
9
+ var _zustand = require("zustand");
10
+ var _core = require("@oxy.so/core");
11
+ var _theme = require("@oxy.so/bloom/theme");
12
+ var _storageHelpers = require("../utils/storageHelpers.js");
13
+ var _useAccountColor = require("./useAccountColor.js");
14
+ var _useAuth = require("./useAuth.js");
15
+ var _useAccountMutations = require("./mutations/useAccountMutations.js");
16
+ /**
17
+ * useAccountTheme / useAccountThemeControls
18
+ *
19
+ * The Oxy account carries a portable theme (`user.themePreference`: a mode and
20
+ * a colour preset) that every Oxy app can wear. The COLOUR is the account
21
+ * colour and always applies (`useAccountColor`). Whether an app also follows
22
+ * the account's MODE is the viewer's choice per device: the theme SOURCE.
23
+ *
24
+ * - `account` (the default): the account's mode is applied to Bloom, and a mode
25
+ * chosen here is written back to the account for the other Oxy apps.
26
+ * - `app`: the mode stays on this device; nothing is written to the account.
27
+ *
28
+ * The source is a local preference, never sent anywhere. On web it is read
29
+ * synchronously, so the first paint already knows it; on native it resolves
30
+ * from AsyncStorage right after mount. Bloom's own persistence still paints the
31
+ * last theme instantly on cold boot, so the account theme lands without a flash
32
+ * once the session resolves.
33
+ */
34
+
35
+ /** Where the app's theme MODE comes from on this device. */
36
+
37
+ const THEME_SOURCE_KEY = 'oxy.theme.source';
38
+ function normalizeSource(stored) {
39
+ return stored === 'app' ? 'app' : 'account';
40
+ }
41
+
42
+ /**
43
+ * Bloom's richer mode set onto the portable subset the account stores
44
+ * (`adaptive` has no cross-app meaning, so it is `system`).
45
+ */
46
+ function toPortableMode(mode) {
47
+ return mode === 'light' || mode === 'dark' ? mode : 'system';
48
+ }
49
+
50
+ /** Web reads `localStorage` synchronously; native resolves in `hydrate`. */
51
+ function readInitialSource() {
52
+ if ((0, _storageHelpers.isReactNative)() || typeof window === 'undefined') {
53
+ return {
54
+ source: 'account',
55
+ hydrated: false
56
+ };
57
+ }
58
+ try {
59
+ return {
60
+ source: normalizeSource(window.localStorage?.getItem(THEME_SOURCE_KEY)),
61
+ hydrated: true
62
+ };
63
+ } catch {
64
+ // A sandboxed document's storage getter throws: no stored choice.
65
+ return {
66
+ source: 'account',
67
+ hydrated: true
68
+ };
69
+ }
70
+ }
71
+ const useThemeSourceStore = (0, _zustand.create)((set, get) => ({
72
+ ...readInitialSource(),
73
+ setSource(source) {
74
+ set({
75
+ source,
76
+ hydrated: true
77
+ });
78
+ void (0, _storageHelpers.createPlatformStorage)().then(storage => storage.setItem(THEME_SOURCE_KEY, source)).catch(() => undefined);
79
+ },
80
+ async hydrate() {
81
+ if (get().hydrated) return;
82
+ const stored = await (0, _storageHelpers.createPlatformStorage)().then(storage => storage.getItem(THEME_SOURCE_KEY)).catch(() => null);
83
+ // A choice made while storage was being read wins over the stored one.
84
+ if (!get().hydrated) set({
85
+ source: normalizeSource(stored),
86
+ hydrated: true
87
+ });
88
+ }
89
+ }));
90
+
91
+ /**
92
+ * Apply the account theme to Bloom: the colour always (through
93
+ * `useAccountColor`, which `canUse` can narrow), the mode while this device's
94
+ * source is `account`. Mount ONCE, inside `OxyProvider` and Bloom's theme
95
+ * provider.
96
+ */
97
+ function useAccountTheme({
98
+ canUse
99
+ } = {}) {
100
+ const {
101
+ isAuthenticated,
102
+ user
103
+ } = (0, _useAuth.useAuth)();
104
+ const source = useThemeSourceStore(state => state.source);
105
+ const hydrated = useThemeSourceStore(state => state.hydrated);
106
+ const hydrate = useThemeSourceStore(state => state.hydrate);
107
+ const {
108
+ setMode
109
+ } = (0, _theme.useBloomTheme)();
110
+ (0, _useAccountColor.useAccountColor)({
111
+ canUse
112
+ });
113
+ (0, _react.useEffect)(() => {
114
+ void hydrate();
115
+ }, [hydrate]);
116
+ const accountMode = user?.themePreference?.mode;
117
+ (0, _react.useEffect)(() => {
118
+ if (!hydrated || !isAuthenticated || source !== 'account' || !accountMode) return;
119
+ setMode(accountMode);
120
+ }, [hydrated, isAuthenticated, source, accountMode, setMode]);
121
+ }
122
+ /**
123
+ * Source-aware theme mode changes for a settings screen. Bloom changes at once;
124
+ * on the `account` source the account's portable theme follows. Without a
125
+ * usable session the effective source is `app`, so changes stay local, and the
126
+ * stored choice applies again once signed in. The colour is chosen with
127
+ * `useAccountColorSave`.
128
+ */
129
+ function useAccountThemeControls() {
130
+ const {
131
+ user,
132
+ canUsePrivateApi
133
+ } = (0, _useAuth.useAuth)();
134
+ const {
135
+ mode,
136
+ colorPreset,
137
+ setMode
138
+ } = (0, _theme.useBloomTheme)();
139
+ const {
140
+ mutateAsync
141
+ } = (0, _useAccountMutations.useUpdateProfile)();
142
+ const storedSource = useThemeSourceStore(state => state.source);
143
+ const setSource = useThemeSourceStore(state => state.setSource);
144
+ const source = canUsePrivateApi ? storedSource : 'app';
145
+ const persist = (0, _react.useCallback)(async next => {
146
+ await mutateAsync({
147
+ themePreference: {
148
+ mode: toPortableMode(next.mode),
149
+ colorPreset: next.colorPreset
150
+ }
151
+ });
152
+ }, [mutateAsync]);
153
+ const changeThemeMode = (0, _react.useCallback)(async nextMode => {
154
+ setMode(nextMode);
155
+ if (source === 'account') await persist({
156
+ mode: nextMode,
157
+ colorPreset
158
+ });
159
+ }, [setMode, source, persist, colorPreset]);
160
+ const accountTheme = user?.themePreference;
161
+ const hasAccountTheme = !!accountTheme && (0, _useAccountColor.resolveAccountColor)({
162
+ themePreference: accountTheme
163
+ }) !== null;
164
+ const changeThemeSource = (0, _react.useCallback)(nextSource => {
165
+ setSource(nextSource);
166
+ // An existing account theme is applied by `useAccountTheme`; only an
167
+ // account without one is seeded, from what the viewer sees now.
168
+ if (nextSource !== 'account' || !canUsePrivateApi || hasAccountTheme) return;
169
+ persist({
170
+ mode,
171
+ colorPreset
172
+ }).catch(error => {
173
+ _core.logger.error('Failed to seed the account theme', error);
174
+ });
175
+ }, [setSource, canUsePrivateApi, hasAccountTheme, persist, mode, colorPreset]);
176
+ return {
177
+ source,
178
+ changeThemeSource,
179
+ changeThemeMode
180
+ };
181
+ }
182
+ //# sourceMappingURL=useAccountTheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_zustand","_core","_theme","_storageHelpers","_useAccountColor","_useAuth","_useAccountMutations","THEME_SOURCE_KEY","normalizeSource","stored","toPortableMode","mode","readInitialSource","isReactNative","window","source","hydrated","localStorage","getItem","useThemeSourceStore","create","set","get","setSource","createPlatformStorage","then","storage","setItem","catch","undefined","hydrate","useAccountTheme","canUse","isAuthenticated","user","useAuth","state","setMode","useBloomTheme","useAccountColor","useEffect","accountMode","themePreference","useAccountThemeControls","canUsePrivateApi","colorPreset","mutateAsync","useUpdateProfile","storedSource","persist","useCallback","next","changeThemeMode","nextMode","accountTheme","hasAccountTheme","resolveAccountColor","changeThemeSource","nextSource","error","logger"],"sourceRoot":"../../../../src","sources":["ui/hooks/useAccountTheme.ts"],"mappings":"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","ignoreList":[]}
@@ -5,63 +5,83 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.useFileDownloadUrl = void 0;
7
7
  var _react = require("react");
8
+ var _oxyRuntimeContext = require("../context/oxyRuntimeContext.js");
9
+ function isAbsoluteUrl(ref) {
10
+ return ref.startsWith('http://') || ref.startsWith('https://');
11
+ }
12
+
8
13
  /**
9
- * Hook to resolve a file's download URL asynchronously.
14
+ * Resolve a file's download URL for the current caller.
15
+ *
16
+ * A URL `assets.url` already resolved is answered in the FIRST render from
17
+ * core's identity-scoped cache (`assets.cachedUrl`): no request, no loading
18
+ * frame. Only a miss resolves asynchronously, through `assets.url`, which
19
+ * returns a scoped media-token stream URL for a private asset. There is no
20
+ * public-CDN fallback: `assets.publicUrl` 404s for private uploads. A
21
+ * reference that is already an absolute `http(s)` URL is returned unchanged.
10
22
  *
11
- * Uses `getFileDownloadUrlAsync`, which returns a scoped media-token stream URL
12
- * for private assets. There is no sync CDN fallback — the synchronous
13
- * `getFileDownloadUrl` is public-CDN-only and 404s for private uploads.
23
+ * For a synchronous, render-only answer (an image resolver, a list row) use
24
+ * `oxyServices.assets.renderUrl`, which reads the same cache.
14
25
  */
15
26
  const useFileDownloadUrl = (oxyServices, fileId, options) => {
16
- const [url, setUrl] = (0, _react.useState)(null);
17
- const [loading, setLoading] = (0, _react.useState)(false);
18
- const [error, setError] = (0, _react.useState)(null);
19
27
  const variant = options?.variant;
20
28
  const expiresIn = options?.expiresIn;
29
+ // A resolved URL can carry the viewer's scoped media token, so the viewer is
30
+ // part of what was asked: an account switch never shows the previous one's.
31
+ const viewerId = (0, _oxyRuntimeContext.useOptionalOxy)()?.user?.id ?? '';
32
+ const request = fileId ? `${viewerId}|${fileId}|${variant ?? ''}|${expiresIn ?? ''}` : null;
33
+ const immediate = !fileId ? null : isAbsoluteUrl(fileId) ? fileId : oxyServices?.assets.cachedUrl(fileId, variant, expiresIn) ?? null;
34
+ const needsResolve = !!fileId && !!oxyServices && immediate === null;
35
+ const [settled, setSettled] = (0, _react.useState)(null);
21
36
  (0, _react.useEffect)(() => {
22
- if (!fileId) {
23
- setUrl(null);
24
- setLoading(false);
25
- setError(null);
26
- return;
27
- }
28
- if (!oxyServices) {
29
- setUrl(null);
30
- setLoading(false);
31
- setError(new Error('OxyServices instance not configured for useFileDownloadUrl'));
32
- return;
33
- }
37
+ if (!needsResolve || !fileId || !oxyServices || !request) return;
34
38
  let cancelled = false;
35
- const instance = oxyServices;
36
- const targetFileId = fileId;
37
- const load = async () => {
38
- setLoading(true);
39
- setError(null);
40
- try {
41
- const resolvedUrl = await instance.assets.url(targetFileId, variant, expiresIn);
42
- if (!cancelled) {
43
- setUrl(resolvedUrl || null);
44
- }
45
- } catch (err) {
46
- if (!cancelled) {
47
- setUrl(null);
48
- setError(err instanceof Error ? err : new Error(String(err)));
49
- }
50
- } finally {
51
- if (!cancelled) {
52
- setLoading(false);
53
- }
39
+ oxyServices.assets.url(fileId, variant, expiresIn).then(url => {
40
+ if (!cancelled) setSettled({
41
+ request,
42
+ url: url || null,
43
+ error: null
44
+ });
45
+ }, err => {
46
+ if (!cancelled) {
47
+ setSettled({
48
+ request,
49
+ url: null,
50
+ error: err instanceof Error ? err : new Error(String(err))
51
+ });
54
52
  }
55
- };
56
- load();
53
+ });
57
54
  return () => {
58
55
  cancelled = true;
59
56
  };
60
- }, [fileId, oxyServices, variant, expiresIn]);
57
+ }, [needsResolve, fileId, oxyServices, variant, expiresIn, request]);
58
+ if (!fileId) return {
59
+ url: null,
60
+ loading: false,
61
+ error: null
62
+ };
63
+ if (immediate !== null) return {
64
+ url: immediate,
65
+ loading: false,
66
+ error: null
67
+ };
68
+ if (!oxyServices) {
69
+ return {
70
+ url: null,
71
+ loading: false,
72
+ error: new Error('OxyServices instance not configured for useFileDownloadUrl')
73
+ };
74
+ }
75
+ // A result settled for another file, variant or expiry is never shown.
76
+ if (settled?.request !== request) return {
77
+ url: null,
78
+ loading: true,
79
+ error: null
80
+ };
61
81
  return {
62
- url,
63
- loading,
64
- error
82
+ url: settled.url,
83
+ loading: false,
84
+ error: settled.error
65
85
  };
66
86
  };
67
87
  exports.useFileDownloadUrl = useFileDownloadUrl;
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","useFileDownloadUrl","oxyServices","fileId","options","url","setUrl","useState","loading","setLoading","error","setError","variant","expiresIn","useEffect","Error","cancelled","instance","targetFileId","load","resolvedUrl","assets","err","String","exports"],"sourceRoot":"../../../../src","sources":["ui/hooks/useFileDownloadUrl.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,kBAAkB,GAAGA,CAChCC,WAA2C,EAC3CC,MAAiC,EACjCC,OAAmC,KACN;EAC7B,MAAM,CAACC,GAAG,EAAEC,MAAM,CAAC,GAAG,IAAAC,eAAQ,EAAgB,IAAI,CAAC;EACnD,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAG,IAAAF,eAAQ,EAAC,KAAK,CAAC;EAC7C,MAAM,CAACG,KAAK,EAAEC,QAAQ,CAAC,GAAG,IAAAJ,eAAQ,EAAe,IAAI,CAAC;EAEtD,MAAMK,OAAO,GAAGR,OAAO,EAAEQ,OAAO;EAChC,MAAMC,SAAS,GAAGT,OAAO,EAAES,SAAS;EAEpC,IAAAC,gBAAS,EAAC,MAAM;IACd,IAAI,CAACX,MAAM,EAAE;MACXG,MAAM,CAAC,IAAI,CAAC;MACZG,UAAU,CAAC,KAAK,CAAC;MACjBE,QAAQ,CAAC,IAAI,CAAC;MACd;IACF;IAEA,IAAI,CAACT,WAAW,EAAE;MAChBI,MAAM,CAAC,IAAI,CAAC;MACZG,UAAU,CAAC,KAAK,CAAC;MACjBE,QAAQ,CAAC,IAAII,KAAK,CAAC,4DAA4D,CAAC,CAAC;MACjF;IACF;IAEA,IAAIC,SAAS,GAAG,KAAK;IACrB,MAAMC,QAAQ,GAAGf,WAAW;IAC5B,MAAMgB,YAAY,GAAGf,MAAM;IAE3B,MAAMgB,IAAI,GAAG,MAAAA,CAAA,KAAY;MACvBV,UAAU,CAAC,IAAI,CAAC;MAChBE,QAAQ,CAAC,IAAI,CAAC;MAEd,IAAI;QACF,MAAMS,WAAW,GAAG,MAAMH,QAAQ,CAACI,MAAM,CAAChB,GAAG,CAACa,YAAY,EAAEN,OAAO,EAAEC,SAAS,CAAC;QAE/E,IAAI,CAACG,SAAS,EAAE;UACdV,MAAM,CAACc,WAAW,IAAI,IAAI,CAAC;QAC7B;MACF,CAAC,CAAC,OAAOE,GAAY,EAAE;QACrB,IAAI,CAACN,SAAS,EAAE;UACdV,MAAM,CAAC,IAAI,CAAC;UACZK,QAAQ,CAACW,GAAG,YAAYP,KAAK,GAAGO,GAAG,GAAG,IAAIP,KAAK,CAACQ,MAAM,CAACD,GAAG,CAAC,CAAC,CAAC;QAC/D;MACF,CAAC,SAAS;QACR,IAAI,CAACN,SAAS,EAAE;UACdP,UAAU,CAAC,KAAK,CAAC;QACnB;MACF;IACF,CAAC;IAEDU,IAAI,CAAC,CAAC;IAEN,OAAO,MAAM;MACXH,SAAS,GAAG,IAAI;IAClB,CAAC;EACH,CAAC,EAAE,CAACb,MAAM,EAAED,WAAW,EAAEU,OAAO,EAAEC,SAAS,CAAC,CAAC;EAE7C,OAAO;IAAER,GAAG;IAAEG,OAAO;IAAEE;EAAM,CAAC;AAChC,CAAC;AAACc,OAAA,CAAAvB,kBAAA,GAAAA,kBAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_oxyRuntimeContext","isAbsoluteUrl","ref","startsWith","useFileDownloadUrl","oxyServices","fileId","options","variant","expiresIn","viewerId","useOptionalOxy","user","id","request","immediate","assets","cachedUrl","needsResolve","settled","setSettled","useState","useEffect","cancelled","url","then","error","err","Error","String","loading","exports"],"sourceRoot":"../../../../src","sources":["ui/hooks/useFileDownloadUrl.ts"],"mappings":"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","ignoreList":[]}
@@ -38,6 +38,7 @@ export { useOxy, useOptionalOxy, OxyProviderMissingError } from "./context/OxyCo
38
38
  // Hooks
39
39
  export { useAuth } from "./hooks/useAuth.js";
40
40
  export { useAccountColor, useAccountColorSave, resolveAccountColor, entitledAccountColors } from "./hooks/useAccountColor.js";
41
+ export { useAccountTheme, useAccountThemeControls } from "./hooks/useAccountTheme.js";
41
42
  // This app's Oxy-signed assertion of which app it is (ADR 0045), for an SDK
42
43
  // that attaches it to its own requests without pulling in the account screens.
43
44
  export { useAppAssertion, AppAssertionProviderMissingError } from "./appAssertion/AppAssertionContext.js";
@@ -1 +1 @@
1
- {"version":3,"names":["default","OxyProvider","OxySignInButton","OxyAuthPrompt","LogoIcon","LogoText","FollowButton","FollowTargetButton","useFollowErrorMessage","ProfileButton","PeableButton","OxyPayButton","useOxy","useOptionalOxy","OxyProviderMissingError","useAuth","useAccountColor","useAccountColorSave","resolveAccountColor","entitledAccountColors","useAppAssertion","AppAssertionProviderMissingError","createDeferredProductAnalytics","useFollow","useFollowerCounts","useSeedFollowStatuses","useFollowTarget","useSupervision","supervisionQueryKeys","useUserProfile","useUserProfiles","useCurrentUser","useUserById","useUserByUsername","useStorage","useOxyEvent","useUpdateProfile","useUploadAvatar","useUploadFile","useFileDownloadUrl","useMutationStatus","useOnlineStatus","useDisplayCurrency","useDisplayPrice","DisplayCurrencySelector","buildFollowMenuItems","resolveFollowPrimaryAction","FOLLOW_ACTION_LEAVES_ACTIVE","queryKeys","invalidateAccountQueries","invalidateUserQueries","invalidateSessionQueries","invalidateDeviceQueries","invalidatePrivacyQueries","invalidateSecurityQueries","invalidateStorageQueries","invalidatePaymentsQueries","invalidateConnectedAppsQueries","invalidateAuthMethodsQueries","upsertCachedUser","upsertCachedUsers","CLEARABLE_USER_FIELDS","clearedFieldsFromProfileUpdate","clearedFieldsFromAccountUpdate","useAuthStore","handleAuthError","isInvalidSessionError","isTimeoutOrNetworkError","extractErrorMessage"],"sourceRoot":"../../../src","sources":["ui/client.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO,wBAAqB;;AAE5B;AACA,SAASA,OAAO,IAAIC,WAAW,QAAQ,6BAA0B;AACjE,SAASD,OAAO,IAAIE,eAAe,QAAQ,iCAA8B;AACzE,SAASF,OAAO,IAAIG,aAAa,QAAQ,+BAA4B;AAErE,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASL,OAAO,IAAIM,YAAY,QAAQ,8BAA2B;AAMnE,SAASC,kBAAkB,QAAQ,oCAAiC;AAGpE,SAASC,qBAAqB,QAAQ,8BAA2B;AAEjE,SAASR,OAAO,IAAIS,aAAa,QAAQ,+BAA4B;AAErE,SAAST,OAAO,IAAIU,YAAY,QAAQ,8BAA2B;AAEnE;AACA,SAASV,OAAO,IAAIW,YAAY,QAAQ,8BAA2B;AACnE;;AAGA;AACA,SAASC,MAAM,EAAEC,cAAc,EAAEC,uBAAuB,QAAQ,yBAAsB;;AAEtF;AACA,SAASC,OAAO,QAAQ,oBAAiB;AACzC,SACEC,eAAe,EACfC,mBAAmB,EACnBC,mBAAmB,EACnBC,qBAAqB,QAChB,4BAAyB;AAChC;AACA;AACA,SACEC,eAAe,EACfC,gCAAgC,QAC3B,uCAAoC;AAI3C,SAASC,8BAA8B,QAAQ,iCAA8B;AAE7E,SAASC,SAAS,EAAEC,iBAAiB,EAAEC,qBAAqB,QAAQ,sBAAmB;AACvF,SAASC,eAAe,QAAQ,4BAAyB;AACzD,SAASC,cAAc,EAAEC,oBAAoB,QAAQ,mCAAgC;AAErF,SACEC,cAAc,EACdC,eAAe,EACfC,cAAc,EACdC,WAAW,EACXC,iBAAiB,QACZ,sCAAmC;AAC1C,SAASC,UAAU,QAAQ,uBAAoB;AAC/C;AACA;AACA,SAASC,WAAW,QAAQ,wBAAqB;AACjD;AACA;AACA;AACA;AACA,SACEC,gBAAgB,EAChBC,eAAe,EACfC,aAAa,QACR,0CAAuC;AAC9C,SAASC,kBAAkB,QAAQ,+BAA4B;AAC/D,SAASC,iBAAiB,QAAQ,8BAA2B;AAE7D,SAASC,eAAe,QAAQ,4BAAyB;AACzD,SAASC,kBAAkB,QAAQ,+BAA4B;AAC/D,SAASC,eAAe,QAAQ,4BAAyB;AACzD,SAASC,uBAAuB,QAAQ,yCAAsC;AAG9E;AACA;;AAEA;AACA,SACEC,oBAAoB,EACpBC,0BAA0B,EAC1BC,2BAA2B,QACtB,6BAA0B;AAGjC;AACA,SACEC,SAAS,EACTC,wBAAwB,EACxBC,qBAAqB,EACrBC,wBAAwB,EACxBC,uBAAuB,EACvBC,wBAAwB,EACxBC,yBAAyB,EACzBC,wBAAwB,EACxBC,yBAAyB,EACzBC,8BAA8B,EAC9BC,4BAA4B,QACvB,8BAA2B;AAClC,SACEC,gBAAgB,EAChBC,iBAAiB,EACjBC,qBAAqB,EACrBC,8BAA8B,EAC9BC,8BAA8B,QACzB,8BAA2B;AAOlC;AACA,SAASC,YAAY,QAAQ,uBAAoB;;AAEjD;AACA,SACEC,eAAe,EACfC,qBAAqB,EACrBC,uBAAuB,EACvBC,mBAAmB,QACd,0BAAuB","ignoreList":[]}
1
+ {"version":3,"names":["default","OxyProvider","OxySignInButton","OxyAuthPrompt","LogoIcon","LogoText","FollowButton","FollowTargetButton","useFollowErrorMessage","ProfileButton","PeableButton","OxyPayButton","useOxy","useOptionalOxy","OxyProviderMissingError","useAuth","useAccountColor","useAccountColorSave","resolveAccountColor","entitledAccountColors","useAccountTheme","useAccountThemeControls","useAppAssertion","AppAssertionProviderMissingError","createDeferredProductAnalytics","useFollow","useFollowerCounts","useSeedFollowStatuses","useFollowTarget","useSupervision","supervisionQueryKeys","useUserProfile","useUserProfiles","useCurrentUser","useUserById","useUserByUsername","useStorage","useOxyEvent","useUpdateProfile","useUploadAvatar","useUploadFile","useFileDownloadUrl","useMutationStatus","useOnlineStatus","useDisplayCurrency","useDisplayPrice","DisplayCurrencySelector","buildFollowMenuItems","resolveFollowPrimaryAction","FOLLOW_ACTION_LEAVES_ACTIVE","queryKeys","invalidateAccountQueries","invalidateUserQueries","invalidateSessionQueries","invalidateDeviceQueries","invalidatePrivacyQueries","invalidateSecurityQueries","invalidateStorageQueries","invalidatePaymentsQueries","invalidateConnectedAppsQueries","invalidateAuthMethodsQueries","upsertCachedUser","upsertCachedUsers","CLEARABLE_USER_FIELDS","clearedFieldsFromProfileUpdate","clearedFieldsFromAccountUpdate","useAuthStore","handleAuthError","isInvalidSessionError","isTimeoutOrNetworkError","extractErrorMessage"],"sourceRoot":"../../../src","sources":["ui/client.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO,wBAAqB;;AAE5B;AACA,SAASA,OAAO,IAAIC,WAAW,QAAQ,6BAA0B;AACjE,SAASD,OAAO,IAAIE,eAAe,QAAQ,iCAA8B;AACzE,SAASF,OAAO,IAAIG,aAAa,QAAQ,+BAA4B;AAErE,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASL,OAAO,IAAIM,YAAY,QAAQ,8BAA2B;AAMnE,SAASC,kBAAkB,QAAQ,oCAAiC;AAGpE,SAASC,qBAAqB,QAAQ,8BAA2B;AAEjE,SAASR,OAAO,IAAIS,aAAa,QAAQ,+BAA4B;AAErE,SAAST,OAAO,IAAIU,YAAY,QAAQ,8BAA2B;AAEnE;AACA,SAASV,OAAO,IAAIW,YAAY,QAAQ,8BAA2B;AACnE;;AAGA;AACA,SAASC,MAAM,EAAEC,cAAc,EAAEC,uBAAuB,QAAQ,yBAAsB;;AAEtF;AACA,SAASC,OAAO,QAAQ,oBAAiB;AACzC,SACEC,eAAe,EACfC,mBAAmB,EACnBC,mBAAmB,EACnBC,qBAAqB,QAChB,4BAAyB;AAChC,SAASC,eAAe,EAAEC,uBAAuB,QAAQ,4BAAyB;AAElF;AACA;AACA,SACEC,eAAe,EACfC,gCAAgC,QAC3B,uCAAoC;AAI3C,SAASC,8BAA8B,QAAQ,iCAA8B;AAE7E,SAASC,SAAS,EAAEC,iBAAiB,EAAEC,qBAAqB,QAAQ,sBAAmB;AACvF,SAASC,eAAe,QAAQ,4BAAyB;AACzD,SAASC,cAAc,EAAEC,oBAAoB,QAAQ,mCAAgC;AAErF,SACEC,cAAc,EACdC,eAAe,EACfC,cAAc,EACdC,WAAW,EACXC,iBAAiB,QACZ,sCAAmC;AAC1C,SAASC,UAAU,QAAQ,uBAAoB;AAC/C;AACA;AACA,SAASC,WAAW,QAAQ,wBAAqB;AACjD;AACA;AACA;AACA;AACA,SACEC,gBAAgB,EAChBC,eAAe,EACfC,aAAa,QACR,0CAAuC;AAC9C,SAASC,kBAAkB,QAAQ,+BAA4B;AAC/D,SAASC,iBAAiB,QAAQ,8BAA2B;AAE7D,SAASC,eAAe,QAAQ,4BAAyB;AACzD,SAASC,kBAAkB,QAAQ,+BAA4B;AAC/D,SAASC,eAAe,QAAQ,4BAAyB;AACzD,SAASC,uBAAuB,QAAQ,yCAAsC;AAG9E;AACA;;AAEA;AACA,SACEC,oBAAoB,EACpBC,0BAA0B,EAC1BC,2BAA2B,QACtB,6BAA0B;AAGjC;AACA,SACEC,SAAS,EACTC,wBAAwB,EACxBC,qBAAqB,EACrBC,wBAAwB,EACxBC,uBAAuB,EACvBC,wBAAwB,EACxBC,yBAAyB,EACzBC,wBAAwB,EACxBC,yBAAyB,EACzBC,8BAA8B,EAC9BC,4BAA4B,QACvB,8BAA2B;AAClC,SACEC,gBAAgB,EAChBC,iBAAiB,EACjBC,qBAAqB,EACrBC,8BAA8B,EAC9BC,8BAA8B,QACzB,8BAA2B;AAOlC;AACA,SAASC,YAAY,QAAQ,uBAAoB;;AAEjD;AACA,SACEC,eAAe,EACfC,qBAAqB,EACrBC,uBAAuB,EACvBC,mBAAmB,QACd,0BAAuB","ignoreList":[]}
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * useAccountTheme / useAccountThemeControls
5
+ *
6
+ * The Oxy account carries a portable theme (`user.themePreference`: a mode and
7
+ * a colour preset) that every Oxy app can wear. The COLOUR is the account
8
+ * colour and always applies (`useAccountColor`). Whether an app also follows
9
+ * the account's MODE is the viewer's choice per device: the theme SOURCE.
10
+ *
11
+ * - `account` (the default): the account's mode is applied to Bloom, and a mode
12
+ * chosen here is written back to the account for the other Oxy apps.
13
+ * - `app`: the mode stays on this device; nothing is written to the account.
14
+ *
15
+ * The source is a local preference, never sent anywhere. On web it is read
16
+ * synchronously, so the first paint already knows it; on native it resolves
17
+ * from AsyncStorage right after mount. Bloom's own persistence still paints the
18
+ * last theme instantly on cold boot, so the account theme lands without a flash
19
+ * once the session resolves.
20
+ */
21
+
22
+ import { useCallback, useEffect } from 'react';
23
+ import { create } from 'zustand';
24
+ import { logger } from '@oxy.so/core';
25
+ import { useBloomTheme } from '@oxy.so/bloom/theme';
26
+ import { createPlatformStorage, isReactNative } from "../utils/storageHelpers.js";
27
+ import { resolveAccountColor, useAccountColor } from "./useAccountColor.js";
28
+ import { useAuth } from "./useAuth.js";
29
+ import { useUpdateProfile } from "./mutations/useAccountMutations.js";
30
+
31
+ /** Where the app's theme MODE comes from on this device. */
32
+
33
+ const THEME_SOURCE_KEY = 'oxy.theme.source';
34
+ function normalizeSource(stored) {
35
+ return stored === 'app' ? 'app' : 'account';
36
+ }
37
+
38
+ /**
39
+ * Bloom's richer mode set onto the portable subset the account stores
40
+ * (`adaptive` has no cross-app meaning, so it is `system`).
41
+ */
42
+ function toPortableMode(mode) {
43
+ return mode === 'light' || mode === 'dark' ? mode : 'system';
44
+ }
45
+
46
+ /** Web reads `localStorage` synchronously; native resolves in `hydrate`. */
47
+ function readInitialSource() {
48
+ if (isReactNative() || typeof window === 'undefined') {
49
+ return {
50
+ source: 'account',
51
+ hydrated: false
52
+ };
53
+ }
54
+ try {
55
+ return {
56
+ source: normalizeSource(window.localStorage?.getItem(THEME_SOURCE_KEY)),
57
+ hydrated: true
58
+ };
59
+ } catch {
60
+ // A sandboxed document's storage getter throws: no stored choice.
61
+ return {
62
+ source: 'account',
63
+ hydrated: true
64
+ };
65
+ }
66
+ }
67
+ const useThemeSourceStore = create((set, get) => ({
68
+ ...readInitialSource(),
69
+ setSource(source) {
70
+ set({
71
+ source,
72
+ hydrated: true
73
+ });
74
+ void createPlatformStorage().then(storage => storage.setItem(THEME_SOURCE_KEY, source)).catch(() => undefined);
75
+ },
76
+ async hydrate() {
77
+ if (get().hydrated) return;
78
+ const stored = await createPlatformStorage().then(storage => storage.getItem(THEME_SOURCE_KEY)).catch(() => null);
79
+ // A choice made while storage was being read wins over the stored one.
80
+ if (!get().hydrated) set({
81
+ source: normalizeSource(stored),
82
+ hydrated: true
83
+ });
84
+ }
85
+ }));
86
+
87
+ /**
88
+ * Apply the account theme to Bloom: the colour always (through
89
+ * `useAccountColor`, which `canUse` can narrow), the mode while this device's
90
+ * source is `account`. Mount ONCE, inside `OxyProvider` and Bloom's theme
91
+ * provider.
92
+ */
93
+ export function useAccountTheme({
94
+ canUse
95
+ } = {}) {
96
+ const {
97
+ isAuthenticated,
98
+ user
99
+ } = useAuth();
100
+ const source = useThemeSourceStore(state => state.source);
101
+ const hydrated = useThemeSourceStore(state => state.hydrated);
102
+ const hydrate = useThemeSourceStore(state => state.hydrate);
103
+ const {
104
+ setMode
105
+ } = useBloomTheme();
106
+ useAccountColor({
107
+ canUse
108
+ });
109
+ useEffect(() => {
110
+ void hydrate();
111
+ }, [hydrate]);
112
+ const accountMode = user?.themePreference?.mode;
113
+ useEffect(() => {
114
+ if (!hydrated || !isAuthenticated || source !== 'account' || !accountMode) return;
115
+ setMode(accountMode);
116
+ }, [hydrated, isAuthenticated, source, accountMode, setMode]);
117
+ }
118
+ /**
119
+ * Source-aware theme mode changes for a settings screen. Bloom changes at once;
120
+ * on the `account` source the account's portable theme follows. Without a
121
+ * usable session the effective source is `app`, so changes stay local, and the
122
+ * stored choice applies again once signed in. The colour is chosen with
123
+ * `useAccountColorSave`.
124
+ */
125
+ export function useAccountThemeControls() {
126
+ const {
127
+ user,
128
+ canUsePrivateApi
129
+ } = useAuth();
130
+ const {
131
+ mode,
132
+ colorPreset,
133
+ setMode
134
+ } = useBloomTheme();
135
+ const {
136
+ mutateAsync
137
+ } = useUpdateProfile();
138
+ const storedSource = useThemeSourceStore(state => state.source);
139
+ const setSource = useThemeSourceStore(state => state.setSource);
140
+ const source = canUsePrivateApi ? storedSource : 'app';
141
+ const persist = useCallback(async next => {
142
+ await mutateAsync({
143
+ themePreference: {
144
+ mode: toPortableMode(next.mode),
145
+ colorPreset: next.colorPreset
146
+ }
147
+ });
148
+ }, [mutateAsync]);
149
+ const changeThemeMode = useCallback(async nextMode => {
150
+ setMode(nextMode);
151
+ if (source === 'account') await persist({
152
+ mode: nextMode,
153
+ colorPreset
154
+ });
155
+ }, [setMode, source, persist, colorPreset]);
156
+ const accountTheme = user?.themePreference;
157
+ const hasAccountTheme = !!accountTheme && resolveAccountColor({
158
+ themePreference: accountTheme
159
+ }) !== null;
160
+ const changeThemeSource = useCallback(nextSource => {
161
+ setSource(nextSource);
162
+ // An existing account theme is applied by `useAccountTheme`; only an
163
+ // account without one is seeded, from what the viewer sees now.
164
+ if (nextSource !== 'account' || !canUsePrivateApi || hasAccountTheme) return;
165
+ persist({
166
+ mode,
167
+ colorPreset
168
+ }).catch(error => {
169
+ logger.error('Failed to seed the account theme', error);
170
+ });
171
+ }, [setSource, canUsePrivateApi, hasAccountTheme, persist, mode, colorPreset]);
172
+ return {
173
+ source,
174
+ changeThemeSource,
175
+ changeThemeMode
176
+ };
177
+ }
178
+ //# sourceMappingURL=useAccountTheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCallback","useEffect","create","logger","useBloomTheme","createPlatformStorage","isReactNative","resolveAccountColor","useAccountColor","useAuth","useUpdateProfile","THEME_SOURCE_KEY","normalizeSource","stored","toPortableMode","mode","readInitialSource","window","source","hydrated","localStorage","getItem","useThemeSourceStore","set","get","setSource","then","storage","setItem","catch","undefined","hydrate","useAccountTheme","canUse","isAuthenticated","user","state","setMode","accountMode","themePreference","useAccountThemeControls","canUsePrivateApi","colorPreset","mutateAsync","storedSource","persist","next","changeThemeMode","nextMode","accountTheme","hasAccountTheme","changeThemeSource","nextSource","error"],"sourceRoot":"../../../../src","sources":["ui/hooks/useAccountTheme.ts"],"mappings":"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","ignoreList":[]}