@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
@@ -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);
@@ -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
  };
@@ -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 {
@@ -131,6 +130,8 @@ const props = [
131
130
  'imageUploader',
132
131
  'search',
133
132
  'copyright',
133
+ 'recaptchaV3Key',
134
+ 'reaction',
134
135
  ];
135
136
 
136
137
  type SortKeyItems = 'insertedAt_desc' | 'insertedAt_asc' | 'like_desc';
@@ -240,8 +241,9 @@ const propsWithValidate = {
240
241
 
241
242
  copyright: { type: Boolean, default: true },
242
243
 
243
- recaptchav3key: {
244
+ recaptchaV3Key: {
244
245
  type: String,
246
+ default: '',
245
247
  },
246
248
 
247
249
  reaction: {
@@ -285,7 +287,7 @@ export default defineComponent({
285
287
  // eslint-disable-next-line vue/no-setup-props-destructure
286
288
  let abort: () => void;
287
289
 
288
- const fetchComment = (pageNumber: number): void => {
290
+ const fetchCommentData = (pageNumber: number): void => {
289
291
  const { serverURL, path, pageSize } = config.value;
290
292
  const controller = new AbortController();
291
293
 
@@ -293,7 +295,7 @@ export default defineComponent({
293
295
 
294
296
  abort?.();
295
297
 
296
- fetchCommentList({
298
+ fetchComment({
297
299
  serverURL,
298
300
  lang: config.value.lang,
299
301
  path,
@@ -320,12 +322,12 @@ export default defineComponent({
320
322
  abort = controller.abort.bind(controller);
321
323
  };
322
324
 
323
- const loadMore = (): void => fetchComment(page.value + 1);
325
+ const loadMore = (): void => fetchCommentData(page.value + 1);
324
326
 
325
327
  const refresh = (): void => {
326
328
  count.value = 0;
327
329
  data.value = [];
328
- fetchComment(1);
330
+ fetchCommentData(1);
329
331
  };
330
332
 
331
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
 
@@ -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
+ }
@@ -23,11 +23,9 @@ export interface WalineEmojiConfig {
23
23
  map: WalineEmojiMaps;
24
24
  }
25
25
 
26
- export interface WalineConfig
27
- extends Required<Omit<WalineProps, 'wordLimit' | 'recaptchaV3Key'>> {
26
+ export interface WalineConfig extends Required<Omit<WalineProps, 'wordLimit'>> {
28
27
  locale: WalineLocale;
29
28
  wordLimit: [number, number] | false;
30
- // emoji: Promise<EmojiConfig>;
31
29
  }
32
30
 
33
31
  export const getServerURL = (serverURL: string): string => {
@@ -66,6 +64,7 @@ export const getConfig = ({
66
64
  login = 'enable',
67
65
  search = getDefaultSearchOptions(),
68
66
  reaction,
67
+ recaptchaV3Key = '',
69
68
  ...more
70
69
  }: WalineProps): WalineConfig => ({
71
70
  serverURL: getServerURL(serverURL),
@@ -87,6 +86,7 @@ export const getConfig = ({
87
86
  login,
88
87
  copyright,
89
88
  search,
89
+ recaptchaV3Key,
90
90
  reaction: reaction === true ? defaultReaction : reaction || false,
91
91
  ...more,
92
92
  });
@@ -3,7 +3,6 @@ export * from './darkmode';
3
3
  export * from './date';
4
4
  export * from './emoji';
5
5
  export * from './error';
6
- export * from './fetch';
7
6
  export * from './getRoot';
8
7
  export * from './image';
9
8
  export * from './markdown';
@@ -1,5 +1,6 @@
1
+ import { fetchRecentComment } from '../api';
1
2
  import { useUserInfo } from '../composables';
2
- import { fetchRecentComment, getRoot } from '../utils';
3
+ import { getRoot } from '../utils';
3
4
 
4
5
  import type { WalineComment } from '../typings';
5
6
 
@@ -1,6 +0,0 @@
1
- import { IReCaptchaLoaderOptions } from 'recaptcha-v3/dist/ReCaptchaLoader';
2
-
3
- export interface IReCaptchaOptions {
4
- siteKey: string;
5
- loaderOptions: IReCaptchaLoaderOptions;
6
- }
@@ -1,3 +0,0 @@
1
- # Vue reCAPTCHA-v3
2
-
3
- This is a fork from https://github.com/AurityLab/vue-recaptcha-v3 because of commonjs bundle conflict with vite.