From b494ba1abdb40e6e65443a38ee4bc9cfdfe5a782 Mon Sep 17 00:00:00 2001 From: Kiro Agent <244629292+kiro-agent@users.noreply.github.com> Date: Sun, 31 May 2026 03:35:07 +0000 Subject: [PATCH] Force-translate dynamic content to English in remaining display sites The previous force-English wiring covered grids, info-page title, history, timeline cards, and the info-page summary. This patch extends it to every remaining place where Bangumi or plugin-API data was still rendered in its source language (Chinese/Japanese): - Anime alias bottom sheet (the screen the user reported) - Character cards, character full page (name, nameCN, info, summary) - Staff cards (name, nameCN, position cn label) - Plain-text user comment body - Tag chips on the info page - Download manager: anime title and episode names - Download episode picker: episode identifier - Episode-comments sheet: episode title in header and selection list - Image-search result anime title - Video page: collection title in toolbar, episode identifier in road list - Watch-history card: last-watch episode name - Plugin search results in source sheet (anime title returned by plugin) The underlying data (used as plugin search keywords / storage identifiers / URL routing) is never mutated - translation happens only at display time via TranslatedText, falling back to the original on cache miss or network error. Co-authored-by: DeadEnd Dev <283450271+Deadendev@users.noreply.github.com> --- lib/bean/card/bangumi_history_card.dart | 2 +- lib/bean/card/character_card.dart | 7 ++++--- lib/bean/card/comments_card.dart | 3 ++- lib/bean/card/staff_card.dart | 7 ++++--- lib/pages/download/download_episode_sheet.dart | 3 ++- lib/pages/download/download_page.dart | 5 +++-- lib/pages/info/character_page.dart | 9 +++++---- lib/pages/info/info_tabview.dart | 3 ++- lib/pages/info/source_sheet.dart | 5 +++-- lib/pages/player/episode_comments_sheet.dart | 7 ++++--- lib/pages/search/image_search_page.dart | 3 ++- lib/pages/video/video_page.dart | 5 +++-- 12 files changed, 35 insertions(+), 24 deletions(-) diff --git a/lib/bean/card/bangumi_history_card.dart b/lib/bean/card/bangumi_history_card.dart index 7c2c84d97..f7107379a 100644 --- a/lib/bean/card/bangumi_history_card.dart +++ b/lib/bean/card/bangumi_history_card.dart @@ -161,7 +161,7 @@ class _BangumiHistoryCardVState extends State { ), const SizedBox(width: 4), Flexible( - child: Text( + child: TranslatedText( episodeText, style: theme.textTheme.bodySmall?.copyWith( color: colorScheme.onSurfaceVariant, diff --git a/lib/bean/card/character_card.dart b/lib/bean/card/character_card.dart index 396037eaf..e3ae91875 100644 --- a/lib/bean/card/character_card.dart +++ b/lib/bean/card/character_card.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/characters/character_item.dart'; import 'package:kazumi/pages/info/character_page.dart'; import 'package:kazumi/utils/device.dart'; @@ -19,15 +20,15 @@ class CharacterCard extends StatelessWidget { ? NetworkImage('https://bangumi.tv/img/info_only.png') : NetworkImage(characterItem.avator.grid), ), - title: Text( + title: TranslatedText( characterItem.name, overflow: TextOverflow.ellipsis, maxLines: 1, ), subtitle: characterItem.actorList.isNotEmpty - ? Text(characterItem.actorList[0].name) + ? TranslatedText(characterItem.actorList[0].name) : null, - trailing: Text(characterItem.relation), + trailing: TranslatedText(characterItem.relation), onTap: () { showModalBottomSheet( isScrollControlled: true, diff --git a/lib/bean/card/comments_card.dart b/lib/bean/card/comments_card.dart index c628d4e25..e6216408d 100644 --- a/lib/bean/card/comments_card.dart +++ b/lib/bean/card/comments_card.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/comments/comment_item.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:skeletonizer/skeletonizer.dart'; @@ -110,7 +111,7 @@ class CommentsCard extends StatelessWidget { ], ), const SizedBox(height: 8), - Text(commentItem!.comment.comment), + TranslatedText(commentItem!.comment.comment), ], ), ), diff --git a/lib/bean/card/staff_card.dart b/lib/bean/card/staff_card.dart index 00ff1725e..9a49c4430 100644 --- a/lib/bean/card/staff_card.dart +++ b/lib/bean/card/staff_card.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/staff/staff_item.dart'; class StaffCard extends StatelessWidget { @@ -17,15 +18,15 @@ class StaffCard extends StatelessWidget { ? NetworkImage('https://bangumi.tv/img/info_only.png') : NetworkImage(staffFullItem.staff.images!.grid), ), - title: Text( + title: TranslatedText( staffFullItem.staff.name, overflow: TextOverflow.ellipsis, maxLines: 1, ), subtitle: staffFullItem.staff.nameCN.isNotEmpty - ? Text(staffFullItem.staff.nameCN) + ? TranslatedText(staffFullItem.staff.nameCN) : null, - trailing: Text(staffFullItem.positions.isNotEmpty + trailing: TranslatedText(staffFullItem.positions.isNotEmpty ? (staffFullItem.positions[0].type.cn) : ''), ); diff --git a/lib/pages/download/download_episode_sheet.dart b/lib/pages/download/download_episode_sheet.dart index 5ea131986..194bac710 100644 --- a/lib/pages/download/download_episode_sheet.dart +++ b/lib/pages/download/download_episode_sheet.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'package:kazumi/bean/dialog/dialog_helper.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/download/download_module.dart'; import 'package:kazumi/modules/roads/road_module.dart'; import 'package:kazumi/pages/download/download_controller.dart'; @@ -152,7 +153,7 @@ class _DownloadEpisodeSheetState extends State { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8), - child: Text( + child: TranslatedText( identifier, maxLines: 2, overflow: TextOverflow.ellipsis, diff --git a/lib/pages/download/download_page.dart b/lib/pages/download/download_page.dart index 4680be401..be3528143 100644 --- a/lib/pages/download/download_page.dart +++ b/lib/pages/download/download_page.dart @@ -3,6 +3,7 @@ import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'package:kazumi/bean/appbar/sys_app_bar.dart'; import 'package:kazumi/bean/dialog/dialog_helper.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/download/download_module.dart'; import 'package:kazumi/modules/bangumi/bangumi_item.dart'; import 'package:kazumi/pages/download/download_controller.dart'; @@ -101,7 +102,7 @@ class _DownloadPageState extends State { ), ), ), - title: Text( + title: TranslatedText( record.bangumiName, maxLines: 1, overflow: TextOverflow.ellipsis, @@ -158,7 +159,7 @@ class _DownloadPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( + TranslatedText( episode.episodeName.isNotEmpty ? episode.episodeName : 'Ep ${episode.episodeNumber}', diff --git a/lib/pages/info/character_page.dart b/lib/pages/info/character_page.dart index 939df0263..c6367ce66 100644 --- a/lib/pages/info/character_page.dart +++ b/lib/pages/info/character_page.dart @@ -1,5 +1,6 @@ import 'dart:ui'; import 'package:flutter/material.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/character/character_full_item.dart'; import 'package:kazumi/modules/comments/comment_item.dart'; import 'package:kazumi/request/apis/bangumi_api.dart'; @@ -153,7 +154,7 @@ class _CharacterPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( + TranslatedText( characterFullItem.name, style: Theme.of(context) .textTheme @@ -170,7 +171,7 @@ class _CharacterPageState extends State { Padding( padding: const EdgeInsets.only( top: 4.0, bottom: 12.0), - child: Text( + child: TranslatedText( characterFullItem.nameCN, style: Theme.of(context) .textTheme @@ -194,7 +195,7 @@ class _CharacterPageState extends State { ), ), ), - Text( + TranslatedText( characterFullItem.info, style: Theme.of(context) .textTheme @@ -215,7 +216,7 @@ class _CharacterPageState extends State { ), ), ), - Text( + TranslatedText( characterFullItem.summary, style: Theme.of(context) .textTheme diff --git a/lib/pages/info/info_tabview.dart b/lib/pages/info/info_tabview.dart index 0f9c94c07..a003fae2e 100644 --- a/lib/pages/info/info_tabview.dart +++ b/lib/pages/info/info_tabview.dart @@ -12,6 +12,7 @@ import 'package:kazumi/modules/characters/character_item.dart'; import 'package:kazumi/modules/staff/staff_item.dart'; import 'package:kazumi/utils/device.dart'; import 'package:kazumi/services/translation/translation_service.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; class InfoTabView extends StatefulWidget { const InfoTabView({ @@ -192,7 +193,7 @@ class _InfoTabViewState extends State label: Row( mainAxisSize: MainAxisSize.min, children: [ - Text('${widget.bangumiItem.tags[index].name} '), + TranslatedText('${widget.bangumiItem.tags[index].name} '), Text( '${widget.bangumiItem.tags[index].count}', style: TextStyle( diff --git a/lib/pages/info/source_sheet.dart b/lib/pages/info/source_sheet.dart index 77dbfae19..8f579df24 100644 --- a/lib/pages/info/source_sheet.dart +++ b/lib/pages/info/source_sheet.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_modular/flutter_modular.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/pages/info/info_controller.dart'; import 'package:kazumi/services/logging/logger.dart'; import 'package:kazumi/bean/dialog/dialog_helper.dart'; @@ -591,7 +592,7 @@ class _SourceSheetState extends State }, child: Padding( padding: const EdgeInsets.all(20), - child: Text(searchItem.name), + child: TranslatedText(searchItem.name), ), ), ), @@ -814,7 +815,7 @@ class _AliasDialogState extends State<_AliasDialog> { final index = entry.key; final alias = entry.value; return ListTile( - title: Text(alias), + title: TranslatedText(alias), trailing: IconButton( onPressed: () { KazumiDialog.show( diff --git a/lib/pages/player/episode_comments_sheet.dart b/lib/pages/player/episode_comments_sheet.dart index 24221e651..21a01abb2 100644 --- a/lib/pages/player/episode_comments_sheet.dart +++ b/lib/pages/player/episode_comments_sheet.dart @@ -5,6 +5,7 @@ import 'package:flutter_modular/flutter_modular.dart'; import 'package:kazumi/bean/dialog/dialog_helper.dart'; import 'package:kazumi/bean/card/episode_comments_card.dart'; import 'package:kazumi/bean/widget/error_widget.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/bangumi/episode_item.dart'; import 'package:kazumi/pages/video/video_controller.dart'; import 'package:kazumi/request/apis/bangumi_api.dart'; @@ -159,13 +160,13 @@ class _EpisodeCommentsSheetState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( + TranslatedText( '${videoPageController.episodeInfo.readType()}.${videoPageController.episodeInfo.episode} ${videoPageController.episodeInfo.name}', overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12, color: Theme.of(context).colorScheme.outline)), - Text( + TranslatedText( (videoPageController.episodeInfo.nameCn != '') ? '${videoPageController.episodeInfo.readType()}.${videoPageController.episodeInfo.episode} ${videoPageController.episodeInfo.nameCn}' : '${videoPageController.episodeInfo.readType()}.${videoPageController.episodeInfo.episode} ${videoPageController.episodeInfo.name}', @@ -256,7 +257,7 @@ class _EpisodeCommentsSheetState extends State { final bool selected = index + 1 == selectedEpisode; return ListTile( selected: selected, - title: Text( + title: TranslatedText( episodeTitle.isEmpty ? episodeText : '$episodeText $episodeTitle', diff --git a/lib/pages/search/image_search_page.dart b/lib/pages/search/image_search_page.dart index dd0659ce7..d034c2adf 100644 --- a/lib/pages/search/image_search_page.dart +++ b/lib/pages/search/image_search_page.dart @@ -7,6 +7,7 @@ import 'package:image_picker/image_picker.dart'; import 'package:kazumi/bean/appbar/sys_app_bar.dart'; import 'package:kazumi/bean/card/network_img_layer.dart'; import 'package:kazumi/bean/dialog/dialog_helper.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/modules/search/image_search_module.dart'; import 'package:kazumi/pages/search/search_controller.dart'; import 'package:kazumi/utils/constants.dart'; @@ -638,7 +639,7 @@ class _ImageSearchPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( + TranslatedText( _formatTraceResultTitle(result), maxLines: 1, overflow: TextOverflow.ellipsis, diff --git a/lib/pages/video/video_page.dart b/lib/pages/video/video_page.dart index 112593252..144b44c71 100644 --- a/lib/pages/video/video_page.dart +++ b/lib/pages/video/video_page.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:canvas_danmaku/models/danmaku_content_item.dart'; import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; +import 'package:kazumi/bean/widget/translated_text.dart'; import 'package:kazumi/pages/player/player_controller.dart'; import 'package:kazumi/pages/video/video_controller.dart'; import 'package:kazumi/pages/history/history_controller.dart'; @@ -905,7 +906,7 @@ class _VideoPageState extends State children: [ const Text(' Collection '), Expanded( - child: Text( + child: TranslatedText( videoPageController.title, overflow: TextOverflow.ellipsis, style: TextStyle( @@ -1075,7 +1076,7 @@ class _VideoPageState extends State const SizedBox(width: 6) ], Expanded( - child: Text( + child: TranslatedText( road.identifier[count0 - 1], maxLines: 2, overflow: TextOverflow.ellipsis,