artalk 2.3.3 → 2.4.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 (105) hide show
  1. package/dist/Artalk.css +1 -1
  2. package/dist/Artalk.es.js +3184 -2888
  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 +3157 -2887
  7. package/dist/ArtalkLite.iife.js +1 -1
  8. package/dist/ArtalkLite.js +1 -1
  9. package/dist/src/api/admin.d.ts +10 -0
  10. package/dist/src/api/api-base.d.ts +14 -0
  11. package/dist/src/api/captcha.d.ts +14 -0
  12. package/dist/src/api/comment.d.ts +29 -0
  13. package/dist/src/api/index.d.ts +31 -0
  14. package/dist/src/api/page.d.ts +22 -0
  15. package/dist/src/api/request.d.ts +12 -0
  16. package/dist/src/api/site.d.ts +17 -0
  17. package/dist/src/api/system.d.ts +13 -0
  18. package/dist/src/api/upload.d.ts +11 -0
  19. package/dist/src/api/user.d.ts +28 -0
  20. package/dist/src/artalk.d.ts +56 -0
  21. package/dist/src/comment/actions.d.ts +17 -0
  22. package/dist/src/comment/comment.d.ts +67 -0
  23. package/dist/src/comment/index.d.ts +2 -0
  24. package/dist/src/comment/render.d.ts +76 -0
  25. package/dist/src/components/action-btn.d.ts +52 -0
  26. package/dist/src/components/dialog.d.ts +18 -0
  27. package/dist/src/components/pagination.d.ts +30 -0
  28. package/dist/src/components/read-more-btn.d.ts +33 -0
  29. package/dist/src/context.d.ts +72 -0
  30. package/dist/src/defaults.d.ts +3 -0
  31. package/dist/src/editor/editor.d.ts +84 -0
  32. package/dist/src/editor/index.d.ts +2 -0
  33. package/dist/src/editor/plugs/editor-plug.d.ts +26 -0
  34. package/dist/src/editor/plugs/emoticons-plug.d.ts +36 -0
  35. package/dist/src/editor/plugs/header-input-plug.d.ts +13 -0
  36. package/dist/src/editor/plugs/preview-plug.d.ts +10 -0
  37. package/dist/src/editor/plugs/upload-plug.d.ts +10 -0
  38. package/dist/src/i18n/en.d.ts +69 -0
  39. package/dist/src/i18n/index.d.ts +294 -0
  40. package/dist/src/i18n/zh-CN.d.ts +3 -0
  41. package/dist/src/layer/index.d.ts +3 -0
  42. package/dist/src/layer/layer.d.ts +32 -0
  43. package/dist/src/layer/sidebar-layer.d.ts +20 -0
  44. package/dist/src/lib/checker/admin-checker.d.ts +3 -0
  45. package/dist/src/lib/checker/captcha-checker.d.ts +3 -0
  46. package/dist/src/lib/checker/index.d.ts +42 -0
  47. package/dist/src/lib/component.d.ts +12 -0
  48. package/dist/src/lib/detect.d.ts +10 -0
  49. package/dist/src/lib/stat.d.ts +15 -0
  50. package/dist/src/lib/ui.d.ts +23 -0
  51. package/dist/src/lib/user.d.ts +13 -0
  52. package/dist/src/lib/utils.d.ts +39 -0
  53. package/dist/src/list/index.d.ts +2 -0
  54. package/dist/src/list/list-lite.d.ts +63 -0
  55. package/dist/src/list/list-nest.d.ts +10 -0
  56. package/dist/src/list/list.d.ts +26 -0
  57. package/dist/src/main.d.ts +4 -0
  58. package/dist/types/artalk-config.d.ts +132 -0
  59. package/dist/types/artalk-data.d.ts +204 -0
  60. package/dist/types/context.d.ts +146 -0
  61. package/dist/types/event.d.ts +28 -0
  62. package/dist/types/global.d.ts +0 -0
  63. package/dist/types/plug.d.ts +4 -0
  64. package/index.html +3 -3
  65. package/package.json +5 -5
  66. package/src/api/admin.ts +18 -0
  67. package/src/api/api-base.ts +27 -0
  68. package/src/api/captcha.ts +24 -0
  69. package/src/api/comment.ts +84 -0
  70. package/src/api/index.ts +25 -361
  71. package/src/api/page.ts +85 -0
  72. package/src/api/request.ts +12 -8
  73. package/src/api/site.ts +51 -0
  74. package/src/api/system.ts +39 -0
  75. package/src/api/upload.ts +29 -0
  76. package/src/api/user.ts +75 -0
  77. package/src/artalk.ts +75 -76
  78. package/src/comment/actions.ts +3 -3
  79. package/src/comment/comment.ts +6 -9
  80. package/src/comment/render.ts +93 -47
  81. package/src/components/pagination.ts +0 -1
  82. package/src/context.ts +57 -18
  83. package/src/editor/editor.ts +111 -18
  84. package/src/editor/plugs/header-input-plug.ts +1 -1
  85. package/src/editor/plugs/upload-plug.ts +1 -1
  86. package/src/i18n/en.ts +3 -0
  87. package/src/i18n/index.ts +117 -2
  88. package/src/i18n/zh-CN.ts +4 -1
  89. package/src/layer/sidebar-layer.ts +1 -3
  90. package/src/lib/checker/admin-checker.ts +1 -1
  91. package/src/lib/checker/captcha-checker.ts +3 -3
  92. package/src/lib/stat.ts +2 -2
  93. package/src/lib/ui.ts +6 -0
  94. package/src/list/list-lite.ts +33 -25
  95. package/src/list/list.ts +3 -4
  96. package/src/main.ts +3 -0
  97. package/src/style/comment.less +2 -3
  98. package/src/style/main.less +6 -0
  99. package/test/CSRF.html +26 -0
  100. package/types/artalk-data.d.ts +3 -0
  101. package/types/context.d.ts +19 -1
  102. package/types/global.d.ts +0 -2
  103. package/vite-base.config.ts +9 -5
  104. package/vite.config.ts +5 -1
  105. package/types/index.d.ts +0 -3
