@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
@@ -1,118 +1,136 @@
1
- @mixin emoji() {
2
- .wl-emoji-popup {
3
- position: absolute;
4
- top: 100%;
5
- left: 1.25em;
6
- z-index: 10;
7
-
8
- max-width: 526px;
9
- border: var(--waline-border);
10
- border-radius: 6px;
11
-
12
- background: var(--waline-bgcolor);
13
- box-shadow: var(--waline-box-shadow);
14
-
15
- opacity: 0;
16
- visibility: hidden;
17
-
18
- transition: transform 0.2s ease-out, opacity 0.2s ease-out;
19
- transform: scale(0.9, 0.9);
20
- transform-origin: 0 0;
21
-
22
- &.display {
23
- opacity: 1;
24
- visibility: visible;
25
- transform: none;
26
- }
1
+ .wl-emoji-popup {
2
+ position: absolute;
3
+ top: 100%;
4
+ left: 1.25em;
5
+ z-index: 10;
6
+
7
+ max-width: 526px;
8
+ border: var(--waline-border);
9
+ border-radius: 6px;
10
+
11
+ background: var(--waline-bgcolor);
12
+ box-shadow: var(--waline-box-shadow);
13
+
14
+ opacity: 0;
15
+ visibility: hidden;
16
+
17
+ transition: transform 0.2s ease-out, opacity 0.2s ease-out;
18
+ transform: scale(0.9, 0.9);
19
+ transform-origin: 0 0;
20
+
21
+ &.display {
22
+ opacity: 1;
23
+ visibility: visible;
24
+ transform: none;
25
+ }
26
+
27
+ button {
28
+ display: inline-block;
29
+ vertical-align: middle;
30
+
31
+ width: 2em;
32
+ margin: 0.125em;
33
+ padding: 0;
34
+ border-width: 0;
27
35
 
28
- button {
29
- display: inline-block;
30
- vertical-align: middle;
36
+ background: transparent;
31
37
 
32
- width: 2em;
33
- margin: 0.125em;
34
- padding: 0;
35
- border-width: 0;
38
+ font-size: inherit;
39
+ line-height: 2;
40
+ text-align: center;
36
41
 
37
- background: transparent;
42
+ cursor: pointer;
38
43
 
39
- font-size: inherit;
40
- line-height: 2;
41
- text-align: center;
44
+ &:hover {
45
+ background: var(--waline-bgcolor-hover);
46
+ }
47
+ }
48
+
49
+ .wl-emoji {
50
+ display: inline-block;
51
+ vertical-align: middle;
52
+ max-width: 1.5em;
53
+ max-height: 1.5em;
54
+ }
42
55
 
43
- cursor: pointer;
56
+ .wl-tab-wrapper {
57
+ overflow-y: auto;
58
+ max-height: 145px;
59
+ padding: 0.5em;
44
60
 
45
- &:hover {
46
- background: var(--waline-bgcolor-hover);
47
- }
61
+ &::-webkit-scrollbar {
62
+ width: 6px;
63
+ height: 6px;
48
64
  }
49
65
 
50
- .wl-emoji {
51
- display: inline-block;
52
- vertical-align: middle;
53
- max-width: 1.5em;
54
- max-height: 1.5em;
66
+ &::-webkit-scrollbar-track-piece:vertical {
67
+ -webkit-border-radius: 6px;
68
+ border-radius: 6px;
69
+ background: rgb(0 0 0 / 10%);
55
70
  }
56
71
 
57
- .wl-tab-wrapper {
58
- overflow-y: auto;
59
- max-height: 145px;
60
- padding: 0.5em;
61
-
62
- &::-webkit-scrollbar {
63
- width: 6px;
64
- height: 6px;
65
- }
66
-
67
- &::-webkit-scrollbar-track-piece:vertical {
68
- -webkit-border-radius: 6px;
69
- border-radius: 6px;
70
- background: rgb(0 0 0 / 10%);
71
- }
72
-
73
- &::-webkit-scrollbar-thumb:vertical {
74
- width: 6px;
75
- -webkit-border-radius: 6px;
76
- border-radius: 6px;
77
- background: var(--waline-theme-color);
78
- }
72
+ &::-webkit-scrollbar-thumb:vertical {
73
+ width: 6px;
74
+ -webkit-border-radius: 6px;
75
+ border-radius: 6px;
76
+ background: var(--waline-theme-color);
79
77
  }
78
+ }
79
+
80
+ .wl-tabs {
81
+ position: relative;
82
+ height: 2em;
83
+ padding: 0 6px 1px;
84
+ overflow-x: scroll;
85
+ white-space: nowrap;
86
+
87
+ &::before {
88
+ content: ' ';
89
+
90
+ position: absolute;
91
+ top: 0;
92
+ right: 0;
93
+ left: 0;
94
+ z-index: 2;
80
95
 
81
- .wl-tabs {
82
- position: relative;
83
- height: 2em;
84
- padding: 0 6px 1px;
96
+ height: 1px;
85
97
 
86
- &::before {
87
- content: ' ';
98
+ background: var(--waline-border-color);
99
+ }
88
100
 
89
- position: absolute;
90
- top: 0;
91
- right: 0;
92
- left: 0;
93
- z-index: 2;
101
+ &::-webkit-scrollbar {
102
+ width: 6px;
103
+ height: 6px;
104
+ }
94
105
 
95
- height: 1px;
106
+ &::-webkit-scrollbar-track-piece:horizontal {
107
+ -webkit-border-radius: 6px;
108
+ border-radius: 6px;
109
+ background: rgb(0 0 0 / 10%);
110
+ }
96
111
 
97
- background: var(--waline-border-color);
98
- }
112
+ &::-webkit-scrollbar-thumb:horizontal {
113
+ height: 6px;
114
+ -webkit-border-radius: 6px;
115
+ border-radius: 6px;
116
+ background: var(--waline-theme-color);
99
117
  }
118
+ }
100
119
 
101
- .wl-tab {
102
- position: relative;
103
- margin: 0;
104
- padding: 0 0.5em;
120
+ .wl-tab {
121
+ position: relative;
122
+ margin: 0;
123
+ padding: 0 0.5em;
105
124
 
106
- &.active {
107
- z-index: 3;
125
+ &.active {
126
+ z-index: 3;
108
127
 
109
- border: 1px solid var(--waline-border-color);
110
- border-top-width: 0;
111
- border-bottom-right-radius: 6px;
112
- border-bottom-left-radius: 6px;
128
+ border: 1px solid var(--waline-border-color);
129
+ border-top-width: 0;
130
+ border-bottom-right-radius: 6px;
131
+ border-bottom-left-radius: 6px;
113
132
 
114
- background: var(--waline-bgcolor);
115
- }
133
+ background: var(--waline-bgcolor);
116
134
  }
117
135
  }
118
136
  }
@@ -1,151 +1,70 @@
1
- @mixin gif() {
2
- .wl-gif-popup {
3
- position: absolute;
4
- top: 100%;
5
- left: 1.25em;
6
- z-index: 10;
7
-
8
- width: 436px;
9
- padding: 12px 12px 4px;
10
- border: var(--waline-border);
11
- border-radius: 6px;
12
-
13
- background: var(--waline-bgcolor);
14
- box-shadow: var(--waline-box-shadow);
15
-
16
- opacity: 0;
17
- visibility: hidden;
18
-
19
- transition: transform 0.2s ease-out, opacity 0.2s ease-out;
20
- transform: scale(0.9, 0.9);
21
- transform-origin: 0 0;
22
-
23
- &.display {
24
- opacity: 1;
25
- visibility: visible;
26
- transform: none;
27
- }
28
-
29
- input {
30
- box-sizing: border-box;
31
-
32
- width: 100%;
33
- margin-bottom: 10px;
34
- padding: 3px 5px;
35
- border: var(--waline-border);
36
- }
37
-
38
- img {
39
- display: block;
40
-
41
- box-sizing: border-box;
42
-
43
- width: 100%;
44
- border-width: 2px;
45
- border-style: solid;
46
- border-color: #fff;
47
-
48
- cursor: pointer;
49
-
50
- &:hover {
51
- border-color: var(--waline-theme-color);
52
- border-radius: 2px;
53
- }
54
- }
55
-
56
- .wl-gif-waterfall {
57
- overflow-y: auto;
58
- max-height: 800px;
59
- }
60
-
61
- button {
62
- display: inline-block;
63
- vertical-align: middle;
64
-
65
- width: 2em;
66
- margin: 0.125em;
67
- padding: 0;
68
- border-width: 0;
69
-
70
- background: transparent;
71
-
72
- font-size: inherit;
73
- line-height: 2;
74
- text-align: center;
75
-
76
- cursor: pointer;
77
-
78
- &:hover {
79
- background: var(--waline-bgcolor-hover);
80
- }
81
- }
82
-
83
- .wl-gif {
84
- display: inline-block;
85
- vertical-align: middle;
86
- max-width: 1.5em;
87
- max-height: 1.5em;
88
- }
89
-
90
- .wl-tab-wrapper {
91
- overflow-y: auto;
92
- max-height: 145px;
93
- padding: 0.5em;
94
-
95
- &::-webkit-scrollbar {
96
- width: 6px;
97
- height: 6px;
98
- }
1
+ .wl-gif-popup {
2
+ position: absolute;
3
+ top: 100%;
4
+ left: 1.25em;
5
+ z-index: 10;
6
+
7
+ width: calc(100% - 3em);
8
+ padding: 0.75em 0.75em 0.25em;
9
+ border: var(--waline-border);
10
+ border-radius: 6px;
11
+
12
+ background: var(--waline-bgcolor);
13
+ box-shadow: var(--waline-box-shadow);
14
+
15
+ opacity: 0;
16
+ visibility: hidden;
17
+
18
+ transition: transform 0.2s ease-out, opacity 0.2s ease-out;
19
+ transform: scale(0.9, 0.9);
20
+ transform-origin: 0 0;
21
+
22
+ &.display {
23
+ opacity: 1;
24
+ visibility: visible;
25
+ transform: none;
26
+ }
99
27
 
100
- &::-webkit-scrollbar-track-piece:vertical {
101
- -webkit-border-radius: 6px;
102
- border-radius: 6px;
103
- background: rgb(0 0 0 / 10%);
104
- }
28
+ input {
29
+ box-sizing: border-box;
105
30
 
106
- &::-webkit-scrollbar-thumb:vertical {
107
- width: 6px;
108
- -webkit-border-radius: 6px;
109
- border-radius: 6px;
110
- background: var(--waline-theme-color);
111
- }
112
- }
31
+ width: 100%;
32
+ margin-bottom: 10px;
33
+ padding: 3px 5px;
34
+ border: var(--waline-border);
35
+ }
113
36
 
114
- .wl-tabs {
115
- position: relative;
116
- height: 2em;
117
- padding: 0 6px 1px;
37
+ img {
38
+ display: block;
118
39
 
119
- &::before {
120
- content: ' ';
40
+ box-sizing: border-box;
121
41
 
122
- position: absolute;
123
- top: 0;
124
- right: 0;
125
- left: 0;
126
- z-index: 2;
42
+ width: 100%;
43
+ border-width: 2px;
44
+ border-style: solid;
45
+ border-color: #fff;
127
46
 
128
- height: 1px;
47
+ cursor: pointer;
129
48
 
130
- background: var(--waline-border-color);
131
- }
49
+ &:hover {
50
+ border-color: var(--waline-theme-color);
51
+ border-radius: 2px;
132
52
  }
53
+ }
54
+ }
133
55
 
134
- .wl-tab {
135
- position: relative;
136
- margin: 0;
137
- padding: 0 0.5em;
138
-
139
- &.active {
140
- z-index: 3;
56
+ .wl-gallery {
57
+ max-height: 80vh;
58
+ display: flex;
59
+ overflow-y: auto;
60
+ }
141
61
 
142
- border: 1px solid var(--waline-border-color);
143
- border-top-width: 0;
144
- border-bottom-right-radius: 6px;
145
- border-bottom-left-radius: 6px;
62
+ .wl-gallery-column {
63
+ height: -webkit-max-content;
64
+ height: -moz-max-content;
65
+ height: max-content;
146
66
 
147
- background: var(--waline-bgcolor);
148
- }
149
- }
150
- }
67
+ flex: 1;
68
+ display: flex;
69
+ flex-direction: column;
151
70
  }
@@ -4,6 +4,9 @@
4
4
  @use 'base';
5
5
 
6
6
  @use 'panel';
7
+ @use 'emoji';
8
+ @use 'gif';
9
+
7
10
  @use 'card';
8
11
  @use 'layout';
9
12
 
@@ -1,6 +1,3 @@
1
- @use 'emoji';
2
- @use 'gif';
3
-
4
1
  .wl-comment {
5
2
  position: relative;
6
3
  display: flex;
@@ -287,6 +284,3 @@
287
284
  }
288
285
  }
289
286
  }
290
-
291
- @include emoji.emoji;
292
- @include gif.gif;
@@ -39,6 +39,46 @@ export interface WalineEmojiInfo {
39
39
 
40
40
  export type WalineEmojiMaps = Record<string, string>;
41
41
 
42
+ export interface WalineSearchResult extends Record<string, unknown> {
43
+ /**
44
+ * Image link
45
+ */
46
+ src: string;
47
+
48
+ /**
49
+ * Image title, optional
50
+ */
51
+ title?: string;
52
+
53
+ /**
54
+ * Image preview link, optional
55
+ *
56
+ * @default src
57
+ */
58
+ preview?: string;
59
+ }
60
+
61
+ export interface WalineSearchOptions {
62
+ /**
63
+ * Search action
64
+ */
65
+ search: (word: string) => Promise<WalineSearchResult[]>;
66
+
67
+ /**
68
+ * Default search action
69
+ *
70
+ * @default () => search('')
71
+ */
72
+ default?: () => Promise<WalineSearchResult[]>;
73
+
74
+ /**
75
+ * Fetch more action
76
+ *
77
+ * @default (word) => search(word)
78
+ */
79
+ more?: (word: string, currectCount: number) => Promise<WalineSearchResult[]>;
80
+ }
81
+
42
82
  export type WalineMeta = 'nick' | 'mail' | 'link';
43
83
 
44
84
  export type WalineImageUploader = (image: File) => Promise<string>;
@@ -4,6 +4,7 @@ import type {
4
4
  WalineImageUploader,
5
5
  WalineMeta,
6
6
  WalineTexRenderer,
7
+ WalineSearchOptions,
7
8
  } from './base';
8
9
  import type { WalineLocale } from './locale';
9
10
 
@@ -148,6 +149,13 @@ export interface WalineProps {
148
149
  */
149
150
  emoji?: (string | WalineEmojiInfo)[] | false;
150
151
 
152
+ /**
153
+ * 设置搜索功能
154
+ *
155
+ * Customize Search feature
156
+ */
157
+ search?: WalineSearchOptions | false;
158
+
151
159
  /**
152
160
  * 代码高亮
153
161
  *
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  defaultLang,
3
+ defaultLocales,
3
4
  defaultUploadImage,
4
5
  defaultHighlighter,
5
6
  defaultTexRenderer,
7
+ getDefaultSearchOptions,
6
8
  getMeta,
7
- defaultLocales,
8
9
  } from '../config';
9
10
 
10
11
  import { decodePath, isLinkHttp, removeEndingSplash } from './path';
@@ -27,7 +28,7 @@ export interface WalineConfig extends Required<Omit<WalineProps, 'wordLimit'>> {
27
28
  // emoji: Promise<EmojiConfig>;
28
29
  }
29
30
 
30
- const getServerURL = (serverURL: string): string => {
31
+ export const getServerURL = (serverURL: string): string => {
31
32
  const result = removeEndingSplash(serverURL);
32
33
 
33
34
  return isLinkHttp(result) ? result : `https://${result}`;
@@ -61,6 +62,7 @@ export const getConfig = ({
61
62
  texRenderer,
62
63
  copyright = true,
63
64
  login = 'enable',
65
+ search = getDefaultSearchOptions(),
64
66
  ...more
65
67
  }: WalineProps): WalineConfig => ({
66
68
  serverURL: getServerURL(serverURL),
@@ -81,5 +83,6 @@ export const getConfig = ({
81
83
  pageSize,
82
84
  login,
83
85
  copyright,
86
+ search,
84
87
  ...more,
85
88
  });
@@ -10,5 +10,3 @@ export * from './markdown';
10
10
  export * from './path';
11
11
  export * from './query';
12
12
  export * from './wordCount';
13
- export * from './fetchGif';
14
- export * from './throttle';
@@ -1,62 +0,0 @@
1
- export type GifFormat =
2
- | 'gif'
3
- | 'mediumgif'
4
- | 'tinygif'
5
- | 'nanogif'
6
- | 'mp4'
7
- | 'loopedmp4'
8
- | 'tinymp4'
9
- | 'nanomp4'
10
- | 'webm'
11
- | 'tinywebm'
12
- | 'nanowebm';
13
- export interface MediaObject {
14
- preview: string;
15
- url: string;
16
- dims: number[];
17
- size: number;
18
- }
19
-
20
- export interface FetchGifRequest {
21
- key?: string;
22
- keyword: string;
23
- pos?: string;
24
- limit?: number;
25
- }
26
-
27
- export interface GifObject {
28
- created: number;
29
- hasaudio: boolean;
30
- id: string;
31
- media: Record<GifFormat, MediaObject>[];
32
- tags: string[];
33
- title: string;
34
- itemurl: string;
35
- hascaption: boolean;
36
- url: string;
37
- }
38
-
39
- export interface FetchGifResponse {
40
- next: string;
41
- results: GifObject[];
42
- }
43
-
44
- export const fetchGif = ({
45
- key,
46
- keyword,
47
- pos,
48
- limit,
49
- }: FetchGifRequest): Promise<FetchGifResponse> => {
50
- const baseUrl = `https://g.tenor.com/v1/search`;
51
- const query = new URLSearchParams('media_filter=minimal');
52
- query.set('key', key || 'PAY5JLFIH6V6');
53
- query.set('limit', (limit || 20).toString());
54
- query.set('pos', pos || '');
55
- query.set('q', keyword);
56
-
57
- return fetch(`${baseUrl}?${query.toString()}`, {
58
- headers: {
59
- 'Content-Type': 'application/json',
60
- },
61
- }).then((resp) => resp.json() as Promise<FetchGifResponse>);
62
- };
@@ -1,16 +0,0 @@
1
- export function throttle(
2
- func: (...args: any[]) => void,
3
- timeout = 300
4
- ): (...args: []) => void {
5
- let timer: number | null;
6
- return (...args: []): void => {
7
- if (timer) {
8
- clearTimeout(timer);
9
- }
10
-
11
- timer = window.setTimeout(() => {
12
- func(...args);
13
- timer = null;
14
- }, timeout);
15
- };
16
- }