artalk 2.4.3 → 2.5.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 (145) hide show
  1. package/README.md +27 -0
  2. package/dist/Artalk.css +1 -1
  3. package/dist/Artalk.es.js +4895 -4067
  4. package/dist/Artalk.iife.js +1 -1
  5. package/dist/Artalk.js +1 -1
  6. package/dist/ArtalkLite.css +1 -1
  7. package/dist/ArtalkLite.es.js +2496 -1779
  8. package/dist/ArtalkLite.iife.js +1 -1
  9. package/dist/ArtalkLite.js +1 -1
  10. package/dist/i18n/jp.js +1 -1
  11. package/dist/i18n/zh-TW.js +1 -1
  12. package/dist/src/api/index.d.ts +2 -2
  13. package/dist/src/api/system.d.ts +5 -2
  14. package/dist/src/artalk.d.ts +42 -34
  15. package/dist/src/comment/comment.d.ts +2 -2
  16. package/dist/src/comment/height-limit.d.ts +30 -0
  17. package/dist/src/comment/render-ctx.d.ts +23 -0
  18. package/dist/src/comment/render.d.ts +2 -50
  19. package/dist/src/comment/renders/actions.d.ts +5 -0
  20. package/dist/src/comment/renders/avatar.d.ts +5 -0
  21. package/dist/src/comment/renders/content.d.ts +5 -0
  22. package/dist/src/comment/renders/header.d.ts +5 -0
  23. package/dist/src/comment/renders/index.d.ts +2 -0
  24. package/dist/src/comment/renders/pending.d.ts +5 -0
  25. package/dist/src/comment/renders/reply-at.d.ts +5 -0
  26. package/dist/src/comment/renders/reply-to.d.ts +5 -0
  27. package/dist/src/components/dialog.d.ts +1 -1
  28. package/dist/src/config.d.ts +8 -0
  29. package/dist/src/context.d.ts +15 -29
  30. package/dist/src/editor/edit-mode.d.ts +9 -0
  31. package/dist/src/editor/editor-ui.d.ts +25 -0
  32. package/dist/src/editor/editor.d.ts +37 -45
  33. package/dist/src/editor/funcs.d.ts +2 -0
  34. package/dist/src/editor/mover.d.ts +8 -0
  35. package/dist/src/editor/plug-manager.d.ts +17 -0
  36. package/dist/src/editor/plugs/editor-plug.d.ts +13 -1
  37. package/dist/src/editor/reply.d.ts +9 -0
  38. package/dist/src/editor/submit.d.ts +16 -0
  39. package/dist/src/editor/ui.d.ts +25 -0
  40. package/dist/src/i18n/index.d.ts +11 -7
  41. package/dist/src/layer/index.d.ts +2 -2
  42. package/dist/src/layer/layer.d.ts +1 -1
  43. package/dist/src/lib/checker/captcha-renders.d.ts +5 -0
  44. package/dist/src/lib/checker/index.d.ts +18 -10
  45. package/dist/src/lib/dark-mode.d.ts +4 -0
  46. package/dist/src/lib/marked.d.ts +9 -0
  47. package/dist/src/lib/utils.d.ts +1 -5
  48. package/dist/src/list/list-lite.d.ts +15 -11
  49. package/dist/src/list/list-nest.d.ts +2 -2
  50. package/dist/src/list/list-ui.d.ts +7 -0
  51. package/dist/src/list/paginator/adaptors/index.d.ts +12 -0
  52. package/dist/src/list/paginator/adaptors/pagination.d.ts +9 -0
  53. package/dist/src/list/paginator/adaptors/read-more.d.ts +10 -0
  54. package/dist/src/list/paginator/holder.d.ts +16 -0
  55. package/dist/src/list/paginator/index.d.ts +10 -0
  56. package/dist/src/service.d.ts +40 -0
  57. package/dist/types/artalk-config.d.ts +5 -2
  58. package/dist/types/artalk-data.d.ts +3 -3
  59. package/dist/types/context.d.ts +11 -17
  60. package/dist/types/global.d.ts +1 -0
  61. package/package.json +6 -7
  62. package/src/api/system.ts +3 -12
  63. package/src/artalk.ts +101 -158
  64. package/src/comment/comment.ts +7 -6
  65. package/src/comment/height-limit.ts +100 -0
  66. package/src/comment/render-ctx.ts +30 -0
  67. package/src/comment/render.ts +31 -375
  68. package/src/comment/renders/actions.ts +114 -0
  69. package/src/comment/renders/avatar.ts +22 -0
  70. package/src/comment/renders/content.ts +39 -0
  71. package/src/comment/renders/header.ts +84 -0
  72. package/src/comment/renders/index.ts +19 -0
  73. package/src/comment/renders/pending.ts +12 -0
  74. package/src/comment/renders/reply-at.ts +16 -0
  75. package/src/comment/renders/reply-to.ts +24 -0
  76. package/src/config.ts +65 -0
  77. package/src/context.ts +31 -88
  78. package/src/defaults.ts +1 -0
  79. package/src/editor/edit-mode.ts +102 -0
  80. package/src/editor/editor.ts +100 -394
  81. package/src/editor/funcs.ts +96 -0
  82. package/src/editor/mover.ts +43 -0
  83. package/src/editor/plug-manager.ts +172 -0
  84. package/src/editor/plugs/editor-plug.ts +20 -2
  85. package/src/editor/plugs/{emoticons-plug.less → emoticons-plug.scss} +5 -4
  86. package/src/editor/plugs/emoticons-plug.ts +2 -1
  87. package/src/editor/plugs/header-input-plug.ts +5 -5
  88. package/src/editor/plugs/{preview-plug.less → preview-plug.scss} +1 -1
  89. package/src/editor/plugs/preview-plug.ts +8 -4
  90. package/src/editor/plugs/upload-plug.ts +10 -13
  91. package/src/editor/reply.ts +62 -0
  92. package/src/editor/submit.ts +98 -0
  93. package/src/editor/ui.ts +36 -0
  94. package/src/i18n/index.ts +21 -10
  95. package/src/layer/index.ts +2 -2
  96. package/src/layer/layer.ts +4 -4
  97. package/src/layer/sidebar-layer.ts +2 -1
  98. package/src/lib/checker/admin.ts +36 -0
  99. package/src/lib/checker/captcha-renders.ts +68 -0
  100. package/src/lib/checker/captcha.ts +26 -0
  101. package/src/lib/checker/index.ts +38 -20
  102. package/src/lib/dark-mode.ts +48 -0
  103. package/src/lib/marked.ts +133 -0
  104. package/src/lib/utils.ts +1 -123
  105. package/src/list/list-lite.ts +59 -162
  106. package/src/list/list-ui.ts +80 -0
  107. package/src/list/list.ts +16 -8
  108. package/src/list/paginator/adaptors/index.ts +21 -0
  109. package/src/list/paginator/adaptors/pagination.ts +42 -0
  110. package/src/list/paginator/adaptors/read-more.ts +56 -0
  111. package/src/list/paginator/holder.ts +55 -0
  112. package/src/list/paginator/index.ts +13 -0
  113. package/src/service.ts +118 -0
  114. package/src/style/{_color.less → _color.scss} +3 -3
  115. package/src/style/{_extend.less → _extend.scss} +1 -1
  116. package/src/style/_variables.scss +3 -0
  117. package/src/style/{comment.less → comment.scss} +36 -12
  118. package/src/style/{editor.less → editor.scss} +11 -11
  119. package/src/style/{list.less → list.scss} +8 -6
  120. package/src/style/{main.less → main.scss} +24 -23
  121. package/src/style/{sidebar-layer.less → sidebar-layer.scss} +8 -8
  122. package/types/artalk-config.d.ts +5 -2
  123. package/types/artalk-data.d.ts +3 -3
  124. package/types/context.d.ts +11 -17
  125. package/types/global.d.ts +1 -0
  126. package/CNAME +0 -1
  127. package/LICENSE +0 -165
  128. package/index.html +0 -157
  129. package/postcss.config.js +0 -5
  130. package/scripts/build-i18n.mjs +0 -46
  131. package/src/lib/checker/admin-checker.ts +0 -36
  132. package/src/lib/checker/captcha-checker.ts +0 -84
  133. package/src/style/_variables.less +0 -3
  134. package/test/ArtalkCount.html +0 -16
  135. package/test/ArtalkI18n.html +0 -16
  136. package/test/ArtalkLite.html +0 -15
  137. package/test/CSRF.html +0 -26
  138. package/tsconfig.json +0 -12
  139. package/vite-base.config.ts +0 -21
  140. package/vite-demo.config.ts +0 -12
  141. package/vite-lite.config.ts +0 -22
  142. package/vite.config.ts +0 -27
  143. /package/dist/src/lib/checker/{admin-checker.d.ts → admin.d.ts} +0 -0
  144. /package/dist/src/lib/checker/{captcha-checker.d.ts → captcha.d.ts} +0 -0
  145. /package/src/style/{pagination.less → pagination.scss} +0 -0
