@waline/client 2.12.0 → 2.13.1
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/LICENSE +339 -0
- package/dist/api.cjs +1 -1
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +271 -53
- package/dist/api.d.mts +271 -53
- package/dist/api.d.ts +271 -53
- package/dist/api.mjs +1 -1
- package/dist/api.mjs.map +1 -1
- package/dist/comment.cjs +1 -1
- package/dist/comment.cjs.map +1 -1
- package/dist/comment.d.cts +1 -1
- package/dist/comment.d.mts +1 -1
- package/dist/comment.d.ts +1 -1
- package/dist/comment.js +73 -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 +8 -8
- 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.d.cts +1 -1
- package/dist/pageview.d.mts +1 -1
- package/dist/pageview.d.ts +1 -1
- package/dist/pageview.js +126 -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 +75 -11
- package/dist/shim.d.mts +75 -11
- 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.css +1 -1
- package/dist/waline.css.map +1 -1
- package/dist/waline.d.cts +75 -11
- package/dist/waline.d.mts +75 -11
- package/dist/waline.d.ts +75 -11
- package/dist/waline.js +6795 -1
- package/dist/waline.js.map +1 -1
- package/dist/waline.mjs +1 -1
- package/dist/waline.mjs.map +1 -1
- package/package.json +28 -29
- package/src/api/articleCounter.ts +50 -16
- package/src/api/comment.ts +131 -39
- package/src/api/commentCount.ts +25 -20
- package/src/api/index.ts +1 -0
- package/src/api/login.ts +49 -6
- package/src/api/pageview.ts +25 -12
- package/src/api/recentComment.ts +23 -7
- package/src/api/user.ts +43 -0
- package/src/api/utils.ts +21 -5
- package/src/components/ArticleReaction.vue +12 -3
- package/src/components/CommentBox.vue +26 -21
- package/src/components/ImageWall.vue +14 -14
- package/src/components/Waline.vue +25 -16
- package/src/composables/userInfo.ts +1 -2
- package/src/composables/vote.ts +1 -1
- package/src/config/default.ts +23 -24
- package/src/pageview.ts +2 -2
- package/src/styles/index.scss +2 -1
- package/src/styles/userlist.scss +158 -0
- package/src/utils/emoji.ts +1 -1
- package/src/widgets/index.ts +1 -0
- package/src/widgets/recentComments.ts +2 -2
- package/src/widgets/userList.ts +136 -0
package/src/api/user.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { errorCheck } from './utils';
|
|
2
|
+
import type { BaseAPIOptions } from './utils';
|
|
3
|
+
import type { WalineComment } from '../typings';
|
|
4
|
+
|
|
5
|
+
export interface GetUserListOptions extends BaseAPIOptions {
|
|
6
|
+
/**
|
|
7
|
+
* 每页个数
|
|
8
|
+
*
|
|
9
|
+
* Number per page
|
|
10
|
+
*/
|
|
11
|
+
pageSize: number;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 取消请求的信号
|
|
15
|
+
*
|
|
16
|
+
* AbortSignal to cancel request
|
|
17
|
+
*/
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface WalineUser
|
|
22
|
+
extends Pick<WalineComment, 'nick' | 'link' | 'avatar' | 'label' | 'level'> {
|
|
23
|
+
count: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface GetUserListResponse {
|
|
27
|
+
errno: number;
|
|
28
|
+
message: string;
|
|
29
|
+
data: WalineUser[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const getUserList = ({
|
|
33
|
+
serverURL,
|
|
34
|
+
signal,
|
|
35
|
+
pageSize,
|
|
36
|
+
lang,
|
|
37
|
+
}: GetUserListOptions): Promise<WalineUser[]> =>
|
|
38
|
+
fetch(`${serverURL}/user?pageSize=${pageSize}&lang=${lang}`, {
|
|
39
|
+
signal,
|
|
40
|
+
})
|
|
41
|
+
.then((resp) => <Promise<GetUserListResponse>>resp.json())
|
|
42
|
+
.then((resp) => errorCheck(resp, 'user list'))
|
|
43
|
+
.then((resp) => resp.data);
|
package/src/api/utils.ts
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface BaseAPIOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Waline 服务端地址
|
|
4
|
+
*
|
|
5
|
+
* Waline serverURL
|
|
6
|
+
*/
|
|
7
|
+
serverURL: string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 错误信息所使用的语言
|
|
11
|
+
*
|
|
12
|
+
* Language used in error text
|
|
13
|
+
*/
|
|
14
|
+
lang: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface APIErrorResponse {
|
|
2
18
|
errno: number;
|
|
3
19
|
errmsg: string;
|
|
4
20
|
}
|
|
@@ -9,13 +25,13 @@ export const JSON_HEADERS: Record<string, string> = {
|
|
|
9
25
|
};
|
|
10
26
|
|
|
11
27
|
export const errorCheck = <T = unknown>(
|
|
12
|
-
data: T |
|
|
28
|
+
data: T | APIErrorResponse,
|
|
13
29
|
name = ''
|
|
14
30
|
): T => {
|
|
15
|
-
if (typeof data === 'object' && (data as
|
|
31
|
+
if (typeof data === 'object' && (data as APIErrorResponse).errno)
|
|
16
32
|
throw new TypeError(
|
|
17
|
-
`Fetch ${name} failed with ${(data as
|
|
18
|
-
(data as
|
|
33
|
+
`Fetch ${name} failed with ${(data as APIErrorResponse).errno}: ${
|
|
34
|
+
(data as APIErrorResponse).errmsg
|
|
19
35
|
}`
|
|
20
36
|
);
|
|
21
37
|
|
|
@@ -27,8 +27,9 @@ import {
|
|
|
27
27
|
onMounted,
|
|
28
28
|
onUnmounted,
|
|
29
29
|
ref,
|
|
30
|
+
watch,
|
|
30
31
|
} from 'vue';
|
|
31
|
-
import {
|
|
32
|
+
import { getArticleCounter, updateArticleCounter } from '../api';
|
|
32
33
|
import { VOTE_IDENTIFIER, VOTE_INDEX, useVoteStorage } from '../composables';
|
|
33
34
|
import type { WalineConfig } from '../utils';
|
|
34
35
|
import type { WalineLocale } from '../typings';
|
|
@@ -70,7 +71,7 @@ export default defineComponent({
|
|
|
70
71
|
if (reaction.length) {
|
|
71
72
|
const controller = new AbortController();
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
getArticleCounter({
|
|
74
75
|
serverURL,
|
|
75
76
|
lang,
|
|
76
77
|
paths: [path],
|
|
@@ -128,7 +129,15 @@ export default defineComponent({
|
|
|
128
129
|
voteStorage.value = voteStorage.value.slice(-50);
|
|
129
130
|
};
|
|
130
131
|
|
|
131
|
-
onMounted(() =>
|
|
132
|
+
onMounted(() => {
|
|
133
|
+
watch(
|
|
134
|
+
() => [config.value.serverURL, config.value.path],
|
|
135
|
+
() => {
|
|
136
|
+
fetchCounter();
|
|
137
|
+
},
|
|
138
|
+
{ immediate: true }
|
|
139
|
+
);
|
|
140
|
+
});
|
|
132
141
|
onUnmounted(() => abort?.());
|
|
133
142
|
|
|
134
143
|
return {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
>
|
|
37
37
|
<div v-for="kind in config.meta" :key="kind" class="wl-header-item">
|
|
38
38
|
<label
|
|
39
|
-
:for="kind"
|
|
39
|
+
:for="`wl-${kind}`"
|
|
40
40
|
v-text="
|
|
41
41
|
locale[kind] +
|
|
42
42
|
(config.requiredMeta.includes(kind) || !config.requiredMeta.length
|
|
@@ -287,7 +287,7 @@ import {
|
|
|
287
287
|
GifIcon,
|
|
288
288
|
} from './Icons';
|
|
289
289
|
import ImageWall from './ImageWall.vue';
|
|
290
|
-
import {
|
|
290
|
+
import { addComment, login } from '../api';
|
|
291
291
|
import { useEditor, useUserMeta, useUserInfo } from '../composables';
|
|
292
292
|
import {
|
|
293
293
|
getEmojis,
|
|
@@ -532,7 +532,7 @@ export default defineComponent({
|
|
|
532
532
|
|
|
533
533
|
isSubmitting.value = true;
|
|
534
534
|
|
|
535
|
-
|
|
535
|
+
addComment({
|
|
536
536
|
serverURL,
|
|
537
537
|
lang,
|
|
538
538
|
token: userInfo.value?.token,
|
|
@@ -590,8 +590,12 @@ export default defineComponent({
|
|
|
590
590
|
const height = 800;
|
|
591
591
|
const left = (window.innerWidth - width) / 2;
|
|
592
592
|
const top = (window.innerHeight - height) / 2;
|
|
593
|
+
const query = new URLSearchParams({
|
|
594
|
+
lng: lang,
|
|
595
|
+
token: userInfo.value!.token,
|
|
596
|
+
});
|
|
593
597
|
const handler = window.open(
|
|
594
|
-
`${serverURL}/ui/profile
|
|
598
|
+
`${serverURL}/ui/profile?${query.toString()}`,
|
|
595
599
|
'_blank',
|
|
596
600
|
`width=${width},height=${height},left=${left},top=${top},scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no`
|
|
597
601
|
);
|
|
@@ -668,23 +672,6 @@ export default defineComponent({
|
|
|
668
672
|
{ immediate: true }
|
|
669
673
|
);
|
|
670
674
|
|
|
671
|
-
watch(showGif, async (showGif) => {
|
|
672
|
-
if (!showGif) return;
|
|
673
|
-
|
|
674
|
-
const searchOptions = config.value.search as WalineSearchOptions;
|
|
675
|
-
|
|
676
|
-
// clear input
|
|
677
|
-
if (gifSearchInputRef.value) gifSearchInputRef.value.value = '';
|
|
678
|
-
|
|
679
|
-
searchResults.loading = true;
|
|
680
|
-
|
|
681
|
-
searchResults.list = searchOptions.default
|
|
682
|
-
? await searchOptions.default()
|
|
683
|
-
: await searchOptions.search('');
|
|
684
|
-
|
|
685
|
-
searchResults.loading = false;
|
|
686
|
-
});
|
|
687
|
-
|
|
688
675
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
689
676
|
const onMessageRecive = ({ data }: any): void => {
|
|
690
677
|
if (!data || data.type !== 'profile') return;
|
|
@@ -705,6 +692,24 @@ export default defineComponent({
|
|
|
705
692
|
editor.value = props.edit.orig;
|
|
706
693
|
}
|
|
707
694
|
|
|
695
|
+
// watch gif
|
|
696
|
+
watch(showGif, async (showGif) => {
|
|
697
|
+
if (!showGif) return;
|
|
698
|
+
|
|
699
|
+
const searchOptions = config.value.search as WalineSearchOptions;
|
|
700
|
+
|
|
701
|
+
// clear input
|
|
702
|
+
if (gifSearchInputRef.value) gifSearchInputRef.value.value = '';
|
|
703
|
+
|
|
704
|
+
searchResults.loading = true;
|
|
705
|
+
|
|
706
|
+
searchResults.list = searchOptions.default
|
|
707
|
+
? await searchOptions.default()
|
|
708
|
+
: await searchOptions.search('');
|
|
709
|
+
|
|
710
|
+
searchResults.loading = false;
|
|
711
|
+
});
|
|
712
|
+
|
|
708
713
|
// watch editor
|
|
709
714
|
watch(
|
|
710
715
|
() => editor.value,
|
|
@@ -133,27 +133,27 @@ export default defineComponent({
|
|
|
133
133
|
window.scrollTo({ top: scrollY });
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
-
const imageLoad = (e: Event) => {
|
|
136
|
+
const imageLoad = (e: Event): void => {
|
|
137
137
|
state.value[(e.target as HTMLImageElement).src] = true;
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
-
watch(
|
|
141
|
-
() => [props.items],
|
|
142
|
-
() => {
|
|
143
|
-
state.value = {};
|
|
144
|
-
redraw(true);
|
|
145
|
-
}
|
|
146
|
-
);
|
|
147
|
-
watch(
|
|
148
|
-
() => [props.columnWidth, props.gap],
|
|
149
|
-
() => redraw()
|
|
150
|
-
);
|
|
151
|
-
|
|
152
140
|
onMounted(() => {
|
|
153
141
|
redraw(true);
|
|
154
|
-
resizeObserver = new ResizeObserver(() => redraw());
|
|
155
142
|
|
|
143
|
+
resizeObserver = new ResizeObserver(() => redraw());
|
|
156
144
|
resizeObserver.observe(wall.value!);
|
|
145
|
+
|
|
146
|
+
watch(
|
|
147
|
+
() => [props.items],
|
|
148
|
+
() => {
|
|
149
|
+
state.value = {};
|
|
150
|
+
redraw(true);
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
watch(
|
|
154
|
+
() => [props.columnWidth, props.gap],
|
|
155
|
+
() => redraw()
|
|
156
|
+
);
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
onBeforeUnmount(() => resizeObserver!.unobserve(wall.value!));
|
|
@@ -81,19 +81,22 @@
|
|
|
81
81
|
|
|
82
82
|
<script lang="ts">
|
|
83
83
|
import { useStyleTag } from '@vueuse/core';
|
|
84
|
-
import {
|
|
84
|
+
import {
|
|
85
|
+
computed,
|
|
86
|
+
defineComponent,
|
|
87
|
+
onMounted,
|
|
88
|
+
onUnmounted,
|
|
89
|
+
provide,
|
|
90
|
+
ref,
|
|
91
|
+
watch,
|
|
92
|
+
} from 'vue';
|
|
85
93
|
import Reaction from './ArticleReaction.vue';
|
|
86
94
|
import CommentBox from './CommentBox.vue';
|
|
87
95
|
import CommentCard from './CommentCard.vue';
|
|
88
96
|
import { LoadingIcon } from './Icons';
|
|
89
97
|
import { useUserInfo, useLikeStorage } from '../composables';
|
|
90
98
|
import { defaultLocales } from '../config';
|
|
91
|
-
import {
|
|
92
|
-
deleteComment,
|
|
93
|
-
fetchComment,
|
|
94
|
-
likeComment,
|
|
95
|
-
updateComment,
|
|
96
|
-
} from '../api';
|
|
99
|
+
import { deleteComment, getComment, likeComment, updateComment } from '../api';
|
|
97
100
|
import { getConfig, getDarkStyle } from '../utils';
|
|
98
101
|
|
|
99
102
|
import type { PropType } from 'vue';
|
|
@@ -263,8 +266,9 @@ export default defineComponent({
|
|
|
263
266
|
|
|
264
267
|
props: SHOULD_VALIDATE ? propsWithValidate : props,
|
|
265
268
|
|
|
266
|
-
setup(
|
|
267
|
-
const
|
|
269
|
+
setup(_props) {
|
|
270
|
+
const props = _props as unknown as WalineProps;
|
|
271
|
+
const config = computed(() => getConfig(props));
|
|
268
272
|
|
|
269
273
|
const userInfo = useUserInfo();
|
|
270
274
|
const likeStorage = useLikeStorage();
|
|
@@ -287,7 +291,7 @@ export default defineComponent({
|
|
|
287
291
|
// eslint-disable-next-line vue/no-setup-props-destructure
|
|
288
292
|
let abort: () => void;
|
|
289
293
|
|
|
290
|
-
const
|
|
294
|
+
const getCommentData = (pageNumber: number): void => {
|
|
291
295
|
const { serverURL, path, pageSize } = config.value;
|
|
292
296
|
const controller = new AbortController();
|
|
293
297
|
|
|
@@ -295,7 +299,7 @@ export default defineComponent({
|
|
|
295
299
|
|
|
296
300
|
abort?.();
|
|
297
301
|
|
|
298
|
-
|
|
302
|
+
getComment({
|
|
299
303
|
serverURL,
|
|
300
304
|
lang: config.value.lang,
|
|
301
305
|
path,
|
|
@@ -322,12 +326,12 @@ export default defineComponent({
|
|
|
322
326
|
abort = controller.abort.bind(controller);
|
|
323
327
|
};
|
|
324
328
|
|
|
325
|
-
const loadMore = (): void =>
|
|
329
|
+
const loadMore = (): void => getCommentData(page.value + 1);
|
|
326
330
|
|
|
327
331
|
const refresh = (): void => {
|
|
328
332
|
count.value = 0;
|
|
329
333
|
data.value = [];
|
|
330
|
-
|
|
334
|
+
getCommentData(1);
|
|
331
335
|
};
|
|
332
336
|
|
|
333
337
|
const onSortByChange = (item: SortKeyItems): void => {
|
|
@@ -462,9 +466,14 @@ export default defineComponent({
|
|
|
462
466
|
|
|
463
467
|
provide('config', config);
|
|
464
468
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
469
|
+
onMounted(() => {
|
|
470
|
+
watch(
|
|
471
|
+
() => [props.serverURL, props.path],
|
|
472
|
+
() => refresh(),
|
|
473
|
+
{ immediate: true }
|
|
474
|
+
);
|
|
475
|
+
});
|
|
476
|
+
onUnmounted(() => abort?.());
|
|
468
477
|
|
|
469
478
|
return {
|
|
470
479
|
config,
|
|
@@ -10,8 +10,7 @@ export type UserInfoRef = Ref<UserInfo | Record<string, never>>;
|
|
|
10
10
|
let userInfoStorage: UserInfoRef | null = null;
|
|
11
11
|
|
|
12
12
|
export const useUserInfo = (): UserInfoRef =>
|
|
13
|
-
userInfoStorage
|
|
14
|
-
(userInfoStorage = useStorage<UserInfo | Record<string, never>>(
|
|
13
|
+
(userInfoStorage ??= useStorage<UserInfo | Record<string, never>>(
|
|
15
14
|
USER_KEY,
|
|
16
15
|
{}
|
|
17
16
|
));
|
package/src/composables/vote.ts
CHANGED
|
@@ -17,4 +17,4 @@ export type VoteRef = Ref<VoteLogItem[]>;
|
|
|
17
17
|
let voteStorage: VoteRef | null = null;
|
|
18
18
|
|
|
19
19
|
export const useVoteStorage = (): VoteRef =>
|
|
20
|
-
|
|
20
|
+
(voteStorage ??= useStorage<VoteLogItem[]>(VOTE_KEY, []));
|
package/src/config/default.ts
CHANGED
|
@@ -14,9 +14,8 @@ export const defaultLang = 'zh-CN';
|
|
|
14
14
|
|
|
15
15
|
export const defaultUploadImage = (file: File): Promise<string> =>
|
|
16
16
|
new Promise((resolve, reject) => {
|
|
17
|
-
if (file.size > 128 * 1000)
|
|
17
|
+
if (file.size > 128 * 1000)
|
|
18
18
|
return reject(new Error('File too large! File size limit 128KB'));
|
|
19
|
-
}
|
|
20
19
|
|
|
21
20
|
const reader = new FileReader();
|
|
22
21
|
|
|
@@ -31,43 +30,43 @@ export const defaultTexRenderer = (blockMode: boolean): string =>
|
|
|
31
30
|
: '<span class="wl-tex">Tex is not available in preview</span>';
|
|
32
31
|
|
|
33
32
|
export const getDefaultSearchOptions = (lang: string): WalineSearchOptions => {
|
|
34
|
-
interface
|
|
33
|
+
interface GifsResult {
|
|
34
|
+
data: IGif[];
|
|
35
35
|
meta: {
|
|
36
36
|
msg: string;
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
37
38
|
response_id: string;
|
|
38
39
|
status: number;
|
|
39
40
|
};
|
|
40
41
|
pagination: {
|
|
41
42
|
count: number;
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
42
44
|
total_count: number;
|
|
43
45
|
offset: number;
|
|
44
46
|
};
|
|
45
47
|
}
|
|
46
|
-
interface GifsResult extends Result {
|
|
47
|
-
data: IGif[];
|
|
48
|
-
}
|
|
49
48
|
|
|
50
49
|
const fetchGiphy = async (
|
|
51
50
|
url: string,
|
|
52
51
|
params: Record<string, string> = {}
|
|
53
|
-
): Promise<WalineSearchResult> =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
): Promise<WalineSearchResult> =>
|
|
53
|
+
fetch(
|
|
54
|
+
`https://api.giphy.com/v1/gifs/${url}?${new URLSearchParams({
|
|
55
|
+
lang,
|
|
56
|
+
limit: '20',
|
|
57
|
+
rating: 'g',
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
59
|
+
api_key: '6CIMLkNMMOhRcXPoMCPkFy4Ybk2XUiMp',
|
|
60
|
+
...params,
|
|
61
|
+
}).toString()}`
|
|
62
|
+
)
|
|
63
|
+
.then((resp) => <Promise<GifsResult>>resp.json())
|
|
64
|
+
.then(({ data }) =>
|
|
65
|
+
data.map((gif) => ({
|
|
66
|
+
title: gif.title,
|
|
67
|
+
src: gif.images.downsized_medium.url,
|
|
68
|
+
}))
|
|
69
|
+
);
|
|
71
70
|
|
|
72
71
|
return {
|
|
73
72
|
search: (word: string): Promise<WalineSearchResult> =>
|
package/src/pageview.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPageviews, updatePageviews } from './api';
|
|
2
2
|
import { errorHandler, getQuery, getServerURL } from './utils';
|
|
3
3
|
|
|
4
4
|
import type { WalineAbort } from './typings';
|
|
@@ -78,7 +78,7 @@ export const pageviewCount = ({
|
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
const fetch = (elements: HTMLElement[]): Promise<void> =>
|
|
81
|
-
|
|
81
|
+
getPageviews({
|
|
82
82
|
serverURL: getServerURL(serverURL),
|
|
83
83
|
paths: elements.map((element) => getQuery(element) || path),
|
|
84
84
|
lang,
|
package/src/styles/index.scss
CHANGED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
.wl-user-list {
|
|
2
|
+
padding: 0;
|
|
3
|
+
list-style: none;
|
|
4
|
+
|
|
5
|
+
.wl-user-item {
|
|
6
|
+
margin: 10px 0;
|
|
7
|
+
|
|
8
|
+
&:nth-child(1) .wl-user-badge {
|
|
9
|
+
background: var(--waline-rank-gold-bgcolor, #fa3939);
|
|
10
|
+
color: var(--waline-white);
|
|
11
|
+
font-weight: bold;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&:nth-child(2) .wl-user-badge {
|
|
15
|
+
background: var(--waline-rank-silver-bgcolor, #fb811c);
|
|
16
|
+
color: var(--waline-white);
|
|
17
|
+
font-weight: bold;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&:nth-child(3) .wl-user-badge {
|
|
21
|
+
background: var(--waline-rank-copper-bgcolor, #feb207);
|
|
22
|
+
color: var(--waline-white);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
a,
|
|
27
|
+
a:hover,
|
|
28
|
+
a:visited {
|
|
29
|
+
color: var(--waline-color);
|
|
30
|
+
text-decoration: none;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.wl-user-avatar {
|
|
34
|
+
position: relative;
|
|
35
|
+
|
|
36
|
+
display: inline-block;
|
|
37
|
+
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
|
|
40
|
+
margin-right: 10px;
|
|
41
|
+
border-radius: 4px;
|
|
42
|
+
|
|
43
|
+
line-height: 0;
|
|
44
|
+
|
|
45
|
+
> img {
|
|
46
|
+
width: var(--waline-user-avatar-size, 48px);
|
|
47
|
+
height: var(--waline-user-avatar-size, 48px);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.wl-user-badge {
|
|
52
|
+
position: absolute;
|
|
53
|
+
right: 0;
|
|
54
|
+
bottom: 0;
|
|
55
|
+
|
|
56
|
+
min-width: 0.7em;
|
|
57
|
+
height: 1.5em;
|
|
58
|
+
padding: 0 0.4em;
|
|
59
|
+
border-radius: 4px;
|
|
60
|
+
|
|
61
|
+
background: var(--waline-info-bgcolor);
|
|
62
|
+
color: var(--waline-info-color);
|
|
63
|
+
|
|
64
|
+
font-weight: bold;
|
|
65
|
+
font-size: 10px;
|
|
66
|
+
line-height: 1.5em;
|
|
67
|
+
text-align: center;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.wl-user-meta {
|
|
71
|
+
display: inline-block;
|
|
72
|
+
vertical-align: top;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.wl-badge {
|
|
76
|
+
display: inline-block;
|
|
77
|
+
vertical-align: text-top;
|
|
78
|
+
|
|
79
|
+
margin-left: 0.5em;
|
|
80
|
+
padding: 0 0.3em;
|
|
81
|
+
border: 1px solid var(--waline-badge-color);
|
|
82
|
+
border-radius: 4px;
|
|
83
|
+
|
|
84
|
+
color: var(--waline-badge-color);
|
|
85
|
+
|
|
86
|
+
font-size: var(--waline-badge-font-size);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.wl-user-wall {
|
|
91
|
+
padding: 0;
|
|
92
|
+
list-style: none;
|
|
93
|
+
|
|
94
|
+
.wl-user-item {
|
|
95
|
+
position: relative;
|
|
96
|
+
display: inline-block;
|
|
97
|
+
transition: transform ease-in-out 0.2s;
|
|
98
|
+
|
|
99
|
+
&::before,
|
|
100
|
+
&::after {
|
|
101
|
+
position: absolute;
|
|
102
|
+
bottom: 100%;
|
|
103
|
+
left: 50%;
|
|
104
|
+
z-index: 10;
|
|
105
|
+
|
|
106
|
+
opacity: 0;
|
|
107
|
+
pointer-events: none;
|
|
108
|
+
|
|
109
|
+
transition: all 0.18s ease-out 0.18s;
|
|
110
|
+
transform: translate(-50%, 4px);
|
|
111
|
+
transform-origin: top;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
&::before {
|
|
115
|
+
content: '';
|
|
116
|
+
|
|
117
|
+
width: 0;
|
|
118
|
+
height: 0;
|
|
119
|
+
border: 5px solid transparent;
|
|
120
|
+
border-top-color: rgb(16 16 16 / 95%);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&::after {
|
|
124
|
+
content: attr(aria-label);
|
|
125
|
+
|
|
126
|
+
margin-bottom: 10px;
|
|
127
|
+
padding: 0.5em 1em;
|
|
128
|
+
border-radius: 2px;
|
|
129
|
+
|
|
130
|
+
background: rgb(16 16 16 / 95%);
|
|
131
|
+
color: #fff;
|
|
132
|
+
|
|
133
|
+
font-size: 12px;
|
|
134
|
+
white-space: nowrap;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
&:hover {
|
|
138
|
+
transform: scale(1.1);
|
|
139
|
+
|
|
140
|
+
&::before,
|
|
141
|
+
&::after {
|
|
142
|
+
opacity: 1;
|
|
143
|
+
pointer-events: none;
|
|
144
|
+
transform: translate(-50%, 0);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
img {
|
|
149
|
+
width: var(--waline-user-avatar-size, 48px);
|
|
150
|
+
height: var(--waline-user-avatar-size, 48px);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.wl-user-badge,
|
|
155
|
+
.wl-user-meta {
|
|
156
|
+
display: none;
|
|
157
|
+
}
|
|
158
|
+
}
|
package/src/utils/emoji.ts
CHANGED
|
@@ -22,7 +22,7 @@ const fetchEmoji = (link: string): Promise<WalineEmojiInfo> => {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
return fetch(`${link}/info.json`)
|
|
25
|
-
.then((resp) =>
|
|
25
|
+
.then((resp) => <Promise<Omit<WalineEmojiInfo, 'folder'>>>resp.json())
|
|
26
26
|
.then((emojiInfo) => {
|
|
27
27
|
const info = {
|
|
28
28
|
folder: link,
|
package/src/widgets/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRecentComment } from '../api';
|
|
2
2
|
import { useUserInfo } from '../composables';
|
|
3
3
|
import { getRoot } from '../utils';
|
|
4
4
|
|
|
@@ -62,7 +62,7 @@ export const RecentComments = ({
|
|
|
62
62
|
const root = getRoot(el);
|
|
63
63
|
const controller = new AbortController();
|
|
64
64
|
|
|
65
|
-
return
|
|
65
|
+
return getRecentComment({
|
|
66
66
|
serverURL,
|
|
67
67
|
count,
|
|
68
68
|
lang,
|