@waline/client 2.11.0 → 2.11.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.
Files changed (73) hide show
  1. package/LICENSE +339 -0
  2. package/dist/api.cjs +2 -0
  3. package/dist/api.cjs.map +1 -0
  4. package/dist/api.d.cts +1 -0
  5. package/dist/api.d.mts +1 -0
  6. package/dist/api.d.ts +1 -0
  7. package/dist/api.mjs +2 -0
  8. package/dist/api.mjs.map +1 -0
  9. package/dist/comment.cjs +2 -0
  10. package/dist/comment.cjs.map +1 -0
  11. package/dist/comment.d.cts +39 -0
  12. package/dist/comment.d.mts +39 -0
  13. package/dist/comment.d.ts +39 -0
  14. package/dist/comment.js +2 -0
  15. package/dist/comment.js.map +1 -0
  16. package/dist/comment.mjs +2 -0
  17. package/dist/comment.mjs.map +1 -0
  18. package/dist/component.mjs +1 -1
  19. package/dist/component.mjs.map +1 -1
  20. package/dist/legacy.umd.js +1 -1
  21. package/dist/legacy.umd.js.map +1 -1
  22. package/dist/pageview.cjs +1 -1
  23. package/dist/pageview.cjs.map +1 -1
  24. package/dist/pageview.js +1 -1
  25. package/dist/pageview.js.map +1 -1
  26. package/dist/pageview.mjs +1 -1
  27. package/dist/pageview.mjs.map +1 -1
  28. package/dist/shim.cjs +1 -1
  29. package/dist/shim.cjs.map +1 -1
  30. package/dist/shim.mjs +1 -1
  31. package/dist/shim.mjs.map +1 -1
  32. package/dist/waline-meta.css +1 -1
  33. package/dist/waline-meta.css.map +1 -1
  34. package/dist/waline.cjs +1 -1
  35. package/dist/waline.cjs.map +1 -1
  36. package/dist/waline.css +1 -1
  37. package/dist/waline.css.map +1 -1
  38. package/dist/waline.js +1 -1
  39. package/dist/waline.js.map +1 -1
  40. package/dist/waline.mjs +1 -1
  41. package/dist/waline.mjs.map +1 -1
  42. package/package.json +34 -13
  43. package/src/api/articleCounter.ts +53 -0
  44. package/src/api/comment.ts +147 -0
  45. package/src/api/commentCount.ts +30 -0
  46. package/src/api/index.ts +6 -0
  47. package/src/api/login.ts +53 -0
  48. package/src/api/pageview.ts +41 -0
  49. package/src/api/recentComment.ts +29 -0
  50. package/src/api/utils.ts +23 -0
  51. package/src/comment.ts +2 -10
  52. package/src/components/ArticleReaction.vue +18 -30
  53. package/src/components/CommentBox.vue +23 -48
  54. package/src/components/Waline.vue +11 -9
  55. package/src/composables/index.ts +3 -1
  56. package/src/composables/recaptchaV3.ts +23 -0
  57. package/src/composables/userInfo.ts +1 -12
  58. package/src/entrys/api.ts +1 -0
  59. package/src/entrys/comment.ts +2 -0
  60. package/src/init.ts +0 -11
  61. package/src/pageview.ts +2 -7
  62. package/src/styles/card.scss +1 -1
  63. package/src/styles/helpers/_svg.scss +12 -12
  64. package/src/styles/index.scss +1 -1
  65. package/src/styles/meta.scss +10 -14
  66. package/src/styles/reaction.scss +24 -18
  67. package/src/utils/config.ts +3 -3
  68. package/src/utils/index.ts +0 -1
  69. package/src/widgets/recentComments.ts +2 -1
  70. package/src/components/RecaptchaV3/IReCaptchaOptions.ts +0 -6
  71. package/src/components/RecaptchaV3/README.md +0 -3
  72. package/src/components/RecaptchaV3/RecaptchaVuePlugin.ts +0 -86
  73. package/src/utils/fetch.ts +0 -310
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/client",
3
- "version": "2.11.0",
3
+ "version": "2.11.2",
4
4
  "description": "client for waline comment system",
5
5
  "keywords": [
6
6
  "valine",
@@ -25,6 +25,11 @@
25
25
  "require": "./dist/shim.cjs",
26
26
  "default": "./dist/shim.cjs"
27
27
  },
