@waline/client 2.6.0 → 2.6.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.
Files changed (54) hide show
  1. package/dist/component.esm.js +1 -1
  2. package/dist/component.esm.js.map +1 -1
  3. package/dist/component.js +1 -1
  4. package/dist/component.js.map +1 -1
  5. package/dist/legacy.d.ts +5 -0
  6. package/dist/legacy.js +1 -1
  7. package/dist/legacy.js.map +1 -1
  8. package/dist/pageview.cjs.js +1 -1
  9. package/dist/pageview.cjs.js.map +1 -1
  10. package/dist/pageview.esm.js +1 -1
  11. package/dist/pageview.esm.js.map +1 -1
  12. package/dist/pageview.js +1 -1
  13. package/dist/pageview.js.map +1 -1
  14. package/dist/shim.d.ts +5 -0
  15. package/dist/shim.esm.d.ts +5 -0
  16. package/dist/shim.esm.js +1 -1
  17. package/dist/shim.esm.js.map +1 -1
  18. package/dist/shim.js +1 -1
  19. package/dist/shim.js.map +1 -1
  20. package/dist/waline.cjs.d.ts +5 -0
  21. package/dist/waline.cjs.js +1 -1
  22. package/dist/waline.cjs.js.map +1 -1
  23. package/dist/waline.css +1 -1
  24. package/dist/waline.css.map +1 -1
  25. package/dist/waline.d.ts +5 -0
  26. package/dist/waline.esm.d.ts +5 -0
  27. package/dist/waline.esm.js +1 -1
  28. package/dist/waline.esm.js.map +1 -1
  29. package/dist/waline.js +1 -1
  30. package/dist/waline.js.map +1 -1
  31. package/package.json +21 -21
  32. package/src/components/CommentBox.vue +52 -37
  33. package/src/components/CommentCard.vue +21 -19
  34. package/src/components/ImageWall.vue +2 -4
  35. package/src/components/Waline.vue +7 -0
  36. package/src/composables/userInfo.ts +1 -1
  37. package/src/config/default.ts +6 -0
  38. package/src/config/i18n/en.ts +5 -0
  39. package/src/config/i18n/generate.ts +5 -0
  40. package/src/config/i18n/jp.ts +5 -0
  41. package/src/config/i18n/pt-BR.ts +5 -0
  42. package/src/config/i18n/ru.ts +5 -0
  43. package/src/config/i18n/vi-VN.ts +5 -0
  44. package/src/config/i18n/zh-CN.ts +5 -0
  45. package/src/config/i18n/zh-TW.ts +7 -2
  46. package/src/init.ts +0 -1
  47. package/src/pageview.ts +5 -1
  48. package/src/styles/card.scss +2 -0
  49. package/src/styles/emoji.scss +4 -1
  50. package/src/styles/gif.scss +6 -5
  51. package/src/typings/locale.ts +5 -0
  52. package/src/utils/fetch.ts +3 -0
  53. package/src/utils/markedMathExtension.ts +1 -0
  54. package/LICENSE +0 -339
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/client",
3
- "version": "2.6.0",
3
+ "version": "2.6.3",
4
4
  "description": "client for waline comment system",
5
5
  "keywords": [
6
6
  "valine",
@@ -56,6 +56,15 @@
56
56
  "dist",
57
57
  "src"
58
58
  ],
59
+ "scripts": {
60
+ "build": "pnpm rollup && pnpm style",
61
+ "clean": "rimraf ./dist",
62
+ "dev": "vite -c config/vite.config.js",
63
+ "lint": "eslint --ext .ts,.vue .",
64
+ "prepublish": "pnpm clean && pnpm build",
65
+ "rollup": "rollup -c ./config/rollup.config.js",
66
+ "style": "sass ./src/styles/index.scss ./dist/waline.css --style=compressed"
67
+ },
59
68
  "browserslist": {
60
69
  "production": [
61
70
  ">0.5%",
@@ -71,40 +80,31 @@
71
80
  ]
72
81
  },
