@waline/client 2.13.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/LICENSE +339 -0
  2. package/dist/api.cjs +1 -1
  3. package/dist/api.cjs.map +1 -1
  4. package/dist/api.d.cts +302 -69
  5. package/dist/api.d.mts +302 -69
  6. package/dist/api.d.ts +302 -69
  7. package/dist/api.mjs +1 -1
  8. package/dist/api.mjs.map +1 -1
  9. package/dist/comment.cjs +1 -1
  10. package/dist/comment.cjs.map +1 -1
  11. package/dist/comment.d.cts +2 -2
  12. package/dist/comment.d.mts +2 -2
  13. package/dist/comment.d.ts +2 -2
  14. package/dist/comment.js +68 -1
  15. package/dist/comment.js.map +1 -1
  16. package/dist/comment.mjs +1 -1
  17. package/dist/comment.mjs.map +1 -1
  18. package/dist/component.mjs +1 -1
  19. package/dist/component.mjs.map +1 -1
  20. package/dist/legacy.umd.d.ts +21 -11
  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.d.cts +1 -1
  26. package/dist/pageview.d.mts +1 -1
  27. package/dist/pageview.d.ts +1 -1
  28. package/dist/pageview.js +121 -1
  29. package/dist/pageview.js.map +1 -1
  30. package/dist/pageview.mjs +1 -1
  31. package/dist/pageview.mjs.map +1 -1
  32. package/dist/shim.cjs +1 -1
  33. package/dist/shim.cjs.map +1 -1
  34. package/dist/shim.d.cts +25 -19
  35. package/dist/shim.d.mts +25 -19
  36. package/dist/shim.mjs +1 -1
  37. package/dist/shim.mjs.map +1 -1
  38. package/dist/waline.cjs +1 -1
  39. package/dist/waline.cjs.map +1 -1
  40. package/dist/waline.css +1 -1
  41. package/dist/waline.css.map +1 -1
  42. package/dist/waline.d.cts +25 -19
  43. package/dist/waline.d.mts +25 -19
  44. package/dist/waline.d.ts +25 -19
  45. package/dist/waline.js +6787 -1
  46. package/dist/waline.js.map +1 -1
  47. package/dist/waline.mjs +1 -1
  48. package/dist/waline.mjs.map +1 -1
  49. package/package.json +28 -29
  50. package/src/api/articleCounter.ts +52 -22
  51. package/src/api/comment.ts +158 -55
  52. package/src/api/commentCount.ts +24 -21
  53. package/src/api/login.ts +49 -6
  54. package/src/api/pageview.ts +26 -13
  55. package/src/api/recentComment.ts +23 -10
  56. package/src/api/user.ts +24 -18
  57. package/src/api/utils.ts +33 -10
  58. package/src/comment.ts +1 -1
  59. package/src/compact/convert.ts +1 -1
  60. package/src/components/ArticleReaction.vue +12 -3
  61. package/src/components/CommentBox.vue +37 -29
  62. package/src/components/ImageWall.vue +14 -14
  63. package/src/components/Waline.vue +59 -49
  64. package/src/config/default.ts +23 -24
  65. package/src/pageview.ts +3 -3
  66. package/src/styles/index.scss +3 -3
  67. package/src/styles/{nomalize.scss → normalize.scss} +0 -0
  68. package/src/styles/panel.scss +1 -1
  69. package/src/styles/user-list.scss +158 -0
  70. package/src/typings/base.ts +5 -1
  71. package/src/typings/comment.ts +1 -5
  72. package/src/typings/waline.ts +13 -2
  73. package/src/utils/config.ts +2 -0
  74. package/src/utils/date.ts +3 -3
  75. package/src/utils/emoji.ts +1 -1
  76. package/src/widgets/recentComments.ts +2 -2
  77. package/src/widgets/userList.ts +8 -10
  78. package/src/styles/userlist.scss +0 -116
@@ -14,9 +14,8 @@ export const defaultLang = 'zh-CN';
14
14
 
15
15
  export const defaultUploadImage = (file: File): Promise<string> =>
