@waline/client 2.11.2 → 2.11.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/dist/comment.cjs +1 -1
- package/dist/comment.cjs.map +1 -1
- package/dist/comment.js +1 -1
- package/dist/comment.js.map +1 -1
- package/dist/comment.mjs +1 -1
- package/dist/comment.mjs.map +1 -1
- package/dist/component.mjs +1 -1
- package/dist/component.mjs.map +1 -1
- package/dist/legacy.umd.d.ts +57 -30
- package/dist/legacy.umd.js +1 -1
- package/dist/legacy.umd.js.map +1 -1
- package/dist/pageview.cjs +1 -1
- package/dist/pageview.cjs.map +1 -1
- package/dist/pageview.js +1 -1
- package/dist/pageview.js.map +1 -1
- package/dist/pageview.mjs +1 -1
- package/dist/pageview.mjs.map +1 -1
- package/dist/shim.cjs +1 -1
- package/dist/shim.cjs.map +1 -1
- package/dist/shim.d.cts +58 -31
- package/dist/shim.d.mts +58 -31
- package/dist/shim.mjs +1 -1
- package/dist/shim.mjs.map +1 -1
- package/dist/waline.cjs +1 -1
- package/dist/waline.cjs.map +1 -1
- package/dist/waline.d.cts +58 -31
- package/dist/waline.d.mts +58 -31
- package/dist/waline.d.ts +58 -31
- package/dist/waline.js +1 -1
- package/dist/waline.js.map +1 -1
- package/dist/waline.mjs +1 -1
- package/dist/waline.mjs.map +1 -1
- package/package.json +1 -1
- package/src/compact/convert.ts +2 -2
- package/src/components/ArticleReaction.vue +36 -24
- package/src/components/CommentBox.vue +1 -1
- package/src/components/ImageWall.vue +1 -1
- package/src/composables/vote.ts +5 -2
- package/src/typings/base.ts +33 -7
- package/src/typings/locale.ts +37 -23
- package/src/utils/config.ts +8 -2
package/package.json
CHANGED
package/src/compact/convert.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { warning } from './logger';
|
|
2
2
|
import { resolveOldEmojiMap } from './valine';
|
|
3
|
-
|
|
4
|
-
import type { DeprecatedValineOptions } from './valine';
|
|
5
3
|
import {
|
|
6
4
|
DROPPED_OPTIONS_WHICH_CAN_NOT_BE_POLYFILLED,
|
|
7
5
|
DROPPED_OPTIONS_WHICH_CAN_STILL_BE_POLYFILLED,
|
|
8
6
|
} from './dropped';
|
|
7
|
+
|
|
8
|
+
import type { DeprecatedValineOptions } from './valine';
|
|
9
9
|
import type { DeprecatedWalineOptions } from './v1';
|
|
10
10
|
import type { WalineInitOptions } from '../typings';
|
|
11
11
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-if="reaction
|
|
2
|
+
<div v-if="reaction.length" class="wl-reaction">
|
|
3
3
|
<h4 v-text="locale.reactionTitle" />
|
|
4
4
|
<ul>
|
|
5
5
|
<li
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
ref,
|
|
30
30
|
} from 'vue';
|
|
31
31
|
import { fetchArticleCounter, updateArticleCounter } from '../api';
|
|
32
|
-
import { useVoteStorage } from '../composables';
|
|
32
|
+
import { VOTE_IDENTIFIER, VOTE_INDEX, useVoteStorage } from '../composables';
|
|
33
33
|
import type { WalineConfig } from '../utils';
|
|
34
34
|
import type { WalineLocale } from '../typings';
|
|
35
35
|
|
|
@@ -49,42 +49,48 @@ export default defineComponent({
|
|
|
49
49
|
const reaction = computed((): ReactionItem[] => {
|
|
50
50
|
const { reaction, path } = config.value;
|
|
51
51
|
|
|
52
|
-
return
|
|
52
|
+
return reaction.map((icon, index) => ({
|
|
53
53
|
icon,
|
|
54
54
|
vote: votes.value[index] || 0,
|
|
55
55
|
desc: locale.value[`reaction${index}` as keyof WalineLocale],
|
|
56
56
|
active: Boolean(
|
|
57
|
-
voteStorage.value.find(
|
|
57
|
+
voteStorage.value.find(
|
|
58
|
+
({ [VOTE_IDENTIFIER]: voteIdentifier, [VOTE_INDEX]: voteIndex }) =>
|
|
59
|
+
voteIdentifier === path && voteIndex === index
|
|
60
|
+
)
|
|
58
61
|
),
|
|
59
62
|
}));
|
|
60
63
|
});
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
let abort: () => void;
|
|
63
66
|
|
|
64
|
-
const fetchCounter =
|
|
67
|
+
const fetchCounter = (): void => {
|
|
65
68
|
const { serverURL, lang, path, reaction } = config.value;
|
|
66
69
|
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const resp = await fetchArticleCounter({
|
|
72
|
-
serverURL,
|
|
73
|
-
lang,
|
|
74
|
-
paths: [path],
|
|
75
|
-
type: reaction.map((_, k) => `reaction${k}`),
|
|
76
|
-
signal: controller.signal,
|
|
77
|
-
});
|
|
70
|
+
if (reaction.length) {
|
|
71
|
+
const controller = new AbortController();
|
|
78
72
|
|
|
79
|
-
|
|
73
|
+
fetchArticleCounter({
|
|
74
|
+
serverURL,
|
|
75
|
+
lang,
|
|
76
|
+
paths: [path],
|
|
77
|
+
type: reaction.map((_, k) => `reaction${k}`),
|
|
78
|
+
signal: controller.signal,
|
|
79
|
+
}).then((resp) => {
|
|
80
|
+
if (Array.isArray(resp) || typeof resp === 'number') return;
|
|
81
|
+
votes.value = reaction.map((_, k) => resp[`reaction${k}`]);
|
|
82
|
+
});
|
|
80
83
|
|
|
81
|
-
|
|
84
|
+
abort = controller.abort.bind(controller);
|
|
85
|
+
}
|
|
82
86
|
};
|
|
83
87
|
|
|
84
88
|
const vote = async (index: number): Promise<void> => {
|
|
85
89
|
const { serverURL, lang, path } = config.value;
|
|
86
|
-
const hasVoted = voteStorage.value.find(
|
|
87
|
-
|
|
90
|
+
const hasVoted = voteStorage.value.find(
|
|
91
|
+
({ [VOTE_IDENTIFIER]: voteIdentifier }) => voteIdentifier === path
|
|
92
|
+
);
|
|
93
|
+
const hasVotedTheReaction = hasVoted && hasVoted[VOTE_INDEX] === index;
|
|
88
94
|
|
|
89
95
|
if (hasVotedTheReaction) return;
|
|
90
96
|
|
|
@@ -97,7 +103,10 @@ export default defineComponent({
|
|
|
97
103
|
|
|
98
104
|
votes.value[index] = (votes.value[index] || 0) + 1;
|
|
99
105
|
if (hasVoted) {
|
|
100
|
-
votes.value[hasVoted
|
|
106
|
+
votes.value[hasVoted[VOTE_INDEX]] = Math.max(
|
|
107
|
+
votes.value[hasVoted[VOTE_INDEX]] - 1,
|
|
108
|
+
0
|
|
109
|
+
);
|
|
101
110
|
updateArticleCounter({
|
|
102
111
|
serverURL,
|
|
103
112
|
lang,
|
|
@@ -109,7 +118,10 @@ export default defineComponent({
|
|
|
109
118
|
hasVoted.i = index;
|
|
110
119
|
voteStorage.value = Array.from(voteStorage.value);
|
|
111
120
|
} else {
|
|
112
|
-
voteStorage.value = [
|
|
121
|
+
voteStorage.value = [
|
|
122
|
+
...voteStorage.value,
|
|
123
|
+
{ [VOTE_IDENTIFIER]: path, [VOTE_INDEX]: index },
|
|
124
|
+
];
|
|
113
125
|
}
|
|
114
126
|
|
|
115
127
|
if (voteStorage.value.length > 50)
|
|
@@ -117,7 +129,7 @@ export default defineComponent({
|
|
|
117
129
|
};
|
|
118
130
|
|
|
119
131
|
onMounted(() => fetchCounter());
|
|
120
|
-
onUnmounted(() =>
|
|
132
|
+
onUnmounted(() => abort?.());
|
|
121
133
|
|
|
122
134
|
return {
|
|
123
135
|
reaction,
|
|
@@ -75,7 +75,7 @@ export default defineComponent({
|
|
|
75
75
|
},
|
|
76
76
|
|
|
77
77
|
props: {
|
|
78
|
-
items: { type: Array as PropType<WalineSearchResult
|
|
78
|
+
items: { type: Array as PropType<WalineSearchResult>, default: () => [] },
|
|
79
79
|
columnWidth: { type: Number, default: 300 },
|
|
80
80
|
gap: { type: Number, default: 0 },
|
|
81
81
|
},
|
package/src/composables/vote.ts
CHANGED
|
@@ -4,9 +4,12 @@ import type { Ref } from 'vue';
|
|
|
4
4
|
|
|
5
5
|
const VOTE_KEY = 'WALINE_VOTE';
|
|
6
6
|
|
|
7
|
+
export const VOTE_IDENTIFIER = 'id';
|
|
8
|
+
export const VOTE_INDEX = 'i';
|
|
9
|
+
|
|
7
10
|
export interface VoteLogItem {
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
[VOTE_IDENTIFIER]: string;
|
|
12
|
+
[VOTE_INDEX]: number;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export type VoteRef = Ref<VoteLogItem[]>;
|
package/src/typings/base.ts
CHANGED
|
@@ -39,44 +39,70 @@ export interface WalineEmojiInfo {
|
|
|
39
39
|
|
|
40
40
|
export type WalineEmojiMaps = Record<string, string>;
|
|
41
41
|
|
|
42
|
-
export interface
|
|
42
|
+
export interface WalineSearchImageData extends Record<string, unknown> {
|
|
43
43
|
/**
|
|
44
|
+
* 图片链接
|
|
45
|
+
*
|
|
44
46
|
* Image link
|
|
45
47
|
*/
|
|
46
48
|
src: string;
|
|
47
49
|
|
|
48
50
|
/**
|
|
49
|
-
*
|
|
51
|
+
* 图片标题
|
|
52
|
+
*
|
|
53
|
+
* @description 用于图片的 alt 属性
|
|
54
|
+
*
|
|
55
|
+
* Image title
|
|
56
|
+
*
|
|
57
|
+
* @description Used for alt attribute of image
|
|
50
58
|
*/
|
|
51
59
|
title?: string;
|
|
52
60
|
|
|
53
61
|
/**
|
|
54
|
-
*
|
|
62
|
+
* 图片缩略图
|
|
63
|
+
*
|
|
64
|
+
* @description 为了更好的加载性能,我们会优先在列表中使用此缩略图
|
|
65
|
+
*
|
|
66
|
+
* Image preview link
|
|
67
|
+
*
|
|
68
|
+
* @description For better loading performance, we will use this thumbnail first in the list
|
|
55
69
|
*
|
|
56
70
|
* @default src
|
|
57
71
|
*/
|
|
58
72
|
preview?: string;
|
|
59
73
|
}
|
|
60
74
|
|
|
75
|
+
export type WalineSearchResult = WalineSearchImageData[];
|
|
76
|
+
|
|
61
77
|
export interface WalineSearchOptions {
|
|
62
78
|
/**
|
|
79
|
+
* 搜索操作
|
|
80
|
+
*
|
|
63
81
|
* Search action
|
|
64
82
|
*/
|
|
65
|
-
search: (word: string) => Promise<WalineSearchResult
|
|
83
|
+
search: (word: string) => Promise<WalineSearchResult>;
|
|
66
84
|
|
|
67
85
|
/**
|
|
68
|
-
*
|
|
86
|
+
* 打开列表时展示的默认结果
|
|
87
|
+
*
|
|
88
|
+
* Default result when opening list
|
|
69
89
|
*
|
|
70
90
|
* @default () => search('')
|
|
71
91
|
*/
|
|
72
|
-
default?: () => Promise<WalineSearchResult
|
|
92
|
+
default?: () => Promise<WalineSearchResult>;
|
|
73
93
|
|
|
74
94
|
/**
|
|
95
|
+
* 获取更多的操作
|
|
96
|
+
*
|
|
97
|
+
* @description 会在列表滚动到底部时触发,如果你的搜索服务支持分页功能,你应该设置此项实现无限滚动
|
|
98
|
+
*
|
|
75
99
|
* Fetch more action
|
|
76
100
|
*
|
|
101
|
+
* @description It will be triggered when the list scrolls to the bottom. If your search service supports paging, you should set this to achieve infinite scrolling
|
|
102
|
+
*
|
|
77
103
|
* @default (word) => search(word)
|
|
78
104
|
*/
|
|
79
|
-
more?: (word: string, currectCount: number) => Promise<WalineSearchResult
|
|
105
|
+
more?: (word: string, currectCount: number) => Promise<WalineSearchResult>;
|
|
80
106
|
}
|
|
81
107
|
|
|
82
108
|
export type WalineMeta = 'nick' | 'mail' | 'link';
|
package/src/typings/locale.ts
CHANGED
|
@@ -8,52 +8,66 @@ export interface WalineDateLocale {
|
|
|
8
8
|
|
|
9
9
|
export type WalineLevelLocale = Record<`level${number}`, string>;
|
|
10
10
|
|
|
11
|
-
export interface
|
|
11
|
+
export interface WalineReactionLocale {
|
|
12
|
+
reactionTitle: string;
|
|
13
|
+
reaction0: string;
|
|
14
|
+
reaction1: string;
|
|
15
|
+
reaction2: string;
|
|
16
|
+
reaction3: string;
|
|
17
|
+
reaction4: string;
|
|
18
|
+
reaction5: string;
|
|
19
|
+
reaction6: string;
|
|
20
|
+
reaction7: string;
|
|
21
|
+
reaction8: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface WalineLocale
|
|
25
|
+
extends WalineDateLocale,
|
|
26
|
+
WalineLevelLocale,
|
|
27
|
+
WalineReactionLocale {
|
|
12
28
|
nick: string;
|
|
13
|
-
nickError: string;
|
|
14
29
|
mail: string;
|
|
15
|
-
mailError: string;
|
|
16
30
|
link: string;
|
|
17
31
|
optional: string;
|
|
18
32
|
placeholder: string;
|
|
19
33
|
sofa: string;
|
|
20
34
|
submit: string;
|
|
21
|
-
like: string;
|
|
22
|
-
cancelLike: string;
|
|
23
|
-
reply: string;
|
|
24
|
-
cancelReply: string;
|
|
25
35
|
comment: string;
|
|
26
36
|
refresh: string;
|
|
27
37
|
more: string;
|
|
28
|
-
preview: string;
|
|
29
|
-
emoji: string;
|
|
30
|
-
uploadImage: string;
|
|
31
38
|
uploading: string;
|
|
32
39
|
login: string;
|
|
33
|
-
logout: string;
|
|
34
40
|
admin: string;
|
|
35
41
|
sticky: string;
|
|
36
42
|
word: string;
|
|
37
|
-
wordHint: string;
|
|
38
43
|
anonymous: string;
|
|
39
44
|
gif: string;
|
|
40
45
|
gifSearchPlaceholder: string;
|
|
41
|
-
|
|
46
|
+
|
|
47
|
+
// manage
|
|
42
48
|
approved: string;
|
|
43
49
|
waiting: string;
|
|
44
50
|
spam: string;
|
|
45
51
|
unsticky: string;
|
|
52
|
+
|
|
53
|
+
// sorting
|
|
46
54
|
oldest: string;
|
|
47
55
|
latest: string;
|
|
48
56
|
hottest: string;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
|
|
58
|
+
// hint
|
|
59
|
+
nickError: string;
|
|
60
|
+
mailError: string;
|
|
61
|
+
wordHint: string;
|
|
62
|
+
|
|
63
|
+
// i18n
|
|
64
|
+
like: string;
|
|
65
|
+
cancelLike: string;
|
|
66
|
+
reply: string;
|
|
67
|
+
cancelReply: string;
|
|
68
|
+
preview: string;
|
|
69
|
+
emoji: string;
|
|
70
|
+
uploadImage: string;
|
|
71
|
+
profile: string;
|
|
72
|
+
logout: string;
|
|
59
73
|
}
|
package/src/utils/config.ts
CHANGED
|
@@ -23,9 +23,11 @@ export interface WalineEmojiConfig {
|
|
|
23
23
|
map: WalineEmojiMaps;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export interface WalineConfig
|
|
26
|
+
export interface WalineConfig
|
|
27
|
+
extends Required<Omit<WalineProps, 'wordLimit' | 'reaction'>> {
|
|
27
28
|
locale: WalineLocale;
|
|
28
29
|
wordLimit: [number, number] | false;
|
|
30
|
+
reaction: string[];
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
export const getServerURL = (serverURL: string): string => {
|
|
@@ -87,6 +89,10 @@ export const getConfig = ({
|
|
|
87
89
|
copyright,
|
|
88
90
|
search,
|
|
89
91
|
recaptchaV3Key,
|
|
90
|
-
reaction: reaction
|
|
92
|
+
reaction: Array.isArray(reaction)
|
|
93
|
+
? reaction
|
|
94
|
+
: reaction === true
|
|
95
|
+
? defaultReaction
|
|
96
|
+
: [],
|
|
91
97
|
...more,
|
|
92
98
|
});
|