73
82
  "dependencies": {
74
- "@vueuse/core": "^8.6.0",
83
+ "@vueuse/core": "^9.1.0",
75
84
  "autosize": "^5.0.1",
76
- "marked": "^4.0.16",
85
+ "marked": "^4.0.18",
77
86
  "vue": "^3.2.37"
78
87
  },
79
88
  "devDependencies": {
80
- "@babel/core": "7.18.2",
81
- "@babel/preset-env": "7.18.2",
89
+ "@babel/core": "7.18.10",
90
+ "@babel/preset-env": "7.18.10",
82
91
  "@rollup/plugin-babel": "5.3.1",
83
- "@rollup/plugin-commonjs": "22.0.0",
92
+ "@rollup/plugin-commonjs": "22.0.2",
84
93
  "@rollup/plugin-node-resolve": "13.3.0",
85
94
  "@rollup/plugin-replace": "4.0.0",
86
95
  "@types/autosize": "4.0.1",
87
96
  "@types/marked": "4.0.3",
88
- "@types/node": "17.0.41",
89
- "@vitejs/plugin-vue": "2.3.3",
97
+ "@types/node": "18.7.3",
98
+ "@vitejs/plugin-vue": "3.0.3",
90
99
  "rimraf": "3.0.2",
91
- "rollup": "2.75.6",
100
+ "rollup": "2.78.0",
92
101
  "rollup-plugin-dts": "4.2.2",
93
102
  "rollup-plugin-terser": "7.0.2",
94
103
  "rollup-plugin-ts": "3.0.2",
95
- "typescript": "4.7.3",
96
- "vite": "2.9.10"
104
+ "typescript": "4.7.4",
105
+ "vite": "3.0.7"
97
106
  },
98
107
  "engines": {
99
108
  "node": ">=14"
100
- },
101
- "scripts": {
102
- "build": "pnpm rollup && pnpm style",
103
- "clean": "rimraf ./dist",
104
- "dev": "vite -c config/vite.config.js",
105
- "lint": "eslint --ext .ts,.vue .",
106
- "prepublish": "pnpm clean && pnpm build",
107
- "rollup": "rollup -c ./config/rollup.config.js",
108
- "style": "sass ./src/styles/index.scss ./dist/waline.css --style=compressed"
109
109
  }
110
- }
110
+ }
@@ -6,12 +6,21 @@
6
6
  <CloseIcon :size="14" />
7
7
  </button>
8
8
 
9
- <img :src="userInfo.avatar" alt="avatar" />
9
+ <a
10
+ href="#"
11
+ class="wl-login-nick"
12
+ aria-label="Profile"
13
+ :title="locale.profile"
14
+ @click="onProfile"
15
+ >
16
+ <img :src="userInfo.avatar" alt="avatar" />
17
+ </a>
10
18
  </div>
11
19
  <a
12
20
  href="#"
13
21
  class="wl-login-nick"
14
22
  aria-label="Profile"
23
+ :title="locale.profile"
15
24
  @click="onProfile"
16
25
  v-text="userInfo.display_name"
17
26
  />
@@ -22,7 +31,7 @@
22
31
  v-if="config.login !== 'force' && config.meta.length && !isLogin"
23
32
  :class="['wl-header', `item${config.meta.length}`]"
24
33
  >
25
- <div v-for="kind in config.meta" class="wl-header-item" :key="kind">
34
+ <div v-for="kind in config.meta" :key="kind" class="wl-header-item">
26
35
  <label
27
36
  :for="kind"
28
37
  v-text="
@@ -33,34 +42,35 @@
33
42
  "
34
43
  />
35
44
  <input
45
+ :id="`wl-${kind}`"
36
46
  :ref="
37
47
  (element) => {
38
48
  if (element) inputRefs[kind] = element as HTMLInputElement;
39
49
  }
40
50
  "
41
- :id="`wl-${kind}`"
51
+ v-model="userMeta[kind]"
42
52
  :class="['wl-input', `wl-${kind}`]"
43
53
  :name="kind"
44
54
  :type="kind === 'mail' ? 'email' : 'text'"
45
- v-model="userMeta[kind]"
46
55
  />
