@waline/client 2.5.0 → 2.6.1

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 (50) hide show
  1. package/LICENSE +339 -0
  2. package/dist/component.esm.js +1 -1
  3. package/dist/component.esm.js.map +1 -1
  4. package/dist/component.js +1 -1
  5. package/dist/component.js.map +1 -1
  6. package/dist/legacy.d.ts +40 -0
  7. package/dist/legacy.js +1 -1
  8. package/dist/legacy.js.map +1 -1
  9. package/dist/pageview.cjs.js +1 -1
  10. package/dist/pageview.cjs.js.map +1 -1
  11. package/dist/pageview.esm.js +1 -1
  12. package/dist/pageview.esm.js.map +1 -1
  13. package/dist/pageview.js +1 -1
  14. package/dist/pageview.js.map +1 -1
  15. package/dist/shim.d.ts +41 -1
  16. package/dist/shim.esm.d.ts +41 -1
  17. package/dist/shim.esm.js +1 -1
  18. package/dist/shim.esm.js.map +1 -1
  19. package/dist/shim.js +1 -1
  20. package/dist/shim.js.map +1 -1
  21. package/dist/waline.cjs.d.ts +41 -1
  22. package/dist/waline.cjs.js +1 -1
  23. package/dist/waline.cjs.js.map +1 -1
  24. package/dist/waline.css +1 -1
  25. package/dist/waline.css.map +1 -1
  26. package/dist/waline.d.ts +41 -1
  27. package/dist/waline.esm.d.ts +41 -1
  28. package/dist/waline.esm.js +1 -1
  29. package/dist/waline.esm.js.map +1 -1
  30. package/dist/waline.js +1 -1
  31. package/dist/waline.js.map +1 -1
  32. package/package.json +31 -33
  33. package/src/comment.ts +7 -2
  34. package/src/components/CommentBox.vue +57 -63
  35. package/src/components/CommentCard.vue +1 -1
  36. package/src/components/ImageWall.vue +166 -0
  37. package/src/composables/like.ts +1 -1
  38. package/src/config/default.ts +91 -1
  39. package/src/init.ts +2 -10
  40. package/src/pageview.ts +7 -2
  41. package/src/styles/emoji.scss +112 -94
  42. package/src/styles/gif.scss +58 -139
  43. package/src/styles/index.scss +3 -0
  44. package/src/styles/panel.scss +0 -6
  45. package/src/typings/base.ts +40 -0
  46. package/src/typings/waline.ts +8 -0
  47. package/src/utils/config.ts +5 -2
  48. package/src/utils/index.ts +0 -2
  49. package/src/utils/fetchGif.ts +0 -62
  50. package/src/utils/throttle.ts +0 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/client",
3
- "version": "2.5.0",
3
+ "version": "2.6.1",
4
4
  "description": "client for waline comment system",
5
5
  "keywords": [
6
6
  "valine",
@@ -56,15 +56,6 @@
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
- },
68
59
  "browserslist": {
69
60
  "production": [
70
61
  ">0.5%",
@@ -80,33 +71,40 @@
80
71
  ]
81
72
  },
82
73
  "dependencies": {
83
- "@vueuse/core": "^8.4.2",
74
+ "@vueuse/core": "^8.6.0",
84
75
  "autosize": "^5.0.1",
85
- "marked": "^4.0.15",
86
- "vue": "^3.2.33"
76
+ "marked": "^4.0.17",
77
+ "vue": "^3.2.37"
87
78
  },
