feat(app): 海报弹层内中/English 切换——二维码海报支持英文版
- 弹层顶部 SegmentTabs(light) 两档,默认跟 App 语言前缀;只影响海报内容 与二维码 ?lang=,不动 App 语言设置 - 提示文案经 lookupAppLocalizations 按海报语言取(arb 中英双全,零硬编码) - 标题/场地/地址复用相册多语言回退链按海报语言取 - QrImageView 补 semanticsLabel(读屏原本无名,兼作测试断言口) Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import '../features/albums/album_format.dart';
|
||||
import '../features/albums/models.dart';
|
||||
import '../l10n/app_localizations.dart';
|
||||
import '../ui/components/photo_thumbnail.dart';
|
||||
import '../ui/components/segment_tabs.dart';
|
||||
import '../ui/tokens.dart';
|
||||
|
||||
/// 外链打开注入点(生产=url_launcher;测试 override)。
|
||||
@@ -325,6 +326,9 @@ class ShareQrPage extends ConsumerWidget {
|
||||
|
||||
/// 二维码海报弹层:宣传图(banner→cover 兜底)+ 标题 + 时间 + 地址 + 二维码;
|
||||
/// 「保存海报图」= RepaintBoundary 3x 渲染 PNG → 相册(gal)。
|
||||
///
|
||||
/// 弹层内「中文/English」切换海报语言(默认跟 App 语言):内容文案/相册
|
||||
/// 字段/二维码 `?lang=` 随切换,App 语言设置与弹层 chrome 不受影响。
|
||||
class _PosterSheet extends ConsumerStatefulWidget {
|
||||
const _PosterSheet({required this.album});
|
||||
|
||||
@@ -339,6 +343,12 @@ class _PosterSheetState extends ConsumerState<_PosterSheet> {
|
||||
String? _bannerUrl;
|
||||
bool _saving = false;
|
||||
|
||||
/// 海报语言('zh'|'en';打开时刻快照 App 语言前缀,切换只影响海报)。
|
||||
late String _posterLang =
|
||||
AppLocalizations.of(context).localeName.toLowerCase().startsWith('zh')
|
||||
? 'zh'
|
||||
: 'en';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -377,9 +387,10 @@ class _PosterSheetState extends ConsumerState<_PosterSheet> {
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final theme = Theme.of(context);
|
||||
final localeName = l10n.localeName;
|
||||
final url = shareAlbumUrl(widget.album, localeName);
|
||||
final title = albumDisplayTitle(widget.album, localeName);
|
||||
// 海报内容按海报语言渲染(弹层 chrome 仍跟 App 语言)。
|
||||
final posterL10n = lookupAppLocalizations(Locale(_posterLang));
|
||||
final url = shareAlbumUrl(widget.album, _posterLang);
|
||||
final title = albumDisplayTitle(widget.album, _posterLang);
|
||||
// 海报日期:日期粒度(UI06 选择器已去时间;展示同口径)。
|
||||
String posterDate(DateTime utc) {
|
||||
final wall = tryToAlbumZone(utc, widget.album.timezone) ?? utc.toUtc();
|
||||
@@ -391,9 +402,9 @@ class _PosterSheetState extends ConsumerState<_PosterSheet> {
|
||||
? null
|
||||
: posterDate(widget.album.endAt!);
|
||||
final dateRange = end == null ? start : '$start ~ $end';
|
||||
final venue = albumDisplayVenue(widget.album, localeName);
|
||||
final venue = albumDisplayVenue(widget.album, _posterLang);
|
||||
String? addressForPoster(AlbumSummary album) {
|
||||
for (final t in albumDisplayTranslations(album, localeName)) {
|
||||
for (final t in albumDisplayTranslations(album, _posterLang)) {
|
||||
final a = t.address?.trim();
|
||||
if (a != null && a.isNotEmpty) return a;
|
||||
}
|
||||
@@ -426,6 +437,18 @@ class _PosterSheetState extends ConsumerState<_PosterSheet> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: kSpace8),
|
||||
// ── 海报语言切换:内容/二维码随之,App 语言不动 ──
|
||||
SegmentTabs<String>(
|
||||
value: _posterLang,
|
||||
onChanged: (lang) => setState(() => _posterLang = lang),
|
||||
style: SegmentTabsStyle.light,
|
||||
segments: [
|
||||
('zh', l10n.localeChinese),
|
||||
('en', l10n.localeEnglish),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: kSpace12),
|
||||
// ── 海报(整块 RepaintBoundary;下载即渲染此区域)──
|
||||
RepaintBoundary(
|
||||
key: _posterKey,
|
||||
@@ -520,12 +543,13 @@ class _PosterSheetState extends ConsumerState<_PosterSheet> {
|
||||
version: QrVersions.auto,
|
||||
size: 200,
|
||||
backgroundColor: Colors.white,
|
||||
semanticsLabel: url,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: kSpace12),
|
||||
Center(
|
||||
child: Text(
|
||||
l10n.shareScanHint,
|
||||
posterL10n.shareScanHint,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: const Color(0xFF69778E),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user