新增:首页 Feed 接入真实数据——四态/尾部三态/聚合曝光埋点,社区 demo 消亡第一页(T3-14)
CI / flutter-gates (push) Successful in 2m41s
CI / flutter-gates (push) Successful in 2m41s
- home_page Feed segment 改接 CommunityController:骨架屏首载、空态 CTA、 错误横幅重试、下拉刷新(失败保留旧列表 + SnackBar)、触底游标翻页 (失败态只走显式重试,不随滚动风暴自动重打) - PostCard 三形态(单图通栏 4:3 / 多图折叠封面 +N 角标 / 纯文字 6 行)+ PostMediaGrid(列数规则 + ink 80% scrim 精算)+ LikeButton(error 族修订 Colors.red,T3-14 纯展示禁用态,ToggleSync 接线留 T3-15/16)+ FeedSkeleton (呼吸动效尊重减弱动态设置);降级作者统一「宠友」占位 - SignedNetworkImage:预签名 URL 缓存 key 剥离 X-Amz-* 签名参数, RemoteImage 全仓换用(同图不同签名命中同一缓存条目) - feed 域埋点:feed_viewed 聚合曝光(浏览段开/结算于切 Tab、切分段、 退后台、销毁;≥50% 可见 ≥500ms 段内按帖去重,postId 不上报)+ feed_load_failed(refresh/load_more 双路,会话失效不报) - integration_test/feed_live_test.dart:compose 六容器 Linux 桌面真链路 实测入口(PATBOND_FEED_LIVE=1 门控,默认跳过) - 测试 379 → 421(+42):四态/尾部三态/翻页不丢不重/降级作者/曝光结算 时机/缓存 key/事件属性全覆盖;analyze 0,format 无 diff Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patbond_flutter/core/theme/app_theme.dart';
|
||||
|
||||
/// 点赞 / 收藏按钮语义变体(05 号规范 §3.5:同一组件,图标与语义色
|
||||
/// 参数化)。点赞激活 = `error` 图标 + `errorDark` 计数(demo 的
|
||||
/// `Colors.red` 3.13:1 修订弃用,D6);收藏激活 = `accentDark` 同色。
|
||||
enum LikeButtonVariant {
|
||||
like(
|
||||
inactiveIcon: Icons.favorite_border,
|
||||
activeIcon: Icons.favorite,
|
||||
activeIconColor: AppColors.error,
|
||||
activeCountColor: AppColors.errorDark,
|
||||
),
|
||||
bookmark(
|
||||
inactiveIcon: Icons.bookmark_border,
|
||||
activeIcon: Icons.bookmark,
|
||||
activeIconColor: AppColors.accentDark,
|
||||
activeCountColor: AppColors.accentDark,
|
||||
);
|
||||
|
||||
const LikeButtonVariant({
|
||||
required this.inactiveIcon,
|
||||
required this.activeIcon,
|
||||
required this.activeIconColor,
|
||||
required this.activeCountColor,
|
||||
});
|
||||
|
||||
final IconData inactiveIcon;
|
||||
final IconData activeIcon;
|
||||
final Color activeIconColor;
|
||||
final Color activeCountColor;
|
||||
}
|
||||
|
||||
/// 点赞/收藏交互钮(05 号规范 §3.5 静态规格):图标 20 + 计数 13/w600,
|
||||
/// 未激活一律 `inkSoft`(6.59:1)。触控 44×44 由 padding 撑足。
|
||||
///
|
||||
/// T3-14 只做展示([onPressed] 传 null 即禁用态,仍按正常色渲染计数与
|
||||
/// 状态);乐观更新动画与 ToggleSync 接线属 T3-15/16。
|
||||
class LikeButton extends StatelessWidget {
|
||||
const LikeButton({
|
||||
required this.variant,
|
||||
required this.active,
|
||||
required this.count,
|
||||
super.key,
|
||||
this.onPressed,
|
||||
this.semanticLabel,
|
||||
});
|
||||
|
||||
final LikeButtonVariant variant;
|
||||
final bool active;
|
||||
final int count;
|
||||
final VoidCallback? onPressed;
|
||||
final String? semanticLabel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final iconColor = active ? variant.activeIconColor : AppColors.inkSoft;
|
||||
final countColor = active ? variant.activeCountColor : AppColors.inkSoft;
|
||||
return Semantics(
|
||||
label: semanticLabel,
|
||||
button: onPressed != null,
|
||||
child: InkWell(
|
||||
onTap: onPressed,
|
||||
borderRadius: BorderRadius.circular(AppRadius.pill),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 44, minHeight: 44),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
active ? variant.activeIcon : variant.inactiveIcon,
|
||||
size: 20,
|
||||
color: iconColor,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'$count',
|
||||
style: TextStyle(
|
||||
color: countColor,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user