diff --git a/src/components/uh-glass-picker/uh-glass-picker.vue b/src/components/uh-glass-picker/uh-glass-picker.vue
new file mode 100644
index 0000000..f419974
--- /dev/null
+++ b/src/components/uh-glass-picker/uh-glass-picker.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/uh-glass-popup/uh-glass-popup.vue b/src/components/uh-glass-popup/uh-glass-popup.vue
index 685a824..2b51b95 100644
--- a/src/components/uh-glass-popup/uh-glass-popup.vue
+++ b/src/components/uh-glass-popup/uh-glass-popup.vue
@@ -23,6 +23,8 @@
radius ?: string
/** 是否开启 wot 位置自适应圆角(bottom→上圆角 / center→四圆角等),与 radius 二选一 */
round ?: boolean
+ lazyRender ?: boolean
+ hideWhenClose?: boolean
/** 追加到面板的内联样式,如宽度:width:640rpx; */
customStyle ?: string
customClass? :string
@@ -43,6 +45,8 @@
safeAreaInsetBottom: false,
radius: '',
round: false,
+ lazyRender: true,
+ hideWhenClose: true,
customStyle: '',
customClass:''
})
@@ -66,10 +70,12 @@
:closable="closable"
:modal="modal"
:close-on-click-modal="closeOnClickModal"
+ :hide-when-close="hideWhenClose"
:safe-area-inset-bottom="safeAreaInsetBottom"
:round="round"
:custom-style="panelStyle"
:custom-class="panelClass"
+ :lazy-render="lazyRender"
@update:model-value="(value: boolean) => emit('update:modelValue', value)"
@close="emit('close')"
@click-modal="emit('click-modal')"
diff --git a/src/components/uh-links-mini-apply/uh-links-mini-apply.vue b/src/components/uh-links-mini-apply/uh-links-mini-apply.vue
index 7b48239..31bbf52 100644
--- a/src/components/uh-links-mini-apply/uh-links-mini-apply.vue
+++ b/src/components/uh-links-mini-apply/uh-links-mini-apply.vue
@@ -201,7 +201,7 @@
+ custom-class="!border rounded-xl" @close="handleClose(false)">
申请收录小程序
diff --git a/src/components/uh-plugin-unavailable/uh-plugin-unavailable.vue b/src/components/uh-plugin-unavailable/uh-plugin-unavailable.vue
index a78b717..953985c 100644
--- a/src/components/uh-plugin-unavailable/uh-plugin-unavailable.vue
+++ b/src/components/uh-plugin-unavailable/uh-plugin-unavailable.vue
@@ -6,6 +6,7 @@
pluginId : string
errorText ?: string
checking : boolean
+ customClass ?: string
}>(), {
errorText: '',
})
@@ -16,7 +17,7 @@
/** 插件信息(未在清单中时兜底) */
const pluginInfo = computed(() => {
- return NeedPlugins.get(props.pluginId) ?? {pluginId:props.pluginId, name: '未找到插件' }
+ return NeedPlugins.get(props.pluginId) ?? { pluginId: props.pluginId, name: '未找到插件' }
})
function handleRefresh() {
@@ -26,7 +27,9 @@
-
+
@@ -46,8 +49,7 @@
+ open-type="contact" hover-class="none">提交反馈
@@ -59,5 +61,6 @@
.uh-contact-btn::after {
border: none;
}
+
/* #endif */
\ No newline at end of file
diff --git a/src/components/uh-plugin-unavailable/uh-plugin-unavailable.vue.bak b/src/components/uh-plugin-unavailable/uh-plugin-unavailable.vue.bak
deleted file mode 100644
index 03dd947..0000000
--- a/src/components/uh-plugin-unavailable/uh-plugin-unavailable.vue.bak
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-
-
- {{ pluginInfo.name }}
-
-
-
- 未安装/启用插件
-
-
-
- {{ pluginInfo.desc }}
-
-
-
- {{ errorText }}
-
-
-
- 插件地址:{{ pluginInfo.url }}
-
-
-
-
-
- 复制地址
-
-
-
-
-
- 复制地址
-
-
- 提交反馈
-
-
-
-
-
-
-
- 刷新试试
-
-
-
-
- 提示:请确保 Halo 博客已安装相关插件
-
-
-
-
-
diff --git a/src/pages-blog/friend-links/friend-links.vue b/src/pages-blog/friend-links/friend-links.vue
index eb24f62..fe0d71c 100644
--- a/src/pages-blog/friend-links/friend-links.vue
+++ b/src/pages-blog/friend-links/friend-links.vue
@@ -5,6 +5,7 @@
import { getMiniProgramLinkGroupedList } from '@/api/uni-halo'
import { useAppConfigStore } from '@/store/appConfig'
import { useSettingStore } from '@/store/setting'
+ import { sleep } from '@/utils/common'
import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
import { checkAvatarUrl, checkImageUrl } from '@/utils/url'
import { NeedPluginIds } from '@/hooks/usePluginAvailable'
@@ -29,24 +30,37 @@
/** 站点 tab:PluginLinks */
const { pluginId: sitePluginId, checking: siteChecking, tips: siteTips, available: sitePluginAvailable, check: checkSitePluginAvailable } = usePluginAvailable({
pluginId: NeedPluginIds.PluginLinks,
- tips: '检测到当前插件没有安装或者启用,无法使用友情链接功能哦,请联系管理员',
+ tips: '啊偶,功能正在维护中...',
+ callback: (isAvailable) => {
+ if (!isAvailable) { return }
+ uni.pageScrollTo({
+ scrollTop: 0,
+ duration: 0,
+ })
+ handleGetLinkGroupData()
+ }
})
/** 小程序 tab:plugin-uni-halo */
const { pluginId: miniPluginId, checking: miniChecking, tips: miniTips, available: miniPluginAvailable, check: checkMiniPluginAvailable } = usePluginAvailable({
pluginId: NeedPluginIds.PluginUniHalo,
- tips: '检测到当前插件没有安装或者启用,无法使用小程序链接功能哦,请联系管理员',
+ tips: '啊偶,功能正在维护中...', callback: (isAvailable) => {
+ if (!isAvailable) { return }
+ uni.pageScrollTo({
+ scrollTop: 0,
+ duration: 0,
+ })
+ handleGetMiniProgramLinks()
+ }
})
/** 重新检测站点插件:可用则拉取友链数据(供 uh-plugin-unavailable 刷新按钮) */
async function handleSitePluginRefresh() {
- if (await checkSitePluginAvailable())
- handleGetLinkGroupData()
+ if (await checkSitePluginAvailable()) { handleGetLinkGroupData() }
}
/** 重新检测小程序插件:可用则拉取小程序链接数据(供 uh-plugin-unavailable 刷新按钮) */
async function handleMiniPluginRefresh() {
- if (await checkMiniPluginAvailable())
- handleGetMiniProgramLinks()
+ if (await checkMiniPluginAvailable()) { handleGetMiniProgramLinks() }
}
/* ---------------- tabs ---------------- */
@@ -64,8 +78,7 @@
// 审核模式下小程序 tab 隐藏,强制停留在站点 tab
watch(() => appConfigStore.auditModeEnabled, (enabled) => {
- if (enabled)
- activeTabIndex.value = 0
+ if (enabled) { activeTabIndex.value = 0 }
})
/* ==================== 站点 tab(plugin-links) ==================== */
@@ -122,12 +135,11 @@
},
}))
dataList.value = dataList.value.concat(list)
- setTimeout(() => {
- updateSiteLoadingStatus(
- dataList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success,
- )
- loadMoreText.value = res.data.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~'
- }, 500)
+ await sleep(600)
+ updateSiteLoadingStatus(
+ dataList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success,
+ )
+ loadMoreText.value = res.data.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~'
}
catch (err) {
console.error(err)
@@ -135,9 +147,7 @@
loadMoreText.value = '加载失败,请下拉刷新!'
}
finally {
- setTimeout(() => {
- uni.stopPullDownRefresh()
- }, 500)
+ uni.stopPullDownRefresh()
}
}
@@ -173,13 +183,6 @@
})
}
- function calcSiteThumbnail(val ?: string) : string {
- if (!val)
- return ''
- const _val = val.endsWith('/') ? val : `${val}/`
- return `https://image.thum.io/get/width/1000/crop/800/${_val}`
- }
-
/* ==================== 小程序 tab(plugin-uni-halo) ==================== */
/* ---------------- 状态 ---------------- */
const { loadingStatus: miniLoadingStatus, updateLoadingStatus: updateMiniLoadingStatus } = useDataLoadingStatus()
@@ -193,20 +196,17 @@
try {
const res = await getMiniProgramLinkGroupedList()
miniGroups.value = res.data || []
- setTimeout(() => {
- updateMiniLoadingStatus(
- miniGroups.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success,
- )
- }, 500)
+ await sleep(600)
+ updateMiniLoadingStatus(
+ miniGroups.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success,
+ )
}
catch (err) {
console.error(err)
updateMiniLoadingStatus(DataLoadingStatusEnum.Error)
}
finally {
- setTimeout(() => {
- uni.stopPullDownRefresh()
- }, 500)
+ uni.stopPullDownRefresh()
}
}
@@ -393,16 +393,17 @@
-
+
-
+
站点详情
@@ -418,23 +419,24 @@
-
-
+
+
{{ detail.data.spec.displayName }}
- {{ detail.data.spec.groupName }}
-
+ {{ detail.data.spec.groupName }}
+
复制地址
- {{ detail.data.spec.url }}
+ {{ detail.data.spec.url }}
-
+
{{ detail.data.spec.description || '这个博主很懒,没写简介~' }}
@@ -457,11 +459,11 @@
-
-
-
+
+
+
{{ group.displayName || '未分组' }}
+ class="text-sm text-gray-900 font-bold">{{ group.displayName || '未分组' }}
({{ group.links.length }})
@@ -491,9 +493,9 @@
-
+
申请
@@ -501,7 +503,8 @@
-
+
小程序详情
diff --git a/src/pages-blog/love/list.vue b/src/pages-blog/love/list.vue
index 3df1186..7cc438c 100644
--- a/src/pages-blog/love/list.vue
+++ b/src/pages-blog/love/list.vue
@@ -241,10 +241,8 @@
-
-
@@ -263,16 +261,10 @@
-
-
-
- 看看我们的恋爱清单都完成了哪些吧
-
@@ -298,10 +290,10 @@
-
+
计划内容
-
+
{{ item.content || '-' }}
diff --git a/src/pages-blog/search/search.vue b/src/pages-blog/search/search.vue
index 4ba4b56..529cddc 100644
--- a/src/pages-blog/search/search.vue
+++ b/src/pages-blog/search/search.vue
@@ -22,7 +22,15 @@
const { pluginId, checking, tips, available: uniHaloPluginAvailable, check: checkPluginAvailable } = usePluginAvailable({
pluginId: NeedPluginIds.PluginSearchWidget,
- tips: '啊偶,当前功能未开放!',
+ tips: '啊偶,功能正在维护中...',
+ callback: (isAvailable) => {
+ if (!isAvailable) { return }
+ uni.pageScrollTo({
+ scrollTop: 0,
+ duration: 0,
+ })
+ handleOnSearch()
+ }
})
async function handlePluginRefresh() {
diff --git a/src/pages-blog/setting/setting.vue b/src/pages-blog/setting/setting.vue
index 35c2770..a8c4674 100644
--- a/src/pages-blog/setting/setting.vue
+++ b/src/pages-blog/setting/setting.vue
@@ -10,7 +10,7 @@
definePage({
style: {
navigationBarTitleText: '偏好设置',
- navigationStyle: 'custom'
+ navigationStyle: 'custom',
},
})
@@ -87,7 +87,7 @@
]
/* ---------------- 状态读取 ---------------- */
- function valueOf(path : Path) : unknown {
+ function prefValueOf(path : Path) : unknown {
return getByPath(settingStore.settings, path)
}
@@ -133,11 +133,17 @@
settingStore.savePreference(buildPatch(path, null))
}
- /* ---------------- 枚举底部弹层 ---------------- */
+ /* ---------------- 枚举底部弹层(uh-glass-popup + wd-picker-view) ---------------- */
const enumSheet = ref<{ show : boolean, def : PrefDef | null }>({ show: false, def: null })
+ /** 弹层内滚动中的临时选中值(单列;确认时才落库,取消不生效) */
+ const pickerValue = ref<(string | number)[]>([''])
function handleOpenEnum(def : PrefDef) {
+ console.log('handleOpenEnum', def)
enumSheet.value = { show: true, def }
+ // 打开时同步当前值(跟随站点默认 → 空串哨兵)
+ pickerValue.value = [isFollowing(def) ? '' : String(prefValueOf(def.path) ?? '')]
+ console.log('pickerValue', pickerValue.value)
}
function handleCloseEnum() {
@@ -157,37 +163,59 @@
handleCloseEnum()
}
- /* ---------------- wd-picker 弹层数据 ---------------- */
+ /* ---------------- wd-picker-view 弹层数据 ---------------- */
/** 枚举弹层列(首项「跟随站点默认」,空串哨兵映射 null) */
const enumColumns = computed(() => {
const def = enumSheet.value.def
- if (!def)
- return []
+ if (!def) { return [] }
return [
{ label: '跟随站点默认', value: '' },
...(def.options || []).map(opt => ({ label: opt.label, value: opt.value })),
]
})
- /** 当前选中列值(单列;跟随站点默认时为空串) */
- const enumValue = computed(() => {
- const def = enumSheet.value.def
- if (!def)
- return ['']
- return [isFollowing(def) ? '' : String(valueOf(def.path) ?? '')]
- })
+ /** wd-picker-view 滚动变化:更新临时选中值(未确认不落库) */
+ function handlePickerChange(payload : { selectedValues : (string | number)[] }) {
+ pickerValue.value = payload.selectedValues
+ }
- /** wd-picker 确认:空串哨兵还原为「跟随站点默认」 */
- function handlePickerConfirm(payload: { value: (string | number)[] }) {
- const picked = String(payload.value[0] ?? '')
+ /** 确认:空串哨兵还原为「跟随站点默认」 */
+ function handlePickerConfirm() {
+ const picked = String(pickerValue.value[0] ?? '')
handleChooseEnum(picked === '' ? null : picked)
}
+ /** 取消:不落库,直接关闭 */
+ function handlePickerCancel() {
+ handleCloseEnum()
+ }
+
/** 当前枚举项是否处于「跟随站点默认」 */
function isFollowing(def : PrefDef) : boolean {
return !isOverridden(def.path)
}
+ /* ---------------- 展示行(预计算,避免模板渲染期函数调用) ---------------- */
+ /** 偏好展示行:展示文本/跟随态/开关值在数据层算好,模板只做属性访问 */
+ interface PrefRow extends PrefDef {
+ displayValue : string
+ following : boolean
+ /** 仅 kind==='bool' 使用 */
+ boolValue : boolean
+ }
+
+ function buildRows(defs : PrefDef[]) : PrefRow[] {
+ return defs.map(def => ({
+ ...def,
+ displayValue: enumLabelOf(def, prefValueOf(def.path)),
+ following: isFollowing(def),
+ boolValue: def.kind === 'bool' ? prefValueOf(def.path) === true : false,
+ }))
+ }
+
+ const layoutRows = computed(() => buildRows(layoutPrefs))
+ const featureRows = computed(() => buildRows(featurePrefs))
+
/* ---------------- 重置全部 ---------------- */
function handleResetAll() {
uni.showModal({
@@ -211,10 +239,10 @@
-
-
+
+
-
+
@@ -224,14 +252,14 @@
-
+ :class="index < layoutRows.length - 1 ? 'border-b border-black/5' : ''"
+ @click="handleOpenEnum(row)">
- {{ def.label }}
+ {{ row.label }}
- 跟随站点默认
+ 跟随站点默认
已自定义
@@ -239,8 +267,7 @@
- {{ enumLabelOf(def, valueOf(def.path)) }}
+ {{ row.displayValue }}
@@ -255,64 +282,87 @@
-
+
-
+
- {{ def.label }}
+ {{ row.label }}
- 跟随站点默认
+ 跟随站点默认
已自定义
恢复默认
+ @click.stop="handleRevert(row.path)">
+ 恢复默认
+
-
+
+ :class="index < featureRows.length - 1 ? 'border-b border-black/5' : ''"
+ @click="handleOpenEnum(row)">
- {{ def.label }}
+ {{ row.label }}
- 跟随站点默认
+ 跟随站点默认
已自定义
恢复默认
+ @click.stop="handleRevert(row.path)">
+ 恢复默认
+
- {{ enumLabelOf(def, valueOf(def.path)) }}
+ {{ row.displayValue }}
-
-
- 恢复默认
+
+
+
+ 恢复默认
+
-
-
+
+
+
+
+
+
+ {{ enumSheet.def?.label || '请选择' }}
+
+
+
+
+
+
+ 取消
+
+
+ 确定
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/pages/tabbar/gallery/gallery.vue b/src/pages/tabbar/gallery/gallery.vue
index 0790d41..78d1273 100644
--- a/src/pages/tabbar/gallery/gallery.vue
+++ b/src/pages/tabbar/gallery/gallery.vue
@@ -4,6 +4,8 @@
import { getPhotoGroupList, getPhotoListByGroupName } from '@/api/halo'
import { useAppConfigStore } from '@/store/appConfig'
import { checkImageUrl } from '@/utils/url'
+ import { usePluginAvailable } from '@/hooks/usePluginAvailable'
+ import { sleep } from '@/utils/common'
import { t } from '@/locale'
import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
import type { IPhoto, IPhotoGroup } from '@/api/types/halo'
@@ -25,7 +27,7 @@
/** 依赖插件(PluginPhotos) */
const { pluginId, checking, tips, available: uniHaloPluginAvailable, check: checkPluginAvailable } = usePluginAvailable({
pluginId: 'PluginPhotos',
- tips: '很抱歉,功能正在维护中...',
+ tips: '啊偶,功能正在维护中...',
callback: (isAvailable) => {
if (!isAvailable) { return }
uni.pageScrollTo({
@@ -114,6 +116,7 @@
? dataList.value.concat(list)
: list
}
+ await sleep(600)
updateLoadingStatus(dataList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
loadMoreText.value = res.data.hasNext ? t('common.loadMore') : t('common.noMore')
}
@@ -123,11 +126,7 @@
loadMoreText.value = t('common.loadFailed')
}
finally {
- setTimeout(() => {
- uni.hideLoading()
- uni.stopPullDownRefresh()
- lock.value = false
- }, 500)
+ uni.stopPullDownRefresh()
}
}
@@ -191,29 +190,30 @@
-
+
+
- {{ cate.spec.displayName }} ({{ cate.status?.photoCount ?? 0 }})
+ {{ cate.spec.displayName }}
+
+ ({{ cate.status?.photoCount ?? 0 }})
+
-
-
- /**
- * 瞬间页(源自旧项目 pages/tabbar/moments/moments.vue,新建复刻)
- * 功能:瞬间卡片列表(头像/内容/图片/音频/视频/标签) + 分页加载
- * 设计:社交信息流(实心白纸卡 + 着色昵称 + 朋友圈式不缩进正文),区别于工具页的玻璃拟态
- */
import { computed, ref } from 'vue'
import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
+ import dayjs from 'dayjs'
import { getMomentList } from '@/api/halo'
import { useAppConfigStore } from '@/store/appConfig'
import { NeedPluginIds } from '@/hooks/usePluginAvailable'
@@ -13,8 +9,8 @@
import { checkAvatarUrl, checkThumbnailUrl } from '@/utils/url'
import { buildMomentFavoriteItem } from '@/utils/favorite'
import { generateUUID } from '@/utils/uuid'
+ import { sleep } from '@/utils/common'
import { formatTime } from '@/utils/formatTime'
- import { randomTagColor } from '@/utils/random'
import { t } from '@/locale'
import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
import { markdownConfig } from '@/config/markdown'
@@ -42,22 +38,26 @@
}
})
- /** 站点名称(原 startConfig.title 已随启动页下线,改读 appConfig.appInfo.name) */
const siteName = computed(() => {
const appInfo = haloConfigs.value.appConfig?.appInfo as { name ?: string } | undefined
return appInfo?.name || bloggerInfo.value.nickname || 'uni-halo'
})
- /** 依赖插件(plugin-moments,参考 gallery 对象传参模式) */
const { pluginId, checking, tips, available: uniHaloPluginAvailable, check: checkPluginAvailable } = usePluginAvailable({
pluginId: NeedPluginIds.PluginMoments,
- tips: '检测到当前插件没有安装或者启用,无法使用瞬间功能哦,请联系管理员',
+ tips: '啊偶,功能正在维护中...',
+ callback: (isAvailable) => {
+ if (!isAvailable) { return }
+ uni.pageScrollTo({
+ scrollTop: 0,
+ duration: 0,
+ })
+ handleGetData()
+ }
})
- /** 重新检测插件:可用则拉取数据(供 uh-plugin-unavailable 刷新按钮) */
async function handlePluginRefresh() {
- if (await checkPluginAvailable())
- handleGetData()
+ if (await checkPluginAvailable()) { handleGetData() }
}
/* ---------------- 状态 ---------------- */
@@ -70,6 +70,10 @@
videos ?: { id ?: string, url : string }[]
audios ?: { type ?: string, url : string }[]
spec : IMoment['spec'] & { newHtml ?: string }
+ year : string
+ month : string
+ day : string
+ weekend : string
}
const dataList = ref([])
const isLoadMore = ref(false)
@@ -77,20 +81,33 @@
const videoContexts = ref>({})
const currentVideoId = ref(null)
- /** 移除内容中的 tag 链接 */
function removeTagLinksCompletely(htmlString : string) : string {
const regex = /]+class=(['"])[^'"]*\btag\b[^'"]*\1[^>]*>[\s\S]*?<\/a>/gi
return htmlString.replace(regex, '')
}
- /** 瞬间项映射(spec.content.medium 拆分为 images/videos/audios + 内容 tag 清理 + 作者兜底) */
+ const WEEKDAY_TEXT = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
+
+ function splitMomentDate(timeStr ?: string) {
+ const d = timeStr ? dayjs(timeStr) : null
+ if (!d || !d.isValid()) {
+ return { year: '', month: '', day: '', weekend: '' }
+ }
+ return {
+ year: `${d.year()}`,
+ month: `${d.month() + 1}`,
+ day: `${d.date()}`,
+ weekend: WEEKDAY_TEXT[d.day()],
+ }
+ }
+
function mapMomentItem(item : IMoment) : MomentCard {
const medium = (item.spec.content?.medium || [])
.map(x => ({ ...x, url: x.url || '' }))
const owner = item.owner
return {
...item,
- // 无顶层 owner(如个别历史接口)时兜底为博主信息
+ ...splitMomentDate(item.spec?.releaseTime),
owner: owner?.displayName
? owner
: { displayName: bloggerInfo.value.nickname || '', name: bloggerInfo.value.nickname || '', avatar: bloggerInfo.value.avatar },
@@ -107,7 +124,6 @@
/* ---------------- 数据加载 ---------------- */
async function handleGetData() {
if (calcAuditModeEnabled.value) {
- // 审核模式:真实瞬间按 audit-data moments 过滤(数组顺序即展示顺序)
const auditMomentNames = appConfigStore.auditData.spec?.moments || []
try {
const res = await getMomentList({ page: 1, size: 0 })
@@ -117,12 +133,9 @@
filtered.sort((a, b) => (orderMap.get(a.metadata.name) ?? 999) - (orderMap.get(b.metadata.name) ?? 999))
const tempItems = filtered.map(mapMomentItem)
dataList.value = tempItems
- nextTick(() => {
- createVideoContexts(tempItems)
- })
+ await sleep(600)
updateLoadingStatus(dataList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
loadMoreText.value = t('common.noMore')
- uni.hideLoading()
uni.stopPullDownRefresh()
}
catch (err) {
@@ -133,7 +146,6 @@
return
}
- uni.showLoading({ mask: true, title: t('common.loading') })
if (!isLoadMore.value) {
updateLoadingStatus(DataLoadingStatusEnum.Loading)
}
@@ -151,11 +163,9 @@
dataList.value = isLoadMore.value
? dataList.value.concat(tempItems)
: tempItems
- updateLoadingStatus(dataList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
- nextTick(() => {
- createVideoContexts(tempItems)
- })
+ await sleep(600)
+ updateLoadingStatus(dataList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
}
catch (err) {
console.error(err)
@@ -163,46 +173,10 @@
loadMoreText.value = t('common.loadFailed')
}
finally {
- setTimeout(() => {
- uni.hideLoading()
- uni.stopPullDownRefresh()
- }, 500)
+ uni.stopPullDownRefresh()
}
}
- /* ---------------- 视频互斥 ---------------- */
- function createVideoContexts(list : { videos ?: { id ?: string }[] }[]) {
- stopAllVideos()
- list.map(item => item.videos || []).flat().forEach((item) => {
- if (item.id) {
- videoContexts.value[item.id] = uni.createVideoContext(`video_${item.id}`)
- }
- })
- }
-
- function stopAllVideos(excludesVideoId : string | null = null) {
- Object.keys(videoContexts.value).forEach((videoId) => {
- if (!excludesVideoId || excludesVideoId !== videoId) {
- videoContexts.value[videoId]?.pause()
- }
- })
- }
-
- function onVideoPlay(videoId : string) {
- currentVideoId.value = videoId
- stopAllVideos(videoId)
- }
-
- function onVideoPause(videoId : string) {
- if (currentVideoId.value === videoId) {
- currentVideoId.value = null
- }
- }
-
- function onVideoEnded() {
- currentVideoId.value = null
- }
-
/* ---------------- 交互 ---------------- */
function handlePreview(index : number, list : { url : string }[]) {
uni.previewImage({
@@ -220,12 +194,10 @@
})
}
- /** 是否已收藏该瞬间(卡片收藏格高亮) */
function isMomentFavorite(moment : IMoment) : boolean {
return favoritesStore.isFavorite('moment', moment.metadata.name)
}
- /** 切换收藏(收藏/取消),收藏时按当前卡片内容生成快照入库 */
function handleToggleMomentFavorite(moment : MomentCard) {
if (!moment) { return }
const favorited = favoritesStore.toggle(buildMomentFavoriteItem(moment))
@@ -271,7 +243,8 @@
})
onReachBottom(() => {
- if (!uniHaloPluginAvailable.value) { return }
+ if (!uniHaloPluginAvailable.value)
+ return
if (calcAuditModeEnabled.value) {
uni.showToast({ icon: 'none', title: t('common.noMoreData') })
return
@@ -288,108 +261,105 @@
-
-
+
+
-
+ min-height="75vh" @refresh="handleGetData" />
-
-
-
-
-
-
-
-
-
- {{ moment.owner?.displayName || bloggerInfo.nickname }}
-
-
- {{ formatMomentTime(moment.spec.releaseTime) }}
+
+
+
+
+ {{ moment.day }}/{{ moment.month }}
+ {{ moment.year }}
+ {{ moment.weekend }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ moment.owner?.displayName || bloggerInfo.nickname }}
+
+
+ {{ formatMomentTime(moment.spec.releaseTime) }}
+
+
+
+ 详情
+
+
-
- 详情
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+ # {{ tag }}
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- # {{ tag }}
-
-
-
-
-
-
-
- 点赞 {{ moment.stats.upvote || 0 }}
-
-
-
- 评论 {{ moment.stats.totalComment || 0 }}
-
-
-
- {{ isMomentFavorite(moment) ? '已收藏' : '收藏' }}
+
+
+
+
+ 点赞 {{ moment.stats.upvote || 0 }}
+
+
+
+ 评论 {{ moment.stats.totalComment || 0 }}
+
+
+
+
+ {{ isMomentFavorite(moment) ? '已收藏' : '收藏' }}
+
+
-
{{ loadMoreText }}