artalk 2.5.0 → 2.5.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 (50) hide show
  1. package/dist/Artalk.css +1 -1
  2. package/dist/Artalk.es.js +3177 -3165
  3. package/dist/Artalk.iife.js +1 -1
  4. package/dist/Artalk.js +1 -1
  5. package/dist/ArtalkLite.css +1 -1
  6. package/dist/ArtalkLite.es.js +3186 -3174
  7. package/dist/ArtalkLite.iife.js +1 -1
  8. package/dist/ArtalkLite.js +1 -1
  9. package/dist/i18n/jp.js +1 -1
  10. package/dist/i18n/zh-TW.js +1 -1
  11. package/dist/src/api/user.d.ts +1 -1
  12. package/dist/src/context.d.ts +1 -0
  13. package/dist/src/i18n/external.d.ts +70 -0
  14. package/dist/src/i18n/index.d.ts +0 -68
  15. package/dist/src/lib/checker/index.d.ts +0 -2
  16. package/dist/src/lib/user.d.ts +6 -3
  17. package/dist/src/list/list-ui.d.ts +9 -0
  18. package/dist/src/list/list.d.ts +0 -1
  19. package/dist/src/service.d.ts +8 -2
  20. package/dist/types/context.d.ts +3 -4
  21. package/package.json +1 -1
  22. package/src/api/comment.ts +7 -7
  23. package/src/api/page.ts +0 -2
  24. package/src/api/request.ts +6 -4
  25. package/src/api/upload.ts +3 -4
  26. package/src/api/user.ts +9 -9
  27. package/src/artalk.ts +5 -3
  28. package/src/context.ts +4 -2
  29. package/src/editor/edit-mode.ts +2 -1
  30. package/src/editor/editor.ts +2 -1
  31. package/src/editor/funcs.ts +3 -2
  32. package/src/editor/plugs/header-input-plug.ts +7 -6
  33. package/src/editor/plugs/upload-plug.ts +2 -1
  34. package/src/editor/submit.ts +2 -1
  35. package/src/i18n/external.ts +10 -0
  36. package/src/i18n/index.ts +1 -9
  37. package/src/i18n/jp.ts +1 -1
  38. package/src/i18n/zh-TW.ts +1 -1
  39. package/src/layer/sidebar-layer.ts +2 -1
  40. package/src/lib/checker/admin.ts +5 -4
  41. package/src/lib/checker/index.ts +0 -2
  42. package/src/lib/user.ts +13 -7
  43. package/src/list/list-ui.ts +59 -2
  44. package/src/list/list.ts +18 -53
  45. package/src/list/paginator/holder.ts +3 -2
  46. package/src/service.ts +2 -2
  47. package/src/style/list.scss +4 -4
  48. package/src/style/main.scss +1 -1
  49. package/types/context.d.ts +3 -4
  50. package/dist/src/editor/editor-ui.d.ts +0 -25