@@ -15,12 +15,24 @@ declare abstract class EditorPlug {
15
15
  protected $panel?: HTMLElement;
16
16
  protected $btn?: HTMLElement;
17
17
  onHeaderInput?: (key: string, $input: HTMLElement) => void;
18
+ contentTransformer?: (rawContent: string) => string;
19
+ onContentUpdated?: (content: string) => void;
18
20
  constructor(editor: Editor);
21
+ /** Name of plug */
19
22
  static Name: string;
23
+ /** Register plug panel will provide a plug el */
20
24
  protected registerPanel(html?: string): HTMLElement;
25
+ /** Register plug btn will add a btn on the bottom of editor */
21
26
  protected registerBtn(html: string): HTMLElement;
22
- protected registerHeaderInputEvt(action: (key: string, $input: HTMLElement) => void): void;
27
+ /** Register the event of header input is changed */
28
+ protected registerHeaderInputEvt(func: (key: string, $input: HTMLElement) => void): void;
29
+ /** Register the content transformer to handle the content of the last submit by the editor */
30
+ protected registerContentTransformer(func: (raw: string) => string): void;
31
+ /** Register the event of editor content is updated */
32
+ protected registerContentUpdatedEvt(func: (content: string) => void): void;
33
+ /** Get panel element of plug */
23
34
  getPanel(): HTMLElement | undefined;
35
+ /** Get btn element of plug */
24
36
  getBtn(): HTMLElement | undefined;
25
37
  }