16
16
  new Promise((resolve, reject) => {
17
- if (file.size > 128 * 1000) {
17
+ if (file.size > 128 * 1000)
18
18
  return reject(new Error('File too large! File size limit 128KB'));
19
- }
20
19
 
21
20
  const reader = new FileReader();
22
21
 
@@ -31,43 +30,43 @@ export const defaultTexRenderer = (blockMode: boolean): string =>
31
30
  : '<span class="wl-tex">Tex is not available in preview</span>';
32
31
 
33
32
  export const getDefaultSearchOptions = (lang: string): WalineSearchOptions => {
34
- interface Result {
33
+ interface GifsResult {
34
+ data: IGif[];
35
35
  meta: {
36
36
  msg: string;
37
+ // eslint-disable-next-line @typescript-eslint/naming-convention
37
38
  response_id: string;
38
39
  status: number;
39
40
  };
40
41
  pagination: {
41
42
  count: number;
43
+ // eslint-disable-next-line @typescript-eslint/naming-convention
42
44
  total_count: number;
43
45
  offset: number;
44
46
  };
45
47
  }
46
- interface GifsResult extends Result {
47
- data: IGif[];
48
- }
49
48
 
50
49
  const fetchGiphy = async (
51
50
  url: string,
52
51
  params: Record<string, string> = {}
53
- ): Promise<WalineSearchResult> => {
54
- const querystring = new URLSearchParams({
55
- lang,
56
- limit: '20',
57
- rating: 'g',
58
- api_key: '6CIMLkNMMOhRcXPoMCPkFy4Ybk2XUiMp',
59
- ...params,
60
- }).toString();
61
-
62
- const resp = await fetch(
63
- `https://api.giphy.com/v1/gifs/${url}?${querystring}`
64
- ).then((resp) => resp.json() as Promise<GifsResult>);
65
-
66
- return resp.data.map((gif) => ({
67
- title: gif.title,
68
- src: gif.images.downsized_medium.url,
69
- }));
70
- };
52
+ ): Promise<WalineSearchResult> =>
53
+ fetch(
54
+ `https://api.giphy.com/v1/gifs/${url}?${new URLSearchParams({
55
+ lang,
56
+ limit: '20',
57
+ rating: 'g',
58
+ // eslint-disable-next-line @typescript-eslint/naming-convention
59
+ api_key: '6CIMLkNMMOhRcXPoMCPkFy4Ybk2XUiMp',
60
+ ...params,
61
+ }).toString()}`
62
+ )
63
+ .then((resp) => <Promise<GifsResult>>resp.json())
64
+ .then(({ data }) =>
65
+ data.map((gif) => ({
66
+ title: gif.title,
67
+ src: gif.images.downsized_medium.url,
68
+ }))
69
+ );
71
70
 
72
71
  return {
73
72
  search: (word: string): Promise<WalineSearchResult> =>
package/src/pageview.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { fetchPageviews, updatePageviews } from './api';
1
+ import { getPageview, updatePageview } from './api';
2
2
  import { errorHandler, getQuery, getServerURL } from './utils';
3
3
 
4
4
  import type { WalineAbort } from './typings';
@@ -78,7 +78,7 @@ export const pageviewCount = ({
78
78
  };
79
79
 
80
80
  const fetch = (elements: HTMLElement[]): Promise<void> =>
81
- fetchPageviews({
81
+ getPageview({
82
82
  serverURL: getServerURL(serverURL),
83
83
  paths: elements.map((element) => getQuery(element) || path),
84
84
  lang,
@@ -92,7 +92,7 @@ export const pageviewCount = ({
92
92
  const normalElements = elements.filter((element) => !filter(element));
93
93
  const elementsNeedstoBeFetched = elements.filter(filter);
94
94
 
95
- void updatePageviews({
95
+ void updatePageview({
96
96
  serverURL: getServerURL(serverURL),
97
97
  path,
98
98
  lang,
@@ -1,5 +1,5 @@
1
1
  @use 'config';
2
- @use 'nomalize';
2
+ @use 'normalize';
3
3
 
4
4
  @use 'base';
5
5
 
@@ -9,9 +9,9 @@
9
9
 
10
10
  @use 'card';
11
11
  @use 'layout';
12
+ @use 'reaction';
12
13
 
13
14
  @use 'highlight';
14
15
 
15
16
  @use 'recent';
16
- @use 'userlist';
17
- @use 'reaction';
17
+ @use 'user-list';
File without changes
@@ -242,7 +242,7 @@
242
242
  color: var(--waline-theme-color);
243
243
  }
244
244
 
245
- &.actived {
245
+ &.active {
246
246
  color: var(--waline-active-color);
247
247
  }
248
248
  }
@@ -0,0 +1,158 @@
1
+ .wl-user-list {
2
+ padding: 0;
3
+ list-style: none;
4
+
5
+ .wl-user-item {
6
+ margin: 10px 0;
7
+
8
+ &:nth-child(1) .wl-user-badge {
9
+ background: var(--waline-rank-gold-bgcolor, #fa3939);
10
+ color: var(--waline-white);
11
+ font-weight: bold;
12
+ }
13
+
14
+ &:nth-child(2) .wl-user-badge {
15
+ background: var(--waline-rank-silver-bgcolor, #fb811c);
16
+ color: var(--waline-white);
17
+ font-weight: bold;
18
+ }
19
+
20
+ &:nth-child(3) .wl-user-badge {
21
+ background: var(--waline-rank-copper-bgcolor, #feb207);
22
+ color: var(--waline-white);
23
+ }
24
+ }
25
+
26
+ a,
27
+ a:hover,
28
+ a:visited {
29
+ color: var(--waline-color);
30
+ text-decoration: none;
31
+ }
32
+
33
+ .wl-user-avatar {
34
+ position: relative;
35
+
36
+ display: inline-block;
37
+
38
+ overflow: hidden;
39
+
40
+ margin-right: 10px;
41
+ border-radius: 4px;
42
+
43
+ line-height: 0;
44
+
45
+ > img {
46
+ width: var(--waline-user-avatar-size, 48px);
47
+ height: var(--waline-user-avatar-size, 48px);
48
+ }
49
+ }
50
+
51
+ .wl-user-badge {
52
+ position: absolute;
53
+ right: 0;
54
+ bottom: 0;
55
+
56
+ min-width: 0.7em;
57
+ height: 1.5em;
58
+ padding: 0 0.4em;
59
+ border-radius: 4px;
60
+
61
+ background: var(--waline-info-bgcolor);
62
+ color: var(--waline-info-color);
63
+
64
+ font-weight: bold;
65
+ font-size: 10px;
66
+ line-height: 1.5em;
67
+ text-align: center;
68
+ }
69
+
70
+ .wl-user-meta {
71
+ display: inline-block;
72
+ vertical-align: top;
73
+ }
74
+
75
+ .wl-badge {
76
+ display: inline-block;
77
+ vertical-align: text-top;
78
+
79
+ margin-left: 0.5em;
80
+ padding: 0 0.3em;
81
+ border: 1px solid var(--waline-badge-color);
82
+ border-radius: 4px;
83
+
84
+ color: var(--waline-badge-color);
85
+
86
+ font-size: var(--waline-badge-font-size);
87
+ }
88
+ }
89
+
90
+ .wl-user-wall {
91
+ padding: 0;
92
+ list-style: none;
93
+
94
+ .wl-user-item {
95
+ position: relative;
96
+ display: inline-block;
97
+ transition: transform ease-in-out 0.2s;
98
+
99
+ &::before,
100
+ &::after {
101
+ position: absolute;
102
+ bottom: 100%;
103
+ left: 50%;
104
+ z-index: 10;
105
+
106
+ opacity: 0;
107
+ pointer-events: none;
108
+
109
+ transition: all 0.18s ease-out 0.18s;
110
+ transform: translate(-50%, 4px);
111
+ transform-origin: top;
112
+ }
113
+
114
+ &::before {
115
+ content: '';
116
+
117
+ width: 0;
118
+ height: 0;
119
+ border: 5px solid transparent;
120
+ border-top-color: rgb(16 16 16 / 95%);
121
+ }
122
+
123
+ &::after {
124
+ content: attr(aria-label);
125
+
126
+ margin-bottom: 10px;
127
+ padding: 0.5em 1em;
128
+ border-radius: 2px;
129
+
130
+ background: rgb(16 16 16 / 95%);
131
+ color: #fff;
132
+
133
+ font-size: 12px;
134
+ white-space: nowrap;
135
+ }
136
+
137
+ &:hover {
138
+ transform: scale(1.1);
139
+
140
+ &::before,
141
+ &::after {
142
+ opacity: 1;
143
+ pointer-events: none;
144
+ transform: translate(-50%, 0);
145
+ }
146
+ }
147
+
148
+ img {
149
+ width: var(--waline-user-avatar-size, 48px);
150
+ height: var(--waline-user-avatar-size, 48px);
151
+ }
152
+ }
153
+
154
+ .wl-user-badge,
155
+ .wl-user-meta {
156
+ display: none;
157
+ }
158
+ }
@@ -1,3 +1,5 @@
1
+ export type WalineCommentSorting = 'latest' | 'oldest' | 'hottest';
2
+
1
3
  export interface WalineEmojiInfo {
2
4
  /**
3
5
  * 选项卡上的 Emoji 名称
@@ -39,6 +41,8 @@ export interface WalineEmojiInfo {
39
41
 
40
42
  export type WalineEmojiMaps = Record<string, string>;
41
43
 
44
+ export type WalineLoginStatus = 'enable' | 'disable' | 'force';
45
+
42
46
  export interface WalineSearchImageData extends Record<string, unknown> {
43
47
  /**
44
48
  * 图片链接
@@ -102,7 +106,7 @@ export interface WalineSearchOptions {
102
106
  *
103
107
  * @default (word) => search(word)
104
108
  */
105
- more?: (word: string, currectCount: number) => Promise<WalineSearchResult>;
109
+ more?: (word: string, currentCount: number) => Promise<WalineSearchResult>;
106
110
  }
107
111
 
108
112
  export type WalineMeta = 'nick' | 'mail' | 'link';
@@ -40,15 +40,11 @@ export interface WalineCommentData {
40
40
  */
41
41
  at?: string;
42
42
 
43
- /**
44
- * edit comment id
45
- */
46
- eid?: string;
47
-
48
43
  /**
49
44
  * Comment link
50
45
  */
51
46
  url: string;
47
+
52
48
  /**
53
49
  * Recaptcha Token
54
50
  */
@@ -1,7 +1,9 @@
1
1
  import type {
2
+ WalineCommentSorting,
2
3
  WalineHighlighter,
3
4
  WalineEmojiInfo,
4
5
  WalineImageUploader,
6
+ WalineLoginStatus,
5
7
  WalineMeta,
6
8
  WalineTexRenderer,
7
9
  WalineSearchOptions,
@@ -129,6 +131,15 @@ export interface WalineProps {
129
131
  */
130
132
  locale?: Partial<WalineLocale>;
131
133
 
134
+ /**
135
+ * 评论列表排序方式
136
+ *
137
+ * Sorting method for comment list
138
+ *
139
+ * @default 'latest'
140
+ */
141
+ commentSorting?: WalineCommentSorting;
142
+
132
143
  /**
133
144
  * 是否启用暗黑模式适配
134
145
  *
@@ -194,12 +205,12 @@ export interface WalineProps {
194
205
  * Login mode status, optional values:
195
206
  *
196
207
  * - `'enable'`: enable login (default)
197
- * - `'disable'`: Login is disabled, users should fill in infomation to comment
208
+ * - `'disable'`: Login is disabled, users should fill in information to comment
198
209
  * - `'force'`: Forced login, users must login to comment
199
210
  *
200
211
  * @default 'enable'
201
212
  */
202
- login?: 'enable' | 'disable' | 'force';
213
+ login?: WalineLoginStatus;
203
214
 
204
215
  /**
205
216
  * 是否在页脚展示版权信息
@@ -67,6 +67,7 @@ export const getConfig = ({
67
67
  search,
68
68
  reaction,
69
69
  recaptchaV3Key = '',
70
+ commentSorting = 'latest',
70
71
  ...more
71
72
  }: WalineProps): WalineConfig => ({
72
73
  serverURL: getServerURL(serverURL),
@@ -94,5 +95,6 @@ export const getConfig = ({
94
95
  : reaction === true
95
96
  ? defaultReaction
96
97
  : [],
98
+ commentSorting,
97
99
  ...more,
98
100
  });
package/src/utils/date.ts CHANGED
@@ -30,15 +30,15 @@ export const getTimeAgo = (
30
30
  ? new Date(date.indexOf(' ') !== -1 ? date.replace(/-/g, '/') : date)
31
31
  : date;
32
32
 
33
- const timepassed = now.getTime() - time.getTime();
33
+ const timePassed = now.getTime() - time.getTime();
34
34
 
35
- const days = Math.floor(timepassed / (24 * 3600 * 1000));
35
+ const days = Math.floor(timePassed / (24 * 3600 * 1000));
36
36
 
37
37
  if (days === 0) {
38
38
  // 计算相差小时数
39
39
 
40
40
  // 计算天数后剩余的毫秒数
41
- const leave1 = timepassed % (24 * 3600 * 1000);
41
+ const leave1 = timePassed % (24 * 3600 * 1000);
42
42
  const hours = Math.floor(leave1 / (3600 * 1000));
43
43
 
44
44
  if (hours === 0) {
@@ -22,7 +22,7 @@ const fetchEmoji = (link: string): Promise<WalineEmojiInfo> => {
22
22
  }
23
23
 
24
24
  return fetch(`${link}/info.json`)
25
- .then((resp) => resp.json() as Promise<Omit<WalineEmojiInfo, 'folder'>>)
25
+ .then((resp) => <Promise<Omit<WalineEmojiInfo, 'folder'>>>resp.json())
26
26
  .then((emojiInfo) => {
27
27
  const info = {
28
28
  folder: link,
@@ -1,4 +1,4 @@
1
- import { fetchRecentComment } from '../api';
1
+ import { getRecentComment } from '../api';
2
2
  import { useUserInfo } from '../composables';
3
3
  import { getRoot } from '../utils';
4
4
 
@@ -62,7 +62,7 @@ export const RecentComments = ({
62
62
  const root = getRoot(el);
63
63
  const controller = new AbortController();
64
64
 
65
- return fetchRecentComment({
65
+ return getRecentComment({
66
66
  serverURL,
67
67
  count,
68
68
  lang,
@@ -1,4 +1,4 @@
1
- import { fetchUserList, WalineUser } from '../api';
1
+ import { getUserList, WalineUser } from '../api';
2
2
  import { defaultLang, defaultLocales } from '../config';
3
3
  import { WalineLocale } from '../typings';
4
4
  import { getRoot } from '../utils';
@@ -80,18 +80,17 @@ export const UserList = ({
80
80
  const root = getRoot(el);
81
81
  const controller = new AbortController();
82
82
 
83
- return fetchUserList({
83
+ return getUserList({
84
84
  serverURL,
85
85
  pageSize: count,
86
86
  lang,
87
87
  signal: controller.signal,
88
88
  }).then((users) => {
89
- if (!root || !users.length) {
89
+ if (!root || !users.length)
90
90
  return {
91
91
  users,
92
92
  destroy: (): void => controller.abort(),
93
93
  };
94
- }
95
94
 
96
95
  locale = {
97
96
  ...(defaultLocales[lang] || defaultLocales[defaultLang]),
@@ -101,23 +100,22 @@ export const UserList = ({
101
100
  root.innerHTML = `<ul class="wl-user-${mode}">${users
102
101
  .map((user, index) =>
103
102
  [
104
- '<li class="wl-user-item">',
103
+ `<li class="wl-user-item" aria-label="${user.nick}">`,
105
104
  user.link && `<a href="${user.link}" target="_blank">`,
106
105
  '<div class="wl-user-avatar">',
107
106
  `<img src="${user.avatar}" alt="${user.nick}">`,
108
- `<i>${index + 1}</i>`,
107
+ `<span class="wl-user-badge">${index + 1}</span>`,
109
108
  '</div>',
110
109
  '<div class="wl-user-meta">',
111
- `<div class="wl-user-name"><div>${user.nick}</div>`,
112
- '<div class="wl-user-tag wl-card">',
110
+ '<div class="wl-user-name">',
111
+ user.nick,
113
112
  user.level &&
114
113
  `<span class="wl-badge">${
115
114
  locale ? locale[`level${user.level}`] : `Level ${user.level}`
116
115
  }</span>`,
117
116
  user.label && `<span class="wl-badge">${user.label}</span>`,
118
117
  '</div>',
119
- '</div>',
120
- user.link && `<span class="wl-user-meta">${user.link}</span>`,
118
+ user.link && user.link,
121
119
  '</div>',
122
120
  user.link && '</a>',
123
121
  '</li>',
@@ -1,116 +0,0 @@
1
- :root {
2
- --waline-rank-gold-bgcolor: #FA3939;
3
- --waline-rank-silver-bgcolor: #FB811C;
4
- --waline-rank-copper-bgcolor: #FEB207;
5
- }
6
-
7
- .wl-user-list {
8
- list-style: none;
9
- padding: 0;
10
-
11
- > li + li {
12
- margin-top: 10px;
13
- }
14
-
15
- > li, > li > a {
16
- display: flex;
17
- flex-direction: row;
18
- gap: 10px;
19
- }
20
-
21
- a,
22
- a:hover,
23
- a:visited {
24
- text-decoration: none;
25
- color: var(--waline-color);
26
- }
27
-
28
- .wl-user-avatar {
29
- position: relative;
30
- line-height: 0;
31
-
32
- > i {
33
- position: absolute;
34
- bottom: 0;
35
- right: 0;
36
- min-width: 1.5em;
37
- height: 1.5em;
38
- line-height: 1.5em;
39
- background: var(--waline-info-bgcolor);
40
- text-align: center;
41
- font-size: 10px;
42
- border-radius: 2px;
43
- font-style: normal;
44
- color: var(--waline-info-color);
45
- }
46
- }
47
-
48
- img {
49
- width: 48px;
50
- height: 48px;
51
- border-radius: 2px;
52
- }
53
-
54
- .wl-user-name {
55
- display: flex;
56
- flex-direction: row;
57
- align-items: center;
58
- gap: 10px;
59
- }
60
- .wl-user-tag {
61
- padding-bottom: 0;
62
- border-bottom: none;
63
- width: auto;
64
- }
65
-
66
-
67
- > li:nth-child(1) i {
68
- background: var(--waline-rank-gold-bgcolor);
69
- color: var(--waline-white);
70
- font-weight: bold;
71
- }
72
-
73
- > li:nth-child(2) i {
74
- background: var(--waline-rank-silver-bgcolor);
75
- color: var(--waline-white);
76
- font-weight: bold;
77
- }
78
-
79
- > li:nth-child(3) i {
80
- background: var(--waline-rank-copper-bgcolor);
81
- color: var(--waline-white);
82
- font-weight: bold;
83
- }
84
- }
85
-
86
- .wl-user-wall {
87
- display: flex;
88
- flex-direction: row;
89
- list-style: none;
90
- padding: 0;
91
-
92
- > li {
93
- width: 48px;
94
- height: 48px;
95
- overflow: hidden;
96
- }
97
-
98
- > li:hover img {
99
- transform: scale(1.25);
100
- }
101
-
102
- img {
103
- width: 48px;
104
- height: 48px;
105
- border-radius: 0;
106
- transition: transform ease-in-out 400ms;
107
- }
108
-
109
- .wl-user-avatar > i,
110
- .wl-user-meta {
111
- display: none;
112
- }
113
- }
114
-
115
-
116
-