Skip to content

Commit

Permalink
feat(ui/goto): improved solution of navigating to comment via link ha…
Browse files Browse the repository at this point in the history
…sh (#693) (#765)
  • Loading branch information
qwqcode committed Feb 4, 2024
1 parent afa7888 commit 2a21951
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 107 deletions.
3 changes: 0 additions & 3 deletions ui/artalk-sidebar/src/pages/comments.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ onMounted(() => {
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())
}
})
artalk!.ctx.updateConf({
Expand Down
30 changes: 0 additions & 30 deletions ui/artalk/src/list/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ export const initListPaginatorFunc = (ctx: ContextApi) => {
paginator?.showErr?.($t('loadFail'))
})

// List goto auto next page when comment not found
// autoJumpToNextPage(ctx, paginator)

// loading
ctx.on('list-fetch', (params) => {
paginator?.setLoading(true)
Expand All @@ -78,30 +75,3 @@ export const initListPaginatorFunc = (ctx: ContextApi) => {
paginator?.setLoading(false)
})
}

function autoJumpToNextPage(ctx: ContextApi, paginator: Paginator|null) {
// TODO: Disable this feature temporarily. Because it may cause the page memory leak.
// if the comments is too much and the comment still not found.
// Consider to refactor to a better solution.
// Such as: calculate in backend and jump to the specific page directly.
return

const autoSwitchPageForFindComment = (commentID: number) => {
const comment = ctx.getData().findComment(commentID)
if (!!comment || !paginator?.getHasMore()) return

// wait for list loaded
ctx.on('list-loaded', () => {
autoSwitchPageForFindComment(commentID) // recursive, until comment found or no more page
}, { once: true })

// TODO: 自动范围改为直接跳转到计算后的页面
setTimeout(() => {
paginator?.next()
}, 80)
}

ctx.on('list-goto', (commentID) => {
autoSwitchPageForFindComment(commentID)
})
}
41 changes: 41 additions & 0 deletions ui/artalk/src/plugins/list/goto-dispatcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { ArtalkPlugin } from '@/types'
import * as Utils from '@/lib/utils'

export const GotoDispatcher: ArtalkPlugin = (ctx) => {
let lastID = 0
const check = ({ locker }: { locker: boolean }) => {
const commentID = extractCommentID()
if (!commentID) return

if (locker && lastID === commentID) return // if the commentID is the same as the last one, do nothing
lastID = commentID // record the last commentID

ctx.trigger('list-goto', commentID) // trigger event
}

const hashChangeHandler = () => check({ locker: false })
const listLoadedHandler = () => check({ locker: true })
ctx.on('mounted', () => {
window.addEventListener('hashchange', hashChangeHandler)
ctx.on('list-loaded', listLoadedHandler)
})
ctx.on('unmounted', () => {
window.removeEventListener('hashchange', hashChangeHandler)
ctx.off('list-loaded', listLoadedHandler)
})
}

function extractCommentID(): number|null {
// Try get from hash
// Hash retrieval priority is higher than query,
// Because click goto will change hash.
const match = window.location.hash.match(/#atk-comment-([0-9]+)/)
let commentId = match && match[1] && !Number.isNaN(parseFloat(match[1])) ? parseFloat(match[1]) : null

// Fail over to get from query
if (!commentId) {
commentId = Number(Utils.getQueryParam('atk_comment')) // same as backend GetReplyLink()
}

return commentId || null
}
17 changes: 17 additions & 0 deletions ui/artalk/src/plugins/list/goto-focus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { ArtalkPlugin } from '@/types'

export const GotoFocus: ArtalkPlugin = (ctx) => {
ctx.on('list-goto', async (commentID) => {
// find the comment node
let comment = ctx.getCommentNodes().find(c => c.getID() === commentID)
if (!comment) {
// fetch and insert the comment from the server
const data = (await ctx.getApi().comments.getComment(commentID)).data
ctx.get('list').getListLayout({ forceFlatMode: true }).insert(data.comment, data.reply_comment)
comment = ctx.getCommentNodes().find(c => c.getID() === commentID)
}
if (!comment) return
comment.focus()
})
}

72 changes: 0 additions & 72 deletions ui/artalk/src/plugins/list/goto.ts

This file was deleted.

5 changes: 3 additions & 2 deletions ui/artalk/src/plugins/list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Unread } from './unread'
import { Count } from './count'
import { SidebarBtn } from './sidebar-btn'
import { UnreadBadge } from './unread-badge'
import { Goto } from './goto'
import { GotoDispatcher } from './goto-dispatcher'
import { GotoFocus } from './goto-focus'
import { Copyright } from './copyright'
import { NoComment } from './no-comment'
import { Dropdown } from './dropdown'
Expand All @@ -18,7 +19,7 @@ import { GotoFirst } from './goto-first'
const ListPlugins: ArtalkPlugin[] = [
Fetch, Loading, Unread,
WithEditor, Count, SidebarBtn, UnreadBadge,
Dropdown, Goto, NoComment, Copyright,
Dropdown, GotoDispatcher, GotoFocus, NoComment, Copyright,
TimeTicking, ErrorDialog, ReachBottom, GotoFirst
]

Expand Down

0 comments on commit 2a21951

Please sign in to comment.