28
+ "./api": {
29
+ "types": "./dist/api.d.ts",
30
+ "require": "./dist/api.cjs",
31
+ "default": "./dist/api.mjs"
32
+ },
28
33
  "./component": {
29
34
  "default": "./dist/component.mjs"
30
35
  },
@@ -34,6 +39,12 @@
34
39
  "require": "./dist/waline.cjs",
35
40
  "default": "./dist/waline.js"
36
41
  },
42
+ "./comment": {
43
+ "types": "./dist/comment.d.ts",
44
+ "import": "./dist/comment.mjs",
45
+ "require": "./dist/comment.cjs",
46
+ "default": "./dist/comment.js"
47
+ },
37
48
  "./pageview": {
38
49
  "types": "./dist/pageview.d.ts",
39
50
  "import": "./dist/pageview.mjs",
@@ -42,9 +53,20 @@
42
53
  },
43
54
  "./waline.css": "./dist/waline.css",
44
55
  "./waline-meta.css": "./dist/waline-meta.css",
56
+ "./dist/api": {
57
+ "types": "./dist/api.d.ts",
58
+ "require": "./dist/api.cjs",
59
+ "default": "./dist/api.mjs"
60
+ },
45
61
  "./dist/component": {
46
62
  "default": "./dist/component.mjs"
47
63
  },
64
+ "./dist/comment": {
65
+ "types": "./dist/comment.d.ts",
66
+ "import": "./dist/comment.mjs",
67
+ "require": "./dist/comment.cjs",
68
+ "default": "./dist/comment.js"
69
+ },
48
70
  "./dist/pageview": {
49
71
  "types": "./dist/pageview.d.ts",
50
72
  "import": "./dist/pageview.mjs",
@@ -71,17 +93,6 @@
71
93
  "dist",
72
94
  "src"
73
95
  ],
