artalk 2.7.0 → 2.7.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 (175) hide show
  1. package/README.md +1 -1
  2. package/dist/Artalk.css +1 -1
  3. package/dist/Artalk.es.js +209 -188
  4. package/dist/Artalk.es.js.map +1 -0
  5. package/dist/Artalk.iife.js +2 -1
  6. package/dist/Artalk.iife.js.map +1 -0
  7. package/dist/Artalk.js +2 -1
  8. package/dist/Artalk.js.map +1 -0
  9. package/dist/ArtalkLite.css +1 -1
  10. package/dist/ArtalkLite.es.js +209 -188
  11. package/dist/ArtalkLite.es.js.map +1 -0
  12. package/dist/ArtalkLite.iife.js +2 -1
  13. package/dist/ArtalkLite.iife.js.map +1 -0
  14. package/dist/ArtalkLite.js +2 -1
  15. package/dist/ArtalkLite.js.map +1 -0
  16. package/dist/i18n/jp.js +1 -1
  17. package/dist/i18n/zh-TW.js +1 -1
  18. package/dist/src/api/_base.d.ts +7 -0
  19. package/dist/src/api/_options.d.ts +5 -0
  20. package/dist/src/artalk.d.ts +0 -2
  21. package/dist/src/components/checker/index.d.ts +2 -0
  22. package/dist/src/i18n/en.d.ts +4 -0
  23. package/dist/src/i18n/external.d.ts +4 -0
  24. package/dist/src/i18n/index.d.ts +12 -0
  25. package/dist/src/i18n/jp.d.ts +4 -0
  26. package/dist/src/i18n/zh-TW.d.ts +4 -0
  27. package/dist/src/lib/user.d.ts +8 -6
  28. package/dist/src/main.d.ts +3 -0
  29. package/dist/src/plugins/editor/_kit.d.ts +7 -1
  30. package/dist/src/service.d.ts +2 -8
  31. package/dist/types/event.d.ts +1 -1
  32. package/package.json +43 -17
  33. package/dist/src/components/dark-mode.d.ts +0 -2
  34. package/src/api/_base.ts +0 -18
  35. package/src/api/_options.ts +0 -25
  36. package/src/api/_request.ts +0 -104
  37. package/src/api/admin.ts +0 -18
  38. package/src/api/captcha.ts +0 -24
  39. package/src/api/comment.ts +0 -84
  40. package/src/api/index.ts +0 -29
  41. package/src/api/page.ts +0 -83
  42. package/src/api/site.ts +0 -51
  43. package/src/api/system.ts +0 -49
  44. package/src/api/upload.ts +0 -28
  45. package/src/api/user.ts +0 -132
  46. package/src/artalk.ts +0 -119
  47. package/src/comment/actions.ts +0 -83
  48. package/src/comment/comment.html +0 -18
  49. package/src/comment/comment.ts +0 -192
  50. package/src/comment/height-limit.ts +0 -100
  51. package/src/comment/index.ts +0 -3
  52. package/src/comment/render.ts +0 -150
  53. package/src/comment/renders/actions.ts +0 -114
  54. package/src/comment/renders/avatar.ts +0 -22
  55. package/src/comment/renders/content.ts +0 -39
  56. package/src/comment/renders/header.ts +0 -84
  57. package/src/comment/renders/index.ts +0 -19
  58. package/src/comment/renders/pending.ts +0 -12
  59. package/src/comment/renders/reply-at.ts +0 -16
  60. package/src/comment/renders/reply-to.ts +0 -24
  61. package/src/components/action-btn.ts +0 -170
  62. package/src/components/checker/admin.ts +0 -37
  63. package/src/components/checker/captcha-renders.ts +0 -69
  64. package/src/components/checker/captcha.ts +0 -26
  65. package/src/components/checker/index.ts +0 -192
  66. package/src/components/dark-mode.ts +0 -30
  67. package/src/components/dialog.ts +0 -62
  68. package/src/components/error-dialog.ts +0 -35
  69. package/src/components/pagination.ts +0 -153
  70. package/src/components/read-more-btn.ts +0 -92
  71. package/src/config.ts +0 -119
  72. package/src/context.ts +0 -146
  73. package/src/data.ts +0 -110
  74. package/src/defaults.ts +0 -61
  75. package/src/editor/editor.html +0 -18
  76. package/src/editor/editor.ts +0 -114
  77. package/src/editor/state.ts +0 -52
  78. package/src/editor/ui.ts +0 -36
  79. package/src/i18n/en.ts +0 -81
  80. package/src/i18n/external.ts +0 -10
  81. package/src/i18n/index.ts +0 -67
  82. package/src/i18n/jp.ts +0 -83
  83. package/src/i18n/zh-CN.ts +0 -85
  84. package/src/i18n/zh-TW.ts +0 -83
  85. package/src/layer/index.ts +0 -4
  86. package/src/layer/layer-manager.ts +0 -32
  87. package/src/layer/layer.ts +0 -39
  88. package/src/layer/scrollbar-helper.ts +0 -24
  89. package/src/layer/sidebar-layer.html +0 -8
  90. package/src/layer/sidebar-layer.ts +0 -155
  91. package/src/layer/wrap.ts +0 -77
  92. package/src/lib/component.ts +0 -12
  93. package/src/lib/detect.ts +0 -222
  94. package/src/lib/event-manager.ts +0 -47
  95. package/src/lib/highlight.ts +0 -5
  96. package/src/lib/marked-renderer.ts +0 -32
  97. package/src/lib/marked.ts +0 -72
  98. package/src/lib/sanitizer.ts +0 -57
  99. package/src/lib/ui.ts +0 -193
  100. package/src/lib/user.ts +0 -55
  101. package/src/lib/utils.ts +0 -236
  102. package/src/list/comment.ts +0 -20
  103. package/src/list/layout.ts +0 -120
  104. package/src/list/list.html +0 -20
  105. package/src/list/list.ts +0 -79
  106. package/src/list/nest.ts +0 -66
  107. package/src/list/page.ts +0 -97
  108. package/src/list/paginator/index.ts +0 -25
  109. package/src/list/paginator/read-more.ts +0 -67
  110. package/src/list/paginator/up-down.ts +0 -51
  111. package/src/main.ts +0 -5
  112. package/src/plugins/admin-only-elem.ts +0 -40
  113. package/src/plugins/conf-remoter.ts +0 -54
  114. package/src/plugins/dark-mode.ts +0 -12
  115. package/src/plugins/editor/_kit.ts +0 -57
  116. package/src/plugins/editor/_plug.ts +0 -60
  117. package/src/plugins/editor/_sample.ts +0 -8
  118. package/src/plugins/editor/closable.ts +0 -44
  119. package/src/plugins/editor/emoticons.scss +0 -72
  120. package/src/plugins/editor/emoticons.ts +0 -293
  121. package/src/plugins/editor/header-event.ts +0 -35
  122. package/src/plugins/editor/header-link.ts +0 -31
  123. package/src/plugins/editor/header-user.ts +0 -98
  124. package/src/plugins/editor/index.ts +0 -40
  125. package/src/plugins/editor/local-storage.ts +0 -36
  126. package/src/plugins/editor/mover.ts +0 -29
  127. package/src/plugins/editor/preview.scss +0 -7
  128. package/src/plugins/editor/preview.ts +0 -41
  129. package/src/plugins/editor/state-edit.ts +0 -116
  130. package/src/plugins/editor/state-reply.ts +0 -91
  131. package/src/plugins/editor/submit-add.ts +0 -33
  132. package/src/plugins/editor/submit-btn.ts +0 -25
  133. package/src/plugins/editor/submit.ts +0 -73
  134. package/src/plugins/editor/textarea.ts +0 -55
  135. package/src/plugins/editor/upload.ts +0 -145
  136. package/src/plugins/editor-kit.ts +0 -161
  137. package/src/plugins/index.ts +0 -16
  138. package/src/plugins/list/copyright.ts +0 -16
  139. package/src/plugins/list/count.ts +0 -31
  140. package/src/plugins/list/dropdown.ts +0 -95
  141. package/src/plugins/list/error-dialog.ts +0 -22
  142. package/src/plugins/list/fetch.ts +0 -64
  143. package/src/plugins/list/goto-first.ts +0 -23
  144. package/src/plugins/list/goto.ts +0 -72
  145. package/src/plugins/list/index.ts +0 -25
  146. package/src/plugins/list/loading.ts +0 -17
  147. package/src/plugins/list/no-comment.ts +0 -25
  148. package/src/plugins/list/reach-bottom.ts +0 -46
  149. package/src/plugins/list/sidebar-btn.ts +0 -39
  150. package/src/plugins/list/time-ticking.ts +0 -22
  151. package/src/plugins/list/unread-badge.ts +0 -26
  152. package/src/plugins/list/unread.ts +0 -38
  153. package/src/plugins/list/with-editor.ts +0 -59
  154. package/src/plugins/markdown.ts +0 -10
  155. package/src/plugins/stat.ts +0 -79
  156. package/src/plugins/version-check.ts +0 -37
  157. package/src/service.ts +0 -91
  158. package/src/style/_color.scss +0 -41
  159. package/src/style/_extend.scss +0 -20
  160. package/src/style/_variables.scss +0 -3
  161. package/src/style/comment.scss +0 -360
  162. package/src/style/editor.scss +0 -194
  163. package/src/style/list.scss +0 -212
  164. package/src/style/main.scss +0 -486
  165. package/src/style/pagination.scss +0 -58
  166. package/src/style/sidebar-layer.scss +0 -92
  167. package/types/config.ts +0 -153
  168. package/types/context.ts +0 -84
  169. package/types/data.ts +0 -271
  170. package/types/editor.ts +0 -95
  171. package/types/event.ts +0 -40
  172. package/types/global.d.ts +0 -1
  173. package/types/index.ts +0 -7
  174. package/types/plugin.ts +0 -3
  175. package/types/sidebar.ts +0 -3