47
56
  </div>
48
57
  </div>
49
58
 
50
59
  <textarea
51
- class="wl-editor"
52
- ref="editorRef"
53
60
  id="wl-edit"
54
- :placeholder="replyUser ? `@${replyUser}` : locale.placeholder"
61
+ ref="editorRef"
55
62
  v-model="editor"
63
+ class="wl-editor"
64
+ :placeholder="replyUser ? `@${replyUser}` : locale.placeholder"
56
65
  @keydown="onKeyDown"
57
66
  @drop="onDrop"
58
67
  @paste="onPaste"
59
68
  />
60
69
 
61
- <div class="wl-preview" v-show="showPreview">
70
+ <div v-show="showPreview" class="wl-preview">
62
71
  <hr />
63
72
  <h4>{{ locale.preview }}:</h4>
73
+ <!-- eslint-disable-next-line vue/no-v-html -->
64
74
  <div class="wl-content" v-html="previewText" />
65
75
  </div>
66
76
 
@@ -100,9 +110,9 @@
100
110
  </button>
101
111
 
102
112
  <input
113
+ id="wl-image-upload"
103
114
  ref="imageUploadRef"
104
115
  class="upload"
105
- id="wl-image-upload"
106
116
  type="file"
107
117
  accept=".png,.jpg,.jpeg,.webp,.bmp,.gif"
108
118
  @change="onChange"
@@ -169,9 +179,9 @@
169
179
  :class="{ display: showGif }"
170
180
  >
171
181
  <input
182
+ ref="gifSearchInputRef"
172
183
  type="text"
173
184
  :placeholder="locale.gifSearchPlaceholder"
174
- ref="gifSearchInputRef"
175
185
  @input="onGifSearch"
176
186
  />
177
187
 
@@ -193,10 +203,13 @@
193
203
  class="wl-emoji-popup"
194
204
  :class="{ display: showEmoji }"
195
205
  >
196
- <template v-for="(config, index) in emoji.tabs" :key="config.name">
206
+ <template
207
+ v-for="(emojiItem, index) in emoji.tabs"
208
+ :key="emojiItem.name"
209
+ >
197
210
  <div v-if="index === emojiTabIndex" class="wl-tab-wrapper">
198
211
  <button
199
- v-for="key in config.items"
212
+ v-for="key in emojiItem.items"
200
213
  :key="key"
201
214
  :title="key"
202
215
  @click="insert(`:${key}:`)"
@@ -214,17 +227,17 @@
214
227
  </template>
215
228
  <div v-if="emoji.tabs.length > 1" class="wl-tabs">
216
229
  <button
217
- v-for="(config, index) in emoji.tabs"
218
- :key="config.name"
230
+ v-for="(emojiItem, index) in emoji.tabs"
231
+ :key="emojiItem.name"
219
232
  class="wl-tab"
220
233
  :class="{ active: emojiTabIndex === index }"
221
234
  @click="emojiTabIndex = index"
222
235
  >
223
236
  <img
224
237
  class="wl-emoji"
225
- :src="config.icon"
226
- :alt="config.name"
227
- :title="config.name"
238
+ :src="emojiItem.icon"
239
+ :alt="emojiItem.name"
240
+ :title="emojiItem.name"
228
241
  loading="lazy"
229
242
  referrerPolicy="no-referrer"
230
243
  />
@@ -398,6 +411,10 @@ export default defineComponent({
398
411
  uploadText,
399
412
  `\r\n![${file.name}](${url})`
400
413
  );
414
+ })
415
+ .catch((e) => {
416
+ alert(e.message);
417
+ editor.value = editor.value.replace(uploadText, '');
401
418
  });
402
419
  };
403
420
 
