import '../style/list.less' ; import Context from '../context' ; import * as Utils from '../lib/utils' ; import * as Ui from '../lib/ui' ; import Api from '../api' ; import ListHTML from './html/list.html?raw' ; import ListLite from './list-lite' ; import { ListData } from '~/types/artalk-data' ; export default class List extends ListLite { private $closeCommentBtn ! : HTMLElement ; private $openSidebarBtn ! : HTMLElement ; private $unreadBadge ! : HTMLElement ; constructor ( ctx ) { const el = Utils . createElement ( ListHTML ) ; super ( ctx ) ; el . querySelector ( '.atk-list-body' ) ! . append ( this . $el ) ; this . $el = el ; let flatMode = false ; if ( this . ctx . conf . flatMode === 'auto' ) { if ( window . matchMedia ( "(max-width: 768px)" ) . matches ) flatMode = true ; } else if ( this . ctx . conf . flatMode === true ) { flatMode = true ; } this . flatMode = flatMode ; this . pageMode = this . conf . pagination ?. readMore ? 'read-more' : 'pagination' ; this . pageSize = this . conf . pagination ?. pageSize || 20 ; this . repositionAt = this . $el ; this . initListActionBtn ( ) ; this . $el . querySelector < HTMLElement > ( '.atk-copyright' ) ! . innerHTML = `Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${ ARTALK_VERSION }">Artalk</a>` ; this . ctx . on ( 'list-reload' , ( ) => ( this . fetchComments ( 0 ) ) ) ; this . ctx . on ( 'list-refresh-ui' , ( ) => ( this . refreshUI ( ) ) ) ; this . ctx . on ( 'list-import' , ( data ) => ( this . importComments ( data ) ) ) ; this . ctx . on ( 'list-insert' , ( data ) => ( this . insertComment ( data ) ) ) ; this . ctx . on ( 'list-delete' , ( comment ) => ( this . deleteComment ( comment . id ) ) ) ; this . ctx . on ( 'list-update' , ( updateData ) => { updateData ( this . data ) ; this . refreshUI ( ) ; } ) ; this . ctx . on ( 'unread-update' , ( data ) => ( this . showUnreadBadge ( data . notifies ?. length || 0 ) ) ) ; } private initListActionBtn ( ) { this . $openSidebarBtn = this . $el . querySelector ( '[data-action="open-sidebar"]' ) ! ; this . $closeCommentBtn = this . $el . querySelector ( '[data-action="admin-close-comment"]' ) ! ; this . $unreadBadge = this . $el . querySelector ( '.atk-unread-badge' ) ! ; this . $openSidebarBtn . addEventListener ( 'click' , ( ) => { this . ctx . trigger ( 'sidebar-show' ) ; } ) ; this . $closeCommentBtn . addEventListener ( 'click' , ( ) => { if ( ! this . data ) return ; this . data . page . admin_only = ! this . data . page . admin_only ; this . adminPageEditSave ( ) ; } ) ; } /** 刷新界面 */ public refreshUI ( ) { super . refreshUI ( ) ; this . $el . querySelector < HTMLElement > ( '.atk-comment-count-num' ) ! . innerText = String ( Number ( this . data ?. total ) || 0 ) ; if ( ! ! this . ctx . user . data . nick && ! ! this . ctx . user . data . email ) { this . $openSidebarBtn . classList . remove ( 'atk-hide' ) ; } else { this . $openSidebarBtn . classList . add ( 'atk-hide' ) ; } this . ctx . trigger ( 'check-admin-show-el' ) ; this . $openSidebarBtn . querySelector < HTMLElement > ( '.atk-text' ) ! . innerText = ( ! this . ctx . user . data . isAdmin ) ? '通知中心' : '控制中心' ; if ( ! ! this . data && ! ! this . data . page && this . data . page . admin_only === true ) { this . ctx . trigger ( 'editor-close' ) ; this . $closeCommentBtn . innerHTML = '打开评论' ; } else { this . ctx . trigger ( 'editor-open' ) ; this . $closeCommentBtn . innerHTML = '关闭评论' ; } } protected onLoad ( data , offset ) { super . onLoad ( data , offset ) ; this . checkGoToCommentByUrlHash ( ) ; } /** 跳到评论项位置 - 根据 `location.hash` */ public async checkGoToCommentByUrlHash ( ) { let commentId = Number ( Utils . getQueryParam ( 'atk_comment' ) ) ; if ( ! commentId ) { const match = window . location . hash . match ( /#atk-comment-([0-9]+)/ ) ; if ( ! match || ! match [ 1 ] || Number . isNaN ( Number ( match [ 1 ] ) ) ) return ; commentId = Number ( match [ 1 ] ) ; } if ( ! commentId ) return ; const notifyKey = Utils . getQueryParam ( 'atk_notify_key' ) ; if ( notifyKey ) { new Api ( this . ctx ) . markRead ( notifyKey ) . then ( ( ) => { this . unread = this . unread . filter ( o => o . comment_id !== commentId ) ; this . ctx . trigger ( 'unread-update' , { notifies : this . unread } ) ; } ) ; } const comment = this . findComment ( commentId ) ; if ( ! comment ) return ; Ui . scrollIntoView ( comment . getEl ( ) , false ) ; window . setTimeout ( ( ) => { comment . getEl ( ) . classList . add ( 'atk-flash-once' ) ; } , 800 ) ; } /** 管理员设置页面信息 */ public adminPageEditSave ( ) { if ( ! this . data || ! this . data . page ) return ; this . ctx . trigger ( 'editor-show-loading' ) ; new Api ( this . ctx ) . pageEdit ( this . data . page ) . then ( ( page ) => { if ( this . data ) this . data . page = { ... page } ; this . refreshUI ( ) ; } ) . catch ( err => { this . ctx . trigger ( 'editor-notify' , { msg : `修改页面数据失败：${ err . msg || String ( err ) }` , type : 'e' } ) ; } ) . finally ( ( ) => { this . ctx . trigger ( 'editor-hide-loading' ) ; } ) ; } public showUnreadBadge ( count ) { if ( count > 0 ) { this . $unreadBadge . innerText = `${ Number ( count || 0 ) }` ; this . $unreadBadge . style . display = 'block' ; } else { this . $unreadBadge . style . display = 'none' ; } } }