package/src/i18n/index.ts CHANGED
@@ -3,7 +3,7 @@ import zhCN from './zh-CN'
3
3
 
4
4
  export type I18n = typeof en
5
5
 
6
- // @note the Key name is followed by `ISO 639`
6
+ // @note the key of language is followed by `ISO 639`
7
7
  // https://en.wikipedia.org/wiki/ISO_639
8
8
  // https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
9
9
  export const internal = {
@@ -14,8 +14,123 @@ export const internal = {
14
14
 
15
15
  export const external = {
16
16
  'jp-JP': {},
17
- 'zh-TW': {},
17
+ 'zh-TW': {
18
+ /* Editor */
19
+ placeholder: '鍵入內容...',
20
+ noComment: '「此時無聲勝有聲」',
21
+ send: '發送評論',
22
+ save: '保存評論',
23
+ nick: '昵稱',
24
+ email: '郵箱',
25
+ link: '網址',
26
+ emoticon: '表情',
27
+ preview: '預覽',
28
+ image: '圖片',
29
+ uploadFail: '上傳失敗',
30
+ commentFail: '評論失敗',
31
+ restoredMsg: '內容已自動恢復',
32
+ onlyAdminCanReply: '僅管理員可評論',
33
+ uploadLoginMsg: '填入你的名字郵箱才能上傳哦',
34
+
35
+ /* List */
36
+ counter: '{count} 條評論',
37
+ sortLatest: '最新',
38
+ sortOldest: '最早',
39
+ sortBest: '最熱',
40
+ sortAuthor: '作者',
41
+ openComment: '打開評論',
42
+ closeComment: '關閉評論',
43
+ listLoadFailMsg: '無法獲取評論列表數據',
44
+ listRetry: '點擊重新獲取',
45
+ loadMore: '加載更多',
46
+
47
+ /* Comment */
48
+ admin: '管理員',
49
+ reply: '回覆',
50
+ voteUp: '贊同',
51
+ voteDown: '反對',
52
+ voteFail: '投票失敗',
53
+ readMore: '閱讀更多',
54
+ actionConfirm: '確認操作',
55
+ collapse: '摺疊',
56
+ collapsed: '已摺疊',
57
+ collapsedMsg: '該評論已被系統或管理員摺疊',
58
+ expand: '展開',
59
+ approved: '已審',
60
+ pending: '待審',
61
+ pendingMsg: '審核中,僅本人可見。',
62
+ edit: '編輯',
63
+ editCancel: '取消編輯',
64
+ delete: '刪除',
65
+ deleteConfirm: '確認刪除',
66
+ pin: '置頂',
67
+ unpin: '取消置頂',
68
+
69
+ /* Time */
70
+ seconds: '秒前',
71
+ minutes: '分鐘前',
72
+ hours: '小時前',
73
+ days: '天前',
74
+ now: '剛剛',
75
+
76
+ /* Checker */
77
+ adminCheck: '鍵入密碼來驗證管理員身份:',
78
+ captchaCheck: '鍵入驗證碼繼續:',
79
+ confirm: '確認',
80
+ cancel: '取消',
81
+
82
+ /* Sidebar */
83
+ msgCenter: '通知中心',
84
+ ctrlCenter: '控制中心',
85
+
86
+ /* General */
87
+ frontend: '前端',
88
+ backend: '後端',
89
+ loading: '加載中',
90
+ loadFail: '加載失敗',
91
+ editing: '修改中',
92
+ editFail: '修改失敗',
93
+ deleting: '刪除中',
94
+ deleteFail: '刪除失敗',
95
+ reqGot: '請求響應',
96
+ reqAborted: '請求超時或意外終止',
97
+ },
18
98
  'fr-FR': {},
19
99
  'de-DE': {},
20
100
  'bn-IN': {},
21
101
  }
102
+
103
+ /**
104
+ * get a locale object by language name
105
+ */
106
+ function getLocaleSet(lang: string): I18n {
107
+ // normalize a key of language to `ISO 639`
108
+ lang = lang.replace(
109
+ /^([a-zA-Z]+)(-[a-zA-Z]+)?$/,
110
+ (_, p1: string, p2: string) => (p1.toLowerCase() + (p2 || '').toUpperCase())
111
+ )
112
+
113
+ // case not found
114
+ if (!internal[lang]) {
115
+ return internal.en // use `en` by default
116
+ }
117
+
118
+ return internal[lang]
119
+ }
120
+
121
+ /**
122
+ * get a i18n message by key
123
+ */
124
+ function getI18n(locale: I18n|string, key: keyof I18n, args: {[key: string]: string} = {}) {
125
+ if (typeof locale === 'string') {
126
+ locale = getLocaleSet(locale)
127
+ }
128
+
129
+ let str = locale?.[key] || key
130
+ str = str.replace(/\{\s*(\w+?)\s*\}/g, (_, token) => args[token] || '')
131
+
132
+ return str
133
+ }
134
+
135
+ export { getLocaleSet, getI18n }
136
+ export default getI18n
package/src/i18n/zh-CN.ts CHANGED
@@ -5,6 +5,7 @@ const zhCN: I18n = {
5
5
  placeholder: '键入内容...',
6
6
  noComment: '「此时无声胜有声」',
7
7
  send: '发送评论',
8
+ save: '保存评论',
8
9
  nick: '昵称',
9
10
  email: '邮箱',
10
11
  link: '网址',
@@ -40,10 +41,12 @@ const zhCN: I18n = {
40
41
  collapse: '折叠',
41
42
  collapsed: '已折叠',
42
43
  collapsedMsg: '该评论已被系统或管理员折叠',
43
- expand: '取消折叠',
44
+ expand: '展开',
44
45
  approved: '已审',
45
46
  pending: '待审',
46
47
  pendingMsg: '审核中,仅本人可见。',
48
+ edit: '编辑',
49
+ editCancel: '取消编辑',
47
50
  delete: '删除',
48
51
  deleteConfirm: '确认删除',
49
52
  pin: '置顶',
@@ -1,5 +1,3 @@
1
- import '../style/sidebar-layer.less'
2
-
3
1
  import Context from '~/types/context'
4
2
  import Component from '@/lib/component'
5
3
  import * as Utils from '@/lib/utils'
@@ -62,7 +60,7 @@ export default class SidebarLayer extends Component {
62
60
 
63
61
  // 管理员身份验证 (若身份失效,弹出验证窗口)
64
62
  ;(async () => {
65
- const resp = await this.ctx.getApi().loginStatus()
63
+ const resp = await this.ctx.getApi().user.loginStatus()
66
64
  if (resp.is_admin && !resp.is_login) {
67
65
  this.layer?.hide()
68
66
  this.firstShow = true
@@ -11,7 +11,7 @@ const AdminChecker: Checker = {
11
11
  password: inputVal
12
12
  }
13
13
 
14
- return that.ctx.getApi().login(data.name, data.email, data.password)
14
+ return that.ctx.getApi().user.login(data.name, data.email, data.password)
15
15
  },
16
16
 
17
17
  body(that, ctx) {
@@ -4,7 +4,7 @@ import { Checker } from '.'
4
4
 
5
5
  const CaptchaChecker: Checker = {
6
6
  request(that, ctx, inputVal) {
7
- return that.ctx.getApi().captchaCheck(inputVal)
7
+ return that.ctx.getApi().captcha.captchaCheck(inputVal)
8
8
  },
9
9
 
10
10
  body(that, ctx) {
@@ -34,7 +34,7 @@ const CaptchaChecker: Checker = {
34
34
  if (stop) return
35
35
  let isPass = false
36
36
  try {
37
- const resp = await that.ctx.getApi().captchaStatus()
37
+ const resp = await that.ctx.getApi().captcha.captchaStatus()
38
38
  isPass = resp.is_pass
39
39
  } catch { isPass = false }
40
40
  if (isPass) {
@@ -60,7 +60,7 @@ const CaptchaChecker: Checker = {
60
60
  // 刷新验证码
61
61
  elem.querySelector<HTMLElement>('.atk-captcha-img')!.onclick = () => {
62
62
  const imgEl = elem.querySelector('.atk-captcha-img')
63
- that.ctx.getApi().captchaGet()
63
+ that.ctx.getApi().captcha.captchaGet()
64
64
  .then((imgData) => {
65
65
  imgEl!.setAttribute('src', imgData)
66
66
  })
package/src/lib/stat.ts CHANGED
@@ -21,7 +21,7 @@ export async function initCountWidget(p: CountConf) {
21
21
  }
22
22
 
23
23
  // PV
24
- const curtPagePvNum = p.pvAdd ? await p.ctx.getApi().pv() : undefined
24
+ const curtPagePvNum = p.pvAdd ? await p.ctx.getApi().page.pv() : undefined
25
25
  const pvEl = p.ctx.conf.pvEl
26
26
  if (pvEl && document.querySelector(pvEl)) {
27
27
  handleStatCount(p, {
@@ -52,7 +52,7 @@ export async function handleStatCount(
52
52
  .filter((pageKey) => pageCounts[pageKey] === undefined)
53
53
  queryPageKeys = [...new Set(queryPageKeys)] // 去重
54
54
  if (queryPageKeys.length > 0) {
55
- const counts: any = await p.ctx.getApi().stat(args.api, queryPageKeys)
55
+ const counts: any = await p.ctx.getApi().page.stat(args.api, queryPageKeys)
56
56
  pageCounts = { ...pageCounts, ...counts }
57
57
  }
58
58
 
package/src/lib/ui.ts CHANGED
@@ -32,6 +32,12 @@ export function hideLoading(parentElem: HTMLElement) {
32
32
  if ($loading) $loading.style.display = 'none'
33
33
  }
34
34
 
35
+ /** 元素加载动画 */
36
+ export function setLoading(val: boolean, parentElem: HTMLElement) {
37
+ if (val) showLoading(parentElem)
38
+ else hideLoading(parentElem)
39
+ }
40
+
35
41
  /** 元素是否用户可见 */
36
42
  export function isVisible(el: HTMLElement, viewport: HTMLElement = document.documentElement) {
37
43
  const viewportHeight = viewport.clientHeight
@@ -7,7 +7,7 @@ import Comment from '../comment'
7
7
  import Pagination from '../components/pagination'
8
8
  import ReadMoreBtn from '../components/read-more-btn'
9
9
  import * as ListNest from './list-nest'
10
- import { backendMinVersion } from '../../package.json'
10
+ import { backendMinVersion, version as ARTALK_VERSION } from '../../package.json'
11
11
 
12
12
  export default class ListLite extends Component {
13
13
  protected $commentsWrap: HTMLElement
@@ -78,40 +78,42 @@ export default class ListLite extends Component {
78
78
  return this.$commentsWrap
79
79
  }
80
80
 
81
+ /** 加载动画 */
82
+ public setLoading(val: boolean, isFirstLoad: boolean = false) {
83
+ this.isLoading = val
84
+ if (isFirstLoad) Ui.setLoading(val, this.$el)
85
+ else if (this.pageMode === 'read-more') this.readMoreBtn!.setLoading(val)
86
+ else if (this.pageMode === 'pagination') this.pagination!.setLoading(val)
87
+ }
88
+
81
89
  /** 评论获取 */
82
90
  public async fetchComments(offset: number) {
83
91
  if (this.isLoading) return
84
92
 
93
+ const isFirstLoad = (offset === 0)
94
+ const setLoading = (val: boolean) => this.setLoading(val, isFirstLoad)
95
+
85
96
  // 加载动画
86
- const showLoading = () => {
87
- this.isLoading = true
88
- if (offset === 0) Ui.showLoading(this.$el)
89
- else if (this.pageMode === 'read-more') this.readMoreBtn!.setLoading(true)
90
- else if (this.pageMode === 'pagination') this.pagination!.setLoading(true)
91
- }
92
- const hideLoading = () => {
93
- this.isLoading = false
94
- if (offset === 0) Ui.hideLoading(this.$el)
95
- else if (this.pageMode === 'read-more') this.readMoreBtn!.setLoading(false)
96
- else if (this.pageMode === 'pagination') this.pagination!.setLoading(false)
97
- }
98
- showLoading()
97
+ setLoading(true)
99
98
 
100
99
  // 事件通知(开始加载评论)
101
100
  this.ctx.trigger('list-load')
102
101
 
103
102
  // 清空评论(加载按钮)
104
- if (this.pageMode === 'read-more' && offset === 0) { this.ctx.clearAllComments() }
103
+ if (isFirstLoad && this.pageMode === 'read-more') {
104
+ this.ctx.clearAllComments()
105
+ }
105
106
 
106
107
  // 请求评论数据
107
108
  let listData: ListData
108
109
  try {
109
- listData = await this.ctx.getApi().get(offset, this.pageSize, this.flatMode, this.paramsEditor)
110
+ listData = await this.ctx.getApi().comment
111
+ .get(offset, this.pageSize, this.flatMode, this.paramsEditor)
110
112
  } catch (e: any) {
111
113
  this.onError(e.msg || String(e), offset, e.data)
112
114
  throw e
113
115
  } finally {
114
- hideLoading()
116
+ setLoading(false)
115
117
  }
116
118
 
117
119
  // 清除原有错误
@@ -124,7 +126,7 @@ export default class ListLite extends Component {
124
126
  this.onError(String(e), offset)
125
127
  throw e
126
128
  } finally {
127
- hideLoading()
129
+ setLoading(false)
128
130
  }
129
131
  }
130
132
 
@@ -194,15 +196,13 @@ export default class ListLite extends Component {
194
196
  const at = this.scrollListenerAt || document
195
197
  if (this.autoLoadScrollEvent) at.removeEventListener('scroll', this.autoLoadScrollEvent) // 解除原有
196
198
  this.autoLoadScrollEvent = () => {
197
- if (this.pageMode !== 'read-more') return
198
- if (!this.readMoreBtn) return
199
-
200
- if (!this.readMoreBtn.hasMore) return
201
- if (this.isLoading) return
199
+ if (this.pageMode !== 'read-more'
200
+ || !this.readMoreBtn?.hasMore
201
+ || this.isLoading
202
+ ) return
202
203
 
203
204
  const $target = this.$el.querySelector<HTMLElement>('.atk-list-comments-wrap > .atk-comment-wrap:nth-last-child(3)') // 获取倒数第3个评论元素
204
- if (!$target) return
205
- if (Ui.isVisible($target, this.scrollListenerAt)) {
205
+ if ($target && Ui.isVisible($target, this.scrollListenerAt)) {
206
206
  this.readMoreBtn.click() // 自动点击加载更多按钮
207
207
  }
208
208
  }
@@ -429,6 +429,14 @@ export default class ListLite extends Component {
429
429
  this.ctx.trigger('list-inserted', commentData)
430
430
  }
431
431
 
432
+ /** 更新评论 */
433
+ public updateComment(commentData: CommentData) {
434
+ const comment = this.ctx.findComment(commentData.id)
435
+ if (comment) {
436
+ comment.setData(commentData)
437
+ }
438
+ }
439
+
432
440
  /** 更新未读数据 */
433
441
  public updateUnread(notifies: NotifyData[]) {
434
442
  this.unread = notifies
package/src/list/list.ts CHANGED
@@ -1,7 +1,6 @@
1
- import '../style/list.less'
2
-
3
1
  import { ListData, NotifyData } from '~/types/artalk-data'
4
2
  import Context from '~/types/context'
3
+ import { version as ARTALK_VERSION } from '../../package.json'
5
4
  import * as Utils from '../lib/utils'
6
5
  import * as Ui from '../lib/ui'
7
6
  import ListHTML from './list.html?raw'
@@ -143,7 +142,7 @@ export default class List extends ListLite {
143
142
  // 已阅 API
144
143
  const notifyKey = Utils.getQueryParam('atk_notify_key')
145
144
  if (notifyKey) {
146
- this.ctx.getApi().markRead(notifyKey)
145
+ this.ctx.getApi().user.markRead(notifyKey)
147
146
  .then(() => {
148
147
  this.unread = this.unread.filter(o => o.comment_id !== commentId)
149
148
  this.updateUnread(this.unread)
@@ -175,7 +174,7 @@ export default class List extends ListLite {
175
174
  if (!this.data || !this.data.page) return
176
175
 
177
176
  this.ctx.editorShowLoading()
178
- this.ctx.getApi().pageEdit(this.data.page)
177
+ this.ctx.getApi().page.pageEdit(this.data.page)
179
178
  .then((page) => {
180
179
  if (this.data)
181
180
  this.data.page = { ...page }
package/src/main.ts CHANGED
@@ -1,3 +1,6 @@
1
1
  import Artalk from './artalk'
2
+ import ListLite from './list/list-lite'
2
3
 
3
4
  export default Artalk
5
+
6
+ export { ListLite }
@@ -258,9 +258,8 @@
258
258
  color: var(--at-color-red);
259
259
  }
260
260
 
261
- &:not(:first-child):not(.atk-hide) {
262
- margin-left: 8px;
263
- padding-left: 8px;
261
+ &:not(:last-child):not(.atk-hide) {
262
+ margin-right: 16px;
264
263
  }
265
264
 
266
265
  &:hover {
@@ -1,4 +1,9 @@
1
1
  @import "./_color.less";
2
+ @import './comment.less';
3
+ @import './list.less';
4
+ @import './pagination.less';
5
+ @import './editor.less';
6
+ @import './sidebar-layer.less';
2
7
 
3
8
  .artalk {
4
9
  position: relative;
@@ -460,4 +465,5 @@ i.atk-icon {
460
465
 
461
466
  img[atk-emoticon] {
462
467
  max-height: 60px;
468
+ display: initial;
463
469
  }
package/test/CSRF.html ADDED
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>CSRF Test</title>
8
+
9
+ <!-- 解除注释来测试当 referer 为空时的行为 -->
10
+ <!-- <meta name="referrer" content="never"> -->
11
+ </head>
12
+ <body>
13
+
14
+ <form action="http://localhost:23366/api/add" method="post">
15
+ <input type="text" name="name" value="admin">
16
+ <input type="text" name="email" value="test@example.com">
17
+ <input type="text" name="link" value="">
18
+ <input type="text" name="content" value="CSRF Success">
19
+ <input type="text" name="rid" value="0">
20
+ <input type="text" name="page_key" value="https://artalk.js.org/">
21
+ <input type="text" name="site_name" value="ArtalkDocs">
22
+ <button type="submit">Fire!</button>
23
+ </form>
24
+
25
+ </body>
26
+ </html>
@@ -8,6 +8,9 @@ export interface CommentData {
8
8
  /** 用户昵称 */
9
9
  nick: string
10
10
 
11
+ /** 用户邮箱 (该字段仅管理员可见) */
12
+ email?: string
13
+
11
14
  /** 用户邮箱(已加密) */
12
15
  email_encrypted: string
13
16
 
@@ -38,7 +38,7 @@ export default interface ContextApi {
38
38
  /* 设置持有的同事类 (中介者模式) */
39
39
  setApi(api: Api): void
40
40
  setEditor(editor: Editor): void
41
- setList(list: ListLite): void
41
+ setList(list?: ListLite): void
42
42
  setSidebarLayer(list: SidebarLayer): void
43
43
  setCheckerLauncher(checkerLauncher: CheckerLauncher): void
44
44
 
@@ -63,21 +63,36 @@ export default interface ContextApi {
63
63
  /** 插入评论 */
64
64
  insertComment(commentData: CommentData): void
65
65
 
66
+ /** 更新评论 */
67
+ updateComment(commentData: CommentData): void
68
+
66
69
  /** 评论回复 */
67
70
  replyComment(commentData: CommentData, $comment: HTMLElement, scroll?: boolean): void
68
71
 
69
72
  /** 取消回复评论 */
70
73
  cancelReplyComment(): void
71
74
 
75
+ /** 编辑评论 */
76
+ editComment(commentData: CommentData, $comment: HTMLElement): void
77
+
78
+ /** 取消编辑评论 */
79
+ cancelEditComment(): void
80
+
72
81
  /** 更新通知数据 */
73
82
  updateNotifies(notifies: NotifyData[]): void
74
83
 
75
84
  /** 列表 - 重新加载数据 */
76
85
  listReload(): void
77
86
 
87
+ /** 列表 - 重新加载数据 (别名) */
88
+ reload(): void
89
+
78
90
  /** 列表 - UI 更新 */
79
91
  listRefreshUI(): void
80
92
 
93
+ /** 列表 - HashGoto 功能检测 */
94
+ listHashGotoCheck(): void
95
+
81
96
  /** 显示侧边栏 */
82
97
  showSidebar(payload?: SidebarShowPayload): void
83
98
 
@@ -125,4 +140,7 @@ export default interface ContextApi {
125
140
 
126
141
  /** i18n 翻译 */
127
142
  $t(key: keyof I18n, args?: {[key: string]: string}): string
143
+
144
+ /** 设置暗黑模式 */
145
+ setDarkMode(darkMode: boolean): void
128
146
  }
package/types/global.d.ts CHANGED
@@ -1,2 +0,0 @@
1
- declare const ARTALK_VERSION: string
2
- declare const ARTALK_LITE: boolean
@@ -1,11 +1,9 @@
1
1
  import { defineConfig } from 'vite'
2
2
  import tsconfigPaths from 'vite-tsconfig-paths'
3
- import { version } from './package.json'
3
+ import { resolve } from 'path'
4
+ import dts from 'vite-plugin-dts'
4
5
 
5
6
  export default defineConfig({
6
- define: {
7
- ARTALK_VERSION: JSON.stringify(version),
8
- },
9
7
  css: {
10
8
  preprocessorOptions: {
11
9
  less: {
@@ -13,5 +11,11 @@ export default defineConfig({
13
11
  },
14
12
  },
15
13
  },
16
- plugins: [tsconfigPaths()],
14
+ resolve: {
15
+ alias: {
16
+ '@': resolve(__dirname, 'src'),
17
+ '~': resolve(__dirname),
18
+ }
19
+ },
20
+ plugins: [tsconfigPaths(), dts()],
17
21
  })
package/vite.config.ts CHANGED
@@ -17,7 +17,11 @@ export default Utils.mergeDeep(baseConf, defineConfig({
17
17
  },
18
18
  rollupOptions: {
19
19
  output: {
20
- assetFileNames: (assetInfo) => (/\.css$/.test(assetInfo.name) ? "Artalk.css" : "[name].[ext]")
20
+ assetFileNames: (assetInfo) => (/\.css$/.test(assetInfo.name || '') ? "Artalk.css" : "[name].[ext]"),
21
+
22
+ // Entry module "src/main.ts" is using named and default exports together.
23
+ // Consumers of your bundle will have to use `Artalk["default"]` to access the default export
24
+ exports: 'named'
21
25
  }
22
26
  }
23
27
  },
package/types/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import Artalk from '../src/artalk'
2
-
3
- export default Artalk