artalk 2.1.6 → 2.1.7

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.
package/index.html CHANGED
@@ -31,7 +31,7 @@
31
31
  </style>
32
32
  </head>
33
33
  <body>
34
- <div class="card billboard artalk-fade-in">
34
+ <div class="card billboard atk-fade-in">
35
35
  <div class="title"><a href="https://github.com/ArtalkJS/Artalk" target="_blank"><span>『 </span>Artalk<span> 』</span></a></div>
36
36
  <div class="desc">一款简洁的自托管评论系统 <span id="ArtalkPV"></span></div>
37
37
  <div class="social">
@@ -42,11 +42,11 @@
42
42
  <a href="https://github.com/ArtalkJS/Artalk" target="_blank"><img src="https://img.shields.io/github/stars/ArtalkJS/Artalk?style=flat-square"></a>
43
43
  </div>
44
44
  </div>
45
- <div class="card artalk-fade-in">
45
+ <div class="card atk-fade-in">
46
46
  <div id="comments"></div>
47
47
  </div>
48
- <div class="float-btn to-night artalk-fade-in">Blink</div>
49
- <div class="float-btn to-top artalk-fade-in" style="display: none;">TOP</div>
48
+ <div class="float-btn to-night atk-fade-in">Blink</div>
49
+ <div class="float-btn to-top atk-fade-in" style="display: none;">TOP</div>
50
50
 
51
51
  <script type="module">
52
52
  import Artalk from './src/main'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artalk",
3
- "version": "2.1.6",
3
+ "version": "2.1.7",
4
4
  "license": "GPL-3.0",
5
5
  "description": "A Selfhosted Comment System",
6
6
  "keywords": [
@@ -136,6 +136,11 @@ export default class Comment extends Component {
136
136
  $badge.remove()
137
137
  }
138
138
 
139
+ if (this.data.is_pinned) {
140
+ const $pinnedBadge = Utils.createElement(`<span class="atk-item atk-pinned-badge">置顶</span>`) // 置顶徽章
141
+ $nick.insertAdjacentElement('afterend', $pinnedBadge)
142
+ }
143
+
139
144
  const $date = this.$el.querySelector<HTMLElement>('.atk-date')!
140
145
  $date.innerText = this.getDateFormatted()
141
146
  $date.setAttribute('data-atk-comment-date', String(+new Date(this.data.date)))
@@ -272,6 +277,16 @@ export default class Comment extends Component {
272
277
  delBtn.setClick(() => {
273
278
  this.adminDelete(delBtn)
274
279
  })
280
+
281
+ // 绑定置顶按钮事件
282
+ const pinnedBtn = new ActionBtn({
283
+ text: () => (this.data.is_pinned ? '取消置顶' : '置顶'),
284
+ adminOnly: true
285
+ })
286
+ pinnedBtn.appendTo(this.$actions)
287
+ pinnedBtn.setClick(() => {
288
+ this.adminEdit('pinned', pendingBtn)
289
+ })
275
290
  }
276
291
  //#endregion
277
292
 
@@ -404,9 +419,9 @@ export default class Comment extends Component {
404
419
  })
405
420
  }
406
421
 