88
79
  "devDependencies": {
89
- "@babel/core": "^7.17.10",
90
- "@babel/preset-env": "^7.17.10",
91
- "@rollup/plugin-babel": "^5.3.1",
92
- "@rollup/plugin-commonjs": "^22.0.0",
93
- "@rollup/plugin-node-resolve": "^13.3.0",
94
- "@rollup/plugin-replace": "^4.0.0",
95
- "@types/autosize": "^4.0.1",
96
- "@types/marked": "^4.0.3",
97
- "@types/node": "^17.0.33",
98
- "@vitejs/plugin-vue": "^2.3.3",
99
- "@vue/compiler-sfc": "^3.2.33",
100
- "@yeger/vue-masonry-wall": "^3.0.31",
101
- "rimraf": "^3.0.2",
102
- "rollup": "^2.73.0",
103
- "rollup-plugin-dts": "^4.2.1",
104
- "rollup-plugin-terser": "^7.0.2",
105
- "rollup-plugin-ts": "^2.0.7",
106
- "typescript": "^4.6.4",
107
- "vite": "^2.9.9"
80
+ "@babel/core": "7.18.5",
81
+ "@babel/preset-env": "7.18.2",
82
+ "@rollup/plugin-babel": "5.3.1",
83
+ "@rollup/plugin-commonjs": "22.0.0",
84
+ "@rollup/plugin-node-resolve": "13.3.0",
85
+ "@rollup/plugin-replace": "4.0.0",
86
+ "@types/autosize": "4.0.1",
87
+ "@types/marked": "4.0.3",
88
+ "@types/node": "17.0.43",
89
+ "@vitejs/plugin-vue": "2.3.3",
90
+ "rimraf": "3.0.2",
91
+ "rollup": "2.75.6",
92
+ "rollup-plugin-dts": "4.2.2",
93
+ "rollup-plugin-terser": "7.0.2",
94
+ "rollup-plugin-ts": "3.0.2",
95
+ "typescript": "4.7.3",
96
+ "vite": "2.9.12"
108
97
  },
109
98
  "engines": {
110
99
  "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"
111
109
  }
112
- }
110
+ }
package/src/comment.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { useUserInfo } from './composables';
2
- import { decodePath, errorHandler, fetchCommentCount } from './utils';
2
+ import {
3
+ decodePath,
4
+ errorHandler,
5
+ fetchCommentCount,
6
+ getServerURL,
7
+ } from './utils';
3
8
  import type { WalineAbort } from './typings';
4
9
 