74
- "scripts": {
75
- "build": "pnpm rollup && pnpm style",
76
- "clean": "rimraf ./dist",
77
- "dev": "vite -c config/vite.config.js",
78
- "lint": "eslint --ext .ts,.vue .",
79
- "prepublishOnly": "pnpm clean && pnpm build",
80
- "rollup": "rollup -c ./config/rollup.config.js",
81
- "style": "pnpm style:main && pnpm style:meta",
82
- "style:main": "sass ./src/styles/index.scss ./dist/waline.css --style=compressed",
83
- "style:meta": "sass ./src/styles/meta.scss ./dist/waline-meta.css --style=compressed"
84
- },
85
96
  "browserslist": {
86
97
  "production": [
87
98
  ">0.5%",
@@ -124,5 +135,15 @@
124
135
  },
125
136
  "engines": {
126
137
  "node": ">=14"
138
+ },
139
+ "scripts": {
140
+ "build": "pnpm rollup && pnpm style",
141
+ "clean": "rimraf ./dist",
142
+ "dev": "vite -c config/vite.config.js",
143
+ "lint": "eslint --ext .ts,.vue .",
144
+ "rollup": "rollup -c ./config/rollup.config.js",
145
+ "style": "pnpm style:main && pnpm style:meta",
146
+ "style:main": "sass ./src/styles/index.scss ./dist/waline.css --style=compressed",
147
+ "style:meta": "sass ./src/styles/meta.scss ./dist/waline-meta.css --style=compressed"
127
148
  }
128
- }
149
+ }
@@ -0,0 +1,53 @@
1
+ import { JSON_HEADERS, errorCheck } from './utils';
2
+
3
+ export interface FetchArticleCounterOptions {
4
+ serverURL: string;
5
+ lang: string;
6
+ paths: string[];
7
+ signal: AbortSignal;
8
+ type: string[];
9
+ }
10
+
11
+ export const fetchArticleCounter = ({
12
+ serverURL,
13
+ lang,
14
+ paths,
15
+ type,
16
+ signal,
17
+ }: FetchArticleCounterOptions): Promise<
18
+ Record<string, number>[] | Record<string, number> | number[] | number
19
+ > =>
20
+ fetch(
21
+ `${serverURL}/article?path=${encodeURIComponent(
22
+ paths.join(',')
23
+ )}&type=${encodeURIComponent(type.join(','))}&lang=${lang}`,
24
+ { signal }
25
+ )
26
+ .then(
27
+ (resp) =>
28
+ resp.json() as Promise<Record<string, number>[] | number[] | number>
29
+ )
30
+ .then((data) => errorCheck(data, 'article count'));
31
+
32
+ export interface UpdateArticleCounterOptions {
33
+ serverURL: string;
34
+ lang: string;
35
+ path: string;
36
+ type: string;
37
+ action?: 'inc' | 'desc';
38
+ }
39
+
40
+ export const updateArticleCounter = ({
41
+ serverURL,
42
+ lang,
43
+ path,
44
+ type,
45
+ action,
46
+ }: UpdateArticleCounterOptions): Promise<number> =>
47
+ fetch(`${serverURL}/article?lang=${lang}`, {
48
+ method: 'POST',
49
+ headers: JSON_HEADERS,
50
+ body: JSON.stringify({ path, type, action }),
51
+ })
52
+ .then((resp) => resp.json() as Promise<number>)
53
+ .then((data) => errorCheck(data, 'article count'));
@@ -0,0 +1,147 @@
1
+ import { JSON_HEADERS, errorCheck } from './utils';
2
+ import type { WalineComment, WalineCommentData } from '../typings';
3
+
4
+ export interface FetchCommentOptions {
5
+ serverURL: string;
6
+ path: string;
7
+ page: number;
8
+ pageSize: number;
9
+ sortBy: string;
10
+ signal: AbortSignal;
11
+ token?: string;
12
+ lang: string;
13
+ }
14
+
15
+ export interface CommentData {
16
+ count: number;
17
+ data: WalineComment[];
18
+ totalPages: number;
19
+ }
20
+
21
+ export const fetchComment = ({
22
+ serverURL,
23
+ lang,
24
+ path,
25
+ page,
26
+ pageSize,
27
+ sortBy,
28
+ signal,
29
+ token,
30
+ }: FetchCommentOptions): Promise<CommentData> => {
31
+ const headers: Record<string, string> = {};
32
+
33
+ if (token) headers.Authorization = `Bearer ${token}`;
34
+
35
+ return fetch(
36
+ `${serverURL}/comment?path=${encodeURIComponent(
37
+ path
38
+ )}&pageSize=${pageSize}&page=${page}&lang=${lang}&sortBy=${sortBy}`,
39
+ { signal, headers }
40
+ )
41
+ .then((resp) => resp.json() as Promise<CommentData>)
42
+ .then((data) => errorCheck(data, 'comment data'));
43
+ };
44
+
45
+ export interface PostCommentOptions {
46
+ serverURL: string;
47
+ lang: string;
48
+ token?: string;
49
+ comment: WalineCommentData;
50
+ }
51
+
52
+ export interface PostCommentResponse {
53
+ data?: WalineComment;
54
+ errmsg?: string;
55
+ }
56
+
57
+ export const postComment = ({
58
+ serverURL,
59
+ lang,
60
+ token,
61
+ comment,
62
+ }: PostCommentOptions): Promise<PostCommentResponse> => {
63
+ const headers: Record<string, string> = {
64
+ // eslint-disable-next-line @typescript-eslint/naming-convention
65
+ 'Content-Type': 'application/json',
66
+ };
67
+
68
+ if (token) headers.Authorization = `Bearer ${token}`;
69
+
70
+ if (comment.eid) {
71
+ return fetch(`${serverURL}/comment/${comment.eid}?lang=${lang}`, {
72
+ method: 'PUT',
73
+ headers,
74
+ body: JSON.stringify(comment),
75
+ }).then((resp) => resp.json() as Promise<PostCommentResponse>);
76
+ }
77
+
78
+ return fetch(`${serverURL}/comment?lang=${lang}`, {
79
+ method: 'POST',
80
+ headers,
81
+ body: JSON.stringify(comment),
82
+ }).then((resp) => resp.json() as Promise<PostCommentResponse>);
83
+ };
84
+
85
+ export interface DeleteCommentOptions {
86
+ serverURL: string;
87
+ lang: string;
88
+ token: string;
89
+ objectId: string | number;
90
+ }
91
+
92
+ export const deleteComment = ({
93
+ serverURL,
94
+ lang,
95
+ token,
96
+ objectId,
97
+ }: DeleteCommentOptions): Promise<void> =>
98
+ fetch(`${serverURL}/comment/${objectId}?lang=${lang}`, {
99
+ method: 'DELETE',
100
+ headers: {
101
+ Authorization: `Bearer ${token}`,
102
+ },
103
+ }).then((resp) => resp.json() as Promise<void>);
104
+
105
+ export interface LikeCommentOptions {
106
+ serverURL: string;
107
+ lang: string;
108
+ objectId: number | string;
109
+ like: boolean;
110
+ }
111
+
112
+ export const likeComment = ({
113
+ serverURL,
114
+ lang,
115
+ objectId,
116
+ like,
117
+ }: LikeCommentOptions): Promise<void> =>
118
+ fetch(`${serverURL}/comment/${objectId}?lang=${lang}`, {
119
+ method: 'PUT',
120
+ headers: JSON_HEADERS,
121
+ body: JSON.stringify({ like }),
122
+ }).then((resp) => resp.json() as Promise<void>);
123
+
124
+ export interface UpdateCommentOptions {
125
+ serverURL: string;
126
+ lang: string;
127
+ token: string;
128
+ objectId: number | string;
129
+ status?: 'approved' | 'waiting' | 'spam';
130
+ sticky?: number;
131
+ }
132
+
133
+ export const updateComment = ({
134
+ serverURL,
135
+ lang,
136
+ token,
137
+ objectId,
138
+ ...data
139
+ }: UpdateCommentOptions): Promise<void> =>
140
+ fetch(`${serverURL}/comment/${objectId}?lang=${lang}`, {
141
+ method: 'PUT',
142
+ headers: {
143
+ ...JSON_HEADERS,
144
+ Authorization: `Bearer ${token}`,
145
+ },
146
+ body: JSON.stringify(data),
147
+ }).then((resp) => resp.json() as Promise<void>);
@@ -0,0 +1,30 @@
1
+ import { errorCheck } from './utils';
2
+
3
+ export interface FetchCommentCountOptions {
4
+ serverURL: string;
5
+ lang: string;
6
+ paths: string[];
7
+ signal: AbortSignal;
8
+ }
9
+
10
+ export const fetchCommentCount = ({
11
+ serverURL,
12
+ lang,
13
+ paths,
14
+ signal,
15
+ }: FetchCommentCountOptions): Promise<number[]> => {
16
+ const headers: Record<string, string> = {};
17
+
18
+ return (
19
+ fetch(
20
+ `${serverURL}/comment?type=count&url=${encodeURIComponent(
21
+ paths.join(',')
22
+ )}&lang=${lang}`,
23
+ { signal, headers }
24
+ )
25
+ .then((resp) => resp.json() as Promise<number | number[]>)
26
+ .then((data) => errorCheck(data, 'comment count'))
27
+ // TODO: Improve this API
28
+ .then((counts) => (Array.isArray(counts) ? counts : [counts]))
29
+ );
30
+ };
@@ -0,0 +1,6 @@
1
+ export * from './articleCounter';
2
+ export * from './comment';
3
+ export * from './commentCount';
4
+ export * from './login';
5
+ export * from './pageview';
6
+ export * from './recentComment';
@@ -0,0 +1,53 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2
+
3
+ export interface LoginOptions {
4
+ lang: string;
5
+ serverURL: string;
6
+ }
7
+
8
+ export interface UserInfo {
9
+ // eslint-disable-next-line @typescript-eslint/naming-convention
10
+ display_name: string;
11
+ email: string;
12
+ url: string;
13
+ token: string;
14
+ avatar: string;
15
+ mailMd5: string;
16
+ objectId: string | number;
17
+ type: 'administrator' | 'guest';
18
+ }
19
+
20
+ export const login = ({
21
+ lang,
22
+ serverURL,
23
+ }: LoginOptions): Promise<UserInfo & { remember: boolean }> => {
24
+ const width = 450;
25
+ const height = 450;
26
+ const left = (window.innerWidth - width) / 2;
27
+ const top = (window.innerHeight - height) / 2;
28
+
29
+ const handler = window.open(
30
+ `${serverURL}/ui/login?lng=${encodeURIComponent(lang)}`,
31
+ '_blank',
32
+ `width=${width},height=${height},left=${left},top=${top},scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no`
33
+ );
34
+
35
+ handler?.postMessage({ type: 'TOKEN', data: null }, '*');
36
+
37
+ return new Promise((resolve) => {
38
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
+ const receiver = ({ data }: any): void => {
40
+ if (!data || typeof data !== 'object' || data.type !== 'userInfo') return;
41
+
42
+ if (data.data.token) {
43
+ handler?.close();
44
+
45
+ window.removeEventListener('message', receiver);
46
+
47
+ resolve(data.data as UserInfo & { remember: boolean });
48
+ }
49
+ };
50
+
51
+ window.addEventListener('message', receiver);
52
+ });
53
+ };
@@ -0,0 +1,41 @@
1
+ import { fetchArticleCounter, updateArticleCounter } from './articleCounter';
2
+
3
+ interface FetchPageviewOptions {
4
+ serverURL: string;
5
+ lang: string;
6
+ paths: string[];
7
+ signal: AbortSignal;
8
+ }
9
+
10
+ export const fetchPageviews = ({
11
+ serverURL,
12
+ lang,
13
+ paths,
14
+ signal,
15
+ }: FetchPageviewOptions): Promise<number[]> =>
16
+ fetchArticleCounter({
17
+ serverURL,
18
+ lang,
19
+ paths,
20
+ type: ['time'],
21
+ signal,
22
+ })
23
+ // TODO: Improve this API
24
+ .then((counts) => (Array.isArray(counts) ? counts : [counts])) as Promise<
25
+ number[]
26
+ >;
27
+
28
+ export interface UpdatePageviewOptions {
29
+ serverURL: string;
30
+ lang: string;
31
+ path: string;
32
+ action?: 'inc' | 'desc';
33
+ }
34
+
35
+ export const updatePageviews = (
36
+ options: UpdatePageviewOptions
37
+ ): Promise<number> =>
38
+ updateArticleCounter({
39
+ ...options,
40
+ type: 'time',
41
+ });
@@ -0,0 +1,29 @@
1
+ import { errorCheck } from './utils';
2
+ import type { WalineComment } from '../typings';
3
+
4
+ export interface FetchRecentCommentOptions {
5
+ serverURL: string;
6
+ lang: string;
7
+ count: number;
8
+ signal: AbortSignal;
9
+ token?: string;
10
+ }
11
+
12
+ export const fetchRecentComment = ({
13
+ serverURL,
14
+ lang,
15
+ count,
16
+ signal,
17
+ token,
18
+ }: FetchRecentCommentOptions): Promise<WalineComment[]> => {
19
+ const headers: Record<string, string> = {};
20
+
21
+ if (token) headers.Authorization = `Bearer ${token}`;
22
+
23
+ return fetch(`${serverURL}/comment?type=recent&count=${count}&lang=${lang}`, {
24
+ signal,
25
+ headers,
26
+ })
27
+ .then((resp) => resp.json() as Promise<WalineComment[]>)
28
+ .then((data) => errorCheck(data, 'recent comment'));
29
+ };
@@ -0,0 +1,23 @@
1
+ export interface FetchErrorData {
2
+ errno: number;
3
+ errmsg: string;
4
+ }
5
+
6
+ export const JSON_HEADERS: Record<string, string> = {
7
+ // eslint-disable-next-line @typescript-eslint/naming-convention
8
+ 'Content-Type': 'application/json',
9
+ };
10
+
11
+ export const errorCheck = <T = unknown>(
12
+ data: T | FetchErrorData,
13
+ name = ''
14
+ ): T => {
15
+ if (typeof data === 'object' && (data as FetchErrorData).errno)
16
+ throw new TypeError(
17
+ `Fetch ${name} failed with ${(data as FetchErrorData).errno}: ${
18
+ (data as FetchErrorData).errmsg
19
+ }`
20
+ );
21
+
22
+ return data as T;
23
+ };
package/src/comment.ts CHANGED
@@ -1,10 +1,5 @@
1
- import { useUserInfo } from './composables';
2
- import {
3
- decodePath,
4
- errorHandler,
5
- fetchCommentCount,
6
- getServerURL,
7
- } from './utils';
1
+ import { fetchCommentCount } from './api';
2
+ import { decodePath, errorHandler, getServerURL } from './utils';
8
3
  import type { WalineAbort } from './typings';
