fix(asset-detail): fade in sibling modules during up-pull collapse

The .card-siblings wrapper lives inside <scroll-view v-else>, so when
viewMode flips to 'expanded' the wrapper is destroyed and the
siblingFadeOpacity binding has no element to animate. Up-pull therefore
shows nothing fading in even though the computed correctly returns
0 -> 1.

Add a top-level overlay that mirrors the same four modules
(card-meta-row, info-row, creator-section, chain-section) and binds
its opacity to siblingFadeOpacity. The overlay is rendered only when
viewMode === 'expanded', positioned fixed at the bottom with z-index 60
(above the expanded card at 50, below the header at 100), and uses
pointer-events: none on the wrapper so the up-pull gesture from the
lower viewport can still reach .pull-collapse-surface; interactive
children re-enable pointer-events: auto.

The original .card-siblings inside <scroll-view> is untouched and
still drives the down-pull fade-out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
zerosaturation 2026-07-28 15:56:45 +08:00
parent 3d984f19cd
commit 128a12fa03

View File

@ -253,6 +253,134 @@
</view>
</scroll-view>
<!-- 2026-07-28 fix (sibling fade-in): detail-container 顶层再渲染一份 .card-siblings,
仅在 expanded 态挂载原因:v-if/v-else-if expanded <scroll-view> ,
.card-siblings 节点随父级一起消失,导致 siblingFadeOpacity up-pull 阶段虽然
正确算出 01 DOM 上无元素可绑,上拉收起过程中 sibling modules 始终不可见
这份 overlay 复用父级作用域的 isLiked/likeCount/assetData 等所有响应式数据(无需 props),
opacity siblingFadeOpacity 即可接住上拉渐显;正常态下 scroll-view 里仍有一份原版 -->
<view v-if="viewMode === 'expanded'" class="card-siblings-expanded-overlay">
<view class="card-siblings"
:style="{ opacity: siblingFadeOpacity, transition: 'opacity .12s linear' }">
<!-- 点赞 + 收益 + 倒计时行 -->
<view class="card-meta-row">
<!-- 点赞 -->
<view class="like-area" @tap="handleLike">
<image :src="isLiked ? '/static/icon/like-after.png' : '/static/icon/like-before.png'"
class="like-icon" mode="aspectFit"></image>
<text class="like-num">{{ likeCount || 0 }}</text>
</view>
<!-- 收益 -->
<view class="earnings-area">
<image class="crystal-icon" src="/static/icon/crystal.png" mode="aspectFit"></image>
<text class="earnings-text">{{ assetData.hourly_earnings || 5 }}/</text>
</view>
<!-- 倒计时如有 -->
<view v-if="assetData.display_status === 1 && countdownText" class="countdown-area">
<view class="countdown-pill">
<image class="crystal-icon" src="/static/assetDetail/time.png" mode="aspectFit">
</image>
<text class="countdown-val">{{ countdownText }}</text>
</view>
</view>
</view>
<!-- 信息行创作者 + 铸造时间 + 来源 -->
<view class="info-row">
<view class="info-col">
<view class="info-item">
<text class="info-label">来源</text>
<text class="info-value">{{ assetData.source || '铸造' }}</text>
</view>
</view>
<view class="info-col">
<view class="info-item">
<text class="info-label">创作者</text>
<view class="info-nickname">
<image v-if="assetData.owner?.avatar" class="info-avatar"
:src="assetData.owner.avatar" mode="aspectFill">
</image>
<text class="info-value">{{ assetData.owner_nickname || '未知' }}</text>
</view>
</view>
</view>
<view class="info-col">
<view class="info-item">
<text class="info-label">铸造时间</text>
<text class="info-value">{{ formattedAcquireTime }}</text>
</view>
</view>
</view>
<!-- 创作者信息模块 -->
<view v-if="likeCount > 0" class="creator-section" @tap="showLikeUsersModal = true">
<!-- 点赞用户头像区域 -->
<view class="liked-users-area">
<view v-for="(user, index) in likedUsers" :key="index" class="liked-user-avatar" :style="{
transform: `translate(${user.ellipseX || 0}rpx, ${user.ellipseY || 0}rpx) scale(${user.size || 1})`,
zIndex: index < 2 ? index + 1 : (index < 4 ? index + 3 : index + 1)
}">
<image class="liked-user-image" :src="user.avatar" mode="aspectFill"></image>
</view>
</view>
<view class="creator-info">
<text class="creator-title">TA们最近为你点过赞</text>
<view class="creator-card">
<text class="creator-tip">点击查看</text>
<image class="creator-preview" src="/static/rank/activity-support-icon/tubiao.png"
mode="aspectFill"></image>
</view>
</view>
</view>
<!-- 链上数据 -->
<view class="chain-section">
<image class="chain-logo" src="/static/logo/APPLOGO.png" mode="aspectFit"></image>
<view class="chain-left">
<view class="chain-row">
<text class="chain-label">数根名称</text>
<view class="chain-value-wrap">
<text class="chain-value">{{ assetData.name || '未知' }}</text>
</view>
</view>
<view class="chain-row">
<text class="chain-label">数根发行方</text>
<view class="chain-value-wrap">
<text class="chain-value">TOPFANS</text>
</view>
</view>
<view class="chain-row">
<text class="chain-label">区块链编号</text>
<view class="chain-value-wrap">
<text class="chain-value">{{ showBlockNumber ? (assetData.block_number || '未知') :
hiddenBlockNumber }}</text>
<view class="toggle-btn" @tap="showBlockNumber = !showBlockNumber">
<image class="toggle-icon"
:src="showBlockNumber ? '/static/icon/show.png' : '/static/icon/hide.png'"
mode="aspectFit"></image>
</view>
</view>
</view>
<view class="chain-row">
<text class="chain-label">链上哈希</text>
<view class="chain-value-wrap">
<text class="chain-value chain-hash" @longpress="copyHash">{{ showTxHash ? displayTxHash
: hiddenTxHash }}</text>
<view class="toggle-btn" @tap="showTxHash = !showTxHash">
<image class="toggle-icon"
:src="showTxHash ? '/static/icon/show.png' : '/static/icon/hide.png'"
mode="aspectFit"></image>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 点赞用户弹窗 -->
<LikeUsersModal :visible="showLikeUsersModal" :tabs="[]" @close="showLikeUsersModal = false">
<template #content>
@ -2037,6 +2165,31 @@ onUnmounted(() => {
will-change: opacity;
}
/* 2026-07-28 fix (sibling fade-in): expanded .card-siblings overlay,
父级 detail-container 顶层渲染, expanded 态挂载opacity siblingFadeOpacity,
上拉收起过程中 01 渐显,接住原本因 scroll-view 销毁而丢失的渐显视觉
position: fixed + bottom: 0 overlay 始终贴底;跟手过程 wrapper surface 整体
translateY(-pullDistance) 把卡片往上推,overlay 自然落在腾出的下方空间
pointer-events: none 让上拉手势从 overlay 范围也能穿透到 .pull-collapse-surface;
单独给 .like-area/.creator-section/.toggle-btn/.chain-hash auto,让交互元素仍可点 */
.card-siblings-expanded-overlay {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 60;
padding: 40rpx;
background: transparent;
pointer-events: none;
}
.card-siblings-expanded-overlay .like-area,
.card-siblings-expanded-overlay .creator-section,
.card-siblings-expanded-overlay .toggle-btn,
.card-siblings-expanded-overlay .chain-hash {
pointer-events: auto;
}
/* 2026-07-27 refactor (Finding B): ,
2026-07-28 fix: fixed 定位脱离滚动容器与 pull transform,固定在 header(top:96rpx, z-index:100)
下方;z-index 95 保证盖住卡片和滚动内容,但仍在 header 之下 */