diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index c65a4673f8..f71a6d2023 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: dart 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 d8f3d74555..c1ae159c10 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: dart 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/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 fec5b7e9af..e4b89f7856 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 dart 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 b38cb4c78c..0fef6a8138 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 f45c91ae64..94a93b97ae 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'; @@ -18,13 +20,13 @@ class DynamicThemeBuilder extends StatefulWidget { }); 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(); @@ -42,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, ), ); } @@ -82,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 55890f17ab..b2aee6cdc5 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 2d9c8b7427..33740a7b13 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 b2fdcd867b..c5deea5e3e 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 d1626ed5ab..38b61aea06 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 13a4457e22..65a41ca375 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 520fd9c68e..6a35891eaa 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 0921bb1d73..9c678dc0c5 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 29489078ef..cd04bf8e91 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 0d5b8e30f5..9ae5df625a 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 d1dbfd7eb0..61f9b32931 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 0e7bed3d31..d655f550b3 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 9147e1d028..6cac4190be 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 48e134eacb..143e4048b8 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 d039e5b703..d5827ca096 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 e6ac9a0214..8de0fae9ba 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 9d0625ce53..464f08d9ef 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 2fb0e803ae..15f078d52c 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 ceea41c97d..35162b7fcb 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 11fd08392f..cfeb419f37 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 1884b5e37a..1b087d5a1b 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..d30b60342c 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 56e9247ebc..697dcbd4cf 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 822ffe6f87..eed856cb02 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 c42c526dce..7bec8b1c6d 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 5f527eb14a..630ffe0dab 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 36320b6559..8c38222fc8 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: ^3.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