@waline/client 2.0.7 → 2.1.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/client",
3
- "version": "2.0.7",
3
+ "version": "2.1.0",
4
4
  "description": "client for waline comment system",
5
5
  "keywords": [
6
6
  "valine",
@@ -40,9 +40,10 @@
40
40
  "scripts": {
41
41
  "build": "npm run rollup && npm run style",
42
42
  "clean": "rimraf ./dist",
43
+ "dev": "vite -c config/vite.config.js",
43
44
  "lint": "eslint --ext .ts,.vue .",
44
45
  "prepublish": "npm run clean && npm run build",
45
- "rollup": "rollup -c ./scripts/rollup.config.js",
46
+ "rollup": "rollup -c ./config/rollup.config.js",
46
47
  "style": "sass ./src/styles/index.scss ./dist/waline.css --style=compressed"
47
48
  },
48
49
  "browserslist": {
@@ -63,12 +64,14 @@
63
64
  "@vueuse/core": "^8.3.1",
64
65
  "autosize": "^5.0.1",
65
66
  "hanabi": "^0.4.0",
66
- "marked": "^4.0.14",
67
+ "marked": "^4.0.15",
67
68
  "vue": "^3.2.33"
68
69
  },
69
70
  "devDependencies": {
70
71
  "@types/autosize": "^4.0.1",
71
- "@types/marked": "^4.0.3"
72
+ "@types/marked": "^4.0.3",
73
+ "@vitejs/plugin-vue": "^2.3.1",
74
+ "vite": "^2.9.6"
72
75
  },
73
76
  "engines": {
74
77
  "node": ">=12.20.0"
@@ -78,7 +78,7 @@
78
78
  </a>
79
79
 
80
80
  <button
81
- v-show="config.emoji.length"
81
+ v-show="emoji.tabs.length"
82
82
  ref="emojiButtonRef"
83
83
  class="wl-action"
84
84
  :class="{ actived: showEmoji }"
@@ -396,16 +396,19 @@ export default defineComponent({
396
396
  if (login === 'force') return;
397
397
 
398
398
  // check nick
399
- if (
400
- (requiredMeta.indexOf('nick') > -1 || comment.nick) &&
401
- !comment.nick
402
- ) {
399
+ if (requiredMeta.indexOf('nick') > -1 && !comment.nick) {
403
400
  inputRefs.value.nick?.focus();
404
401
  return alert(locale.value.nickError);
405
402
  }
406
403
 
407
404
  // check mail
408
- if (requiredMeta.indexOf('mail') > -1 && !comment.mail) {
405
+ if (
406
+ (requiredMeta.indexOf('mail') > -1 && !comment.mail) ||
407
+ (comment.mail &&
408
+ !/^\w(?:[\w._-]*\w)?@(?:\w(?:[\w-]*\w)?\.){0,2}\w+$/.exec(
409
+ comment.mail
410
+ ))
411
+ ) {
409
412
  inputRefs.value.mail?.focus();
410
413
  return alert(locale.value.mailError);
411
414
  }
@@ -603,9 +606,11 @@ export default defineComponent({
603
606
  watch(
604
607
  () => config.value.emoji,
605
608
  (emojiConfig) =>
606
- getEmojis(emojiConfig).then((config) => {
607
- emoji.value = config;
608
- }),
609
+ getEmojis(Array.isArray(emojiConfig) ? emojiConfig : []).then(
610
+ (config) => {
611
+ emoji.value = config;
612
+ }
613
+ ),
609
614
  { immediate: true }
610
615
  );
611
616
  });
@@ -23,6 +23,11 @@
23
23
  v-text="locale.admin"
24
24
  />
25
25
  <span v-if="comment.sticky" class="wl-badge" v-text="locale.sticky" />
26
+ <span
27
+ v-if="comment.level >= 0"
28
+ class="wl-badge"
29
+ v-text="locale[`level${comment.level}`] || `Level ${comment.level}`"
30
+ />
26
31
 
27
32
  <span class="wl-time" v-text="time" />
28
33
 
@@ -61,16 +61,8 @@
61
61
  </template>
62
62
 
63
63
  <script lang="ts">
64
- import {
65
- computed,
66
- defineComponent,
67
- onBeforeUnmount,
68
- onMounted,
69
- provide,
70
- ref,
71
- watch,
72
- watchEffect,
73
- } from 'vue';
64
+ import { useStyleTag } from '@vueuse/core';
65
+ import { computed, defineComponent, onMounted, provide, ref, watch } from 'vue';
74
66
  import CommentBox from './CommentBox.vue';
75
67
  import CommentCard from './CommentCard.vue';
76
68
  import { LoadingIcon } from './Icons';
@@ -171,23 +163,24 @@ export default defineComponent({
171
163
  },
172
164
 
173
165
  emoji: {
174
- type: Array as PropType<(string | WalineEmojiInfo)[]>,
166
+ type: [Array, Boolean] as PropType<(string | WalineEmojiInfo)[] | false>,
175
167
  ...(SHOULD_VALIDATE
176
168
  ? {
177
169
  validator: (value: unknown): boolean =>
178
- Array.isArray(value) &&
179
- value.every(
180
- (item) =>
181
- typeof item === 'string' ||
182
- (typeof item === 'object' &&
183
- typeof item.name === 'string' &&
184
- typeof item.folder === 'string' &&
185
- typeof item.icon === 'string' &&
186
- Array.isArray(item.items) &&
187
- (item.items as unknown[]).every(
188
- (icon) => typeof icon === 'string'
189
- ))
190
- ),
170
+ value === false ||
171
+ (Array.isArray(value) &&
172
+ value.every(
173
+ (item) =>
174
+ typeof item === 'string' ||
175
+ (typeof item === 'object' &&
176
+ typeof item.name === 'string' &&
177
+ typeof item.folder === 'string' &&
178
+ typeof item.icon === 'string' &&
179
+ Array.isArray(item.items) &&
180
+ (item.items as unknown[]).every(
181
+ (icon) => typeof icon === 'string'
182
+ ))
183
+ )),
191
184
  }
192
185
  : {}),
193
186
  },
@@ -225,9 +218,10 @@ export default defineComponent({
225
218
 
226
219
  const darkmodeStyle = computed(() => getDarkStyle(config.value.dark));
227
220
 
221
+ useStyleTag(darkmodeStyle);
222
+
228
223
  // eslint-disable-next-line vue/no-setup-props-destructure
229
224
  let abort: () => void;
230
- let stop: () => void;
231
225
 
232
226
  const fetchComment = (pageNumber: number): void => {
233
227
  const { serverURL, path, pageSize } = config.value;
@@ -293,21 +287,7 @@ export default defineComponent({
293
287
 
294
288
  watch(() => props.path, refresh);
295
289
 
296
- onMounted(() => {
297
- refresh();
298
-
299
- const style = document.createElement('style');
300
-
301
- style.innerText = darkmodeStyle.value;
302
-
303
- document.querySelector('[data-waline]')?.appendChild(style);
304
-
305
- stop = watchEffect(() => {
306
- style.innerText = darkmodeStyle.value;
307
- });
308
- });
309
-
310
- onBeforeUnmount(() => stop());
290
+ onMounted(() => refresh());
311
291
 
312
292
  return {
313
293
  config,
@@ -1,6 +1,6 @@
1
1
  import { useNow } from '@vueuse/core';
2
2
  import { computed } from 'vue';
3
- import { dateFormat } from '../utils';
3
+ import { getTimeAgo } from '../utils';
4
4
 
5
5
  import type { ComputedRef } from 'vue';
6
6
  import type { WalineLocale } from '../typings';
@@ -11,51 +11,5 @@ export const useTimeAgo = (
11
11
  ): ComputedRef<string> => {
12
12
  const now = useNow();
13
13
 
14
- return computed(() => {
15
- if (!date) return '';
16
-
17
- const time =
18
- typeof date === 'string'
19
- ? new Date(date.indexOf(' ') !== -1 ? date.replace(/-/g, '/') : date)
20
- : date;
21
-
22
- const timepassed = now.value.getTime() - time.getTime();
23
-
24
- const days = Math.floor(timepassed / (24 * 3600 * 1000));
25
-
26
- if (days === 0) {
27
- // 计算相差小时数
28
-
29
- // 计算天数后剩余的毫秒数
30
- const leave1 = timepassed % (24 * 3600 * 1000);
31
- const hours = Math.floor(leave1 / (3600 * 1000));
32
-
33
- if (hours === 0) {
34
- //计算相差分钟数
35
-
36
- // 计算小时数后剩余的毫秒数
37
- const leave2 = leave1 % (3600 * 1000);
38
- const minutes = Math.floor(leave2 / (60 * 1000));
39
-
40
- // 计算相差秒数
41
- if (minutes === 0) {
42
- // 计算分钟数后剩余的毫秒数
43
- const leave3 = leave2 % (60 * 1000);
44
- const seconds = Math.round(leave3 / 1000);
45
-
46
- return `${seconds} ${locale.seconds}`;
47
- }
48
-
49
- return `${minutes} ${locale.minutes}`;
50
- }
51
-
52
- return `${hours} ${locale.hours}`;
53
- }
54
-
55
- if (days < 0) return locale.now;
56
-
57
- if (days < 8) return `${days} ${locale.days}`;
58
-
59
- return dateFormat(time);
60
- });
14
+ return computed(() => getTimeAgo(date, now.value, locale));
61
15
  };
@@ -31,4 +31,10 @@ export default generateLocale([
31
31
  'Words',
32
32
  'Please input comments between $0 and $1 words!\n Current word number: $2',
33
33
  'Anonymous',
34
+ 'Dwarves',
35
+ 'Hobbits',
36
+ 'Ents',
37
+ 'Wizards',
38
+ 'Elves',
39
+ 'Maiar',
34
40
  ]);
@@ -31,6 +31,12 @@ const localeKeys = [
31
31
  'word',
32
32
  'wordHint',
33
33
  'anonymous',
34
+ 'level0',
35
+ 'level1',
36
+ 'level2',
37
+ 'level3',
38
+ 'level4',
39
+ 'level5',
34
40
  ];
35
41
 
36
42
  export const generateLocale = (locale: string[]): WalineLocale =>
@@ -31,4 +31,10 @@ export default generateLocale([
31
31
  '字',
32
32
  '评论字数应在 $0 到 $1 字之间!\n当前字数:$2',
33
33
  '匿名',
34
+ '潜水',
35
+ '冒泡',
36
+ '吐槽',
37
+ '活跃',
38
+ '话痨',
39
+ '传说',
34
40
  ]);
@@ -31,4 +31,10 @@ export default generateLocale([
31
31
  '字',
32
32
  '評論字數應在 $0 到 $1 字之間!\n當前字數:$2',
33
33
  '匿名',
34
+ '潛水',
35
+ '冒泡',
36
+ '吐槽',
37
+ '活躍',
38
+ '話癆',
39
+ '傳說',
34
40
  ]);
@@ -10,7 +10,7 @@ import type { WalineInitOptions } from '../typings';
10
10
  export { WalineInstance } from '../init';
11
11
 
12
12
  warning(
13
- ' This is a legacy package compatable with Valine and Waline@v1, please switch to Waline@v2 using https://<CDN.LINK>/@waline/client/dist/waline.js instead!'
13
+ ' This is a legacy package compatible with Valine and Waline@v1, please switch to Waline@v2 using https://<CDN.LINK>/@waline/client/dist/waline.js instead!'
14
14
  );
15
15
 
16
16
  // inject css styles
@@ -22,4 +22,5 @@ export interface WalineComment extends Exclude<WalineCommentData, 'ua'> {
22
22
  sticky?: boolean;
23
23
  browser?: string;
24
24
  os?: string;
25
+ level?: number;
25
26
  }
@@ -1,4 +1,12 @@
1
- export interface WalineLocale {
1
+ export interface WalineDateLocale {
2
+ seconds: string;
3
+ minutes: string;
4
+ hours: string;
5
+ days: string;
6
+ now: string;
7
+ }
8
+
9
+ export interface WalineLocale extends WalineDateLocale {
2
10
  nick: string;
3
11
  nickError: string;
4
12
  mail: string;
@@ -16,11 +24,6 @@ export interface WalineLocale {
16
24
  preview: string;
17
25
  emoji: string;
18
26
  uploadImage: string;
19
- seconds: string;
20
- minutes: string;
21
- hours: string;
22
- days: string;
23
- now: string;
24
27
  uploading: string;
25
28
  login: string;
26
29
  logout: string;
@@ -146,7 +146,7 @@ export interface WalineProps {
146
146
  *
147
147
  * @default ['https://cdn.jsdelivr.net/gh/walinejs/emojis/weibo']
148
148
  */
149
- emoji?: (string | WalineEmojiInfo)[];
149
+ emoji?: (string | WalineEmojiInfo)[] | false;
150
150
 
151
151
  /**
152
152
  * 代码高亮
package/src/utils/date.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { WalineDateLocale } from '../typings';
2
+
1
3
  const padWithZeros = (vNumber: number, width: number): string => {
2
4
  let numAsString = vNumber.toString();
3
5
 
@@ -15,3 +17,55 @@ export const dateFormat = (date: Date): string => {
15
17
 
16
18
  return `${vYear}-${vMonth}-${vDay}`;
17
19
  };
20
+
21
+ export const getTimeAgo = (
22
+ date: Date | string,
23
+ now: Date,
24
+ locale: WalineDateLocale
25
+ ): string => {
26
+ if (!date) return '';
27
+
28
+ const time =
29
+ typeof date === 'string'
30
+ ? new Date(date.indexOf(' ') !== -1 ? date.replace(/-/g, '/') : date)
31
+ : date;
32
+
33
+ const timepassed = now.getTime() - time.getTime();
34
+
35
+ const days = Math.floor(timepassed / (24 * 3600 * 1000));
36
+
37
+ if (days === 0) {
38
+ // 计算相差小时数
39
+
40
+ // 计算天数后剩余的毫秒数
41
+ const leave1 = timepassed % (24 * 3600 * 1000);
42
+ const hours = Math.floor(leave1 / (3600 * 1000));
43
+
44
+ if (hours === 0) {
45
+ //计算相差分钟数
46
+
47
+ // 计算小时数后剩余的毫秒数
48
+ const leave2 = leave1 % (3600 * 1000);
49
+ const minutes = Math.floor(leave2 / (60 * 1000));
50
+
51
+ // 计算相差秒数
52
+ if (minutes === 0) {
53
+ // 计算分钟数后剩余的毫秒数
54
+ const leave3 = leave2 % (60 * 1000);
55
+ const seconds = Math.round(leave3 / 1000);
56
+
57
+ return `${seconds} ${locale.seconds}`;
58
+ }
59
+
60
+ return `${minutes} ${locale.minutes}`;
61
+ }
62
+
63
+ return `${hours} ${locale.hours}`;
64
+ }
65
+
66
+ if (days < 0) return locale.now;
67
+
68
+ if (days < 8) return `${days} ${locale.days}`;
69
+
70
+ return dateFormat(time);
71
+ };