@@ -1,120 +0,0 @@
1
- import type { CommentData } from '~/types'
2
- import * as Ui from '@/lib/ui'
3
- import Comment from '../comment/comment'
4
- import * as ListNest from './nest'
5
-
6
- export interface LayoutOptions {
7
- $commentsWrap: HTMLElement
8
- nestSortBy: ListNest.SortByType
9
- nestMax: number
10
- flatMode: boolean
11
-
12
- createCommentNode(comment: CommentData, ctxComments: CommentData[]): Comment
13
- findCommentNode(id: number): Comment|undefined
14
- getCommentDataList(): CommentData[]
15
- }
16
-
17
- export default class ListLayout {
18
- constructor(private options: LayoutOptions) {}
19
-
20
- // TODO refactor `if syntax` to strategy pattern
21
- import(comments: CommentData[]) {
22
- if (this.options.flatMode) {
23
- comments.forEach((commentData: CommentData) => {
24
- this.putCommentFlatMode(commentData, comments, 'append')
25
- })
26
- } else {
27
- this.importCommentsNestMode(comments)
28
- }
29
- }
30
-
31
- insert(comment: CommentData) {
32
- if (!this.options.flatMode) {
33
- this.insertCommentNest(comment)
34
- } else {
35
- this.insertCommentFlatMode(comment)
36
- }
37
- }
38
-
39
- // 导入评论 · 嵌套模式
40
- private importCommentsNestMode(srcData: CommentData[]) {
41
- // 遍历 root 评论
42
- const rootNodes = ListNest.makeNestCommentNodeList(srcData, this.options.nestSortBy, this.options.nestMax)
43
- rootNodes.forEach((rootNode: ListNest.CommentNode) => {
44
- const rootC = this.options.createCommentNode(rootNode.comment, srcData)
45
-
46
- // 显示并播放渐入动画
47
- this.options.$commentsWrap?.appendChild(rootC.getEl())
48
- rootC.getRender().playFadeAnim()
49
-
50
- // 加载子评论
51
- const loadChildren = (parentC: Comment, parentNode: ListNest.CommentNode) => {
52
- parentNode.children.forEach((node: ListNest.CommentNode) => {
53
- const childD = node.comment
54
- const childC = this.options.createCommentNode(childD, srcData)
55
-
56
- // 插入到父评论中
57
- parentC.putChild(childC)
58
-
59
- // 递归加载子评论
60
- loadChildren(childC, node)
61
- })
62
- }
63
- loadChildren(rootC, rootNode)
64
-
65
- // 限高检测
66
- rootC.getRender().checkHeightLimit()
67
- })
68
- }
69
-
70
- /** 导入评论 · 平铺模式 */
71
- private putCommentFlatMode(cData: CommentData, ctxData: CommentData[], insertMode: 'append'|'prepend') {
72
- if (cData.is_collapsed) cData.is_allow_reply = false
73
- const comment = this.options.createCommentNode(cData, ctxData)
74
-
75
- // 可见评论添加到界面
76
- // 注:不可见评论用于显示 “引用内容”
77
- if (cData.visible) {
78
- if (insertMode === 'append') this.options.$commentsWrap?.append(comment.getEl())
79
- if (insertMode === 'prepend') this.options.$commentsWrap?.prepend(comment.getEl())
80
- comment.getRender().playFadeAnim()
81
- }
82
-
83
- // 平铺评论插入后 · 内容限高检测
84
- comment.getRender().checkHeightLimit()
85
-
86
- return comment
87
- }
88
-
89
- private insertCommentNest(commentData: CommentData) {
90
- // 嵌套模式
91
- const comment = this.options.createCommentNode(commentData, this.options.getCommentDataList())
92
-
93
- if (commentData.rid === 0) {
94
- // root评论 新增
95
- this.options.$commentsWrap?.prepend(comment.getEl())
96
- } else {
97
- // 子评论 新增
98
- const parent = this.options.findCommentNode(commentData.rid)
99
- if (parent) {
100
- parent.putChild(comment, (this.options.nestSortBy === 'DATE_ASC' ? 'append' : 'prepend'))
101
-
102
- // 若父评论存在 “子评论部分” 限高,取消限高
103
- comment.getParents().forEach((p) => {
104
- p.getRender().heightLimitRemoveForChildren()
105
- })
106
- }
107
- }
108
-
109
- comment.getRender().checkHeightLimit()
110
-
111
- Ui.scrollIntoView(comment.getEl()) // 滚动到可以见
112
- comment.getRender().playFadeAnim() // 播放评论渐出动画
113
- }
114
-
115
- private insertCommentFlatMode(commentData: CommentData) {
116
- // 平铺模式
117
- const comment = this.putCommentFlatMode(commentData, this.options.getCommentDataList(), 'prepend')
118
- Ui.scrollIntoView(comment.getEl()) // 滚动到可见
119
- }
120
- }
@@ -1,20 +0,0 @@
1
- <div class="atk-list">
2
- <div class="atk-list-header">
3
- <div class="atk-comment-count">
4
- <div class="atk-text"></div>
5
- </div>
6
- <div class="atk-right-action">
7
- <span data-action="admin-close-comment" class="atk-hide" atk-only-admin-show></span>
8
- <span data-action="open-sidebar" class="atk-hide atk-on">
9
- <span class="atk-unread-badge" style="display: none;"></span>
10
- <div class="atk-text"></div>
11
- </span>
12
- </div>
13
- </div>
14
- <div class="atk-list-body">
15
- <div class="atk-list-comments-wrap"></div>
16
- </div>
17
- <div class="atk-list-footer">
18
- <div class="atk-copyright"></div>
19
- </div>
20
- </div>
package/src/list/list.ts DELETED
@@ -1,79 +0,0 @@
1
- import type { ContextApi } from '~/types'
2
- import Component from '../lib/component'
3
- import * as Utils from '../lib/utils'
4
- import CommentNode from '../comment/comment'
5
- import ListHTML from './list.html?raw'
6
- import ListLayout from './layout'
7
- import { createComment as createCommentNode } from './comment'
8
- import { initListPaginatorFunc } from './page'
9
-
10
- export default class List extends Component {
11
- /** 列表评论集区域元素 */
12
- $commentsWrap!: HTMLElement
13
- public getCommentsWrapEl() { return this.$commentsWrap }
14
-
15
- protected commentNodes: CommentNode[] = []
16
- getCommentNodes() { return this.commentNodes }
17
-
18
- constructor (ctx: ContextApi) {
19
- super(ctx)
20
-
21
- // Init base element
22
- this.$el = Utils.createElement(ListHTML)
23
- this.$commentsWrap = this.$el.querySelector('.atk-list-comments-wrap')!
24
-
25
- // Init paginator
26
- initListPaginatorFunc(ctx)
27
-
28
- // Bind events
29
- this.initCrudEvents()
30
- }
31
-
32
- getListLayout() {
33
- return new ListLayout({
34
- $commentsWrap: this.$commentsWrap,
35
- nestSortBy: this.ctx.conf.nestSort,
36
- nestMax: this.ctx.conf.nestMax,
37
- flatMode: this.ctx.conf.flatMode as boolean,
38
- // flatMode must be boolean because it had been handled when Artalk.init
39
- createCommentNode: (d, c) => {
40
- const node = createCommentNode(this.ctx, d, c)
41
- this.commentNodes.push(node)
42
- return node
43
- },
44
- findCommentNode: (id) => this.commentNodes.find(c => c.getID() === id),
45
- getCommentDataList: () => this.ctx.getData().getComments(),
46
- })
47
- }
48
-
49
- private initCrudEvents() {
50
- this.ctx.on('list-load', (comments) => {
51
- // 导入数据
52
- this.getListLayout().import(comments)
53
- })
54
-
55
- this.ctx.on('list-loaded', (comments) => {
56
- if (comments.length === 0) this.$commentsWrap.innerHTML = ''
57
- })
58
-
59
- // When comment insert
60
- this.ctx.on('comment-inserted', (comment) => {
61
- this.getListLayout().insert(comment)
62
- })
63
-
64
- // When comment delete
65
- this.ctx.on('comment-deleted', (comment) => {
66
- const node = this.commentNodes.find(c => c.getID() === comment.id)
67
- if (!node) { console.error(`comment node id=${comment.id} not found`);return }
68
- node.getEl().remove()
69
- this.commentNodes = this.commentNodes.filter(c => c.getID() !== comment.id)
70
- // TODO remove child nodes
71
- })
72
-
73
- // When comment update
74
- this.ctx.on('comment-updated', (comment) => {
75
- const node = this.commentNodes.find(c => c.getID() === comment.id)
76
- node && node.setData(comment)
77
- })
78
- }
79
- }
package/src/list/nest.ts DELETED
@@ -1,66 +0,0 @@
1
- import type { CommentData } from '~/types'
2
-
3
- export type CommentNode = {
4
- id: number
5
- comment: CommentData
6
- children: CommentNode[]
7
- parent?: CommentNode
8
- level: number
9
- }
10
-
11
- export type SortByType = 'DATE_DESC'|'DATE_ASC'|'SRC_INDEX'|'VOTE_UP_DESC'
12
-
13
- // 构建树状结构列表
14
- export function makeNestCommentNodeList(srcData: CommentData[], sortBy: SortByType = 'DATE_DESC', nestMax = 2) {
15
- const nodeList: CommentNode[] = []
16
-
17
- const roots = srcData.filter((o) => o.rid === 0)
18
- roots.forEach((root: CommentData) => {
19
- const rootNode: CommentNode = {
20
- id: root.id,
21
- comment: root,
22
- children: [],
23
- level: 1,
24
- }
25
-
26
- rootNode.parent = rootNode
27
- nodeList.push(rootNode)
28
-
29
- ;(function loadChildren(parentNode: CommentNode) {
30
- const children = srcData.filter((o) => o.rid === parentNode.id)
31
- if (children.length === 0) return
32
- if (parentNode.level >= nestMax) parentNode = parentNode.parent!
33
- children.forEach((child: CommentData) => {
34
- const childNode: CommentNode = {
35
- id: child.id,
36
- comment: child,
37
- children: [],
38
- parent: parentNode,
39
- level: parentNode.level + 1,
40
- }
41
-
42
- parentNode.children.push(childNode)
43
- loadChildren(childNode)
44
- })
45
- })(rootNode)
46
- })
47
-
48
- // 排序
49
- const sortFunc = (a: CommentNode, b: CommentNode): number => {
50
- let v = a.id - b.id
51
- if (sortBy === 'DATE_ASC') v = +new Date(a.comment.date) - +new Date(b.comment.date)
52
- else if (sortBy === 'DATE_DESC') v = +new Date(b.comment.date) - +new Date(a.comment.date)
53
- else if (sortBy === 'SRC_INDEX') v = srcData.indexOf(a.comment) - srcData.indexOf(b.comment)
54
- else if (sortBy === 'VOTE_UP_DESC') v = b.comment.vote_up - a.comment.vote_up
55
- return v
56
- }
57
-
58
- (function sortLevels(nodes: CommentNode[]) {
59
- nodes.forEach((node) => {
60
- node.children = node.children.sort(sortFunc)
61
- sortLevels(node.children)
62
- })
63
- })(nodeList)
64
-
65
- return nodeList
66
- }
package/src/list/page.ts DELETED
@@ -1,97 +0,0 @@
1
- import type { ArtalkConfig, ContextApi } from '~/types'
2
- import $t from '@/i18n'
3
- import { Paginator } from './paginator'
4
- import ReadMorePaginator from './paginator/read-more'
5
- import UpDownPaginator from './paginator/up-down'
6
-
7
- function createPaginatorByConf(conf: ArtalkConfig): Paginator {
8
- if (conf.pagination.readMore) return new ReadMorePaginator()
9
- return new UpDownPaginator()
10
- }
11
-
12
- function getPageDataByLastData(ctx: ContextApi): { offset: number, total: number } {
13
- const last = ctx.getData().getListLastFetch()
14
- const r = { offset: 0, total: 0 }
15
- if (!last) return r
16
-
17
- r.offset = last.params.offset
18
- if (last.data) r.total = last.params.flatMode ? last.data.total : last.data.total_roots
19
-
20
- return r
21
- }
22
-
23
- export const initListPaginatorFunc = (ctx: ContextApi) => {
24
- let paginator: Paginator|null = null
25
-
26
- // Init paginator when conf loaded
27
- ctx.on('conf-loaded', (conf) => {
28
- const list = ctx.get('list')
29
-
30
- if (paginator) paginator.dispose() // if had been init, dispose it
31
-
32
- // create paginator instance
33
- paginator = createPaginatorByConf(conf)
34
-
35
- // create paginator dom
36
- const { offset, total } = getPageDataByLastData(ctx)
37
- const $paginator = paginator.create({
38
- ctx, pageSize: conf.pagination.pageSize, total,
39
-
40
- readMoreAutoLoad: conf.pagination.autoLoad,
41
- })
42
-
43
- // mount paginator dom
44
- list.$commentsWrap.after($paginator)
45
-
46
- // update paginator info
47
- paginator?.update(offset, total)
48
- })
49
-
50
- // When list loaded
51
- ctx.on('list-loaded', (comments) => {
52
- // update paginator info
53
- const { offset, total } = getPageDataByLastData(ctx)
54
- paginator?.update(offset, total)
55
- })
56
-
57
- // When list fetch
58
- ctx.on('list-fetch', (params) => {
59
- // if clear comments when fetch new page data
60
- if (ctx.getData().getComments().length > 0 && paginator?.getIsClearComments(params)) {
61
- ctx.getData().clearComments()
62
- }
63
- })
64
-
65
- // When list error
66
- ctx.on('list-error', () => {
67
- paginator?.showErr?.($t('loadFail'))
68
- })
69
-
70
- // List goto auto next page when comment not found
71
- const autoSwitchPageForFindComment = (commentID: number) => {
72
- const comment = ctx.getData().findComment(commentID)
73
- if (!!comment || !paginator?.getHasMore()) return
74
-
75
- // wait for list loaded
76
- ctx.on('list-loaded', () => {
77
- autoSwitchPageForFindComment(commentID) // recursive, until comment found or no more page
78
- }, { once: true })
79
-
80
- // TODO 自动范围改为直接跳转到计算后的页面
81
- setTimeout(() => {
82
- paginator?.next()
83
- }, 80)
84
- }
85
-
86
- ctx.on('list-goto', (commentID) => {
87
- autoSwitchPageForFindComment(commentID)
88
- })
89
-
90
- // loading
91
- ctx.on('list-fetch', (params) => {
92
- paginator?.setLoading(true)
93
- })
94
- ctx.on('list-fetched', ({ params }) => {
95
- paginator?.setLoading(false)
96
- })
97
- }
@@ -1,25 +0,0 @@
1
- import type { ContextApi, ListFetchParams } from '~/types'
2
- import UpDownPaginator from './up-down'
3
- import ReadMorePaginator from './read-more'
4
-
5
- export interface IPgHolderOpt {
6
- ctx: ContextApi
7
- total: number
8
- pageSize: number
9
-
10
- readMoreAutoLoad?: boolean
11
- }
12
-
13
- export interface Paginator {
14
- create(opts: IPgHolderOpt): HTMLElement
15
- setLoading(val: boolean): void
16
- update(offset: number, total: number): void
17
- next(): void
18
- showErr?(msg: string): void
19
- getHasMore(): boolean
20
- /** Clear comments when fetch new page data */
21
- getIsClearComments(params: Partial<ListFetchParams>): boolean
22
- dispose(): void
23
- }
24
-
25
- export default { UpDownPaginator, ReadMorePaginator }
@@ -1,67 +0,0 @@
1
- import type { ListFetchParams } from '~/types'
2
- import ReadMoreBtn from '@/components/read-more-btn'
3
- import $t from '@/i18n'
4
- import type { Paginator, IPgHolderOpt } from '.'
5
-
6
- /**
7
- * 阅读更多形式的分页
8
- */
9
- export default class ReadMorePaginator implements Paginator {
10
- private instance!: ReadMoreBtn
11
- private onReachedBottom: (() => void) | null = null
12
- private opt!: IPgHolderOpt
13
-
14
- create(opt: IPgHolderOpt) {
15
- this.opt = opt
16
-
17
- this.instance = new ReadMoreBtn({
18
- pageSize: opt.pageSize,
19
- onClick: async (o) => {
20
- opt.ctx.fetch({
21
- offset: o,
22
- })
23
- },
24
- text: $t('loadMore'),
25
- })
26
-
27
- // 滚动到底部自动加载
28
- if (opt.readMoreAutoLoad) {
29
- this.onReachedBottom = () => {
30
- if (!this.instance.hasMore || this.opt.ctx.getData().getLoading()) return
31
- this.instance.click()
32
- }
33
- this.opt.ctx.on('list-reach-bottom', this.onReachedBottom)
34
- }
35
-
36
- return this.instance.$el
37
- }
38
-
39
- setLoading(val: boolean) {
40
- this.instance.setLoading(val)
41
- }
42
-
43
- update(offset: number, total: number) {
44
- this.instance.update(offset, total)
45
- }
46
-
47
- showErr(msg: string) {
48
- this.instance.showErr(msg)
49
- }
50
-
51
- next() {
52
- this.instance.click()
53
- }
54
-
55
- getHasMore(): boolean {
56
- return this.instance.hasMore
57
- }
58
-
59
- getIsClearComments(params: Partial<ListFetchParams>): boolean {
60
- return params.offset === 0
61
- }
62
-
63
- dispose(): void {
64
- this.onReachedBottom && this.opt.ctx.off('list-reach-bottom', this.onReachedBottom)
65
- this.instance.$el.remove()
66
- }
67
- }
@@ -1,51 +0,0 @@
1
- import PaginationComponent from '@/components/pagination'
2
- import type { Paginator, IPgHolderOpt } from '.'
3
-
4
- /**
5
- * 翻页形式的分页
6
- */
7
- export default class UpDownPaginator implements Paginator {
8
- private instance!: PaginationComponent
9
-
10
- create(opt: IPgHolderOpt) {
11
- this.instance = new PaginationComponent(opt.total, {
12
- pageSize: opt.pageSize,
13
- onChange: async (o) => {
14
- opt.ctx.editorResetState() // 防止评论框被吞
15
-
16
- opt.ctx.fetch({
17
- offset: o,
18
- onSuccess: () => {
19
- opt.ctx.listGotoFirst()
20
- }
21
- })
22
- }
23
- })
24
-
25
- return this.instance.$el
26
- }
27
-
28
- setLoading(val: boolean) {
29
- this.instance.setLoading(val)
30
- }
31
-
32
- update(offset: number, total: number) {
33
- this.instance.update(offset, total)
34
- }
35
-
36
- next() {
37
- this.instance.next()
38
- }
39
-
40
- getHasMore(): boolean {
41
- return this.instance.getHasMore()
42
- }
43
-
44
- getIsClearComments(): boolean {
45
- return true
46
- }
47
-
48
- dispose(): void {
49
- this.instance.$el.remove()
50
- }
51
- }
package/src/main.ts DELETED
@@ -1,5 +0,0 @@
1
- import Artalk from './artalk'
2
- import * as ArtalkType from '../types'
3
-
4
- export { ArtalkType }
5
- export default Artalk
@@ -1,40 +0,0 @@
1
- import type { ArtalkPlugin } from '~/types'
2
-
3
- export const AdminOnlyElem: ArtalkPlugin = (ctx) => {
4
- const scanApply = () => {
5
- applyAdminOnlyEls(ctx.get('user').data.isAdmin, getAdminOnlyEls({
6
- $root: ctx.$root
7
- }))
8
- }
9
-
10
- ctx.on('list-loaded', () => {
11
- scanApply()
12
- })
13
-
14
- ctx.on('user-changed', (user) => {
15
- scanApply()
16
- })
17
- }
18
-
19
- function getAdminOnlyEls(opts: { $root: HTMLElement }): HTMLElement[] {
20
- const els: HTMLElement[] = []
21
-
22
- // elements in $root
23
- opts.$root.querySelectorAll<HTMLElement>(`[atk-only-admin-show]`).forEach(item => els.push(item))
24
-
25
- // TODO provide a Artalk.conf hook to set whitelist of admin-only elements,
26
- // and move following code to that hook (move into packages/artalk-sidebar)
27
-
28
- // elements in sidebar
29
- const $sidebarEl = document.querySelector<HTMLElement>('.atk-sidebar')
30
- if ($sidebarEl) $sidebarEl.querySelectorAll<HTMLElement>(`[atk-only-admin-show]`).forEach(item => els.push(item))
31
-
32
- return els
33
- }
34
-
35
- function applyAdminOnlyEls(isAdmin: boolean, els: HTMLElement[]) {
36
- els.forEach(($item: HTMLElement) => {
37
- if (isAdmin) $item.classList.remove('atk-hide')
38
- else $item.classList.add('atk-hide')
39
- })
40
- }
@@ -1,54 +0,0 @@
1
- import type { ArtalkConfig, ArtalkPlugin, ContextApi } from '~/types'
2
- import { handleConfFormServer } from '@/config'
3
- import { showErrorDialog } from '../components/error-dialog'
4
-
5
- export const ConfRemoter: ArtalkPlugin = (ctx) => {
6
- ctx.on('inited', () => {
7
- loadConf(ctx)
8
- })
9
- }
10
-
11
- function loadConf(ctx: ContextApi) {
12
- ctx.getApi().system.conf().then((data) => {
13
- let conf: Partial<ArtalkConfig> = {
14
- apiVersion: data.version.version, // version info
15
- }
16
-
17
- // reference conf from backend
18
- if (ctx.conf.useBackendConf) {
19
- if (!data.frontend_conf) throw new Error('The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled')
20
- conf = { ...conf, ...handleConfFormServer(data.frontend_conf) }
21
- }
22
-
23
- // apply conf modifier
24
- ctx.conf.remoteConfModifier && ctx.conf.remoteConfModifier(conf)
25
-
26
- ctx.updateConf(conf)
27
- }).catch((err) => {
28
- ctx.updateConf({})
29
-
30
- let sidebarOpenView = ''
31
-
32
- // if response err_no_site, modify the sidebar open view to create site
33
- if (err.data?.err_no_site) {
34
- const viewLoadParam = { create_name: ctx.conf.site, create_urls: `${window.location.protocol}//${window.location.host}` }
35
- sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}`
36
- }
37
-
38
- showErrorDialog({
39
- $err: ctx.get('list').$el,
40
- errMsg: err.msg || String(err),
41
- errData: err.data,
42
- retryFn: () => loadConf(ctx),
43
- onOpenSidebar:() => ctx.showSidebar({
44
- view: sidebarOpenView as any
45
- })
46
- })
47
-
48
- throw err
49
- }).then(() => {
50
- // 评论获取
51
- if (ctx.conf.remoteConfModifier) return // only auto fetch when no remoteConfModifier
52
- ctx.fetch({ offset: 0 })
53
- }).catch(() => {})
54
- }
@@ -1,12 +0,0 @@
1
- import type { ArtalkPlugin } from '~/types'
2
- import { applyDarkMode } from '@/components/dark-mode'
3
-
4
- export const DarkMode: ArtalkPlugin = (ctx) => {
5
- const sync = () => {
6
- applyDarkMode([ctx.$root, ctx.get('layerManager').getEl()], ctx.conf.darkMode)
7
- }
8
-
9
- ctx.on('inited', () => sync())
10
- ctx.on('conf-loaded', () => sync())
11
- ctx.on('dark-mode-changed', () => sync())
12
- }