From 92bc1746f1295b3250de88e43fdb62244b94ad30 Mon Sep 17 00:00:00 2001 From: Ushie Date: Sat, 11 Nov 2023 11:43:17 +0300 Subject: [PATCH] feat: Allow changing languages (#1450) Co-authored-by: Aunali321 Co-authored-by: Pun Butrach Co-authored-by: oSumAtrIX --- .github/workflows/pr-build.yml | 2 + .github/workflows/release-build.yml | 4 +- README.md | 5 +- assets/i18n/en_US.json | 331 ------------------ assets/i18n/strings.i18n.json | 255 ++++++++++++++ docs/4_building.md | 11 +- lib/main.dart | 39 +-- lib/services/download_manager.dart | 4 +- lib/services/manager_api.dart | 34 +- lib/services/toast.dart | 11 +- lib/ui/theme/dynamic_theme_builder.dart | 43 ++- .../views/app_selector/app_selector_view.dart | 29 +- .../app_selector/app_selector_viewmodel.dart | 63 ++-- .../views/contributors/contributors_view.dart | 23 +- lib/ui/views/home/home_view.dart | 31 +- lib/ui/views/home/home_viewmodel.dart | 120 +++---- lib/ui/views/installer/installer_view.dart | 18 +- .../views/installer/installer_viewmodel.dart | 57 ++- lib/ui/views/navigation/navigation_view.dart | 17 +- .../patch_options/patch_options_view.dart | 25 +- .../patch_options_viewmodel.dart | 25 +- lib/ui/views/patcher/patcher_view.dart | 17 +- lib/ui/views/patcher/patcher_viewmodel.dart | 49 ++- .../patches_selector_view.dart | 69 ++-- .../patches_selector_viewmodel.dart | 45 +-- .../settings_manage_api_url.dart | 26 +- .../settings_manage_keystore_password.dart | 14 +- .../settings_manage_sources.dart | 36 +- .../settings_update_language.dart | 111 +++--- .../settings_update_theme.dart | 54 ++- lib/ui/views/settings/settings_view.dart | 16 +- lib/ui/views/settings/settings_viewmodel.dart | 87 +++-- lib/ui/widgets/appInfoView/app_info_view.dart | 140 +++----- .../appInfoView/app_info_viewmodel.dart | 26 +- .../appSelectorView/installed_app_item.dart | 26 +- .../not_installed_app_item.dart | 27 +- .../contributorsView/contributors_card.dart | 12 +- .../widgets/homeView/installed_apps_card.dart | 24 +- .../widgets/homeView/latest_commit_card.dart | 32 +- .../homeView/update_confirmation_dialog.dart | 37 +- .../patcherView/app_selector_card.dart | 20 +- .../patcherView/patch_selector_card.dart | 24 +- .../patchesSelectorView/patch_item.dart | 27 +- .../patch_options_fields.dart | 72 ++-- lib/ui/widgets/settingsView/about_widget.dart | 17 +- .../settings_advanced_section.dart | 4 +- .../settings_auto_update_patches.dart | 17 +- .../settingsView/settings_debug_section.dart | 49 ++- .../settings_enable_patches_selection.dart | 20 +- .../settingsView/settings_export_section.dart | 133 +++---- ...ettings_require_suggested_app_version.dart | 28 +- .../settingsView/settings_section.dart | 10 +- .../settingsView/settings_team_section.dart | 19 +- .../settingsView/settings_tile_dialog.dart | 14 +- .../settings_universal_patches.dart | 23 +- .../settings_version_compatibility_check.dart | 23 +- .../settingsView/social_media_widget.dart | 17 +- lib/ui/widgets/shared/application_item.dart | 5 +- pubspec.yaml | 8 +- slang.yaml | 5 + 60 files changed, 1122 insertions(+), 1408 deletions(-) delete mode 100644 assets/i18n/en_US.json create mode 100644 assets/i18n/strings.i18n.json create mode 100644 slang.yaml diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index 8424eff412..a092c237e8 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -32,6 +32,8 @@ jobs: cache: true - name: Install Flutter dependencies run: flutter pub get + - name: Generate translation with Slang + run: dart run slang - name: Generate files with Builder run: flutter packages pub run build_runner build --delete-conflicting-outputs - name: Build with Flutter diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index 94f2921d13..309be8ac73 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -22,6 +22,8 @@ jobs: channel: "stable" - name: Set up Flutter run: flutter pub get + - name: Generate translation with Slang + run: dart run slang - name: Generate files with Builder run: flutter packages pub run build_runner build --delete-conflicting-outputs - name: Build with Flutter @@ -47,4 +49,4 @@ jobs: with: repo_token: "${{ secrets.GITHUB_TOKEN }}" prerelease: false - files: revanced-manager-${{ env.RELEASE_VERSION }}.apk \ No newline at end of file + files: revanced-manager-${{ env.RELEASE_VERSION }}.apk diff --git a/README.md b/README.md index 89f41ea69e..c9d33d7650 100644 --- a/README.md +++ b/README.md @@ -31,5 +31,6 @@ We're accepting translations on [Crowdin](https://translate.revanced.app). 3. Add your GitHub token in gradle.properties like [this](/docs/4_building.md) 4. Open the project in terminal 5. Run `flutter pub get` in terminal -6. Then `flutter packages pub run build_runner build --delete-conflicting-outputs` (Must be done on each git pull) -7. To build release APK run `flutter build apk` +6. Generate translation file using `dart run slang` +7. Then `flutter packages pub run build_runner build --delete-conflicting-outputs` (Must be done on each git pull) +8. To build release APK run `flutter build apk` diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json deleted file mode 100644 index 47b35a4a08..0000000000 --- a/assets/i18n/en_US.json +++ /dev/null @@ -1,331 +0,0 @@ -{ - "okButton": "OK", - "cancelButton": "Cancel", - "dismissButton": "Dismiss", - "quitButton": "Quit", - "updateButton": "Update", - "enabledLabel": "Enabled", - "disabledLabel": "Disabled", - "installed":"Installed: {version}", - "suggested":"Suggested: {version}", - "yesButton": "Yes", - "noButton": "No", - "warning": "Warning", - "options": "Options", - "notice": "Notice", - "noShowAgain": "Don't show this again", - "add": "Add", - "remove": "Remove", - "navigationView": { - "dashboardTab": "Dashboard", - "patcherTab": "Patcher", - "settingsTab": "Settings" - }, - "homeView": { - "refreshSuccess": "Refreshed successfully", - "widgetTitle": "Dashboard", - - "updatesSubtitle": "Updates", - "patchedSubtitle": "Patched apps", - - "noUpdates": "No updates available", - - "WIP": "Work in progress...", - - "noInstallations": "No patched apps installed", - "installUpdate": "Continue to install the update?", - - "updateDialogTitle": "Update Manager", - "updatePatchesDialogTitle": "Update ReVanced Patches", - "updateChangelogTitle": "Changelog", - - "patchesConsentDialogText": "ReVanced Patches needs to be downloaded.", - "patchesConsentDialogText2": "This will connect you to {url}.", - "patchesConsentDialogText3": "Auto update?", - "patchesConsentDialogText3Sub": "You can change this in settings at a later time.", - - "notificationTitle": "Update downloaded", - "notificationText": "Tap to install the update", - - "downloadingMessage": "Downloading update...", - "downloadedMessage": "Update downloaded!", - - "installingMessage": "Installing update...", - - "errorDownloadMessage": "Unable to download update", - "errorInstallMessage": "Unable to install update", - - "noConnection": "No internet connection", - "updatesDisabled": "Updating a patched app is currently disabled. Repatch the app again." - }, - "applicationItem": { - "infoButton": "Info" - }, - "latestCommitCard": { - "loadingLabel": "Loading...", - "timeagoLabel": "{time} ago", - "patcherLabel": "Patcher: ", - "managerLabel": "Manager: ", - "updateButton": "Update Manager" - }, - "patcherView": { - "widgetTitle": "Patcher", - "patchButton": "Patch", - - "armv7WarningDialogText": "Patching on ARMv7 devices is not yet supported and might fail. Proceed anyways?", - - "removedPatchesWarningDialogText": "The following patches have been removed since the last time you used them.\n\n{patches}\n\nProceed anyways?", - "requiredOptionDialogText" : "Some patch options have to be set." - }, - "appSelectorCard": { - "widgetTitle": "Select an application", - "widgetTitleSelected": "Selected application", - "widgetSubtitle": "No application selected", - - "noAppsLabel": "No applications found", - "notInstalled":"App not installed", - - "currentVersion": "Current", - "suggestedVersion": "Suggested", - "allVersions": "All versions" - }, - "patchSelectorCard": { - "widgetTitle": "Select patches", - "widgetTitleSelected": "Selected patches", - - "widgetSubtitle": "Select an application first", - "widgetEmptySubtitle": "No patches selected" - }, - "socialMediaCard": { - "widgetTitle": "Socials", - "widgetSubtitle": "We are online!" - }, - "appSelectorView": { - "viewTitle": "Select an application", - "searchBarHint": "Search applications", - - "storageButton": "Storage", - "selectFromStorageButton": "Select from storage", - - "errorMessage": "Unable to use selected application", - - "downloadToast": "Download function is not available yet", - - "requireSuggestedAppVersionDialogText": "The version of the app you have selected does not match the suggested version. Please select the app that matches the suggested version.\n\nSelected version: v{selected}\nSuggested version: v{suggested}\n\n.To proceed anyway, disable \"Require suggested app version\" in the settings.", - - "featureNotAvailable": "Feature not implemented", - "featureNotAvailableText": "This application is a split APK and cannot be selected. Unfortunately, this feature is only available for rooted users at the moment. However, you can still install the application by selecting its APK files from your device's storage instead" - }, - "patchesSelectorView": { - "viewTitle": "Select patches", - "searchBarHint": "Search patches", - "universalPatches": "Universal patches", - "newPatches": "New patches", - "patches": "Patches", - - "doneButton": "Done", - - "default": "Default", - "defaultTooltip": "Select all default patches", - - "none": "None", - "noneTooltip": "Deselect all patches", - - "loadPatchesSelection": "Load patch selection", - "noSavedPatches": "No saved patch selection for the selected app.\nPress Done to save the current selection.", - "noPatchesFound": "No patches found for the selected app", - "setRequiredOption": "Some patches require options to be set:\n\n{patches}\n\nPlease set them before continuing." - }, - "patchOptionsView": { - "customValue": "Custom value", - "resetOptionsTooltip": "Reset patch options", - "viewTitle": "Patch options", - "saveOptions": "Save", - - "addOptions": "Add options", - "deselectPatch": "Deselect patch", - "tooltip": "More input options", - "selectFilePath": "Select file path", - "selectFolder": "Select folder", - "selectOption": "Select option", - - "requiredOption": "This option is required", - "unsupportedOption": "This option is not supported", - "requiredOptionNull": "The following options have to be set:\n\n{options}" - }, - "patchItem": { - "unsupportedDialogText": "Selecting this patch may result in patching errors.\n\nApp version: {packageVersion}\nSupported versions:\n{supportedVersions}", - "unsupportedPatchVersion": "Patch is not supported for this app version.", - "unsupportedRequiredOption": "This patch contains a required option that is not supported by this app", - - "patchesChangeWarningDialogText": "It is recommended to use the default patch selection and options. Changing them may result in unexpected issues.\n\nYou'll need to turn on \"Allow changing patch selection\" in settings before changing any patch selection.", - "patchesChangeWarningDialogButton": "Use default selection" - }, - "installerView": { - "widgetTitle": "Installer", - "installType": "Select install type", - "installTypeDescription": "Select the installation type to proceed with.", - - "installButton": "Install", - "installRootType": "Mount", - "installNonRootType": "Normal", - - "pressBackAgain": "Press back again to cancel", - "openButton": "Open", - "shareButton": "Share file", - - "notificationTitle": "ReVanced Manager is patching", - "notificationText": "Tap to return to the installer", - - "exportApkButtonTooltip": "Export patched APK", - "exportLogButtonTooltip": "Export log", - - "screenshotDetected": "A screenshot has been detected. If you are trying to share the log, please share a text copy instead.\n\nCopy log to clipboard?", - "copiedToClipboard": "Copied log to clipboard", - - "noExit": "Installer is still running, cannot exit..." - }, - "settingsView": { - "widgetTitle": "Settings", - - "appearanceSectionTitle": "Appearance", - "teamSectionTitle": "Team", - "debugSectionTitle": "Debugging", - "advancedSectionTitle": "Advanced", - "exportSectionTitle": "Import & export", - - "themeModeLabel": "App theme", - "systemThemeLabel": "System", - "lightThemeLabel": "Light", - "darkThemeLabel": "Dark", - - "dynamicThemeLabel": "Material You", - "dynamicThemeHint": "Enjoy an experience closer to your device", - - "languageLabel": "Language", - "englishOption": "English", - - "sourcesLabel": "Sources", - "sourcesLabelHint": "Configure your sources", - "sourcesIntegrationsLabel": "Integrations source", - "sourcesResetDialogTitle": "Reset", - "sourcesResetDialogText": "Are you sure you want to reset your sources to their default values?", - "apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?", - "sourcesUpdateNote": "Note: Patches will be updated to the latest version automatically.\n\nThis will reveal your IP address to the server.", - - "apiURLLabel": "API URL", - "apiURLHint": "Configure your API URL", - "selectApiURL": "API URL", - "hostRepositoryLabel": "Repository API", - "orgPatchesLabel": "Patches organization", - "sourcesPatchesLabel": "Patches source", - "orgIntegrationsLabel": "Integrations organization", - - "contributorsLabel": "Contributors", - "contributorsHint": "A list of contributors of ReVanced", - - "logsLabel": "Share logs", - "logsHint": "Share ReVanced Manager logs", - - "enablePatchesSelectionLabel": "Allow changing patch selection", - "enablePatchesSelectionHint": "Allow changing the selection of patches", - "enablePatchesSelectionWarningText": "Changing the selection of patches may cause unexpected issues.\n\nEnable anyways?", - "disablePatchesSelectionWarningText": "You are about to disable changing the selection of patches.\nThe default selection of patches will be restored.\n\nDisable anyways?", - - "autoUpdatePatchesLabel": "Auto update patches", - "autoUpdatePatchesHint": "Automatically update patches to the latest version", - "universalPatchesLabel": "Show universal patches", - "universalPatchesHint": "Display all apps and universal patches (may slow down the app list)", - - "versionCompatibilityCheckLabel": "Version compatibility check", - "versionCompatibilityCheckHint": "Restricts patches to supported app versions", - "requireSuggestedAppVersionLabel": "Require suggested app version", - "requireSuggestedAppVersionHint": "Enforce selection of suggested app version", - "requireSuggestedAppVersionDialogText": "Selecting an app that is not the suggested version may cause unexpected issues.\n\nDo you want to proceed anyways?", - - "aboutLabel": "About", - "snackbarMessage": "Copied to clipboard", - "restartAppForChanges": "Restart the app to apply changes", - - "deleteTempDirLabel": "Delete temporary files", - "deleteTempDirHint": "Delete unused temporary files", - "deletedTempDir": "Temporary files deleted", - - "exportPatchesLabel": "Export patch selection", - "exportPatchesHint": "Export patch selection to a JSON file", - "exportedPatches": "Patch selection exported", - "noExportFileFound": "No patch selection to export", - - "importPatchesLabel": "Import patch selection", - "importPatchesHint": "Import patch selection from a JSON file", - "importedPatches": "Patch selection imported", - - "resetStoredPatchesLabel": "Reset patch selection", - "resetStoredPatchesHint": "Reset the stored patch selection", - "resetStoredPatchesDialogTitle": "Reset patch selection?", - "resetStoredPatchesDialogText": "The default selection of patches will be restored.", - "resetStoredPatches": "Patch selection has been reset", - - "resetStoredOptionsLabel": "Reset patch options", - "resetStoredOptionsHint": "Reset all patch options", - "resetStoredOptionsDialogTitle": "Reset patch options?", - "resetStoredOptionsDialogText": "Resetting patch options will remove all saved options.", - "resetStoredOptions": "Options have been reset", - - "deleteLogsLabel": "Clear logs", - "deleteLogsHint": "Delete collected ReVanced Manager logs", - "deletedLogs": "Logs deleted", - - "regenerateKeystoreLabel": "Regenerate keystore", - "regenerateKeystoreHint": "Regenerate the keystore used to sign apps", - - "regenerateKeystoreDialogTitle": "Regenerate keystore?", - "regenerateKeystoreDialogText": "Patched apps signed with the old keystore will no longer be able to be updated.", - "regeneratedKeystore": "Keystore regenerated", - - "exportKeystoreLabel": "Export keystore", - "exportKeystoreHint": "Export the keystore used to sign apps", - "exportedKeystore": "Keystore exported", - "noKeystoreExportFileFound": "No keystore to export", - - "importKeystoreLabel": "Import keystore", - "importKeystoreHint": "Import a keystore used to sign apps", - "importedKeystore": "Keystore imported", - - "selectKeystorePassword": "Keystore password", - "selectKeystorePasswordHint": "Select keystore password used to sign apps", - - "jsonSelectorErrorMessage": "Unable to use selected JSON file", - "keystoreSelectorErrorMessage": "Unable to use selected keystore file" - }, - "appInfoView": { - "widgetTitle": "App info", - "openButton": "Open", - "uninstallButton": "Uninstall", - "unpatchButton": "Unpatch", - "rootDialogTitle": "Error", - - "unpatchDialogText": "Are you sure you want to unpatch this app?", - "rootDialogText": "App was installed with superuser permissions, but currently ReVanced Manager has no permissions.\nPlease grant superuser permissions first.", - - "packageNameLabel": "Package name", - "installTypeLabel": "Installation type", - "rootTypeLabel": "Root", - "nonRootTypeLabel": "Non-root", - "patchedDateLabel": "Patched date", - "appliedPatchesLabel": "Applied patches", - - "patchedDateHint": "{date} at {time}", - "appliedPatchesHint": "{quantity} applied patches", - - "updateNotImplemented": "This feature has not been implemented yet" - }, - "contributorsView": { - "widgetTitle": "Contributors", - "patcherContributors": "Patcher contributors", - "patchesContributors": "Patches contributors", - "integrationsContributors": "Integrations contributors", - "cliContributors": "CLI contributors", - "managerContributors": "Manager contributors" - } -} diff --git a/assets/i18n/strings.i18n.json b/assets/i18n/strings.i18n.json new file mode 100644 index 0000000000..af119c2f89 --- /dev/null +++ b/assets/i18n/strings.i18n.json @@ -0,0 +1,255 @@ +{ + "okButton": "OK", + "cancelButton": "Cancel", + "quitButton": "Quit", + "updateButton": "Update", + "installed": "Installed: ${version}", + "suggested": "Suggested: ${version}", + "yesButton": "Yes", + "noButton": "No", + "warning": "Warning", + "options": "Options", + "notice": "Notice", + "noShowAgain": "Don't show this again", + "add": "Add", + "remove": "Remove", + "navigationView": { + "dashboardTab": "Dashboard", + "patcherTab": "Patcher", + "settingsTab": "Settings" + }, + "homeView": { + "refreshSuccess": "Refreshed successfully", + "widgetTitle": "Dashboard", + "updatesSubtitle": "Updates", + "patchedSubtitle": "Patched apps", + "noInstallations": "No patched apps installed", + "installUpdate": "Continue to install the update?", + "updateDialogTitle": "Update Manager", + "updatePatchesDialogTitle": "Update ReVanced Patches", + "updateChangelogTitle": "Changelog", + "patchesConsentDialogText": "ReVanced Patches needs to be downloaded.", + "patchesConsentDialogText2": "This will connect you to ${url}.", + "patchesConsentDialogText3": "Auto update?", + "patchesConsentDialogText3Sub": "You can change this in settings at a later time.", + "downloadingMessage": "Downloading update...", + "downloadedMessage": "Update downloaded!", + "installingMessage": "Installing update...", + "errorDownloadMessage": "Unable to download update", + "errorInstallMessage": "Unable to install update", + "noConnection": "No internet connection", + "updatesDisabled": "Updating a patched app is currently disabled. Repatch the app again." + }, + "applicationItem": { + "infoButton": "Info" + }, + "latestCommitCard": { + "loadingLabel": "Loading...", + "timeagoLabel": "${time} ago" + }, + "patcherView": { + "widgetTitle": "Patcher", + "patchButton": "Patch", + "armv7WarningDialogText": "Patching on ARMv7 devices is not yet supported and might fail. Proceed anyways?", + "removedPatchesWarningDialogText": "The following patches have been removed since the last time you used them.\n\n${patches}\n\nProceed anyways?", + "requiredOptionDialogText": "Some patch options have to be set." + }, + "appSelectorCard": { + "widgetTitle": "Select an application", + "widgetTitleSelected": "Selected application", + "widgetSubtitle": "No application selected", + "noAppsLabel": "No applications found", + "notInstalled": "App not installed", + "currentVersion": "Current", + "suggestedVersion": "Suggested", + "allVersions": "All versions" + }, + "patchSelectorCard": { + "widgetTitle": "Select patches", + "widgetTitleSelected": "Selected patches", + "widgetSubtitle": "Select an application first", + "widgetEmptySubtitle": "No patches selected" + }, + "socialMediaCard": { + "widgetTitle": "Socials", + "widgetSubtitle": "We are online!" + }, + "appSelectorView": { + "viewTitle": "Select an application", + "searchBarHint": "Search applications", + "storageButton": "Storage", + "selectFromStorageButton": "Select from storage", + "errorMessage": "Unable to use selected application", + "downloadToast": "Download function is not available yet", + "requireSuggestedAppVersionDialogText": "The version of the app you have selected does not match the suggested version. Please select the app that matches the suggested version.\n\nSelected version: v${selected}\nSuggested version: v${suggested}\n\n.To proceed anyway, disable \"Require suggested app version\" in the settings.", + "featureNotAvailable": "Feature not implemented", + "featureNotAvailableText": "This application is a split APK and cannot be selected. Unfortunately, this feature is only available for rooted users at the moment. However, you can still install the application by selecting its APK files from your device's storage instead" + }, + "patchesSelectorView": { + "viewTitle": "Select patches", + "searchBarHint": "Search patches", + "universalPatches": "Universal patches", + "newPatches": "New patches", + "patches": "Patches", + "doneButton": "Done", + "defaultText": "Default", + "defaultTooltip": "Select all default patches", + "none": "None", + "noneTooltip": "Deselect all patches", + "loadPatchesSelection": "Load patch selection", + "noSavedPatches": "No saved patch selection for the selected app.\nPress Done to save the current selection.", + "noPatchesFound": "No patches found for the selected app", + "setRequiredOption": "Some patches require options to be set:\n\n${patches}\n\nPlease set them before continuing." + }, + "patchOptionsView": { + "customValue": "Custom value", + "resetOptionsTooltip": "Reset patch options", + "viewTitle": "Patch options", + "saveOptions": "Save", + "addOptions": "Add options", + "deselectPatch": "Deselect patch", + "tooltip": "More input options", + "selectFilePath": "Select file path", + "selectFolder": "Select folder", + "requiredOption": "This option is required", + "unsupportedOption": "This option is not supported", + "requiredOptionNull": "The following options have to be set:\n\n${options}" + }, + "patchItem": { + "unsupportedDialogText": "Selecting this patch may result in patching errors.\n\nApp version: ${packageVersion}\nSupported versions:\n${supportedVersions}", + "unsupportedRequiredOption": "This patch contains a required option that is not supported by this app", + "patchesChangeWarningDialogText": "It is recommended to use the default patch selection and options. Changing them may result in unexpected issues.\n\nYou'll need to turn on \"Allow changing patch selection\" in settings before changing any patch selection.", + "patchesChangeWarningDialogButton": "Use default selection" + }, + "installerView": { + "installType": "Select install type", + "installTypeDescription": "Select the installation type to proceed with.", + "installButton": "Install", + "installRootType": "Mount", + "installNonRootType": "Normal", + "pressBackAgain": "Press back again to cancel", + "openButton": "Open", + "notificationTitle": "ReVanced Manager is patching", + "notificationText": "Tap to return to the installer", + "exportApkButtonTooltip": "Export patched APK", + "exportLogButtonTooltip": "Export log", + "screenshotDetected": "A screenshot has been detected. If you are trying to share the log, please share a text copy instead.\n\nCopy log to clipboard?", + "copiedToClipboard": "Copied log to clipboard", + "noExit": "Installer is still running, cannot exit..." + }, + "settingsView": { + "widgetTitle": "Settings", + "appearanceSectionTitle": "Appearance", + "teamSectionTitle": "Team", + "debugSectionTitle": "Debugging", + "advancedSectionTitle": "Advanced", + "exportSectionTitle": "Import & export", + "themeModeLabel": "App theme", + "systemThemeLabel": "System", + "lightThemeLabel": "Light", + "darkThemeLabel": "Dark", + "dynamicThemeLabel": "Material You", + "dynamicThemeHint": "Enjoy an experience closer to your device", + "languageLabel": "Language", + "languageUpdated": "Language updated", + "sourcesLabel": "Sources", + "sourcesLabelHint": "Configure your sources", + "sourcesIntegrationsLabel": "Integrations source", + "sourcesResetDialogTitle": "Reset", + "sourcesResetDialogText": "Are you sure you want to reset your sources to their default values?", + "apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?", + "sourcesUpdateNote": "Note: Patches will be updated to the latest version automatically.\n\nThis will reveal your IP address to the server.", + "apiURLLabel": "API URL", + "apiURLHint": "Configure your API URL", + "selectApiURL": "API URL", + "hostRepositoryLabel": "Repository API", + "orgPatchesLabel": "Patches organization", + "sourcesPatchesLabel": "Patches source", + "orgIntegrationsLabel": "Integrations organization", + "contributorsLabel": "Contributors", + "contributorsHint": "A list of contributors of ReVanced", + "logsLabel": "Share logs", + "logsHint": "Share ReVanced Manager logs", + "enablePatchesSelectionLabel": "Allow changing patch selection", + "enablePatchesSelectionHint": "Allow changing the selection of patches", + "enablePatchesSelectionWarningText": "Changing the selection of patches may cause unexpected issues.\n\nEnable anyways?", + "disablePatchesSelectionWarningText": "You are about to disable changing the selection of patches.\nThe default selection of patches will be restored.\n\nDisable anyways?", + "autoUpdatePatchesLabel": "Auto update patches", + "autoUpdatePatchesHint": "Automatically update patches to the latest version", + "universalPatchesLabel": "Show universal patches", + "universalPatchesHint": "Display all apps and universal patches (may slow down the app list)", + "versionCompatibilityCheckLabel": "Version compatibility check", + "versionCompatibilityCheckHint": "Restricts patches to supported app versions", + "aboutLabel": "About", + "snackbarMessage": "Copied to clipboard", + "restartAppForChanges": "Restart the app to apply changes", + "deleteTempDirLabel": "Delete temporary files", + "deleteTempDirHint": "Delete unused temporary files", + "deletedTempDir": "Temporary files deleted", + "exportPatchesLabel": "Export patch selection", + "exportPatchesHint": "Export patch selection to a JSON file", + "exportedPatches": "Patch selection exported", + "noExportFileFound": "No patch selection to export", + "importPatchesLabel": "Import patch selection", + "importPatchesHint": "Import patch selection from a JSON file", + "importedPatches": "Patch selection imported", + "resetStoredPatchesLabel": "Reset patch selection", + "resetStoredPatchesHint": "Reset the stored patch selection", + "resetStoredPatchesDialogTitle": "Reset patch selection?", + "resetStoredPatchesDialogText": "The default selection of patches will be restored.", + "resetStoredPatches": "Patch selection has been reset", + "resetStoredOptionsLabel": "Reset patch options", + "resetStoredOptionsHint": "Reset all patch options", + "resetStoredOptionsDialogTitle": "Reset patch options?", + "resetStoredOptionsDialogText": "Resetting patch options will remove all saved options.", + "resetStoredOptions": "Options have been reset", + "requireSuggestedAppVersionLabel": "Require suggested app version", + "requireSuggestedAppVersionHint": "Enforce selection of suggested app version", + "requireSuggestedAppVersionDialogText": "Selecting an app that is not the suggested version may cause unexpected issues.\n\nDo you want to proceed anyways?", + "deleteLogsLabel": "Clear logs", + "deleteLogsHint": "Delete collected ReVanced Manager logs", + "deletedLogs": "Logs deleted", + "regenerateKeystoreLabel": "Regenerate keystore", + "regenerateKeystoreHint": "Regenerate the keystore used to sign apps", + "regenerateKeystoreDialogTitle": "Regenerate keystore?", + "regenerateKeystoreDialogText": "Patched apps signed with the old keystore will no longer be able to be updated.", + "regeneratedKeystore": "Keystore regenerated", + "exportKeystoreLabel": "Export keystore", + "exportKeystoreHint": "Export the keystore used to sign apps", + "exportedKeystore": "Keystore exported", + "noKeystoreExportFileFound": "No keystore to export", + "importKeystoreLabel": "Import keystore", + "importKeystoreHint": "Import a keystore used to sign apps", + "importedKeystore": "Keystore imported", + "selectKeystorePassword": "Keystore password", + "selectKeystorePasswordHint": "Select keystore password used to sign apps", + "jsonSelectorErrorMessage": "Unable to use selected JSON file", + "keystoreSelectorErrorMessage": "Unable to use selected keystore file" + }, + "appInfoView": { + "widgetTitle": "App info", + "openButton": "Open", + "uninstallButton": "Uninstall", + "unpatchButton": "Unpatch", + "rootDialogTitle": "Error", + "unpatchDialogText": "Are you sure you want to unpatch this app?", + "rootDialogText": "App was installed with superuser permissions, but currently ReVanced Manager has no permissions.\nPlease grant superuser permissions first.", + "packageNameLabel": "Package name", + "installTypeLabel": "Installation type", + "rootTypeLabel": "Root", + "nonRootTypeLabel": "Non-root", + "patchedDateLabel": "Patched date", + "appliedPatchesLabel": "Applied patches", + "patchedDateHint": "${date} at ${time}", + "appliedPatchesHint": "${quantity} applied patches", + "updateNotImplemented": "This feature has not been implemented yet" + }, + "contributorsView": { + "widgetTitle": "Contributors", + "patcherContributors": "Patcher contributors", + "patchesContributors": "Patches contributors", + "integrationsContributors": "Integrations contributors", + "cliContributors": "CLI contributors", + "managerContributors": "Manager contributors" + } +} diff --git a/docs/4_building.md b/docs/4_building.md index b3904c5053..f7861c408b 100644 --- a/docs/4_building.md +++ b/docs/4_building.md @@ -9,13 +9,20 @@ This page will guide you through building ReVanced Manager from source. ```sh git clone https://github.com/revanced/revanced-manager.git && cd revanced-manager ``` + 3. Get dependencies ```sh flutter pub get ``` -4. Delete conflicting outputs +4. Generate translation file + + ```sh + dart run slang + ``` + +5. Delete conflicting outputs ```sh flutter packages pub run build_runner build --delete-conflicting-outputs @@ -24,7 +31,7 @@ This page will guide you through building ReVanced Manager from source. > [!Note] > Must be run every time you sync your local repository with the remote repository. -5. Build the APK +6. Build the APK ```sh flutter build apk diff --git a/lib/main.dart b/lib/main.dart index c81701bae2..6b8a661635 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,6 @@ -import 'dart:developer'; - import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/download_manager.dart'; import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/manager_api.dart'; @@ -18,6 +15,7 @@ Future main() async { await setupLocator(); WidgetsFlutterBinding.ensureInitialized(); await locator().initialize(); + await locator().initialize(); final String apiUrl = locator().getApiUrl(); await locator().initialize(apiUrl); @@ -26,7 +24,11 @@ Future main() async { tz.initializeTimeZones(); prefs = await SharedPreferences.getInstance(); - runApp(const MyApp()); + final managerAPI = locator(); + final locale = managerAPI.getLocale(); + LocaleSettings.setLocaleRaw(locale); + + runApp(TranslationProvider(child: const MyApp())); } class MyApp extends StatelessWidget { @@ -34,32 +36,9 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - // String rawLocale = prefs.getString('language') ?? 'en_US'; - // String replaceLocale = rawLocale.replaceAll('_', '-'); - // List localeList = replaceLocale.split('-'); - // Locale locale = Locale(localeList[0], localeList[1]); - const Locale locale = Locale('en', 'US'); - - return DynamicThemeBuilder( + return const DynamicThemeBuilder( title: 'ReVanced Manager', - home: const NavigationView(), - localizationsDelegates: [ - FlutterI18nDelegate( - translationLoader: FileTranslationLoader( - fallbackFile: 'en_US', - forcedLocale: locale, - basePath: 'assets/i18n', - useCountryCode: true, - ), - missingTranslationHandler: (key, locale) { - log( - '--> Missing translation: key: $key, languageCode: ${locale?.languageCode}', - ); - }, - ), - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - ], + home: NavigationView(), ); } } diff --git a/lib/services/download_manager.dart b/lib/services/download_manager.dart index 4c0919b984..caa705d7e9 100644 --- a/lib/services/download_manager.dart +++ b/lib/services/download_manager.dart @@ -19,7 +19,8 @@ class DownloadManager { ); Future initialize() async { - _userAgent = 'ReVanced-Manager/${await _managerAPI.getCurrentManagerVersion()}'; + _userAgent = + 'ReVanced-Manager/${await _managerAPI.getCurrentManagerVersion()}'; } Dio initDio(String url) { @@ -72,4 +73,3 @@ class DownloadManager { ); } } - diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 7a9e091d56..e15e3d9d5b 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -4,11 +4,11 @@ import 'package:device_apps/device_apps.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:injectable/injectable.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:path_provider/path_provider.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/github_api.dart'; @@ -62,7 +62,8 @@ class ManagerAPI { Future initialize() async { _prefs = await SharedPreferences.getInstance(); isRooted = await _rootAPI.isRooted(); - isDynamicThemeAvailable = (await getSdkVersion()) >= 31; // ANDROID_12_SDK_VERSION = 31 + isDynamicThemeAvailable = + (await getSdkVersion()) >= 31; // ANDROID_12_SDK_VERSION = 31 storedPatchesFile = (await getApplicationDocumentsDirectory()).path + storedPatchesFile; } @@ -276,6 +277,14 @@ class ManagerAPI { return _prefs.getString('keystorePassword') ?? defaultKeystorePassword; } + String getLocale() { + return _prefs.getString('locale') ?? 'en'; + } + + Future setLocale(String value) async { + await _prefs.setString('locale', value); + } + Future deleteTempFolder() async { final Directory dir = Directory('/data/local/tmp/revanced-manager'); if (await dir.exists()) { @@ -586,7 +595,7 @@ class ManagerAPI { onWillPop: () async => false, child: AlertDialog( backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - title: I18nText('warning'), + title: Text(t.warning), content: ValueListenableBuilder( valueListenable: noShow, builder: (context, value, child) { @@ -594,22 +603,19 @@ class ManagerAPI { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - I18nText( - 'patchItem.patchesChangeWarningDialogText', - child: const Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), + Text( + t.patchItem.patchesChangeWarningDialogText, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), CheckboxListTile( value: value, contentPadding: EdgeInsets.zero, - title: I18nText( - 'noShowAgain', + title: Text( + t.noShowAgain, ), onChanged: (selected) { noShow.value = selected!; @@ -621,7 +627,7 @@ class ManagerAPI { ), actions: [ CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () { setPatchesChangeWarning(noShow.value); Navigator.of(context).pop(); diff --git a/lib/services/toast.dart b/lib/services/toast.dart index cb9a62b705..e49d517632 100644 --- a/lib/services/toast.dart +++ b/lib/services/toast.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:fluttertoast/fluttertoast.dart' as t; class Toast { @@ -12,10 +11,7 @@ class Toast { void show(String text) { t.Fluttertoast.showToast( - msg: FlutterI18n.translate( - _fToast.context!, - text, - ), + msg: text, toastLength: t.Toast.LENGTH_LONG, gravity: t.ToastGravity.CENTER, ); @@ -23,10 +19,7 @@ class Toast { void showBottom(String text) { t.Fluttertoast.showToast( - msg: FlutterI18n.translate( - _fToast.context!, - text, - ), + msg: text, toastLength: t.Toast.LENGTH_LONG, gravity: t.ToastGravity.BOTTOM, ); diff --git a/lib/ui/theme/dynamic_theme_builder.dart b/lib/ui/theme/dynamic_theme_builder.dart index 233c78b562..a8934f8645 100644 --- a/lib/ui/theme/dynamic_theme_builder.dart +++ b/lib/ui/theme/dynamic_theme_builder.dart @@ -3,9 +3,11 @@ import 'package:dynamic_color/dynamic_color.dart'; import 'package:dynamic_themes/dynamic_themes.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.router.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/theme.dart'; import 'package:stacked_services/stacked_services.dart'; @@ -15,17 +17,16 @@ class DynamicThemeBuilder extends StatefulWidget { Key? key, required this.title, required this.home, - required this.localizationsDelegates, }) : super(key: key); final String title; final Widget home; - final Iterable localizationsDelegates; @override State createState() => _DynamicThemeBuilderState(); } -class _DynamicThemeBuilderState extends State with WidgetsBindingObserver { +class _DynamicThemeBuilderState extends State + with WidgetsBindingObserver { Brightness brightness = PlatformDispatcher.instance.platformBrightness; final ManagerAPI _managerAPI = locator(); @@ -43,8 +44,9 @@ class _DynamicThemeBuilderState extends State with WidgetsB if (_managerAPI.getThemeMode() < 2) { SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( - systemNavigationBarIconBrightness: - brightness == Brightness.light ? Brightness.dark : Brightness.light, + systemNavigationBarIconBrightness: brightness == Brightness.light + ? Brightness.dark + : Brightness.light, ), ); } @@ -83,24 +85,33 @@ class _DynamicThemeBuilderState extends State with WidgetsB return DynamicTheme( themeCollection: ThemeCollection( themes: { - 0: brightness == Brightness.light ? lightCustomTheme : darkCustomTheme, - 1: brightness == Brightness.light ? lightDynamicTheme : darkDynamicTheme, + 0: brightness == Brightness.light + ? lightCustomTheme + : darkCustomTheme, + 1: brightness == Brightness.light + ? lightDynamicTheme + : darkDynamicTheme, 2: lightCustomTheme, 3: lightDynamicTheme, 4: darkCustomTheme, 5: darkDynamicTheme, }, - fallbackTheme: PlatformDispatcher.instance.platformBrightness == Brightness.light ? lightCustomTheme : darkCustomTheme, + fallbackTheme: PlatformDispatcher.instance.platformBrightness == + Brightness.light + ? lightCustomTheme + : darkCustomTheme, ), builder: (context, theme) => MaterialApp( - debugShowCheckedModeBanner: false, - title: widget.title, - navigatorKey: StackedService.navigatorKey, - onGenerateRoute: StackedRouter().onGenerateRoute, - theme: theme, - home: widget.home, - localizationsDelegates: widget.localizationsDelegates, - ), + debugShowCheckedModeBanner: false, + title: widget.title, + navigatorKey: StackedService.navigatorKey, + onGenerateRoute: StackedRouter().onGenerateRoute, + theme: theme, + home: widget.home, + localizationsDelegates: GlobalMaterialLocalizations.delegates, + locale: TranslationProvider.of(context).flutterLocale, + supportedLocales: AppLocaleUtils.supportedLocales, + ), ); }, ); diff --git a/lib/ui/views/app_selector/app_selector_view.dart b/lib/ui/views/app_selector/app_selector_view.dart index 3d1d92ca93..a5712d6e19 100644 --- a/lib/ui/views/app_selector/app_selector_view.dart +++ b/lib/ui/views/app_selector/app_selector_view.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart' hide SearchBar; -import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/app_selector/app_selector_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/appSelectorView/app_skeleton_loader.dart'; import 'package:revanced_manager/ui/widgets/appSelectorView/installed_app_item.dart'; @@ -24,7 +24,7 @@ class _AppSelectorViewState extends State { viewModelBuilder: () => AppSelectorViewModel(), builder: (context, model, child) => Scaffold( floatingActionButton: FloatingActionButton.extended( - label: I18nText('appSelectorView.storageButton'), + label: Text(t.appSelectorView.storageButton), icon: const Icon(Icons.sd_storage), onPressed: () { model.selectAppFromStorage(context); @@ -35,13 +35,13 @@ class _AppSelectorViewState extends State { SliverAppBar( pinned: true, floating: true, - title: I18nText( - 'appSelectorView.viewTitle', + title: Text( + t.appSelectorView.viewTitle, ), titleTextStyle: TextStyle( fontSize: 22.0, - color: Theme.of(context).textTheme.titleLarge!.color, - ), + color: Theme.of(context).textTheme.titleLarge!.color, + ), leading: IconButton( icon: Icon( Icons.arrow_back, @@ -57,10 +57,7 @@ class _AppSelectorViewState extends State { horizontal: 12.0, ), child: SearchBar( - hintText: FlutterI18n.translate( - context, - 'appSelectorView.searchBarHint', - ), + hintText: t.appSelectorView.searchBarHint, onQueryChanged: (searchQuery) { setState(() { _query = searchQuery; @@ -73,14 +70,10 @@ class _AppSelectorViewState extends State { SliverToBoxAdapter( child: model.noApps ? Center( - child: I18nText( - 'appSelectorCard.noAppsLabel', - child: Text( - '', - style: TextStyle( - color: - Theme.of(context).textTheme.titleLarge!.color, - ), + child: Text( + t.appSelectorCard.noAppsLabel, + style: TextStyle( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), ) diff --git a/lib/ui/views/app_selector/app_selector_viewmodel.dart b/lib/ui/views/app_selector/app_selector_viewmodel.dart index 00a094dd32..07e84b84b0 100644 --- a/lib/ui/views/app_selector/app_selector_viewmodel.dart +++ b/lib/ui/views/app_selector/app_selector_viewmodel.dart @@ -4,8 +4,8 @@ import 'package:device_apps/device_apps.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_file_dialog/flutter_file_dialog.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; @@ -141,24 +141,21 @@ class AppSelectorViewModel extends BaseViewModel { context: context, builder: (context) => AlertDialog( backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - title: I18nText('warning'), - content: I18nText( - 'appSelectorView.requireSuggestedAppVersionDialogText', - translationParams: { - 'suggested': suggestedVersion, - 'selected': selectedVersion, - }, - child: const Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), + title: Text(t.warning), + content: Text( + t.appSelectorView.requireSuggestedAppVersionDialogText( + suggested: suggestedVersion, + selected: selectedVersion, + ), + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, ), + ), actions: [ CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => Navigator.of(context).pop(), ), ], @@ -181,26 +178,20 @@ class AppSelectorViewModel extends BaseViewModel { color: Theme.of(context).colorScheme.primary, ), const SizedBox(height: 20), - I18nText( - 'appSelectorView.featureNotAvailable', - child: const Text( - '', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w600, - wordSpacing: 1.5, - ), + Text( + t.appSelectorView.featureNotAvailable, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + wordSpacing: 1.5, ), ), const SizedBox(height: 20), - I18nText( - 'appSelectorView.featureNotAvailableText', - child: const Text( - '', - style: TextStyle( - fontSize: 14, - ), + Text( + t.appSelectorView.featureNotAvailableText, + style: const TextStyle( + fontSize: 14, ), ), const SizedBox(height: 30), @@ -214,7 +205,7 @@ class AppSelectorViewModel extends BaseViewModel { children: [ const Icon(Icons.sd_card), const SizedBox(width: 10), - I18nText('appSelectorView.selectFromStorageButton'), + Text(t.appSelectorView.selectFromStorageButton), ], ), ), @@ -228,7 +219,7 @@ class AppSelectorViewModel extends BaseViewModel { mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox(width: 10), - I18nText('cancelButton'), + Text(t.cancelButton), ], ), ), @@ -269,7 +260,7 @@ class AppSelectorViewModel extends BaseViewModel { if (kDebugMode) { print(e); } - _toast.showBottom('appSelectorView.errorMessage'); + _toast.showBottom(t.appSelectorView.errorMessage); } } @@ -297,5 +288,5 @@ class AppSelectorViewModel extends BaseViewModel { } void showDownloadToast() => - _toast.showBottom('appSelectorView.downloadToast'); + _toast.showBottom(t.appSelectorView.downloadToast); } diff --git a/lib/ui/views/contributors/contributors_view.dart b/lib/ui/views/contributors/contributors_view.dart index a409c17ecd..8d3dc7a957 100644 --- a/lib/ui/views/contributors/contributors_view.dart +++ b/lib/ui/views/contributors/contributors_view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/contributors/contributors_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/contributorsView/contributors_card.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart'; @@ -18,13 +18,10 @@ class ContributorsView extends StatelessWidget { body: CustomScrollView( slivers: [ CustomSliverAppBar( - title: I18nText( - 'contributorsView.widgetTitle', - child: Text( - '', - style: GoogleFonts.inter( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + title: Text( + t.contributorsView.widgetTitle, + style: GoogleFonts.inter( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), ), @@ -34,27 +31,27 @@ class ContributorsView extends StatelessWidget { delegate: SliverChildListDelegate.fixed( [ ContributorsCard( - title: 'contributorsView.patcherContributors', + title: t.contributorsView.patcherContributors, contributors: model.patcherContributors, ), const SizedBox(height: 20), ContributorsCard( - title: 'contributorsView.patchesContributors', + title: t.contributorsView.patchesContributors, contributors: model.patchesContributors, ), const SizedBox(height: 20), ContributorsCard( - title: 'contributorsView.integrationsContributors', + title: t.contributorsView.integrationsContributors, contributors: model.integrationsContributors, ), const SizedBox(height: 20), ContributorsCard( - title: 'contributorsView.cliContributors', + title: t.contributorsView.cliContributors, contributors: model.cliContributors, ), const SizedBox(height: 20), ContributorsCard( - title: 'contributorsView.managerContributors', + title: t.contributorsView.managerContributors, contributors: model.managerContributors, ), SizedBox(height: MediaQuery.viewPaddingOf(context).bottom), diff --git a/lib/ui/views/home/home_view.dart b/lib/ui/views/home/home_view.dart index 06ed6e9f28..3a803e9fa0 100644 --- a/lib/ui/views/home/home_view.dart +++ b/lib/ui/views/home/home_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/homeView/installed_apps_card.dart'; import 'package:revanced_manager/ui/widgets/homeView/latest_commit_card.dart'; @@ -25,13 +25,10 @@ class HomeView extends StatelessWidget { slivers: [ CustomSliverAppBar( isMainView: true, - title: I18nText( - 'homeView.widgetTitle', - child: Text( - '', - style: GoogleFonts.inter( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + title: Text( + t.homeView.widgetTitle, + style: GoogleFonts.inter( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), ), @@ -40,22 +37,16 @@ class HomeView extends StatelessWidget { sliver: SliverList( delegate: SliverChildListDelegate.fixed( [ - I18nText( - 'homeView.updatesSubtitle', - child: Text( - '', - style: Theme.of(context).textTheme.titleLarge, - ), + Text( + t.homeView.updatesSubtitle, + style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 10), LatestCommitCard(model: model, parentContext: context), const SizedBox(height: 23), - I18nText( - 'homeView.patchedSubtitle', - child: Text( - '', - style: Theme.of(context).textTheme.titleLarge, - ), + Text( + t.homeView.patchedSubtitle, + style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 10), InstalledAppsCard(), diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index b85e49da1c..42b08f2e3a 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -1,17 +1,18 @@ // ignore_for_file: use_build_context_synchronously import 'dart:async'; import 'dart:io'; + import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:injectable/injectable.dart'; import 'package:install_plugin/install_plugin.dart'; import 'package:path_provider/path_provider.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.router.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/manager_api.dart'; @@ -51,12 +52,12 @@ class HomeViewModel extends BaseViewModel { ), onDidReceiveNotificationResponse: (response) async { if (response.id == 0) { - _toast.showBottom('homeView.installingMessage'); + _toast.showBottom(t.homeView.installingMessage); final File? managerApk = await _managerAPI.downloadManager(); if (managerApk != null) { await InstallPlugin.installApk(managerApk.path); } else { - _toast.showBottom('homeView.errorDownloadMessage'); + _toast.showBottom(t.homeView.errorDownloadMessage); } } }, @@ -65,20 +66,20 @@ class HomeViewModel extends BaseViewModel { .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.requestNotificationsPermission(); - final bool isConnected = await Connectivity().checkConnectivity() != - ConnectivityResult.none; + final bool isConnected = + await Connectivity().checkConnectivity() != ConnectivityResult.none; if (!isConnected) { - _toast.showBottom('homeView.noConnection'); + _toast.showBottom(t.homeView.noConnection); } final NotificationAppLaunchDetails? notificationAppLaunchDetails = await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) { - _toast.showBottom('homeView.installingMessage'); + _toast.showBottom(t.homeView.installingMessage); final File? managerApk = await _managerAPI.downloadManager(); if (managerApk != null) { await InstallPlugin.installApk(managerApk.path); } else { - _toast.showBottom('homeView.errorDownloadMessage'); + _toast.showBottom(t.homeView.errorDownloadMessage); } } @@ -177,42 +178,35 @@ class HomeViewModel extends BaseViewModel { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - I18nText( - 'homeView.patchesConsentDialogText', - child: Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.secondary, - ), + Text( + t.homeView.patchesConsentDialogText, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.secondary, ), ), Padding( padding: const EdgeInsets.symmetric(vertical: 10), - child: I18nText( - 'homeView.patchesConsentDialogText2', - translationParams: { - 'url': _managerAPI.defaultApiUrl.split('/')[2], - }, - child: Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.error, - ), + child: Text( + t.homeView.patchesConsentDialogText2( + url: _managerAPI.defaultApiUrl.split('/')[2], + ), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.error, ), ), ), CheckboxListTile( value: value, contentPadding: EdgeInsets.zero, - title: I18nText( - 'homeView.patchesConsentDialogText3', + title: Text( + t.homeView.patchesConsentDialogText3, ), - subtitle: I18nText( - 'homeView.patchesConsentDialogText3Sub', + subtitle: Text( + t.homeView.patchesConsentDialogText3Sub, ), onChanged: (selected) { autoUpdate.value = selected!; @@ -229,7 +223,7 @@ class HomeViewModel extends BaseViewModel { await _managerAPI.setPatchesConsent(false); SystemNavigator.pop(); }, - label: I18nText('quitButton'), + label: Text(t.quitButton), ), CustomMaterialButton( onPressed: () async { @@ -237,7 +231,7 @@ class HomeViewModel extends BaseViewModel { await _managerAPI.setPatchesAutoUpdate(autoUpdate.value); Navigator.of(context).pop(); }, - label: I18nText('okButton'), + label: Text(t.okButton), ), ], ), @@ -245,7 +239,7 @@ class HomeViewModel extends BaseViewModel { } Future updatePatches(BuildContext context) async { - _toast.showBottom('homeView.downloadingMessage'); + _toast.showBottom(t.homeView.downloadingMessage); final String patchesVersion = await _managerAPI.getLatestPatchesVersion() ?? '0.0.0'; final String integrationsVersion = @@ -253,17 +247,17 @@ class HomeViewModel extends BaseViewModel { if (patchesVersion != '0.0.0' && integrationsVersion != '0.0.0') { await _managerAPI.setCurrentPatchesVersion(patchesVersion); await _managerAPI.setCurrentIntegrationsVersion(integrationsVersion); - _toast.showBottom('homeView.downloadedMessage'); + _toast.showBottom(t.homeView.downloadedMessage); forceRefresh(context); } else { - _toast.showBottom('homeView.errorDownloadMessage'); + _toast.showBottom(t.homeView.errorDownloadMessage); } } Future updateManager(BuildContext context) async { final ValueNotifier downloaded = ValueNotifier(false); try { - _toast.showBottom('homeView.downloadingMessage'); + _toast.showBottom(t.homeView.downloadingMessage); showDialog( context: context, builder: (context) => ValueListenableBuilder( @@ -271,17 +265,14 @@ class HomeViewModel extends BaseViewModel { builder: (context, value, child) { return SimpleDialog( contentPadding: const EdgeInsets.all(16.0), - title: I18nText( + title: Text( !value - ? 'homeView.downloadingMessage' - : 'homeView.downloadedMessage', - child: Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.secondary, - ), + ? t.homeView.downloadingMessage + : t.homeView.downloadedMessage, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.secondary, ), ), children: [ @@ -325,7 +316,7 @@ class HomeViewModel extends BaseViewModel { Align( alignment: Alignment.centerRight, child: CustomMaterialButton( - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () { _revancedAPI.disposeManagerUpdateProgress(); Navigator.of(context).pop(); @@ -338,15 +329,12 @@ class HomeViewModel extends BaseViewModel { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - I18nText( - 'homeView.installUpdate', - child: Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.secondary, - ), + Text( + t.homeView.installUpdate, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.secondary, ), ), const SizedBox(height: 16.0), @@ -357,7 +345,7 @@ class HomeViewModel extends BaseViewModel { alignment: Alignment.centerRight, child: CustomMaterialButton( isFilled: false, - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () { Navigator.of(context).pop(); }, @@ -367,7 +355,7 @@ class HomeViewModel extends BaseViewModel { Align( alignment: Alignment.centerRight, child: CustomMaterialButton( - label: I18nText('updateButton'), + label: Text(t.updateButton), onPressed: () async { await InstallPlugin.installApk( downloadedApk!.path, @@ -414,21 +402,21 @@ class HomeViewModel extends BaseViewModel { // uiLocalNotificationDateInterpretation: // UILocalNotificationDateInterpretation.absoluteTime, // ); - _toast.showBottom('homeView.installingMessage'); + _toast.showBottom(t.homeView.installingMessage); await InstallPlugin.installApk(managerApk.path); } else { - _toast.showBottom('homeView.errorDownloadMessage'); + _toast.showBottom(t.homeView.errorDownloadMessage); } } on Exception catch (e) { if (kDebugMode) { print(e); } - _toast.showBottom('homeView.errorInstallMessage'); + _toast.showBottom(t.homeView.errorInstallMessage); } } void updatesAreDisabled() { - _toast.showBottom('homeView.updatesDisabled'); + _toast.showBottom(t.homeView.updatesDisabled); } Future showUpdateConfirmationDialog( @@ -465,7 +453,7 @@ class HomeViewModel extends BaseViewModel { Future forceRefresh(BuildContext context) async { _managerAPI.clearAllData(); - _toast.showBottom('homeView.refreshSuccess'); + _toast.showBottom(t.homeView.refreshSuccess); initialize(context); } } diff --git a/lib/ui/views/installer/installer_view.dart b/lib/ui/views/installer/installer_view.dart index 4093258e5f..fd23e6b1f0 100644 --- a/lib/ui/views/installer/installer_view.dart +++ b/lib/ui/views/installer/installer_view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/installer/installer_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/installerView/gradient_progress_indicator.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; @@ -23,10 +23,10 @@ class InstallerView extends StatelessWidget { floatingActionButton: Visibility( visible: !model.isPatching && !model.hasErrors, child: FloatingActionButton.extended( - label: I18nText( + label: Text( model.isInstalled - ? 'installerView.openButton' - : 'installerView.installButton', + ? t.installerView.openButton + : t.installerView.installButton, ), icon: model.isInstalled ? const Icon(Icons.open_in_new) @@ -51,19 +51,13 @@ class InstallerView extends StatelessWidget { Visibility( visible: !model.hasErrors, child: IconButton.filledTonal( - tooltip: FlutterI18n.translate( - context, - 'installerView.exportApkButtonTooltip', - ), + tooltip: t.installerView.exportApkButtonTooltip, icon: const Icon(Icons.save), onPressed: () => model.onButtonPressed(0), ), ), IconButton.filledTonal( - tooltip: FlutterI18n.translate( - context, - 'installerView.exportLogButtonTooltip', - ), + tooltip: t.installerView.exportLogButtonTooltip, icon: const Icon(Icons.post_add), onPressed: () => model.onButtonPressed(1), ), diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index 39a59db4f8..1e84acd647 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -4,9 +4,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_background/flutter_background.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; @@ -49,14 +49,8 @@ class InstallerViewModel extends BaseViewModel { try { FlutterBackground.initialize( androidConfig: FlutterBackgroundAndroidConfig( - notificationTitle: FlutterI18n.translate( - context, - 'installerView.notificationTitle', - ), - notificationText: FlutterI18n.translate( - context, - 'installerView.notificationText', - ), + notificationTitle: t.installerView.notificationTitle, + notificationText: t.installerView.notificationText, notificationIcon: const AndroidResource( name: 'ic_notification', ), @@ -198,7 +192,6 @@ class InstallerViewModel extends BaseViewModel { 'Android version: ${info['androidVersion']}', 'Supported architectures: ${info['supportedArch'].join(", ")}', 'Root permissions: ${isRooted ? 'Yes' : 'No'}', - '\n- Patch Info', 'App: ${_app.packageName} v${_app.version}', 'Patches version: ${_managerAPI.patchesVersion}', @@ -210,37 +203,36 @@ class InstallerViewModel extends BaseViewModel { 'Show universal patches: ${_managerAPI.areUniversalPatchesEnabled()}', 'Patches source: ${_managerAPI.getPatchesRepo()}', 'Integration source: ${_managerAPI.getIntegrationsRepo()}', - '\n- Logs', logs, ]; Clipboard.setData(ClipboardData(text: formattedLogs.join('\n'))); - _toast.showBottom('installerView.copiedToClipboard'); + _toast.showBottom(t.installerView.copiedToClipboard); } Future screenshotDetected(BuildContext context) async { await showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText( - 'warning', + title: Text( + t.warning, ), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, icon: const Icon(Icons.warning), content: SingleChildScrollView( - child: I18nText('installerView.screenshotDetected'), + child: Text(t.installerView.screenshotDetected), ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () { Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { copyLogs(); showPopupScreenshotWarning = true; @@ -259,8 +251,8 @@ class InstallerViewModel extends BaseViewModel { context: context, barrierDismissible: false, builder: (context) => AlertDialog( - title: I18nText( - 'installerView.installType', + title: Text( + t.installerView.installType, ), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, icon: const Icon(Icons.file_download_outlined), @@ -278,20 +270,17 @@ class InstallerViewModel extends BaseViewModel { horizontal: 20, vertical: 10, ), - child: I18nText( - 'installerView.installTypeDescription', - child: Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.secondary, - ), + child: Text( + t.installerView.installTypeDescription, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.secondary, ), ), ), RadioListTile( - title: I18nText('installerView.installNonRootType'), + title: Text(t.installerView.installNonRootType), contentPadding: const EdgeInsets.symmetric(horizontal: 16), value: 0, @@ -301,7 +290,7 @@ class InstallerViewModel extends BaseViewModel { }, ), RadioListTile( - title: I18nText('installerView.installRootType'), + title: Text(t.installerView.installRootType), contentPadding: const EdgeInsets.symmetric(horizontal: 16), value: 1, @@ -317,14 +306,14 @@ class InstallerViewModel extends BaseViewModel { ), actions: [ CustomMaterialButton( - label: I18nText('cancelButton'), + label: Text(t.cancelButton), isFilled: false, onPressed: () { Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('installerView.installButton'), + label: Text(t.installerView.installButton), onPressed: () { Navigator.of(context).pop(); installResult(context, installType.value == 1); @@ -431,11 +420,11 @@ class InstallerViewModel extends BaseViewModel { if (isPatching) { if (!cancel) { cancel = true; - _toast.showBottom('installerView.pressBackAgain'); + _toast.showBottom(t.installerView.pressBackAgain); } else if (!isCanceled) { await stopPatcher(); } else { - _toast.showBottom('installerView.noExit'); + _toast.showBottom(t.installerView.noExit); } return false; } diff --git a/lib/ui/views/navigation/navigation_view.dart b/lib/ui/views/navigation/navigation_view.dart index 7089d06908..0c30476618 100644 --- a/lib/ui/views/navigation/navigation_view.dart +++ b/lib/ui/views/navigation/navigation_view.dart @@ -1,7 +1,7 @@ import 'package:animations/animations.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart'; import 'package:stacked/stacked.dart'; @@ -47,30 +47,21 @@ class NavigationView extends StatelessWidget { icon: model.isIndexSelected(0) ? const Icon(Icons.dashboard) : const Icon(Icons.dashboard_outlined), - label: FlutterI18n.translate( - context, - 'navigationView.dashboardTab', - ), + label: t.navigationView.dashboardTab, tooltip: '', ), NavigationDestination( icon: model.isIndexSelected(1) ? const Icon(Icons.build) : const Icon(Icons.build_outlined), - label: FlutterI18n.translate( - context, - 'navigationView.patcherTab', - ), + label: t.navigationView.patcherTab, tooltip: '', ), NavigationDestination( icon: model.isIndexSelected(2) ? const Icon(Icons.settings) : const Icon(Icons.settings_outlined), - label: FlutterI18n.translate( - context, - 'navigationView.settingsTab', - ), + label: t.navigationView.settingsTab, tooltip: '', ), ], diff --git a/lib/ui/views/patch_options/patch_options_view.dart b/lib/ui/views/patch_options/patch_options_view.dart index e35b849da3..5cad890daa 100644 --- a/lib/ui/views/patch_options/patch_options_view.dart +++ b/lib/ui/views/patch_options/patch_options_view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/ui/views/patch_options/patch_options_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/patchesSelectorView/patch_options_fields.dart'; @@ -25,19 +25,16 @@ class PatchOptionsView extends StatelessWidget { Navigator.pop(context); } }, - label: I18nText('patchOptionsView.saveOptions'), + label: Text(t.patchOptionsView.saveOptions), icon: const Icon(Icons.save), ), body: CustomScrollView( slivers: [ SliverAppBar( - title: I18nText( - 'patchOptionsView.viewTitle', - child: Text( - '', - style: GoogleFonts.inter( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + title: Text( + t.patchOptionsView.viewTitle, + style: GoogleFonts.inter( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), actions: [ @@ -48,10 +45,7 @@ class PatchOptionsView extends StatelessWidget { icon: const Icon( Icons.history, ), - tooltip: FlutterI18n.translate( - context, - 'patchOptionsView.resetOptionsTooltip', - ), + tooltip: t.patchOptionsView.resetOptionsTooltip, ), ], ), @@ -82,8 +76,7 @@ class PatchOptionsView extends StatelessWidget { model.modifyOptions(value, option); }, ) - else if (option.valueType == - 'StringArray' || + else if (option.valueType == 'StringArray' || option.valueType == 'IntArray' || option.valueType == 'LongArray') IntStringLongListPatchOption( @@ -112,7 +105,7 @@ class PatchOptionsView extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.add), - I18nText('patchOptionsView.addOptions'), + Text(t.patchOptionsView.addOptions), ], ), ), diff --git a/lib/ui/views/patch_options/patch_options_viewmodel.dart b/lib/ui/views/patch_options/patch_options_viewmodel.dart index c1da79920b..df27389d6b 100644 --- a/lib/ui/views/patch_options/patch_options_viewmodel.dart +++ b/lib/ui/views/patch_options/patch_options_viewmodel.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; @@ -141,8 +141,8 @@ class PatchOptionsViewModel extends BaseViewModel { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - I18nText( - 'patchOptionsView.addOptions', + Text( + t.patchOptionsView.addOptions, ), Text( '', @@ -155,7 +155,7 @@ class PatchOptionsViewModel extends BaseViewModel { ), actions: [ CustomMaterialButton( - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () { Navigator.of(context).pop(); }, @@ -228,12 +228,12 @@ Future showRequiredOptionNullDialog( context: context, builder: (context) => AlertDialog( backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - title: I18nText('notice'), + title: Text(t.notice), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText( - 'patchOptionsView.deselectPatch', + label: Text( + t.patchOptionsView.deselectPatch, ), onPressed: () async { if (managerAPI.isPatchesChangeEnabled()) { @@ -258,17 +258,16 @@ Future showRequiredOptionNullDialog( }, ), CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () { Navigator.of(context).pop(); }, ), ], - content: I18nText( - 'patchOptionsView.requiredOptionNull', - translationParams: { - 'options': optionsTitles.join('\n'), - }, + content: Text( + t.patchOptionsView.requiredOptionNull( + options: optionsTitles.join('\n'), + ), ), ), ); diff --git a/lib/ui/views/patcher/patcher_view.dart b/lib/ui/views/patcher/patcher_view.dart index c15a69439c..5faaab6db6 100644 --- a/lib/ui/views/patcher/patcher_view.dart +++ b/lib/ui/views/patcher/patcher_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/patcherView/app_selector_card.dart'; import 'package:revanced_manager/ui/widgets/patcherView/patch_selector_card.dart'; @@ -20,9 +20,9 @@ class PatcherView extends StatelessWidget { floatingActionButton: Visibility( visible: model.showPatchButton(), child: FloatingActionButton.extended( - label: I18nText('patcherView.patchButton'), + label: Text(t.patcherView.patchButton), icon: const Icon(Icons.build), - onPressed: () async{ + onPressed: () async { if (model.checkRequiredPatchOption(context)) { final bool proceed = model.showRemovedPatchesDialog(context); if (proceed && context.mounted) { @@ -36,13 +36,10 @@ class PatcherView extends StatelessWidget { slivers: [ CustomSliverAppBar( isMainView: true, - title: I18nText( - 'patcherView.widgetTitle', - child: Text( - '', - style: GoogleFonts.inter( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + title: Text( + t.patcherView.widgetTitle, + style: GoogleFonts.inter( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), ), diff --git a/lib/ui/views/patcher/patcher_viewmodel.dart b/lib/ui/views/patcher/patcher_viewmodel.dart index 95244c6d81..62bfdcbb34 100644 --- a/lib/ui/views/patcher/patcher_viewmodel.dart +++ b/lib/ui/views/patcher/patcher_viewmodel.dart @@ -1,10 +1,10 @@ // ignore_for_file: use_build_context_synchronously import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:injectable/injectable.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.router.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; @@ -50,22 +50,23 @@ class PatcherViewModel extends BaseViewModel { showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('notice'), + title: Text(t.notice), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText( - 'patcherView.removedPatchesWarningDialogText', - translationParams: {'patches': removedPatches.join('\n')}, + content: Text( + t.patcherView.removedPatchesWarningDialogText( + patches: removedPatches.join('\n'), + ), ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () { Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { Navigator.of(context).pop(); showArmv7WarningDialog(context); @@ -92,19 +93,19 @@ class PatcherViewModel extends BaseViewModel { showDialog( context: context ?? ctx, builder: (context) => AlertDialog( - title: I18nText('notice'), + title: Text(t.notice), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('patcherView.requiredOptionDialogText'), + content: Text(t.patcherView.requiredOptionDialogText), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () => { Navigator.of(context).pop(), }, ), CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => { Navigator.pop(context), navigateToPatchesSelector(), @@ -125,16 +126,16 @@ class PatcherViewModel extends BaseViewModel { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('warning'), + title: Text(t.warning), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('patcherView.armv7WarningDialogText'), + content: Text(t.patcherView.armv7WarningDialogText), actions: [ CustomMaterialButton( - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () => Navigator.of(context).pop(), ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), isFilled: false, onPressed: () { Navigator.of(context).pop(); @@ -161,20 +162,11 @@ class PatcherViewModel extends BaseViewModel { String suggestedVersion = _patcherAPI.getSuggestedVersion(selectedApp!.packageName); if (suggestedVersion.isEmpty) { - suggestedVersion = FlutterI18n.translate( - context, - 'appSelectorCard.allVersions', - ); + suggestedVersion = t.appSelectorCard.allVersions; } else { suggestedVersion = 'v$suggestedVersion'; } - return '${FlutterI18n.translate( - context, - 'appSelectorCard.currentVersion', - )}: v${selectedApp!.version}\n${FlutterI18n.translate( - context, - 'appSelectorCard.suggestedVersion', - )}: $suggestedVersion'; + return '${t.appSelectorCard.currentVersion}: v${selectedApp!.version}\n${t.appSelectorCard.suggestedVersion}: $suggestedVersion'; } Future loadLastSelectedPatches() async { @@ -205,7 +197,10 @@ class PatcherViewModel extends BaseViewModel { removedPatches.add('• ${patch.name}'); for (final option in patch.options) { _managerAPI.clearPatchOption( - selectedApp!.packageName, patch.name, option.key); + selectedApp!.packageName, + patch.name, + option.key, + ); } } } diff --git a/lib/ui/views/patches_selector/patches_selector_view.dart b/lib/ui/views/patches_selector/patches_selector_view.dart index eb20cf822b..36ba5d226f 100644 --- a/lib/ui/views/patches_selector/patches_selector_view.dart +++ b/lib/ui/views/patches_selector/patches_selector_view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart' hide SearchBar; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/search_bar.dart'; @@ -39,7 +39,7 @@ class _PatchesSelectorViewState extends State { child: FloatingActionButton.extended( label: Row( children: [ - I18nText('patchesSelectorView.doneButton'), + Text(t.patchesSelectorView.doneButton), Text(' (${model.selectedPatches.length})'), ], ), @@ -57,8 +57,8 @@ class _PatchesSelectorViewState extends State { SliverAppBar( pinned: true, floating: true, - title: I18nText( - 'patchesSelectorView.viewTitle', + title: Text( + t.patchesSelectorView.viewTitle, ), titleTextStyle: TextStyle( fontSize: 22.0, @@ -98,8 +98,8 @@ class _PatchesSelectorViewState extends State { itemBuilder: (BuildContext context) => [ PopupMenuItem( value: 0, - child: I18nText( - 'patchesSelectorView.loadPatchesSelection', + child: Text( + t.patchesSelectorView.loadPatchesSelection, ), ), ], @@ -113,10 +113,7 @@ class _PatchesSelectorViewState extends State { horizontal: 12.0, ), child: SearchBar( - hintText: FlutterI18n.translate( - context, - 'patchesSelectorView.searchBarHint', - ), + hintText: t.patchesSelectorView.searchBarHint, onQueryChanged: (searchQuery) { setState(() { _query = searchQuery; @@ -131,12 +128,9 @@ class _PatchesSelectorViewState extends State { ? Padding( padding: const EdgeInsets.all(8.0), child: Center( - child: I18nText( - 'patchesSelectorView.noPatchesFound', - child: Text( - '', - style: Theme.of(context).textTheme.bodyMedium, - ), + child: Text( + t.patchesSelectorView.noPatchesFound, + style: Theme.of(context).textTheme.bodyMedium, ), ), ) @@ -150,11 +144,8 @@ class _PatchesSelectorViewState extends State { Row( children: [ ActionChip( - label: I18nText('patchesSelectorView.default'), - tooltip: FlutterI18n.translate( - context, - 'patchesSelectorView.defaultTooltip', - ), + label: Text(t.patchesSelectorView.defaultText), + tooltip: t.patchesSelectorView.defaultTooltip, onPressed: () { if (_managerAPI.isPatchesChangeEnabled()) { model.selectDefaultPatches(); @@ -165,11 +156,8 @@ class _PatchesSelectorViewState extends State { ), const SizedBox(width: 8), ActionChip( - label: I18nText('patchesSelectorView.none'), - tooltip: FlutterI18n.translate( - context, - 'patchesSelectorView.noneTooltip', - ), + label: Text(t.patchesSelectorView.none), + tooltip: t.patchesSelectorView.noneTooltip, onPressed: () { if (_managerAPI.isPatchesChangeEnabled()) { model.clearPatches(); @@ -180,11 +168,16 @@ class _PatchesSelectorViewState extends State { ), ], ), - if (model.getQueriedPatches(_query).any((patch) => model.isPatchNew(patch))) + if (model + .getQueriedPatches(_query) + .any((patch) => model.isPatchNew(patch))) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - model.getPatchCategory(context, 'patchesSelectorView.newPatches'), + model.getPatchCategory( + context, + t.patchesSelectorView.newPatches, + ), ...model.getQueriedPatches(_query).map((patch) { if (model.isPatchNew(patch)) { return model.getPatchItem(context, patch); @@ -193,25 +186,35 @@ class _PatchesSelectorViewState extends State { } }), if (model.getQueriedPatches(_query).any((patch) => !model.isPatchNew(patch) && patch.compatiblePackages.isNotEmpty)) - model.getPatchCategory(context, 'patchesSelectorView.patches'), + model.getPatchCategory( + context, + t.patchesSelectorView.patches, + ), ], ), ...model.getQueriedPatches(_query).map( (patch) { - if (patch.compatiblePackages.isNotEmpty && !model.isPatchNew(patch)) { + if (patch.compatiblePackages.isNotEmpty && + !model.isPatchNew(patch)) { return model.getPatchItem(context, patch); } else { return Container(); } }, ), - if (model.getQueriedPatches(_query).any((patch) => patch.compatiblePackages.isEmpty)) + if (model + .getQueriedPatches(_query) + .any((patch) => patch.compatiblePackages.isEmpty)) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - model.getPatchCategory(context, 'patchesSelectorView.universalPatches'), + model.getPatchCategory( + context, + t.patchesSelectorView.universalPatches, + ), ...model.getQueriedPatches(_query).map((patch) { - if (patch.compatiblePackages.isEmpty && !model.isPatchNew(patch)) { + if (patch.compatiblePackages.isEmpty && + !model.isPatchNew(patch)) { return model.getPatchItem(context, patch); } else { return Container(); diff --git a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart index 173c1f5376..361e49e41a 100644 --- a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart +++ b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart @@ -1,8 +1,8 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.router.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; @@ -91,17 +91,16 @@ class PatchesSelectorViewModel extends BaseViewModel { barrierDismissible: false, context: context, builder: (context) => AlertDialog( - title: I18nText('notice'), + title: Text(t.notice), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText( - 'patchesSelectorView.setRequiredOption', - translationParams: { - 'patches': patches.map((patch) => '• $patch').join('\n'), - }, + content: Text( + t.patchesSelectorView.setRequiredOption( + patches: patches.map((patch) => '• $patch').join('\n'), + ), ), actions: [ CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => { Navigator.of(context).pop(), }, @@ -129,25 +128,22 @@ class PatchesSelectorViewModel extends BaseViewModel { context: context, builder: (context) => AlertDialog( backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - title: I18nText('warning'), - content: I18nText( - 'patchItem.patchesChangeWarningDialogText', - child: const Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), + title: Text(t.warning), + content: Text( + t.patchItem.patchesChangeWarningDialogText, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, ), ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => Navigator.of(context).pop(), ), CustomMaterialButton( - label: I18nText('patchItem.patchesChangeWarningDialogButton'), + label: Text(t.patchItem.patchesChangeWarningDialogButton), onPressed: () { Navigator.of(context) ..pop() @@ -263,13 +259,10 @@ class PatchesSelectorViewModel extends BaseViewModel { bottom: 10.0, left: 5.0, ), - child: I18nText( + child: Text( category, - child: Text( - '', - style: TextStyle( - color: Theme.of(context).colorScheme.primary, - ), + style: TextStyle( + color: Theme.of(context).colorScheme.primary, ), ), ), @@ -334,7 +327,7 @@ class PatchesSelectorViewModel extends BaseViewModel { this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch)); } } else { - locator().showBottom('patchesSelectorView.noSavedPatches'); + locator().showBottom(t.patchesSelectorView.noSavedPatches); } notifyListeners(); } else { diff --git a/lib/ui/views/settings/settingsFragment/settings_manage_api_url.dart b/lib/ui/views/settings/settingsFragment/settings_manage_api_url.dart index 6fa1ccc1dd..034430b110 100644 --- a/lib/ui/views/settings/settingsFragment/settings_manage_api_url.dart +++ b/lib/ui/views/settings/settingsFragment/settings_manage_api_url.dart @@ -1,8 +1,8 @@ // ignore_for_file: use_build_context_synchronously import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/ui/widgets/settingsView/custom_text_field.dart'; @@ -24,7 +24,7 @@ class SManageApiUrl extends BaseViewModel { builder: (context) => AlertDialog( title: Row( children: [ - I18nText('settingsView.apiURLLabel'), + Text(t.settingsView.apiURLLabel), const Spacer(), IconButton( icon: const Icon(Icons.manage_history_outlined), @@ -43,7 +43,7 @@ class SManageApiUrl extends BaseViewModel { color: Theme.of(context).colorScheme.secondary, ), inputController: _apiUrlController, - label: I18nText('settingsView.selectApiURL'), + label: Text(t.settingsView.selectApiURL), hint: apiUrl, onChanged: (value) => notifyListeners(), ), @@ -53,21 +53,21 @@ class SManageApiUrl extends BaseViewModel { actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () { _apiUrlController.clear(); Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () { String apiUrl = _apiUrlController.text; if (!apiUrl.startsWith('https')) { apiUrl = 'https://$apiUrl'; } _managerAPI.setApiUrl(apiUrl); - _toast.showBottom('settingsView.restartAppForChanges'); + _toast.showBottom(t.settingsView.restartAppForChanges); Navigator.of(context).pop(); }, ), @@ -80,20 +80,20 @@ class SManageApiUrl extends BaseViewModel { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('settingsView.sourcesResetDialogTitle'), + title: Text(t.settingsView.sourcesResetDialogTitle), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('settingsView.apiURLResetDialogText'), + content: Text(t.settingsView.apiURLResetDialogText), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () => Navigator.of(context).pop(), ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { _managerAPI.setApiUrl(''); - _toast.showBottom('settingsView.restartAppForChanges'); + _toast.showBottom(t.settingsView.restartAppForChanges); Navigator.of(context) ..pop() ..pop(); @@ -114,8 +114,8 @@ class SManageApiUrlUI extends StatelessWidget { Widget build(BuildContext context) { return SettingsTileDialog( padding: const EdgeInsets.symmetric(horizontal: 20.0), - title: 'settingsView.apiURLLabel', - subtitle: 'settingsView.apiURLHint', + title: t.settingsView.apiURLLabel, + subtitle: t.settingsView.apiURLHint, onTap: () => sManageApiUrl.showApiUrlDialog(context), ); } diff --git a/lib/ui/views/settings/settingsFragment/settings_manage_keystore_password.dart b/lib/ui/views/settings/settingsFragment/settings_manage_keystore_password.dart index 4ac4689bde..9439a9e967 100644 --- a/lib/ui/views/settings/settingsFragment/settings_manage_keystore_password.dart +++ b/lib/ui/views/settings/settingsFragment/settings_manage_keystore_password.dart @@ -1,8 +1,8 @@ // ignore_for_file: use_build_context_synchronously import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/ui/widgets/settingsView/custom_text_field.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart'; @@ -23,7 +23,7 @@ class SManageKeystorePassword extends BaseViewModel { builder: (context) => AlertDialog( title: Row( children: [ - I18nText('settingsView.selectKeystorePassword'), + Text(t.settingsView.selectKeystorePassword), const Spacer(), IconButton( icon: const Icon(Icons.manage_history_outlined), @@ -39,7 +39,7 @@ class SManageKeystorePassword extends BaseViewModel { children: [ CustomTextField( inputController: _keystorePasswordController, - label: I18nText('settingsView.selectKeystorePassword'), + label: Text(t.settingsView.selectKeystorePassword), hint: '', onChanged: (value) => notifyListeners(), ), @@ -49,14 +49,14 @@ class SManageKeystorePassword extends BaseViewModel { actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () { _keystorePasswordController.clear(); Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () { final String passwd = _keystorePasswordController.text; _managerAPI.setKeystorePassword(passwd); @@ -78,8 +78,8 @@ class SManageKeystorePasswordUI extends StatelessWidget { Widget build(BuildContext context) { return SettingsTileDialog( padding: const EdgeInsets.symmetric(horizontal: 20.0), - title: 'settingsView.selectKeystorePassword', - subtitle: 'settingsView.selectKeystorePasswordHint', + title: t.settingsView.selectKeystorePassword, + subtitle: t.settingsView.selectKeystorePasswordHint, onTap: () => sManageKeystorePassword.showKeystoreDialog(context), ); } diff --git a/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart b/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart index 76e3171b1f..91437f5d33 100644 --- a/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart +++ b/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart @@ -1,8 +1,8 @@ // ignore_for_file: use_build_context_synchronously import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/ui/widgets/settingsView/custom_text_field.dart'; @@ -34,7 +34,7 @@ class SManageSources extends BaseViewModel { builder: (context) => AlertDialog( title: Row( children: [ - I18nText('settingsView.sourcesLabel'), + Text(t.settingsView.sourcesLabel), const Spacer(), IconButton( icon: const Icon(Icons.manage_history_outlined), @@ -53,7 +53,7 @@ class SManageSources extends BaseViewModel { color: Colors.transparent, ), inputController: _hostSourceController, - label: I18nText('settingsView.hostRepositoryLabel'), + label: Text(t.settingsView.hostRepositoryLabel), hint: hostRepository, onChanged: (value) => notifyListeners(), ), @@ -64,7 +64,7 @@ class SManageSources extends BaseViewModel { color: Theme.of(context).colorScheme.secondary, ), inputController: _orgPatSourceController, - label: I18nText('settingsView.orgPatchesLabel'), + label: Text(t.settingsView.orgPatchesLabel), hint: patchesRepo.split('/')[0], onChanged: (value) => notifyListeners(), ), @@ -75,7 +75,7 @@ class SManageSources extends BaseViewModel { color: Colors.transparent, ), inputController: _patSourceController, - label: I18nText('settingsView.sourcesPatchesLabel'), + label: Text(t.settingsView.sourcesPatchesLabel), hint: patchesRepo.split('/')[1], onChanged: (value) => notifyListeners(), ), @@ -86,7 +86,7 @@ class SManageSources extends BaseViewModel { color: Theme.of(context).colorScheme.secondary, ), inputController: _orgIntSourceController, - label: I18nText('settingsView.orgIntegrationsLabel'), + label: Text(t.settingsView.orgIntegrationsLabel), hint: integrationsRepo.split('/')[0], onChanged: (value) => notifyListeners(), ), @@ -97,19 +97,19 @@ class SManageSources extends BaseViewModel { color: Colors.transparent, ), inputController: _intSourceController, - label: I18nText('settingsView.sourcesIntegrationsLabel'), + label: Text(t.settingsView.sourcesIntegrationsLabel), hint: integrationsRepo.split('/')[1], onChanged: (value) => notifyListeners(), ), const SizedBox(height: 20), - I18nText('settingsView.sourcesUpdateNote'), + Text(t.settingsView.sourcesUpdateNote), ], ), ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () { _orgPatSourceController.clear(); _patSourceController.clear(); @@ -119,7 +119,7 @@ class SManageSources extends BaseViewModel { }, ), CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () { _managerAPI.setRepoUrl(_hostSourceController.text.trim()); _managerAPI.setPatchesRepo( @@ -130,7 +130,7 @@ class SManageSources extends BaseViewModel { ); _managerAPI.setCurrentPatchesVersion('0.0.0'); _managerAPI.setCurrentIntegrationsVersion('0.0.0'); - _toast.showBottom('settingsView.restartAppForChanges'); + _toast.showBottom(t.settingsView.restartAppForChanges); Navigator.of(context).pop(); }, ), @@ -143,24 +143,24 @@ class SManageSources extends BaseViewModel { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('settingsView.sourcesResetDialogTitle'), + title: Text(t.settingsView.sourcesResetDialogTitle), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('settingsView.sourcesResetDialogText'), + content: Text(t.settingsView.sourcesResetDialogText), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () => Navigator.of(context).pop(), ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { _managerAPI.setRepoUrl(''); _managerAPI.setPatchesRepo(''); _managerAPI.setIntegrationsRepo(''); _managerAPI.setCurrentPatchesVersion('0.0.0'); _managerAPI.setCurrentIntegrationsVersion('0.0.0'); - _toast.showBottom('settingsView.restartAppForChanges'); + _toast.showBottom(t.settingsView.restartAppForChanges); Navigator.of(context) ..pop() ..pop(); @@ -181,8 +181,8 @@ class SManageSourcesUI extends StatelessWidget { Widget build(BuildContext context) { return SettingsTileDialog( padding: const EdgeInsets.symmetric(horizontal: 20.0), - title: 'settingsView.sourcesLabel', - subtitle: 'settingsView.sourcesLabelHint', + title: t.settingsView.sourcesLabel, + subtitle: t.settingsView.sourcesLabelHint, onTap: () => sManageSources.showSourcesDialog(context), ); } diff --git a/lib/ui/views/settings/settingsFragment/settings_update_language.dart b/lib/ui/views/settings/settingsFragment/settings_update_language.dart index 66bb2c3e7f..99687c8a18 100644 --- a/lib/ui/views/settings/settingsFragment/settings_update_language.dart +++ b/lib/ui/views/settings/settingsFragment/settings_update_language.dart @@ -1,77 +1,98 @@ // ignore_for_file: use_build_context_synchronously import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:language_code/language_code.dart'; import 'package:revanced_manager/app/app.locator.dart'; -import 'package:revanced_manager/main.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; +import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/toast.dart'; -import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart'; +import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:stacked/stacked.dart'; -import 'package:timeago/timeago.dart' as timeago; final _settingViewModel = SettingsViewModel(); class SUpdateLanguage extends BaseViewModel { final Toast _toast = locator(); late SharedPreferences _prefs; - String selectedLanguage = 'English'; - String selectedLanguageLocale = prefs.getString('language') ?? 'en_US'; - List languages = []; + final ManagerAPI _managerAPI = locator(); Future initialize() async { _prefs = await SharedPreferences.getInstance(); - selectedLanguageLocale = - _prefs.getString('language') ?? selectedLanguageLocale; + _prefs.getString('language'); notifyListeners(); } - Future updateLanguage(BuildContext context, String? value) async { - if (value != null) { - selectedLanguageLocale = value; - _prefs = await SharedPreferences.getInstance(); - await _prefs.setString('language', value); - await FlutterI18n.refresh(context, Locale(value)); - timeago.setLocaleMessages(value, timeago.EnMessages()); - locator().notifyListeners(); - notifyListeners(); - } - } - - Future initLang() async { - languages.sort((a, b) => a['name'].compareTo(b['name'])); - notifyListeners(); + Future updateLocale(String locale) async { + LocaleSettings.setLocaleRaw(locale); + _managerAPI.setLocale(locale); + Future.delayed( + const Duration(milliseconds: 120), + () => _toast.showBottom(t.settingsView.languageUpdated), + ); } Future showLanguagesDialog(BuildContext parentContext) { - initLang(); + // initLang(); + + // Return a dialog with list for each language supported by the application. + // the dialog will display the english and native name of each languages, + // the current language will be highlighted by selected radio button. return showDialog( context: parentContext, - builder: (context) => SimpleDialog( - title: I18nText('settingsView.languageLabel'), + builder: (context) => AlertDialog( + title: Text(t.settingsView.languageLabel), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - children: [ - SizedBox( - height: 500, - child: ListView.builder( - itemCount: languages.length, - itemBuilder: (context, index) { - return RadioListTile( - title: Text(languages[index]['name']), - subtitle: Text(languages[index]['locale']), - value: languages[index]['locale'], - groupValue: selectedLanguageLocale, + contentPadding: EdgeInsets.zero, + content: SingleChildScrollView( + child: ListBody( + children: AppLocale.values.map( + (locale) { + return RadioListTile( + title: Text( + (() { + try { + return LanguageCodes.fromCode(locale.languageCode) + .englishName; + } catch (e) { + // This act as an fallback if the language is not supported by the package + // Do not try to make this nicer or debug it; trust me, I've tried. + return locale.languageCode; + } + })(), + ), + subtitle: Text( + (() { + try { + return LanguageCodes.fromCode(locale.languageCode) + .nativeName; + } catch (e) { + return '????'; + } + })(), + ), + value: locale.languageCode.replaceAll('-', '_') == + LocaleSettings.currentLocale.languageCode.replaceAll( + '-', + '_', + ), + groupValue: true, onChanged: (value) { - selectedLanguage = languages[index]['name']; - _toast.showBottom('settingsView.restartAppForChanges'); - updateLanguage(context, value); - Navigator.pop(context); + updateLocale(locale.languageCode.replaceAll('-', '_')); }, ); }, - ), + ).toList(), + ), + ), + actions: [ + CustomMaterialButton( + label: Text(t.okButton), + onPressed: () { + Navigator.of(context).pop(); + }, ), ], ), @@ -86,8 +107,8 @@ class SUpdateLanguageUI extends StatelessWidget { Widget build(BuildContext context) { return SettingsTileDialog( padding: const EdgeInsets.symmetric(horizontal: 20.0), - title: 'settingsView.languageLabel', - subtitle: _settingViewModel.sUpdateLanguage.selectedLanguage, + title: t.settingsView.languageLabel, + subtitle: LocaleSettings.currentLocale.name, onTap: () => _settingViewModel.sUpdateLanguage.showLanguagesDialog(context), ); diff --git a/lib/ui/views/settings/settingsFragment/settings_update_theme.dart b/lib/ui/views/settings/settingsFragment/settings_update_theme.dart index 66fa683094..acaf1cb928 100644 --- a/lib/ui/views/settings/settingsFragment/settings_update_theme.dart +++ b/lib/ui/views/settings/settingsFragment/settings_update_theme.dart @@ -3,8 +3,8 @@ import 'package:dynamic_themes/dynamic_themes.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; @@ -22,18 +22,15 @@ class _SUpdateThemeUIState extends State { @override Widget build(BuildContext context) { return SettingsSection( - title: 'settingsView.appearanceSectionTitle', + title: t.settingsView.appearanceSectionTitle, children: [ ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.themeModeLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.themeModeLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), trailing: CustomMaterialButton( @@ -45,17 +42,14 @@ class _SUpdateThemeUIState extends State { if (managerAPI.isDynamicThemeAvailable) SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.dynamicThemeLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.dynamicThemeLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.dynamicThemeHint'), + subtitle: Text(t.settingsView.dynamicThemeHint), value: getDynamicThemeStatus(), onChanged: (value) => { setUseDynamicTheme( @@ -100,16 +94,16 @@ class _SUpdateThemeUIState extends State { setState(() {}); } - I18nText getThemeModeName() { + Text getThemeModeName() { switch (getThemeMode()) { case 0: - return I18nText('settingsView.systemThemeLabel'); + return Text(t.settingsView.systemThemeLabel); case 1: - return I18nText('settingsView.lightThemeLabel'); + return Text(t.settingsView.lightThemeLabel); case 2: - return I18nText('settingsView.darkThemeLabel'); + return Text(t.settingsView.darkThemeLabel); default: - return I18nText('settingsView.systemThemeLabel'); + return Text(t.settingsView.systemThemeLabel); } } @@ -119,7 +113,7 @@ class _SUpdateThemeUIState extends State { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('settingsView.themeModeLabel'), + title: Text(t.settingsView.themeModeLabel), icon: const Icon(Icons.palette), contentPadding: const EdgeInsets.symmetric(vertical: 16), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, @@ -132,7 +126,7 @@ class _SUpdateThemeUIState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ RadioListTile( - title: I18nText('settingsView.systemThemeLabel'), + title: Text(t.settingsView.systemThemeLabel), contentPadding: const EdgeInsets.symmetric(horizontal: 16), value: 0, groupValue: value, @@ -141,7 +135,7 @@ class _SUpdateThemeUIState extends State { }, ), RadioListTile( - title: I18nText('settingsView.lightThemeLabel'), + title: Text(t.settingsView.lightThemeLabel), contentPadding: const EdgeInsets.symmetric(horizontal: 16), value: 1, groupValue: value, @@ -150,7 +144,7 @@ class _SUpdateThemeUIState extends State { }, ), RadioListTile( - title: I18nText('settingsView.darkThemeLabel'), + title: Text(t.settingsView.darkThemeLabel), contentPadding: const EdgeInsets.symmetric(horizontal: 16), value: 2, groupValue: value, @@ -166,13 +160,13 @@ class _SUpdateThemeUIState extends State { actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('cancelButton'), + label: Text(t.cancelButton), onPressed: () { Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () { setThemeMode(context, newTheme.value); Navigator.of(context).pop(); diff --git a/lib/ui/views/settings/settings_view.dart b/lib/ui/views/settings/settings_view.dart index fb623440b8..c9b7492be5 100644 --- a/lib/ui/views/settings/settings_view.dart +++ b/lib/ui/views/settings/settings_view.dart @@ -1,8 +1,9 @@ // ignore_for_file: prefer_const_constructors import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; +import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_language.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_theme.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart'; @@ -27,13 +28,10 @@ class SettingsView extends StatelessWidget { slivers: [ CustomSliverAppBar( isMainView: true, - title: I18nText( - 'settingsView.widgetTitle', - child: Text( - '', - style: GoogleFonts.inter( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + title: Text( + t.settingsView.widgetTitle, + style: GoogleFonts.inter( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), ), @@ -47,7 +45,7 @@ class SettingsView extends StatelessWidget { children: const [ SUpdateThemeUI(), // _settingsDivider, - // SUpdateLanguageUI(), + SUpdateLanguageUI(), _settingsDivider, SAdvancedSection(), _settingsDivider, diff --git a/lib/ui/views/settings/settings_viewmodel.dart b/lib/ui/views/settings/settings_viewmodel.dart index 721ee78e74..22ac88e74e 100644 --- a/lib/ui/views/settings/settings_viewmodel.dart +++ b/lib/ui/views/settings/settings_viewmodel.dart @@ -1,12 +1,13 @@ import 'dart:io'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_file_dialog/flutter_file_dialog.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:logcat/logcat.dart'; import 'package:path_provider/path_provider.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.router.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; @@ -53,21 +54,18 @@ class SettingsViewModel extends BaseViewModel { context: context, builder: (context) => AlertDialog( backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - title: I18nText('warning'), - content: I18nText( - 'settingsView.enablePatchesSelectionWarningText', - child: const Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), + title: Text(t.warning), + content: Text( + t.settingsView.enablePatchesSelectionWarningText, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, ), ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { _managerAPI.setChangingToggleModified(true); _managerAPI.setPatchesChangeEnabled(true); @@ -75,7 +73,7 @@ class SettingsViewModel extends BaseViewModel { }, ), CustomMaterialButton( - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () { Navigator.of(context).pop(); }, @@ -88,27 +86,24 @@ class SettingsViewModel extends BaseViewModel { context: context, builder: (context) => AlertDialog( backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - title: I18nText('warning'), - content: I18nText( - 'settingsView.disablePatchesSelectionWarningText', - child: const Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), + title: Text(t.warning), + content: Text( + t.settingsView.disablePatchesSelectionWarningText, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, ), ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () { Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { _managerAPI.setChangingToggleModified(true); _patchesSelectorViewModel.selectDefaultPatches(); @@ -151,28 +146,26 @@ class SettingsViewModel extends BaseViewModel { context: context, builder: (context) => AlertDialog( backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - title: I18nText('warning'), - content: I18nText( - 'settingsView.requireSuggestedAppVersionDialogText', - child: const Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), + title: Text(t.warning), + content: Text( + t.settingsView.requireSuggestedAppVersionDialogText, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, ), + ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { _managerAPI.enableRequireSuggestedAppVersionStatus(false); Navigator.of(context).pop(); }, ), CustomMaterialButton( - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () { Navigator.of(context).pop(); }, @@ -193,13 +186,13 @@ class SettingsViewModel extends BaseViewModel { void deleteKeystore() { _managerAPI.deleteKeystore(); - _toast.showBottom('settingsView.regeneratedKeystore'); + _toast.showBottom(t.settingsView.regeneratedKeystore); notifyListeners(); } void deleteTempDir() { _managerAPI.deleteTempFolder(); - _toast.showBottom('settingsView.deletedTempDir'); + _toast.showBottom(t.settingsView.deletedTempDir); notifyListeners(); } @@ -215,9 +208,9 @@ class SettingsViewModel extends BaseViewModel { fileName: 'selected_patches_$dateTime.json', ), ); - _toast.showBottom('settingsView.exportedPatches'); + _toast.showBottom(t.settingsView.exportedPatches); } else { - _toast.showBottom('settingsView.noExportFileFound'); + _toast.showBottom(t.settingsView.noExportFileFound); } } on Exception catch (e) { if (kDebugMode) { @@ -241,13 +234,13 @@ class SettingsViewModel extends BaseViewModel { if (_patcherViewModel.selectedApp != null) { _patcherViewModel.loadLastSelectedPatches(); } - _toast.showBottom('settingsView.importedPatches'); + _toast.showBottom(t.settingsView.importedPatches); } } on Exception catch (e) { if (kDebugMode) { print(e); } - _toast.showBottom('settingsView.jsonSelectorErrorMessage'); + _toast.showBottom(t.settingsView.jsonSelectorErrorMessage); } } else { _managerAPI.showPatchesChangeWarningDialog(context); @@ -266,9 +259,9 @@ class SettingsViewModel extends BaseViewModel { fileName: 'keystore_$dateTime.keystore', ), ); - _toast.showBottom('settingsView.exportedKeystore'); + _toast.showBottom(t.settingsView.exportedKeystore); } else { - _toast.showBottom('settingsView.noKeystoreExportFileFound'); + _toast.showBottom(t.settingsView.noKeystoreExportFileFound); } } on Exception catch (e) { if (kDebugMode) { @@ -284,24 +277,24 @@ class SettingsViewModel extends BaseViewModel { final File inFile = File(result); inFile.copySync(_managerAPI.keystoreFile); - _toast.showBottom('settingsView.importedKeystore'); + _toast.showBottom(t.settingsView.importedKeystore); } } on Exception catch (e) { if (kDebugMode) { print(e); } - _toast.showBottom('settingsView.keystoreSelectorErrorMessage'); + _toast.showBottom(t.settingsView.keystoreSelectorErrorMessage); } } void resetAllOptions() { _managerAPI.resetAllOptions(); - _toast.showBottom('settingsView.resetStoredOptions'); + _toast.showBottom(t.settingsView.resetStoredOptions); } void resetSelectedPatches() { _managerAPI.resetLastSelectedPatches(); - _toast.showBottom('settingsView.resetStoredPatches'); + _toast.showBottom(t.settingsView.resetStoredPatches); } Future deleteLogs() async { @@ -310,7 +303,7 @@ class SettingsViewModel extends BaseViewModel { if (logsDir.existsSync()) { logsDir.deleteSync(recursive: true); } - _toast.showBottom('settingsView.deletedLogs'); + _toast.showBottom(t.settingsView.deletedLogs); } Future exportLogcatLogs() async { diff --git a/lib/ui/widgets/appInfoView/app_info_view.dart b/lib/ui/widgets/appInfoView/app_info_view.dart index 283beb1293..601c1887ee 100644 --- a/lib/ui/widgets/appInfoView/app_info_view.dart +++ b/lib/ui/widgets/appInfoView/app_info_view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/ui/widgets/appInfoView/app_info_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; @@ -22,13 +22,10 @@ class AppInfoView extends StatelessWidget { body: CustomScrollView( slivers: [ CustomSliverAppBar( - title: I18nText( - 'appInfoView.widgetTitle', - child: Text( - '', - style: GoogleFonts.inter( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + title: Text( + t.appInfoView.widgetTitle, + style: GoogleFonts.inter( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), ), @@ -86,16 +83,13 @@ class AppInfoView extends StatelessWidget { .primary, ), const SizedBox(height: 10), - I18nText( - 'appInfoView.openButton', - child: Text( - '', - style: TextStyle( - color: Theme.of(context) - .colorScheme - .primary, - fontWeight: FontWeight.bold, - ), + Text( + t.appInfoView.openButton, + style: TextStyle( + color: Theme.of(context) + .colorScheme + .primary, + fontWeight: FontWeight.bold, ), ), ], @@ -130,16 +124,13 @@ class AppInfoView extends StatelessWidget { .primary, ), const SizedBox(height: 10), - I18nText( - 'appInfoView.uninstallButton', - child: Text( - '', - style: TextStyle( - color: Theme.of(context) - .colorScheme - .primary, - fontWeight: FontWeight.bold, - ), + Text( + t.appInfoView.uninstallButton, + style: TextStyle( + color: Theme.of(context) + .colorScheme + .primary, + fontWeight: FontWeight.bold, ), ), ], @@ -183,16 +174,13 @@ class AppInfoView extends StatelessWidget { .primary, ), const SizedBox(height: 10), - I18nText( - 'appInfoView.unpatchButton', - child: Text( - '', - style: TextStyle( - color: Theme.of(context) - .colorScheme - .primary, - fontWeight: FontWeight.bold, - ), + Text( + t.appInfoView.unpatchButton, + style: TextStyle( + color: Theme.of(context) + .colorScheme + .primary, + fontWeight: FontWeight.bold, ), ), ], @@ -209,14 +197,11 @@ class AppInfoView extends StatelessWidget { ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'appInfoView.packageNameLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.appInfoView.packageNameLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), subtitle: Text(app.packageName), @@ -225,61 +210,50 @@ class AppInfoView extends StatelessWidget { ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'appInfoView.installTypeLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.appInfoView.installTypeLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), subtitle: app.isRooted - ? I18nText('appInfoView.rootTypeLabel') - : I18nText('appInfoView.nonRootTypeLabel'), + ? Text(t.appInfoView.rootTypeLabel) + : Text(t.appInfoView.nonRootTypeLabel), ), const SizedBox(height: 4), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'appInfoView.patchedDateLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.appInfoView.patchedDateLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText( - 'appInfoView.patchedDateHint', - translationParams: { - 'date': model.getPrettyDate(context, app.patchDate), - 'time': model.getPrettyTime(context, app.patchDate), - }, + subtitle: Text( + t.appInfoView.patchedDateHint( + date: model.getPrettyDate(context, app.patchDate), + time: model.getPrettyTime(context, app.patchDate), + ), ), ), const SizedBox(height: 4), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'appInfoView.appliedPatchesLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.appInfoView.appliedPatchesLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText( - 'appInfoView.appliedPatchesHint', - translationParams: { - 'quantity': app.appliedPatches.length.toString(), - }, + subtitle: Text( + t.appInfoView.appliedPatchesHint( + quantity: app.appliedPatches.length.toString(), + ), ), onTap: () => model.showAppliedPatchesDialog(context, app), ), diff --git a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart index 324415672c..76c425b2f0 100644 --- a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart +++ b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart @@ -1,9 +1,9 @@ // ignore_for_file: use_build_context_synchronously import 'package:device_apps/device_apps.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:intl/intl.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/patcher_api.dart'; @@ -53,7 +53,7 @@ class AppInfoViewModel extends BaseViewModel { } void updateNotImplemented(BuildContext context) { - _toast.showBottom('appInfoView.updateNotImplemented'); + _toast.showBottom(t.appInfoView.updateNotImplemented); } Future showUninstallDialog( @@ -66,12 +66,12 @@ class AppInfoViewModel extends BaseViewModel { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('appInfoView.rootDialogTitle'), + title: Text(t.appInfoView.rootDialogTitle), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('appInfoView.rootDialogText'), + content: Text(t.appInfoView.rootDialogText), actions: [ CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => Navigator.of(context).pop(), ), ], @@ -82,21 +82,21 @@ class AppInfoViewModel extends BaseViewModel { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText( - 'appInfoView.unpatchButton', + title: Text( + t.appInfoView.unpatchButton, ), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText( - 'appInfoView.unpatchDialogText', + content: Text( + t.appInfoView.unpatchDialogText, ), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () => Navigator.of(context).pop(), ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () { uninstallApp(context, app, onlyUnpatch); Navigator.of(context).pop(); @@ -130,14 +130,14 @@ class AppInfoViewModel extends BaseViewModel { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('appInfoView.appliedPatchesLabel'), + title: Text(t.appInfoView.appliedPatchesLabel), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, content: SingleChildScrollView( child: Text(getAppliedPatchesString(app.appliedPatches)), ), actions: [ CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => Navigator.of(context).pop(), ), ], diff --git a/lib/ui/widgets/appSelectorView/installed_app_item.dart b/lib/ui/widgets/appSelectorView/installed_app_item.dart index ae129cbfdc..220abe8b17 100644 --- a/lib/ui/widgets/appSelectorView/installed_app_item.dart +++ b/lib/ui/widgets/appSelectorView/installed_app_item.dart @@ -1,6 +1,6 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; class InstalledAppItem extends StatefulWidget { @@ -61,27 +61,17 @@ class _InstalledAppItemState extends State { ), ), Text(widget.pkgName), - I18nText( - FlutterI18n.translate( - context, - 'installed', - translationParams: { - 'version': 'v${widget.installedVersion}', - }, - ), + Text( + t.installed(version: widget.installedVersion), ), Wrap( children: [ - I18nText( - 'suggested', - translationParams: { - 'version': widget.suggestedVersion.isEmpty - ? FlutterI18n.translate( - context, - 'appSelectorCard.allVersions', - ) + Text( + t.suggested( + version: widget.suggestedVersion.isEmpty + ? t.appSelectorCard.allVersions : 'v${widget.suggestedVersion}', - }, + ), ), const SizedBox(width: 4), Text( diff --git a/lib/ui/widgets/appSelectorView/not_installed_app_item.dart b/lib/ui/widgets/appSelectorView/not_installed_app_item.dart index c2f3f52e09..e16439bfab 100644 --- a/lib/ui/widgets/appSelectorView/not_installed_app_item.dart +++ b/lib/ui/widgets/appSelectorView/not_installed_app_item.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; class NotInstalledAppItem extends StatefulWidget { @@ -55,27 +55,20 @@ class _NotInstalledAppItem extends State { ), ), const SizedBox(height: 4), - I18nText( - 'appSelectorCard.notInstalled', - child: Text( - '', - style: TextStyle( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + Text( + t.appSelectorCard.notInstalled, + style: TextStyle( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), Wrap( children: [ - I18nText( - 'suggested', - translationParams: { - 'version': widget.suggestedVersion.isEmpty - ? FlutterI18n.translate( - context, - 'appSelectorCard.allVersions', - ) + Text( + t.suggested( + version: widget.suggestedVersion.isEmpty + ? t.appSelectorCard.allVersions : 'v${widget.suggestedVersion}', - }, + ), ), const SizedBox(width: 4), Text( diff --git a/lib/ui/widgets/contributorsView/contributors_card.dart b/lib/ui/widgets/contributorsView/contributors_card.dart index d0a4c624ef..8d685fb13d 100644 --- a/lib/ui/widgets/contributorsView/contributors_card.dart +++ b/lib/ui/widgets/contributorsView/contributors_card.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_cache_manager/file.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/services/download_manager.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -26,14 +25,11 @@ class _ContributorsCardState extends State { children: [ Padding( padding: const EdgeInsets.only(bottom: 8.0), - child: I18nText( + child: Text( widget.title, - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), ), diff --git a/lib/ui/widgets/homeView/installed_apps_card.dart b/lib/ui/widgets/homeView/installed_apps_card.dart index ec825340bf..342090843a 100644 --- a/lib/ui/widgets/homeView/installed_apps_card.dart +++ b/lib/ui/widgets/homeView/installed_apps_card.dart @@ -1,7 +1,7 @@ import 'package:device_apps/device_apps.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; @@ -51,19 +51,15 @@ class InstalledAppsCard extends StatelessWidget { color: Theme.of(context).colorScheme.secondary, ), const SizedBox(height: 16), - I18nText( - 'homeView.noInstallations', - child: Text( - '', - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .titleMedium! - .copyWith( - color: - Theme.of(context).colorScheme.secondary, - ), - ), + Text( + t.homeView.noInstallations, + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + color: Theme.of(context).colorScheme.secondary, + ), ), ], ), diff --git a/lib/ui/widgets/homeView/latest_commit_card.dart b/lib/ui/widgets/homeView/latest_commit_card.dart index cb263e259d..ccb33d1db9 100644 --- a/lib/ui/widgets/homeView/latest_commit_card.dart +++ b/lib/ui/widgets/homeView/latest_commit_card.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; @@ -40,13 +40,13 @@ class _LatestCommitCardState extends State { children: [ FutureBuilder( future: model.getLatestManagerReleaseTime(), - builder: (context, snapshot) => snapshot.hasData && - snapshot.data!.isNotEmpty - ? I18nText( - 'latestCommitCard.timeagoLabel', - translationParams: {'time': snapshot.data!}, - ) - : I18nText('latestCommitCard.loadingLabel'), + builder: (context, snapshot) => + snapshot.hasData && snapshot.data!.isNotEmpty + ? Text( + t.latestCommitCard + .timeagoLabel(time: snapshot.data!), + ) + : Text(t.latestCommitCard.loadingLabel), ), ], ), @@ -59,7 +59,7 @@ class _LatestCommitCardState extends State { builder: (context, snapshot) => Opacity( opacity: snapshot.hasData && snapshot.data! ? 1.0 : 0.25, child: CustomMaterialButton( - label: I18nText('updateButton'), + label: Text(t.updateButton), onPressed: snapshot.hasData && snapshot.data! ? () => widget.model.showUpdateConfirmationDialog( widget.parentContext, @@ -92,15 +92,9 @@ class _LatestCommitCardState extends State { future: model.getLatestPatchesReleaseTime(), builder: (context, snapshot) => Text( snapshot.hasData && snapshot.data!.isNotEmpty - ? FlutterI18n.translate( - context, - 'latestCommitCard.timeagoLabel', - translationParams: {'time': snapshot.data!}, - ) - : FlutterI18n.translate( - context, - 'latestCommitCard.loadingLabel', - ), + ? t.latestCommitCard + .timeagoLabel(time: snapshot.data!) + : t.latestCommitCard.loadingLabel, ), ), ], @@ -114,7 +108,7 @@ class _LatestCommitCardState extends State { builder: (context, snapshot) => Opacity( opacity: snapshot.hasData && snapshot.data! ? 1.0 : 0.25, child: CustomMaterialButton( - label: I18nText('updateButton'), + label: Text(t.updateButton), onPressed: snapshot.hasData && snapshot.data! ? () => widget.model.showUpdateConfirmationDialog( widget.parentContext, diff --git a/lib/ui/widgets/homeView/update_confirmation_dialog.dart b/lib/ui/widgets/homeView/update_confirmation_dialog.dart index 7839536ad5..68d1bb85f4 100644 --- a/lib/ui/widgets/homeView/update_confirmation_dialog.dart +++ b/lib/ui/widgets/homeView/update_confirmation_dialog.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; @@ -50,16 +50,13 @@ class UpdateConfirmationDialog extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - I18nText( + Text( isPatches - ? 'homeView.updatePatchesDialogTitle' - : 'homeView.updateDialogTitle', - child: const Text( - '', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - ), + ? t.homeView.updatePatchesDialogTitle + : t.homeView.updateDialogTitle, + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4.0), @@ -88,7 +85,7 @@ class UpdateConfirmationDialog extends StatelessWidget { ), CustomMaterialButton( isExpanded: true, - label: I18nText('updateButton'), + label: Text(t.updateButton), onPressed: () { Navigator.of(context).pop(); isPatches @@ -101,17 +98,13 @@ class UpdateConfirmationDialog extends StatelessWidget { ), Padding( padding: const EdgeInsets.only(left: 24.0, bottom: 12.0), - child: I18nText( - 'homeView.updateChangelogTitle', - child: Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - color: Theme.of(context) - .colorScheme - .onSecondaryContainer, - ), + child: Text( + t.homeView.updateChangelogTitle, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + color: + Theme.of(context).colorScheme.onSecondaryContainer, ), ), ), diff --git a/lib/ui/widgets/patcherView/app_selector_card.dart b/lib/ui/widgets/patcherView/app_selector_card.dart index e97a004d6e..ec2ba3888e 100644 --- a/lib/ui/widgets/patcherView/app_selector_card.dart +++ b/lib/ui/widgets/patcherView/app_selector_card.dart @@ -1,7 +1,8 @@ import 'dart:typed_data'; + import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; @@ -19,21 +20,18 @@ class AppSelectorCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - I18nText( + Text( locator().selectedApp == null - ? 'appSelectorCard.widgetTitle' - : 'appSelectorCard.widgetTitleSelected', - child: const Text( - '', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w500, - ), + ? t.appSelectorCard.widgetTitle + : t.appSelectorCard.widgetTitleSelected, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), if (locator().selectedApp == null) - I18nText('appSelectorCard.widgetSubtitle') + Text(t.appSelectorCard.widgetSubtitle) else Row( children: [ diff --git a/lib/ui/widgets/patcherView/patch_selector_card.dart b/lib/ui/widgets/patcherView/patch_selector_card.dart index 56da857078..8417ab8694 100644 --- a/lib/ui/widgets/patcherView/patch_selector_card.dart +++ b/lib/ui/widgets/patcherView/patch_selector_card.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; @@ -21,16 +21,13 @@ class PatchSelectorCard extends StatelessWidget { children: [ Row( children: [ - I18nText( + Text( locator().selectedPatches.isEmpty - ? 'patchSelectorCard.widgetTitle' - : 'patchSelectorCard.widgetTitleSelected', - child: const Text( - '', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w500, - ), + ? t.patchSelectorCard.widgetTitle + : t.patchSelectorCard.widgetTitleSelected, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, ), ), Text( @@ -46,10 +43,10 @@ class PatchSelectorCard extends StatelessWidget { ), const SizedBox(height: 4), if (locator().selectedApp == null) - I18nText('patchSelectorCard.widgetSubtitle') + Text(t.patchSelectorCard.widgetSubtitle) else locator().selectedPatches.isEmpty - ? I18nText('patchSelectorCard.widgetEmptySubtitle') + ? Text(t.patchSelectorCard.widgetEmptySubtitle) : Text(_getPatchesSelection()), ], ), @@ -58,7 +55,8 @@ class PatchSelectorCard extends StatelessWidget { String _getPatchesSelection() { String text = ''; - final List selectedPatches = locator().selectedPatches; + final List selectedPatches = + locator().selectedPatches; selectedPatches.sort((a, b) => a.name.compareTo(b.name)); for (final Patch p in selectedPatches) { text += '• ${p.getSimpleName()}\n'; diff --git a/lib/ui/widgets/patchesSelectorView/patch_item.dart b/lib/ui/widgets/patchesSelectorView/patch_item.dart index 92fe1454b4..a8ace9cb13 100644 --- a/lib/ui/widgets/patchesSelectorView/patch_item.dart +++ b/lib/ui/widgets/patchesSelectorView/patch_item.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/toast.dart'; @@ -162,7 +162,7 @@ class _PatchItemState extends State { Padding( padding: const EdgeInsets.only(top: 8), child: TextButton.icon( - label: I18nText('warning'), + label: Text(t.warning), icon: const Icon( Icons.warning_amber_outlined, size: 20.0, @@ -215,19 +215,18 @@ class _PatchItemState extends State { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('warning'), + title: Text(t.warning), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText( - 'patchItem.unsupportedDialogText', - translationParams: { - 'packageVersion': widget.packageVersion, - 'supportedVersions': + content: Text( + t.patchItem.unsupportedDialogText( + packageVersion: widget.packageVersion, + supportedVersions: '• ${widget.supportedPackageVersions.reversed.join('\n• ')}', - }, + ), ), actions: [ CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => Navigator.of(context).pop(), ), ], @@ -239,14 +238,14 @@ class _PatchItemState extends State { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('notice'), + title: Text(t.notice), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText( - 'patchItem.unsupportedRequiredOption', + content: Text( + t.patchItem.unsupportedRequiredOption, ), actions: [ CustomMaterialButton( - label: I18nText('okButton'), + label: Text(t.okButton), onPressed: () => Navigator.of(context).pop(), ), ], diff --git a/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart b/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart index ae026cb73b..b3e96f737d 100644 --- a/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart +++ b/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_file_dialog/flutter_file_dialog.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; @@ -93,13 +93,10 @@ class IntAndStringPatchOption extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 8), - I18nText( - 'patchOptionsView.requiredOption', - child: Text( - '', - style: TextStyle( - color: Theme.of(context).colorScheme.error, - ), + Text( + t.patchOptionsView.requiredOption, + style: TextStyle( + color: Theme.of(context).colorScheme.error, ), ), ], @@ -240,14 +237,11 @@ class IntStringLongListPatchOption extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.add, size: 20), - I18nText( - 'add', - child: const Text( - '', - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - ), + Text( + t.add, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, ), ), ], @@ -279,13 +273,10 @@ class UnsupportedPatchOption extends StatelessWidget { alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), - child: I18nText( - 'patchOptionsView.unsupportedOption', - child: const Text( - '', - style: TextStyle( - fontSize: 16, - ), + child: Text( + t.patchOptionsView.unsupportedOption, + style: const TextStyle( + fontSize: 16, ), ), ), @@ -400,7 +391,9 @@ class _TextFieldForPatchOptionState extends State { final bool isStringOption = widget.optionType.contains('String'); final bool isArrayOption = widget.optionType.contains('Array'); selectedKey ??= widget.selectedKey; - controller.text = !isStringOption && isArrayOption && selectedKey == '' && + controller.text = !isStringOption && + isArrayOption && + selectedKey == '' && (widget.value != null && widget.value.toString().startsWith('[')) ? '' : widget.value ?? ''; @@ -447,13 +440,10 @@ class _TextFieldForPatchOptionState extends State { ..add( DropdownMenuItem( value: '', - child: I18nText( - 'patchOptionsView.customValue', - child: const Text( - '', - style: TextStyle( - fontSize: 16, - ), + child: Text( + t.patchOptionsView.customValue, + style: const TextStyle( + fontSize: 16, ), ), ), @@ -486,25 +476,22 @@ class _TextFieldForPatchOptionState extends State { isStringOption ? TextInputType.text : TextInputType.number, decoration: InputDecoration( suffixIcon: PopupMenuButton( - tooltip: FlutterI18n.translate( - context, - 'patchOptionsView.tooltip', - ), + tooltip: t.patchOptionsView.tooltip, itemBuilder: (BuildContext context) { return [ if (isArrayOption) PopupMenuItem( - value: 'remove', - child: I18nText('remove'), + value: t.remove, + child: Text(t.remove), ), if (isStringOption) ...[ PopupMenuItem( - value: 'patchOptionsView.selectFilePath', - child: I18nText('patchOptionsView.selectFilePath'), + value: t.patchOptionsView.selectFilePath, + child: Text(t.patchOptionsView.selectFilePath), ), PopupMenuItem( - value: 'patchOptionsView.selectFolder', - child: I18nText('patchOptionsView.selectFolder'), + value: t.patchOptionsView.selectFolder, + child: Text(t.patchOptionsView.selectFolder), ), ], ]; @@ -519,7 +506,8 @@ class _TextFieldForPatchOptionState extends State { } break; case 'patchOptionsView.selectFolder': - final DirectoryLocation? result = await FlutterFileDialog.pickDirectory(); + final DirectoryLocation? result = + await FlutterFileDialog.pickDirectory(); if (result != null) { controller.text = result.toString(); widget.onChanged(controller.text); diff --git a/lib/ui/widgets/settingsView/about_widget.dart b/lib/ui/widgets/settingsView/about_widget.dart index ebad5f92e8..a6657f61f3 100644 --- a/lib/ui/widgets/settingsView/about_widget.dart +++ b/lib/ui/widgets/settingsView/about_widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/utils/about_info.dart'; class AboutWidget extends StatefulWidget { @@ -34,21 +34,18 @@ class _AboutWidgetState extends State { ); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: I18nText('settingsView.snackbarMessage'), + content: Text(t.settingsView.snackbarMessage), backgroundColor: Theme.of(context).colorScheme.secondary, ), ); } : null, - title: I18nText( - 'settingsView.aboutLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.aboutLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), subtitle: snapshot.hasData diff --git a/lib/ui/widgets/settingsView/settings_advanced_section.dart b/lib/ui/widgets/settingsView/settings_advanced_section.dart index 53b3cadf00..8c1e5e0f1c 100644 --- a/lib/ui/widgets/settingsView/settings_advanced_section.dart +++ b/lib/ui/widgets/settingsView/settings_advanced_section.dart @@ -1,6 +1,7 @@ // ignore_for_file: prefer_const_constructors import 'package:flutter/material.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_patches.dart'; @@ -10,14 +11,13 @@ import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_universal_patches.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_version_compatibility_check.dart'; - class SAdvancedSection extends StatelessWidget { const SAdvancedSection({super.key}); @override Widget build(BuildContext context) { return SettingsSection( - title: 'settingsView.advancedSectionTitle', + title: t.settingsView.advancedSectionTitle, children: const [ SAutoUpdatePatches(), SEnablePatchesSelection(), diff --git a/lib/ui/widgets/settingsView/settings_auto_update_patches.dart b/lib/ui/widgets/settingsView/settings_auto_update_patches.dart index 2063d658e6..90e74fe1e9 100644 --- a/lib/ui/widgets/settingsView/settings_auto_update_patches.dart +++ b/lib/ui/widgets/settingsView/settings_auto_update_patches.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; class SAutoUpdatePatches extends StatefulWidget { @@ -16,17 +16,14 @@ class _SAutoUpdatePatchesState extends State { Widget build(BuildContext context) { return SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.autoUpdatePatchesLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.autoUpdatePatchesLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.autoUpdatePatchesHint'), + subtitle: Text(t.settingsView.autoUpdatePatchesHint), value: _settingsViewModel.isPatchesAutoUpdate(), onChanged: (value) { setState(() { diff --git a/lib/ui/widgets/settingsView/settings_debug_section.dart b/lib/ui/widgets/settingsView/settings_debug_section.dart index 7a155b4e59..e4336b8366 100644 --- a/lib/ui/widgets/settingsView/settings_debug_section.dart +++ b/lib/ui/widgets/settingsView/settings_debug_section.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/about_widget.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; @@ -12,51 +12,42 @@ class SDebugSection extends StatelessWidget { @override Widget build(BuildContext context) { return SettingsSection( - title: 'settingsView.debugSectionTitle', + title: t.settingsView.debugSectionTitle, children: [ ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.logsLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.logsLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.logsHint'), + subtitle: Text(t.settingsView.logsHint), onTap: () => _settingsViewModel.exportLogcatLogs(), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.deleteLogsLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.deleteLogsLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.deleteLogsHint'), + subtitle: Text(t.settingsView.deleteLogsHint), onTap: () => _settingsViewModel.deleteLogs(), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.deleteTempDirLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.deleteTempDirLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.deleteTempDirHint'), + subtitle: Text(t.settingsView.deleteTempDirHint), onTap: () => _settingsViewModel.deleteTempDir(), ), const AboutWidget( diff --git a/lib/ui/widgets/settingsView/settings_enable_patches_selection.dart b/lib/ui/widgets/settingsView/settings_enable_patches_selection.dart index a0c5b463ef..a9a3ee4b35 100644 --- a/lib/ui/widgets/settingsView/settings_enable_patches_selection.dart +++ b/lib/ui/widgets/settingsView/settings_enable_patches_selection.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; class SEnablePatchesSelection extends StatefulWidget { const SEnablePatchesSelection({super.key}); @override - State createState() => _SEnablePatchesSelectionState(); + State createState() => + _SEnablePatchesSelectionState(); } final _settingsViewModel = SettingsViewModel(); @@ -16,17 +17,14 @@ class _SEnablePatchesSelectionState extends State { Widget build(BuildContext context) { return SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.enablePatchesSelectionLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.enablePatchesSelectionLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.enablePatchesSelectionHint'), + subtitle: Text(t.settingsView.enablePatchesSelectionHint), value: _settingsViewModel.isPatchesChangeEnabled(), onChanged: (value) async { await _settingsViewModel.showPatchesChangeEnableDialog(value, context); diff --git a/lib/ui/widgets/settingsView/settings_export_section.dart b/lib/ui/widgets/settingsView/settings_export_section.dart index 70aaf9b035..2f7bd0e14a 100644 --- a/lib/ui/widgets/settingsView/settings_export_section.dart +++ b/lib/ui/widgets/settingsView/settings_export_section.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_keystore_password.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; @@ -13,106 +13,88 @@ class SExportSection extends StatelessWidget { @override Widget build(BuildContext context) { return SettingsSection( - title: 'settingsView.exportSectionTitle', + title: t.settingsView.exportSectionTitle, children: [ ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.exportPatchesLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.exportPatchesLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.exportPatchesHint'), + subtitle: Text(t.settingsView.exportPatchesHint), onTap: () => _settingsViewModel.exportPatches(), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.importPatchesLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.importPatchesLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.importPatchesHint'), + subtitle: Text(t.settingsView.importPatchesHint), onTap: () => _settingsViewModel.importPatches(context), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.resetStoredPatchesLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.resetStoredPatchesLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.resetStoredPatchesHint'), + subtitle: Text(t.settingsView.resetStoredPatchesHint), onTap: () => _showResetDialog( context, - 'settingsView.resetStoredPatchesDialogTitle', - 'settingsView.resetStoredPatchesDialogText', + t.settingsView.resetStoredPatchesDialogTitle, + t.settingsView.resetStoredPatchesDialogText, _settingsViewModel.resetSelectedPatches, ), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.resetStoredOptionsLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.resetStoredOptionsLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.resetStoredOptionsHint'), + subtitle: Text(t.settingsView.resetStoredOptionsHint), onTap: () => _showResetDialog( context, - 'settingsView.resetStoredOptionsDialogTitle', - 'settingsView.resetStoredOptionsDialogText', + t.settingsView.resetStoredOptionsDialogTitle, + t.settingsView.resetStoredOptionsDialogText, _settingsViewModel.resetAllOptions, ), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.exportKeystoreLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.exportKeystoreLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.exportKeystoreHint'), + subtitle: Text(t.settingsView.exportKeystoreHint), onTap: () => _settingsViewModel.exportKeystore(), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.importKeystoreLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.importKeystoreLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.importKeystoreHint'), + subtitle: Text(t.settingsView.importKeystoreHint), onTap: () async { await _settingsViewModel.importKeystore(); final sManageKeystorePassword = SManageKeystorePassword(); @@ -123,17 +105,14 @@ class SExportSection extends StatelessWidget { ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.regenerateKeystoreLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.regenerateKeystoreLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.regenerateKeystoreHint'), + subtitle: Text(t.settingsView.regenerateKeystoreHint), onTap: () => _showDeleteKeystoreDialog(context), ), // SManageKeystorePasswordUI(), @@ -150,17 +129,17 @@ class SExportSection extends StatelessWidget { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText(dialogTitle), + title: Text(dialogTitle), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText(dialogText), + content: Text(dialogText), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () => Navigator.of(context).pop(), ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () => { Navigator.of(context).pop(), dialogAction(), @@ -175,17 +154,17 @@ class SExportSection extends StatelessWidget { return showDialog( context: context, builder: (context) => AlertDialog( - title: I18nText('settingsView.regenerateKeystoreDialogTitle'), + title: Text(t.settingsView.regenerateKeystoreDialogTitle), backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('settingsView.regenerateKeystoreDialogText'), + content: Text(t.settingsView.regenerateKeystoreDialogText), actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), + label: Text(t.noButton), onPressed: () => Navigator.of(context).pop(), ), CustomMaterialButton( - label: I18nText('yesButton'), + label: Text(t.yesButton), onPressed: () => { Navigator.of(context).pop(), _settingsViewModel.deleteKeystore(), diff --git a/lib/ui/widgets/settingsView/settings_require_suggested_app_version.dart b/lib/ui/widgets/settingsView/settings_require_suggested_app_version.dart index a46ee10d34..85fc7bdb7d 100644 --- a/lib/ui/widgets/settingsView/settings_require_suggested_app_version.dart +++ b/lib/ui/widgets/settingsView/settings_require_suggested_app_version.dart @@ -1,36 +1,36 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; class SRequireSuggestedAppVersion extends StatefulWidget { const SRequireSuggestedAppVersion({super.key}); @override - State createState() => _SRequireSuggestedAppVersionState(); + State createState() => + _SRequireSuggestedAppVersionState(); } final _settingsViewModel = SettingsViewModel(); -class _SRequireSuggestedAppVersionState extends State { +class _SRequireSuggestedAppVersionState + extends State { @override Widget build(BuildContext context) { return SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.requireSuggestedAppVersionLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.requireSuggestedAppVersionLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.requireSuggestedAppVersionHint'), + subtitle: Text(t.settingsView.requireSuggestedAppVersionHint), value: _settingsViewModel.isRequireSuggestedAppVersionEnabled(), onChanged: (value) async { - await _settingsViewModel.showRequireSuggestedAppVersionDialog(context, value); - setState(() {}); + await _settingsViewModel.showRequireSuggestedAppVersionDialog( + context, value); + setState(() {}); }, ); } diff --git a/lib/ui/widgets/settingsView/settings_section.dart b/lib/ui/widgets/settingsView/settings_section.dart index 74570a14af..c62c5352bc 100644 --- a/lib/ui/widgets/settingsView/settings_section.dart +++ b/lib/ui/widgets/settingsView/settings_section.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; class SettingsSection extends StatelessWidget { const SettingsSection({ @@ -17,13 +16,10 @@ class SettingsSection extends StatelessWidget { children: [ Container( padding: const EdgeInsets.only(top: 16.0, bottom: 10.0, left: 20.0), - child: I18nText( + child: Text( title, - child: Text( - '', - style: TextStyle( - color: Theme.of(context).colorScheme.primary, - ), + style: TextStyle( + color: Theme.of(context).colorScheme.primary, ), ), ), diff --git a/lib/ui/widgets/settingsView/settings_team_section.dart b/lib/ui/widgets/settingsView/settings_team_section.dart index aa2d81a6f3..bcf117e795 100644 --- a/lib/ui/widgets/settingsView/settings_team_section.dart +++ b/lib/ui/widgets/settingsView/settings_team_section.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; import 'package:revanced_manager/ui/widgets/settingsView/social_media_widget.dart'; @@ -12,21 +12,18 @@ class STeamSection extends StatelessWidget { @override Widget build(BuildContext context) { return SettingsSection( - title: 'settingsView.teamSectionTitle', + title: t.settingsView.teamSectionTitle, children: [ ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.contributorsLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.contributorsLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.contributorsHint'), + subtitle: Text(t.settingsView.contributorsHint), onTap: () => _settingsViewModel.navigateToContributors(), ), const SocialMediaWidget( diff --git a/lib/ui/widgets/settingsView/settings_tile_dialog.dart b/lib/ui/widgets/settingsView/settings_tile_dialog.dart index ce3a817d70..5c65c23d07 100644 --- a/lib/ui/widgets/settingsView/settings_tile_dialog.dart +++ b/lib/ui/widgets/settingsView/settings_tile_dialog.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; class SettingsTileDialog extends StatelessWidget { const SettingsTileDialog({ @@ -18,17 +17,14 @@ class SettingsTileDialog extends StatelessWidget { Widget build(BuildContext context) { return ListTile( contentPadding: padding ?? EdgeInsets.zero, - title: I18nText( + title: Text( title, - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText(subtitle), + subtitle: Text(subtitle), onTap: onTap, ); } diff --git a/lib/ui/widgets/settingsView/settings_universal_patches.dart b/lib/ui/widgets/settingsView/settings_universal_patches.dart index 1b4c27ee66..9d3cd4d13c 100644 --- a/lib/ui/widgets/settingsView/settings_universal_patches.dart +++ b/lib/ui/widgets/settingsView/settings_universal_patches.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; @@ -8,31 +8,26 @@ class SUniversalPatches extends StatefulWidget { const SUniversalPatches({super.key}); @override - State createState() => - _SUniversalPatchesState(); + State createState() => _SUniversalPatchesState(); } final _settingsViewModel = SettingsViewModel(); final _patchesSelectorViewModel = PatchesSelectorViewModel(); final _patcherViewModel = PatcherViewModel(); -class _SUniversalPatchesState - extends State { +class _SUniversalPatchesState extends State { @override Widget build(BuildContext context) { return SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.universalPatchesLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.universalPatchesLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.universalPatchesHint'), + subtitle: Text(t.settingsView.universalPatchesHint), value: _settingsViewModel.areUniversalPatchesEnabled(), onChanged: (value) { setState(() { diff --git a/lib/ui/widgets/settingsView/settings_version_compatibility_check.dart b/lib/ui/widgets/settingsView/settings_version_compatibility_check.dart index ead3b07094..b055d0c27d 100644 --- a/lib/ui/widgets/settingsView/settings_version_compatibility_check.dart +++ b/lib/ui/widgets/settingsView/settings_version_compatibility_check.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; @@ -9,29 +9,28 @@ class SVersionCompatibilityCheck extends StatefulWidget { const SVersionCompatibilityCheck({super.key}); @override - State createState() => _SVersionCompatibilityCheckState(); + State createState() => + _SVersionCompatibilityCheckState(); } final _settingsViewModel = SettingsViewModel(); final _patchesSelectorViewModel = PatchesSelectorViewModel(); final _patcherViewModel = PatcherViewModel(); -class _SVersionCompatibilityCheckState extends State { +class _SVersionCompatibilityCheckState + extends State { @override Widget build(BuildContext context) { return SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.versionCompatibilityCheckLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.settingsView.versionCompatibilityCheckLabel, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('settingsView.versionCompatibilityCheckHint'), + subtitle: Text(t.settingsView.versionCompatibilityCheckHint), value: _settingsViewModel.isVersionCompatibilityCheckEnabled(), onChanged: (value) { setState(() { diff --git a/lib/ui/widgets/settingsView/social_media_widget.dart b/lib/ui/widgets/settingsView/social_media_widget.dart index 4431ac6ab9..faee63c11d 100644 --- a/lib/ui/widgets/settingsView/social_media_widget.dart +++ b/lib/ui/widgets/settingsView/social_media_widget.dart @@ -1,7 +1,7 @@ import 'package:expandable/expandable.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/widgets/settingsView/social_media_item.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_icon.dart'; @@ -26,17 +26,14 @@ class SocialMediaWidget extends StatelessWidget { ), header: ListTile( contentPadding: padding ?? EdgeInsets.zero, - title: I18nText( - 'socialMediaCard.widgetTitle', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), + title: Text( + t.socialMediaCard.widgetTitle, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, ), ), - subtitle: I18nText('socialMediaCard.widgetSubtitle'), + subtitle: Text(t.socialMediaCard.widgetSubtitle), ), expanded: Padding( padding: padding ?? EdgeInsets.zero, diff --git a/lib/ui/widgets/shared/application_item.dart b/lib/ui/widgets/shared/application_item.dart index b733643563..f8cba060c8 100644 --- a/lib/ui/widgets/shared/application_item.dart +++ b/lib/ui/widgets/shared/application_item.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/gen/strings.g.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; import 'package:timeago/timeago.dart'; @@ -24,7 +24,6 @@ class ApplicationItem extends StatefulWidget { } class _ApplicationItemState extends State { - @override void initState() { super.initState(); @@ -82,7 +81,7 @@ class _ApplicationItemState extends State { crossAxisAlignment: CrossAxisAlignment.end, children: [ CustomMaterialButton( - label: I18nText('applicationItem.infoButton'), + label: Text(t.applicationItem.infoButton), onPressed: widget.onPressed, ), ], diff --git a/pubspec.yaml b/pubspec.yaml index e5d5c80b64..ea3157c43c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,7 +29,6 @@ dependencies: url: https://github.com/BenjaminHalko/flutter_background ref: specify-namespace flutter_cache_manager: ^3.3.0 - flutter_i18n: ^0.34.0 flutter_local_notifications: ^16.1.0 flutter_localizations: sdk: flutter @@ -81,10 +80,13 @@ dependencies: flutter_file_dialog: ^3.0.2 wakelock_plus: ^1.1.3 share_plus: ^7.2.1 + slang: ^3.25.0 + slang_flutter: ^3.25.0 + language_code: ^0.3.1 dev_dependencies: - json_serializable: ^6.6.1 build_runner: any + json_serializable: ^6.6.1 flutter_launcher_icons: ^0.13.0 flutter_lints: ^2.0.1 flutter_test: @@ -101,3 +103,5 @@ flutter: - asset: fonts/custom-icons.ttf assets: - assets/i18n/ +flutter_localizations: # add this + sdk: flutter diff --git a/slang.yaml b/slang.yaml new file mode 100644 index 0000000000..42b2aed50b --- /dev/null +++ b/slang.yaml @@ -0,0 +1,5 @@ +base_locale: en +fallback_strategy: base_locale +input_file_pattern: .i18n.json +input_directory: assets/i18n +output_directory: lib/gen