@waline/client 2.3.2 → 2.4.2
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.esm.js +1 -1
- package/dist/component.esm.js.map +1 -1
- package/dist/component.js +1 -1
- package/dist/component.js.map +1 -1
- package/dist/legacy.d.ts +4 -9
- package/dist/legacy.js +1 -1
- package/dist/legacy.js.map +1 -1
- package/dist/pageview.cjs.d.ts +47 -0
- package/dist/pageview.cjs.js +1 -1
- package/dist/pageview.cjs.js.map +1 -1
- package/dist/pageview.esm.d.ts +47 -0
- 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 +46 -11
- package/dist/shim.esm.d.ts +46 -11
- 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 +46 -11
- 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 +46 -11
- package/dist/waline.esm.d.ts +46 -11
- 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 +19 -5
- package/src/components/CommentCard.vue +80 -14
- package/src/components/Icons.ts +28 -2
- package/src/components/Waline.vue +115 -2
- package/src/composables/index.ts +1 -0
- package/src/composables/like.ts +14 -0
- package/src/composables/userInfo.ts +9 -1
- package/src/config/i18n/en.ts +2 -0
- package/src/config/i18n/generate.ts +2 -0
- package/src/config/i18n/jp.ts +2 -0
- package/src/config/i18n/pt-BR.ts +2 -0
- package/src/config/i18n/ru.ts +2 -0
- package/src/config/i18n/vi-VN.ts +2 -0
- package/src/config/i18n/zh-CN.ts +2 -0
- package/src/config/i18n/zh-TW.ts +2 -0
- package/src/styles/card.scss +55 -27
- package/src/styles/nomalize.scss +0 -1
- package/src/styles/panel.scss +0 -1
- package/src/typings/comment.ts +56 -1
- package/src/typings/locale.ts +3 -8
- package/src/typings/waline.ts +1 -1
- package/src/utils/config.ts +1 -1
- package/src/utils/fetch.ts +77 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waline/client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "client for waline comment system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"valine",
|
|
@@ -71,19 +71,33 @@
|
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
|
-
"@vueuse/core": "^8.4.
|
|
74
|
+
"@vueuse/core": "^8.4.2",
|
|
75
75
|
"autosize": "^5.0.1",
|
|
76
76
|
"marked": "^4.0.15",
|
|
77
77
|
"vue": "^3.2.33"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
+
"@babel/core": "^7.17.10",
|
|
81
|
+
"@babel/preset-env": "^7.17.10",
|
|
82
|
+
"@rollup/plugin-babel": "^5.3.1",
|
|
83
|
+
"@rollup/plugin-commonjs": "^22.0.0",
|
|
84
|
+
"@rollup/plugin-node-resolve": "^13.3.0",
|
|
85
|
+
"@rollup/plugin-replace": "^4.0.0",
|
|
80
86
|
"@types/autosize": "^4.0.1",
|
|
81
87
|
"@types/marked": "^4.0.3",
|
|
82
|
-
"@
|
|
83
|
-
"
|
|
88
|
+
"@types/node": "^17.0.31",
|
|
89
|
+
"@vitejs/plugin-vue": "^2.3.2",
|
|
90
|
+
"@vue/compiler-sfc": "^3.2.33",
|
|
91
|
+
"rimraf": "^3.0.2",
|
|
92
|
+
"rollup": "^2.72.1",
|
|
93
|
+
"rollup-plugin-dts": "^4.2.1",
|
|
94
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
95
|
+
"rollup-plugin-ts": "^2.0.7",
|
|
96
|
+
"typescript": "^4.6.4",
|
|
97
|
+
"vite": "^2.9.8"
|
|
84
98
|
},
|
|
85
99
|
"engines": {
|
|
86
|
-
"node": ">=
|
|
100
|
+
"node": ">=14"
|
|
87
101
|
},
|
|
88
102
|
"scripts": {
|
|
89
103
|
"build": "pnpm rollup && pnpm style",
|
|
@@ -25,21 +25,39 @@
|
|
|
25
25
|
<span v-if="comment.label" class="wl-badge" v-text="comment.label" />
|
|
26
26
|
<span v-if="comment.sticky" class="wl-badge" v-text="locale.sticky" />
|
|
27
27
|
<span
|
|
28
|
-
v-if="comment.level >= 0"
|
|
28
|
+
v-if="comment.level && comment.level >= 0"
|
|
29
29
|
:class="`wl-badge level${comment.level}`"
|
|
30
30
|
v-text="locale[`level${comment.level}`] || `Level ${comment.level}`"
|
|
31
31
|
/>
|
|
32
|
-
|
|
33
32
|
<span class="wl-time" v-text="time" />
|
|
34
33
|
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
<div class="wl-comment-actions">
|
|
35
|
+
<button
|
|
36
|
+
class="wl-delete"
|
|
37
|
+
v-if="isAdmin || isOwner"
|
|
38
|
+
@click="$emit('delete', comment)"
|
|
39
|
+
>
|
|
40
|
+
<DeleteIcon />
|
|
41
|
+
</button>
|
|
42
|
+
|
|
43
|
+
<button
|
|
44
|
+
class="wl-like"
|
|
45
|
+
@click="$emit('like', comment)"
|
|
46
|
+
:title="like ? locale.cancelLike : locale.like"
|
|
47
|
+
>
|
|
48
|
+
<LikeIcon :active="like" />
|
|
49
|
+
<span v-if="'like' in comment" v-text="comment.like" />
|
|
50
|
+
</button>
|
|
51
|
+
|
|
52
|
+
<button
|
|
53
|
+
class="wl-reply"
|
|
54
|
+
:class="{ active: isReplyingCurrent }"
|
|
55
|
+
:title="isReplyingCurrent ? locale.cancelReply : locale.reply"
|
|
56
|
+
@click="$emit('reply', isReplyingCurrent ? null : comment)"
|
|
57
|
+
>
|
|
58
|
+
<ReplyIcon />
|
|
59
|
+
</button>
|
|
60
|
+
</div>
|
|
43
61
|
</div>
|
|
44
62
|
<div class="wl-meta" aria-hidden="true">
|
|
45
63
|
<span v-if="comment.addr" v-text="comment.addr" />
|
|
@@ -48,6 +66,27 @@
|
|
|
48
66
|
</div>
|
|
49
67
|
<div class="wl-content" v-html="comment.comment" />
|
|
50
68
|
|
|
69
|
+
<div v-if="isAdmin" class="wl-admin-actions">
|
|
70
|
+
<span class="wl-comment-status">
|
|
71
|
+
<button
|
|
72
|
+
v-for="status in commentStatus"
|
|
73
|
+
:key="status"
|
|
74
|
+
:class="`wl-btn wl-${status}`"
|
|
75
|
+
:disabled="comment.status === status"
|
|
76
|
+
@click="$emit('status', { status, comment })"
|
|
77
|
+
v-text="status"
|
|
78
|
+
/>
|
|
79
|
+
</span>
|
|
80
|
+
|
|
81
|
+
<button
|
|
82
|
+
class="wl-btn wl-sticky"
|
|
83
|
+
v-if="isAdmin && !comment.rid"
|
|
84
|
+
@click="$emit('sticky', comment)"
|
|
85
|
+
>
|
|
86
|
+
{{ comment.sticky ? 'unsticky' : 'sticky' }}
|
|
87
|
+
</button>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
51
90
|
<div v-if="isReplyingCurrent" class="wl-reply-wrapper">
|
|
52
91
|
<CommentBox
|
|
53
92
|
:replyId="comment.objectId"
|
|
@@ -66,6 +105,10 @@
|
|
|
66
105
|
:rootId="rootId"
|
|
67
106
|
@reply="$emit('reply', $event)"
|
|
68
107
|
@submit="$emit('submit', $event)"
|
|
108
|
+
@like="$emit('like', $event)"
|
|
109
|
+
@delete="$emit('delete', $event)"
|
|
110
|
+
@status="$emit('status', $event)"
|
|
111
|
+
@sticky="$emit('sticky', $event)"
|
|
69
112
|
/>
|
|
70
113
|
</div>
|
|
71
114
|
</div>
|
|
@@ -75,13 +118,15 @@
|
|
|
75
118
|
<script lang="ts">
|
|
76
119
|
import { computed, defineComponent, inject } from 'vue';
|
|
77
120
|
import CommentBox from './CommentBox.vue';
|
|
78
|
-
import { ReplyIcon, VerifiedIcon } from './Icons';
|
|
121
|
+
import { DeleteIcon, LikeIcon, ReplyIcon, VerifiedIcon } from './Icons';
|
|
79
122
|
import { isLinkHttp } from '../utils';
|
|
80
|
-
import { useTimeAgo } from '../composables';
|
|
123
|
+
import { useTimeAgo, useLikeStorage, useUserInfo } from '../composables';
|
|
81
124
|
|
|
82
125
|
import type { ComputedRef, PropType } from 'vue';
|
|
83
126
|
import type { WalineConfig } from '../utils';
|
|
84
|
-
import type { WalineComment } from '../typings';
|
|
127
|
+
import type { WalineComment, WalineCommentStatus } from '../typings';
|
|
128
|
+
|
|
129
|
+
const commentStatus: WalineCommentStatus[] = ['approved', 'waiting', 'spam'];
|
|
85
130
|
|
|
86
131
|
export default defineComponent({
|
|
87
132
|
props: {
|
|
@@ -100,16 +145,21 @@ export default defineComponent({
|
|
|
100
145
|
|
|
101
146
|
components: {
|
|
102
147
|
CommentBox,
|
|
148
|
+
DeleteIcon,
|
|
149
|
+
LikeIcon,
|
|
103
150
|
ReplyIcon,
|
|
104
151
|
VerifiedIcon,
|
|
105
152
|
},
|
|
106
153
|
|
|
107
|
-
emits: ['submit', 'reply'],
|
|
154
|
+
emits: ['submit', 'reply', 'like', 'delete', 'status', 'sticky'],
|
|
108
155
|
|
|
109
156
|
setup(props) {
|
|
110
157
|
const config = inject<ComputedRef<WalineConfig>>(
|
|
111
158
|
'config'
|
|
112
159
|
) as ComputedRef<WalineConfig>;
|
|
160
|
+
const likes = useLikeStorage();
|
|
161
|
+
const userInfo = useUserInfo();
|
|
162
|
+
|
|
113
163
|
const locale = computed(() => config.value.locale);
|
|
114
164
|
|
|
115
165
|
const link = computed(() => {
|
|
@@ -118,8 +168,18 @@ export default defineComponent({
|
|
|
118
168
|
return link ? (isLinkHttp(link) ? link : `https://${link}`) : '';
|
|
119
169
|
});
|
|
120
170
|
|
|
171
|
+
const like = computed(() => likes.value.includes(props.comment.objectId));
|
|
172
|
+
|
|
121
173
|
const time = useTimeAgo(props.comment.insertedAt, locale.value);
|
|
122
174
|
|
|
175
|
+
const isAdmin = computed(() => userInfo.value.type === 'administrator');
|
|
176
|
+
|
|
177
|
+
const isOwner = computed(
|
|
178
|
+
() =>
|
|
179
|
+
props.comment.user_id &&
|
|
180
|
+
userInfo.value.objectId === props.comment.user_id
|
|
181
|
+
);
|
|
182
|
+
|
|
123
183
|
const isReplyingCurrent = computed(
|
|
124
184
|
() => props.comment.objectId === props.reply?.objectId
|
|
125
185
|
);
|
|
@@ -130,7 +190,13 @@ export default defineComponent({
|
|
|
130
190
|
|
|
131
191
|
isReplyingCurrent,
|
|
132
192
|
link,
|
|
193
|
+
like,
|
|
133
194
|
time,
|
|
195
|
+
|
|
196
|
+
isAdmin,
|
|
197
|
+
isOwner,
|
|
198
|
+
|
|
199
|
+
commentStatus,
|
|
134
200
|
};
|
|
135
201
|
},
|
|
136
202
|
});
|
package/src/components/Icons.ts
CHANGED
|
@@ -22,6 +22,16 @@ export const CloseIcon: FunctionalComponent<{ size: number }> = ({ size }) =>
|
|
|
22
22
|
]
|
|
23
23
|
);
|
|
24
24
|
|
|
25
|
+
export const DeleteIcon: FunctionalComponent = () =>
|
|
26
|
+
h(
|
|
27
|
+
'svg',
|
|
28
|
+
{ viewBox: '0 0 1024 1024', width: '24', height: '24' },
|
|
29
|
+
h('path', {
|
|
30
|
+
d: 'm341.013 394.667 27.755 393.45h271.83l27.733-393.45h64.106l-28.01 397.952a64 64 0 0 1-63.83 59.498H368.768a64 64 0 0 1-63.83-59.52l-28.053-397.93h64.128zm139.307 19.818v298.667h-64V414.485h64zm117.013 0v298.667h-64V414.485h64zM181.333 288h640v64h-640v-64zm453.483-106.667v64h-256v-64h256z',
|
|
31
|
+
fill: 'red',
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
|
|
25
35
|
export const EmojiIcon: FunctionalComponent = () =>
|
|
26
36
|
h(
|
|
27
37
|
'svg',
|
|
@@ -44,6 +54,22 @@ export const ImageIcon: FunctionalComponent = () =>
|
|
|
44
54
|
}),
|
|
45
55
|
]);
|
|
46
56
|
|
|
57
|
+
export const LikeIcon: FunctionalComponent<{ active: boolean }> = ({
|
|
58
|
+
active = false,
|
|
59
|
+
}: {
|
|
60
|
+
active?: boolean;
|
|
61
|
+
}) =>
|
|
62
|
+
h('svg', { viewBox: '0 0 1024 1024', width: '24', height: '24' }, [
|
|
63
|
+
h('path', {
|
|
64
|
+
d: `M850.654 323.804c-11.042-25.625-26.862-48.532-46.885-68.225-20.022-19.61-43.258-34.936-69.213-45.73-26.78-11.124-55.124-16.727-84.375-16.727-40.622 0-80.256 11.123-114.698 32.135A214.79 214.79 0 0 0 512 241.819a214.79 214.79 0 0 0-23.483-16.562c-34.442-21.012-74.076-32.135-114.698-32.135-29.25 0-57.595 5.603-84.375 16.727-25.872 10.711-49.19 26.12-69.213 45.73-20.105 19.693-35.843 42.6-46.885 68.225-11.453 26.615-17.303 54.877-17.303 83.963 0 27.439 5.603 56.03 16.727 85.117 9.31 24.307 22.659 49.52 39.715 74.981 27.027 40.293 64.188 82.316 110.33 124.915 76.465 70.615 152.189 119.394 155.402 121.371l19.528 12.525c8.652 5.52 19.776 5.52 28.427 0l19.529-12.525c3.213-2.06 78.854-50.756 155.401-121.371 46.143-42.6 83.304-84.622 110.33-124.915 17.057-25.46 30.487-50.674 39.716-74.981 11.124-29.087 16.727-57.678 16.727-85.117.082-29.086-5.768-57.348-17.221-83.963z${
|
|
65
|
+
active
|
|
66
|
+
? ''
|
|
67
|
+
: 'M512 761.5S218.665 573.55 218.665 407.767c0-83.963 69.461-152.023 155.154-152.023 60.233 0 112.473 33.618 138.181 82.727 25.708-49.109 77.948-82.727 138.18-82.727 85.694 0 155.155 68.06 155.155 152.023C805.335 573.551 512 761.5 512 761.5z'
|
|
68
|
+
}`,
|
|
69
|
+
fill: active ? 'red' : 'currentColor',
|
|
70
|
+
}),
|
|
71
|
+
]);
|
|
72
|
+
|
|
47
73
|
export const PreviewIcon: FunctionalComponent = () =>
|
|
48
74
|
h('svg', { viewBox: '0 0 1024 1024', width: '24', height: '24' }, [
|
|
49
75
|
h('path', {
|
|
@@ -69,9 +95,9 @@ export const MarkdownIcon: FunctionalComponent = () =>
|
|
|
69
95
|
export const ReplyIcon: FunctionalComponent = () =>
|
|
70
96
|
h(
|
|
71
97
|
'svg',
|
|
72
|
-
{ viewBox: '0 0 1024 1024', width: '
|
|
98
|
+
{ viewBox: '0 0 1024 1024', width: '24', height: '24' },
|
|
73
99
|
h('path', {
|
|
74
|
-
d: '
|
|
100
|
+
d: 'M810.667 213.333a64 64 0 0 1 64 64V704a64 64 0 0 1-64 64H478.336l-146.645 96.107a21.333 21.333 0 0 1-33.024-17.856V768h-85.334a64 64 0 0 1-64-64V277.333a64 64 0 0 1 64-64h597.334zm0 64H213.333V704h149.334v63.296L459.243 704h351.424V277.333zm-271.36 213.334v64h-176.64v-64h176.64zm122.026-128v64H362.667v-64h298.666z',
|
|
75
101
|
fill: 'currentColor',
|
|
76
102
|
})
|
|
77
103
|
);
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
:reply="reply"
|
|
16
16
|
@reply="onReply"
|
|
17
17
|
@submit="onSubmit"
|
|
18
|
+
@status="onStatusChange"
|
|
19
|
+
@delete="onDelete"
|
|
20
|
+
@sticky="onSticky"
|
|
21
|
+
@like="onLike"
|
|
18
22
|
/>
|
|
19
23
|
</div>
|
|
20
24
|
|
|
@@ -66,13 +70,21 @@ import { computed, defineComponent, onMounted, provide, ref, watch } from 'vue';
|
|
|
66
70
|
import CommentBox from './CommentBox.vue';
|
|
67
71
|
import CommentCard from './CommentCard.vue';
|
|
68
72
|
import { LoadingIcon } from './Icons';
|
|
69
|
-
import { useUserInfo } from '../composables';
|
|
73
|
+
import { useUserInfo, useLikeStorage } from '../composables';
|
|
70
74
|
import { defaultLocales } from '../config';
|
|
71
|
-
import {
|
|
75
|
+
import {
|
|
76
|
+
deleteComment,
|
|
77
|
+
fetchCommentList,
|
|
78
|
+
likeComment,
|
|
79
|
+
getConfig,
|
|
80
|
+
getDarkStyle,
|
|
81
|
+
updateComment,
|
|
82
|
+
} from '../utils';
|
|
72
83
|
|
|
73
84
|
import type { PropType } from 'vue';
|
|
74
85
|
import type {
|
|
75
86
|
WalineComment,
|
|
87
|
+
WalineCommentStatus,
|
|
76
88
|
WalineEmojiInfo,
|
|
77
89
|
WalineHighlighter,
|
|
78
90
|
WalineTexRenderer,
|
|
@@ -203,6 +215,7 @@ export default defineComponent({
|
|
|
203
215
|
const config = computed(() => getConfig(props as unknown as WalineProps));
|
|
204
216
|
|
|
205
217
|
const userInfo = useUserInfo();
|
|
218
|
+
const likeStorage = useLikeStorage();
|
|
206
219
|
|
|
207
220
|
const status = ref<'loading' | 'success' | 'error'>('loading');
|
|
208
221
|
|
|
@@ -281,6 +294,102 @@ export default defineComponent({
|
|
|
281
294
|
} else data.value.unshift(comment);
|
|
282
295
|
};
|
|
283
296
|
|
|
297
|
+
const onStatusChange = async ({
|
|
298
|
+
comment,
|
|
299
|
+
status,
|
|
300
|
+
}: {
|
|
301
|
+
comment: WalineComment;
|
|
302
|
+
status: WalineCommentStatus;
|
|
303
|
+
}): Promise<void> => {
|
|
304
|
+
if (comment.status === status) return;
|
|
305
|
+
|
|
306
|
+
const { serverURL, lang } = config.value;
|
|
307
|
+
|
|
308
|
+
await updateComment({
|
|
309
|
+
serverURL,
|
|
310
|
+
lang,
|
|
311
|
+
token: userInfo.value?.token,
|
|
312
|
+
objectId: comment.objectId,
|
|
313
|
+
status,
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
comment.status = status;
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
const onSticky = async (comment: WalineComment): Promise<void> => {
|
|
320
|
+
if (comment.rid) return;
|
|
321
|
+
|
|
322
|
+
const { serverURL, lang } = config.value;
|
|
323
|
+
|
|
324
|
+
await updateComment({
|
|
325
|
+
serverURL,
|
|
326
|
+
lang,
|
|
327
|
+
token: userInfo.value?.token,
|
|
328
|
+
objectId: comment.objectId,
|
|
329
|
+
sticky: comment.sticky ? 0 : 1,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
comment.sticky = !comment.sticky;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const onDelete = async ({ objectId }: WalineComment): Promise<void> => {
|
|
336
|
+
if (!confirm('Are you sure you want to delete this comment?')) return;
|
|
337
|
+
|
|
338
|
+
const { serverURL, lang } = config.value;
|
|
339
|
+
|
|
340
|
+
await deleteComment({
|
|
341
|
+
serverURL,
|
|
342
|
+
lang,
|
|
343
|
+
token: userInfo.value?.token,
|
|
344
|
+
objectId: objectId,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// delete comment from data
|
|
348
|
+
data.value.some((item, index) => {
|
|
349
|
+
if (item.objectId === objectId) {
|
|
350
|
+
data.value = data.value.filter((_item, i) => i !== index);
|
|
351
|
+
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return item.children.some((child, childIndex) => {
|
|
356
|
+
if (child.objectId === objectId) {
|
|
357
|
+
data.value[index].children = item.children.filter(
|
|
358
|
+
(_item, i) => i !== childIndex
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return false;
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const onLike = async (comment: WalineComment): Promise<void> => {
|
|
370
|
+
const { serverURL, lang } = config.value;
|
|
371
|
+
const { objectId } = comment;
|
|
372
|
+
const hasLiked = likeStorage.value.includes(objectId);
|
|
373
|
+
|
|
374
|
+
await likeComment({
|
|
375
|
+
serverURL,
|
|
376
|
+
lang,
|
|
377
|
+
objectId,
|
|
378
|
+
like: !hasLiked,
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
if (hasLiked)
|
|
382
|
+
likeStorage.value = likeStorage.value.filter((id) => id !== objectId);
|
|
383
|
+
else {
|
|
384
|
+
likeStorage.value = [...likeStorage.value, objectId];
|
|
385
|
+
|
|
386
|
+
if (likeStorage.value.length > 50)
|
|
387
|
+
likeStorage.value = likeStorage.value.slice(-50);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
comment.like = (comment.like || 0) + (hasLiked ? -1 : 1);
|
|
391
|
+
};
|
|
392
|
+
|
|
284
393
|
provide('config', config);
|
|
285
394
|
|
|
286
395
|
watch(() => (props as unknown as WalineProps).path, refresh);
|
|
@@ -303,6 +412,10 @@ export default defineComponent({
|
|
|
303
412
|
refresh,
|
|
304
413
|
onReply,
|
|
305
414
|
onSubmit,
|
|
415
|
+
onStatusChange,
|
|
416
|
+
onDelete,
|
|
417
|
+
onSticky,
|
|
418
|
+
onLike,
|
|
306
419
|
|
|
307
420
|
version: VERSION,
|
|
308
421
|
};
|
package/src/composables/index.ts
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useStorage } from '@vueuse/core';
|
|
2
|
+
|
|
3
|
+
import type { Ref } from 'vue';
|
|
4
|
+
|
|
5
|
+
const LIKE_KEY = 'WALIKE_LIKE';
|
|
6
|
+
|
|
7
|
+
export type LikeID = number | string;
|
|
8
|
+
|
|
9
|
+
export type LikeRef = Ref<LikeID[]>;
|
|
10
|
+
|
|
11
|
+
let likeStorage: LikeRef | null = null;
|
|
12
|
+
|
|
13
|
+
export const useLikeStorage = (): LikeRef =>
|
|
14
|
+
likeStorage || (likeStorage = useStorage<LikeID[]>(LIKE_KEY, []));
|
|
@@ -10,11 +10,19 @@ export interface UserInfo {
|
|
|
10
10
|
token: string;
|
|
11
11
|
avatar: string;
|
|
12
12
|
mailMd5: string;
|
|
13
|
+
objectId: string | number;
|
|
14
|
+
type: 'administrator' | 'guest';
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export const USER_KEY = 'WALINE_USER';
|
|
16
18
|
|
|
17
19
|
export type UserInfoRef = Ref<UserInfo | Record<string, never>>;
|
|
18
20
|
|
|
21
|
+
let userInfoStorage: UserInfoRef | null = null;
|
|
22
|
+
|
|
19
23
|
export const useUserInfo = (): UserInfoRef =>
|
|
20
|
-
|
|
24
|
+
userInfoStorage ||
|
|
25
|
+
(userInfoStorage = useStorage<UserInfo | Record<string, never>>(
|
|
26
|
+
'USER_KEY',
|
|
27
|
+
{}
|
|
28
|
+
));
|
package/src/config/i18n/en.ts
CHANGED
package/src/config/i18n/jp.ts
CHANGED
package/src/config/i18n/pt-BR.ts
CHANGED
package/src/config/i18n/ru.ts
CHANGED
package/src/config/i18n/vi-VN.ts
CHANGED
package/src/config/i18n/zh-CN.ts
CHANGED
package/src/config/i18n/zh-TW.ts
CHANGED
package/src/styles/card.scss
CHANGED
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
.wl-user {
|
|
19
19
|
--avatar-size: var(--waline-avatar-size);
|
|
20
20
|
|
|
21
|
+
position: relative;
|
|
22
|
+
margin-right: 0.75em;
|
|
23
|
+
|
|
21
24
|
@media (max-width: 720px) {
|
|
22
25
|
--avatar-size: var(--waline-m-avatar-size);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
position: relative;
|
|
26
|
-
margin-right: 0.75em;
|
|
27
|
-
|
|
28
28
|
img {
|
|
29
29
|
width: var(--avatar-size);
|
|
30
30
|
height: var(--avatar-size);
|
|
@@ -101,30 +101,6 @@
|
|
|
101
101
|
font-size: 0.75em;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
.wl-reply {
|
|
105
|
-
float: right;
|
|
106
|
-
|
|
107
|
-
padding: 4px;
|
|
108
|
-
border: none;
|
|
109
|
-
|
|
110
|
-
background: transparent;
|
|
111
|
-
color: var(--waline-color);
|
|
112
|
-
|
|
113
|
-
line-height: 1;
|
|
114
|
-
|
|
115
|
-
cursor: pointer;
|
|
116
|
-
|
|
117
|
-
transition: color 0.2s ease;
|
|
118
|
-
|
|
119
|
-
&:hover {
|
|
120
|
-
color: var(--waline-theme-color);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
&.active {
|
|
124
|
-
color: var(--waline-active-color);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
104
|
.wl-meta {
|
|
129
105
|
position: relative;
|
|
130
106
|
line-height: 1;
|
|
@@ -152,6 +128,36 @@
|
|
|
152
128
|
}
|
|
153
129
|
}
|
|
154
130
|
|
|
131
|
+
.wl-comment-actions {
|
|
132
|
+
float: right;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.wl-delete,
|
|
136
|
+
.wl-like,
|
|
137
|
+
.wl-reply {
|
|
138
|
+
display: inline-flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
padding: 4px;
|
|
141
|
+
border: none;
|
|
142
|
+
|
|
143
|
+
background: transparent;
|
|
144
|
+
color: var(--waline-color);
|
|
145
|
+
|
|
146
|
+
line-height: 1;
|
|
147
|
+
|
|
148
|
+
cursor: pointer;
|
|
149
|
+
|
|
150
|
+
transition: color 0.2s ease;
|
|
151
|
+
|
|
152
|
+
&:hover {
|
|
153
|
+
color: var(--waline-theme-color);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
&.active {
|
|
157
|
+
color: var(--waline-active-color);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
155
161
|
.wl-content {
|
|
156
162
|
position: relative;
|
|
157
163
|
|
|
@@ -213,6 +219,28 @@
|
|
|
213
219
|
}
|
|
214
220
|
}
|
|
215
221
|
|
|
222
|
+
.wl-admin-actions {
|
|
223
|
+
margin: 8px 0;
|
|
224
|
+
font-size: 12px;
|
|
225
|
+
text-align: right;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.wl-comment-status {
|
|
229
|
+
margin: 0 8px;
|
|
230
|
+
|
|
231
|
+
.wl-btn {
|
|
232
|
+
border-radius: 0;
|
|
233
|
+
|
|
234
|
+
&:first-child {
|
|
235
|
+
border-radius: 0.5em 0 0 0.5em;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
&:last-child {
|
|
239
|
+
border-radius: 0 0.5em 0.5em 0;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
216
244
|
.wl-quote {
|
|
217
245
|
border-left: 1px dashed rgb(237 237 237 / 50%);
|
|
218
246
|
|
package/src/styles/nomalize.scss
CHANGED