Skip to content

Cherry pick safe commits#142

Merged
omeritzics merged 46 commits intomasterfrom
cherry-pick-safe-commits
Feb 14, 2026
Merged

Cherry pick safe commits#142
omeritzics merged 46 commits intomasterfrom
cherry-pick-safe-commits

Conversation

@omeritzics
Copy link
Owner

@omeritzics omeritzics commented Feb 14, 2026

PR Type

Enhancement, Bug fix


Description

  • Refactor apps page UI with improved status indicators

  • Replace custom animation utilities with standard Flutter curves

  • Update Android build configuration for ABI splitting support

  • Fix Flutter API deprecations and improve code compatibility

  • Enhance translation strings across 30+ languages


Diagram Walkthrough

flowchart LR
  A["Apps Page UI"] -->|"Refactor status display"| B["Enhanced Status Indicators"]
  C["Animation Utilities"] -->|"Replace with standard curves"| D["Flutter Curves"]
  E["Android Build Config"] -->|"Add ABI splitting"| F["Multi-ABI Support"]
  G["Deprecated APIs"] -->|"Fix usage"| H["Compatible Code"]
  I["Translation Files"] -->|"Improve strings"| J["30+ Languages Updated"]
Loading

File Walkthrough

Relevant files
Enhancement
3 files
apps.dart
Refactor app status UI and layout structure                           
+91/-64 
cached_app_icon.dart
Replace custom motion curves with standard Flutter curves
+6/-7     
app_button.dart
Replace custom motion curves with standard Flutter curves
+5/-6     
Bug fix
7 files
icon_prefetcher_example.dart
Fix deprecated FilledButton API usage                                       
+6/-5     
import_export.dart
Fix button property names and selection modal text             
+4/-4     
enhanced_icon_prefetcher.dart
Fix constructor syntax and add missing parameters               
+10/-2   
updated_app_catalogue_example.dart
Add missing import and fix icon reference                               
+2/-1     
refactored_icon_pipeline_example.dart
Add missing app_button component import                                   
+1/-1     
notifications_provider.dart
Fix unused variable naming in PageRouteBuilder                     
+1/-1     
icon_cache_example.dart
Add missing app_button component import                                   
+1/-0     
Configuration changes
1 files
build.gradle.kts
Update Kotlin configuration and add ABI split support       
+35/-12 
Documentation
9 files
he.json
Improve Hebrew translation strings                                             
+31/-16 
ar.json
Improve Arabic translation strings                                             
+18/-2   
hu.json
Improve Hungarian translation strings                                       
+2/-2     
uk.json
Improve Ukrainian translation strings                                       
+2/-2     
cs.json
Improve Czech translation strings                                               
+2/-2     
pl.json
Improve Polish translation strings                                             
+2/-2     
ja.json
Improve Japanese translation strings                                         
+2/-2     
et.json
Improve Estonian translation strings                                         
+2/-2     
zh-Hant-TW.json
Improve Traditional Chinese translation strings                   
+2/-2     
Additional files
25 files
ci.yml +1/-5     
bs.json +2/-2     
ca.json +2/-2     
da.json +2/-2     
de.json +2/-2     
en-EO.json +2/-2     
en.json +2/-2     
es.json +2/-2     
fa.json +2/-2     
fr.json +2/-2     
gl.json +2/-2     
id.json +2/-2     
it.json +2/-2     
ko.json +2/-2     
ml.json +2/-2     
nl.json +2/-2     
pt-BR.json +2/-2     
pt.json +2/-2     
ru.json +2/-2     
sv.json +2/-2     
tr.json +2/-2     
vi.json +2/-2     
zh.json +2/-2     
home.dart +0/-1     
pubspec.yaml +1/-1     

omeritzics and others added 30 commits February 12, 2026 20:35
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Fix build issues & Improve Hebrew and Arabic Translations
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
omeritzics and others added 15 commits February 12, 2026 23:38
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
(cherry picked from commit 96d6aea)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@qodo-code-review
Copy link

qodo-code-review bot commented Feb 14, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Payload parsing crash: The new payload parsing uses .split('\n').sublist(1) which will throw a
RangeError when payload does not contain any newline, causing a crash instead of graceful
handling.

