Skip to content

Commit

Permalink
refactor(ui/list): separate list into standalone components (#618)
Browse files Browse the repository at this point in the history
* refactor(ui/list): separate the functions of list

* fix

* move files
  • Loading branch information
qwqcode authored Oct 27, 2023
1 parent 87a6296 commit 1608911
Show file tree
Hide file tree
Showing 59 changed files with 1,092 additions and 992 deletions.
4 changes: 2 additions & 2 deletions ui/packages/artalk-sidebar/src/global.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Artalk from 'artalk'
import type { LocalUser } from 'artalk/types/artalk-config'
import { useUserStore } from './stores/user'
const { t } = useI18n()

export let artalk: Artalk|null = null

Expand All @@ -25,14 +26,13 @@ export function createArtalkInstance() {
artalkEl.style.display = 'none'
document.body.append(artalkEl)

Artalk.DisabledComponents = ['list']
return Artalk.init({
el: artalkEl,
server: (import.meta.env.DEV) ? 'http://localhost:23366' : '../',
pageKey: bootParams.pageKey,
site: bootParams.site,
darkMode: bootParams.darkMode,
useBackendConf: true
useBackendConf: true,
})
}

Expand Down
51 changes: 24 additions & 27 deletions ui/packages/artalk-sidebar/src/pages/comments.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,54 +33,51 @@ onMounted(() => {
}
watch(curtTab, (curtTab) => {
list.fetchComments(0)
artalk!.ctx.fetch({
offset: 0
})
})
watch(curtSite, (value) => {
list.reload()
artalk!.ctx.reload()
})
// 初始化评论列表
const list = new Artalk.List(artalk!.ctx, {
liteMode: true,
flatMode: true,
unreadHighlight: true,
scrollListenerAt: wrapEl.value,
pageMode: 'pagination',
// pageSize: 20 // TODO consider fixed pageSize value in sidebar
noCommentText: `<div class="atk-sidebar-no-content">${t('noContent')}</div>`,
renderComment: (comment) => {
const pageURL = comment.getData().page_url
comment.getRender().setOpenURL(`${pageURL}#atk-comment-${comment.getID()}`)
comment.getConf().onReplyBtnClick = () => {
artalk!.ctx.replyComment(comment.getData(), comment.getEl())
}
artalk!.ctx.updateConf({
noComment: `<div class="atk-sidebar-no-content">${t('noContent')}</div>`,
pagination: {
pageSize: 20,
readMore: false,
autoLoad: false,
},
paramsEditor: (params) => {
listUnreadHighlight: true,
listFetchParamsModifier: (params) => {
params.type = curtTab.value // 列表数据类型
params.site_name = curtSite.value // 站点名
if (search.value) params.search = search.value
}
},
listScrollListenerAt: wrapEl.value,
})
artalk!.ctx.inject('list', list)
artalk!.on('list-inserted', (data) => {
wrapEl.value!.scrollTo(0, 0)
artalk!.ctx.on('comment-rendered', (comment) => {
const pageURL = comment.getData().page_url
comment.getRender().setOpenURL(`${pageURL}#atk-comment-${comment.getID()}`)
comment.getConf().onReplyBtnClick = () => {
artalk!.ctx.replyComment(comment.getData(), comment.getEl())
}
})
list.reload()
artalk!.reload()
listEl.value?.append(list.$el)
listEl.value?.append(artalk!.ctx.get('list')!.$el)
// 搜索功能
nav.enableSearch((value: string) => {
search.value = value
list.reload()
artalk!.reload()
}, () => {
if (search.value === '') return
search.value = ''
list.reload()
artalk!.reload()
})
})
</script>
Expand Down
2 changes: 1 addition & 1 deletion ui/packages/artalk/src/artalk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default class Artalk {

/** Reload comment list of Artalk */
public reload() {
this.ctx.listReload()
this.ctx.reload()
}

/** Destroy instance of Artalk */
Expand Down
30 changes: 0 additions & 30 deletions ui/packages/artalk/src/comment/render-ctx.ts

This file was deleted.

32 changes: 27 additions & 5 deletions ui/packages/artalk/src/comment/render.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
import Comment from './comment'
import ActionBtn from '../components/action-btn'
import * as Utils from '../lib/utils'
import * as Ui from '../lib/ui'

import * as HeightLimit from './height-limit'
import CommentHTML from './comment.html?raw'
import Comment from './comment'
import RenderCtx from './render-ctx'
import loadRenders from './renders'
import * as HeightLimit from './height-limit'

export default class CommentRender extends RenderCtx {
export default class Render {
public comment: Comment

public get ctx() { return this.comment.ctx }
public get data() { return this.comment.getData() }
public get conf() { return this.comment.conf }
public get cConf() { return this.comment.getConf() }

public $el!: HTMLElement
public $main!: HTMLElement
public $header!: HTMLElement
public $headerNick!: HTMLElement
public $headerBadgeWrap!: HTMLElement
public $body!: HTMLElement
public $content!: HTMLElement
public $childrenWrap!: HTMLElement|null
public $actions!: HTMLElement
public voteBtnUp?: ActionBtn
public voteBtnDown?: ActionBtn

public $replyTo?: HTMLElement // 回复评论内容 (平铺下显示)
public $replyAt?: HTMLElement // 回复 AT(层级嵌套下显示)

public constructor(comment: Comment) {
super(comment)
this.comment = comment
}

public render() {
Expand Down
90 changes: 45 additions & 45 deletions ui/packages/artalk/src/comment/renders/actions.ts
Original file line number Diff line number Diff line change
@@ -1,114 +1,114 @@
import * as Utils from '../../lib/utils'
import ActionBtn from '../../components/action-btn'
import RenderCtx from '../render-ctx'
import Render from '../render'

/**
* 评论操作按钮界面
*/
export default function renderActions(ctx: RenderCtx) {
export default function renderActions(r: Render) {
Object.entries({
renderVote, renderReply,
// 管理员操作
renderCollapse, renderModerator, renderPin, renderEdit, renderDel
}).forEach(([name, render]) => {
render(ctx)
render(r)
})
}


// 操作按钮 - 投票
function renderVote(ctx: RenderCtx) {
if (!ctx.ctx.conf.vote) return // 关闭投票功能
function renderVote(r: Render) {
if (!r.ctx.conf.vote) return // 关闭投票功能

// 赞同按钮
ctx.voteBtnUp = new ActionBtn(ctx.ctx, () => `${ctx.ctx.$t('voteUp')} (${ctx.data.vote_up || 0})`).appendTo(ctx.$actions)
ctx.voteBtnUp.setClick(() => {
ctx.comment.getActions().vote('up')
r.voteBtnUp = new ActionBtn(r.ctx, () => `${r.ctx.$t('voteUp')} (${r.data.vote_up || 0})`).appendTo(r.$actions)
r.voteBtnUp.setClick(() => {
r.comment.getActions().vote('up')
})

// 反对按钮
if (ctx.ctx.conf.voteDown) {
ctx.voteBtnDown = new ActionBtn(ctx.ctx, () => `${ctx.ctx.$t('voteDown')} (${ctx.data.vote_down || 0})`).appendTo(ctx.$actions)
ctx.voteBtnDown.setClick(() => {
ctx.comment.getActions().vote('down')
if (r.ctx.conf.voteDown) {
r.voteBtnDown = new ActionBtn(r.ctx, () => `${r.ctx.$t('voteDown')} (${r.data.vote_down || 0})`).appendTo(r.$actions)
r.voteBtnDown.setClick(() => {
r.comment.getActions().vote('down')
})
}
}

// 操作按钮 - 回复
function renderReply(ctx: RenderCtx) {
if (!ctx.data.is_allow_reply) return // 不允许回复
function renderReply(r: Render) {
if (!r.data.is_allow_reply) return // 不允许回复

const replyBtn = Utils.createElement(`<span>${ctx.ctx.$t('reply')}</span>`)
ctx.$actions.append(replyBtn)
const replyBtn = Utils.createElement(`<span>${r.ctx.$t('reply')}</span>`)
r.$actions.append(replyBtn)
replyBtn.addEventListener('click', (e) => {
e.stopPropagation() // 防止穿透
if (!ctx.cConf.onReplyBtnClick) {
ctx.ctx.replyComment(ctx.data, ctx.$el)
if (!r.cConf.onReplyBtnClick) {
r.ctx.replyComment(r.data, r.$el)
} else {
ctx.cConf.onReplyBtnClick()
r.cConf.onReplyBtnClick()
}
})
}

// 操作按钮 - 折叠
function renderCollapse(ctx: RenderCtx) {
const collapseBtn = new ActionBtn(ctx.ctx, {
text: () => (ctx.data.is_collapsed ? ctx.ctx.$t('expand') : ctx.ctx.$t('collapse')),
function renderCollapse(r: Render) {
const collapseBtn = new ActionBtn(r.ctx, {
text: () => (r.data.is_collapsed ? r.ctx.$t('expand') : r.ctx.$t('collapse')),
adminOnly: true
})
collapseBtn.appendTo(ctx.$actions)
collapseBtn.appendTo(r.$actions)
collapseBtn.setClick(() => {
ctx.comment.getActions().adminEdit('collapsed', collapseBtn)
r.comment.getActions().adminEdit('collapsed', collapseBtn)
})
}

// 操作按钮 - 审核
function renderModerator(ctx: RenderCtx) {
const pendingBtn = new ActionBtn(ctx.ctx, {
text: () => (ctx.data.is_pending ? ctx.ctx.$t('pending') : ctx.ctx.$t('approved')),
function renderModerator(r: Render) {
const pendingBtn = new ActionBtn(r.ctx, {
text: () => (r.data.is_pending ? r.ctx.$t('pending') : r.ctx.$t('approved')),
adminOnly: true
})
pendingBtn.appendTo(ctx.$actions)
pendingBtn.appendTo(r.$actions)
pendingBtn.setClick(() => {
ctx.comment.getActions().adminEdit('pending', pendingBtn)
r.comment.getActions().adminEdit('pending', pendingBtn)
})
}

// 操作按钮 - 置顶
function renderPin(ctx: RenderCtx) {
const pinnedBtn = new ActionBtn(ctx.ctx, {
text: () => (ctx.data.is_pinned ? ctx.ctx.$t('unpin') : ctx.ctx.$t('pin')),
function renderPin(r: Render) {
const pinnedBtn = new ActionBtn(r.ctx, {
text: () => (r.data.is_pinned ? r.ctx.$t('unpin') : r.ctx.$t('pin')),
adminOnly: true
})
pinnedBtn.appendTo(ctx.$actions)
pinnedBtn.appendTo(r.$actions)
pinnedBtn.setClick(() => {
ctx.comment.getActions().adminEdit('pinned', pinnedBtn)
r.comment.getActions().adminEdit('pinned', pinnedBtn)
})
}

// 操作按钮 - 编辑
function renderEdit(ctx: RenderCtx) {
const editBtn = new ActionBtn(ctx.ctx, {
text: ctx.ctx.$t('edit'),
function renderEdit(r: Render) {
const editBtn = new ActionBtn(r.ctx, {
text: r.ctx.$t('edit'),
adminOnly: true
})
editBtn.appendTo(ctx.$actions)
editBtn.appendTo(r.$actions)
editBtn.setClick(() => {
ctx.ctx.editComment(ctx.data, ctx.$el)
r.ctx.editComment(r.data, r.$el)
})
}

// 操作按钮 - 删除
function renderDel(ctx: RenderCtx) {
const delBtn = new ActionBtn(ctx.ctx, {
text: ctx.ctx.$t('delete'),
function renderDel(r: Render) {
const delBtn = new ActionBtn(r.ctx, {
text: r.ctx.$t('delete'),
confirm: true,
confirmText: ctx.ctx.$t('deleteConfirm'),
confirmText: r.ctx.$t('deleteConfirm'),
adminOnly: true,
})
delBtn.appendTo(ctx.$actions)
delBtn.appendTo(r.$actions)
delBtn.setClick(() => {
ctx.comment.getActions().adminDelete(delBtn)
r.comment.getActions().adminDelete(delBtn)
})
}
14 changes: 7 additions & 7 deletions ui/packages/artalk/src/comment/renders/avatar.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import * as Utils from '../../lib/utils'
import RenderCtx from '../render-ctx'
import Render from '../render'

/**
* 评论头像界面
*/
export default function renderAvatar(ctx: RenderCtx) {
const $avatar = ctx.$el.querySelector<HTMLElement>('.atk-avatar')!
export default function renderAvatar(r: Render) {
const $avatar = r.$el.querySelector<HTMLElement>('.atk-avatar')!
const $avatarImg = Utils.createElement<HTMLImageElement>('<img />')

const avatarURLBuilder = ctx.conf.avatarURLBuilder
$avatarImg.src = avatarURLBuilder ? avatarURLBuilder(ctx.data) : ctx.comment.getGravatarURL()
const avatarURLBuilder = r.conf.avatarURLBuilder
$avatarImg.src = avatarURLBuilder ? avatarURLBuilder(r.data) : r.comment.getGravatarURL()

if (ctx.data.link) {
if (r.data.link) {
const $avatarA = Utils.createElement<HTMLLinkElement>('<a target="_blank" rel="noreferrer noopener nofollow"></a>')
$avatarA.href = Utils.isValidURL(ctx.data.link) ? ctx.data.link : `https://${ctx.data.link}`
$avatarA.href = Utils.isValidURL(r.data.link) ? r.data.link : `https://${r.data.link}`
$avatarA.append($avatarImg)
$avatar.append($avatarA)
} else {
Expand Down
Loading

0 comments on commit 1608911

Please sign in to comment.