26
38
  export default EditorPlug;
@@ -0,0 +1,9 @@
1
+ import type { CommentData } from '../../types/artalk-data';
2
+ import Editor from './editor';
3
+ export interface ReplyManager {
4
+ editor: Editor;
5
+ comment?: CommentData;
6
+ setReply(comment: CommentData, $comment: HTMLElement, scroll?: boolean): void;
7
+ cancelReply(): void;
8
+ }
9
+ export declare function createReplyManager(editor: Editor): ReplyManager;
@@ -0,0 +1,16 @@
1
+ import type { CommentData } from '../../types/artalk-data';
2
+ import Editor from './editor';
3
+ export interface SubmitManager {
4
+ editor: Editor;
5
+ do: () => Promise<void>;
6
+ customs: CustomSubmit[];
7
+ registerCustom(c: CustomSubmit): void;
8
+ }
9
+ export declare function createSubmitManager(editor: Editor): SubmitManager;
10
+ interface CustomSubmit {
11
+ activeCond: () => void;
12
+ pre?: () => void;
13
+ req?: () => Promise<CommentData>;
14
+ post?: (nComment: CommentData) => void;
15
+ }
16
+ export {};
@@ -0,0 +1,25 @@
1
+ declare const Sel: {
2
+ $header: string;
3
+ $nick: string;
4
+ $email: string;
5
+ $link: string;
6
+ $textareaWrap: string;
7
+ $textarea: string;
8
+ $bottom: string;
9
+ $submitBtn: string;
10
+ $notifyWrap: string;
11
+ $plugBtnWrap: string;
12
+ $plugPanelWrap: string;
13
+ };
14
+ export interface EditorUI extends Record<keyof typeof Sel, HTMLElement> {
15
+ $el: HTMLElement;
16
+ $nick: HTMLInputElement;
17
+ $email: HTMLInputElement;
18
+ $link: HTMLInputElement;
19
+ $textarea: HTMLTextAreaElement;
20
+ $submitBtn: HTMLButtonElement;
21
+ $sendReply?: HTMLElement;
22
+ $editCancelBtn?: HTMLElement;
23
+ }
24
+ export declare function render(): EditorUI;
25
+ export {};
@@ -1,5 +1,6 @@
1
1
  import en from './en';