package/dist/i18n/jp.js CHANGED
@@ -1 +1 @@
1
- !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).jp=o()}(this,(function(){"use strict";const e={placeholder:"Leave a comment",noComment:"No Comment",send:"Send",save:"Save",nick:"Nickname",email:"Email",link:"Website",emoticon:"Emoji",preview:"Preview",image:"Image",uploadFail:"Upload Failed",commentFail:"Failed to comment",restoredMsg:"Content has been restored",onlyAdminCanReply:"Only admin can reply",uploadLoginMsg:"Please fill in your name and email to upload",counter:"{count} Comments",sortLatest:"Latest",sortOldest:"Oldest",sortBest:"Best",sortAuthor:"Author",openComment:"Open Comment",closeComment:"Close Comment",listLoadFailMsg:"Failed to load comments",listRetry:"Click to retry",loadMore:"Load More",admin:"Admin",reply:"Reply",voteUp:"Up",voteDown:"Down",voteFail:"Vote Failed",readMore:"Read More",actionConfirm:"Confirm",collapse:"Collapse",collapsed:"Collapsed",collapsedMsg:"This comment has been collapsed",expand:"Expand",approved:"Approved",pending:"Pending",pendingMsg:"Pending, visible only to commenter.",edit:"Edit",editCancel:"Cancel Edit",delete:"Delete",deleteConfirm:"Confirm",pin:"Pin",unpin:"Unpin",seconds:"seconds ago",minutes:"minutes ago",hours:"hours ago",days:"days ago",now:"just now",adminCheck:"Enter admin password:",captchaCheck:"Enter the CAPTCHA to continue:",confirm:"Confirm",cancel:"Cancel",msgCenter:"Messages",ctrlCenter:"Admin",frontend:"Frontend",backend:"Backend",loading:"Loading",loadFail:"Load Failed",editing:"Editing",editFail:"Edit Failed",deleting:"Deleting",deleteFail:"Delete Failed",reqGot:"Request got",reqAborted:"Request timed out or terminated unexpectedly"},o={en:e,"en-US":e,"zh-CN":{placeholder:"键入内容...",noComment:"「此时无声胜有声」",send:"发送评论",save:"保存评论",nick:"昵称",email:"邮箱",link:"网址",emoticon:"表情",preview:"预览",image:"图片",uploadFail:"上传失败",commentFail:"评论失败",restoredMsg:"内容已自动恢复",onlyAdminCanReply:"仅管理员可评论",uploadLoginMsg:"填入你的名字邮箱才能上传哦",counter:"{count} 条评论",sortLatest:"最新",sortOldest:"最早",sortBest:"最热",sortAuthor:"作者",openComment:"打开评论",closeComment:"关闭评论",listLoadFailMsg:"无法获取评论列表数据",listRetry:"点击重新获取",loadMore:"加载更多",admin:"管理员",reply:"回复",voteUp:"赞同",voteDown:"反对",voteFail:"投票失败",readMore:"阅读更多",actionConfirm:"确认操作",collapse:"折叠",collapsed:"已折叠",collapsedMsg:"该评论已被系统或管理员折叠",expand:"展开",approved:"已审",pending:"待审",pendingMsg:"审核中,仅本人可见。",edit:"编辑",editCancel:"取消编辑",delete:"删除",deleteConfirm:"确认删除",pin:"置顶",unpin:"取消置顶",seconds:"秒前",minutes:"分钟前",hours:"小时前",days:"天前",now:"刚刚",adminCheck:"键入密码来验证管理员身份:",captchaCheck:"键入验证码继续:",confirm:"确认",cancel:"取消",msgCenter:"通知中心",ctrlCenter:"控制中心",frontend:"前端",backend:"后端",loading:"加载中",loadFail:"加载失败",editing:"修改中",editFail:"修改失败",deleting:"删除中",deleteFail:"删除失败",reqGot:"请求响应",reqAborted:"请求超时或意外终止"}},n="ArtalkI18n";var t;t=(t="en").replace(/^([a-zA-Z]+)(-[a-zA-Z]+)?$/,((e,o,n)=>o.toLowerCase()+(n||"").toUpperCase())),o[t]?o[t]:window[n]&&window[n][t]?window[n][t]:o.en;const i=function(e,o,t){return window[n]||(window[n]={}),window[n][e]=o,t&&t.forEach((e=>{window[n][e]=o})),o}("jp",{placeholder:"コメントを残す",noComment:"コメントなし",send:"送信",save:"保存",nick:"ニックネーム",email:"メール",link:"ウェブサイト",emoticon:"絵文字",preview:"プレビュー",image:"画像",uploadFail:"アップロードに失敗しました",commentFail:"コメントに失敗しました",restoredMsg:"コンテンツが復元されました",onlyAdminCanReply:"管理者のみが返信できます",uploadLoginMsg:"アップロードするには、名前とメールアドレスを入力してください",counter:"{count} コメント",sortLatest:"最新のもの",sortOldest:"最も古い",sortBest:"ベスト",sortAuthor:"著者",openComment:"コメントを開く",closeComment:"コメントを閉じる",listLoadFailMsg:"コメントの読み込みに失敗しました",listRetry:"クリックで再試行",loadMore:"もっと読み込む",admin:"管理者",reply:"返信",voteUp:"アップ",voteDown:"ダウン",voteFail:"投票に失敗しました",readMore:"続きを読む",actionConfirm:"確認",collapse:"折りたたむ",collapsed:"折りたたまれた",collapsedMsg:"このコメントは折りたたまれました",expand:"展開",approved:"承認されました",pending:"保留中",pendingMsg:"保留中、コメント投稿者にのみ表示されます",edit:"編集",editCancel:"編集をキャンセル",delete:"削除",deleteConfirm:"確認",pin:"ピン",unpin:"ピン外し",seconds:"秒前",minutes:"分前",hours:"時間前",days:"数日前",now:"たった今",adminCheck:"管理者パスワードを入力してください:",captchaCheck:"続けるにはCAPTCHAを入力してください:",confirm:"確認",cancel:"取消",msgCenter:"メッセージ",ctrlCenter:"コンソール",frontend:"フロントエンド",backend:"バックエンド",loading:"読み込み中",loadFail:"読み込みに失敗しました",editing:"編集中",editFail:"編集に失敗しました",deleting:"削除中",deleteFail:"削除に失敗しました",reqGot:"リクエストを取得しました",reqAborted:"リクエストがタイムアウトしたか、予期せず終了した"},["jp-JP"]);return i}));
1
+ !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).jp=o()}(this,(function(){"use strict";const e="ArtalkI18n";var o,n,t;return o="jp",n={placeholder:"コメントを残す",noComment:"コメントなし",send:"送信",save:"保存",nick:"ニックネーム",email:"メール",link:"ウェブサイト",emoticon:"絵文字",preview:"プレビュー",image:"画像",uploadFail:"アップロードに失敗しました",commentFail:"コメントに失敗しました",restoredMsg:"コンテンツが復元されました",onlyAdminCanReply:"管理者のみが返信できます",uploadLoginMsg:"アップロードするには、名前とメールアドレスを入力してください",counter:"{count} コメント",sortLatest:"最新のもの",sortOldest:"最も古い",sortBest:"ベスト",sortAuthor:"著者",openComment:"コメントを開く",closeComment:"コメントを閉じる",listLoadFailMsg:"コメントの読み込みに失敗しました",listRetry:"クリックで再試行",loadMore:"もっと読み込む",admin:"管理者",reply:"返信",voteUp:"アップ",voteDown:"ダウン",voteFail:"投票に失敗しました",readMore:"続きを読む",actionConfirm:"確認",collapse:"折りたたむ",collapsed:"折りたたまれた",collapsedMsg:"このコメントは折りたたまれました",expand:"展開",approved:"承認されました",pending:"保留中",pendingMsg:"保留中、コメント投稿者にのみ表示されます",edit:"編集",editCancel:"編集をキャンセル",delete:"削除",deleteConfirm:"確認",pin:"ピン",unpin:"ピン外し",seconds:"秒前",minutes:"分前",hours:"時間前",days:"数日前",now:"たった今",adminCheck:"管理者パスワードを入力してください:",captchaCheck:"続けるにはCAPTCHAを入力してください:",confirm:"確認",cancel:"取消",msgCenter:"メッセージ",ctrlCenter:"コンソール",frontend:"フロントエンド",backend:"バックエンド",loading:"読み込み中",loadFail:"読み込みに失敗しました",editing:"編集中",editFail:"編集に失敗しました",deleting:"削除中",deleteFail:"削除に失敗しました",reqGot:"リクエストを取得しました",reqAborted:"リクエストがタイムアウトしたか、予期せず終了した"},t=["jp-JP"],window[e]||(window[e]={}),window[e][o]=n,t&&t.forEach((o=>{window[e][o]=n})),n}));
@@ -1 +1 @@
1
- !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self)["zh-TW"]=o()}(this,(function(){"use strict";const e={placeholder:"Leave a comment",noComment:"No Comment",send:"Send",save:"Save",nick:"Nickname",email:"Email",link:"Website",emoticon:"Emoji",preview:"Preview",image:"Image",uploadFail:"Upload Failed",commentFail:"Failed to comment",restoredMsg:"Content has been restored",onlyAdminCanReply:"Only admin can reply",uploadLoginMsg:"Please fill in your name and email to upload",counter:"{count} Comments",sortLatest:"Latest",sortOldest:"Oldest",sortBest:"Best",sortAuthor:"Author",openComment:"Open Comment",closeComment:"Close Comment",listLoadFailMsg:"Failed to load comments",listRetry:"Click to retry",loadMore:"Load More",admin:"Admin",reply:"Reply",voteUp:"Up",voteDown:"Down",voteFail:"Vote Failed",readMore:"Read More",actionConfirm:"Confirm",collapse:"Collapse",collapsed:"Collapsed",collapsedMsg:"This comment has been collapsed",expand:"Expand",approved:"Approved",pending:"Pending",pendingMsg:"Pending, visible only to commenter.",edit:"Edit",editCancel:"Cancel Edit",delete:"Delete",deleteConfirm:"Confirm",pin:"Pin",unpin:"Unpin",seconds:"seconds ago",minutes:"minutes ago",hours:"hours ago",days:"days ago",now:"just now",adminCheck:"Enter admin password:",captchaCheck:"Enter the CAPTCHA to continue:",confirm:"Confirm",cancel:"Cancel",msgCenter:"Messages",ctrlCenter:"Admin",frontend:"Frontend",backend:"Backend",loading:"Loading",loadFail:"Load Failed",editing:"Editing",editFail:"Edit Failed",deleting:"Deleting",deleteFail:"Delete Failed",reqGot:"Request got",reqAborted:"Request timed out or terminated unexpectedly"},o={en:e,"en-US":e,"zh-CN":{placeholder:"键入内容...",noComment:"「此时无声胜有声」",send:"发送评论",save:"保存评论",nick:"昵称",email:"邮箱",link:"网址",emoticon:"表情",preview:"预览",image:"图片",uploadFail:"上传失败",commentFail:"评论失败",restoredMsg:"内容已自动恢复",onlyAdminCanReply:"仅管理员可评论",uploadLoginMsg:"填入你的名字邮箱才能上传哦",counter:"{count} 条评论",sortLatest:"最新",sortOldest:"最早",sortBest:"最热",sortAuthor:"作者",openComment:"打开评论",closeComment:"关闭评论",listLoadFailMsg:"无法获取评论列表数据",listRetry:"点击重新获取",loadMore:"加载更多",admin:"管理员",reply:"回复",voteUp:"赞同",voteDown:"反对",voteFail:"投票失败",readMore:"阅读更多",actionConfirm:"确认操作",collapse:"折叠",collapsed:"已折叠",collapsedMsg:"该评论已被系统或管理员折叠",expand:"展开",approved:"已审",pending:"待审",pendingMsg:"审核中,仅本人可见。",edit:"编辑",editCancel:"取消编辑",delete:"删除",deleteConfirm:"确认删除",pin:"置顶",unpin:"取消置顶",seconds:"秒前",minutes:"分钟前",hours:"小时前",days:"天前",now:"刚刚",adminCheck:"键入密码来验证管理员身份:",captchaCheck:"键入验证码继续:",confirm:"确认",cancel:"取消",msgCenter:"通知中心",ctrlCenter:"控制中心",frontend:"前端",backend:"后端",loading:"加载中",loadFail:"加载失败",editing:"修改中",editFail:"修改失败",deleting:"删除中",deleteFail:"删除失败",reqGot:"请求响应",reqAborted:"请求超时或意外终止"}},n="ArtalkI18n";var t;t=(t="en").replace(/^([a-zA-Z]+)(-[a-zA-Z]+)?$/,((e,o,n)=>o.toLowerCase()+(n||"").toUpperCase())),o[t]?o[t]:window[n]&&window[n][t]?window[n][t]:o.en;const i=function(e,o,t){return window[n]||(window[n]={}),window[n][e]=o,t&&t.forEach((e=>{window[n][e]=o})),o}("zh-TW",{placeholder:"鍵入內容...",noComment:"「此時無聲勝有聲」",send:"發送評論",save:"保存評論",nick:"昵稱",email:"郵箱",link:"網址",emoticon:"表情",preview:"預覽",image:"圖片",uploadFail:"上傳失敗",commentFail:"評論失敗",restoredMsg:"內容已自動恢復",onlyAdminCanReply:"僅管理員可評論",uploadLoginMsg:"填入你的名字郵箱才能上傳哦",counter:"{count} 條評論",sortLatest:"最新",sortOldest:"最早",sortBest:"最熱",sortAuthor:"作者",openComment:"打開評論",closeComment:"關閉評論",listLoadFailMsg:"無法獲取評論列表數據",listRetry:"點擊重新獲取",loadMore:"加載更多",admin:"管理員",reply:"回覆",voteUp:"贊同",voteDown:"反對",voteFail:"投票失敗",readMore:"閱讀更多",actionConfirm:"確認操作",collapse:"摺疊",collapsed:"已摺疊",collapsedMsg:"該評論已被系統或管理員摺疊",expand:"展開",approved:"已審",pending:"待審",pendingMsg:"審核中,僅本人可見。",edit:"編輯",editCancel:"取消編輯",delete:"刪除",deleteConfirm:"確認刪除",pin:"置頂",unpin:"取消置頂",seconds:"秒前",minutes:"分鐘前",hours:"小時前",days:"天前",now:"剛剛",adminCheck:"鍵入密碼來驗證管理員身份:",captchaCheck:"鍵入驗證碼繼續:",confirm:"確認",cancel:"取消",msgCenter:"通知中心",ctrlCenter:"控制中心",frontend:"前端",backend:"後端",loading:"加載中",loadFail:"加載失敗",editing:"修改中",editFail:"修改失敗",deleting:"刪除中",deleteFail:"刪除失敗",reqGot:"請求響應",reqAborted:"請求超時或意外終止"});return i}));
1
+ !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self)["zh-TW"]=o()}(this,(function(){"use strict";const e="ArtalkI18n";var o,n,t;return o="zh-TW",n={placeholder:"鍵入內容...",noComment:"「此時無聲勝有聲」",send:"發送評論",save:"保存評論",nick:"昵稱",email:"郵箱",link:"網址",emoticon:"表情",preview:"預覽",image:"圖片",uploadFail:"上傳失敗",commentFail:"評論失敗",restoredMsg:"內容已自動恢復",onlyAdminCanReply:"僅管理員可評論",uploadLoginMsg:"填入你的名字郵箱才能上傳哦",counter:"{count} 條評論",sortLatest:"最新",sortOldest:"最早",sortBest:"最熱",sortAuthor:"作者",openComment:"打開評論",closeComment:"關閉評論",listLoadFailMsg:"無法獲取評論列表數據",listRetry:"點擊重新獲取",loadMore:"加載更多",admin:"管理員",reply:"回覆",voteUp:"贊同",voteDown:"反對",voteFail:"投票失敗",readMore:"閱讀更多",actionConfirm:"確認操作",collapse:"摺疊",collapsed:"已摺疊",collapsedMsg:"該評論已被系統或管理員摺疊",expand:"展開",approved:"已審",pending:"待審",pendingMsg:"審核中,僅本人可見。",edit:"編輯",editCancel:"取消編輯",delete:"刪除",deleteConfirm:"確認刪除",pin:"置頂",unpin:"取消置頂",seconds:"秒前",minutes:"分鐘前",hours:"小時前",days:"天前",now:"剛剛",adminCheck:"鍵入密碼來驗證管理員身份:",captchaCheck:"鍵入驗證碼繼續:",confirm:"確認",cancel:"取消",msgCenter:"通知中心",ctrlCenter:"控制中心",frontend:"前端",backend:"後端",loading:"加載中",loadFail:"加載失敗",editing:"修改中",editFail:"修改失敗",deleting:"刪除中",deleteFail:"刪除失敗",reqGot:"請求響應",reqAborted:"請求超時或意外終止"},window[e]||(window[e]={}),window[e][o]=n,t&&t.forEach((o=>{window[e][o]=n})),n}));
@@ -27,7 +27,7 @@ export default class UserApi extends ApiBase {
27
27
  /** 用户 · 注销 */
28
28
  logout(): Promise<unknown>;
29
29
  /** 已读标记 */
30
- markRead(notifyKey: string, readAll?: boolean): Promise<unknown>;
30
+ markRead(commentID: number, notifyKey: string, readAll?: boolean): Promise<unknown>;
31
31
  /** 用户 · 列表 */
32
32
  userList(offset?: number, limit?: number, type?: 'all' | 'admin' | 'in_conf'): Promise<{
33
33
  users: UserDataForAdmin[];
@@ -20,6 +20,7 @@ declare class Context implements ContextApi {
20
20
  private eventList;
21
21
  constructor(conf: ArtalkConfig, $root?: HTMLElement);
22
22
  inject(depName: string, obj: any): void;
23
+ get(depName: string): any;
23
24
  getApi(): Api;
24
25
  getCommentList(): Comment[];
25
26
  getCommentDataList(): CommentData[];
@@ -0,0 +1,70 @@
1
+ import type { I18n } from '.';
2
+ export declare const GLOBAL_LOCALES_KEY = "ArtalkI18n";
3
+ export declare function defineLocaleExternal(lang: string, locale: I18n, aliases?: string[]): {
4
+ placeholder: string;
5
+ noComment: string;
6
+ send: string;
7
+ save: string;
8
+ nick: string;
9
+ email: string;
10
+ link: string;
11
+ emoticon: string;
12
+ preview: string;
13
+ image: string;
14
+ uploadFail: string;
15
+ commentFail: string;
16
+ restoredMsg: string;
17
+ onlyAdminCanReply: string;
18
+ uploadLoginMsg: string;
19
+ counter: string;
20
+ sortLatest: string;
21
+ sortOldest: string;
22
+ sortBest: string;
23
+ sortAuthor: string;
24
+ openComment: string;
25
+ closeComment: string;
26
+ listLoadFailMsg: string;
27
+ listRetry: string;
28
+ loadMore: string;
29
+ admin: string;
30
+ reply: string;
31
+ voteUp: string;
32
+ voteDown: string;
33
+ voteFail: string;
34
+ readMore: string;
35
+ actionConfirm: string;
36
+ collapse: string;
37
+ collapsed: string;
38
+ collapsedMsg: string;
39
+ expand: string;
40
+ approved: string;
41
+ pending: string;
42
+ pendingMsg: string;
43
+ edit: string;
44
+ editCancel: string;
45
+ delete: string;
46
+ deleteConfirm: string;
47
+ pin: string;
48
+ unpin: string;
49
+ seconds: string;
50
+ minutes: string;
51
+ hours: string;
52
+ days: string;
53
+ now: string;
54
+ adminCheck: string;
55
+ captchaCheck: string;
56
+ confirm: string;
57
+ cancel: string;
58
+ msgCenter: string;
59
+ ctrlCenter: string;
60
+ frontend: string;
61
+ backend: string;
62
+ loading: string;
63
+ loadFail: string;
64
+ editing: string;
65
+ editFail: string;
66
+ deleting: string;
67
+ deleteFail: string;
68
+ reqGot: string;
69
+ reqAborted: string;
70
+ };
@@ -207,74 +207,6 @@ export declare const internal: {
207
207
  reqAborted: string;
208
208
  };
209
209
  };
210
- export declare function defineLocaleExternal(lang: string, locale: I18n, aliases?: string[]): {
211
- placeholder: string;
212
- noComment: string;
213
- send: string;
214
- save: string;
215
- nick: string;
216
- email: string;
217
- link: string;
218
- emoticon: string;
219
- preview: string;
220
- image: string;
221
- uploadFail: string;
222
- commentFail: string;
223
- restoredMsg: string;
224
- onlyAdminCanReply: string;
225
- uploadLoginMsg: string;
226
- counter: string;
227
- sortLatest: string;
228
- sortOldest: string;
229
- sortBest: string;
230
- sortAuthor: string;
231
- openComment: string;
232
- closeComment: string;
233
- listLoadFailMsg: string;
234
- listRetry: string;
235
- loadMore: string;
236
- admin: string;
237
- reply: string;
238
- voteUp: string;
239
- voteDown: string;
240
- voteFail: string;
241
- readMore: string;
242
- actionConfirm: string;
243
- collapse: string;
244
- collapsed: string;
245
- collapsedMsg: string;
246
- expand: string;
247
- approved: string;
248
- pending: string;
249
- pendingMsg: string;
250
- edit: string;
251
- editCancel: string;
252
- delete: string;
253
- deleteConfirm: string;
254
- pin: string;
255
- unpin: string;
256
- seconds: string;
257
- minutes: string;
258
- hours: string;
259
- days: string;
260
- now: string;
261
- adminCheck: string;
262
- captchaCheck: string;
263
- confirm: string;
264
- cancel: string;
265
- msgCenter: string;
266
- ctrlCenter: string;
267
- frontend: string;
268
- backend: string;
269
- loading: string;
270
- loadFail: string;
271
- editing: string;
272
- editFail: string;
273
- deleting: string;
274
- deleteFail: string;
275
- reqGot: string;
276
- reqAborted: string;
277
- };
278
210
  /**
279
211
  * find a locale object by language name
280
212
  */
@@ -1,7 +1,6 @@
1
1
  import Context from '../../../types/context';
2
2
  import Layer from '../../layer';
3
3
  import type Api from '../../api';
4
- import type User from '../user';
5
4
  export interface CheckerCaptchaPayload extends CheckerPayload {
6
5
  imgData?: string;
7
6
  iframe?: string;
@@ -41,7 +40,6 @@ export interface CheckerCtx {
41
40
  set<K extends keyof CheckerStore>(key: K, val: CheckerStore[K]): void;
42
41
  getCtx(): Context;
43
42
  getApi(): Api;
44
- getUser(): User;
45
43
  getLayer(): Layer;
46
44
  hideInteractInput(): void;
47
45
  triggerSuccess(): void;
@@ -1,9 +1,10 @@
1
1
  import { LocalUser } from '../../types/artalk-config';
2
2
  import Context from '../../types/context';
3
- export default class User {
4
- ctx: Context;
3
+ declare class User {
4
+ ctx?: Context;
5
5
  data: LocalUser;
6
- constructor(ctx: Context);
6
+ constructor();
7
+ setContext(ctx: Context): void;
7
8
  /** 保存用户到 localStorage 中 */
8
9
  update(obj?: Partial<LocalUser>): void;
9
10
  /** 注销,清除用户登录状态 */
@@ -11,3 +12,5 @@ export default class User {
11
12
  /** 是否已填写基本用户信息 */
12
13
  checkHasBasicUserInfo(): boolean;
13
14
  }
15
+ declare const UserInstance: User;
16
+ export default UserInstance;
@@ -5,3 +5,12 @@ export declare function refreshUI(list: ListLite): void;
5
5
  export declare function renderErrorDialog(list: ListLite, errMsg: string, errData?: any): HTMLElement;
6
6
  /** 版本检测弹窗 */
7
7
  export declare function versionCheckDialog(list: ListLite, feVer: string, beVer: string): boolean;
8
+ /** 评论排序方式选择下拉菜单 */
9
+ export declare function renderDropdown(conf: {
10
+ $dropdownWrap: HTMLElement;
11
+ dropdownList: [string, () => void][];
12
+ }): void;
13
+ /** 删除评论排序方式选择下拉菜单 */
14
+ export declare function removeDropdown(conf: {
15
+ $dropdownWrap: HTMLElement;
16
+ }): void;
@@ -20,7 +20,6 @@ export default class List extends ListLite {
20
20
  /** 管理员设置页面信息 */
21
21
  adminPageEditSave(): void;
22
22
  showUnreadBadge(count: number): void;
23
- private dropdownLoaded;
24
23
  /** 初始化选择下拉层 */
25
24
  protected initDropdown(): void;
26
25
  updateUnread(notifies: NotifyData[]): void;
@@ -3,7 +3,6 @@ import CheckerLauncher from './lib/checker';
3
3
  import Api from './api';
4
4
  import Editor from './editor';
5
5
  import SidebarLayer from './layer/sidebar-layer';
6
- import User from './lib/user';
7
6
  import ListLite from './list/list-lite';
8
7
  /**
9
8
  * Services
@@ -15,7 +14,14 @@ import ListLite from './list/list-lite';
15
14
  declare const services: {
16
15
  i18n(ctx: Context): void;
17
16
  markdown(): void;
18
- user(ctx: Context): User;
17
+ user(ctx: Context): {
18
+ ctx?: Context | undefined;
19
+ data: import("../types/artalk-config").LocalUser;
20
+ setContext(ctx: Context): void;
21
+ update(obj?: Partial<import("../types/artalk-config").LocalUser>): void;
22
+ logout(): void;
23
+ checkHasBasicUserInfo(): boolean;
24
+ };
19
25
  api(ctx: Context): Api;
20
26
  checkerLauncher(ctx: Context): CheckerLauncher;
21
27
  editor(ctx: Context): Editor;
@@ -22,14 +22,13 @@ export default interface ContextApi {
22
22
  /** 依赖注入函数 */
23
23
  inject<K extends keyof TInjectedServices>(depName: K, obj: TInjectedServices[K]): void
24
24
 
25
+ /** 获取依赖对象 */
26
+ get<K extends keyof TInjectedServices>(depName: K): TInjectedServices[K]
27
+
25
28
  /** 配置对象 */
26
29
  // TODO 修改为 getConf() 和 setConf()
27
30
  conf: ArtalkConfig
28
31
 
29
- /** 用户对象 */
30
- // TODO 修改为 getUser()
31
- user: User
32
-
33
32
  /** marked 依赖对象 */
34
33
  getMarkedInstance(): TMarked | undefined
35
34
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artalk",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "license": "LGPL-3.0",
5
5
  "description": "A Selfhosted Comment System",
6
6
  "keywords": [
@@ -1,6 +1,7 @@
1
1
  import { CommentData, ListData } from '~/types/artalk-data'
2
2
  import * as Utils from '../lib/utils'
3
3
  import ApiBase from './api-base'
4
+ import User from '../lib/user'
4
5
 
5
6
  /**
6
7
  * 评论 API
@@ -16,9 +17,9 @@ export default class CommentApi extends ApiBase {
16
17
  }
17
18
 
18
19
  if (flatMode) params.flat_mode = flatMode // 平铺模式
19
- if (this.ctx.user.checkHasBasicUserInfo()) {
20
- params.name = this.ctx.user.data.nick
21
- params.email = this.ctx.user.data.email
20
+ if (User.checkHasBasicUserInfo()) {
21
+ params.name = User.data.nick
22
+ params.email = User.data.email
22
23
  }
23
24
 
24
25
  if (paramsEditor) paramsEditor(params)
@@ -68,14 +69,13 @@ export default class CommentApi extends ApiBase {
68
69
  /** 投票 */
69
70
  public async vote(targetID: number, type: string) {
70
71
  const params: any = {
71
- site_name: this.ctx.conf.site || '',
72
72
  target_id: targetID,
73
73
  type,
74
74
  }
75
75
 
76
- if (this.ctx.user.checkHasBasicUserInfo()) {
77
- params.name = this.ctx.user.data.nick
78
- params.email = this.ctx.user.data.email
76
+ if (User.checkHasBasicUserInfo()) {
77
+ params.name = User.data.nick
78
+ params.email = User.data.email
79
79
  }
80
80
 
81
81
  const data = await this.POST<any>('/vote', params)
package/src/api/page.ts CHANGED
@@ -55,7 +55,6 @@ export default class PageApi extends ApiBase {
55
55
  /** PV */
56
56
  public async pv() {
57
57
  const params: any = {
58
- site_name: this.ctx.conf.site || '',
59
58
  page_key: this.ctx.conf.pageKey || '',
60
59
  page_title: this.ctx.conf.pageTitle || ''
61
60
  }
@@ -73,7 +72,6 @@ export default class PageApi extends ApiBase {
73
72
  ) {
74
73
  const params: any = {
75
74
  type,
76
- site_name: this.ctx.conf.site || '',
77
75
  }
78
76
 
79
77
  if (pageKeys) params.page_keys = Array.isArray(pageKeys) ? pageKeys.join(',') : pageKeys
@@ -1,11 +1,13 @@
1
1
  import Context from '~/types/context'
2
+ import User from '../lib/user'
3
+ import $t from '../i18n'
2
4
 
3
5
  /** 公共请求函数 */
4
6
  export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit, timeout?: number): Promise<any> {
5
7
  // JWT
6
- if (ctx.user.data.token) {
8
+ if (User.data.token) {
7
9
  const headers = new Headers(init.headers) // 保留原有 headers
8
- headers.set('Authorization', `Bearer ${ctx.user.data.token}`)
10
+ headers.set('Authorization', `Bearer ${User.data.token}`)
9
11
  init.headers = headers
10
12
  }
11
13
 
@@ -20,7 +22,7 @@ export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit,
20
22
  const isNoAccess = noAccessCodes.includes(respHttpCode)
21
23
 
22
24
  if (!resp.ok && !isNoAccess)
23
- throw new Error(`${ctx.$t('reqGot')} ${respHttpCode}`)
25
+ throw new Error(`${$t('reqGot')} ${respHttpCode}`)
24
26
 
25
27
  // 解析获取响应的 json
26
28
  let json: any = await resp.json()
@@ -95,7 +97,7 @@ function timeoutFetch(ctx: Context, url: RequestInfo, ms: number, opts: RequestI
95
97
  promise.finally(() => { clearTimeout(timer) })
96
98
  }
97
99
  promise = promise.catch((err) => {
98
- throw ((err || {}).name === 'AbortError') ? new Error(ctx.$t('reqAborted')) : err
100
+ throw ((err || {}).name === 'AbortError') ? new Error($t('reqAborted')) : err
99
101
  })
100
102
  return promise
101
103
  }
package/src/api/upload.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ToFormData } from './request'
2
2
  import ApiBase from './api-base'
3
+ import User from '../lib/user'
3
4
 
4
5
  /**
5
6
  * 上传 API
@@ -8,13 +9,11 @@ export default class UploadApi extends ApiBase {
8
9
  /** 图片上传 */
9
10
  public async imgUpload(file: File) {
10
11
  const params: any = {
11
- name: this.ctx.user.data.nick,
12
- email: this.ctx.user.data.email,
12
+ name: User.data.nick,
13
+ email: User.data.email,
13
14
  page_key: this.ctx.conf.pageKey,
14
15
  }
15
16
 
16
- if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
17
-
18
17
  const form = ToFormData(params)
19
18
  form.set('file', file)
20
19
 
package/src/api/user.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { UserData, NotifyData, UserDataForAdmin } from '~/types/artalk-data'
2
2
  import ApiBase from './api-base'
3
3
  import { ToFormData } from './request'
4
+ import User from '../lib/user'
4
5
 
5
6
  /**
6
7
  * 用户 API
@@ -12,8 +13,6 @@ export default class UserApi extends ApiBase {
12
13
  name, email, password
13
14
  }
14
15
 
15
- if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
16
-
17
16
  const data = await this.POST<any>('/login', params)
18
17
  return data as { token: string, user: UserData }
19
18
  }
@@ -22,7 +21,7 @@ export default class UserApi extends ApiBase {
22
21
  public userGet(name: string, email: string) {
23
22
  const ctrl = new AbortController()
24
23
  const params: any = {
25
- name, email, site_name: (this.ctx.conf.site || '')
24
+ name, email
26
25
  }
27
26
 
28
27
  const req = this.Fetch(`/user-get`, {
@@ -45,8 +44,8 @@ export default class UserApi extends ApiBase {
45
44
  /** 用户 · 登录状态 */
46
45
  public async loginStatus() {
47
46
  const data = await this.POST<any>('/login-status', {
48
- name: this.ctx.user.data.nick,
49
- email: this.ctx.user.data.email
47
+ name: User.data.nick,
48
+ email: User.data.email
50
49
  })
51
50
  return (data || { is_login: false, is_admin: false }) as { is_login: boolean, is_admin: boolean }
52
51
  }
@@ -57,17 +56,18 @@ export default class UserApi extends ApiBase {
57
56
  }
58
57
 
59
58
  /** 已读标记 */
60
- public markRead(notifyKey: string, readAll = false) {
59
+ public markRead(commentID: number, notifyKey: string, readAll = false) {
61
60
  const params: any = {
62
- site_name: this.ctx.conf.site || '',
61
+ comment_id: commentID,
63
62
  notify_key: notifyKey,
64
63
  }
65
64
 
66
65
  if (readAll) {
66
+ delete params.comment_id
67
67
  delete params.notify_key
68
68
  params.read_all = true
69
- params.name = this.ctx.user.data.nick
70
- params.email = this.ctx.user.data.email
69
+ params.name = User.data.nick
70
+ params.email = User.data.email
71
71
  }
72
72
 
73
73
  return this.POST(`/mark-read`, params)
package/src/artalk.ts CHANGED
@@ -10,6 +10,7 @@ import { handelBaseConf } from './config'
10
10
  import Services from './service'
11
11
  import * as Stat from './lib/stat'
12
12
  import ListLite from './list/list-lite'
13
+ import Api from './api'
13
14
 
14
15
  /**
15
16
  * Artalk
@@ -31,7 +32,7 @@ export default class Artalk {
31
32
  public static DisabledComponents: string[] = []
32
33
 
33
34
  constructor(conf: Partial<ArtalkConfig>) {
34
- if (Artalk.instance) return Artalk.instance.update(conf)
35
+ if (Artalk.instance) Artalk.destroy()
35
36
 
36
37
  // 初始化基本配置
37
38
  this.conf = handelBaseConf(conf)
@@ -56,7 +57,7 @@ export default class Artalk {
56
57
 
57
58
  /** Init Artalk */
58
59
  public static init(conf: Partial<ArtalkConfig>): Artalk {
59
- if (this.instance) return this.instance.update(conf) // 单例模式
60
+ if (this.instance) Artalk.destroy()
60
61
  this.instance = new Artalk(conf)
61
62
  return this.instance
62
63
  }
@@ -153,7 +154,8 @@ export default class Artalk {
153
154
 
154
155
  /** Load count widget */
155
156
  public static loadCountWidget(conf: Partial<ArtalkConfig>) {
156
- const ctx = new ConcreteContext(handelBaseConf(conf))
157
+ const ctx: Context = new ConcreteContext(handelBaseConf(conf))
158
+ ctx.inject('api', new Api(ctx))
157
159
  Stat.initCountWidget({ ctx, pvAdd: false })
158
160
  }
159
161
 
package/src/context.ts CHANGED
@@ -39,14 +39,16 @@ class Context implements ContextApi {
39
39
  this.$root = $root || document.createElement('div')
40
40
  this.$root.classList.add('artalk')
41
41
  this.$root.innerHTML = ''
42
-
43
- this.api = new Api(this)
44
42
  }
45
43
 
46
44
  public inject(depName: string, obj: any) {
47
45
  this[depName] = obj
48
46
  }
49
47
 
48
+ public get(depName: string) {
49
+ return this[depName]
50
+ }
51
+
50
52
  public getApi() {
51
53
  return this.api
52
54
  }
@@ -1,6 +1,7 @@
1
1
  import type { CommentData } from '~/types/artalk-data'
2
2
  import * as Utils from '../lib/utils'
3
3
  import Editor from './editor'
4
+ import User from '../lib/user'
4
5
 
5
6
  export interface EditModeManager {
6
7
  editor: Editor
@@ -69,7 +70,7 @@ function cancelEdit(m: EditModeManager) {
69
70
  m.comment = undefined
70
71
  m.editor.travelBack()
71
72
 
72
- const { nick, email, link } = m.editor.ctx.user.data
73
+ const { nick, email, link } = User.data
73
74
  ui.$nick.value = nick
74
75
  ui.$email.value = email
75
76
  ui.$link.value = link
@@ -4,6 +4,7 @@ import Component from '../lib/component'
4
4
  import * as Utils from '../lib/utils'
5
5
  import * as Ui from '../lib/ui'
6
6
  import marked from '../lib/marked'
7
+ import User from '../lib/user'
7
8
  import initEditorFuncs from './funcs'
8
9
  import { render, EditorUI } from './ui'
9
10
  import { PlugManager } from './plug-manager'
@@ -178,7 +179,7 @@ export default class Editor extends Component {
178
179
  if (!this.ui.$textareaWrap.querySelector('.atk-comment-closed'))
179
180
  this.ui.$textareaWrap.prepend(Utils.createElement(`<div class="atk-comment-closed">${this.$t('onlyAdminCanReply')}</div>`))
180
181
 
181
- if (!this.ctx.user.data.isAdmin) {
182
+ if (!User.data.isAdmin) {
182
183
  this.ui.$textarea.style.display = 'none'
183
184
  this.closePlugPanel()
184
185
  this.ui.$bottom.style.display = 'none'
@@ -1,4 +1,5 @@
1
1
  import Editor from './editor'
2
+ import User from '../lib/user'
2
3
  import { createMover } from './mover'
3
4
  import { createPlugManager } from './plug-manager'
4
5
  import { createReplyManager } from './reply'
@@ -31,7 +32,7 @@ function localStorage(editor: Editor) {
31
32
  function header(editor: Editor) {
32
33
  const $inputs = editor.getHeaderInputEls()
33
34
  Object.entries($inputs).forEach(([key, $input]) => {
34
- $input.value = editor.ctx.user.data[key] || ''
35
+ $input.value = User.data[key] || ''
35
36
  $input.addEventListener('input', () => onHeaderInput(editor, key, $input))
36
37
 
37
38
  // 设置 Placeholder
@@ -42,7 +43,7 @@ function header(editor: Editor) {
42
43
  function onHeaderInput(editor: Editor, field: string, $input: HTMLInputElement) {
43
44
  if (editor.isEditMode) return // 评论编辑模式,不修改个人信息
44
45
 
45
- editor.ctx.user.update({
46
+ User.update({
46
47
  [field]: $input.value.trim()
47
48
  })
48
49