5
10
  export interface WalineCommentCountOptions {
@@ -54,7 +59,7 @@ WalineCommentCountOptions): WalineAbort => {
54
59
 
55
60
  if (elements.length)
56
61
  void fetchCommentCount({
57
- serverURL,
62
+ serverURL: getServerURL(serverURL),
58
63
  paths: Array.from(elements).map((element) =>
59
64
  decodePath(element.dataset.path || element.getAttribute('id') || path)
60
65
  ),
@@ -35,7 +35,7 @@
35
35
  <input
36
36
  :ref="
37
37
  (element) => {
38
- if (element) inputRefs[kind] = element;
38
+ if (element) inputRefs[kind] = element as HTMLInputElement;
39
39
  }
40
40
  "
41
41
  :id="`wl-${kind}`"
@@ -89,6 +89,7 @@
89
89
  </button>
90
90
 
91
91
  <button
92
+ v-if="config.search"
92
93
  ref="gifButtonRef"
93
94
  class="wl-action"
94
95
  :class="{ actived: showGif }"
@@ -174,30 +175,14 @@
174
175
  @input="onGifSearch"
175
176
  />
176
177
 
177
- <masonry-wall
178
- class="wl-gif-waterfall"
178
+ <ImageWall
179
179
  :items="gifData.list"
180
- :ssr-columns="2"
181
180
  :column-width="200"
182
181
  :gap="6"
183
- @scroll="onGifMasonryScroll"
182
+ @insert="insert($event)"
183
+ @scroll="onImageWallScroll"
184
184
  >
185
- <template #default="{ item }">
186
- <img
187
- @click="insert(`![](${item.media[0].tinygif.url})`)"
188
- :src="item.media[0].tinygif.url"
189
- :title="item.title"
190
- loading="lazy"
191
- :style="{
192
- width: '200px',
193
- height:
194
- (200 * item.media[0].tinygif.dims[1]) /
195
- item.media[0].tinygif.dims[0] +
196
- 'px',
197
- }"
198
- />
199
- </template>
200
- </masonry-wall>
185
+ </ImageWall>
201
186
 
202
187
  <div v-if="gifData.loading" class="wl-loading">
203
188
  <LoadingIcon :size="30" />
@@ -261,6 +246,7 @@
261
246
  </template>
262
247
 
263
248
  <script lang="ts">
249
+ import { useDebounceFn } from '@vueuse/core';
264
250
  import autosize from 'autosize';
265
251
  import {
266
252
  computed,
@@ -268,6 +254,7 @@ import {
268
254
  inject,
269
255
  onMounted,
270
256
  onUnmounted,
257
+ reactive,
271
258
  ref,
272
259
  watch,
273
260
  } from 'vue';
@@ -281,21 +268,24 @@ import {
281
268
  LoadingIcon,
282
269
  GifIcon,
283
270
  } from './Icons';
271
+ import ImageWall from './ImageWall.vue';
284
272
  import { useEditor, useUserMeta, useUserInfo } from '../composables';
285
273
  import {
274
+ getEmojis,
286
275
  getImagefromDataTransfer,
287
- parseMarkdown,
288
276
  getWordNumber,
289
277
  parseEmoji,
278
+ parseMarkdown,
290
279
  postComment,
291
- getEmojis,
292
- fetchGif,
293
- FetchGifResponse,
294
- throttle,
295
280
  } from '../utils';
296
281
 
297
282
  import type { ComputedRef, DeepReadonly } from 'vue';
298
- import type { WalineCommentData, WalineImageUploader } from '../typings';
283
+ import type {
284
+ WalineCommentData,
285
+ WalineImageUploader,
286
+ WalineSearchOptions,
287
+ WalineSearchResult,
288
+ } from '../typings';
299
289
  import type { WalineConfig, WalineEmojiConfig } from '../utils';
300
290
 
301
291
  export default defineComponent({
@@ -305,6 +295,7 @@ export default defineComponent({
305
295
  CloseIcon,
306
296
  EmojiIcon,
307
297
  ImageIcon,
298
+ ImageWall,
308
299
  MarkdownIcon,
309
300
  PreviewIcon,
310
301
  LoadingIcon,
@@ -353,11 +344,11 @@ export default defineComponent({
353
344
  const showPreview = ref(false);
354
345
  const previewText = ref('');
355
346
  const wordNumber = ref(0);
356
- const gifData = ref<{
357
- cursor: string;
358
- loading: boolean;
359
- list: FetchGifResponse['results'];
360
- }>({ cursor: '', loading: true, list: [] });
347
+
348
+ const searchResults = reactive({
349
+ loading: true,
350
+ list: [] as WalineSearchResult[],
351
+ });
361
352
 
362
353
  const wordLimit = ref(0);
363
354
  const isWordNumberLegal = ref(false);
@@ -621,35 +612,35 @@ export default defineComponent({
621
612
  showGif.value = false;
622
613
  };
623
614
 
624
- const onGifSearch = throttle(async (event: Event) => {
625
- gifData.value.cursor = '';
626
- gifData.value.list = [];
627
- onGifMasonryScroll(event);
628
- });
629
-
630
- const onGifMasonryScroll = async (event: Event): Promise<void> => {
615
+ const onImageWallScroll = async (event: Event): Promise<void> => {
631
616
  const { scrollTop, clientHeight, scrollHeight } =
632
617
  event.target as HTMLDivElement;
633
618
  const percent = (clientHeight + scrollTop) / scrollHeight;
634
- if (percent < 0.9 || gifData.value.loading) {
635
- return;
636
- }
619
+ const searchOptions = config.value.search as WalineSearchOptions;
620
+ const keyword = gifSearchInputRef.value?.value || '';
621
+
622
+ if (percent < 0.9 || searchResults.loading) return;
623
+
624
+ searchResults.loading = true;
625
+
626
+ searchResults.list.push(
627
+ ...(searchOptions.more
628
+ ? await searchOptions.more(keyword, searchResults.list.length)
629
+ : await searchOptions.search(keyword))
630
+ );
637
631
 
638
- gifData.value.loading = true;
639
- const data = await fetchGif({
640
- keyword: gifSearchInputRef.value?.value || '',
641
- pos: gifData.value.cursor,
642
- }).finally(() => {
643
- gifData.value.loading = false;
644
- });
632
+ searchResults.loading = false;
645
633
 
646
- gifData.value.cursor = data.next;
647
- gifData.value.list = gifData.value.list.concat(data.results);
648
634
  setTimeout(() => {
649
635
  (event.target as HTMLDivElement).scrollTop = scrollTop;
650
636
  }, 50);
651
637
  };
652
638
 
639
+ const onGifSearch = useDebounceFn((event: Event) => {
640
+ searchResults.list = [];
641
+ onImageWallScroll(event);
642
+ }, 300);
643
+
653
644
  // update wordNumber
654
645
  watch(
655
646
  [config, wordNumber],
@@ -675,18 +666,21 @@ export default defineComponent({
675
666
  { immediate: true }
676
667
  );
677
668
 
678
- watch([showGif], async ([showGif]) => {
679
- if (!showGif) {
680
- return;
681
- }
669
+ watch(showGif, async (showGif) => {
670
+ if (!showGif) return;
671
+
672
+ const searchOptions = config.value.search as WalineSearchOptions;
673
+
674
+ // clear input
675
+ if (gifSearchInputRef.value) gifSearchInputRef.value.value = '';
676
+
677
+ searchResults.loading = true;
682
678
 
683
- gifData.value.loading = true;
684
- const data = await fetchGif({ keyword: '' }).finally(() => {
685
- gifData.value.loading = false;
686
- });
679
+ searchResults.list = searchOptions.default
680
+ ? await searchOptions.default()
681
+ : await searchOptions.search('');
687
682
 
688
- gifData.value.cursor = data.next;
689
- gifData.value.list = gifData.value.list.concat(data.results);
683
+ searchResults.loading = false;
690
684
  });
691
685
 
692
686
  onMounted(() => {
@@ -746,7 +740,7 @@ export default defineComponent({
746
740
  onLogout,
747
741
  onProfile,
748
742
  submitComment,
749
- onGifMasonryScroll,
743
+ onImageWallScroll,
750
744
  onGifSearch,
751
745
 
752
746
  isLogin,
@@ -768,6 +762,7 @@ export default defineComponent({
768
762
  showEmoji,
769
763
 
770
764
  // gif
765
+ gifData: searchResults,
771
766
  showGif,
772
767
 
773
768
  // image
@@ -786,7 +781,6 @@ export default defineComponent({
786
781
  gifPopupRef,
787
782
  imageUploadRef,
788
783
  gifSearchInputRef,
789
- gifData,
790
784
  };
791
785
  },
792
786
  });
@@ -25,7 +25,7 @@
25
25
  <span v-if="comment.label" class="wl-badge" v-text="comment.label" />
26
26
  <span v-if="comment.sticky" class="wl-badge" v-text="locale.sticky" />
27
27
  <span
28
- v-if="comment.level && comment.level >= 0"
28
+ v-if="comment.level !== undefined && comment.level >= 0"
29
29
  :class="`wl-badge level${comment.level}`"
30
30
  v-text="locale[`level${comment.level}`] || `Level ${comment.level}`"
31
31
  />
@@ -0,0 +1,166 @@
1
+ <!-- forked from https://github.com/DerYeger/vue-masonry-wall/blob/master/src/masonry-wall.vue -->
2
+
3
+ <!-- MIT License
4
+
5
+ Copyright (c) 2021 Fuxing Loh, Jan Müller
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE. -->
24
+
25
+ <template>
26
+ <div ref="wall" class="wl-gallery" :style="{ gap: `${gap}px` }">
27
+ <div
28
+ v-for="(column, columnIndex) in columns"
29
+ :key="columnIndex"
30
+ class="wl-gallery-column"
31
+ :data-index="columnIndex"
32
+ :style="{ gap: `${gap}px` }"
33
+ >
34
+ <template v-for="itemIndex in column" :key="itemIndex">
35
+ <LoadingIcon
36
+ v-if="!state[items[itemIndex].src]"
37
+ :size="36"
38
+ style="margin: 20px auto"
39
+ />
40
+ <img
41
+ class="wl-gallery-item"
42
+ :src="items[itemIndex].src"
43
+ :title="items[itemIndex].title"
44
+ loading="lazy"
45
+ @load="state[items[itemIndex].src] = true"
46
+ @click="$emit('insert', `![](${items[itemIndex].src})`)"
47
+ />
48
+ </template>
49
+ </div>
50
+ </div>
51
+ </template>
52
+
53
+ <script lang="ts">
54
+ import {
55
+ defineComponent,
56
+ nextTick,
57
+ onBeforeUnmount,
58
+ onMounted,
59
+ ref,
60
+ watch,
61
+ } from 'vue';
62
+
63
+ import { LoadingIcon } from './Icons';
64
+
65
+ import type { PropType } from 'vue';
66
+ import type { WalineSearchResult } from '../typings';
67
+
68
+ type Column = number[];
69
+
70
+ export default defineComponent({
71
+ name: 'ImageWall',
72
+
73
+ components: {
74
+ LoadingIcon,
75
+ },
76
+
77
+ props: {
78
+ items: { type: Array as PropType<WalineSearchResult[]>, default: () => [] },
79
+ columnWidth: { type: Number, default: 300 },
80
+ gap: { type: Number, default: 0 },
81
+ },
82
+
83
+ emit: ['insert'],
84
+
85
+ setup(props) {
86
+ let resizeObserver: ResizeObserver | null = null;
87
+ const wall = ref<HTMLDivElement | null>(null);
88
+ const state = ref<Record<string, boolean>>({});
89
+ const columns = ref<Column[]>([]);
90
+
91
+ const getColumnCount = (): number => {
92
+ const count = Math.floor(
93
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
94
+ (wall.value!.getBoundingClientRect().width + props.gap) /
95
+ (props.columnWidth + props.gap)
96
+ );
97
+
98
+ return count > 0 ? count : 1;
99
+ };
100
+
101
+ const createColumns = (count: number): Column[] =>
102
+ new Array(count).fill(null).map(() => []);
103
+
104
+ const fillColumns = async (itemIndex: number): Promise<void> => {
105
+ if (itemIndex >= props.items.length) return;
106
+
107
+ await nextTick();
108
+
109
+ const columnDivs = Array.from(
110
+ wall.value?.children || []
111
+ ) as HTMLDivElement[];
112
+
113
+ const target = columnDivs.reduce((prev, curr) =>
114
+ curr.getBoundingClientRect().height <
115
+ prev.getBoundingClientRect().height
116
+ ? curr
117
+ : prev
118
+ );
119
+
120
+ columns.value[Number(target.dataset.index)].push(itemIndex);
121
+
122
+ await fillColumns(itemIndex + 1);
123
+ };
124
+
125
+ const redraw = async (force = false): Promise<void> => {
126
+ if (columns.value.length === getColumnCount() && !force) return;
127
+
128
+ columns.value = createColumns(getColumnCount());
129
+
130
+ const scrollY = window.scrollY;
131
+
132
+ await fillColumns(0);
133
+
134
+ window.scrollTo({ top: scrollY });
135
+ };
136
+
137
+ watch(
138
+ () => [props.items],
139
+ () => {
140
+ state.value = {};
141
+ redraw(true);
142
+ }
143
+ );
144
+ watch(
145
+ () => [props.columnWidth, props.gap],
146
+ () => redraw()
147
+ );
148
+
149
+ onMounted(() => {
150
+ redraw(true);
151
+ resizeObserver = new ResizeObserver(() => redraw());
152
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
153
+ resizeObserver.observe(wall.value!);
154
+ });
155
+
156
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
157
+ onBeforeUnmount(() => resizeObserver!.unobserve(wall.value!));
158
+
159
+ return {
160
+ columns,
161
+ state,
162
+ wall,
163
+ };
164
+ },
165
+ });
166
+ </script>
@@ -2,7 +2,7 @@ import { useStorage } from '@vueuse/core';
2
2
 
3
3
  import type { Ref } from 'vue';
4
4
 
5
- const LIKE_KEY = 'WALIKE_LIKE';
5
+ const LIKE_KEY = 'WALINE_LIKE';
6
6
 
7
7
  export type LikeID = number | string;
8
8
 
@@ -1,4 +1,4 @@
1
- import type { WalineMeta } from '../typings';
1
+ import type { WalineMeta, WalineSearchOptions } from '../typings';
2
2
 
3
3
  const availableMeta: WalineMeta[] = ['nick', 'mail', 'link'];
4
4
 
@@ -19,3 +19,93 @@ export const defaultTexRenderer = (blockMode: boolean): string =>
19
19
  blockMode === true
20
20
  ? '<p class="wl-tex">Tex is not available in preview</p>'
21
21
  : '<span class="wl-tex">Tex is not available in preview</span>';
22
+
23
+ export const getDefaultSearchOptions = (): WalineSearchOptions => {
24
+ interface FetchGifRequest {
25
+ keyword: string;
26
+ pos?: string;
27
+ }
28
+
29
+ type GifFormat =
30
+ | 'gif'
31
+ | 'mediumgif'
32
+ | 'tinygif'
33
+ | 'nanogif'
34
+ | 'mp4'
35
+ | 'loopedmp4'
36
+ | 'tinymp4'
37
+ | 'nanomp4'
38
+ | 'webm'
39
+ | 'tinywebm'
40
+ | 'nanowebm';
41
+
42
+ interface MediaObject {
43
+ preview: string;
44
+ url: string;
45
+ dims: number[];
46
+ size: number;
47
+ }
48
+
49
+ interface GifObject {
50
+ created: number;
51
+ hasaudio: boolean;
52
+ id: string;
53
+ media: Record<GifFormat, MediaObject>[];
54
+ tags: string[];
55
+ title: string;
56
+ itemurl: string;
57
+ hascaption: boolean;
58
+ url: string;
59
+ }
60
+
61
+ interface FetchGifResponse {
62
+ next: string;
63
+ results: GifObject[];
64
+ }
65
+
66
+ const state = {
67
+ next: '',
68
+ };
69
+
70
+ const fetchGif = ({
71
+ keyword,
72
+ pos,
73
+ }: FetchGifRequest): Promise<FetchGifResponse> => {
74
+ const baseUrl = `https://g.tenor.com/v1/search`;
75
+ const query = new URLSearchParams('media_filter=minimal');
76
+ query.set('key', 'PAY5JLFIH6V6');
77
+ query.set('limit', '20');
78
+ query.set('pos', pos || '');
79
+ query.set('q', keyword);
80
+
81
+ return fetch(`${baseUrl}?${query.toString()}`, {
82
+ headers: {
83
+ // eslint-disable-next-line @typescript-eslint/naming-convention
84
+ 'Content-Type': 'application/json',
85
+ },
86
+ })
87
+ .then((resp) => resp.json() as Promise<FetchGifResponse>)
88
+ .catch(() => ({ next: pos || '', results: [] }));
89
+ };
90
+
91
+ return {
92
+ search: (word = '') =>
93
+ fetchGif({ keyword: word }).then((resp) => {
94
+ state.next = resp.next;
95
+
96
+ return resp.results.map((item) => ({
97
+ title: item.title,
98
+ src: item.media[0].tinygif.url,
99
+ }));
100
+ }),
101
+ more: (word) =>
102
+ fetchGif({ keyword: word, pos: state.next }).then((resp) => {
103
+ state.next = resp.next;
104
+
105
+ return resp.results.map((item) => ({
106
+ title: item.title,
107
+ src: item.media[0].tinygif.url,
108
+ }));
109
+ }),
110
+ };
111
+ };
package/src/init.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { createApp, h, reactive, watchEffect } from 'vue';
2
- import MasonryWall from '@yeger/vue-masonry-wall';
3
2
 
4
3
  import Waline from './components/Waline.vue';
5
4
  import { commentCount } from './comment';
@@ -81,15 +80,8 @@ export const init = ({
81
80
  ? createApp(() => h(Waline, { path: state.path, ...props }))
82
81
  : null;
83
82
 
84
- if (app) {
85
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
86
- app.use(MasonryWall);
87
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
88
- app.mount(root!);
89
- }
90
-
91
- updateCommentCount();
92
- updatePageviewCount();
83
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
84
+ if (app) app.mount(root!);
93
85
 
94
86
  const stopComment = watchEffect(updateCommentCount);
95
87
  const stopPageview = watchEffect(updatePageviewCount);
package/src/pageview.ts CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  errorHandler,
3
3
  fetchPageviews,
4
4
  getQuery,
5
+ getServerURL,
5
6
  updatePageviews,
6
7
  } from './utils';
7
8
 
@@ -83,7 +84,7 @@ export const pageviewCount = ({
83
84
 
84
85
  const fetch = (elements: HTMLElement[]): Promise<void> =>
85
86
  fetchPageviews({
86
- serverURL,
87
+ serverURL: getServerURL(serverURL),
87
88
  paths: elements.map((element) => getQuery(element) || path),
88
89
  lang,
89
90
  signal: controller.signal,
@@ -96,7 +97,11 @@ export const pageviewCount = ({
96
97
  const normalElements = elements.filter((element) => !filter(element));
97
98
  const elementsNeedstoBeFetched = elements.filter(filter);
98
99
 
99
- void updatePageviews({ serverURL, path, lang }).then((count) =>
100
+ void updatePageviews({
101
+ serverURL: getServerURL(serverURL),
102
+ path,
103
+ lang,
104
+ }).then((count) =>
100
105
  renderVisitorCount(
101
106
  new Array<number>(normalElements.length).fill(count),
102
107
  normalElements