2
- export declare type I18n = typeof en;
2
+ export type I18n = typeof en;
3
+ export type I18nKeys = keyof I18n;
3
4
  export declare const internal: {
4
5
  en: {
5
6
  placeholder: string;
@@ -275,14 +276,17 @@ export declare function defineLocaleExternal(lang: string, locale: I18n, aliases
275
276
  reqAborted: string;
276
277
  };
277
278
  /**
278
- * get a locale object by language name
279
+ * find a locale object by language name
279
280
  */
280
- declare function getLocaleSet(lang: string): I18n;
281
+ export declare function findLocaleSet(lang: string): I18n;
281
282
  /**
282
- * get a i18n message by key
283
+ * Set system locale
283
284
  */
284
- declare function getI18n(locale: I18n | string, key: keyof I18n, args?: {
285
+ export declare function setLocale(locale: I18n | string): void;
286
+ /**
287
+ * Get an i18n message by key
288
+ */
289
+ export declare function t(key: I18nKeys, args?: {
285
290
  [key: string]: string;
286
291
  }): string;
287
- export { getLocaleSet };
288
- export default getI18n;
292
+ export default t;
@@ -1,3 +1,3 @@
1
- import Layer, { GetLayerWrap } from './layer';
1
+ import Layer, { getLayerWrap } from './layer';
2
2
  export default Layer;
3
- export { GetLayerWrap };
3
+ export { getLayerWrap };
@@ -26,7 +26,7 @@ export default class Layer extends Component {
26
26
  dispose(): void;
27
27
  checkCleanLayer(): void;
28
28
  }
29
- export declare function GetLayerWrap(ctx: Context): {
29
+ export declare function getLayerWrap(): {
30
30
  $wrap: HTMLElement;
31
31
  $mask: HTMLElement;
32
32
  };
@@ -0,0 +1,5 @@
1
+ import { CheckerCtx } from '.';
2
+ /** 图片验证码 */
3
+ export declare function imgBody(checker: CheckerCtx): HTMLElement;
4
+ /** iframe 形式的通用验证服务 */
5
+ export declare function iframeBody(checker: CheckerCtx): HTMLElement;
@@ -1,5 +1,7 @@
1
1
  import Context from '../../../types/context';
2
2
  import Layer from '../../layer';
3
+ import type Api from '../../api';
4
+ import type User from '../user';
3
5
  export interface CheckerCaptchaPayload extends CheckerPayload {
4
6
  imgData?: string;
5
7
  iframe?: string;
@@ -15,28 +17,34 @@ export interface CheckerPayload {
15
17
  export default class CheckerLauncher {
16
18
  ctx: Context;
17
19
  launched: Checker[];
18
- captchaConf: {
19
- val?: string;
20
- imgData?: string;
21
- iframe?: string;
22
- };
23
20
  constructor(ctx: Context);
24
21
  checkCaptcha(payload: CheckerCaptchaPayload): void;
25
22
  checkAdmin(payload: CheckerPayload): void;
26
- fire(checker: Checker, payload: CheckerPayload): void;
23
+ fire(checker: Checker, payload: CheckerPayload, postFire?: (c: CheckerCtx) => void): void;
27
24
  private close;
28
25
  }
29
26
  export interface Checker {
30
27
  el?: HTMLElement;
31
28
  inputType?: 'password' | 'text';
32
- body: (launcher: CheckerLauncher, ctx: CheckerCtx) => HTMLElement;
33
- request: (launcher: CheckerLauncher, ctx: CheckerCtx, inputVal: string) => Promise<string>;
34
- onSuccess?: (launcher: CheckerLauncher, ctx: CheckerCtx, data: string, inputVal: string, formEl: HTMLElement) => void;
35
- onError?: (launcher: CheckerLauncher, ctx: CheckerCtx, err: any, inputVal: string, formEl: HTMLElement) => void;
29
+ body: (checker: CheckerCtx) => HTMLElement;
30
+ request: (checker: CheckerCtx, inputVal: string) => Promise<string>;
31
+ onSuccess?: (checker: CheckerCtx, respData: string, inputVal: string, formEl: HTMLElement) => void;
32
+ onError?: (checker: CheckerCtx, err: any, inputVal: string, formEl: HTMLElement) => void;
33
+ }
34
+ interface CheckerStore {
35
+ val?: string;
36
+ img_data?: string;
37
+ iframe?: string;
36
38
  }
37
39
  export interface CheckerCtx {
40
+ get<K extends keyof CheckerStore>(key: K): CheckerStore[K];
41
+ set<K extends keyof CheckerStore>(key: K, val: CheckerStore[K]): void;
42
+ getCtx(): Context;
43
+ getApi(): Api;
44
+ getUser(): User;
38
45
  getLayer(): Layer;
39
46
  hideInteractInput(): void;
40
47
  triggerSuccess(): void;
41
48
  cancel(): void;
42
49
  }
50
+ export {};
@@ -0,0 +1,4 @@
1
+ import type Context from '../../types/context';
2
+ export declare function syncDarkModeConf(ctx: Context): void;
3
+ export declare function setDarkMode(ctx: Context, darkMode: boolean | 'auto', alterConf?: boolean): void;
4
+ export declare function updateClassName(ctx: Context, darkMode: boolean): void;
@@ -0,0 +1,9 @@
1
+ import { marked as libMarked } from 'marked';
2
+ import Context from '../../types/context';
3
+ export type TMarked = typeof libMarked;
4
+ /** Get Marked instance */
5
+ export declare function getInstance(): typeof libMarked | undefined;
6
+ /** 初始化 marked */
7
+ export declare function initMarked(): void;
8
+ /** 解析 markdown */
9
+ export default function marked(ctx: Context, src: string): string;
@@ -16,11 +16,7 @@ export declare function onImagesLoaded($container: HTMLElement, event: Function)
16
16
  export declare function getGravatarURL(ctx: Context, emailMD5: string): string;
17
17
  export declare function sleep(ms: number): Promise<unknown>;
18
18
  /** 版本号比较(a < b :-1 | 0 | b < a :1) */
19
- export declare function versionCompare(a: string, b: string): 0 | 1 | -1;
20
- /** 初始化 marked */
21
- export declare function initMarked(ctx: Context): void;
22
- /** 解析 markdown */
23
- export declare function marked(ctx: Context, src: string): string;
19
+ export declare function versionCompare(a: string, b: string): 1 | 0 | -1;
24
20
  /** 获取修正后的 UserAgent */
25
21
  export declare function getCorrectUserAgent(): Promise<string>;
26
22
  /** 是否为完整的 URL */
@@ -2,13 +2,18 @@ import { ListData, CommentData, NotifyData } from '../../types/artalk-data';
2
2
  import Context from '../../types/context';
3
3
  import Component from '../lib/component';
4
4
  import Comment from '../comment';
5
- import Pagination from '../components/pagination';
6
- import ReadMoreBtn from '../components/read-more-btn';
5
+ import PgHolder, { TPgMode } from './paginator';
7
6
  import * as ListNest from './list-nest';
8
7
  export default class ListLite extends Component {
8
+ /** 列表评论集区域元素 */
9
9
  protected $commentsWrap: HTMLElement;
10
+ /** 最后一次请求得到的列表数据 */
10
11
  protected data?: ListData;
12
+ /** 是否处于加载中状态 */
11
13
  protected isLoading: boolean;
14
+ /** 配置是否已加载 */
15
+ private confLoaded;
16
+ /** 无评论显示文字 */
12
17
  noCommentText?: string;
13
18
  /** 嵌套模式下的排序方式 */
14
19
  private _nestSortBy?;
@@ -19,36 +24,37 @@ export default class ListLite extends Component {
19
24
  get flatMode(): boolean;
20
25
  set flatMode(val: boolean);
21
26
  /** 分页方式 */
22
- _pageMode?: 'pagination' | 'read-more';
27
+ _pageMode?: TPgMode;
23
28
  get pageMode(): 'pagination' | 'read-more';
24
29
  set pageMode(val: 'pagination' | 'read-more');
30
+ /** 分页方式持有者 */
31
+ pgHolder?: PgHolder;
25
32
  /** 每页数量 (每次请求获取量) */
26
33
  private _pageSize?;
27
34
  get pageSize(): number;
28
35
  set pageSize(val: number);
36
+ /** 监听指定元素上的滚动 */
29
37
  scrollListenerAt?: HTMLElement;
38
+ /** 翻页归位到指定元素 */
30
39
  repositionAt?: HTMLElement;
31
- protected pagination?: Pagination;
32
- protected readMoreBtn?: ReadMoreBtn;
33
- protected autoLoadScrollEvent?: any;
34
40
  renderComment?: (comment: Comment) => void;
35
41
  paramsEditor?: (params: any) => void;
36
42
  onAfterLoad?: (data: ListData) => void;
43
+ /** 未读标记 */
37
44
  protected unread: NotifyData[];
38
45
  unreadHighlight?: boolean;
39
46
  constructor(ctx: Context);
40
47
  getData(): ListData | undefined;
41
48
  clearData(): void;
49
+ getLoading(): boolean;
42
50
  getCommentsWrapEl(): HTMLElement;
43
- /** 加载动画 */
51
+ /** 设置加载状态 */
44
52
  setLoading(val: boolean, isFirstLoad?: boolean): void;
45
53
  /** 评论获取 */
46
54
  fetchComments(offset: number): Promise<void>;
47
- private confLoaded;
48
55
  protected onLoad(data: ListData, offset: number): void;
49
56
  /** 分页模式 */
50
57
  private refreshPagination;
51
- private initPagination;
52
58
  /** 错误处理 */
53
59
  protected onError(msg: any, offset: number, errData?: any): void;
54
60
  /** 刷新界面 */
@@ -68,6 +74,4 @@ export default class ListLite extends Component {
68
74
  updateComment(commentData: CommentData): void;
69
75
  /** 更新未读数据 */
70
76
  updateUnread(notifies: NotifyData[]): void;
71
- /** 版本检测 */
72
- versionCheck(name: 'frontend' | 'backend', needVersion: string, curtVersion: string): boolean;
73
77
  }
@@ -1,10 +1,10 @@
1
1
  import { CommentData } from '../../types/artalk-data';
2
- export declare type CommentNode = {
2
+ export type CommentNode = {
3
3
  id: number;
4
4
  comment: CommentData;
5
5
  children: CommentNode[];
6
6
  parent?: CommentNode;
7
7
  level: number;
8
8
  };
9
- export declare type SortByType = 'DATE_DESC' | 'DATE_ASC' | 'SRC_INDEX' | 'VOTE_UP_DESC';
9
+ export type SortByType = 'DATE_DESC' | 'DATE_ASC' | 'SRC_INDEX' | 'VOTE_UP_DESC';
10
10
  export declare function makeNestCommentNodeList(srcData: CommentData[], sortBy?: SortByType, nestMax?: number): CommentNode[];
@@ -0,0 +1,7 @@
1
+ import ListLite from './list-lite';
2
+ /** 界面刷新 */
3
+ export declare function refreshUI(list: ListLite): void;
4
+ /** 构建错误提示界面 */
5
+ export declare function renderErrorDialog(list: ListLite, errMsg: string, errData?: any): HTMLElement;
6
+ /** 版本检测弹窗 */
7
+ export declare function versionCheckDialog(list: ListLite, feVer: string, beVer: string): boolean;
@@ -0,0 +1,12 @@
1
+ import { IPgHolderConf, TPgMode } from '../index';
2
+ declare const Adaptors: Record<TPgMode, IPgAdaptor<any>>;
3
+ export default Adaptors;
4
+ export interface IPgAdaptor<T> {
5
+ instance: T;
6
+ el: HTMLElement;
7
+ createInstance(conf: IPgHolderConf): [T, HTMLElement];
8
+ setLoading(val: boolean): void;
9
+ update(offset: number, total: number): void;
10
+ next(): void;
11
+ showErr?(msg: string): void;
12
+ }
@@ -0,0 +1,9 @@
1
+ import Pagination from '../../../components/pagination';
2
+ import { IPgAdaptor } from '.';
3
+ interface IPaginationAdaptor extends IPgAdaptor<Pagination> {
4
+ }
5
+ /**
6
+ * 翻页形式的分页
7
+ */
8
+ declare const _default: IPaginationAdaptor;
9
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import ReadMoreBtn from '../../../components/read-more-btn';
2
+ import { IPgAdaptor } from '.';
3
+ interface IReadMoreAdaptor extends IPgAdaptor<ReadMoreBtn> {
4
+ autoLoadScrollEvent?: () => void;
5
+ }
6
+ /**
7
+ * 阅读更多形式的分页
8
+ */
9
+ declare const _default: IReadMoreAdaptor;
10
+ export default _default;
@@ -0,0 +1,16 @@
1
+ import { IPgHolderConf, TPgMode } from '.';
2
+ /**
3
+ * 分页方式持有者(调度器)
4
+ */
5
+ export default class PgHolder {
6
+ private conf;
7
+ constructor(conf: IPgHolderConf);
8
+ getAdaptor(): import("./adaptors").IPgAdaptor<any>;
9
+ init(): void;
10
+ setLoading(val: boolean): void;
11
+ update(offset: number, total: number): void;
12
+ getEl(): HTMLElement;
13
+ showErr(msg: string): void;
14
+ setMode(val: TPgMode): void;
15
+ next(): void;
16
+ }
@@ -0,0 +1,10 @@
1
+ import ListLite from '../list-lite';
2
+ import PgHolder from './holder';
3
+ export type TPgMode = 'pagination' | 'read-more';
4
+ export interface IPgHolderConf {
5
+ list: ListLite;
6
+ mode: TPgMode;
7
+ total: number;
8
+ pageSize: number;
9
+ }
10
+ export default PgHolder;
@@ -0,0 +1,40 @@
1
+ import Context from '../types/context';
2
+ import CheckerLauncher from './lib/checker';
3
+ import Api from './api';
4
+ import Editor from './editor';
5
+ import SidebarLayer from './layer/sidebar-layer';
6
+ import User from './lib/user';
7
+ import ListLite from './list/list-lite';
8
+ /**
9
+ * Services
10
+ *
11
+ * @description
12
+ * 当函数有返回值时,该值将自动添加到 Context 类作为一个 private 成员的值,
13
+ * 这个成员的名称与函数名对应。可在 Context 类中访问该对象(同事类)。
14
+ */
15
+ declare const services: {
16
+ i18n(ctx: Context): void;
17
+ markdown(): void;
18
+ user(ctx: Context): User;
19
+ api(ctx: Context): Api;
20
+ checkerLauncher(ctx: Context): CheckerLauncher;
21
+ editor(ctx: Context): Editor;
22
+ list(ctx: Context): ListLite | undefined;
23
+ layer(ctx: Context): void;
24
+ sidebarLayer(ctx: Context): SidebarLayer;
25
+ eventsDefault(ctx: Context): void;
26
+ darkMode(ctx: Context): void;
27
+ };
28
+ export default services;
29
+ type TServiceImps = typeof services;
30
+ type TObjectWithFuncs = {
31
+ [k: string]: (...args: any) => any;
32
+ };
33
+ type TKeysOnlyReturn<T extends TObjectWithFuncs, V> = {
34
+ [K in keyof T]: ReturnType<T[K]> extends V ? K : never;
35
+ }[keyof T];
36
+ type TOmitConditions = TKeysOnlyReturn<TServiceImps, void>;
37
+ type TServiceInjectors = Omit<TServiceImps, TOmitConditions>;
38
+ export type TInjectedServices = {
39
+ [K in keyof TServiceInjectors]: ReturnType<TServiceInjectors[K]>;
40
+ };
@@ -26,7 +26,7 @@ export default interface ArtalkConfig {
26
26
  /** 发送按钮文字 */
27
27
  sendBtn: string
28
28
 
29
- /** 评论框旅行(显示在待回复评论后面) */
29
+ /** 评论框穿梭(显示在待回复评论后面) */
30
30
  editorTravel: boolean
31
31
 
32
32
  /** 表情包 */
@@ -60,6 +60,9 @@ export default interface ArtalkConfig {
60
60
 
61
61
  /** 子评论区域限高 */
62
62
  children: number
63
+
64
+ /** 滚动限高 */
65
+ scrollable: boolean
63
66
  }
64
67
 
65
68
  /** 评论投票按钮 */
@@ -77,7 +80,7 @@ export default interface ArtalkConfig {
77
80
  /** PV 数绑定元素 Selector */
78
81
  pvEl: string
79
82
 
80
- /** 暗黑模式 */
83
+ /** 夜间模式 */
81
84
  darkMode: boolean|'auto'
82
85
 
83
86
  /** 请求超时(单位:秒) */
@@ -44,6 +44,9 @@ export interface CommentData {
44
44
  /** 徽章颜色 */
45
45
  badge_color?: string
46
46
 
47
+ /** IP 归属地 */
48
+ ip_region?: string
49
+
47
50
  /** 是否允许回复 */
48
51
  is_allow_reply?: boolean
49
52
 
@@ -221,7 +224,4 @@ export interface ApiVersionData {
221
224
 
222
225
  /** API 程序 CommitHash */
223
226
  commit_hash: string
224
-
225
- /** API 程序要求前端最小版本 */
226
- fe_min_version: string
227
227
  }
@@ -1,15 +1,14 @@
1
- import { marked as libMarked } from 'marked'
2
1
  import ArtalkConfig from './artalk-config'
3
2
  import { CommentData, NotifyData } from './artalk-data'
4
3
  import { EventPayloadMap, Event, EventScopeType, Handler } from './event'
5
4
  import { internal as internalLocales, I18n } from '../src/i18n'
6
5
  import Api from '../src/api'
7
6
  import User from '../src/lib/user'
8
- import Editor from '../src/editor'
9
7
  import Comment from '../src/comment'
10
- import ListLite from '../src/list/list-lite'
11
- import SidebarLayer, { SidebarShowPayload } from '../src/layer/sidebar-layer'
12
- import CheckerLauncher, { CheckerCaptchaPayload, CheckerPayload } from '../src/lib/checker'
8
+ import { SidebarShowPayload } from '../src/layer/sidebar-layer'
9
+ import { CheckerCaptchaPayload, CheckerPayload } from '../src/lib/checker'
10
+ import type { TMarked } from '../src/lib/marked'
11
+ import type { TInjectedServices } from '../src/service'
13
12
 
14
13
  /**
15
14
  * Context 接口
@@ -17,31 +16,26 @@ import CheckerLauncher, { CheckerCaptchaPayload, CheckerPayload } from '../src/l
17
16
  * (面向接口的编程)
18
17
  */
19
18
  export default interface ContextApi {
20
- /** Context 唯一标识 */
21
- cid: number
22
-
23
19
  /** Artalk 根元素对象 */
24
20
  $root: HTMLElement
25
21
 
22
+ /** 依赖注入函数 */
23
+ inject<K extends keyof TInjectedServices>(depName: K, obj: TInjectedServices[K]): void
24
+
26
25
  /** 配置对象 */
26
+ // TODO 修改为 getConf() 和 setConf()
27
27
  conf: ArtalkConfig
28
28
 
29
29
  /** 用户对象 */
30
+ // TODO 修改为 getUser()
30
31
  user: User
31
32
 
32
33
  /** marked 依赖对象 */
33
- markedInstance?: typeof libMarked
34
+ getMarkedInstance(): TMarked | undefined
34
35
 
35
36
  /** marked 内容替换器 */
36
37
  markedReplacers: ((raw: string) => string)[]
37
38
 
38
- /* 设置持有的同事类 (中介者模式) */
39
- setApi(api: Api): void
40
- setEditor(editor: Editor): void
41
- setList(list?: ListLite): void
42
- setSidebarLayer(list: SidebarLayer): void
43
- setCheckerLauncher(checkerLauncher: CheckerLauncher): void
44
-
45
39
  /** 获取 API 以供 HTTP 请求 */
46
40
  getApi(): Api
47
41
 
@@ -141,7 +135,7 @@ export default interface ContextApi {
141
135
  /** i18n 翻译 */
142
136
  $t(key: keyof I18n, args?: {[key: string]: string}): string
143
137
 
144
- /** 设置暗黑模式 */
138
+ /** 设置夜间模式 */
145
139
  setDarkMode(darkMode: boolean): void
146
140
 
147
141
  /** 更新配置 */
@@ -0,0 +1 @@
1
+ declare const ARTALK_LITE: boolean
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "artalk",
3
- "version": "2.4.3",
4
- "backendMinVersion": "2.3.0",
3
+ "version": "2.5.0",
5
4
  "license": "LGPL-3.0",
6
5
  "description": "A Selfhosted Comment System",
7
6
  "keywords": [
@@ -14,7 +13,7 @@
14
13
  "repository": {
15
14
  "type": "git",
16
15
  "url": "https://github.com/ArtalkJS/Artalk.git",
17
- "directory": "packages/artalk"
16
+ "directory": "ui/packages/artalk"
18
17
  },
19
18
  "homepage": "https://artalk.js.org",
20
19
  "bugs": "https://github.com/ArtalkJS/Artalk/issue",
@@ -24,17 +23,17 @@
24
23
  "module": "./dist/Artalk.es.js",
25
24
  "types": "./dist/src/main.d.ts",
26
25
  "devDependencies": {
27
- "@types/marked": "4.0.6"
26
+ "@types/marked": "4.0.8"
28
27
  },
29
28
  "dependencies": {
29
+ "abortcontroller-polyfill": "^1.7.5",
30
30
  "hanabi": "^0.4.0",
31
31
  "insane": "^2.6.2",
32
- "marked": "^4.0.19",
33
- "abortcontroller-polyfill": "^1.7.3"
32
+ "marked": "^4.2.12"
34
33
  },
35
34
  "scripts": {
36
35
  "dev": "vite",
37
- "build": "pnpm lint && vite build && pnpm build:lite && pnpm build:i18n",
36
+ "build": "vite build && pnpm build:lite && pnpm build:i18n",
38
37
  "build:lite": "vite build --config vite-lite.config.ts",
39
38
  "build:i18n": "node scripts/build-i18n.mjs",
40
39
  "build:demo": "vite build --config vite-demo.config.ts",
package/src/api/system.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import ArtalkConfig from '~/types/artalk-config'
2
2
  import ApiBase from './api-base'
3
+ import { handleBackendRefConf } from '../config'
3
4
 
4
5
  /**
5
6
  * 系统 API
@@ -10,22 +11,12 @@ export default class SystemApi extends ApiBase {
10
11
  const data = await this.POST<any>(`/conf`)
11
12
  const conf = (data.frontend_conf || {}) as ArtalkConfig
12
13
 
13
- // Patch: `emoticons` config string to json
14
- if (conf.emoticons && typeof conf.emoticons === "string") {
15
- conf.emoticons = conf.emoticons.trim()
16
- if (conf.emoticons.startsWith("[") || conf.emoticons.startsWith("{")) {
17
- conf.emoticons = JSON.parse(conf.emoticons) // pase json
18
- } else if (conf.emoticons === "false") {
19
- conf.emoticons = false
20
- }
21
- }
22
-
23
- return conf
14
+ return handleBackendRefConf(conf)
24
15
  }
25
16
 
26
17
  /** 获取配置数据 */
27
18
  public async getSettings() {
28
- const data = await this.POST<string>('/admin/setting-get')
19
+ const data = await this.POST<{custom: string, template: string}>('/admin/setting-get')
29
20
  return data
30
21
  }
31
22