9
4
 
10
5
  export interface WalineCommentCountOptions {
@@ -55,8 +50,6 @@ WalineCommentCountOptions): WalineAbort => {
55
50
  // comment count
56
51
  const elements = document.querySelectorAll<HTMLElement>(selector);
57
52
 
58
- const userInfo = useUserInfo();
59
-
60
53
  if (elements.length)
61
54
  void fetchCommentCount({
62
55
  serverURL: getServerURL(serverURL),
@@ -65,7 +58,6 @@ WalineCommentCountOptions): WalineAbort => {
65
58
  ),
66
59
  lang,
67
60
  signal: controller.signal,
68
- token: userInfo.value?.token,
69
61
  })
70
62
  .then((counts) => {
71
63
  elements.forEach((element, index) => {
@@ -1,18 +1,18 @@
1
1
  <template>
2
2
  <div v-if="reaction && reaction.length" class="wl-reaction">
3
- <h4>{{ locale.reactionTitle }}</h4>
3
+ <h4 v-text="locale.reactionTitle" />
4
4
  <ul>
5
5
  <li
6
6
  v-for="(item, index) in reaction"
7
7
  :key="index"
8
- :class="item.active ? 'active' : ''"
9
- @click="onVote(index)"
8
+ :class="{ active: item.active }"
9
+ @click="vote(index)"
10
10
  >
11
- <div class="wl-reaction__img">
11
+ <div class="wl-reaction-img">
12
12
  <img :src="item.icon" :alt="item.desc" />
13
- <div class="wl-reaction__votes">{{ item.vote }}</div>
13
+ <div class="wl-reaction-votes">{{ item.vote }}</div>
14
14
  </div>
15
- <div class="wl-reaction__text">{{ item.desc }}</div>
15
+ <div class="wl-reaction-text">{{ item.desc }}</div>
16
16
  </li>
17
17
  </ul>
18
18
  </div>
@@ -28,12 +28,10 @@ import {
28
28
  onUnmounted,
29
29
  ref,
30
30
  } from 'vue';
31
- import {
32
- fetchArticleCounter,
33
- updateArticleCounter,
34
- WalineConfig,
35
- } from '../utils';
36
- import { useVoteStorage } from '../composables/vote';
31
+ import { fetchArticleCounter, updateArticleCounter } from '../api';
32
+ import { useVoteStorage } from '../composables';
33
+ import type { WalineConfig } from '../utils';
34
+ import type { WalineLocale } from '../typings';
37
35
 
38
36
  interface ReactionItem {
39
37
  icon: string;
@@ -46,21 +44,15 @@ export default defineComponent({
46
44
  setup() {
47
45
  const votes = ref<ReactionItem['vote'][]>([]);
48
46
  const voteStorage = useVoteStorage();
49
- const config = inject<ComputedRef<WalineConfig>>(
50
- 'config'
51
- ) as ComputedRef<WalineConfig>;
47
+ const config = inject<ComputedRef<WalineConfig>>('config')!;
52
48
  const locale = computed(() => config.value.locale);
53
49
  const reaction = computed((): ReactionItem[] => {
54
- const { path } = config.value;
55
-
56
- if (!Array.isArray(config.value.reaction)) {
57
- return [];
58
- }
50
+ const { reaction, path } = config.value;
59
51
 
60
- return config.value.reaction.map((icon, index) => ({
52
+ return (Array.isArray(reaction) ? reaction : []).map((icon, index) => ({
61
53
  icon,
62
54
  vote: votes.value[index] || 0,
63
- desc: locale.value[`reaction${index}` as `reaction0`],
55
+ desc: locale.value[`reaction${index}` as keyof WalineLocale],
64
56
  active: Boolean(
65
57
  voteStorage.value.find(({ u, i }) => u === path && i === index)
66
58
  ),
@@ -84,21 +76,17 @@ export default defineComponent({
84
76
  signal: controller.signal,
85
77
  });
86
78
 
87
- if (Array.isArray(resp) || typeof resp === 'number') {
88
- return;
89
- }
79
+ if (Array.isArray(resp) || typeof resp === 'number') return;
90
80
 
91
81
  votes.value = reaction.map((_, k) => resp[`reaction${k}`]);
92
82
  };
93
83
 
94
- const onVote = async (index: number): Promise<void> => {
84
+ const vote = async (index: number): Promise<void> => {
95
85
  const { serverURL, lang, path } = config.value;
96
86
  const hasVoted = voteStorage.value.find(({ u }) => u === path);
97
87
  const hasVotedTheReaction = hasVoted && hasVoted.i === index;
98
88
 
99
- if (hasVotedTheReaction) {
100
- return;
101
- }
89
+ if (hasVotedTheReaction) return;
102
90
 
103
91
  await updateArticleCounter({
104
92
  serverURL,
@@ -134,7 +122,7 @@ export default defineComponent({
134
122
  return {
135
123
  reaction,
136
124
  locale,
137
- onVote,
125
+ vote,
138
126
  };
139
127
  },
140
128
  });