0904
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
{{$pinTitle := t .LangCode "ask.pinned"}}
|
||||
<div id="question-list">
|
||||
{{range $index, $elem := .PageQuestions}}
|
||||
<div data-qid="{{$elem.ID}}">
|
||||
<hr>
|
||||
<a class="uk-button uk-button-default uk-button-small uk-float-right"
|
||||
href="/_/{{$.PageUser.Domain}}/{{$elem.ID}}">查看回答</a>
|
||||
<div class="uk-text-left uk-text-small uk-text-muted">
|
||||
{{if $elem.IsPinned}}<span class="tb-pin-flag" title="{{t $.LangCode "ask.pinned"}}">⭐</span>{{end}}
|
||||
{{Date $elem.CreatedAt "Y-m-d H:i:s"}}
|
||||
</div>
|
||||
<p class="uk-text-small uk-text-break tb-preline tb-clamp-5">{{MarkdownPlainText $elem.Content}}</p>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<!-- 翻页游标与服务端 EncodePinCursor 保持一致:
|
||||
isPinned(0/1) + createdAt 的 UnixNano + id 组成的复合键集游标。 -->
|
||||
<!-- 初始 more 由服务端给出:首屏已展示全部提问时按钮直接不渲染,
|
||||
之后每次加载以接口返回的 has_more 为准,最后一页加载完立即隐藏按钮。 -->
|
||||
<div x-data="{ more: {{ if .PageQuestionHasMore }}true{{ else }}false{{ end }}, loading: false, cursor: '{{.PageQuestionCursor}}' }">
|
||||
<button x-show="more" x-bind:disabled="loading" x-on:click.debounce="() => {
|
||||
if (loading) return
|
||||
loading = true
|
||||
fetch(`/api/v1/user/{{.PageUser.Domain}}/questions?cursor=${cursor}`)
|
||||
.then(response => response.json())
|
||||
.then(resp => {
|
||||
loading = false
|
||||
// 外层为 ctx.JSON 的统一包装 {code, data, message},内层才是分页负载;
|
||||
// code !== 0(接口报错)时保持 more 不变,仅复位 loading,下次可重试。
|
||||
if (!resp || resp.code !== 0) return
|
||||
const payload = resp.data || {}
|
||||
let items = Array.isArray(payload.data) ? payload.data : []
|
||||
if (items.length === 0) {
|
||||
more = false
|
||||
return
|
||||
}
|
||||
|
||||
// 防重兜底:先扫描 #question-list 下全部已渲染条目(含服务端首屏与既往
|
||||
// 追加)的 data-qid 构造“已见”集合,仅追加未出现过的提问。若服务端因游标
|
||||
// 未前进等原因返回了与已见内容相同的批次(重复加载历史 bug 的表现形态),
|
||||
// 直接按“到底”处理并隐藏按钮,杜绝无限重复追加。
|
||||
const seenQIDs = new Set()
|
||||
document.querySelectorAll('#question-list [data-qid]').forEach(el => seenQIDs.add(Number(el.dataset.qid)))
|
||||
items = items.filter(q => !seenQIDs.has(q.id))
|
||||
if (items.length === 0) {
|
||||
more = false
|
||||
return
|
||||
}
|
||||
|
||||
// 服务端下发复合键集游标(见上方注释),前端不自行拼接;
|
||||
// has_more 由服务端多取一条探测得出,最后一页加载完立即隐藏按钮。
|
||||
more = payload.has_more !== false
|
||||
cursor = payload.next_cursor || cursor
|
||||
items.forEach(question => {
|
||||
const div = document.createElement('div')
|
||||
div.dataset.qid = question.id
|
||||
div.innerHTML = `
|
||||
<div>
|
||||
<hr>
|
||||
<a class='uk-button uk-button-default uk-button-small uk-float-right'
|
||||
href='/_/{{.PageUser.Domain}}/${question.id}'>查看回答</a>
|
||||
<div class='uk-text-left uk-text-small uk-text-muted'>
|
||||
${question.is_pinned ? '<span class=\'tb-pin-flag\' title=\'{{$pinTitle}}\'>⭐</span>' : ''}
|
||||
${dayjs(question.created_at).format('YYYY-MM-DD HH:mm:ss')}
|
||||
</div>
|
||||
<p class='uk-text-small uk-text-break tb-preline tb-clamp-5'></p>
|
||||
</div>`
|
||||
div.getElementsByTagName('p')[0].innerText = question.content
|
||||
document.getElementById('question-list').appendChild(div)
|
||||
})
|
||||
})
|
||||
// 网络失败/响应非法 JSON 时复位 loading,避免按钮永远停留在加载中状态
|
||||
.catch(() => { loading = false })
|
||||
}" class="uk-button uk-button-default uk-width-1-1 uk-margin-small-bottom">
|
||||
<span x-show="!loading">加载更多</span>
|
||||
<span x-show="loading"><div uk-spinner="ratio: 0.8"></div> 加载中...</span>
|
||||
</button>
|
||||
<div x-show="!more" class="uk-text-meta uk-text-center">
|
||||
<hr>
|
||||
无更多留言
|
||||
<br><br>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user