观影/联系人详情卡补内置蒙版 (#78)
用户:电影这个框弹出来的时候,应该在下面盖一层蒙版吧?跟近期任务类似。 首页各浮层里只有这两张卡没有遮罩:FbTaskPanel / FbDayEditSheet 都是组件内部 根 Stack 自带遮罩+卡片,而 FbMovieDetailSheet / FbPersonSheet 两处漏了, 卡片直接浮在正文上,底下的片名、影院、联系人名字透出来。 改法(按项目既有约定:谁铺满全屏,谁负责画遮罩): - FbMovieDetailSheet.build 根节点 Column -> Stack,前面插全屏 FB_MASK 遮罩, onClick 关闭;卡片容器保持铺满+居中且 HitTestMode.Transparent; - FbPersonSheet.build 同样套一层 Stack + 遮罩(embedded 分支跳过, 那种形态宿主是 bindSheet,系统已有遮罩,再叠就是双暗); - 宿主 FbHomePage 不再包遮罩,只留注释说明。 原因:组件根节点自己铺满全屏,会在外面先吃掉点击 —— 宿主包遮罩会 蒙版看着有、点它关不掉;包两层还会越点越黑(本轮真机实测踩到)。 验证(真机 5NC0225B27004718): - 弹卡后卡片外像素 (247,243,234) -> (147,146,141),反推 alpha=0.40 = 0x66/255; - 卡片内海报 (230,212,188) 不受影响; - 点遮罩后恢复 (247,243,234),卡片关闭; - 联系人卡同样三条全过;hvigorw assembleHap BUILD SUCCESSFUL。
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
* 加载中 / 成功 / 失败。别只画成功态 —— 断网时用户会看到"空白浮层"。
|
* 加载中 / 成功 / 失败。别只画成功态 —— 断网时用户会看到"空白浮层"。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { FbColors, FbMetric, fbAlpha } from '../common/Theme';
|
import { FbColors, FbMetric, fbAlpha, FB_MASK } from '../common/Theme';
|
||||||
import { FbModuleDef, fbModuleOf, fbThemeVars } from '../model/Modules';
|
import { FbModuleDef, fbModuleOf, fbThemeVars } from '../model/Modules';
|
||||||
import { FbMovieAttendeeRow, FbMovieDetail } from '../data/FbMovieRepo';
|
import { FbMovieAttendeeRow, FbMovieDetail } from '../data/FbMovieRepo';
|
||||||
import { FB_TOKEN_STORE } from '../data/FbTokenStore';
|
import { FB_TOKEN_STORE } from '../data/FbTokenStore';
|
||||||
@@ -139,67 +139,94 @@ export struct FbMovieDetailSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
// FB_WRAP_CENTER:把卡片**垂直居中**(用户 2026-10-16 要求:浮在屏幕中间)。
|
/* 🔴 用户 2026-11-06:「电影这个框弹出来的时候,应该在下面盖一层蒙版吧?
|
||||||
// ⚠️ 居中放在**组件内部**做,而不是改宿主的 Stack 对齐 ——
|
跟近期任务类似。」
|
||||||
// 宿主 Stack 里还有别的子元素(日程页的悬浮 +),改对齐会连带挪走它们。
|
|
||||||
// ⚠️ 外层铺满 + Center;内层仍是那张 92% 宽的圆角卡。
|
⇒ 根节点是 **`Stack`**,里面「全屏遮罩 + 卡片」是兄弟节点、叠在一起 ——
|
||||||
Column() {
|
与 `FbTaskPanel`(其文件头第 ③ 条)、`FbDayEditSheet` 完全同一做法。
|
||||||
// 🔴 用 Stack 把"浮层内容"和"全屏查看器"叠起来:
|
|
||||||
// 查看器要盖住整个浮层(含它自己的圆角/把手),所以必须是
|
⚠️ 为什么蒙版做在**组件内部**、而不是宿主外面包一层:
|
||||||
// **同一个 Stack 里的后声明节点**,不能放进浮层内部的 Column
|
· 组件根节点自己铺满全屏(居中卡片需要),会把"点遮罩关闭"的点击
|
||||||
// (那会被浮层的圆角裁剪、也会被内层 Scroll 的滚动带走)。
|
吃在手里 ⇒ 蒙版看着有、点它关不掉;
|
||||||
Stack({ alignContent: Alignment.Center }) {
|
· 宿主再包一层遮罩就成了两层暗色叠在一起(越点越黑)。
|
||||||
/* ⚠️ 2026-10-19:外面这一层只给宽度(92%)——
|
⇒ 谁铺满全屏,谁负责画遮罩。这是本项目浮层的一致约定。
|
||||||
以前卡片是 `width('100%')`(贴屏幕两边)+ 内部 Scroll 92%,
|
|
||||||
看上去是"一整块通栏白",加环也没处可加(环会跑出屏幕)。
|
⚠️ 遮罩色统一用 `FB_MASK`(`#66000000`,与全站其它浮层一致;
|
||||||
现在:卡片 92% + 主题色环,内部滚动区 100%(等价于原来的内容宽度)。 */
|
实测压暗后底噪 247→147,反推 alpha≈0.40 = 0x66/255)。 */
|
||||||
Column() {
|
Stack({ alignContent: Alignment.Center }) {
|
||||||
FbSheetRing({ radius: FbMetric.radius, ringColor: this.accentColor() }) {
|
/* 全屏遮罩:点它就关(与任务面板同一交互) */
|
||||||
Column({ space: 0 }) {
|
Column()
|
||||||
this.sheetHeader()
|
.width('100%')
|
||||||
this.sheetBody()
|
.height('100%')
|
||||||
|
.backgroundColor(FB_MASK)
|
||||||
|
.onClick((): void => {
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
|
|
||||||
|
/* 卡片容器:铺满 + 居中。
|
||||||
|
⚠️ 居中放在**组件内部**做,而不是改宿主的 Stack 对齐 ——
|
||||||
|
宿主 Stack 里还有别的子元素(日程页的悬浮 +),改对齐会连带挪走它们。
|
||||||
|
⚠️ 必须 `HitTestMode.Transparent`:让点击穿透到上层遮罩,
|
||||||
|
同时卡片自身的子节点仍可点(`Block` 会让关闭按钮点不动)。 */
|
||||||
|
Column() {
|
||||||
|
// 🔴 用 Stack 把"浮层内容"和"全屏查看器"叠起来:
|
||||||
|
// 查看器要盖住整个浮层(含它自己的圆角),所以必须是
|
||||||
|
// **同一个 Stack 里的后声明节点**,不能放进浮层内部的 Column
|
||||||
|
// (那会被浮层的圆角裁剪、也会被内层 Scroll 的滚动带走)。
|
||||||
|
Stack({ alignContent: Alignment.Center }) {
|
||||||
|
/* ⚠️ 2026-10-19:外面这一层只给宽度(92%)——
|
||||||
|
以前卡片是 `width('100%')`(贴屏幕两边)+ 内部 Scroll 92%,
|
||||||
|
看上去是"一整块通栏白",加环也没处可加(环会跑出屏幕)。
|
||||||
|
现在:卡片 92% + 主题色环,内部滚动区 100%。 */
|
||||||
|
Column() {
|
||||||
|
FbSheetRing({ radius: FbMetric.radius, ringColor: this.accentColor() }) {
|
||||||
|
Column({ space: 0 }) {
|
||||||
|
this.sheetHeader()
|
||||||
|
this.sheetBody()
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
}
|
}
|
||||||
.width('100%')
|
}
|
||||||
|
.width('92%')
|
||||||
|
// ⚠️ 同样用 `Default`(不写)。`Block` 会挡住浮层内部的子节点
|
||||||
|
// (照片缩略图、关闭按钮都点不动)。
|
||||||
|
|
||||||
|
// ---- 全屏大图查看器 ----
|
||||||
|
if (this.viewerOpen) {
|
||||||
|
this.viewer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 影评 + 评论浮层(工单 #27)----
|
||||||
|
if (this.reviewsOpen && this.detail !== null) {
|
||||||
|
FbMovieReviewSheet({
|
||||||
|
movieId: this.detail.id,
|
||||||
|
movieTitle: this.detail.title,
|
||||||
|
accent: this.accentColor(),
|
||||||
|
onClose: (): void => {
|
||||||
|
this.reviewsOpen = false;
|
||||||
|
},
|
||||||
|
onChanged: (): void => {
|
||||||
|
// 评分/条数可能变了,但详情接口不返回,不在这里强刷
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('92%')
|
.width('100%')
|
||||||
// ⚠️ 同样用 `Default`(不写)。`Block` 会挡住浮层内部的子节点
|
// ⚠️ 高度随内容自适应(浮层是"底部抽屉"形态)。
|
||||||
// (照片缩略图、关闭按钮都点不动)。
|
// 🔴 但**查看器打开时必须撑满**:查看器要盖住整屏,
|
||||||
// `Default` 已足够:浮层在遮罩之后声明 ⇒ 是兄弟节点、会被优先命中。
|
// 如果这里还是内容高度,查看器会被裁在一小块里,
|
||||||
|
// 而且**它没盖住的地方点击会穿透到外层** ——
|
||||||
// ---- 全屏大图查看器 ----
|
// 表现就是"点查看器的 ✕,结果把详情浮层也一起关了"
|
||||||
if (this.viewerOpen) {
|
// ( 2026-10-12 实测到的 bug)。
|
||||||
this.viewer()
|
.height(this.viewerOpen ? '100%' : undefined)
|
||||||
}
|
|
||||||
|
|
||||||
// ---- 影评 + 评论浮层(工单 #27)----
|
|
||||||
if (this.reviewsOpen && this.detail !== null) {
|
|
||||||
FbMovieReviewSheet({
|
|
||||||
movieId: this.detail.id,
|
|
||||||
movieTitle: this.detail.title,
|
|
||||||
accent: this.accentColor(),
|
|
||||||
onClose: (): void => {
|
|
||||||
this.reviewsOpen = false;
|
|
||||||
},
|
|
||||||
onChanged: (): void => {
|
|
||||||
// 评分/条数可能变了,但详情接口不返回,不在这里强刷
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
// ⚠️ 高度随内容自适应(浮层是"底部抽屉"形态)。
|
.height('100%')
|
||||||
// 🔴 但**查看器打开时必须撑满**:查看器要盖住整屏,
|
.justifyContent(FlexAlign.Center)
|
||||||
// 如果这里还是内容高度,查看器会被裁在一小块里,
|
.hitTestBehavior(HitTestMode.Transparent)
|
||||||
// 而且**它没盖住的地方点击会穿透到外层的遮罩** ——
|
|
||||||
// 表现就是"点查看器的 ✕,结果把详情浮层也一起关了"
|
|
||||||
// ( 2026-10-12 实测到的 bug)。
|
|
||||||
.height(this.viewerOpen ? '100%' : undefined)
|
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.justifyContent(FlexAlign.Center)
|
|
||||||
.hitTestBehavior(HitTestMode.Transparent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 浮层顶部:把手 + 关闭 */
|
/** 浮层顶部:把手 + 关闭 */
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
* 只是缺那几项详情专属字段,界面不会空。
|
* 只是缺那几项详情专属字段,界面不会空。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { FbColors, FbMetric, fbTint, FbTint, fbAlpha } from '../common/Theme';
|
import { FbColors, FbMetric, fbTint, FbTint, fbAlpha, FB_MASK } from '../common/Theme';
|
||||||
import { FbModuleDef, fbModuleOf, fbThemeVars } from '../model/Modules';
|
import { FbModuleDef, fbModuleOf, fbThemeVars } from '../model/Modules';
|
||||||
import { FbRosterPerson, FbJobRow, FbContactRow } from '../data/FbPersonRepo';
|
import { FbRosterPerson, FbJobRow, FbContactRow } from '../data/FbPersonRepo';
|
||||||
import { FbAvatar, FbTag } from './Widgets';
|
import { FbAvatar, FbTag } from './Widgets';
|
||||||
@@ -364,11 +364,27 @@ export struct FbPersonSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
// FB_WRAP_CENTER:把卡片**垂直居中**(用户 2026-10-16 要求:浮在屏幕中间)。
|
/* 🔴 用户 2026-11-06:「电影这个框弹出来的时候,应该在下面盖一层蒙版吧?
|
||||||
// ⚠️ 居中放在**组件内部**做,而不是改宿主的 Stack 对齐 ——
|
跟近期任务类似。」
|
||||||
// 宿主 Stack 里还有别的子元素(日程页的悬浮 +),改对齐会连带挪走它们。
|
⇒ 同一条要求同步到这里:首页「联系人」点开的这张卡原来也没有遮罩。
|
||||||
// ⚠️ 外层铺满 + Center;内层仍是那张 92% 宽的圆角卡。
|
|
||||||
Column() {
|
⚠️ 蒙版做在**组件内部**(谁铺满全屏谁负责画遮罩),宿主不再包一层:
|
||||||
|
包两层会越点越黑,而且外层遮罩会被组件自己的全屏根节点吃掉点击。
|
||||||
|
⚠️ `embedded` 时不画遮罩:那种情况宿主是 `bindSheet`,
|
||||||
|
系统已经给了自己的遮罩,再叠一层就是双暗。 */
|
||||||
|
Stack({ alignContent: Alignment.Center }) {
|
||||||
|
if (!this.embedded) {
|
||||||
|
Column()
|
||||||
|
.width('100%')
|
||||||
|
.height('100%')
|
||||||
|
.backgroundColor(FB_MASK)
|
||||||
|
.onClick((): void => {
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ↓↓↓ 以下为原来的根 Column(内容一字未改,只是套进了 Stack) ↓↓↓ */
|
||||||
|
Column() {
|
||||||
// ⚠️ 2026-10-19:**卡片外面那一圈主题色环**由共用组件 `FbSheetRing` 给
|
// ⚠️ 2026-10-19:**卡片外面那一圈主题色环**由共用组件 `FbSheetRing` 给
|
||||||
// (用户要求"所有弹框都加线,保持一致")。
|
// (用户要求"所有弹框都加线,保持一致")。
|
||||||
// 这一层只负责**尺寸**(92% 宽 / 72% 高上限)—— 尺寸与外观分开,
|
// 这一层只负责**尺寸**(92% 宽 / 72% 高上限)—— 尺寸与外观分开,
|
||||||
@@ -630,6 +646,9 @@ export struct FbPersonSheet {
|
|||||||
.width(this.embedded ? 'auto' : '100%')
|
.width(this.embedded ? 'auto' : '100%')
|
||||||
.height(this.embedded ? 'auto' : '100%')
|
.height(this.embedded ? 'auto' : '100%')
|
||||||
.justifyContent(this.embedded ? FlexAlign.Start : FlexAlign.Center)
|
.justifyContent(this.embedded ? FlexAlign.Start : FlexAlign.Center)
|
||||||
.hitTestBehavior(HitTestMode.Transparent)
|
.hitTestBehavior(HitTestMode.Transparent)
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.height('100%')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2125,7 +2125,14 @@ export struct FbHomePage {
|
|||||||
/* 🔴 用户:「"最近观影"点了之后没反应…点了之后应该有反应,
|
/* 🔴 用户:「"最近观影"点了之后没反应…点了之后应该有反应,
|
||||||
要么弹出来详细信息。」
|
要么弹出来详细信息。」
|
||||||
⚠️ 复用电影页的同一张卡(`FbMovieDetailSheet`),
|
⚠️ 复用电影页的同一张卡(`FbMovieDetailSheet`),
|
||||||
不为首页另写一套 —— 否则改一处要改两处。 */
|
不为首页另写一套 —— 否则改一处要改两处。
|
||||||
|
|
||||||
|
🔴 用户 2026-11-06:「电影这个框弹出来的时候,应该在下面盖一层蒙版吧?
|
||||||
|
跟近期任务类似。」
|
||||||
|
⇒ 蒙版由**组件自己**提供(`FbMovieDetailSheet` 内部根 Stack:
|
||||||
|
遮罩 + 卡片叠着),与 `FbTaskPanel` / `FbDayEditSheet` 同一做法。
|
||||||
|
**宿主这里不要再包一层** —— 包了就是两层暗色叠在一起(越点越黑),
|
||||||
|
而且点遮罩时会被组件自己的全屏根节点拦掉,关不掉。 */
|
||||||
if (this.mvDetail !== null || this.mvDetailLoading
|
if (this.mvDetail !== null || this.mvDetailLoading
|
||||||
|| this.mvDetailError !== '') {
|
|| this.mvDetailError !== '') {
|
||||||
FbMovieDetailSheet({
|
FbMovieDetailSheet({
|
||||||
@@ -2145,7 +2152,10 @@ export struct FbHomePage {
|
|||||||
// ==================== #64:联系人详情(可打电话)====================
|
// ==================== #64:联系人详情(可打电话)====================
|
||||||
/* 🔴 用户:「点击之后弹出来详细信息,就跟名册里面那个人的列表
|
/* 🔴 用户:「点击之后弹出来详细信息,就跟名册里面那个人的列表
|
||||||
点击完之后的效果是一样的,这样可以直接打电话。」
|
点击完之后的效果是一样的,这样可以直接打电话。」
|
||||||
⚠️ 复用名册那张卡(`FbPersonSheet`),它自带手机号拨号入口。 */
|
⚠️ 复用名册那张卡(`FbPersonSheet`),它自带手机号拨号入口。
|
||||||
|
|
||||||
|
🔴 2026-11-06 同一条:蒙版同样由组件自己提供(`FbPersonSheet` 内部根
|
||||||
|
Stack:遮罩 + 卡片)。宿主不包 —— 理由同上一段。 */
|
||||||
if (this.pfDetail !== null) {
|
if (this.pfDetail !== null) {
|
||||||
FbPersonSheet({
|
FbPersonSheet({
|
||||||
person: this.pfDetail,
|
person: this.pfDetail,
|
||||||
|
|||||||
Reference in New Issue
Block a user