@waline/client 2.0.1 → 2.0.4
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/dist/component.js +1 -1
- package/dist/component.js.map +1 -1
- package/dist/legacy.js +1 -1
- package/dist/legacy.js.map +1 -1
- package/dist/pageview.cjs.js +1 -1
- package/dist/pageview.cjs.js.map +1 -1
- package/dist/pageview.esm.js +1 -1
- package/dist/pageview.esm.js.map +1 -1
- package/dist/pageview.js +1 -1
- package/dist/pageview.js.map +1 -1
- package/dist/shim.d.ts +29 -4
- package/dist/shim.esm.d.ts +29 -4
- package/dist/shim.esm.js +1 -1
- package/dist/shim.esm.js.map +1 -1
- package/dist/shim.js +1 -1
- package/dist/shim.js.map +1 -1
- package/dist/waline.cjs.d.ts +29 -4
- package/dist/waline.cjs.js +1 -1
- package/dist/waline.cjs.js.map +1 -1
- package/dist/waline.css +1 -1
- package/dist/waline.css.map +1 -1
- package/dist/waline.d.ts +29 -4
- package/dist/waline.esm.d.ts +29 -4
- package/dist/waline.esm.js +1 -1
- package/dist/waline.esm.js.map +1 -1
- package/dist/waline.js +1 -1
- package/dist/waline.js.map +1 -1
- package/package.json +15 -8
- package/src/comment.ts +1 -1
- package/src/compact/convert.ts +2 -2
- package/src/components/CommentBox.vue +52 -55
- package/src/components/CommentCard.vue +10 -5
- package/src/components/Waline.vue +6 -32
- package/src/composables/index.ts +1 -1
- package/src/composables/inputs.ts +9 -21
- package/src/composables/timeAgo.ts +61 -0
- package/src/composables/userInfo.ts +14 -21
- package/src/config/default.ts +2 -2
- package/src/init.ts +1 -1
- package/src/pageview.ts +1 -1
- package/src/styles/layout.scss +1 -1
- package/src/styles/panel.scss +0 -2
- package/src/utils/config.ts +17 -30
- package/src/utils/date.ts +17 -0
- package/src/utils/emoji.ts +11 -9
- package/src/utils/{data.ts → image.ts} +0 -0
- package/src/utils/index.ts +2 -3
- package/src/utils/markdown.ts +1 -1
- package/src/widgets/recentComments.ts +35 -5
- package/src/composables/store.ts +0 -38
- package/src/utils/timeAgo.ts +0 -75
- package/src/utils/userInfo.ts +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waline/client",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
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
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
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
|
|
43
|
+
const userInfo = useUserInfo();
|
|
44
44
|
|
|
45
45
|
if (elements.length)
|
|
46
46
|
void fetchCommentCount({
|
package/src/compact/convert.ts
CHANGED
|
@@ -27,7 +27,7 @@ export const covertOptions = (
|
|
|
27
27
|
visitor,
|
|
28
28
|
|
|
29
29
|
pageview = visitor === true
|
|
30
|
-
? '.leancloud_visitors,.waline-visitor-count,.waline-pageview-count'
|
|
30
|
+
? '.leancloud_visitors,.leancloud-visitors,.waline-visitor-count,.waline-pageview-count'
|
|
31
31
|
: visitor,
|
|
32
32
|
locale = langMode,
|
|
33
33
|
emoji,
|
|
@@ -51,7 +51,7 @@ export const covertOptions = (
|
|
|
51
51
|
warning(`Option "${item}" is REMOVED and CAN NOT be polyfilled!`)
|
|
52
52
|
);
|
|
53
53
|
|
|
54
|
-
// warnings with those which
|
|
54
|
+
// warnings with those which is being polyfilled
|
|
55
55
|
DROPPED_OPTIONS_WHICH_CAN_STILL_BE_POLYFILLED.filter(([oldOption]) =>
|
|
56
56
|
Object.keys(options).includes(oldOption)
|
|
57
57
|
).forEach(([oldOption, newOption]) =>
|
|
@@ -58,10 +58,8 @@
|
|
|
58
58
|
@paste="onPaste"
|
|
59
59
|
/>
|
|
60
60
|
|
|
61
|
-
<div
|
|
62
|
-
|
|
63
|
-
:style="{ display: showPreview ? 'block' : 'none' }"
|
|
64
|
-
>
|
|
61
|
+
<div class="wl-preview" v-show="showPreview">
|
|
62
|
+
<hr />
|
|
65
63
|
<h4>{{ locale.preview }}:</h4>
|
|
66
64
|
<div class="wl-content" v-html="previewText" />
|
|
67
65
|
</div>
|
|
@@ -237,11 +235,12 @@ import {
|
|
|
237
235
|
getWordNumber,
|
|
238
236
|
parseEmoji,
|
|
239
237
|
postComment,
|
|
238
|
+
getEmojis,
|
|
240
239
|
} from '../utils';
|
|
241
240
|
|
|
242
241
|
import type { ComputedRef, DeepReadonly } from 'vue';
|
|
243
242
|
import type { WalineCommentData, WalineImageUploader } from '../typings';
|
|
244
|
-
import type {
|
|
243
|
+
import type { WalineConfig, WalineEmojiConfig } from '../utils';
|
|
245
244
|
|
|
246
245
|
export default defineComponent({
|
|
247
246
|
name: 'CommentBox',
|
|
@@ -273,10 +272,12 @@ export default defineComponent({
|
|
|
273
272
|
emits: ['submit', 'cancel-reply'],
|
|
274
273
|
|
|
275
274
|
setup(props, { emit }) {
|
|
276
|
-
const config = inject<ComputedRef<
|
|
275
|
+
const config = inject<ComputedRef<WalineConfig>>(
|
|
276
|
+
'config'
|
|
277
|
+
) as ComputedRef<WalineConfig>;
|
|
277
278
|
|
|
278
|
-
const
|
|
279
|
-
const
|
|
279
|
+
const inputs = useInputs();
|
|
280
|
+
const userInfo = useUserInfo();
|
|
280
281
|
|
|
281
282
|
const inputRefs = ref<Record<string, HTMLInputElement>>({});
|
|
282
283
|
const editorRef = ref<HTMLTextAreaElement | null>(null);
|
|
@@ -284,7 +285,7 @@ export default defineComponent({
|
|
|
284
285
|
const emojiButtonRef = ref<HTMLDivElement | null>(null);
|
|
285
286
|
const emojiPopupRef = ref<HTMLDivElement | null>(null);
|
|
286
287
|
|
|
287
|
-
const emoji = ref<DeepReadonly<
|
|
288
|
+
const emoji = ref<DeepReadonly<WalineEmojiConfig>>({ tabs: [], map: {} });
|
|
288
289
|
const emojiTabIndex = ref(0);
|
|
289
290
|
const showEmoji = ref(false);
|
|
290
291
|
const showPreview = ref(false);
|
|
@@ -310,7 +311,7 @@ export default defineComponent({
|
|
|
310
311
|
const endPosition = textArea.selectionEnd || 0;
|
|
311
312
|
const scrollTop = textArea.scrollTop;
|
|
312
313
|
|
|
313
|
-
inputs.editor =
|
|
314
|
+
inputs.value.editor =
|
|
314
315
|
textArea.value.substring(0, startPosition) +
|
|
315
316
|
content +
|
|
316
317
|
textArea.value.substring(endPosition, textArea.value.length);
|
|
@@ -335,7 +336,7 @@ export default defineComponent({
|
|
|
335
336
|
return Promise.resolve()
|
|
336
337
|
.then(() => (config.value.imageUploader as WalineImageUploader)(file))
|
|
337
338
|
.then((url) => {
|
|
338
|
-
inputs.editor = inputs.editor.replace(
|
|
339
|
+
inputs.value.editor = inputs.value.editor.replace(
|
|
339
340
|
uploadText,
|
|
340
341
|
`\r\n`
|
|
341
342
|
);
|
|
@@ -376,9 +377,9 @@ export default defineComponent({
|
|
|
376
377
|
|
|
377
378
|
const comment: WalineCommentData = {
|
|
378
379
|
comment: content.value,
|
|
379
|
-
nick: inputs.nick,
|
|
380
|
-
mail: inputs.mail,
|
|
381
|
-
link: inputs.link,
|
|
380
|
+
nick: inputs.value.nick,
|
|
381
|
+
mail: inputs.value.mail,
|
|
382
|
+
link: inputs.value.link,
|
|
382
383
|
ua: navigator.userAgent,
|
|
383
384
|
url: config.value.path,
|
|
384
385
|
};
|
|
@@ -443,18 +444,12 @@ export default defineComponent({
|
|
|
443
444
|
.then((resp) => {
|
|
444
445
|
isSubmitting.value = false;
|
|
445
446
|
|
|
446
|
-
store.update({
|
|
447
|
-
nick: comment.nick,
|
|
448
|
-
link: comment.link,
|
|
449
|
-
mail: comment.mail,
|
|
450
|
-
});
|
|
451
|
-
|
|
452
447
|
if (resp.errmsg) return alert(resp.errmsg);
|
|
453
448
|
|
|
454
449
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
455
450
|
emit('submit', resp.data!);
|
|
456
451
|
|
|
457
|
-
inputs.editor = '';
|
|
452
|
+
inputs.value.editor = '';
|
|
458
453
|
|
|
459
454
|
previewText.value = '';
|
|
460
455
|
|
|
@@ -490,7 +485,7 @@ export default defineComponent({
|
|
|
490
485
|
|
|
491
486
|
if (data.data.token) {
|
|
492
487
|
handler?.close();
|
|
493
|
-
|
|
488
|
+
userInfo.value = data.data;
|
|
494
489
|
(data.data.remember ? localStorage : sessionStorage).setItem(
|
|
495
490
|
'WALINE_USER',
|
|
496
491
|
JSON.stringify(data.data)
|
|
@@ -504,7 +499,7 @@ export default defineComponent({
|
|
|
504
499
|
};
|
|
505
500
|
|
|
506
501
|
const onLogout = (): void => {
|
|
507
|
-
|
|
502
|
+
userInfo.value = {};
|
|
508
503
|
localStorage.setItem('WALINE_USER', 'null');
|
|
509
504
|
sessionStorage.setItem('WALINE_USER', 'null');
|
|
510
505
|
};
|
|
@@ -531,7 +526,8 @@ export default defineComponent({
|
|
|
531
526
|
const receiver = ({ data }: any): void => {
|
|
532
527
|
if (!data || data.type !== 'profile') return;
|
|
533
528
|
|
|
534
|
-
|
|
529
|
+
userInfo.value = { ...userInfo.value, ...data };
|
|
530
|
+
|
|
535
531
|
[localStorage, sessionStorage]
|
|
536
532
|
.filter((store) => store.getItem('WALINE_USER'))
|
|
537
533
|
.forEach((store) =>
|
|
@@ -551,37 +547,6 @@ export default defineComponent({
|
|
|
551
547
|
showEmoji.value = false;
|
|
552
548
|
};
|
|
553
549
|
|
|
554
|
-
// watch editor
|
|
555
|
-
watch(
|
|
556
|
-
() => inputs.editor,
|
|
557
|
-
(value) => {
|
|
558
|
-
const { highlighter, texRenderer } = config.value;
|
|
559
|
-
|
|
560
|
-
content.value = value;
|
|
561
|
-
previewText.value = parseMarkdown(value, {
|
|
562
|
-
emojiMap: emoji.value.map,
|
|
563
|
-
highlighter,
|
|
564
|
-
texRenderer,
|
|
565
|
-
});
|
|
566
|
-
wordNumber.value = getWordNumber(value);
|
|
567
|
-
|
|
568
|
-
if (editorRef.value)
|
|
569
|
-
if (value) autosize(editorRef.value);
|
|
570
|
-
else autosize.destroy(editorRef.value);
|
|
571
|
-
},
|
|
572
|
-
{ immediate: true }
|
|
573
|
-
);
|
|
574
|
-
|
|
575
|
-
// watch emoji value change
|
|
576
|
-
watch(
|
|
577
|
-
() => config.value.emoji,
|
|
578
|
-
(emojiConfig) =>
|
|
579
|
-
emojiConfig.then((config) => {
|
|
580
|
-
emoji.value = config;
|
|
581
|
-
}),
|
|
582
|
-
{ immediate: true }
|
|
583
|
-
);
|
|
584
|
-
|
|
585
550
|
// update wordNumber
|
|
586
551
|
watch(
|
|
587
552
|
[config, wordNumber],
|
|
@@ -609,6 +574,38 @@ export default defineComponent({
|
|
|
609
574
|
|
|
610
575
|
onMounted(() => {
|
|
611
576
|
document.body.addEventListener('click', popupHandler);
|
|
577
|
+
|
|
578
|
+
// watch editor
|
|
579
|
+
watch(
|
|
580
|
+
() => inputs.value.editor,
|
|
581
|
+
(value) => {
|
|
582
|
+
const { highlighter, texRenderer } = config.value;
|
|
583
|
+
|
|
584
|
+
content.value = value;
|
|
585
|
+
previewText.value = parseMarkdown(value, {
|
|
586
|
+
emojiMap: emoji.value.map,
|
|
587
|
+
highlighter,
|
|
588
|
+
texRenderer,
|
|
589
|
+
});
|
|
590
|
+
wordNumber.value = getWordNumber(value);
|
|
591
|
+
|
|
592
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
593
|
+
if (value) autosize(editorRef.value!);
|
|
594
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
595
|
+
else autosize.destroy(editorRef.value!);
|
|
596
|
+
},
|
|
597
|
+
{ immediate: true }
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
// watch emoji value change
|
|
601
|
+
watch(
|
|
602
|
+
() => config.value.emoji,
|
|
603
|
+
(emojiConfig) =>
|
|
604
|
+
getEmojis(emojiConfig).then((config) => {
|
|
605
|
+
emoji.value = config;
|
|
606
|
+
}),
|
|
607
|
+
{ immediate: true }
|
|
608
|
+
);
|
|
612
609
|
});
|
|
613
610
|
|
|
614
611
|
onUnmounted(() => {
|
|
@@ -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="
|
|
27
|
+
<span class="wl-time" v-text="time" />
|
|
28
28
|
|
|
29
29
|
<button
|
|
30
30
|
class="wl-reply"
|
|
@@ -69,10 +69,11 @@
|
|
|
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
|
|
72
|
+
import { isLinkHttp } from '../utils';
|
|
73
|
+
import { useTimeAgo } from '../composables';
|
|
73
74
|
|
|
74
75
|
import type { ComputedRef, PropType } from 'vue';
|
|
75
|
-
import type {
|
|
76
|
+
import type { WalineConfig } from '../utils';
|
|
76
77
|
import type { WalineComment } from '../typings';
|
|
77
78
|
|
|
78
79
|
export default defineComponent({
|
|
@@ -99,7 +100,9 @@ export default defineComponent({
|
|
|
99
100
|
emits: ['submit', 'reply'],
|
|
100
101
|
|
|
101
102
|
setup(props) {
|
|
102
|
-
const config = inject<ComputedRef<
|
|
103
|
+
const config = inject<ComputedRef<WalineConfig>>(
|
|
104
|
+
'config'
|
|
105
|
+
) as ComputedRef<WalineConfig>;
|
|
103
106
|
const locale = computed(() => config.value.locale);
|
|
104
107
|
|
|
105
108
|
const link = computed(() => {
|
|
@@ -108,6 +111,8 @@ export default defineComponent({
|
|
|
108
111
|
return link ? (isLinkHttp(link) ? link : `https://${link}`) : '';
|
|
109
112
|
});
|
|
110
113
|
|
|
114
|
+
const time = useTimeAgo(props.comment.insertedAt, locale.value);
|
|
115
|
+
|
|
111
116
|
const isReplyingCurrent = computed(
|
|
112
117
|
() => props.comment.objectId === props.reply?.objectId
|
|
113
118
|
);
|
|
@@ -118,7 +123,7 @@ export default defineComponent({
|
|
|
118
123
|
|
|
119
124
|
isReplyingCurrent,
|
|
120
125
|
link,
|
|
121
|
-
|
|
126
|
+
time,
|
|
122
127
|
};
|
|
123
128
|
},
|
|
124
129
|
});
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
/>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
|
-
<div v-if="status === 'error'" class="wl-
|
|
21
|
+
<div v-if="status === 'error'" class="wl-operation">
|
|
22
22
|
<button
|
|
23
23
|
type="button"
|
|
24
24
|
class="wl-btn"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
<div v-else-if="!data.length" class="wl-empty" v-text="i18n.sofa" />
|
|
36
36
|
|
|
37
37
|
<!-- Load more button -->
|
|
38
|
-
<div v-else-if="page < totalPages" class="wl-
|
|
38
|
+
<div v-else-if="page < totalPages" class="wl-operation">
|
|
39
39
|
<button
|
|
40
40
|
type="button"
|
|
41
41
|
class="wl-btn"
|
|
@@ -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 =>
|
|
@@ -136,19 +134,12 @@ export default defineComponent({
|
|
|
136
134
|
: {}),
|
|
137
135
|
},
|
|
138
136
|
|
|
139
|
-
visitor: {
|
|
140
|
-
type: Boolean,
|
|
141
|
-
// default: false,
|
|
142
|
-
},
|
|
143
|
-
|
|
144
137
|
dark: {
|
|
145
138
|
type: [String, Boolean],
|
|
146
|
-
// default: false,
|
|
147
139
|
},
|
|
148
140
|
|
|
149
141
|
lang: {
|
|
150
142
|
type: String,
|
|
151
|
-
// default: 'zh-CN',
|
|
152
143
|
...(SHOULD_VALIDATE
|
|
153
144
|
? {
|
|
154
145
|
validator: (value: unknown): boolean =>
|
|
@@ -163,7 +154,6 @@ export default defineComponent({
|
|
|
163
154
|
|
|
164
155
|
pageSize: {
|
|
165
156
|
type: Number,
|
|
166
|
-
// default: 10,
|
|
167
157
|
},
|
|
168
158
|
|
|
169
159
|
wordLimit: {
|
|
@@ -182,9 +172,6 @@ export default defineComponent({
|
|
|
182
172
|
|
|
183
173
|
emoji: {
|
|
184
174
|
type: Array as PropType<(string | WalineEmojiInfo)[]>,
|
|
185
|
-
// default: (): string[] => [
|
|
186
|
-
// 'https://cdn.jsdelivr.net/gh/walinejs/emojis/weibo',
|
|
187
|
-
// ],
|
|
188
175
|
...(SHOULD_VALIDATE
|
|
189
176
|
? {
|
|
190
177
|
validator: (value: unknown): boolean =>
|
|
@@ -207,38 +194,25 @@ export default defineComponent({
|
|
|
207
194
|
|
|
208
195
|
login: {
|
|
209
196
|
type: String as PropType<'enable' | 'disable' | 'force'>,
|
|
210
|
-
// default: 'enable',
|
|
211
197
|
},
|
|
212
198
|
|
|
213
199
|
highlighter: {
|
|
214
200
|
type: Function as PropType<WalineHighlighter>,
|
|
215
|
-
// default: (text: string): string => text,
|
|
216
201
|
},
|
|
217
202
|
|
|
218
203
|
imageUploader: {
|
|
219
|
-
type: [Function,
|
|
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
|
-
// }),
|
|
204
|
+
type: [Function, Boolean] as PropType<WalineImageUploader | false>,
|
|
227
205
|
},
|
|
228
206
|
|
|
229
|
-
|
|
230
|
-
type: Function as PropType<WalineTexRenderer>,
|
|
231
|
-
// default: (blockMode: boolean): string =>
|
|
232
|
-
// blockMode === true
|
|
233
|
-
// ? '<p class="vtex">Tex is not available in preview</p>'
|
|
234
|
-
// : '<span class="vtex">Tex is not available in preview</span>',
|
|
207
|
+
texRenderer: {
|
|
208
|
+
type: [Function, Boolean] as PropType<WalineTexRenderer | false>,
|
|
235
209
|
},
|
|
236
210
|
},
|
|
237
211
|
|
|
238
212
|
setup(props) {
|
|
239
213
|
const config = computed(() => getConfig(props as WalineProps));
|
|
240
214
|
|
|
241
|
-
const
|
|
215
|
+
const userInfo = useUserInfo();
|
|
242
216
|
|
|
243
217
|
const status = ref<'loading' | 'success' | 'error'>('loading');
|
|
244
218
|
|
package/src/composables/index.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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 {
|
|
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
|
|
8
|
-
|
|
9
|
-
|
|
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
|
|
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
|
-
|
|
19
|
-
}
|
|
17
|
+
export type UserInfoRef = Ref<UserInfo | Record<string, never>>;
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
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/config/default.ts
CHANGED
|
@@ -17,5 +17,5 @@ export const defaultUploadImage = (file: File): Promise<string> =>
|
|
|
17
17
|
|
|
18
18
|
export const defaultTexRenderer = (blockMode: boolean): string =>
|
|
19
19
|
blockMode === true
|
|
20
|
-
? '<p class="
|
|
21
|
-
: '<span class="
|
|
20
|
+
? '<p class="wl-tex">Tex is not available in preview</p>'
|
|
21
|
+
: '<span class="wl-tex">Tex is not available in preview</span>';
|
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).
|
|
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
|
package/src/pageview.ts
CHANGED
package/src/styles/layout.scss
CHANGED