@data-fair/lib-vue 1.13.12 → 1.14.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.
- package/package.json +1 -1
- package/session.d.ts +19 -4
- package/session.js +39 -11
package/package.json
CHANGED
package/session.d.ts
CHANGED
|
@@ -42,11 +42,24 @@ export interface Colors {
|
|
|
42
42
|
admin: string;
|
|
43
43
|
'on-admin': string;
|
|
44
44
|
}
|
|
45
|
+
interface FullSiteInfo {
|
|
46
|
+
main?: boolean;
|
|
47
|
+
theme: {
|
|
48
|
+
logo?: string;
|
|
49
|
+
colors: Colors;
|
|
50
|
+
dark: boolean;
|
|
51
|
+
darkColors?: Colors;
|
|
52
|
+
hc: boolean;
|
|
53
|
+
hcColors?: Colors;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
45
56
|
export interface SiteInfo {
|
|
46
57
|
main?: boolean;
|
|
47
58
|
logo?: string;
|
|
59
|
+
dark?: boolean;
|
|
48
60
|
colors: Colors;
|
|
49
61
|
}
|
|
62
|
+
type Theme = 'default' | 'dark' | 'hc';
|
|
50
63
|
export interface Session {
|
|
51
64
|
state: SessionState;
|
|
52
65
|
user: ComputedRef<SessionState['user']>;
|
|
@@ -54,8 +67,9 @@ export interface Session {
|
|
|
54
67
|
account: ComputedRef<SessionState['account']>;
|
|
55
68
|
accountRole: ComputedRef<SessionState['accountRole']>;
|
|
56
69
|
lang: ComputedRef<SessionState['lang']>;
|
|
57
|
-
|
|
70
|
+
theme: Ref<null | Theme>;
|
|
58
71
|
site: Ref<SiteInfo | null>;
|
|
72
|
+
fullSite: Ref<FullSiteInfo | null>;
|
|
59
73
|
loginUrl: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => string;
|
|
60
74
|
login: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => void;
|
|
61
75
|
logout: (redirect?: string) => Promise<void>;
|
|
@@ -65,7 +79,7 @@ export interface Session {
|
|
|
65
79
|
cancelDeletion: () => Promise<void>;
|
|
66
80
|
keepalive: () => Promise<void>;
|
|
67
81
|
refreshSiteInfo: () => Promise<void>;
|
|
68
|
-
|
|
82
|
+
switchTheme: (value: Theme) => void;
|
|
69
83
|
switchLang: (value: string) => void;
|
|
70
84
|
topLocation: Ref<Location | undefined>;
|
|
71
85
|
options: SessionOptions;
|
|
@@ -86,8 +100,9 @@ export declare function createSession(initOptions: Partial<SessionOptions>): Pro
|
|
|
86
100
|
account: ComputedRef<SessionState["account"]>;
|
|
87
101
|
accountRole: ComputedRef<SessionState["accountRole"]>;
|
|
88
102
|
lang: ComputedRef<SessionState["lang"]>;
|
|
89
|
-
|
|
103
|
+
theme: Ref<null | Theme>;
|
|
90
104
|
site: Ref<SiteInfo | null>;
|
|
105
|
+
fullSite: Ref<FullSiteInfo | null>;
|
|
91
106
|
loginUrl: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => string;
|
|
92
107
|
login: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => void;
|
|
93
108
|
logout: (redirect?: string) => Promise<void>;
|
|
@@ -97,7 +112,7 @@ export declare function createSession(initOptions: Partial<SessionOptions>): Pro
|
|
|
97
112
|
cancelDeletion: () => Promise<void>;
|
|
98
113
|
keepalive: () => Promise<void>;
|
|
99
114
|
refreshSiteInfo: () => Promise<void>;
|
|
100
|
-
|
|
115
|
+
switchTheme: (value: Theme) => void;
|
|
101
116
|
switchLang: (value: string) => void;
|
|
102
117
|
topLocation: Ref<Location | undefined>;
|
|
103
118
|
options: SessionOptions;
|
package/session.js
CHANGED
|
@@ -9,6 +9,16 @@ export * from '@data-fair/lib-common-types/session/index.js'
|
|
|
9
9
|
const Cookies = cookiesModule
|
|
10
10
|
const debug = Debug('session')
|
|
11
11
|
debug.log = console.log.bind(console)
|
|
12
|
+
function getDefaultTheme (site) {
|
|
13
|
+
// see https://www.scottohara.me/blog/2021/10/01/detect-high-contrast-and-dark-modes.html
|
|
14
|
+
if (site.theme.hc) {
|
|
15
|
+
if (window.matchMedia && window.matchMedia('(forced-colors: active)').matches) { return 'hc' }
|
|
16
|
+
}
|
|
17
|
+
if (site.theme.dark) {
|
|
18
|
+
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { return 'dark' }
|
|
19
|
+
}
|
|
20
|
+
return 'default'
|
|
21
|
+
}
|
|
12
22
|
function jwtDecodeAlive (jwt) {
|
|
13
23
|
if (!jwt) { return }
|
|
14
24
|
const decoded = jwtDecode(jwt)
|
|
@@ -57,12 +67,13 @@ export async function getSession (initOptions) {
|
|
|
57
67
|
})
|
|
58
68
|
// the core state of the session that is filled by reading cookies
|
|
59
69
|
const state = reactive({})
|
|
70
|
+
const fullSite = ref(null)
|
|
60
71
|
const site = ref(null)
|
|
72
|
+
const theme = ref(null)
|
|
61
73
|
// cookies are the source of truth and this information is transformed into the state reactive object
|
|
62
74
|
const cookies = initOptions?.cookies ?? new Cookies(options.req?.headers.cookie)
|
|
63
75
|
const readState = () => {
|
|
64
|
-
|
|
65
|
-
state.dark = darkCookie === '1' || darkCookie === 'true'
|
|
76
|
+
theme.value = cookies.get('theme') ?? 'default'
|
|
66
77
|
const langCookie = cookies.get('i18n_lang')
|
|
67
78
|
state.lang = langCookie ?? options.defaultLang
|
|
68
79
|
const idToken = cookies.get('id_token')
|
|
@@ -198,15 +209,15 @@ export async function getSession (initOptions) {
|
|
|
198
209
|
await customFetch(`${options.directoryUrl}/api/users/${state.user.id}`, { method: 'PATCH', body: ({ plannedDeletion: null }) })
|
|
199
210
|
readState()
|
|
200
211
|
}
|
|
201
|
-
const switchDark = (value) => {
|
|
202
|
-
const maxAge = 60 * 60 * 24 * 365 // 1 year
|
|
203
|
-
cookies.set('theme_dark', `${value}`, { maxAge, path: cookiesPath })
|
|
204
|
-
readState()
|
|
205
|
-
}
|
|
206
212
|
const switchLang = (value) => {
|
|
207
213
|
const maxAge = 60 * 60 * 24 * 365 // 1 year
|
|
208
214
|
cookies.set('i18n_lang', value, { maxAge, path: cookiesPath })
|
|
209
|
-
|
|
215
|
+
goTo(null)
|
|
216
|
+
}
|
|
217
|
+
const switchTheme = (value) => {
|
|
218
|
+
const maxAge = 60 * 60 * 24 * 365 // 1 year
|
|
219
|
+
cookies.set('theme', value, { maxAge, path: cookiesPath })
|
|
220
|
+
goTo(null)
|
|
210
221
|
}
|
|
211
222
|
const keepalive = async () => {
|
|
212
223
|
if (state.user == null) { return }
|
|
@@ -226,7 +237,23 @@ export async function getSession (initOptions) {
|
|
|
226
237
|
}
|
|
227
238
|
const refreshSiteInfo = async () => {
|
|
228
239
|
const siteInfo = await customFetch(`${options.directoryUrl}/api/sites/_public`) ?? null
|
|
229
|
-
|
|
240
|
+
if (siteInfo.theme) {
|
|
241
|
+
fullSite.value = siteInfo
|
|
242
|
+
const partialSite = {
|
|
243
|
+
main: siteInfo.main,
|
|
244
|
+
logo: siteInfo.theme.logo,
|
|
245
|
+
colors: siteInfo.theme.colors
|
|
246
|
+
}
|
|
247
|
+
if (theme.value == null) { theme.value = getDefaultTheme(siteInfo) }
|
|
248
|
+
if (theme.value === 'hc') { partialSite.colors = siteInfo.theme.hcColors }
|
|
249
|
+
if (theme.value === 'dark') {
|
|
250
|
+
partialSite.colors = siteInfo.theme.darkColors
|
|
251
|
+
partialSite.dark = true
|
|
252
|
+
}
|
|
253
|
+
site.value = partialSite
|
|
254
|
+
} else {
|
|
255
|
+
site.value = siteInfo
|
|
256
|
+
}
|
|
230
257
|
}
|
|
231
258
|
if (options.siteInfo) { await refreshSiteInfo() }
|
|
232
259
|
// immediately performs a keepalive, but only on top windows (not iframes or popups)
|
|
@@ -252,9 +279,10 @@ export async function getSession (initOptions) {
|
|
|
252
279
|
user: computed(() => state.user),
|
|
253
280
|
account: computed(() => state.account),
|
|
254
281
|
accountRole: computed(() => state.accountRole),
|
|
255
|
-
dark: computed(() => state.dark),
|
|
256
282
|
lang: computed(() => state.lang),
|
|
283
|
+
theme,
|
|
257
284
|
site,
|
|
285
|
+
fullSite,
|
|
258
286
|
loginUrl,
|
|
259
287
|
login,
|
|
260
288
|
logout,
|
|
@@ -264,7 +292,7 @@ export async function getSession (initOptions) {
|
|
|
264
292
|
cancelDeletion,
|
|
265
293
|
keepalive,
|
|
266
294
|
refreshSiteInfo,
|
|
267
|
-
|
|
295
|
+
switchTheme,
|
|
268
296
|
switchLang,
|
|
269
297
|
topLocation,
|
|
270
298
|
options
|