407
- /** 管理员 - 评论折叠 */
408
- adminEdit(type: 'collapsed'|'pending', btnElem: ActionBtn) {
409
- if (btnElem.isLoading) return // 若正在折叠中
422
+ /** 管理员 - 评论状态修改 */
423
+ adminEdit(type: 'collapsed'|'pending'|'pinned', btnElem: ActionBtn) {
424
+ if (btnElem.isLoading) return // 若正在修改中
410
425
 
411
426
  btnElem.setLoading(true, '修改中...')
412
427
 
@@ -416,6 +431,8 @@ export default class Comment extends Component {
416
431
  modify.is_collapsed = !modify.is_collapsed
417
432
  } else if (type === 'pending') {
418
433
  modify.is_pending = !modify.is_pending
434
+ } else if (type === 'pinned') {
435
+ modify.is_pinned = !modify.is_pinned
419
436
  }
420
437
 
421
438
  new Api(this.ctx).commentEdit(modify).then((comment) => {
@@ -1,8 +1,10 @@
1
1
  <div class="atk-list">
2
2
  <div class="atk-list-header">
3
3
  <div class="atk-comment-count">
4
- <span class="atk-comment-count-num">0</span>
5
- 条评论
4
+ <div class="atk-text">
5
+ <span class="atk-comment-count-num">0</span>
6
+ 条评论
7
+ </div>
6
8
  </div>
7
9
  <div class="atk-right-action">
8
10
  <span data-action="admin-close-comment" class="atk-hide" atk-only-admin-show>关闭评论</span>
@@ -12,6 +12,8 @@ export default class List extends ListLite {
12
12
  private $closeCommentBtn!: HTMLElement
13
13
  private $openSidebarBtn!: HTMLElement
14
14
  private $unreadBadge!: HTMLElement
15
+ private $commentCount!: HTMLElement
16
+ private $dropdownWrap?: HTMLElement
15
17
 
16
18
  constructor (ctx: Context) {
17
19
  const el = Utils.createElement(ListHTML)
@@ -40,6 +42,10 @@ export default class List extends ListLite {
40
42
  // 操作按钮
41
43
  this.initListActionBtn()
42
44
 
45
+ // 下拉选择层
46
+ this.$commentCount = this.$el.querySelector('.atk-comment-count')!
47
+ this.initDropdown()
48
+
43
49
  // copyright
44
50
  this.$el.querySelector<HTMLElement>('.atk-copyright')!.innerHTML = `Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${ARTALK_VERSION}">Artalk</a>`
45
51
 
@@ -171,4 +177,58 @@ export default class List extends ListLite {
171
177
  this.$unreadBadge.style.display = 'none'
172
178
  }
173
179
  }
180
+
181
+ /** 初始化选择下拉层 */
182
+ protected initDropdown() {
183
+ this.$dropdownWrap = this.$commentCount
184
+ this.$commentCount.classList.add('atk-dropdown-wrap')
185
+
186
+ // 插入图标
187
+ this.$commentsWrap.append(Utils.createElement(`<span class="atk-arrow-down-icon"></span>`))
188
+
189
+ const reloadUseParamsEditor = (func: (p: any) => void) => {
190
+ this.paramsEditor = (p) => { func(p) }
191
+ this.fetchComments(0)
192
+ }
193
+
194
+ // 下拉列表
195
+ const dropdownList = [
196
+ ['最新', () => { reloadUseParamsEditor(p => { p.sort_by = 'date_desc' }) }],
197
+ ['最热', () => { reloadUseParamsEditor(p => { p.sort_by = 'vote' }) }],
198
+ ['最早', () => { reloadUseParamsEditor(p => { p.sort_by = 'date_asc' }) }],
199
+ ['作者', () => { reloadUseParamsEditor(p => { p.view_only_admin = true }) }],
200
+ ]
201
+
202
+ // 列表项点击事件
203
+ let curtActive = 0 // 当前选中
204
+ const onItemClick = (i: number, $item: HTMLElement, name: string, action: Function) => {
205
+ action()
206
+
207
+ // set active
208
+ curtActive = i
209
+ $dropdown.querySelectorAll('.active').forEach((e) => { e.classList.remove('active') })
210
+ $item.classList.add('active')
211
+
212
+ // 关闭层 (临时消失,取消 :hover)
213
+ $dropdown.style.display = 'none'
214
+ setTimeout(() => { $dropdown.style.display = '' }, 80)
215
+ }
216
+
217
+ // 生成列表元素
218
+ const $dropdown = Utils.createElement(`<ul class="atk-dropdown atk-fade-in"></ul>`)
219
+ dropdownList.forEach((item, i) => {
220
+ const name = item[0] as string
221
+ const action = item[1] as Function
222
+
223
+ const $item = Utils.createElement(`<li class="atk-dropdown-item"><span></span></li>`)
224
+ const $link = $item.querySelector<HTMLElement>('span')!
225
+ $link.innerText = name
226
+ $link.onclick = () => { onItemClick(i, $item, name, action) }
227
+ $dropdown.append($item)
228
+
229
+ if (i === curtActive) $item.classList.add('active') // 默认选中项
230
+ })
231
+
232
+ this.$dropdownWrap.append($dropdown)
233
+ }
174
234
  }
@@ -102,6 +102,12 @@
102
102
  color: #fff;
103
103
  }
104
104
 
105
+ .atk-pinned-badge {
106
+ .badge();
107
+ color: #fff;
108
+ background: #f44336;
109
+ }
110
+
105
111
  .atk-ua {
106
112
  .badge()
107
113
  }
@@ -7,6 +7,72 @@
7
7
  padding: 10px 10px 5px 10px;
8
8
  border-bottom: 1px solid var(--at-color-border);
9
9
 
10
+ .atk-text {
11
+ display: inline-block;
12
+ }
13
+
14
+ /* 下拉选择层 */
15
+ .atk-dropdown-wrap {
16
+ position: relative;
17
+ cursor: pointer;
18
+
19
+ .atk-arrow-down-icon {
20
+ cursor: pointer;
21
+ vertical-align: middle;
22
+ border-top: 6px solid var(--at-color-grey);
23
+ border-left: 4px solid transparent;
24
+ border-right: 4px solid transparent;
25
+ margin-top: -1px;
26
+ margin-left: 0.4rem;
27
+ display: inline-block;
28
+ }
29
+
30
+ &:hover {
31
+ .atk-dropdown {
32
+ display: block;
33
+ }
34
+ }
35
+
36
+ .atk-dropdown {
37
+ z-index: 888;
38
+ display: none;
39
+ height: auto !important;
40
+ max-height: calc(100vh - 2.7rem);
41
+ overflow-y: auto;
42
+ position: absolute;
43
+ top: 100%;
44
+ right: 0;
45
+ width: 100%;
46
+ background-color: var(--at-color-bg);
47
+ padding: 0.6rem 0;
48
+ border: 1px solid var(--at-color-border);
49
+ text-align: center;
50
+ border-radius: 0.25rem;
51
+ white-space: nowrap;
52
+ margin: 0;
53
+ list-style: none;
54
+ }
55
+
56
+ .atk-dropdown-item {
57
+ span, a {
58
+ display: block;
59
+ line-height: 2rem;
60
+ position: relative;
61
+ border-bottom: none;
62
+ font-weight: 400;
63
+ padding: 0 1.5rem;
64
+
65
+ &:hover {
66
+ color: var(--at-color-main);
67
+ }
68
+ }
69
+
70
+ &.active span, a {
71
+ color: var(--at-color-main);
72
+ }
73
+ }
74
+ }
75
+
10
76
  .atk-comment-count {
11
77
  font-size: 15px;
12
78
 
@@ -29,6 +29,9 @@ export interface CommentData {
29
29
  /** 是否待审 */
30
30
  is_pending?: boolean
31
31
 
32
+ /** 是否置顶 */
33
+ is_pinned?: boolean
34
+
32
35
  /** 是否为管理员 */
33
36
  is_admin?: boolean
34
37