@waline/client 2.0.2 → 2.0.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/client",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "client for waline comment system",
5
5
  "keywords": [
6
6
  "valine",
@@ -9,9 +9,15 @@
9
9
  "blog"
10
10
  ],
11
11
  "repository": {
12
- "url": "https://github.com/walinejs/waline"
12
+ "url": "https://github.com/walinejs/waline",
13
+ "directory": "packages/client"
13
14
  },
14
15
  "license": "MIT",
16
+ "author": {
17
+ "name": "Mr.Hope",
18
+ "email": "mister-hope@outlook.com",
19
+ "url": "https://mrhope.site"
20
+ },
15
21
  "exports": {
16
22
  ".": {
17
23
  "import": "./dist/shim.esm.js",
@@ -53,14 +59,15 @@
53
59
  ]
54
60
  },
55
61
  "dependencies": {
56
- "autosize": "5.0.1",
57
- "hanabi": "0.4.0",
58
- "marked": "4.0.14",
59
- "vue": "3.2.33"
62
+ "@vueuse/core": "^8.3.1",
63
+ "autosize": "^5.0.1",
64
+ "hanabi": "^0.4.0",
65
+ "marked": "^4.0.14",
66
+ "vue": "^3.2.33"
60
67
  },
61
68
  "devDependencies": {
62
- "@types/autosize": "4.0.1",
63
- "@types/marked": "4.0.3"
69
+ "@types/autosize": "^4.0.1",
70
+ "@types/marked": "^4.0.3"
64
71
  },
