import 'package:patbond_flutter/core/network/api_exception.dart'; import 'package:patbond_flutter/features/community/community_models.dart'; /// 降级作者([AuthorSummary.isDegraded],资料暂不可得或已注销)的 /// 统一占位名(05 号规范:占位头像 + 默认名,客户端不做昵称回退拼装)。 const degradedAuthorName = '宠友'; /// 作者展示名:正常路径 nickname 恒非空(服务端已回退 username); /// 降级形态统一 [degradedAuthorName]。 String authorDisplayName(AuthorSummary author) => author.nickname ?? degradedAuthorName; /// Feed 卡片元信息的相对时间(正典「2 小时前」语言)。 /// [now] 注入口供测试锁定时钟。 String feedRelativeTime(DateTime time, {DateTime? now}) { final reference = now ?? DateTime.now(); final difference = reference.difference(time.toLocal()); if (difference.inMinutes < 1) return '刚刚'; if (difference.inHours < 1) return '${difference.inMinutes} 分钟前'; if (difference.inDays < 1) return '${difference.inHours} 小时前'; if (difference.inDays < 7) return '${difference.inDays} 天前'; final local = time.toLocal(); if (local.year == reference.year) return '${local.month}月${local.day}日'; return '${local.year}年${local.month}月${local.day}日'; } /// Feed 加载失败的用户话术(pets 域 petLoadErrorMessage 同构; /// 服务端原始 message 不上屏)。 String feedLoadErrorMessage(ApiException? error) => switch (error) { ApiNetworkException _ => '网络异常,请检查网络后重试', ApiRateLimitException _ => '请求过于频繁,请稍后再试', _ => '动态加载失败,请稍后重试', };