@@ -454,6 +471,7 @@ export default defineComponent({
454
471
  // check nick
455
472
  if (requiredMeta.indexOf('nick') > -1 && !comment.nick) {
456
473
  inputRefs.value.nick?.focus();
474
+
457
475
  return alert(locale.value.nickError);
458
476
  }
459
477
 
@@ -464,12 +482,14 @@ export default defineComponent({
464
482
  !/^\w(?:[\w._-]*\w)?@(?:\w(?:[\w-]*\w)?\.)*\w+$/.exec(comment.mail))
465
483
  ) {
466
484
  inputRefs.value.mail?.focus();
485
+
467
486
  return alert(locale.value.mailError);
468
487
  }
469
488
 
470
489
  // check comment
471
490
  if (!comment.comment) {
472
491
  editorRef.value?.focus();
492
+
473
493
  return;
474
494
  }
475
495
 
@@ -505,7 +525,6 @@ export default defineComponent({
505
525
 
506
526
  if (resp.errmsg) return alert(resp.errmsg);
507
527
 
508
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
509
528
  emit('submit', resp.data!);
510
529
 
511
530
  editor.value = '';
@@ -578,24 +597,7 @@ export default defineComponent({
578
597
  `width=${width},height=${height},left=${left},top=${top},scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no`
579
598
  );
580
599
 
581
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
582
600
  handler?.postMessage({ type: 'TOKEN', data: userInfo.value!.token }, '*');
583
-
584
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
585
- const receiver = ({ data }: any): void => {
586
- if (!data || data.type !== 'profile') return;
587
-
588
- userInfo.value = { ...userInfo.value, ...data };
589
-
590
- [localStorage, sessionStorage]
591
- .filter((store) => store.getItem('WALINE_USER'))
592
- .forEach((store) =>
593
- store.setItem('WALINE_USER', JSON.stringify(userInfo))
594
- );
595
- window.removeEventListener('message', receiver);
596
- };
597
-
598
- window.addEventListener('message', receiver);
599
601
  };
600
602
 
601
603
  const popupHandler = (event: MouseEvent): void => {
@@ -683,8 +685,22 @@ export default defineComponent({
683
685
  searchResults.loading = false;
684
686
  });
685
687
 
688
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
689
+ const onMessageRecive = ({ data }: any): void => {
690
+ if (!data || data.type !== 'profile') return;
691
+
692
+ userInfo.value = { ...userInfo.value, ...data.data };
693
+
694
+ [localStorage, sessionStorage]
695
+ .filter((store) => store.getItem('WALINE_USER'))
696
+ .forEach((store) =>
697
+ store.setItem('WALINE_USER', JSON.stringify(userInfo))
698
+ );
699
+ };
700
+
686
701
  onMounted(() => {
687
702
  document.body.addEventListener('click', popupHandler);
703
+ window.addEventListener('message', onMessageRecive);
688
704
 
689
705
  // watch editor
690
706
  watch(
@@ -700,9 +716,7 @@ export default defineComponent({
700
716
  });
701
717
  wordNumber.value = getWordNumber(value);
702
718
 
703
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
704
719
  if (value) autosize(editorRef.value!);
705
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
706
720
  else autosize.destroy(editorRef.value!);
707
721
  },
708
722
  { immediate: true }
@@ -723,6 +737,7 @@ export default defineComponent({
723
737
 
724
738
  onUnmounted(() => {
725
739
  document.body.removeEventListener('click', popupHandler);
740
+ window.removeEventListener('message', onMessageRecive);
726
741
  });
727
742
 
728
743
  return {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="wl-item" :id="comment.objectId">
2
+ <div :id="comment.objectId" class="wl-item">
3
3
  <div class="wl-user" aria-hidden="true">
4
4
  <img v-if="comment.avatar" :src="comment.avatar" />
5
5
  <VerifiedIcon v-if="comment.type" />
@@ -33,8 +33,8 @@
33
33
 
34
34
  <div class="wl-comment-actions">
35
35
  <button
36
- class="wl-delete"
37
36
  v-if="isAdmin || isOwner"
37
+ class="wl-delete"
38
38
  @click="$emit('delete', comment)"
39
39
  >
40
40
  <DeleteIcon />
@@ -42,8 +42,8 @@
42
42
 
43
43
  <button
44
44
  class="wl-like"
45
- @click="$emit('like', comment)"
46
45
  :title="like ? locale.cancelLike : locale.like"
46
+ @click="$emit('like', comment)"
47
47
  >
48
48
  <LikeIcon :active="like" />
49
49
  <span v-if="'like' in comment" v-text="comment.like" />
@@ -64,6 +64,7 @@
64
64
  <span v-if="comment.browser" v-text="comment.browser" />
65
65
  <span v-if="comment.os" v-text="comment.os" />
66
66
  </div>
67
+ <!-- eslint-disable-next-line vue/no-v-html -->
67
68
  <div class="wl-content" v-html="comment.comment" />
68
69
 
69
70
  <div v-if="isAdmin" class="wl-admin-actions">
@@ -74,24 +75,24 @@
74
75
  :class="`wl-btn wl-${status}`"
75
76
  :disabled="comment.status === status"
76
77
  @click="$emit('status', { status, comment })"
77
- v-text="status"
78
+ v-text="locale[status]"
78
79
  />
79
80
  </span>
80
81
 
81
82
  <button
82
- class="wl-btn wl-sticky"
83
83
  v-if="isAdmin && !comment.rid"
84
+ class="wl-btn wl-sticky"
84
85
  @click="$emit('sticky', comment)"
85
86
  >
86
- {{ comment.sticky ? 'unsticky' : 'sticky' }}
87
+ {{ comment.sticky ? locale.unsticky : locale.sticky }}
87
88
  </button>
88
89
  </div>
89
90
 
90
91
  <div v-if="isReplyingCurrent" class="wl-reply-wrapper">
91
92
  <CommentBox
92
- :replyId="comment.objectId"
93
- :replyUser="comment.nick"
94
- :rootId="rootId"
93
+ :reply-id="comment.objectId"
94
+ :reply-user="comment.nick"
95
+ :root-id="rootId"
95
96
  @submit="$emit('submit', $event)"
96
97
  @cancel-reply="$emit('reply', null)"
97
98
  />
@@ -102,7 +103,7 @@
102
103
  :key="child.objectId"
103
104
  :comment="child"
104
105
  :reply="reply"
105
- :rootId="rootId"
106
+ :root-id="rootId"
106
107
  @reply="$emit('reply', $event)"
107
108
  @submit="$emit('submit', $event)"
108
109
  @like="$emit('like', $event)"
@@ -129,6 +130,14 @@ import type { WalineComment, WalineCommentStatus } from '../typings';
129
130
  const commentStatus: WalineCommentStatus[] = ['approved', 'waiting', 'spam'];
130
131
 
131
132
  export default defineComponent({
133
+ components: {
134
+ CommentBox,
135
+ DeleteIcon,
136
+ LikeIcon,
137
+ ReplyIcon,
138
+ VerifiedIcon,
139
+ },
140
+
132
141
  props: {
133
142
  comment: {
134
143
  type: Object as PropType<WalineComment>,
@@ -140,17 +149,10 @@ export default defineComponent({
140
149
  },
141
150
  reply: {
142
151
  type: Object as PropType<WalineComment | null>,
152
+ default: null,
143
153
  },
144
154
  },
145
155
 
146
- components: {
147
- CommentBox,
148
- DeleteIcon,
149
- LikeIcon,
150
- ReplyIcon,
151
- VerifiedIcon,
152
- },
153
-
154
156
  emits: ['submit', 'reply', 'like', 'delete', 'status', 'sticky'],
155
157
 
156
158
  setup(props) {
@@ -163,7 +165,7 @@ export default defineComponent({
163
165
  const locale = computed(() => config.value.locale);
164
166
 
165
167
  const link = computed(() => {
166
- let { link } = props.comment;
168
+ const { link } = props.comment;
167
169
 
168
170
  return link ? (isLinkHttp(link) ? link : `https://${link}`) : '';
169
171
  });
@@ -80,7 +80,7 @@ export default defineComponent({
80
80
  gap: { type: Number, default: 0 },
81
81
  },
82
82
 
83
- emit: ['insert'],
83
+ emits: ['insert'],
84
84
 
85
85
  setup(props) {
86
86
  let resizeObserver: ResizeObserver | null = null;
@@ -90,7 +90,6 @@ export default defineComponent({
90
90
 
91
91
  const getColumnCount = (): number => {
92
92
  const count = Math.floor(
93
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
94
93
  (wall.value!.getBoundingClientRect().width + props.gap) /
95
94
  (props.columnWidth + props.gap)
96
95
  );
@@ -149,11 +148,10 @@ export default defineComponent({
149
148
  onMounted(() => {
150
149
  redraw(true);
151
150
  resizeObserver = new ResizeObserver(() => redraw());
152
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
151
+
153
152
  resizeObserver.observe(wall.value!);
154
153
  });
155
154
 
156
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
157
155
  onBeforeUnmount(() => resizeObserver!.unobserve(wall.value!));
158
156
 
159
157
  return {
@@ -89,6 +89,7 @@ import type {
89
89
  WalineHighlighter,
90
90
  WalineTexRenderer,
91
91
  WalineImageUploader,
92
+ WalineSearchOptions,
92
93
  WalineLocale,
93
94
  WalineProps,
94
95
  WalineMeta,
@@ -112,6 +113,7 @@ const props = [
112
113
  'highlighter',
113
114
  'texRenderer',
114
115
  'imageUploader',
116
+ 'search',
115
117
  'copyright',
116
118
  ];
117
119
 
@@ -197,6 +199,11 @@ const propsWithValidate = {
197
199
  default: undefined,
198
200
  },
199
201
 
202
+ search: {
203
+ type: [Object, Boolean] as PropType<WalineSearchOptions | false>,
204
+ default: undefined,
205
+ },
206
+
200
207
  copyright: { type: Boolean, default: true },
201
208
  };
202
209
 
@@ -23,6 +23,6 @@ let userInfoStorage: UserInfoRef | null = null;
23
23
  export const useUserInfo = (): UserInfoRef =>
24
24
  userInfoStorage ||
25
25
  (userInfoStorage = useStorage<UserInfo | Record<string, never>>(
26
- 'USER_KEY',
26
+ USER_KEY,
27
27
  {}
28
28
  ));
@@ -9,7 +9,12 @@ export const defaultLang = 'zh-CN';
9
9
 
10
10
  export const defaultUploadImage = (file: File): Promise<string> =>
11
11
  new Promise((resolve, reject) => {
12
+ if (file.size > 128 * 1000) {
13
+ return reject(new Error('File too large! File size limit 128KB'));
14
+ }
15
+
12
16
  const reader = new FileReader();
17
+
13
18
  reader.readAsDataURL(file);
14
19
  reader.onload = (): void => resolve(reader.result?.toString() || '');
15
20
  reader.onerror = reject;
@@ -73,6 +78,7 @@ export const getDefaultSearchOptions = (): WalineSearchOptions => {
73
78
  }: FetchGifRequest): Promise<FetchGifResponse> => {
74
79
  const baseUrl = `https://g.tenor.com/v1/search`;
75
80
  const query = new URLSearchParams('media_filter=minimal');
81
+
76
82
  query.set('key', 'PAY5JLFIH6V6');
77
83
  query.set('limit', '20');
78
84
  query.set('pos', pos || '');
@@ -41,4 +41,9 @@ export default generateLocale([
41
41
  'Maiar',
42
42
  'GIF',
43
43
  'Search GIF',
44
+ 'Profile',
45
+ 'Approved',
46
+ 'Waiting',
47
+ 'Spam',
48
+ 'Unsticky',
44
49
  ]);
@@ -41,6 +41,11 @@ const localeKeys = [
41
41
  'level5',
42
42
  'gif',
43
43
  'gifSearchPlaceholder',
44
+ 'profile',
45
+ 'approved',
46
+ 'waiting',
47
+ 'spam',
48
+ 'unsticky',
44
49
  ];
45
50
 
46
51
  export const generateLocale = (locale: string[]): WalineLocale =>
@@ -41,4 +41,9 @@ export default generateLocale([
41
41
  'なぬし',
42
42
  'GIF',
43
43
  '探す GIF',
44
+ '個人情報',
45
+ '承認済み',
46
+ '待っている',
47
+ 'スパム',
48
+ 'べたつかない',
44
49
  ]);
@@ -41,4 +41,9 @@ export default generateLocale([
41
41
  'Maiar',
42
42
  'GIF',
43
43
  'Pesquisar GIF',
44
+ 'informação pessoal',
45
+ 'Aprovado',
46
+ 'Espera',
47
+ 'Spam',
48
+ 'Unsticky',
44
49
  ]);
@@ -41,4 +41,9 @@ export default generateLocale([
41
41
  'Maiar',
42
42
  'GIF',
43
43
  'Поиск GIF',
44
+ 'Персональные данные',
45
+ 'Одобренный',
46
+ 'Ожидающий',
47
+ 'Спам',
48
+ 'Нелипкий',
44
49
  ]);
@@ -41,4 +41,9 @@ export default generateLocale([
41
41
  'Maiar',
42
42
  'GIF',
43
43
  'Tìm kiếm GIF',
44
+ 'thông tin cá nhân',
45
+ 'Đã được phê duyệt',
46
+ 'Đang chờ đợi',
47
+ 'Thư rác',
48
+ 'Không dính',
44
49
  ]);
@@ -41,4 +41,9 @@ export default generateLocale([
41
41
  '传说',
42
42
  '表情包',
43
43
  '搜索表情包',
44
+ '个人资料',
45
+ '通过',
46
+ '待审核',
47
+ '垃圾',
48
+ '取消置顶',
44
49
  ]);
@@ -2,11 +2,11 @@ import { generateLocale } from './generate';
2
2
 
3
3
  export default generateLocale([
4
4
  '暱稱',
5
+ '暱稱不能少於3個字元',
5
6
  '郵箱',
7
+ '請填寫正確的郵件地址',
6
8
  '網址',
7
9
  '可選',
8
- '暱稱不能少於3個字元',
9
- '請填寫正確的郵件地址',
10
10
  '歡迎評論',
11
11
  '來發評論吧~',
12
12
  '提交',
@@ -41,4 +41,9 @@ export default generateLocale([
41
41
  '傳說',
42
42
  '表情包',
43
43
  '搜索表情包',
44
+ '個人資料',
45
+ '通過',
46
+ '待審核',
47
+ '垃圾',
48
+ '取消置頂',
44
49
  ]);
package/src/init.ts CHANGED
@@ -80,7 +80,6 @@ export const init = ({
80
80
  ? createApp(() => h(Waline, { path: state.path, ...props }))
81
81
  : null;
82
82
 
83
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
84
83
  if (app) app.mount(root!);
85
84
 
86
85
  const stopComment = watchEffect(updateCommentCount);
package/src/pageview.ts CHANGED
@@ -97,7 +97,11 @@ export const pageviewCount = ({
97
97
  const normalElements = elements.filter((element) => !filter(element));
98
98
  const elementsNeedstoBeFetched = elements.filter(filter);
99
99
 
100
- void updatePageviews({ serverURL, path, lang }).then((count) =>
100
+ void updatePageviews({
101
+ serverURL: getServerURL(serverURL),
102
+ path,
103
+ lang,
104
+ }).then((count) =>
101
105
  renderVisitorCount(
102
106
  new Array<number>(normalElements.length).fill(count),
103
107
  normalElements
@@ -233,10 +233,12 @@
233
233
  border-radius: 0;
234
234
 
235
235
  &:first-child {
236
+ border-right: 0;
236
237
  border-radius: 0.5em 0 0 0.5em;
237
238
  }
238
239
 
239
240
  &:last-child {
241
+ border-left: 0;
240
242
  border-radius: 0 0.5em 0.5em 0;
241
243
  }
242
244
  }
@@ -79,9 +79,12 @@
79
79
 
80
80
  .wl-tabs {
81
81
  position: relative;
82
+
83
+ overflow-x: scroll;
84
+
82
85
  height: 2em;
83
86
  padding: 0 6px 1px;
84
- overflow-x: scroll;
87
+
85
88
  white-space: nowrap;
86
89
 
87
90
  &::before {