@waline/client 2.11.1 → 2.11.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 (84) 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.d.ts +57 -30
  21. package/dist/legacy.umd.js +1 -1
  22. package/dist/legacy.umd.js.map +1 -1
  23. package/dist/pageview.cjs +1 -1
  24. package/dist/pageview.cjs.map +1 -1
  25. package/dist/pageview.js +1 -1
  26. package/dist/pageview.js.map +1 -1
  27. package/dist/pageview.mjs +1 -1
  28. package/dist/pageview.mjs.map +1 -1
  29. package/dist/shim.cjs +1 -1
  30. package/dist/shim.cjs.map +1 -1
  31. package/dist/shim.d.cts +58 -31
  32. package/dist/shim.d.mts +58 -31
  33. package/dist/shim.mjs +1 -1
  34. package/dist/shim.mjs.map +1 -1
  35. package/dist/waline-meta.css +1 -1
  36. package/dist/waline-meta.css.map +1 -1
  37. package/dist/waline.cjs +1 -1
  38. package/dist/waline.cjs.map +1 -1
  39. package/dist/waline.css +1 -1
  40. package/dist/waline.css.map +1 -1
  41. package/dist/waline.d.cts +58 -31
  42. package/dist/waline.d.mts +58 -31
  43. package/dist/waline.d.ts +58 -31
  44. package/dist/waline.js +1 -1
  45. package/dist/waline.js.map +1 -1
  46. package/dist/waline.mjs +1 -1
  47. package/dist/waline.mjs.map +1 -1
  48. package/package.json +34 -13
  49. package/src/api/articleCounter.ts +53 -0
  50. package/src/api/comment.ts +147 -0
  51. package/src/api/commentCount.ts +30 -0
  52. package/src/api/index.ts +6 -0
  53. package/src/api/login.ts +53 -0
  54. package/src/api/pageview.ts +41 -0
  55. package/src/api/recentComment.ts +29 -0
  56. package/src/api/utils.ts +23 -0
  57. package/src/comment.ts +2 -10
  58. package/src/compact/convert.ts +2 -2
  59. package/src/components/ArticleReaction.vue +50 -50
  60. package/src/components/CommentBox.vue +24 -49
  61. package/src/components/ImageWall.vue +1 -1
  62. package/src/components/Waline.vue +9 -9
  63. package/src/composables/index.ts +3 -1
  64. package/src/composables/recaptchaV3.ts +23 -0
  65. package/src/composables/userInfo.ts +1 -12
  66. package/src/composables/vote.ts +5 -2
  67. package/src/entrys/api.ts +1 -0
  68. package/src/entrys/comment.ts +2 -0
  69. package/src/init.ts +0 -11
  70. package/src/pageview.ts +2 -7
  71. package/src/styles/card.scss +1 -1
  72. package/src/styles/helpers/_svg.scss +12 -12
  73. package/src/styles/index.scss +1 -1
  74. package/src/styles/meta.scss +10 -14
  75. package/src/styles/reaction.scss +24 -18
  76. package/src/typings/base.ts +33 -7
  77. package/src/typings/locale.ts +37 -23
  78. package/src/utils/config.ts +9 -3
  79. package/src/utils/index.ts +0 -1
  80. package/src/widgets/recentComments.ts +2 -1
  81. package/src/components/RecaptchaV3/IReCaptchaOptions.ts +0 -6
  82. package/src/components/RecaptchaV3/README.md +0 -3
  83. package/src/components/RecaptchaV3/RecaptchaVuePlugin.ts +0 -86
  84. package/src/utils/fetch.ts +0 -310
@@ -263,7 +263,7 @@
263
263
 
264
264
  <script lang="ts">
265
265
  import { useDebounceFn } from '@vueuse/core';
266
- import { useReCaptcha } from './RecaptchaV3/RecaptchaVuePlugin';
266
+ import { useReCaptcha } from '../composables';
267
267
  import autosize from 'autosize';
