Conversation
Review Summary by QodoMigrate to Flutter native localization system
WalkthroughsDescription• Comprehensive migration from easy_localization package to Flutter's native localization system • Replaced all tr() and plural() function calls with AppLocalizations.of(context)! method-based access across the entire codebase • Updated main.dart to use Flutter's native localizationsDelegates and removed EasyLocalization widget wrapper • Generated localization files for 30+ language variants including English, Chinese, Portuguese, and many others • Updated all app pages (apps.dart, settings.dart, add_app.dart, app.dart, import_export.dart, etc.) to use new localization pattern • Migrated all app sources (GitHub, GitLab, Telegram, Tencent, APKMirror, etc.) to native Flutter localization • Updated components and providers to use AppLocalizations instead of easy_localization • Improved accessibility by adding Semantics widgets to install/update buttons • Added grid/list view toggle button in the toolbar Diagramflowchart LR
A["easy_localization<br/>package"] -->|"Replace with"| B["Flutter native<br/>AppLocalizations"]
C["tr() calls"] -->|"Convert to"| D["AppLocalizations.of<br/>context methods"]
E["EasyLocalization<br/>widget"] -->|"Replace with"| F["localizationsDelegates<br/>& supportedLocales"]
G["30+ language<br/>ARB files"] -->|"Generate"| H["Generated localization<br/>Dart files"]
B --> I["Updated pages<br/>& components"]
D --> I
F --> I
H --> I
File Changes1. lib/generated/app_localizations_zh.dart
|
Code Review by Qodo
1. deleteFile() uses undefined context
|
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request overhauls the application's internationalization infrastructure by transitioning to Flutter's built-in localization capabilities. This change streamlines the process of managing and integrating translated content, laying the groundwork for more robust and maintainable multilingual support. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request successfully migrates the project to Flutter's built-in localization, which is a great improvement. The changes involve updating numerous files to use AppLocalizations and adding a conversion script. However, there are a few critical issues to address. Several debug and conflict-related files have been accidentally included and should be removed. The new Python conversion script contains hardcoded paths, making it non-portable. Most importantly, there's an unsafe use of globalNavigatorKey.currentContext for localization within error classes, which could lead to runtime crashes, especially in background tasks. Addressing these points will ensure the stability and maintainability of the new localization system.
| RateLimitError(this.remainingMinutes) | ||
| : super(plural('tooManyRequestsTryAgainInMinutes', remainingMinutes)); | ||
| : super( | ||
| AppLocalizations.of(globalNavigatorKey.currentContext!)! | ||
| .tooManyRequestsTryAgainInMinutes(remainingMinutes), | ||
| ); |
There was a problem hiding this comment.
Using globalNavigatorKey.currentContext! in error constructors is unsafe and will cause a crash when an error is created from a background process (like an update check) that has no BuildContext.
To fix this, localization should happen when the error is displayed, not when it's created. I suggest refactoring UpdatiumError and its subclasses to format the message when it's needed, using a valid BuildContext.
For example, you could add a method to UpdatiumError:
// In UpdatiumError
class UpdatiumError {
// ...
String getMessage(BuildContext context) => message;
}
// In RateLimitError
class RateLimitError extends UpdatiumError {
final int remainingMinutes;
RateLimitError(this.remainingMinutes) : super('');
@override
String getMessage(BuildContext context) {
return AppLocalizations.of(context)!.tooManyRequestsTryAgainInMinutes(remainingMinutes);
}
}Then showMessage would use error.getMessage(context) to display the localized text safely.
conflict_debug.txt
Outdated
| <<<<<<< HEAD | ||
| action = Semantics( | ||
| button: true, | ||
| label: AppLocalizations.of(context)!.install, | ||
| hint: appsProvider.areDownloadsRunning() |
There was a problem hiding this comment.
This file appears to be a merge conflict artifact. It, along with find_flutter.txt, flutter_path.txt, gen_output.txt, and home_list.txt, seems to be a temporary or debug file that was accidentally committed. These files should be removed from the pull request and added to .gitignore to prevent them from being committed in the future.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
There was a problem hiding this comment.
🚫 CI Build Failed
The automated build process failed. Please review the build logs and fix the issues before requesting another review.
Next steps:
- Check the build logs for specific errors
- Fix the identified issues
- Push your fixes to this branch
- The CI will automatically re-run
Once the build passes, this review will be dismissed automatically.
| throw UpdatiumError( | ||
| tr('fileDeletionError', args: [e.path ?? tr('unknown')]), | ||
| "fileDeletionError"(e.path ?? AppLocalizations.of(context)!\.unknown), | ||
| ); |
There was a problem hiding this comment.
1. deletefile() uses undefined context 📘 Rule violation ⛯ Reliability
deleteFile() constructs an UpdatiumError using AppLocalizations.of(context) even though no context exists in scope, and also calls a string literal like a function. This breaks error handling at a file-deletion failure point and can crash/stop compilation instead of gracefully reporting the failure.
Agent Prompt
## Issue description
`deleteFile()` currently throws an `UpdatiumError` using an undefined `context` and an invalid localization call (`"fileDeletionError"(...)`). This breaks the error-handling path and can prevent graceful degradation on file-deletion failures.
## Issue Context
This code runs when file deletion fails (`PathAccessException`). Per compliance requirements, failure points must be handled reliably and provide meaningful context.
## Fix Focus Areas
- lib/providers/apps_provider.dart[300-307]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| class RateLimitError extends UpdatiumError { | ||
| late int remainingMinutes; | ||
| RateLimitError(this.remainingMinutes) | ||
| : super(plural('tooManyRequestsTryAgainInMinutes', remainingMinutes)); | ||
| : super( | ||
| AppLocalizations.of(globalNavigatorKey.currentContext!)! | ||
| .tooManyRequestsTryAgainInMinutes(remainingMinutes), | ||
| ); |
There was a problem hiding this comment.
2. Null-assert on currentcontext! 📘 Rule violation ⛯ Reliability
Multiple error constructors localize messages via globalNavigatorKey.currentContext!, which can be null (e.g., early startup/background flows). This can cause a crash while building an error message, preventing graceful handling of the original failure.
Agent Prompt
## Issue description
Error constructors are using `globalNavigatorKey.currentContext!` for localization. If `currentContext` is null, constructing the error will crash, defeating robust error handling.
## Issue Context
Errors may be created outside of an active widget tree (startup/background). Localization should be performed with a guaranteed-safe context or provided `AppLocalizations` instance.
## Fix Focus Areas
- lib/custom_errors.dart[24-113]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| void resetLocaleSafe(BuildContext context) { | ||
| if (context.supportedLocales.contains(context.deviceLocale)) { | ||
| context.resetLocale(); | ||
| } else { | ||
| context.setLocale(context.fallbackLocale!); | ||
| context.deleteSaveLocale(); | ||
| } | ||
| // TODO: Implement proper locale reset logic with Flutter's official localization | ||
| debugPrint('Locale reset requested - not implemented yet'); | ||
| } |
There was a problem hiding this comment.
3. resetlocalesafe() left unimplemented 📘 Rule violation ⛯ Reliability
resetLocaleSafe() was changed to a TODO with only a debugPrint, so the locale-reset edge case is no longer handled. This can leave the app in an inconsistent locale state instead of gracefully recovering.
Agent Prompt
## Issue description
`resetLocaleSafe()` no longer handles locale mismatch/reset scenarios and only prints a TODO message.
## Issue Context
Locale mismatch is an edge case that should be handled deterministically by resetting to a supported locale or clearing the forced locale.
## Fix Focus Areas
- lib/providers/settings_provider.dart[385-388]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| content: GestureDetector( | ||
| onLongPress: () { | ||
| Clipboard.setData(ClipboardData(text: e.toString())); | ||
| ScaffoldMessenger.of( | ||
| context, | ||
| ).showSnackBar(SnackBar(content: Text(tr('copiedToClipboard')))); | ||
| ).showSnackBar(SnackBar(content: Text(AppLocalizations.of(context)!\.copiedToClipboard))); | ||
| }, |
There was a problem hiding this comment.
4. Localization syntax breaks build 🐞 Bug ✓ Correctness
Several migrated call sites contain invalid Dart syntax (e.g., AppLocalizations.of(context)!\.x and string-literal function calls like "importX"(name)), which will prevent the app from compiling.
Agent Prompt
### Issue description
The localization migration introduced invalid Dart syntax at multiple call sites (`AppLocalizations.of(context)!\.` and `"key"(args)`), which breaks compilation.
### Issue Context
`AppLocalizations.of(context)` is generated as non-nullable and should be used as `AppLocalizations.of(context).someKey` or `AppLocalizations.of(context).someMethod(arg)`.
### Fix Focus Areas
- lib/custom_errors.dart[160-210]
- lib/pages/import_export.dart[193-205]
- lib/pages/settings.dart[132-145]
- lib/components/generated_form_modal.dart[70-96]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| localizationsDelegates: const [ | ||
| AppLocalizations.delegate, | ||
| GlobalMaterialLocalizations.delegate, | ||
| GlobalWidgetsLocalizations.delegate, | ||
| GlobalCupertinoLocalizations.delegate, | ||
| ], | ||
| supportedLocales: const [ | ||
| Locale('en'), | ||
| Locale('zh'), | ||
| Locale('zh', 'Hant_TW'), | ||
| Locale('it'), | ||
| Locale('ja'), | ||
| Locale('he'), | ||
| Locale('hu'), | ||
| Locale('de'), | ||
| Locale('fa'), | ||
| Locale('fr'), | ||
| Locale('es'), | ||
| Locale('pl'), | ||
| Locale('ru'), | ||
| Locale('bs'), | ||
| Locale('pt'), | ||
| Locale('pt', 'BR'), | ||
| Locale('cs'), | ||
| Locale('sv'), | ||
| Locale('nl'), | ||
| Locale('vi'), | ||
| Locale('tr'), | ||
| Locale('uk'), | ||
| Locale('da'), | ||
| Locale('et'), | ||
| Locale('en', 'EO'), | ||
| Locale('in'), | ||
| Locale('ko'), | ||
| Locale('ca'), | ||
| Locale('ar'), | ||
| Locale('ml'), | ||
| Locale('gl'), | ||
| ], | ||
| locale: settingsProvider.forcedLocale, |
There was a problem hiding this comment.
5. Incorrect locale list 🐞 Bug ✓ Correctness
MaterialApp.supportedLocales is hardcoded with invalid/mismatching locale definitions (e.g.,
Locale('in'), Locale('zh','Hant_TW')), diverging from the generated
AppLocalizations.supportedLocales and breaking locale matching/selection for affected languages.
Agent Prompt
### Issue description
Hardcoded locales in `MaterialApp` don't match the generated localization configuration (incorrect Indonesian and Traditional Chinese locale definitions).
### Issue Context
Flutter gen_l10n already generates `AppLocalizations.supportedLocales` and `AppLocalizations.localizationsDelegates`.
### Fix Focus Areas
- lib/main.dart[804-846]
- lib/providers/settings_provider.dart[291-376]
- lib/generated/app_localizations.dart[112-150]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
/improve |
PR Code Suggestions ✨Latest suggestions up to 1b117c4
Previous suggestionsSuggestions up to commit 0a1a589
Suggestions up to commit 6d42656
✅ Suggestions up to commit 7c0b7b1
✅ Suggestions up to commit ecc1340
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
|
Persistent suggestions updated to latest commit 0a1a589 |
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
|
Persistent suggestions updated to latest commit 1b117c4 |
Co-authored-by: qodo-free-for-open-source-projects[bot] <189517486+qodo-free-for-open-source-projects[bot]@users.noreply.github.com>
|
Related: #255 |
PR Type
Enhancement
Description
Comprehensive migration from
easy_localizationpackage to Flutter's native localization systemReplaced all
tr()andplural()function calls withAppLocalizations.of(context)!method invocations across the entire codebaseUpdated
main.dartto use Flutter's nativeAppLocalizations.delegateand removedEasyLocalizationwrapperGenerated complete localization files for multiple languages (English, Chinese, Portuguese, and 20+ additional languages)
Updated all app pages (
apps.dart,settings.dart,add_app.dart,app.dart,import_export.dart,home.dart) to use native Flutter localizationMigrated all app sources (GitHub, GitLab, Telegram, APKMirror, Tencent, and others) to the new localization system
Updated providers (
apps_provider.dart,settings_provider.dart,notifications_provider.dart) to use native localizationAdded accessibility improvements with
Semanticswidgets in the apps pageAdded error handling with
mountedchecks in download callbacksDiagram Walkthrough
File Walkthrough
1 files
app_localizations_zh.dart
Add complete Chinese localization translationslib/generated/app_localizations_zh.dart
for the Updatium app
AppLocalizationsZhclass extendingAppLocalizationswithChinese (Simplified) translations
AppLocalizationsZhHantTwclass extendingAppLocalizationsZhwith Traditional Chinese (Taiwan) translations
notifications, and error messages
15 files
apps.dart
Migrate localization to Flutter native systemlib/pages/apps.dart
easy_localizationpackage imports with Flutter's nativeAppLocalizationssystemtr()function calls to useAppLocalizations.of(context)!method calls
Semanticswidgets to improve accessibility for install/updatebuttons with labels and hints
mountedchecks in download callbacks toprevent state updates on unmounted widgets
escape sequences
import_export.dart
Migrate import/export page to Flutter localizationlib/pages/import_export.dart
easy_localizationimports with Flutter's nativeAppLocalizationstr()andplural()function calls to useAppLocalizations.of(context)!method callsthe import/export page
telegramapp.dart
Update Telegram app source localizationlib/app_sources/telegramapp.dart
easy_localizationpackage importtr('app')call withAppLocalizations.of(context)!.appfornative Flutter localization
system
app_localizations_pt.dart
Generated Portuguese localization implementation for Flutterlib/generated/app_localizations_pt.dart
strings
pt) classAppLocalizationsPtextendingAppLocalizationspt_BR) classAppLocalizationsPtBrextending
AppLocalizationsPtand plural forms
settings.dart
Migrate settings page to Flutter native localizationlib/pages/settings.dart
easy_localizationpackage import and replaced with Flutter'snative
AppLocalizationstr()function calls to useAppLocalizations.of(context)!pattern
invocation
settings page
apps_provider.dart
Migrate apps provider to Flutter native localizationlib/providers/apps_provider.dart
easy_localizationimport and addedAppLocalizationsimportAppLocalizations.of(context)!patternAppLocalizations.of(globalNavigatorKey.currentContext!)!using
AppLocalizations.delegate.load()tr()andplural()calls with native localization methodsgitlab.dart
Migrate GitLab source to Flutter native localizationlib/app_sources/gitlab.dart
easy_localizationimport and addedAppLocalizationsimportAppLocalizations.of(context)!patterntr()function calls with native localization methodinvocations
tencent.dart
Migrate Tencent source to Flutter native localizationlib/app_sources/tencent.dart
easy_localizationimport and addedAppLocalizationsimportAppLocalizations.of(context)!patternapp_localizations_en.dart
Generated English and Esperanto localization stringslib/generated/app_localizations_en.dart
of translation strings
AppLocalizationsEnclass extendingAppLocalizationswithEnglish translations
AppLocalizationsEnEoclass extendingAppLocalizationsEnwithEsperanto translations
notifications, and pluralization rules
add_app.dart
Migrate add app page to Flutter localizationlib/pages/add_app.dart
easy_localizationimport withAppLocalizationsfrom generatedlocalizations
tr()function calls to useAppLocalizations.of(context)!method calls
plural()toAppLocalizations.of(context)!.source(2)patterntranslation keys
app.dart
Migrate app detail page to Flutter localizationlib/pages/app.dart
easy_localizationimport and replaced withAppLocalizationstr()calls toAppLocalizations.of(context)!methodinvocations
plural()toAppLocalizations.of(context)!.apk()patterncalls
main.dart
Migrate main app to Flutter native localizationlib/main.dart
easy_localizationpackage imports and related controllerinitialization code
flutter_localizationsandAppLocalizationsimportsloadTranslations()function andEasyLocalizationwrapperMaterialAppto useAppLocalizations.delegateand hardcodedsupportedLocaleslistsettingsProvider.forcedLocaledirectly
github.dart
Migrate GitHub source to Flutter localizationlib/app_sources/github.dart
easy_localizationimport and addedAppLocalizationsimporttr()function calls toAppLocalizations.of(context)!method calls
localization pattern
generated_form.dart
Migrate generated form component to Flutter localizationlib/components/generated_form.dart
easy_localizationimport and addedAppLocalizationsimporttr()calls withAppLocalizations.of(context)!methodinvocations
approach
apkmirror.dart
Migrate APKMirror source to Flutter localizationlib/app_sources/apkmirror.dart
easy_localizationimport and addedAppLocalizationsimporttr()toAppLocalizations.of(context)!method calls
93 files