update
This commit is contained in:
@ -31,7 +31,7 @@ const images = (snap?.images ?? [])
|
||||
.filter((im) => im.url)
|
||||
|
||||
// 未登录预览上限:详情页(图集)未登录最多展示前 PREVIEW_LIMIT 张图片;其余由登录门禁提示,
|
||||
// 已登录(客户端 loadFull 拉全量)或图片本就不超上限时全部展示。前 PREVIEW_LIMIT 张服务端已渲染(SEO/无 JS 友好)。
|
||||
// 已登录(客户端 loadAuthedState 拉全量)或图片本就不超上限时全部展示。前 PREVIEW_LIMIT 张服务端已渲染(SEO/无 JS 友好)。
|
||||
const PREVIEW_LIMIT = 5
|
||||
const previewImages = images.slice(0, PREVIEW_LIMIT)
|
||||
|
||||
@ -141,7 +141,7 @@ const displayTitle = (snap?.title || "").replace(/\t/g, " · ")
|
||||
))
|
||||
}
|
||||
|
||||
{/* 登录后追加的额外图片:extraImages 由客户端 loadFull() 在已登录时填充,未登录为空不渲染 */}
|
||||
{/* 登录后追加的额外图片:extraImages 由客户端 loadAuthedState() 在已登录时填充,未登录为空不渲染 */}
|
||||
<template x-for="(im, i) in extraImages" :key="im.url">
|
||||
<figure
|
||||
:data-image-index="5 + i"
|
||||
@ -351,8 +351,9 @@ const displayTitle = (snap?.title || "").replace(/\t/g, " · ")
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import { getUser, getStreetSnapDetailAuthed, toAbs } from "@/lib/api"
|
||||
import { isFavorited, toggleImageFavorite, checkFavorited } from "@/lib/favorites"
|
||||
import { getStreetSnapDetailAuthed, toAbs } from "@/lib/api"
|
||||
import { getUser } from "@/lib/auth"
|
||||
import { isFavorited, toggleImageFavorite } from "@/lib/favorites"
|
||||
|
||||
document.addEventListener("alpine:init", () => {
|
||||
Alpine.data("streetSnapView", () => ({
|
||||
@ -374,6 +375,8 @@ const displayTitle = (snap?.title || "").replace(/\t/g, " · ")
|
||||
isAuthed: false,
|
||||
// 未登录门禁:后端截断图片集时为 true(详情页最多看 PREVIEW_LIMIT 张)
|
||||
preview: false,
|
||||
// 已登录态图集级(gallery,s=)收藏态:由 loadAuthedState 从详情接口取回,广播给 fav-fab
|
||||
galleryFav: false,
|
||||
// 已登录后客户端补拉的全量图片(前 PREVIEW_LIMIT 张已由 SSR 服务端渲染)
|
||||
extraImages: [] as { id: string; url: string; raw: string; name: string }[],
|
||||
|
||||
@ -392,36 +395,49 @@ const displayTitle = (snap?.title || "").replace(/\t/g, " · ")
|
||||
this.initImageFavs()
|
||||
this.maybeLocateImageFromUrl()
|
||||
|
||||
// 已登录且后端未登录截断(preview):客户端拉全量图片集并追加渲染
|
||||
if (getUser() && this.preview) this.loadFull()
|
||||
// 登录后(如从门禁跳登录回跳)自动补全全量
|
||||
window.addEventListener("auth:login", () => { this.isAuthed = true; if (this.preview) this.loadFull() })
|
||||
// 已登录:用一次详情请求拿回完整图片集 + 收藏态(合并原三处 /me/favorites/checks 调用)
|
||||
if (getUser()) this.loadAuthedState()
|
||||
// 登录后(如从门禁跳登录回跳)自动补全全量 + 收藏态
|
||||
window.addEventListener("auth:login", () => { this.isAuthed = true; if (getUser()) this.loadAuthedState() })
|
||||
},
|
||||
|
||||
// 已登录用户:拉取完整图片集,把第 PREVIEW_LIMIT+1 张起的图片追加进 extraImages 渲染。
|
||||
async loadFull() {
|
||||
if (!this.preview) return
|
||||
// 已登录:用一次详情请求拿回「完整图片集 + 收藏态」,合并原三处 /me/favorites/checks 调用。
|
||||
// gallery 级(s=)收藏态广播给页面右下角 fav-fab;image 级(j=)收藏态直接重建 favIds。
|
||||
async loadAuthedState() {
|
||||
if (!getUser()) return
|
||||
try {
|
||||
const full = await getStreetSnapDetailAuthed(this.galleryUid)
|
||||
if (!full || !Array.isArray(full.images)) return
|
||||
const mapped = (full.images || []).slice(5).map((im: any) => ({
|
||||
id: im.id || "",
|
||||
url: toAbs(im.image || ""),
|
||||
raw: im.image || "",
|
||||
name: im.name || "",
|
||||
}))
|
||||
this.extraImages = mapped
|
||||
// 后端详情接口对所有用户统一返回 high 高清样式(付费墙已取消),首屏图即为高清,
|
||||
// 无需客户端再按 VIP 替换。仅把第 6 张起的图片追加进 extraImages 渲染。
|
||||
await this.$nextTick()
|
||||
this.imageCount = document.querySelectorAll(
|
||||
"#snap-gallery [data-image-index]"
|
||||
).length
|
||||
this.initImageFavs()
|
||||
this.initThumbLazyLoading()
|
||||
this.maybeLocateImageFromUrl()
|
||||
|
||||
// gallery 级收藏态 → 广播给 fav-fab(去掉单篇 /me/favorites/checks 查询)
|
||||
this.galleryFav = !!full.favorited
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("fav:set", { detail: { id: this.galleryUid, fav: this.galleryFav } }),
|
||||
)
|
||||
|
||||
// image 级收藏态:以服务端 favorited 为准重建 favIds(覆盖 initImageFavs 的本地初值)
|
||||
const favIds: string[] = []
|
||||
const mark = (im: any) => { if (im && im.id && im.favorited) favIds.push(im.id) }
|
||||
|
||||
if (this.preview) {
|
||||
this.extraImages = (full.images || []).slice(5).map((im: any) => ({
|
||||
id: im.id || "",
|
||||
url: toAbs(im.image || ""),
|
||||
raw: im.image || "",
|
||||
name: im.name || "",
|
||||
}))
|
||||
await this.$nextTick()
|
||||
this.imageCount = document.querySelectorAll(
|
||||
"#snap-gallery [data-image-index]"
|
||||
).length
|
||||
;(full.images || []).slice(5).forEach(mark)
|
||||
this.initThumbLazyLoading()
|
||||
this.maybeLocateImageFromUrl()
|
||||
}
|
||||
;(full.images || []).slice(0, 5).forEach(mark)
|
||||
this.favIds = favIds
|
||||
} catch {
|
||||
/* 失败维持截断态,门禁仍在 */
|
||||
/* 失败维持本地/截断态,门禁仍在 */
|
||||
}
|
||||
},
|
||||
|
||||
@ -479,13 +495,12 @@ const displayTitle = (snap?.title || "").replace(/\t/g, " · ")
|
||||
.filter(Boolean)
|
||||
},
|
||||
|
||||
// 本地即时填充收藏态(未登录态,或登录态加载服务端数据前的占位,避免爱心闪烁)。
|
||||
// 登录态的服务端校正已合并进 loadAuthedState(),不再单独请求 /me/favorites/checks。
|
||||
initImageFavs() {
|
||||
const ids = this.allImageFavIds()
|
||||
if (!ids.length) return
|
||||
this.favIds = ids.filter((id) => isFavorited(id))
|
||||
checkFavorited(ids).then((hit) => {
|
||||
this.favIds = ids.filter((id) => hit.has(id))
|
||||
})
|
||||
},
|
||||
|
||||
isFav(id: string) {
|
||||
|
||||
Reference in New Issue
Block a user