268
268
  import {
269
269
  computed,
@@ -287,6 +287,7 @@ import {
287
287
  GifIcon,
288
288
  } from './Icons';
289
289
  import ImageWall from './ImageWall.vue';
290
+ import { login, postComment } from '../api';
290
291
  import { useEditor, useUserMeta, useUserInfo } from '../composables';
291
292
  import {
292
293
  getEmojis,
@@ -294,7 +295,6 @@ import {
294
295
  getWordNumber,
295
296
  parseEmoji,
296
297
  parseMarkdown,
297
- postComment,
298
298
  } from '../utils';
299
299
 
300
300
  import type { ComputedRef, DeepReadonly } from 'vue';
@@ -343,14 +343,11 @@ export default defineComponent({
343
343
  emits: ['submit', 'cancel-reply', 'cancel-edit'],
344
344
 
345
345
  setup(props, { emit }) {
346
- const config = inject<ComputedRef<WalineConfig>>(
347
- 'config'
348
- ) as ComputedRef<WalineConfig>;
346
+ const config = inject<ComputedRef<WalineConfig>>('config')!;
349
347
 
350
348
  const editor = useEditor();
351
349
  const userMeta = useUserMeta();
352
350
  const userInfo = useUserInfo();
353
- const recaptchaHandler = useReCaptcha();
354
351
 
355
352
  const inputRefs = ref<Record<string, HTMLInputElement>>({});
356
353
  const editorRef = ref<HTMLTextAreaElement | null>(null);
@@ -371,7 +368,7 @@ export default defineComponent({
371
368
 
372
369
  const searchResults = reactive({
373
370
  loading: true,
374
- list: [] as WalineSearchResult[],
371
+ list: [] as WalineSearchResult,
375
372
  });
376
373
 
377
374
  const wordLimit = ref(0);
@@ -388,7 +385,7 @@ export default defineComponent({
388
385
  const canUploadImage = computed(() => config.value.imageUploader !== false);
389
386
 
390
387
  const insert = (content: string): void => {
391
- const textArea = editorRef.value as HTMLTextAreaElement;
388
+ const textArea = editorRef.value!;
392
389
  const startPosition = textArea.selectionStart;
393
390
  const endPosition = textArea.selectionEnd || 0;
394
391
  const scrollTop = textArea.scrollTop;
@@ -449,7 +446,7 @@ export default defineComponent({
449
446
  };
450
447
 
451
448
  const onChange = (): void => {
452
- const inputElement = imageUploadRef.value as HTMLInputElement;
449
+ const inputElement = imageUploadRef.value!;
453
450
 
454
451
  if (inputElement.files && canUploadImage.value)
455
452
  uploadImage(inputElement.files[0]).then(() => {
@@ -463,12 +460,10 @@ export default defineComponent({
463
460
 
464
461
  let token = '';
465
462
 
466
- if (recaptchaHandler) {
467
- const { executeRecaptcha, recaptchaLoaded } = recaptchaHandler;
468
-
469
- await recaptchaLoaded();
470
- token = await executeRecaptcha('social');
471
- }
463
+ if (config.value.recaptchaV3Key)
464
+ token = await useReCaptcha(config.value.recaptchaV3Key).execute(
465
+ 'social'
466
+ );
472
467
 
473
468
  const comment: WalineCommentData = {
474
469
  comment: content.value,
@@ -568,36 +563,16 @@ export default defineComponent({
568
563
  event.preventDefault();
569
564
  const { lang, serverURL } = config.value;
570
565
 
571
- const width = 450;
572
- const height = 450;
573
- const left = (window.innerWidth - width) / 2;
574
- const top = (window.innerHeight - height) / 2;
575
-
576
- const handler = window.open(
577
- `${serverURL}/ui/login?lng=${encodeURIComponent(lang)}`,
578
- '_blank',
579
- `width=${width},height=${height},left=${left},top=${top},scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no`
580
- );
581
-
582
- handler?.postMessage({ type: 'TOKEN', data: null }, '*');
583
-
584
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
585
- const receiver = ({ data }: any): void => {
586
- if (!data || data.type !== 'userInfo') return;
587
-
588
- if (data.data.token) {
589
- handler?.close();
590
- userInfo.value = data.data;
591
- (data.data.remember ? localStorage : sessionStorage).setItem(
592
- 'WALINE_USER',
593
- JSON.stringify(data.data)
594
- );
595
-
596
- window.removeEventListener('message', receiver);
597
- }
598
- };
599
-
600
- window.addEventListener('message', receiver);
566
+ login({
567
+ serverURL,
568
+ lang,
569
+ }).then((data) => {
570
+ userInfo.value = data;
571
+ (data.remember ? localStorage : sessionStorage).setItem(
572
+ 'WALINE_USER',
573
+ JSON.stringify(data)
574
+ );
575
+ });
601
576
  };
602
577
 
603
578
  const onLogout = (): void => {
@@ -626,14 +601,14 @@ export default defineComponent({
626
601
 
627
602
  const popupHandler = (event: MouseEvent): void => {
628
603
  if (
629
- !(emojiButtonRef.value as HTMLElement).contains(event.target as Node) &&
630
- !(emojiPopupRef.value as HTMLElement).contains(event.target as Node)
604
+ !emojiButtonRef.value!.contains(event.target as Node) &&
605
+ !emojiPopupRef.value!.contains(event.target as Node)
631
606
  )
632
607
  showEmoji.value = false;
633
608
 
634
609
  if (
635
- !(gifButtonRef.value as HTMLElement).contains(event.target as Node) &&
636
- !(gifPopupRef.value as HTMLElement).contains(event.target as Node)
610
+ !gifButtonRef.value!.contains(event.target as Node) &&
611
+ !gifPopupRef.value!.contains(event.target as Node)
637
612
  )
638
613
  showGif.value = false;
639
614
  };
@@ -75,7 +75,7 @@ export default defineComponent({
75
75
  },
76
76
 
77
77
  props: {
78
- items: { type: Array as PropType<WalineSearchResult[]>, default: () => [] },
78
+ items: { type: Array as PropType<WalineSearchResult>, default: () => [] },
79
79
  columnWidth: { type: Number, default: 300 },
80
80
  gap: { type: Number, default: 0 },
81
81
  },
@@ -90,12 +90,11 @@ import { useUserInfo, useLikeStorage } from '../composables';
90
90
  import { defaultLocales } from '../config';
91
91
  import {
92
92
  deleteComment,
93
- fetchCommentList,
93
+ fetchComment,
94
94
  likeComment,
95
- getConfig,
96
- getDarkStyle,
97
95
  updateComment,
98
- } from '../utils';
96
+ } from '../api';
97
+ import { getConfig, getDarkStyle } from '../utils';
99
98
 
100
99
  import type { PropType } from 'vue';
101
100
  import type {
@@ -242,8 +241,9 @@ const propsWithValidate = {
242
241
 
243
242
  copyright: { type: Boolean, default: true },
244
243
 
245
- recaptchav3key: {
244
+ recaptchaV3Key: {
246
245
  type: String,
246
+ default: '',
247
247
  },
248
248
 
249
249
  reaction: {
@@ -287,7 +287,7 @@ export default defineComponent({
287
287
  // eslint-disable-next-line vue/no-setup-props-destructure
288
288
  let abort: () => void;
289
289
 
290
- const fetchComment = (pageNumber: number): void => {
290
+ const fetchCommentData = (pageNumber: number): void => {
291
291
  const { serverURL, path, pageSize } = config.value;
292
292
  const controller = new AbortController();
293
293
 
@@ -295,7 +295,7 @@ export default defineComponent({
295
295
 
296
296
  abort?.();
297
297
 
298
- fetchCommentList({
298
+ fetchComment({
299
299
  serverURL,
300
300
  lang: config.value.lang,
301
301
  path,
@@ -322,12 +322,12 @@ export default defineComponent({
322
322
  abort = controller.abort.bind(controller);
323
323
  };
324
324
 
325
- const loadMore = (): void => fetchComment(page.value + 1);
325
+ const loadMore = (): void => fetchCommentData(page.value + 1);
326
326
 
327
327
  const refresh = (): void => {
328
328
  count.value = 0;
329
329
  data.value = [];
330
- fetchComment(1);
330
+ fetchCommentData(1);
331
331
  };
332
332
 
333
333
  const onSortByChange = (item: SortKeyItems): void => {
@@ -1,4 +1,6 @@
1
1
  export * from './inputs';
2
+ export * from './like';
3
+ export * from './recaptchaV3';
2
4
  export * from './timeAgo';
5
+ export * from './vote';
3
6
  export * from './userInfo';
4
- export * from './like';
@@ -0,0 +1,23 @@
1
+ import { load } from 'recaptcha-v3';
2
+
3
+ import type { ReCaptchaInstance } from 'recaptcha-v3';
4
+
5
+ const recaptchaStore: Record<string, Promise<ReCaptchaInstance>> = {};
6
+
7
+ interface ReCaptcha {
8
+ execute: (action: string) => Promise<string>;
9
+ }
10
+
11
+ export const useReCaptcha = (key: string): ReCaptcha => {
12
+ const init =
13
+ recaptchaStore[key] ??
14
+ (recaptchaStore[key] = load(key, {
15
+ useRecaptchaNet: true,
16
+ autoHideBadge: true,
17
+ }));
18
+
19
+ return {
20
+ execute: (action: string) =>
21
+ init.then((instance) => instance.execute(action)),
22
+ };
23
+ };
@@ -1,18 +1,7 @@
1
1
  import { useStorage } from '@vueuse/core';
2
2
 
3
3
  import type { Ref } from 'vue';
4
-
5
- export interface UserInfo {
6
- // eslint-disable-next-line @typescript-eslint/naming-convention
7
- display_name: string;
8
- email: string;
9
- url: string;
10
- token: string;
11
- avatar: string;
12
- mailMd5: string;
13
- objectId: string | number;
14
- type: 'administrator' | 'guest';
15
- }
4
+ import type { UserInfo } from '../api';
16
5
 
17
6
  export const USER_KEY = 'WALINE_USER';
18
7
 
@@ -4,9 +4,12 @@ import type { Ref } from 'vue';
4
4
 
5
5
  const VOTE_KEY = 'WALINE_VOTE';
6
6
 
7
+ export const VOTE_IDENTIFIER = 'id';
8
+ export const VOTE_INDEX = 'i';
9
+
7
10
  export interface VoteLogItem {
8
- u: string;
9
- i: number;
11
+ [VOTE_IDENTIFIER]: string;
12
+ [VOTE_INDEX]: number;
10
13
  }
11
14
 
12
15
  export type VoteRef = Ref<VoteLogItem[]>;
@@ -0,0 +1 @@
1
+ export * from './api';
@@ -0,0 +1,2 @@
1
+ export * from '../comment';
2
+ export * from '../version';
package/src/init.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { createApp, h, reactive, watchEffect } from 'vue';
2
- import { VueReCaptcha } from './components/RecaptchaV3/RecaptchaVuePlugin';
3
2
 
4
3
  import Waline from './components/Waline.vue';
5
4
  import { commentCount } from './comment';
@@ -81,16 +80,6 @@ export const init = ({
81
80
  ? createApp(() => h(Waline, { path: state.path, ...props }))
82
81
  : null;
83
82
 
84
- if (app && initProps.recaptchaV3Key) {
85
- app.use(VueReCaptcha, {
86
- siteKey: initProps.recaptchaV3Key,
87
- loaderOptions: {
88
- useRecaptchaNet: true,
89
- autoHideBadge: true,
90
- },
91
- });
92
- }
93
-
94
83
  if (app) app.mount(root!);
95
84
 
96
85
  const stopComment = watchEffect(updateCommentCount);
package/src/pageview.ts CHANGED
@@ -1,10 +1,5 @@
1
- import {
2
- errorHandler,
3
- fetchPageviews,
4
- getQuery,
5
- getServerURL,
6
- updatePageviews,
7
- } from './utils';
1
+ import { fetchPageviews, updatePageviews } from './api';
2
+ import { errorHandler, getQuery, getServerURL } from './utils';
8
3
 
9
4
  import type { WalineAbort } from './typings';
10
5
 
@@ -56,8 +56,8 @@
56
56
  }
57
57
 
58
58
  .wl-head {
59
- line-height: 1.5;
60
59
  overflow: hidden; // bfc to fix https://github.com/walinejs/waline/issues/1415
60
+ line-height: 1.5;
61
61
  }
62
62
 
63
63
  .wl-nick {
@@ -1,9 +1,9 @@
1
- @use "sass:math";
2
- @use "sass:string";
1
+ @use 'sass:math';
2
+ @use 'sass:string';
3
3
 
4
4
  /* stylelint-disable scss/operator-no-newline-after */
5
5
 
6
- @function string-replace($string, $search, $replace: "") {
6
+ @function string-replace($string, $search, $replace: '') {
7
7
  $index: string.index($string, $search);
8
8
  @return if(
9
9
  $index,
@@ -18,7 +18,7 @@
18
18
  }
19
19
 
20
20
  @function svg-url($svg) {
21
- $encoded: "";
21
+ $encoded: '';
22
22
  $slice: 2000;
23
23
  $index: 0;
24
24
  $loops: math.ceil(math.div(string.length($svg), $slice));
@@ -26,7 +26,7 @@
26
26
  @if not str-index($svg, xmlns) {
27
27
  $svg: string-replace(
28
28
  $svg,
29
- "<svg",
29
+ '<svg',
30
30
  '<svg xmlns="http://www.w3.org/2000/svg"'
31
31
  );
32
32
  }
@@ -34,16 +34,16 @@
34
34
  @for $i from 1 through $loops {
35
35
  $chunk: string.slice($svg, $index, $index + $slice - 1);
36
36
  $chunk: string-replace($chunk, '"', "'");
37
- $chunk: string-replace($chunk, "%", "%25");
38
- $chunk: string-replace($chunk, "#", "%23");
39
- $chunk: string-replace($chunk, "{", "%7B");
40
- $chunk: string-replace($chunk, "}", "%7D");
41
- $chunk: string-replace($chunk, "<", "%3C");
42
- $chunk: string-replace($chunk, ">", "%3E");
37
+ $chunk: string-replace($chunk, '%', '%25');
38
+ $chunk: string-replace($chunk, '#', '%23');
39
+ $chunk: string-replace($chunk, '{', '%7B');
40
+ $chunk: string-replace($chunk, '}', '%7D');
41
+ $chunk: string-replace($chunk, '<', '%3C');
42
+ $chunk: string-replace($chunk, '>', '%3E');
43
43
  $encoded: #{$encoded}#{$chunk};
44
44
  $index: $index + $slice;
45
45
  }
46
- @return url("data:image/svg+xml,#{$encoded}");
46
+ @return url('data:image/svg+xml,#{$encoded}');
47
47
  }
48
48
 
49
49
  @mixin background-svg($svg) {
@@ -13,4 +13,4 @@
13
13
  @use 'highlight';
14
14
 
15
15
  @use 'recent';
16
- @use 'reaction';
16
+ @use 'reaction';
@@ -1,38 +1,30 @@
1
1
  @use 'helpers/svg';
2
2
 
3
3
  $address-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M444.52 3.52 28.74 195.42c-47.97 22.39-31.98 92.75 19.19 92.75h175.91v175.91c0 51.17 70.36 67.17 92.75 19.19l191.9-415.78c15.99-38.39-25.59-79.97-63.97-63.97z"/></svg>';
4
-
5
4
  $default-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z"/></svg>';
6
-
7
5
  $apple-icon: '<svg viewBox="0 0 384 512" fill="#999"><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg>';
8
-
9
6
  $android-icon: '<svg viewBox="0 0 576 512" fill="#999"><path d="M420.55 301.93a24 24 0 1 1 24-24 24 24 0 0 1-24 24m-265.1 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24m273.7-144.48 47.94-83a10 10 0 1 0-17.27-10l-48.54 84.07a301.25 301.25 0 0 0-246.56 0l-48.54-84.07a10 10 0 1 0-17.27 10l47.94 83C64.53 202.22 8.24 285.55 0 384h576c-8.24-98.45-64.54-181.78-146.85-226.55"/></svg>';
10
-
11
7
  $linux-icon: '<svg viewBox="0 0 448 512" fill="#999"><path d="M220.8 123.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm-21.9 1.7c1.2 0 2-1.2 3-1.7 1.1-.6 3.1-.4 3.5-1.6.2-.4-.2-.9-.6-1.1-1.6-.9-3.8-.6-5.5.1-1.3.6-3.4 1.5-3.2 2.9.1 1 1.8 1.5 2.8 1.4zM420 403.8c-3.6-4-5.3-11.6-7.2-19.7-1.8-8.1-3.9-16.8-10.5-22.4-1.3-1.1-2.6-2.1-4-2.9-1.3-.8-2.7-1.5-4.1-2 9.2-27.3 5.6-54.5-3.7-79.1-11.4-30.1-31.3-56.4-46.5-74.4-17.1-21.5-33.7-41.9-33.4-72C311.1 85.4 315.7.1 234.8 0 132.4-.2 158 103.4 156.9 135.2c-1.7 23.4-6.4 41.8-22.5 64.7-18.9 22.5-45.5 58.8-58.1 96.7-6 17.9-8.8 36.1-6.2 53.3-6.5 5.8-11.4 14.7-16.6 20.2-4.2 4.3-10.3 5.9-17 8.3s-14 6-18.5 14.5c-2.1 3.9-2.8 8.1-2.8 12.4 0 3.9.6 7.9 1.2 11.8 1.2 8.1 2.5 15.7.8 20.8-5.2 14.4-5.9 24.4-2.2 31.7 3.8 7.3 11.4 10.5 20.1 12.3 17.3 3.6 40.8 2.7 59.3 12.5 19.8 10.4 39.9 14.1 55.9 10.4 11.6-2.6 21.1-9.6 25.9-20.2 12.5-.1 26.3-5.4 48.3-6.6 14.9-1.2 33.6 5.3 55.1 4.1.6 2.3 1.4 4.6 2.5 6.7v.1c8.3 16.7 23.8 24.3 40.3 23 16.6-1.3 34.1-11 48.3-27.9 13.6-16.4 36-23.2 50.9-32.2 7.4-4.5 13.4-10.1 13.9-18.3.4-8.2-4.4-17.3-15.5-29.7zM223.7 87.3c9.8-22.2 34.2-21.8 44-.4 6.5 14.2 3.6 30.9-4.3 40.4-1.6-.8-5.9-2.6-12.6-4.9 1.1-1.2 3.1-2.7 3.9-4.6 4.8-11.8-.2-27-9.1-27.3-7.3-.5-13.9 10.8-11.8 23-4.1-2-9.4-3.5-13-4.4-1-6.9-.3-14.6 2.9-21.8zM183 75.8c10.1 0 20.8 14.2 19.1 33.5-3.5 1-7.1 2.5-10.2 4.6 1.2-8.9-3.3-20.1-9.6-19.6-8.4.7-9.8 21.2-1.8 28.1 1 .8 1.9-.2-5.9 5.5-15.6-14.6-10.5-52.1 8.4-52.1zm-13.6 60.7c6.2-4.6 13.6-10 14.1-10.5 4.7-4.4 13.5-14.2 27.9-14.2 7.1 0 15.6 2.3 25.9 8.9 6.3 4.1 11.3 4.4 22.6 9.3 8.4 3.5 13.7 9.7 10.5 18.2-2.6 7.1-11 14.4-22.7 18.1-11.1 3.6-19.8 16-38.2 14.9-3.9-.2-7-1-9.6-2.1-8-3.5-12.2-10.4-20-15-8.6-4.8-13.2-10.4-14.7-15.3-1.4-4.9 0-9 4.2-12.3zm3.3 334c-2.7 35.1-43.9 34.4-75.3 18-29.9-15.8-68.6-6.5-76.5-21.9-2.4-4.7-2.4-12.7 2.6-26.4v-.2c2.4-7.6.6-16-.6-23.9-1.2-7.8-1.8-15 .9-20 3.5-6.7 8.5-9.1 14.8-11.3 10.3-3.7 11.8-3.4 19.6-9.9 5.5-5.7 9.5-12.9 14.3-18 5.1-5.5 10-8.1 17.7-6.9 8.1 1.2 15.1 6.8 21.9 16l19.6 35.6c9.5 19.9 43.1 48.4 41 68.9zm-1.4-25.9c-4.1-6.6-9.6-13.6-14.4-19.6 7.1 0 14.2-2.2 16.7-8.9 2.3-6.2 0-14.9-7.4-24.9-13.5-18.2-38.3-32.5-38.3-32.5-13.5-8.4-21.1-18.7-24.6-29.9s-3-23.3-.3-35.2c5.2-22.9 18.6-45.2 27.2-59.2 2.3-1.7.8 3.2-8.7 20.8-8.5 16.1-24.4 53.3-2.6 82.4.6-20.7 5.5-41.8 13.8-61.5 12-27.4 37.3-74.9 39.3-112.7 1.1.8 4.6 3.2 6.2 4.1 4.6 2.7 8.1 6.7 12.6 10.3 12.4 10 28.5 9.2 42.4 1.2 6.2-3.5 11.2-7.5 15.9-9 9.9-3.1 17.8-8.6 22.3-15 7.7 30.4 25.7 74.3 37.2 95.7 6.1 11.4 18.3 35.5 23.6 64.6 3.3-.1 7 .4 10.9 1.4 13.8-35.7-11.7-74.2-23.3-84.9-4.7-4.6-4.9-6.6-2.6-6.5 12.6 11.2 29.2 33.7 35.2 59 2.8 11.6 3.3 23.7.4 35.7 16.4 6.8 35.9 17.9 30.7 34.8-2.2-.1-3.2 0-4.2 0 3.2-10.1-3.9-17.6-22.8-26.1-19.6-8.6-36-8.6-38.3 12.5-12.1 4.2-18.3 14.7-21.4 27.3-2.8 11.2-3.6 24.7-4.4 39.9-.5 7.7-3.6 18-6.8 29-32.1 22.9-76.7 32.9-114.3 7.2zm257.4-11.5c-.9 16.8-41.2 19.9-63.2 46.5-13.2 15.7-29.4 24.4-43.6 25.5s-26.5-4.8-33.7-19.3c-4.7-11.1-2.4-23.1 1.1-36.3 3.7-14.2 9.2-28.8 9.9-40.6.8-15.2 1.7-28.5 4.2-38.7 2.6-10.3 6.6-17.2 13.7-21.1.3-.2.7-.3 1-.5.8 13.2 7.3 26.6 18.8 29.5 12.6 3.3 30.7-7.5 38.4-16.3 9-.3 15.7-.9 22.6 5.1 9.9 8.5 7.1 30.3 17.1 41.6 10.6 11.6 14 19.5 13.7 24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4s5.9-6.3 3.1-6.6-2.6 2.6-6 5.1c-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2s-18.7-4.8-24.9-9.7c-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"/></svg>';
12
-
13
8
  $ubuntu-icon: '<svg viewBox="0 0 496 512" fill="#999"><path d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm52.7 93c8.8-15.2 28.3-20.5 43.5-11.7 15.3 8.8 20.5 28.3 11.7 43.6-8.8 15.2-28.3 20.5-43.5 11.7-15.3-8.9-20.5-28.4-11.7-43.6zM87.4 287.9c-17.6 0-31.9-14.3-31.9-31.9 0-17.6 14.3-31.9 31.9-31.9 17.6 0 31.9 14.3 31.9 31.9 0 17.6-14.3 31.9-31.9 31.9zm28.1 3.1c22.3-17.9 22.4-51.9 0-69.9 8.6-32.8 29.1-60.7 56.5-79.1l23.7 39.6c-51.5 36.3-51.5 112.5 0 148.8L172 370c-27.4-18.3-47.8-46.3-56.5-79zm228.7 131.7c-15.3 8.8-34.7 3.6-43.5-11.7-8.8-15.3-3.6-34.8 11.7-43.6 15.2-8.8 34.7-3.6 43.5 11.7 8.8 15.3 3.6 34.8-11.7 43.6zm.3-69.5c-26.7-10.3-56.1 6.6-60.5 35-5.2 1.4-48.9 14.3-96.7-9.4l22.5-40.3c57 26.5 123.4-11.7 128.9-74.4l46.1.7c-2.3 34.5-17.3 65.5-40.3 88.4zm-5.9-105.3c-5.4-62-71.3-101.2-128.9-74.4l-22.5-40.3c47.9-23.7 91.5-10.8 96.7-9.4 4.4 28.3 33.8 45.3 60.5 35 23.1 22.9 38 53.9 40.2 88.5l-46 .6z"/></svg>';
14
-
15
9
  $window-icon: '<svg viewBox="0 0 448 512" fill="#999"><path d="m0 93.7 183.6-25.3v177.4H0V93.7zm0 324.6 183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"/></svg>';
16
-
17
10
  $chrome-icon: '<svg viewBox="0 0 496 512" fill="#999"><path d="M131.5 217.5 55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6 40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"/></svg>';
18
-
19
11
  $edge-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M481.92 134.48C440.87 54.18 352.26 8 255.91 8 137.05 8 37.51 91.68 13.47 203.66c26-46.49 86.22-79.14 149.46-79.14 79.27 0 121.09 48.93 122.25 50.18 22 23.8 33 50.39 33 83.1 0 10.4-5.31 25.82-15.11 38.57-1.57 2-6.39 4.84-6.39 11 0 5.06 3.29 9.92 9.14 14 27.86 19.37 80.37 16.81 80.51 16.81A115.39 115.39 0 0 0 444.94 322a118.92 118.92 0 0 0 58.95-102.44c.5-43.43-15.5-72.3-21.97-85.08ZM212.77 475.67a154.88 154.88 0 0 1-46.64-45c-32.94-47.42-34.24-95.6-20.1-136A155.5 155.5 0 0 1 203 215.75c59-45.2 94.84-5.65 99.06-1a80 80 0 0 0-4.89-10.14c-9.24-15.93-24-36.41-56.56-53.51-33.72-17.69-70.59-18.59-77.64-18.59-38.71 0-77.9 13-107.53 35.69C35.68 183.3 12.77 208.72 8.6 243c-1.08 12.31-2.75 62.8 23 118.27a248 248 0 0 0 248.3 141.61c-38.12-6.62-65.85-26.64-67.13-27.21Zm250.72-98.33a7.76 7.76 0 0 0-7.92-.23 181.66 181.66 0 0 1-20.41 9.12 197.54 197.54 0 0 1-69.55 12.52c-91.67 0-171.52-63.06-171.52-144a61.12 61.12 0 0 1 6.52-26.75 168.72 168.72 0 0 0-38.76 50c-14.92 29.37-33 88.13 13.33 151.66 6.51 8.91 23 30 56 47.67 23.57 12.65 49 19.61 71.7 19.61 35.14 0 115.43-33.44 163-108.87a7.75 7.75 0 0 0-2.39-10.73Z"/></svg>';
20
-
21
12
  $firefox-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M189.37 152.86Zm-58.74-29.37c.16.01.08.01 0 0Zm351.42 45.35c-10.61-25.5-32.08-53-48.94-61.73 13.72 26.89 21.67 53.88 24.7 74 0 0 0 .14.05.41-27.58-68.75-74.35-96.47-112.55-156.83-1.93-3.05-3.86-6.11-5.74-9.33-1-1.65-1.86-3.34-2.69-5.05a44.88 44.88 0 0 1-3.64-9.62.63.63 0 0 0-.55-.66.9.9 0 0 0-.46 0l-.12.07-.18.1.1-.14c-54.23 31.77-76.72 87.38-82.5 122.78a130 130 0 0 0-48.33 12.33 6.25 6.25 0 0 0-3.09 7.75 6.13 6.13 0 0 0 7.79 3.79l.52-.21a117.84 117.84 0 0 1 42.11-11l1.42-.1c2-.12 4-.2 6-.22A122.61 122.61 0 0 1 291 140c.67.2 1.32.42 2 .63 1.89.57 3.76 1.2 5.62 1.87 1.36.5 2.71 1 4.05 1.58 1.09.44 2.18.88 3.25 1.35q2.52 1.13 5 2.35c.75.37 1.5.74 2.25 1.13q2.4 1.26 4.74 2.63 1.51.87 3 1.8a124.89 124.89 0 0 1 42.66 44.13c-13-9.15-36.35-18.19-58.82-14.28 87.74 43.86 64.18 194.9-57.39 189.2a108.43 108.43 0 0 1-31.74-6.12 139.5 139.5 0 0 1-7.16-2.93c-1.38-.63-2.76-1.27-4.12-2-29.84-15.34-54.44-44.42-57.51-79.75 0 0 11.25-41.95 80.62-41.95 7.5 0 28.93-20.92 29.33-27-.09-2-42.54-18.87-59.09-35.18-8.85-8.71-13.05-12.91-16.77-16.06a69.58 69.58 0 0 0-6.31-4.77 113.05 113.05 0 0 1-.69-59.63c-25.06 11.41-44.55 29.45-58.71 45.37h-.12c-9.67-12.25-9-52.65-8.43-61.08-.12-.53-7.22 3.68-8.15 4.31a178.54 178.54 0 0 0-23.84 20.43 214 214 0 0 0-22.77 27.33 205.84 205.84 0 0 0-32.73 73.9c-.06.27-2.33 10.21-4 22.48q-.42 2.87-.78 5.74c-.57 3.69-1 7.71-1.44 14 0 .24 0 .48-.05.72-.18 2.71-.34 5.41-.49 8.12v1.24c0 134.7 109.21 243.89 243.92 243.89 120.64 0 220.82-87.58 240.43-202.62.41-3.12.74-6.26 1.11-9.41 4.85-41.83-.54-85.79-15.82-122.55Z"/></svg>';
22
-
23
13
  $ie-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"/></svg>';
24
-
25
14
  $safari-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="m274.69 274.69-37.38-37.38L166 346ZM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8Zm155.85 174.79 14.78-6.13a8 8 0 0 1 10.45 4.34 8 8 0 0 1-4.33 10.46L418 197.57a8 8 0 0 1-10.45-4.33 8 8 0 0 1 4.3-10.45ZM314.43 94l6.12-14.78a8 8 0 0 1 10.45-4.3 8 8 0 0 1 4.33 10.45l-6.13 14.78a8 8 0 0 1-10.45 4.33A8 8 0 0 1 314.43 94ZM256 60a8 8 0 0 1 8 8v16a8 8 0 0 1-8 8 8 8 0 0 1-8-8V68a8 8 0 0 1 8-8Zm-75 14.92a8 8 0 0 1 10.46 4.33L197.57 94a8 8 0 1 1-14.78 6.12l-6.13-14.78A8 8 0 0 1 181 74.92Zm-63.58 42.49a8 8 0 0 1 11.31 0L140 128.72a8 8 0 0 1 0 11.28 8 8 0 0 1-11.31 0l-11.31-11.31a8 8 0 0 1 .03-11.28ZM60 256a8 8 0 0 1 8-8h16a8 8 0 0 1 8 8 8 8 0 0 1-8 8H68a8 8 0 0 1-8-8Zm40.15 73.21-14.78 6.13A8 8 0 0 1 74.92 331a8 8 0 0 1 4.33-10.46L94 314.43a8 8 0 0 1 10.45 4.33 8 8 0 0 1-4.3 10.45Zm4.33-136A8 8 0 0 1 94 197.57l-14.78-6.12a8 8 0 0 1-4.3-10.45 8 8 0 0 1 10.45-4.33l14.78 6.13a8 8 0 0 1 4.33 10.44ZM197.57 418l-6.12 14.78a8 8 0 0 1-14.79-6.12l6.13-14.78a8 8 0 1 1 14.78 6.12ZM264 444a8 8 0 0 1-8 8 8 8 0 0 1-8-8v-16a8 8 0 0 1 8-8 8 8 0 0 1 8 8Zm67-6.92a8 8 0 0 1-10.46-4.33L314.43 418a8 8 0 0 1 4.33-10.45 8 8 0 0 1 10.45 4.33l6.13 14.78a8 8 0 0 1-4.34 10.42Zm63.58-42.49a8 8 0 0 1-11.31 0L372 383.28a8 8 0 0 1 0-11.28 8 8 0 0 1 11.31 0l11.31 11.31a8 8 0 0 1-.03 11.28ZM286.25 286.25 110.34 401.66l115.41-175.91 175.91-115.41ZM437.08 331a8 8 0 0 1-10.45 4.33l-14.78-6.13a8 8 0 0 1-4.33-10.45 8 8 0 0 1 10.48-4.32l14.78 6.12a8 8 0 0 1 4.3 10.45Zm6.92-67h-16a8 8 0 0 1-8-8 8 8 0 0 1 8-8h16a8 8 0 0 1 8 8 8 8 0 0 1-8 8Z"/></svg>';
26
15
 
27
16
  .wl-meta > {
28
17
  span::before {
29
18
  content: '';
19
+
20
+ display: inline-block;
21
+
30
22
  width: 1em;
31
23
  height: 1em;
32
- display: inline-block;
33
- background-repeat: no-repeat;
34
- background-position: center center;
35
24
  margin-right: 2px;
25
+
26
+ background-position: center center;
27
+ background-repeat: no-repeat;
36
28
  }
37
29
 
38
30
  .wl-addr::before {
@@ -47,6 +39,7 @@ $safari-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="m274.69 274.69-37
47
39
  .wl-os[data-value^='windows' i]::before {
48
40
  @include svg.background-svg($window-icon);
49
41
  }
42
+
50
43
  .wl-os[data-value^='mac' i]::before,
51
44
  .wl-os[data-value^='ios' i]::before,
52
45
  .wl-os[data-value^='iphone' i]::before,
@@ -61,6 +54,7 @@ $safari-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="m274.69 274.69-37
61
54
  .wl-os[data-value^='ubuntu' i]::before {
62
55
  @include svg.background-svg($ubuntu-icon);
63
56
  }
57
+
64
58
  .wl-os[data-value^='android' i]::before {
65
59
  @include svg.background-svg($android-icon);
66
60
  }
@@ -76,9 +70,11 @@ $safari-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="m274.69 274.69-37
76
70
  .wl-browser[data-value^='firefox' i]::before {
77
71
  @include svg.background-svg($firefox-icon);
78
72
  }
73
+
79
74
  .wl-browser[data-value^='safari' i]::before {
80
75
  @include svg.background-svg($safari-icon);
81
76
  }
77
+
82
78
  .wl-browser[data-value^='ie' i]::before,
83
79
  .wl-browser[data-value^='explorer' i]::before {
84
80
  @include svg.background-svg($ie-icon);
@@ -1,21 +1,23 @@
1
1
  .wl-reaction {
2
- text-align: center;
3
2
  margin-bottom: 1.75em;
3
+ text-align: center;
4
4
 
5
5
  ul {
6
- margin: 0;
7
- list-style-type: none;
8
6
  display: flex;
9
7
  flex-direction: row;
10
- justify-content: center;
11
8
  gap: 16px;
9
+ justify-content: center;
10
+
11
+ margin: 0;
12
+
13
+ list-style-type: none;
12
14
  }
13
15
 
14
16
  li {
15
- cursor: pointer;
16
17
  display: flex;
17
18
  flex-direction: column;
18
19
  align-items: center;
20
+ cursor: pointer;
19
21
 
20
22
  &:hover img,
21
23
  &.active img {
@@ -24,11 +26,12 @@
24
26
  }
25
27
 
26
28
  li.active .wl-reaction {
27
- &__votes {
28
- color: var(--waline-bgcolor);
29
+ &-votes {
29
30
  background: var(--waline-theme-color);
31
+ color: var(--waline-bgcolor);
30
32
  }
31
- &__text {
33
+
34
+ &-text {
32
35
  color: var(--waline-theme-color);
33
36
  }
34
37
  }
@@ -39,28 +42,31 @@
39
42
  transition: all 250ms ease-in-out;
40
43
  }
41
44
 
42
- &__img {
45
+ &-img {
43
46
  position: relative;
44
47
  width: 42px;
45
48
  height: 42px;
46
49
  }
47
50
 
48
- &__votes {
51
+ &-votes {
49
52
  position: absolute;
50
53
  top: -4px;
51
54
  right: -5px;
52
- font-size: 0.75em;
53
- color: var(--waline-theme-color);
54
- background: var(--waline-bgcolor);
55
- border: 1px solid var(--waline-theme-color);
55
+
56
+ min-width: 1em;
56
57
  padding: 2px;
58
+ border: 1px solid var(--waline-theme-color);
57
59
  border-radius: 1em;
58
- line-height: 1;
59
- min-width: 1em;
60
+
61
+ background: var(--waline-bgcolor);
62
+ color: var(--waline-theme-color);
63
+
60
64
  font-weight: 700;
65
+ font-size: 0.75em;
66
+ line-height: 1;
61
67
  }
62
68
 
63
- &__text {
69
+ &-text {
64
70
  font-size: 0.875em;
65
71
  }
66
- }
72
+ }
@@ -39,44 +39,70 @@ export interface WalineEmojiInfo {
39
39
 
40
40
  export type WalineEmojiMaps = Record<string, string>;
41
41
 
42
- export interface WalineSearchResult extends Record<string, unknown> {
42
+ export interface WalineSearchImageData extends Record<string, unknown> {
43
43
  /**
44
+ * 图片链接
45
+ *
44
46
  * Image link
45
47
  */
46
48
  src: string;
47
49
 
48
50
  /**
49
- * Image title, optional
51
+ * 图片标题
52
+ *
53
+ * @description 用于图片的 alt 属性
54
+ *
55
+ * Image title
56
+ *
57
+ * @description Used for alt attribute of image
50
58
  */
51
59
  title?: string;
52
60
 
53
61
  /**
54
- * Image preview link, optional
62
+ * 图片缩略图
63
+ *
64
+ * @description 为了更好的加载性能,我们会优先在列表中使用此缩略图
65
+ *
66
+ * Image preview link
67
+ *
68
+ * @description For better loading performance, we will use this thumbnail first in the list
55
69
  *
56
70
  * @default src
57
71
  */
58
72
  preview?: string;
59
73
  }
60
74
 
75
+ export type WalineSearchResult = WalineSearchImageData[];
76
+
61
77
  export interface WalineSearchOptions {
62
78
  /**
79
+ * 搜索操作
80
+ *
63
81
  * Search action
64
82
  */
65
- search: (word: string) => Promise<WalineSearchResult[]>;
83
+ search: (word: string) => Promise<WalineSearchResult>;
66
84
 
67
85
  /**
68
- * Default search action
86
+ * 打开列表时展示的默认结果
87
+ *
88
+ * Default result when opening list
69
89
  *
70
90
  * @default () => search('')
71
91
  */
72
- default?: () => Promise<WalineSearchResult[]>;
92
+ default?: () => Promise<WalineSearchResult>;
73
93
 
74
94
  /**
95
+ * 获取更多的操作
96
+ *
97
+ * @description 会在列表滚动到底部时触发,如果你的搜索服务支持分页功能,你应该设置此项实现无限滚动
98
+ *
75
99
  * Fetch more action
76
100
  *
101
+ * @description It will be triggered when the list scrolls to the bottom. If your search service supports paging, you should set this to achieve infinite scrolling
102
+ *
77
103
  * @default (word) => search(word)
78
104
  */
79
- more?: (word: string, currectCount: number) => Promise<WalineSearchResult[]>;
105
+ more?: (word: string, currectCount: number) => Promise<WalineSearchResult>;
80
106
  }
81
107
 
82
108
  export type WalineMeta = 'nick' | 'mail' | 'link';