65
72
  "engines": {
66
73
  "node": ">=12.20.0"
package/src/comment.ts CHANGED
@@ -40,7 +40,7 @@ WalineCommentCountOptions): WalineAbort => {
40
40
  // comment count
41
41
  const elements = document.querySelectorAll<HTMLElement>(selector);
42
42
 
43
- const { userInfo } = useUserInfo();
43
+ const userInfo = useUserInfo();
44
44
 
45
45
  if (elements.length)
46
46
  void fetchCommentCount({
@@ -273,8 +273,8 @@ export default defineComponent({
273
273
  setup(props, { emit }) {
274
274
  const config = inject<ComputedRef<Config>>('config') as ComputedRef<Config>;
275
275
 
276
- const { inputs, store } = useInputs();
277
- const { userInfo, setUserInfo } = useUserInfo();
276
+ const inputs = useInputs();
277
+ const userInfo = useUserInfo();
278
278
 
279
279
  const inputRefs = ref<Record<string, HTMLInputElement>>({});
280
280
  const editorRef = ref<HTMLTextAreaElement | null>(null);
@@ -308,7 +308,7 @@ export default defineComponent({
308
308
  const endPosition = textArea.selectionEnd || 0;
309
309
  const scrollTop = textArea.scrollTop;
310
310
 
311
- inputs.editor =
311
+ inputs.value.editor =
312
312
  textArea.value.substring(0, startPosition) +
313
313
  content +
314
314
  textArea.value.substring(endPosition, textArea.value.length);
@@ -333,7 +333,7 @@ export default defineComponent({
333
333
  return Promise.resolve()
334
334
  .then(() => (config.value.imageUploader as WalineImageUploader)(file))
335
335
  .then((url) => {
336
- inputs.editor = inputs.editor.replace(
336
+ inputs.value.editor = inputs.value.editor.replace(
337
337
  uploadText,
338
338
  `\r\n![${file.name}](${url})`
339
339
  );
@@ -374,9 +374,9 @@ export default defineComponent({
374
374
 
375
375
  const comment: WalineCommentData = {
376
376
  comment: content.value,
377
- nick: inputs.nick,
378
- mail: inputs.mail,
379
- link: inputs.link,
377
+ nick: inputs.value.nick,
378
+ mail: inputs.value.mail,
379
+ link: inputs.value.link,
380
380
  ua: navigator.userAgent,
381
381
  url: config.value.path,
382
382
  };
@@ -441,18 +441,12 @@ export default defineComponent({
441
441
  .then((resp) => {
442
442
  isSubmitting.value = false;
443
443
 
444
- store.update({
445
- nick: comment.nick,
446
- link: comment.link,
447
- mail: comment.mail,
448
- });
449
-
450
444
  if (resp.errmsg) return alert(resp.errmsg);
451
445
 
452
446
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
453
447
  emit('submit', resp.data!);
454
448
 
455
- inputs.editor = '';
449
+ inputs.value.editor = '';
456
450
 
457
451
  previewText.value = '';
458
452
 
@@ -488,7 +482,7 @@ export default defineComponent({
488
482
 
489
483
  if (data.data.token) {
490
484
  handler?.close();
491
- setUserInfo(data.data);
485
+ userInfo.value = data.data;
492
486
  (data.data.remember ? localStorage : sessionStorage).setItem(
493
487
  'WALINE_USER',
494
488
  JSON.stringify(data.data)
@@ -502,7 +496,7 @@ export default defineComponent({
502
496
  };
503
497
 
504
498
  const onLogout = (): void => {
505
- setUserInfo({});
499
+ userInfo.value = {};
506
500
  localStorage.setItem('WALINE_USER', 'null');
507
501
  sessionStorage.setItem('WALINE_USER', 'null');
508
502
  };
@@ -529,7 +523,8 @@ export default defineComponent({
529
523
  const receiver = ({ data }: any): void => {
530
524
  if (!data || data.type !== 'profile') return;
531
525
 
532
- setUserInfo(Object.assign({}, userInfo.value, data));
526
+ userInfo.value = { ...userInfo.value, ...data };
527
+
533
528
  [localStorage, sessionStorage]
534
529
  .filter((store) => store.getItem('WALINE_USER'))
535
530
  .forEach((store) =>
@@ -551,7 +546,7 @@ export default defineComponent({
551
546
 
552
547
  // watch editor
553
548
  watch(
554
- () => inputs.editor,
549
+ () => inputs.value.editor,
555
550
  (value) => {
556
551
  const { highlighter, texRenderer } = config.value;
557
552
 
@@ -24,7 +24,7 @@
24
24
  />
25
25
  <span v-if="comment.sticky" class="wl-badge" v-text="locale.sticky" />
26
26
 
27
- <span class="wl-time" v-text="timeAgo(comment.insertedAt, locale)" />
27
+ <span class="wl-time" v-text="time" />
28
28
 
29
29
  <button
30
30
  class="wl-reply"
@@ -69,7 +69,8 @@
69
69
  import { computed, defineComponent, inject } from 'vue';
70
70
  import CommentBox from './CommentBox.vue';
71
71
  import { ReplyIcon, VerifiedIcon } from './Icons';
72
- import { isLinkHttp, timeAgo } from '../utils';
72
+ import { isLinkHttp } from '../utils';
73
+ import { useTimeAgo } from '../composables';
73
74
 
74
75
  import type { ComputedRef, PropType } from 'vue';
75
76
  import type { Config } from '../utils';
@@ -108,6 +109,8 @@ export default defineComponent({
108
109
  return link ? (isLinkHttp(link) ? link : `https://${link}`) : '';
109
110
  });
110
111
 
112
+ const time = useTimeAgo(props.comment.insertedAt, locale.value);
113
+
111
114
  const isReplyingCurrent = computed(
112
115
  () => props.comment.objectId === props.reply?.objectId
113
116
  );
@@ -118,7 +121,7 @@ export default defineComponent({
118
121
 
119
122
  isReplyingCurrent,
120
123
  link,
121
- timeAgo,
124
+ time,
122
125
  };
123
126
  },
124
127
  });
@@ -114,7 +114,6 @@ export default defineComponent({
114
114
 
115
115
  meta: {
116
116
  type: Array,
117
- // default: (): Meta[] => ['nick', 'mail', 'link'],
118
117
  ...(SHOULD_VALIDATE
119
118
  ? {
120
119
  validator: (value: unknown): boolean =>
@@ -126,7 +125,6 @@ export default defineComponent({
126
125
 
127
126
  requiredMeta: {
128
127
  type: Array,
129
- // default: (): Meta[] => [],
130
128
  ...(SHOULD_VALIDATE
131
129
  ? {
132
130
  validator: (value: unknown): boolean =>
@@ -138,17 +136,14 @@ export default defineComponent({
138
136
 
139
137
  visitor: {
140
138
  type: Boolean,
141
- // default: false,
142
139
  },
143
140
 
144
141
  dark: {
145
142
  type: [String, Boolean],
146
- // default: false,
147
143
  },
148
144
 
149
145
  lang: {
150
146
  type: String,
151
- // default: 'zh-CN',
152
147
  ...(SHOULD_VALIDATE
153
148
  ? {
154
149
  validator: (value: unknown): boolean =>
@@ -163,7 +158,6 @@ export default defineComponent({
163
158
 
164
159
  pageSize: {
165
160
  type: Number,
166
- // default: 10,
167
161
  },
168
162
 
169
163
  wordLimit: {
@@ -182,9 +176,6 @@ export default defineComponent({
182
176
 
183
177
  emoji: {
184
178
  type: Array as PropType<(string | WalineEmojiInfo)[]>,
185
- // default: (): string[] => [
186
- // 'https://cdn.jsdelivr.net/gh/walinejs/emojis/weibo',
187
- // ],
188
179
  ...(SHOULD_VALIDATE
189
180
  ? {
190
181
  validator: (value: unknown): boolean =>
@@ -207,38 +198,25 @@ export default defineComponent({
207
198
 
208
199
  login: {
209
200
  type: String as PropType<'enable' | 'disable' | 'force'>,
210
- // default: 'enable',
211
201
  },
212
202
 
213
203
  highlighter: {
214
204
  type: Function as PropType<WalineHighlighter>,
215
- // default: (text: string): string => text,
216
205
  },
217
206
 
218
207
  imageUploader: {
219
- type: [Function, false] as PropType<WalineImageUploader>,
220
- // default: (file: File): Promise<string> =>
221
- // new Promise((resolve, reject) => {
222
- // const reader = new FileReader();
223
- // reader.readAsDataURL(file);
224
- // reader.onload = (): void => resolve(reader.result?.toString() || '');
225
- // reader.onerror = reject;
226
- // }),
208
+ type: [Function, Boolean] as PropType<WalineImageUploader | false>,
227
209
  },
228
210
 
229
211
  texRenderer: {
230
- type: Function as PropType<WalineTexRenderer>,
231
- // default: (blockMode: boolean): string =>
232
- // blockMode === true
233
- // ? '<p class="wl-tex">Tex is not available in preview</p>'
234
- // : '<span class="wl-tex">Tex is not available in preview</span>',
212
+ type: [Function, Boolean] as PropType<WalineTexRenderer | false>,
235
213
  },
236
214
  },
237
215
 
238
216
  setup(props) {
239
217
  const config = computed(() => getConfig(props as WalineProps));
240
218
 
241
- const { userInfo } = useUserInfo();
219
+ const userInfo = useUserInfo();
242
220
 
243
221
  const status = ref<'loading' | 'success' | 'error'>('loading');
244
222
 
@@ -1,3 +1,3 @@
1
1
  export * from './inputs';
2
+ export * from './timeAgo';
2
3
  export * from './userInfo';
3
- export * from './store';
@@ -1,7 +1,5 @@
1
- import { reactive } from 'vue';
2
- import { useStore } from './store';
3
-
4
- import type { Store } from './store';
1
+ import { useStorage } from '@vueuse/core';
2
+ import type { RemovableRef } from '@vueuse/core';
5
3
 
6
4
  export interface Inputs {
7
5
  nick: string;
@@ -10,20 +8,10 @@ export interface Inputs {
10
8
  editor: string;
11
9
  }
12
10
 
13
- let store: Store;
14
- let inputs: Inputs;
15
-
16
- export const useInputs = (): { inputs: Inputs; store: Store } => {
17
- if (!inputs) {
18
- store = useStore('WALINE_USER_CACHE');
19
-
20
- inputs = reactive({
21
- nick: store.get<string>('nick') || '',
22
- mail: store.get<string>('mail') || '',
23
- link: store.get<string>('link') || '',
24
- editor: '',
25
- });
26
- }
27
-
28
- return { inputs, store };
29
- };
11
+ export const useInputs = (): RemovableRef<Inputs> =>
12
+ useStorage<Inputs>('WALINE_USER_CACHE', {
13
+ nick: '',
14
+ mail: '',
15
+ link: '',
16
+ editor: '',
17
+ });
@@ -0,0 +1,61 @@
1
+ import { useNow } from '@vueuse/core';
2
+ import { computed } from 'vue';
3
+ import { dateFormat } from '../utils';
4
+
5
+ import type { ComputedRef } from 'vue';
6
+ import type { WalineLocale } from '../typings';
7
+
8
+ export const useTimeAgo = (
9
+ date: Date | string,
10
+ locale: WalineLocale
11
+ ): ComputedRef<string> => {
12
+ const now = useNow();
13
+
14
+ return computed(() => {
15
+ if (!date) return '';
16
+
17
+ const time =
18
+ typeof date === 'string'
19
+ ? new Date(date.indexOf(' ') !== -1 ? date.replace(/-/g, '/') : date)
20
+ : date;
21
+
22
+ const timepassed = now.value.getTime() - time.getTime();
23
+
24
+ const days = Math.floor(timepassed / (24 * 3600 * 1000));
25
+
26
+ if (days === 0) {
27
+ // 计算相差小时数
28
+
29
+ // 计算天数后剩余的毫秒数
30
+ const leave1 = timepassed % (24 * 3600 * 1000);
31
+ const hours = Math.floor(leave1 / (3600 * 1000));
32
+
33
+ if (hours === 0) {
34
+ //计算相差分钟数
35
+
36
+ // 计算小时数后剩余的毫秒数
37
+ const leave2 = leave1 % (3600 * 1000);
38
+ const minutes = Math.floor(leave2 / (60 * 1000));
39
+
40
+ // 计算相差秒数
41
+ if (minutes === 0) {
42
+ // 计算分钟数后剩余的毫秒数
43
+ const leave3 = leave2 % (60 * 1000);
44
+ const seconds = Math.round(leave3 / 1000);
45
+
46
+ return `${seconds} ${locale.seconds}`;
47
+ }
48
+
49
+ return `${minutes} ${locale.minutes}`;
50
+ }
51
+
52
+ return `${hours} ${locale.hours}`;
53
+ }
54
+
55
+ if (days < 0) return locale.now;
56
+
57
+ if (days < 8) return `${days} ${locale.days}`;
58
+
59
+ return dateFormat(time);
60
+ });
61
+ };
@@ -1,27 +1,20 @@
1
- import { readonly, ref } from 'vue';
2
- import { getUserInfo } from '../utils';
1
+ import { useStorage } from '@vueuse/core';
3
2
 
4
3
  import type { Ref } from 'vue';
5
- import type { UserInfo } from '../utils';
6
4
 
7
- export type UserInfoRef = Ref<UserInfo | Record<string, never>>;
8
-
9
- const userInfo: UserInfoRef = ref({});
5
+ export interface UserInfo {
6
+ // eslint-disable-next-line @typescript-eslint/naming-convention
7
+ display_name: string;
8
+ email: string;
9
+ url: string;
10
+ token: string;
11
+ avatar: string;
12
+ mailMd5: string;
13
+ }
10
14
 
11
- export const useUserInfo = (): {
12
- userInfo: UserInfoRef;
13
- setUserInfo: (userInfo: UserInfo | Record<string, never>) => void;
14
- } => {
15
- if (!userInfo.value.token) {
16
- const info = getUserInfo();
15
+ export const USER_KEY = 'WALINE_USER';
17
16
 
18
- if (info) userInfo.value = info;
19
- }
17
+ export type UserInfoRef = Ref<UserInfo | Record<string, never>>;
20
18
 
21
- return {
22
- userInfo: readonly(userInfo),
23
- setUserInfo: (info: UserInfo | Record<string, never>): void => {
24
- userInfo.value = info;
25
- },
26
- };
27
- };
19
+ export const useUserInfo = (): UserInfoRef =>
20
+ useStorage<UserInfo | Record<string, never>>('USER_KEY', {});
package/src/init.ts CHANGED
@@ -97,7 +97,7 @@ export const init = ({
97
97
  path = window.location.pathname,
98
98
  ...newProps
99
99
  }: Partial<Omit<WalineInitOptions, 'el'>>): void => {
100
- Object.entries(newProps).map(([key, value]) => {
100
+ Object.entries(newProps).forEach(([key, value]) => {
101
101
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
102
102
  // @ts-ignore
103
103
  // eslint-disable-next-line
@@ -0,0 +1,17 @@
1
+ const padWithZeros = (vNumber: number, width: number): string => {
2
+ let numAsString = vNumber.toString();
3
+
4
+ while (numAsString.length < width) {
5
+ numAsString = '0' + numAsString;
6
+ }
7
+
8
+ return numAsString;
9
+ };
10
+
11
+ export const dateFormat = (date: Date): string => {
12
+ const vDay = padWithZeros(date.getDate(), 2);
13
+ const vMonth = padWithZeros(date.getMonth() + 1, 2);
14
+ const vYear = padWithZeros(date.getFullYear(), 2);
15
+
16
+ return `${vYear}-${vMonth}-${vDay}`;
17
+ };
@@ -1,21 +1,23 @@
1
- import { Store, useStore } from '../composables/store';
1
+ import { useStorage } from '@vueuse/core';
2
2
  import { removeEndingSplash } from './path';
3
3
 
4
4
  import type { EmojiConfig } from './config';
5
5
  import type { WalineEmojiInfo } from '../typings';
6
6
 
7
- let store: Store;
8
-
9
7
  const hasVersion = (url: string): boolean =>
10
8
  Boolean(/@[0-9]+\.[0-9]+\.[0-9]+/.test(url));
11
9
 
12
10
  const fetchEmoji = (link: string): Promise<WalineEmojiInfo> => {
13
- if (!store) store = useStore('WALINE_EMOJI');
11
+ const emojiStore = useStorage<Record<string, WalineEmojiInfo>>(
12
+ 'WALINE_EMOJI',
13
+ {}
14
+ );
14
15
 
15
16
  const result = hasVersion(link);
16
17
 
17
18
  if (result) {
18
- const info = store.get<WalineEmojiInfo>(link);
19
+ const info = emojiStore.value.link;
20
+
19
21
  if (info) return Promise.resolve(info);
20
22
  }
21
23
 
@@ -27,7 +29,7 @@ const fetchEmoji = (link: string): Promise<WalineEmojiInfo> => {
27
29
  ...emojiInfo,
28
30
  };
29
31
 
30
- if (result) store.set(link, info);
32
+ if (result) emojiStore.value.link = info;
31
33
 
32
34
  return info;
33
35
  });
File without changes
@@ -1,13 +1,12 @@
1
1
  export * from './config';
2
2
  export * from './darkmode';
3
- export * from './data';
3
+ export * from './date';
4
4
  export * from './emoji';
5
5
  export * from './error';
6
6
  export * from './fetch';
7
7
  export * from './getRoot';
8
+ export * from './image';
8
9
  export * from './markdown';
9
10
  export * from './path';
10
11
  export * from './query';
11
- export * from './timeAgo';
12
- export * from './userInfo';
13
12
  export * from './wordCount';
@@ -1,4 +1,5 @@
1
- import { fetchRecentComment, getRoot, getUserInfo } from '../utils';
1
+ import { useUserInfo } from '../composables';
2
+ import { fetchRecentComment, getRoot } from '../utils';
2
3
 
3
4
  import type { WalineComment } from '../typings';
4
5
 
@@ -46,6 +47,7 @@ export const RecentComments = ({
46
47
  serverURL,
47
48
  count,
48
49
  }: WalineRecentCommentsOptions): Promise<WalineRecentCommentsResult> => {
50
+ const userInfo = useUserInfo();
49
51
  const root = getRoot(el);
50
52
  const controller = new AbortController();
51
53
 
@@ -53,7 +55,7 @@ export const RecentComments = ({
53
55
  serverURL,
54
56
  count,
55
57
  signal: controller.signal,
56
- token: getUserInfo()?.token,
58
+ token: userInfo.value?.token,
57
59
  }).then((comments) => {
58
60
  if (root && comments.length) {
59
61
  root.innerHTML = `<ul class="wl-recent-list">${comments
@@ -1,38 +0,0 @@
1
- export interface Store {
2
- get: <T = unknown>(key: string) => T | null;
3
- set: <T = unknown>(key: string, content: T) => void;
4
- update: <T = unknown>(content: T) => void;
5
- }
6
-
7
- export const useStore = (cacheKey: string): Store => {
8
- let storage: Record<string, unknown> = {};
9
- const content = localStorage.getItem(cacheKey);
10
-
11
- if (content) {
12
- try {
13
- storage = JSON.parse(content) as Record<string, unknown>;
14
- } catch (err) {
15
- // do nothing
16
- }
17
- }
18
-
19
- return {
20
- get: <T>(key: string): T | null => (storage[key] as T) || null,
21
-
22
- set<T>(key: string, content: T): void {
23
- try {
24
- // make sure the content can be stringify and make a deep copy here
25
- storage[key] = JSON.parse(JSON.stringify(content));
26
- localStorage.setItem(cacheKey, JSON.stringify(storage));
27
- } catch (err) {
28
- // do nothing
29
- }
30
- },
31
-
32
- update<T>(content: T): void {
33
- // make sure the content can be stringify and make a deep copy here
34
- storage = JSON.parse(JSON.stringify(content)) as Record<string, unknown>;
35
- localStorage.setItem(cacheKey, JSON.stringify(storage));
36
- },
37
- };
38
- };
@@ -1,75 +0,0 @@
1
- import type { WalineLocale } from '../typings';
2
-
3
- const padWithZeros = (vNumber: number, width: number): string => {
4
- let numAsString = vNumber.toString();
5
-
6
- while (numAsString.length < width) {
7
- numAsString = '0' + numAsString;
8
- }
9
-
10
- return numAsString;
11
- };
12
-
13
- const dateFormat = (date: Date): string => {
14
- const vDay = padWithZeros(date.getDate(), 2);
15
- const vMonth = padWithZeros(date.getMonth() + 1, 2);
16
- const vYear = padWithZeros(date.getFullYear(), 2);
17
-
18
- return `${vYear}-${vMonth}-${vDay}`;
19
- };
20
-
21
- export const timeAgo = (date: Date | string, locale: WalineLocale): string => {
22
- if (date)
23
- try {
24
- if (typeof date === 'string') {
25
- // compat with mysql output date
26
- date = new Date(
27
- date.indexOf(' ') !== -1 ? date.replace(/-/g, '/') : date
28
- );
29
- }
30
- const oldTime = date.getTime();
31
- const currTime = new Date().getTime();
32
- const diffValue = currTime - oldTime;
33
-
34
- const days = Math.floor(diffValue / (24 * 3600 * 1000));
35
-
36
- // 计算相差小时数
37
- if (days === 0) {
38
- // 计算天数后剩余的毫秒数
39
- const leave1 = diffValue % (24 * 3600 * 1000);
40
- const hours = Math.floor(leave1 / (3600 * 1000));
41
-
42
- //计算相差分钟数
43
- if (hours === 0) {
44
- // 计算小时数后剩余的毫秒数
45
- const leave2 = leave1 % (3600 * 1000);
46
- const minutes = Math.floor(leave2 / (60 * 1000));
47
-
48
- // 计算相差秒数
49
- if (minutes === 0) {
50
- // 计算分钟数后剩余的毫秒数
51
- const leave3 = leave2 % (60 * 1000);
52
- const seconds = Math.round(leave3 / 1000);
53
-
54
- return `${seconds} ${locale.seconds}`;
55
- }
56
- return `${minutes} ${locale.minutes}`;
57
- }
58
- return `${hours} ${locale.hours}`;
59
- }
60
-
61
- if (days < 0) {
62
- return locale.now;
63
- }
64
-
65
- if (days < 8) {
66
- return `${days} ${locale.days}`;
67
- } else {
68
- return dateFormat(date);
69
- }
70
- } catch (error) {
71
- console.log(error);
72
- }
73
-
74
- return '';
75
- };
@@ -1,26 +0,0 @@
1
- export interface UserInfo {
2
- // eslint-disable-next-line @typescript-eslint/naming-convention
3
- display_name: string;
4
- email: string;
5
- url: string;
6
- token: string;
7
- avatar: string;
8
- mailMd5: string;
9
- }
10
-
11
- const USER_KEY = 'WALINE_USER';
12
-
13
- export const getUserInfo = (): UserInfo | null => {
14
- try {
15
- const localStorageData = localStorage.getItem(USER_KEY);
16
- const sessionStorageData = sessionStorage.getItem(USER_KEY);
17
-
18
- return localStorageData
19
- ? (JSON.parse(localStorageData) as UserInfo)
20
- : sessionStorageData
21
- ? (JSON.parse(sessionStorageData) as UserInfo)
22
- : null;
23
- } catch (err) {
24
- return null;
25
- }
26
- };