Referred Code
var content = (payload ?? '\n\n').split('\n').sublist(1).join('\n');
globalNavigatorKey.currentState?.push(
  PageRouteBuilder(
    pageBuilder: (context, _, _) => AlertDialog(
      title: Text(title),
      content: Text(content),

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unvalidated payload format: The new notification payload handling assumes a newline-delimited format and does not
validate the input before indexing with sublist(1), enabling malformed external payloads
to crash the UI route push.

Referred Code
var content = (payload ?? '\n\n').split('\n').sublist(1).join('\n');
globalNavigatorKey.currentState?.push(
  PageRouteBuilder(
    pageBuilder: (context, _, _) => AlertDialog(
      title: Text(title),
      content: Text(content),

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing action logging: The newly added install/update trigger calls
appsProvider.downloadAndInstallLatestApps(...) without any visible audit logging context
(user, timestamp, outcome) in this diff, but logging may exist inside the
provider/service.

Referred Code
if (!isInstalled) {
  return FilledButton.tonal(
    onPressed: appsProvider.areDownloadsRunning()
        ? null
        : () {
            appsProvider
                .downloadAndInstallLatestApps([
                  app.id,
                ], globalNavigatorKey.currentContext)
                .catchError((e) {
                  showError(e, context);
                  return <String>[];
                });
          },
    child: Text(tr('install')),
  );
}

if (hasUpdateLocal) {
  return FilledButton.tonal(
    onPressed: appsProvider.areDownloadsRunning()


 ... (clipped 13 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Exception shown to user: The new .catchError((e) { showError(e, context); ... }) may surface raw exception details
to end users depending on showError implementation, which cannot be verified from this
diff.

Referred Code
appsProvider
    .downloadAndInstallLatestApps([
      app.id,
    ], globalNavigatorKey.currentContext)
    .catchError((e) {
      showError(e, context);
      return <String>[];
    });

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@gemini-code-assist
Copy link

Summary of Changes

Hello @omeritzics, 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 integrates a series of 'safe' commits, focusing on maintenance and minor enhancements. Key changes include updating the Android build configuration for modern Kotlin toolchains and ABI-specific APK generation, refactoring UI animation logic to use standard Flutter APIs, improving localization strings across various languages, and updating several package dependencies. These changes aim to modernize the codebase, enhance user experience through better animations and clearer translations, and ensure compatibility with the latest development practices.

Highlights

  • Android Build System Modernization: Updated the Android build configuration to utilize the modern Kotlin JVM toolchain and enabled ABI splits for more efficient APK distribution across different architectures.
  • UI Animation Refactoring: Replaced custom expressive_motion utilities with standard Flutter Duration and Curves for smoother and more maintainable animations in UI components like buttons and app icons.
  • Enhanced Localization: Numerous translation files were updated to improve clarity, consistency, and pluralization rules across various languages, particularly for 'Material You' color references and critical warning messages.
  • Dependency Updates: Several Flutter package dependencies, including characters, matcher, material_color_utilities, and test_api, were updated to their latest versions to ensure compatibility and leverage new features.
Changelog
  • android/app/build.gradle.kts
    • Updated Kotlin JVM toolchain to version 17.
    • Enabled ABI filters for 'armeabi-v7a', 'arm64-v8a', and 'x86_64' in defaultConfig.
    • Configured split APK generation for different ABIs.
    • Refactored version code calculation for ABI splits using 'androidComponents' and added null-safety and bounds checking.
  • assets/translations/ar.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
    • Added pluralization rules for several keys including 'removeAppQuestion', 'tooManyRequestsTryAgainInMinutes', 'apps', 'url', 'minute', 'hour', 'day', 'clearedNLogsBeforeXAfterY', 'xAndNMoreUpdatesAvailable', 'xAndNMoreUpdatesInstalled', 'xAndNMoreUpdatesFailed', 'xAndNMoreUpdatesPossiblyInstalled', 'apk', and 'certificateHash'.
  • assets/translations/bs.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/ca.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/cs.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/da.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/de.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/en-EO.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/en.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/es.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/et.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/fa.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/fr.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/gl.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/he.json
    • Updated 'removeOutdatedFilter' translation.
    • Updated 'showWebInAppView' translation.
    • Updated 'appWithIdOrNameNotFound' translation.
    • Updated 'markInstalled' translation.
    • Updated 'markUpdated' translation.
    • Updated 'releaseDateAsVersion' translation.
    • Updated 'releaseTitleAsVersion' translation.
    • Updated 'addInfoInSettings' translation.
    • Updated 'appsPossiblyUpdated' translation.
    • Updated 'xWasPossiblyUpdatedToY' translation.
    • Updated 'verifyLatestTag' translation.
    • Updated 'reverseSort' translation.
    • Updated 'bgTaskStarted' translation.
    • Updated 'skipUpdateNotifications' translation.
    • Modified 'googleVerificationWarningP1' message.
    • Added pluralization rules for several keys including 'removeAppQuestion', 'tooManyRequestsTryAgainInMinutes', 'bgUpdateGotErrorRetryInMinutes', 'bgCheckFoundUpdatesWillNotifyIfNeeded', 'apps', 'url', 'minute', 'hour', 'day', 'clearedNLogsBeforeXAfterY', 'xAndNMoreUpdatesAvailable', 'xAndNMoreUpdatesInstalled', 'xAndNMoreUpdatesFailed', 'xAndNMoreUpdatesPossiblyInstalled', and 'apk'.
  • assets/translations/hu.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/id.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/it.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/ja.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/ko.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/ml.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/nl.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/pl.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/pt-BR.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/pt.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/ru.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/sv.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/tr.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/uk.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/vi.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/zh-Hant-TW.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • assets/translations/zh.json
    • Updated 'useMaterialYou' translation.
    • Modified 'googleVerificationWarningP1' message.
  • lib/components/app_button.dart
    • Removed 'expressive_motion.dart' import.
    • Replaced custom animation durations and curves with standard Flutter 'Duration' and 'Curves'.
  • lib/components/cached_app_icon.dart
    • Removed 'expressive_motion.dart' import.
    • Replaced custom animation durations and curves with standard Flutter 'Duration' and 'Curves' for shimmer, scale, and rotation animations.
  • lib/examples/icon_cache_example.dart
    • Added import for 'app_button.dart'.
  • lib/examples/icon_prefetcher_example.dart
    • Added import for 'app_button.dart'.
    • Updated 'FilledButton.tonal.icon' syntax to 'FilledButton.tonalIcon'.
  • lib/examples/refactored_icon_pipeline_example.dart
    • Added import for 'app_button.dart'.
    • Removed 'enablePerformanceOverlay' parameter from 'EnhancedAppIconGrid'.
  • lib/examples/updated_app_catalogue_example.dart
    • Added import for 'app_button.dart'.
    • Changed the icon for the 'Cached' stat item to 'Icons.storage'.
  • lib/pages/apps.dart
    • Removed 'dart:math' import.
    • Added 'animations' package import.
    • Improved UI for installed/updated apps by adding a checkmark icon and 'Updated' text.
    • Refined the display of download progress indicators.
  • lib/pages/home.dart
    • Removed the import for 'import_export.dart'.
  • lib/pages/import_export.dart
    • Updated button 'child' property to 'label' for 'AppTextButton'.
    • Corrected localization for 'deselect all' text.
  • lib/providers/notifications_provider.dart
    • Made a minor syntax adjustment in 'PageRouteBuilder'.
  • lib/services/enhanced_icon_prefetcher.dart
    • Updated 'PrefetcherStatus' to include 'duration' and 'metrics'.
    • Corrected syntax for 'retryCount' in 'PrefetchConfig'.
    • Updated 'PrefetchMetrics' constructor to include optional 'lastSuccess', 'lastError', 'lastDuration', and 'lastAttempt' parameters.
  • pubspec.lock
    • Updated 'characters' to '1.4.1'.
    • Updated 'matcher' to '0.12.18'.
    • Updated 'material_color_utilities' to '0.13.0'.
    • Updated 'test_api' to '0.7.8'.
  • pubspec.yaml
    • Updated 'material_color_utilities' dependency to '^0.13.0'.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/ci.yml
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@qodo-code-review
Copy link

qodo-code-review bot commented Feb 14, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
The Import/Export feature was removed

The suggestion highlights that the Import/Export feature was removed from the
main navigation in home.dart without being documented in the PR description. It
requests clarification on whether this removal was intentional.

Examples:

lib/pages/home.dart [13]
import 'package:updatium/pages/apps.dart';

Solution Walkthrough:

Before:

// lib/pages/home.dart
import 'package:updatium/pages/apps.dart';
import 'package:updatium/pages/import_export.dart';
import 'package:updatium/pages/settings.dart';
// ...

class _HomePageState extends State<HomePage> {
  // ...
  final List<Widget> _pages = [
    const AppsPage(),
    const ImportExportPage(), // <-- Feature is present in navigation
    const SettingsPage(),
  ];
  // ...
}

After:

// lib/pages/home.dart
import 'package:updatium/pages/apps.dart';
// import 'package:updatium/pages/import_export.dart'; // <-- Import is removed
import 'package:updatium/pages/settings.dart';
// ...

class _HomePageState extends State<HomePage> {
  // ...
  final List<Widget> _pages = [
    const AppsPage(),
    // const ImportExportPage(), // <-- Feature is removed from navigation
    const SettingsPage(),
  ];
  // ...
}
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies the removal of the Import/Export feature, a significant and undocumented change in home.dart, which could be an unintentional regression.

High
Possible issue
Dispose animation controllers

Implement the dispose method in the AppTextButton widget to properly release the
_animationController and prevent potential memory leaks.

lib/components/app_button.dart [55-61]

 @override
-void initState() {
-  super.initState();
-  _animationController = AnimationController(
-    duration: const Duration(milliseconds: 150),
-    vsync: this,
-  );
-  // ...
+void dispose() {
+  _animationController.dispose();
+  super.dispose();
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a missing dispose method for an AnimationController, which is important for preventing memory leaks.

Medium
Possible issue
Assign version codes to all outputs

Ensure the universal APK receives a unique versionCode by assigning a default
abiVersionCode (e.g., 0) when no ABI filter is present, preventing potential
publishing issues.

android/app/build.gradle.kts [132-153]

 androidComponents {
-     onVariants { variant ->
-         variant.outputs.forEach { output ->
-             val abiFilter = output.filters.find {
-                 it.filterType == com.android.build.api.variant.VariantOutputConfiguration.FilterType.ABI
-             }
-             val abiVersionCode = abiFilter?.identifier?.let { abiCodes[it] }
+    onVariants { variant ->
+        variant.outputs.forEach { output ->
+            val abiFilter = output.filters.find {
+                it.filterType == com.android.build.api.variant.VariantOutputConfiguration.FilterType.ABI
+            }
+            val abiVersionCode = abiFilter?.identifier?.let { abiCodes[it] } ?: 0
 
-             if (abiVersionCode != null) {
-                 // Create a version code within Android limits (max 2100000000)
-                 // Use: (YYMMDDHH % 100000) * 100 + ABI to stay well under limits
-                 val baseBuildNumber = requireNotNull(flutterVersionCode.toLongOrNull()) {
-                     "Invalid flutter.versionCode='$flutterVersionCode' in local.properties; must be a number."
-                 }
-                 val compressedCode = (baseBuildNumber % 100000) * 100 + abiVersionCode
-                 val maxPlayVersionCode = 2_100_000_000L
-                 val safeVersionCode = compressedCode.coerceIn(1L, maxPlayVersionCode)
-                 output.versionCode.set(safeVersionCode.toInt())
-             }
-         }
-     }
- }
+            // Create a version code within Android limits (max 2100000000)
+            // Use: (YYMMDDHH % 100000) * 100 + ABI to stay well under limits
+            val baseBuildNumber = requireNotNull(flutterVersionCode.toLongOrNull()) {
+                "Invalid flutter.versionCode='$flutterVersionCode' in local.properties; must be a number."
+            }
+            val compressedCode = (baseBuildNumber % 100000) * 100 + abiVersionCode
+            val maxPlayVersionCode = 2_100_000_000L
+            val safeVersionCode = compressedCode.coerceIn(1L, maxPlayVersionCode)
+            output.versionCode.set(safeVersionCode.toInt())
+        }
+    }
+}

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a potential issue where the universal APK does not get a unique version code, which could lead to publishing and upgrade problems on app stores.

Medium
  • Update

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a collection of various enhancements and bug fixes. Key changes include refactoring UI components to use standard Flutter animations, modernizing the Android Gradle build script with safer version code handling and ABI splitting, and updating numerous translation strings across more than 30 languages. The changes also address several deprecated Flutter APIs, improving code compatibility.

While the majority of the changes are positive and improve the codebase's maintainability and correctness, I've identified one critical issue in lib/pages/home.dart where a necessary import is removed, which will cause a build failure. Please address this issue before merging.

Repository owner deleted a comment from qodo-code-review bot Feb 14, 2026
Comment on lines +132 to 153
androidComponents {
onVariants { variant ->
variant.outputs.forEach { output ->
val abiFilter = output.filters.find {
it.filterType == com.android.build.api.variant.VariantOutputConfiguration.FilterType.ABI
}
val abiVersionCode = abiFilter?.identifier?.let { abiCodes[it] }

android.applicationVariants.configureEach {
val variant = this
variant.outputs.forEach { output ->
val abiVersionCode = abiCodes[output.filters.find { it.filterType == "ABI" }?.identifier]
if (abiVersionCode != null) {
// Create a version code within Android limits (max 2100000000)
// Use: (YYMMDDHH % 100000) * 100 + ABI to stay well under limits
val baseBuildNumber = flutterVersionCode.toLong()
val compressedCode = (baseBuildNumber % 100000) * 100 + abiVersionCode
(output as ApkVariantOutputImpl).versionCodeOverride = compressedCode.toInt()
if (abiVersionCode != null) {
// Create a version code within Android limits (max 2100000000)
// Use: (YYMMDDHH % 100000) * 100 + ABI to stay well under limits
val baseBuildNumber = requireNotNull(flutterVersionCode.toLongOrNull()) {
"Invalid flutter.versionCode='$flutterVersionCode' in local.properties; must be a number."
}
val compressedCode = (baseBuildNumber % 100000) * 100 + abiVersionCode
val maxPlayVersionCode = 2_100_000_000L
val safeVersionCode = compressedCode.coerceIn(1L, maxPlayVersionCode)
output.versionCode.set(safeVersionCode.toInt())
}
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Assign version codes to all outputs

Suggested change
androidComponents {
onVariants { variant ->
variant.outputs.forEach { output ->
val abiFilter = output.filters.find {
it.filterType == com.android.build.api.variant.VariantOutputConfiguration.FilterType.ABI
}
val abiVersionCode = abiFilter?.identifier?.let { abiCodes[it] }
android.applicationVariants.configureEach {
val variant = this
variant.outputs.forEach { output ->
val abiVersionCode = abiCodes[output.filters.find { it.filterType == "ABI" }?.identifier]
if (abiVersionCode != null) {
// Create a version code within Android limits (max 2100000000)
// Use: (YYMMDDHH % 100000) * 100 + ABI to stay well under limits
val baseBuildNumber = flutterVersionCode.toLong()
val compressedCode = (baseBuildNumber % 100000) * 100 + abiVersionCode
(output as ApkVariantOutputImpl).versionCodeOverride = compressedCode.toInt()
if (abiVersionCode != null) {
// Create a version code within Android limits (max 2100000000)
// Use: (YYMMDDHH % 100000) * 100 + ABI to stay well under limits
val baseBuildNumber = requireNotNull(flutterVersionCode.toLongOrNull()) {
"Invalid flutter.versionCode='$flutterVersionCode' in local.properties; must be a number."
}
val compressedCode = (baseBuildNumber % 100000) * 100 + abiVersionCode
val maxPlayVersionCode = 2_100_000_000L
val safeVersionCode = compressedCode.coerceIn(1L, maxPlayVersionCode)
output.versionCode.set(safeVersionCode.toInt())
}
}
}
}
androidComponents {
onVariants { variant ->
variant.outputs.forEach { output ->
val abiFilter = output.filters.find {
it.filterType == com.android.build.api.variant.VariantOutputConfiguration.FilterType.ABI
}
val abiVersionCode = abiFilter?.identifier?.let { abiCodes[it] } ?: 0
// Create a version code within Android limits (max 2100000000)
// Use: (YYMMDDHH % 100000) * 100 + ABI to stay well under limits
val baseBuildNumber = requireNotNull(flutterVersionCode.toLongOrNull()) {
"Invalid flutter.versionCode='$flutterVersionCode' in local.properties; must be a number."
}
val compressedCode = (baseBuildNumber % 100000) * 100 + abiVersionCode
val maxPlayVersionCode = 2_100_000_000L
val safeVersionCode = compressedCode.coerceIn(1L, maxPlayVersionCode)
output.versionCode.set(safeVersionCode.toInt())
}
}
}

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update your branch, I can't merge it.

@omeritzics omeritzics merged commit 5041e0e into master Feb 14, 2026
0 of 3 checks passed
@omeritzics omeritzics deleted the cherry-pick-safe-commits branch February 15, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant