mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat: Allow changing languages (#1488)
Co-authored-by: validcube <pun.butrach@gmail.com>
This commit is contained in:
parent
c498cff096
commit
f82c439b26
3
.github/workflows/pr-build.yml
vendored
3
.github/workflows/pr-build.yml
vendored
@ -73,7 +73,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Flutter dependencies
|
- name: Install Flutter dependencies
|
||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
|
- name: Generate translation with Slang
|
||||||
|
run: dart run slang
|
||||||
- name: Generate files with Builder
|
- name: Generate files with Builder
|
||||||
run: dart run build_runner build --delete-conflicting-outputs
|
run: dart run build_runner build --delete-conflicting-outputs
|
||||||
|
|
||||||
|
3
.github/workflows/release-build.yml
vendored
3
.github/workflows/release-build.yml
vendored
@ -42,7 +42,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Flutter
|
- name: Set up Flutter
|
||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
|
- name: Generate translation with Slang
|
||||||
|
run: dart run slang
|
||||||
- name: Generate files with Builder
|
- name: Generate files with Builder
|
||||||
run: dart run build_runner build --delete-conflicting-outputs
|
run: dart run build_runner build --delete-conflicting-outputs
|
||||||
|
|
||||||
|
53
.github/workflows/sync-crowdin.yml
vendored
Normal file
53
.github/workflows/sync-crowdin.yml
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
name: Crowdin Action
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
synchronize-with-crowdin:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set up Dart
|
||||||
|
uses: dart-lang/setup-dart@v1
|
||||||
|
|
||||||
|
- name: Sync translation from Crowdin
|
||||||
|
uses: crowdin/github-action@v1
|
||||||
|
with:
|
||||||
|
config: crowdin.yml
|
||||||
|
upload_sources: true
|
||||||
|
upload_translations: false
|
||||||
|
download_translations: true
|
||||||
|
localization_branch_name: feat/translations
|
||||||
|
create_pull_request: true
|
||||||
|
pull_request_title: "chore(i18n): Sync translations"
|
||||||
|
pull_request_body: "Sync translations from [Crowdin/ReVanced](https://crowdin.com/project/revanced)"
|
||||||
|
pull_request_base_branch_name: "dev"
|
||||||
|
commit_message: "chore(i18n): Sync translations"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||||
|
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||||
|
|
||||||
|
- name: Remove empty values from JSON
|
||||||
|
run: |
|
||||||
|
cd assets/i18n
|
||||||
|
sudo chmod 777 *
|
||||||
|
dart nuke.dart >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
- name: Push out changes to i10n
|
||||||
|
run: |
|
||||||
|
git config user.name revanced-bot
|
||||||
|
git config user.email github@revanced.app
|
||||||
|
sudo chown -R $USER:$USER .git
|
||||||
|
git add assets/i18n/*.json
|
||||||
|
git commit -m "chore(Translation): Remove empty values from JSON" assets/i18n/*.json
|
||||||
|
git push origin HEAD:feat/translations
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
14
assets/i18n/README.md
Normal file
14
assets/i18n/README.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Nuke:tm:
|
||||||
|
|
||||||
|
> ![CAUTION]
|
||||||
|
> Some of the code are licensed under BSD 3-Clause License, please check inside the code file for more information.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Move to your desire directory and run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dart nuke.dart
|
||||||
|
```
|
||||||
|
|
||||||
|
and it will remove all the empty keys from the JSON files in the current folder.
|
@ -1,373 +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",
|
|
||||||
"showChangelogButton": "Show changelog",
|
|
||||||
"showUpdateButton": "Show update",
|
|
||||||
"navigationView": {
|
|
||||||
"dashboardTab": "Dashboard",
|
|
||||||
"patcherTab": "Patcher",
|
|
||||||
"settingsTab": "Settings"
|
|
||||||
},
|
|
||||||
"homeView": {
|
|
||||||
"refreshSuccess": "Refreshed successfully",
|
|
||||||
"widgetTitle": "Dashboard",
|
|
||||||
|
|
||||||
"updatesSubtitle": "Updates",
|
|
||||||
"patchedSubtitle": "Patched apps",
|
|
||||||
"changeLaterSubtitle": "You can change this in the settings at a later time.",
|
|
||||||
|
|
||||||
"noUpdates": "No updates available",
|
|
||||||
|
|
||||||
"WIP": "Work in progress...",
|
|
||||||
|
|
||||||
"noInstallations": "No patched apps installed",
|
|
||||||
"installUpdate": "Continue to install the update?",
|
|
||||||
|
|
||||||
"updateSheetTitle": "Update ReVanced Manager",
|
|
||||||
"updateDialogTitle": "New update available",
|
|
||||||
"updatePatchesSheetTitle": "Update ReVanced Patches",
|
|
||||||
"updateChangelogTitle": "Changelog",
|
|
||||||
|
|
||||||
"updateDialogText": "A new update is available for {file}.\n\nThe currently installed version is {version}.",
|
|
||||||
|
|
||||||
"downloadConsentDialogTitle": "Download necessary files?",
|
|
||||||
"downloadConsentDialogText": "ReVanced Manager needs to download necessary files to work properly.",
|
|
||||||
"downloadConsentDialogText2": "This will connect you to {url}.",
|
|
||||||
|
|
||||||
"checkUpdateDialogTitle": "Check for updates?",
|
|
||||||
"checkUpdateDialogText": "Do you want ReVanced Manager to check for updates automatically?",
|
|
||||||
|
|
||||||
"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. Continue anyways?",
|
|
||||||
|
|
||||||
"removedPatchesWarningDialogText": "The following patches have been removed since the last time you used them.\n\n{patches}\n\nContinue anyways?",
|
|
||||||
"requiredOptionDialogText" : "Some patch options have to be set."
|
|
||||||
},
|
|
||||||
"appSelectorCard": {
|
|
||||||
"widgetTitle": "Select an app",
|
|
||||||
"widgetTitleSelected": "Selected app",
|
|
||||||
"widgetSubtitle": "No app selected",
|
|
||||||
|
|
||||||
"noAppsLabel": "No applications found",
|
|
||||||
|
|
||||||
"currentVersion": "Current",
|
|
||||||
"suggestedVersion": "Suggested",
|
|
||||||
"anyVersion": "Any version"
|
|
||||||
},
|
|
||||||
"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 app",
|
|
||||||
"searchBarHint": "Search app",
|
|
||||||
|
|
||||||
"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 which can lead to unexpected issues. Please use the suggested version.\n\nSelected version: {selected}\nSuggested version: {suggested}\n\nTo continue anyway, disable \"Require suggested app version\" in the settings.",
|
|
||||||
|
|
||||||
"featureNotAvailable": "Feature not implemented",
|
|
||||||
"featureNotAvailableText": "This app is a split APK and can only be patched and installed reliably by mounting with root permissions. However, you can patch and install a full APK by selecting it from storage."
|
|
||||||
},
|
|
||||||
"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 the settings before changing any patch selection.",
|
|
||||||
"patchesChangeWarningDialogButton": "Use default selection"
|
|
||||||
},
|
|
||||||
"installerView": {
|
|
||||||
"widgetTitle": "Installer",
|
|
||||||
"installType": "Select install type",
|
|
||||||
"installTypeDescription": "Select the installation type to continue with.",
|
|
||||||
|
|
||||||
"installButton": "Install",
|
|
||||||
"installRootType": "Mount",
|
|
||||||
"installNonRootType": "Regular",
|
|
||||||
|
|
||||||
"warning": "Disable auto updates for the patched app to avoid unexpected issues.",
|
|
||||||
|
|
||||||
"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 the source of patches and integrations",
|
|
||||||
"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 the URL of the API to use",
|
|
||||||
"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": "Do not prevent selecting or deselecting 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",
|
|
||||||
"showUpdateDialogLabel": "Show update dialog",
|
|
||||||
"showUpdateDialogHint": "Show a dialog when a new update is available",
|
|
||||||
"universalPatchesLabel": "Show universal patches",
|
|
||||||
"universalPatchesHint": "Display all apps and universal patches (may slow down the app list)",
|
|
||||||
|
|
||||||
"versionCompatibilityCheckLabel": "Version compatibility check",
|
|
||||||
"versionCompatibilityCheckHint": "Prevent selecting patches that are not compatible with the selected app version",
|
|
||||||
|
|
||||||
"requireSuggestedAppVersionLabel": "Require suggested app version",
|
|
||||||
"requireSuggestedAppVersionHint": "Prevent selecting an app with a version that is not the suggested",
|
|
||||||
"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",
|
|
||||||
"unmountButton": "Unmount",
|
|
||||||
"rootDialogTitle": "Error",
|
|
||||||
|
|
||||||
"unmountDialogText": "Are you sure you want to unmount this app?",
|
|
||||||
"uninstallDialogText": "Are you sure you want to uninstall 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",
|
|
||||||
"mountTypeLabel": "Mount",
|
|
||||||
"regularTypeLabel": "Regular",
|
|
||||||
"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"
|
|
||||||
},
|
|
||||||
"installErrorDialog": {
|
|
||||||
"mount_version_mismatch": "Version mismatch",
|
|
||||||
"mount_no_root": "No root access",
|
|
||||||
"mount_missing_installation": "Installation not found",
|
|
||||||
|
|
||||||
"status_failure_blocked": "Installation blocked",
|
|
||||||
"install_failed_verification_failure": "Verification failed",
|
|
||||||
"status_failure_invalid": "Installation invalid",
|
|
||||||
"install_failed_version_downgrade": "Can't downgrade",
|
|
||||||
"status_failure_conflict": "Installation conflict",
|
|
||||||
"status_failure_storage": "Installation storage issue",
|
|
||||||
"status_failure_incompatible": "Installation incompatible",
|
|
||||||
"status_failure_timeout": "Installation timeout",
|
|
||||||
"status_unknown": "Installation failed",
|
|
||||||
|
|
||||||
"mount_version_mismatch_description": "The installation failed due to the installed app being a different version than the patched app.\n\nInstall the version of the app you are mounting and try again.",
|
|
||||||
"mount_no_root_description": "The installation failed due to root access not being granted.\n\nGrant root access to ReVanced Manager and try again.",
|
|
||||||
"mount_missing_installation_description": "The installation failed due to the unpatched app not being installed on this device in order to mount over it.\n\nInstall the unpatched app before mounting and try again.",
|
|
||||||
|
|
||||||
"status_failure_timeout_description": "The installation took too long to finish.\n\nWould you like to try again?",
|
|
||||||
"status_failure_storage_description": "The installation failed due to insufficient storage.\n\nFree up some space and try again.",
|
|
||||||
"status_failure_invalid_description": "The installation failed due to the patched app being invalid.\n\nUninstall the app and try again?",
|
|
||||||
"status_failure_incompatible_description": "The app is incompatible with this device.\n\nContact the developer of the app and ask for support.",
|
|
||||||
"status_failure_conflict_description": "The installation was prevented by an existing installation of the app.\n\nUninstall the installed app and try again?",
|
|
||||||
"status_failure_blocked_description": "The installation was blocked by {packageName}.\n\nAdjust your security settings and try again.",
|
|
||||||
"install_failed_verification_failure_description": "The installation failed due to a verification issue.\n\nAdjust your security settings and try again.",
|
|
||||||
"install_failed_version_downgrade_description": "The installation failed due to the patched app being a lower version than the installed app.\n\nUninstall the app and try again?",
|
|
||||||
"status_unknown_description": "The installation failed due to an unknown reason. Please try again."
|
|
||||||
}
|
|
||||||
}
|
|
79
assets/i18n/nuke.dart
Normal file
79
assets/i18n/nuke.dart
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
T? removeBlankEntries<T>(T? json) {
|
||||||
|
// This function is protected by BSD 3-Clause License
|
||||||
|
// Changes made to this section are allow removing of '' values from JSON
|
||||||
|
|
||||||
|
/*
|
||||||
|
https://pub.dev/documentation/swiss_knife/latest/swiss_knife/removeEmptyEntries.html
|
||||||
|
|
||||||
|
Copyright 2014, the Dart project authors. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
if (json == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (json is List) {
|
||||||
|
json.removeWhere((e) => e == null);
|
||||||
|
json.forEach(removeBlankEntries);
|
||||||
|
} else if (json is Map) {
|
||||||
|
json.removeWhere(
|
||||||
|
(key, value) => key == null || value == null || value == '',
|
||||||
|
);
|
||||||
|
json.values.forEach(removeBlankEntries);
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> processJsonFiles() async {
|
||||||
|
final Directory directory = Directory.current;
|
||||||
|
final List<FileSystemEntity> files = directory.listSync();
|
||||||
|
|
||||||
|
for (final file in files) {
|
||||||
|
try {
|
||||||
|
if (file is File && file.path.endsWith('.json')) {
|
||||||
|
final String contents = await file.readAsString();
|
||||||
|
final dynamic json = jsonDecode(contents);
|
||||||
|
final dynamic processedJson = removeBlankEntries(json);
|
||||||
|
|
||||||
|
file.writeAsString(
|
||||||
|
const JsonEncoder.withIndent(' ').convert(processedJson),
|
||||||
|
);
|
||||||
|
print('🥞 Task successful on: ${file.path}');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('💥 Task failed on: ${file.path}: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
processJsonFiles();
|
||||||
|
}
|
305
assets/i18n/strings.i18n.json
Normal file
305
assets/i18n/strings.i18n.json
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
{
|
||||||
|
"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",
|
||||||
|
"showChangelogButton": "Show changelog",
|
||||||
|
"showUpdateButton": "Show update",
|
||||||
|
"navigationView": {
|
||||||
|
"dashboardTab": "Dashboard",
|
||||||
|
"patcherTab": "Patcher",
|
||||||
|
"settingsTab": "Settings"
|
||||||
|
},
|
||||||
|
"homeView": {
|
||||||
|
"refreshSuccess": "Refreshed successfully",
|
||||||
|
"widgetTitle": "Dashboard",
|
||||||
|
"updatesSubtitle": "Updates",
|
||||||
|
"patchedSubtitle": "Patched apps",
|
||||||
|
"changeLaterSubtitle": "You can change this in the settings at a later time.",
|
||||||
|
"noUpdates": "No updates available",
|
||||||
|
"WIP": "Work in progress...",
|
||||||
|
"noInstallations": "No patched apps installed",
|
||||||
|
"installUpdate": "Continue to install the update?",
|
||||||
|
"updateSheetTitle": "Update ReVanced Manager",
|
||||||
|
"updateDialogTitle": "New update available",
|
||||||
|
"updatePatchesSheetTitle": "Update ReVanced Patches",
|
||||||
|
"updateChangelogTitle": "Changelog",
|
||||||
|
"updateDialogText": "A new update is available for ${file}.\n\nThe currently installed version is ${version}.",
|
||||||
|
"downloadConsentDialogTitle": "Download necessary files?",
|
||||||
|
"downloadConsentDialogText": "ReVanced Manager needs to download necessary files to work properly.",
|
||||||
|
"downloadConsentDialogText2": "This will connect you to ${url}.",
|
||||||
|
"checkUpdateDialogTitle": "Check for updates?",
|
||||||
|
"checkUpdateDialogText": "Do you want ReVanced Manager to check for updates automatically?",
|
||||||
|
"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. Continue anyways?",
|
||||||
|
"removedPatchesWarningDialogText": "The following patches have been removed since the last time you used them.\n\n${patches}\n\nContinue anyways?",
|
||||||
|
"requiredOptionDialogText": "Some patch options have to be set."
|
||||||
|
},
|
||||||
|
"appSelectorCard": {
|
||||||
|
"widgetTitle": "Select an app",
|
||||||
|
"widgetTitleSelected": "Selected app",
|
||||||
|
"widgetSubtitle": "No app selected",
|
||||||
|
"noAppsLabel": "No applications found",
|
||||||
|
"currentVersion": "Current",
|
||||||
|
"suggestedVersion": "Suggested",
|
||||||
|
"anyVersion": "Any version"
|
||||||
|
},
|
||||||
|
"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 app",
|
||||||
|
"searchBarHint": "Search app",
|
||||||
|
"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 which can lead to unexpected issues. Please use the suggested version.\n\nSelected version: ${selected}\nSuggested version: ${suggested}\n\nTo continue anyway, disable \"Require suggested app version\" in the settings.",
|
||||||
|
"featureNotAvailable": "Feature not implemented",
|
||||||
|
"featureNotAvailableText": "This app is a split APK and can only be patched and installed reliably by mounting with root permissions. However, you can patch and install a full APK by selecting it from storage."
|
||||||
|
},
|
||||||
|
"patchesSelectorView": {
|
||||||
|
"viewTitle": "Select patches",
|
||||||
|
"searchBarHint": "Search patches",
|
||||||
|
"universalPatches": "Universal patches",
|
||||||
|
"newPatches": "New patches",
|
||||||
|
"patches": "Patches",
|
||||||
|
"doneButton": "Done",
|
||||||
|
"defaultChip": "Default",
|
||||||
|
"defaultTooltip": "Select all default patches",
|
||||||
|
"noneChip": "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 the settings before changing any patch selection.",
|
||||||
|
"patchesChangeWarningDialogButton": "Use default selection"
|
||||||
|
},
|
||||||
|
"installerView": {
|
||||||
|
"widgetTitle": "Installer",
|
||||||
|
"installType": "Select install type",
|
||||||
|
"installTypeDescription": "Select the installation type to continue with.",
|
||||||
|
"installButton": "Install",
|
||||||
|
"installRootType": "Mount",
|
||||||
|
"installNonRootType": "Regular",
|
||||||
|
"warning": "Disable auto updates for the patched app to avoid unexpected issues.",
|
||||||
|
"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",
|
||||||
|
"languageUpdated": "Language updated",
|
||||||
|
"englishOption": "English",
|
||||||
|
"sourcesLabel": "Sources",
|
||||||
|
"sourcesLabelHint": "Configure the source of patches and integrations",
|
||||||
|
"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 the URL of the API to use",
|
||||||
|
"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": "Do not prevent selecting or deselecting 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",
|
||||||
|
"showUpdateDialogLabel": "Show update dialog",
|
||||||
|
"showUpdateDialogHint": "Show a dialog when a new update is available",
|
||||||
|
"universalPatchesLabel": "Show universal patches",
|
||||||
|
"universalPatchesHint": "Display all apps and universal patches (may slow down the app list)",
|
||||||
|
"versionCompatibilityCheckLabel": "Version compatibility check",
|
||||||
|
"versionCompatibilityCheckHint": "Prevent selecting patches that are not compatible with the selected app version",
|
||||||
|
"requireSuggestedAppVersionLabel": "Require suggested app version",
|
||||||
|
"requireSuggestedAppVersionHint": "Prevent selecting an app with a version that is not the suggested",
|
||||||
|
"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",
|
||||||
|
"unmountButton": "Unmount",
|
||||||
|
"rootDialogTitle": "Error",
|
||||||
|
"unmountDialogText": "Are you sure you want to unmount this app?",
|
||||||
|
"uninstallDialogText": "Are you sure you want to uninstall 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",
|
||||||
|
"mountTypeLabel": "Mount",
|
||||||
|
"regularTypeLabel": "Regular",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"installErrorDialog": {
|
||||||
|
"mount_version_mismatch": "Version mismatch",
|
||||||
|
"mount_no_root": "No root access",
|
||||||
|
"mount_missing_installation": "Installation not found",
|
||||||
|
"status_failure_blocked": "Installation blocked",
|
||||||
|
"install_failed_verification_failure": "Verification failed",
|
||||||
|
"status_failure_invalid": "Installation invalid",
|
||||||
|
"install_failed_version_downgrade": "Can't downgrade",
|
||||||
|
"status_failure_conflict": "Installation conflict",
|
||||||
|
"status_failure_storage": "Installation storage issue",
|
||||||
|
"status_failure_incompatible": "Installation incompatible",
|
||||||
|
"status_failure_timeout": "Installation timeout",
|
||||||
|
"status_unknown": "Installation failed",
|
||||||
|
"mount_version_mismatch_description": "The installation failed due to the installed app being a different version than the patched app.\n\nInstall the version of the app you are mounting and try again.",
|
||||||
|
"mount_no_root_description": "The installation failed due to root access not being granted.\n\nGrant root access to ReVanced Manager and try again.",
|
||||||
|
"mount_missing_installation_description": "The installation failed due to the unpatched app not being installed on this device in order to mount over it.\n\nInstall the unpatched app before mounting and try again.",
|
||||||
|
"status_failure_timeout_description": "The installation took too long to finish.\n\nWould you like to try again?",
|
||||||
|
"status_failure_storage_description": "The installation failed due to insufficient storage.\n\nFree up some space and try again.",
|
||||||
|
"status_failure_invalid_description": "The installation failed due to the patched app being invalid.\n\nUninstall the app and try again?",
|
||||||
|
"status_failure_incompatible_description": "The app is incompatible with this device.\n\nContact the developer of the app and ask for support.",
|
||||||
|
"status_failure_conflict_description": "The installation was prevented by an existing installation of the app.\n\nUninstall the installed app and try again?",
|
||||||
|
"status_failure_blocked_description": "The installation was blocked by ${packageName}.\n\nAdjust your security settings and try again.",
|
||||||
|
"install_failed_verification_failure_description": "The installation failed due to a verification issue.\n\nAdjust your security settings and try again.",
|
||||||
|
"install_failed_version_downgrade_description": "The installation failed due to the patched app being a lower version than the installed app.\n\nUninstall the app and try again?",
|
||||||
|
"status_unknown_description": "The installation failed due to an unknown reason. Please try again."
|
||||||
|
}
|
||||||
|
}
|
10
crowdin.yml
10
crowdin.yml
@ -1,4 +1,8 @@
|
|||||||
preserve_hierarchy: 1
|
project_id_env: "CROWDIN_PROJECT_ID"
|
||||||
|
api_token_env: "CROWDIN_PERSONAL_TOKEN"
|
||||||
|
|
||||||
|
preserve_hierarchy: true
|
||||||
files:
|
files:
|
||||||
- source: /assets/i18n/en_US.json
|
- source: /assets/i18n/strings.i18n.json
|
||||||
translation: /assets/i18n/%locale_with_underscore%.json
|
translation: /assets/i18n/strings_%locale_with_underscore%.i18n.json
|
||||||
|
skip_untranslated_strings: true
|
||||||
|
@ -15,7 +15,13 @@ This page will guide you through building ReVanced Manager from source.
|
|||||||
flutter pub get
|
flutter pub get
|
||||||
```
|
```
|
||||||
|
|
||||||
4\. Delete conflicting outputs
|
4\. Generate translation file
|
||||||
|
|
||||||
|
```sh
|
||||||
|
dart run slang
|
||||||
|
```
|
||||||
|
|
||||||
|
5\. Delete conflicting outputs
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Must be run every time you sync your local repository with the remote repository.
|
> Must be run every time you sync your local repository with the remote repository.
|
||||||
@ -24,9 +30,7 @@ This page will guide you through building ReVanced Manager from source.
|
|||||||
dart run build_runner build --delete-conflicting-outputs
|
dart run build_runner build --delete-conflicting-outputs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
6\. Build the APK
|
||||||
|
|
||||||
5\. Build the APK
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
flutter build apk
|
flutter build apk
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
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/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/download_manager.dart';
|
||||||
import 'package:revanced_manager/services/github_api.dart';
|
import 'package:revanced_manager/services/github_api.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
@ -19,6 +16,7 @@ Future main() async {
|
|||||||
await setupLocator();
|
await setupLocator();
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await locator<ManagerAPI>().initialize();
|
await locator<ManagerAPI>().initialize();
|
||||||
|
|
||||||
await locator<DownloadManager>().initialize();
|
await locator<DownloadManager>().initialize();
|
||||||
final String apiUrl = locator<ManagerAPI>().getApiUrl();
|
final String apiUrl = locator<ManagerAPI>().getApiUrl();
|
||||||
await locator<RevancedAPI>().initialize(apiUrl);
|
await locator<RevancedAPI>().initialize(apiUrl);
|
||||||
@ -34,7 +32,11 @@ Future main() async {
|
|||||||
|
|
||||||
prefs = await SharedPreferences.getInstance();
|
prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
runApp(const MyApp());
|
final managerAPI = locator<ManagerAPI>();
|
||||||
|
final locale = managerAPI.getLocale();
|
||||||
|
LocaleSettings.setLocaleRaw(locale);
|
||||||
|
|
||||||
|
runApp(TranslationProvider(child: const MyApp()));
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
@ -42,32 +44,9 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// String rawLocale = prefs.getString('language') ?? 'en_US';
|
return const DynamicThemeBuilder(
|
||||||
// String replaceLocale = rawLocale.replaceAll('_', '-');
|
|
||||||
// List<String> localeList = replaceLocale.split('-');
|
|
||||||
// Locale locale = Locale(localeList[0], localeList[1]);
|
|
||||||
const Locale locale = Locale('en', 'US');
|
|
||||||
|
|
||||||
return DynamicThemeBuilder(
|
|
||||||
title: 'ReVanced Manager',
|
title: 'ReVanced Manager',
|
||||||
home: const NavigationView(),
|
home: 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,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ import 'package:device_apps/device_apps.dart';
|
|||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/widgets/I18nText.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.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/patch.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/github_api.dart';
|
import 'package:revanced_manager/services/github_api.dart';
|
||||||
@ -58,8 +58,7 @@ class ManagerAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isDefaultIntegrationsRepo() {
|
bool isDefaultIntegrationsRepo() {
|
||||||
return getIntegrationsRepo().toLowerCase() ==
|
return getIntegrationsRepo().toLowerCase() == defaultIntegrationsRepo;
|
||||||
defaultIntegrationsRepo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
@ -99,7 +98,7 @@ class ManagerAPI {
|
|||||||
}
|
}
|
||||||
await _revancedAPI.clearAllCache();
|
await _revancedAPI.clearAllCache();
|
||||||
await _prefs.setString('apiUrl', url);
|
await _prefs.setString('apiUrl', url);
|
||||||
_toast.showBottom('settingsView.restartAppForChanges');
|
_toast.showBottom(t.settingsView.restartAppForChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getRepoUrl() {
|
String getRepoUrl() {
|
||||||
@ -302,6 +301,14 @@ class ManagerAPI {
|
|||||||
return _prefs.getString('keystorePassword') ?? defaultKeystorePassword;
|
return _prefs.getString('keystorePassword') ?? defaultKeystorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getLocale() {
|
||||||
|
return _prefs.getString('locale') ?? 'en';
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setLocale(String value) async {
|
||||||
|
await _prefs.setString('locale', value);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> deleteTempFolder() async {
|
Future<void> deleteTempFolder() async {
|
||||||
final Directory dir = Directory('/data/local/tmp/revanced-manager');
|
final Directory dir = Directory('/data/local/tmp/revanced-manager');
|
||||||
if (await dir.exists()) {
|
if (await dir.exists()) {
|
||||||
@ -615,7 +622,7 @@ class ManagerAPI {
|
|||||||
builder: (context) => PopScope(
|
builder: (context) => PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: ValueListenableBuilder(
|
content: ValueListenableBuilder(
|
||||||
valueListenable: noShow,
|
valueListenable: noShow,
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
@ -623,22 +630,19 @@ class ManagerAPI {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'patchItem.patchesChangeWarningDialogText',
|
t.patchItem.patchesChangeWarningDialogText,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
HapticCheckboxListTile(
|
HapticCheckboxListTile(
|
||||||
value: value,
|
value: value,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'noShowAgain',
|
t.noShowAgain,
|
||||||
),
|
),
|
||||||
onChanged: (selected) {
|
onChanged: (selected) {
|
||||||
noShow.value = selected!;
|
noShow.value = selected!;
|
||||||
@ -654,7 +658,7 @@ class ManagerAPI {
|
|||||||
setPatchesChangeWarning(noShow.value);
|
setPatchesChangeWarning(noShow.value);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -6,10 +6,10 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
|
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
|
||||||
import 'package:flutter_i18n/widgets/I18nText.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.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/patch.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
@ -304,19 +304,20 @@ class PatcherAPI {
|
|||||||
context: _managerAPI.ctx!,
|
context: _managerAPI.ctx!,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
title: I18nText('installErrorDialog.$statusValue'),
|
title: Text(t['installErrorDialog.$statusValue']),
|
||||||
content: Column(
|
content: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'installErrorDialog.${statusValue}_description',
|
t['installErrorDialog.${statusValue}_description'](
|
||||||
translationParams: statusCode == 2
|
packageName: statusCode == 2
|
||||||
? {
|
? {
|
||||||
'packageName': status['otherPackageName'],
|
'packageName': status['otherPackageName'],
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: (status == null)
|
actions: (status == null)
|
||||||
@ -325,7 +326,7 @@ class PatcherAPI {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
: <Widget>[
|
: <Widget>[
|
||||||
@ -334,14 +335,14 @@ class PatcherAPI {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
if (isFixable)
|
if (isFixable)
|
||||||
FilledButton(
|
FilledButton(
|
||||||
@ -355,7 +356,7 @@ class PatcherAPI {
|
|||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:fluttertoast/fluttertoast.dart' as t;
|
import 'package:fluttertoast/fluttertoast.dart' as t;
|
||||||
|
|
||||||
class Toast {
|
class Toast {
|
||||||
@ -12,10 +11,7 @@ class Toast {
|
|||||||
|
|
||||||
void show(String text) {
|
void show(String text) {
|
||||||
t.Fluttertoast.showToast(
|
t.Fluttertoast.showToast(
|
||||||
msg: FlutterI18n.translate(
|
msg: text,
|
||||||
_fToast.context!,
|
|
||||||
text,
|
|
||||||
),
|
|
||||||
toastLength: t.Toast.LENGTH_LONG,
|
toastLength: t.Toast.LENGTH_LONG,
|
||||||
gravity: t.ToastGravity.CENTER,
|
gravity: t.ToastGravity.CENTER,
|
||||||
);
|
);
|
||||||
@ -23,10 +19,7 @@ class Toast {
|
|||||||
|
|
||||||
void showBottom(String text) {
|
void showBottom(String text) {
|
||||||
t.Fluttertoast.showToast(
|
t.Fluttertoast.showToast(
|
||||||
msg: FlutterI18n.translate(
|
msg: text,
|
||||||
_fToast.context!,
|
|
||||||
text,
|
|
||||||
),
|
|
||||||
toastLength: t.Toast.LENGTH_LONG,
|
toastLength: t.Toast.LENGTH_LONG,
|
||||||
gravity: t.ToastGravity.BOTTOM,
|
gravity: t.ToastGravity.BOTTOM,
|
||||||
);
|
);
|
||||||
|
@ -3,9 +3,11 @@ import 'package:dynamic_color/dynamic_color.dart';
|
|||||||
import 'package:dynamic_themes/dynamic_themes.dart';
|
import 'package:dynamic_themes/dynamic_themes.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/app/app.router.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/manager_api.dart';
|
||||||
import 'package:revanced_manager/theme.dart';
|
import 'package:revanced_manager/theme.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
@ -15,11 +17,9 @@ class DynamicThemeBuilder extends StatefulWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.home,
|
required this.home,
|
||||||
required this.localizationsDelegates,
|
|
||||||
});
|
});
|
||||||
final String title;
|
final String title;
|
||||||
final Widget home;
|
final Widget home;
|
||||||
final Iterable<LocalizationsDelegate> localizationsDelegates;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<DynamicThemeBuilder> createState() => _DynamicThemeBuilderState();
|
State<DynamicThemeBuilder> createState() => _DynamicThemeBuilderState();
|
||||||
@ -108,7 +108,9 @@ class _DynamicThemeBuilderState extends State<DynamicThemeBuilder>
|
|||||||
onGenerateRoute: StackedRouter().onGenerateRoute,
|
onGenerateRoute: StackedRouter().onGenerateRoute,
|
||||||
theme: theme,
|
theme: theme,
|
||||||
home: widget.home,
|
home: widget.home,
|
||||||
localizationsDelegates: widget.localizationsDelegates,
|
localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
||||||
|
locale: TranslationProvider.of(context).flutterLocale,
|
||||||
|
supportedLocales: AppLocaleUtils.supportedLocales,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart' hide SearchBar;
|
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/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/app_skeleton_loader.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/appSelectorView/installed_app_item.dart';
|
import 'package:revanced_manager/ui/widgets/appSelectorView/installed_app_item.dart';
|
||||||
@ -25,7 +25,7 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||||||
viewModelBuilder: () => AppSelectorViewModel(),
|
viewModelBuilder: () => AppSelectorViewModel(),
|
||||||
builder: (context, model, child) => Scaffold(
|
builder: (context, model, child) => Scaffold(
|
||||||
floatingActionButton: HapticFloatingActionButtonExtended(
|
floatingActionButton: HapticFloatingActionButtonExtended(
|
||||||
label: I18nText('appSelectorView.storageButton'),
|
label: Text(t.appSelectorView.storageButton),
|
||||||
icon: const Icon(Icons.sd_storage),
|
icon: const Icon(Icons.sd_storage),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
model.selectAppFromStorage(context);
|
model.selectAppFromStorage(context);
|
||||||
@ -36,8 +36,8 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
floating: true,
|
floating: true,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'appSelectorView.viewTitle',
|
t.appSelectorView.viewTitle,
|
||||||
),
|
),
|
||||||
titleTextStyle: TextStyle(
|
titleTextStyle: TextStyle(
|
||||||
fontSize: 22.0,
|
fontSize: 22.0,
|
||||||
@ -58,10 +58,7 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||||||
horizontal: 12.0,
|
horizontal: 12.0,
|
||||||
),
|
),
|
||||||
child: SearchBar(
|
child: SearchBar(
|
||||||
hintText: FlutterI18n.translate(
|
hintText: t.appSelectorView.searchBarHint,
|
||||||
context,
|
|
||||||
'appSelectorView.searchBarHint',
|
|
||||||
),
|
|
||||||
onQueryChanged: (searchQuery) {
|
onQueryChanged: (searchQuery) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_query = searchQuery;
|
_query = searchQuery;
|
||||||
@ -74,14 +71,10 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: model.noApps
|
child: model.noApps
|
||||||
? Center(
|
? Center(
|
||||||
child: I18nText(
|
|
||||||
'appSelectorCard.noAppsLabel',
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
t.appSelectorCard.noAppsLabel,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color:
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
Theme.of(context).textTheme.titleLarge!.color,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -5,8 +5,8 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_file_dialog/flutter_file_dialog.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/app/app.locator.dart';
|
||||||
|
import 'package:revanced_manager/gen/strings.g.dart';
|
||||||
import 'package:revanced_manager/models/patch.dart';
|
import 'package:revanced_manager/models/patch.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
@ -168,25 +168,22 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'appSelectorView.requireSuggestedAppVersionDialogText',
|
t.appSelectorView.requireSuggestedAppVersionDialogText(
|
||||||
translationParams: {
|
suggested: suggestedVersion,
|
||||||
'suggested': suggestedVersion,
|
selected: selectedVersion,
|
||||||
'selected': selectedVersion,
|
),
|
||||||
},
|
style: const TextStyle(
|
||||||
child: const Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -208,28 +205,22 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
color: Theme.of(innerContext).colorScheme.primary,
|
color: Theme.of(innerContext).colorScheme.primary,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
I18nText(
|
Text(
|
||||||
'appSelectorView.featureNotAvailable',
|
t.appSelectorView.featureNotAvailable,
|
||||||
child: const Text(
|
|
||||||
'',
|
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
wordSpacing: 1.5,
|
wordSpacing: 1.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
I18nText(
|
Text(
|
||||||
'appSelectorView.featureNotAvailableText',
|
t.appSelectorView.featureNotAvailableText,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@ -241,7 +232,7 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Icons.sd_card),
|
const Icon(Icons.sd_card),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
I18nText('appSelectorView.selectFromStorageButton'),
|
Text(t.appSelectorView.selectFromStorageButton),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -254,7 +245,7 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
I18nText('cancelButton'),
|
Text(t.cancelButton),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -295,7 +286,7 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e);
|
print(e);
|
||||||
}
|
}
|
||||||
_toast.showBottom('appSelectorView.errorMessage');
|
_toast.showBottom(t.appSelectorView.errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,5 +314,5 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showDownloadToast() =>
|
void showDownloadToast() =>
|
||||||
_toast.showBottom('appSelectorView.downloadToast');
|
_toast.showBottom(t.appSelectorView.downloadToast);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.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/views/contributors/contributors_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/contributorsView/contributors_card.dart';
|
import 'package:revanced_manager/ui/widgets/contributorsView/contributors_card.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
|
||||||
@ -18,43 +18,40 @@ class ContributorsView extends StatelessWidget {
|
|||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
CustomSliverAppBar(
|
CustomSliverAppBar(
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'contributorsView.widgetTitle',
|
t.contributorsView.widgetTitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(
|
||||||
color: Theme.of(context).textTheme.titleLarge!.color,
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
delegate: SliverChildListDelegate.fixed(
|
delegate: SliverChildListDelegate.fixed(
|
||||||
<Widget>[
|
<Widget>[
|
||||||
ContributorsCard(
|
ContributorsCard(
|
||||||
title: 'contributorsView.patcherContributors',
|
title: t.contributorsView.patcherContributors,
|
||||||
contributors: model.patcherContributors,
|
contributors: model.patcherContributors,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ContributorsCard(
|
ContributorsCard(
|
||||||
title: 'contributorsView.patchesContributors',
|
title: t.contributorsView.patchesContributors,
|
||||||
contributors: model.patchesContributors,
|
contributors: model.patchesContributors,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ContributorsCard(
|
ContributorsCard(
|
||||||
title: 'contributorsView.integrationsContributors',
|
title: t.contributorsView.integrationsContributors,
|
||||||
contributors: model.integrationsContributors,
|
contributors: model.integrationsContributors,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ContributorsCard(
|
ContributorsCard(
|
||||||
title: 'contributorsView.cliContributors',
|
title: t.contributorsView.cliContributors,
|
||||||
contributors: model.cliContributors,
|
contributors: model.cliContributors,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ContributorsCard(
|
ContributorsCard(
|
||||||
title: 'contributorsView.managerContributors',
|
title: t.contributorsView.managerContributors,
|
||||||
contributors: model.managerContributors,
|
contributors: model.managerContributors,
|
||||||
),
|
),
|
||||||
SizedBox(height: MediaQuery.viewPaddingOf(context).bottom),
|
SizedBox(height: MediaQuery.viewPaddingOf(context).bottom),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.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/views/home/home_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/homeView/installed_apps_card.dart';
|
import 'package:revanced_manager/ui/widgets/homeView/installed_apps_card.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/homeView/latest_commit_card.dart';
|
import 'package:revanced_manager/ui/widgets/homeView/latest_commit_card.dart';
|
||||||
@ -25,38 +25,29 @@ class HomeView extends StatelessWidget {
|
|||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
CustomSliverAppBar(
|
CustomSliverAppBar(
|
||||||
isMainView: true,
|
isMainView: true,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'homeView.widgetTitle',
|
t.homeView.widgetTitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(
|
||||||
color: Theme.of(context).textTheme.titleLarge!.color,
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
delegate: SliverChildListDelegate.fixed(
|
delegate: SliverChildListDelegate.fixed(
|
||||||
<Widget>[
|
<Widget>[
|
||||||
I18nText(
|
Text(
|
||||||
'homeView.updatesSubtitle',
|
t.homeView.updatesSubtitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
LatestCommitCard(model: model, parentContext: context),
|
LatestCommitCard(model: model, parentContext: context),
|
||||||
const SizedBox(height: 23),
|
const SizedBox(height: 23),
|
||||||
I18nText(
|
Text(
|
||||||
'homeView.patchedSubtitle',
|
t.homeView.patchedSubtitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
InstalledAppsCard(),
|
InstalledAppsCard(),
|
||||||
],
|
],
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/app/app.router.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/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/github_api.dart';
|
import 'package:revanced_manager/services/github_api.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
@ -68,12 +69,12 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
),
|
),
|
||||||
onDidReceiveNotificationResponse: (response) async {
|
onDidReceiveNotificationResponse: (response) async {
|
||||||
if (response.id == 0) {
|
if (response.id == 0) {
|
||||||
_toast.showBottom('homeView.installingMessage');
|
_toast.showBottom(t.homeView.installingMessage);
|
||||||
final File? managerApk = await _managerAPI.downloadManager();
|
final File? managerApk = await _managerAPI.downloadManager();
|
||||||
if (managerApk != null) {
|
if (managerApk != null) {
|
||||||
await _patcherAPI.installApk(context, managerApk.path);
|
await _patcherAPI.installApk(context, managerApk.path);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('homeView.errorDownloadMessage');
|
_toast.showBottom(t.homeView.errorDownloadMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -82,22 +83,21 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
.resolvePlatformSpecificImplementation<
|
.resolvePlatformSpecificImplementation<
|
||||||
AndroidFlutterLocalNotificationsPlugin>()
|
AndroidFlutterLocalNotificationsPlugin>()
|
||||||
?.requestNotificationsPermission();
|
?.requestNotificationsPermission();
|
||||||
|
|
||||||
final bool isConnected =
|
final bool isConnected =
|
||||||
await Connectivity().checkConnectivity() != ConnectivityResult.none;
|
await Connectivity().checkConnectivity() != ConnectivityResult.none;
|
||||||
if (!isConnected) {
|
if (!isConnected) {
|
||||||
_toast.showBottom('homeView.noConnection');
|
_toast.showBottom(t.homeView.noConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
|
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
|
||||||
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
|
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
|
||||||
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
|
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
|
||||||
_toast.showBottom('homeView.installingMessage');
|
_toast.showBottom(t.homeView.installingMessage);
|
||||||
final File? managerApk = await _managerAPI.downloadManager();
|
final File? managerApk = await _managerAPI.downloadManager();
|
||||||
if (managerApk != null) {
|
if (managerApk != null) {
|
||||||
await _patcherAPI.installApk(context, managerApk.path);
|
await _patcherAPI.installApk(context, managerApk.path);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('homeView.errorDownloadMessage');
|
_toast.showBottom(t.homeView.errorDownloadMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
builder: (context) => PopScope(
|
builder: (context) => PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
title: I18nText('homeView.downloadConsentDialogTitle'),
|
title: Text(t.homeView.downloadConsentDialogTitle),
|
||||||
content: ValueListenableBuilder(
|
content: ValueListenableBuilder(
|
||||||
valueListenable: autoUpdate,
|
valueListenable: autoUpdate,
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
@ -191,26 +191,20 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'homeView.downloadConsentDialogText',
|
t.homeView.downloadConsentDialogText,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
child: I18nText(
|
|
||||||
'homeView.downloadConsentDialogText2',
|
|
||||||
translationParams: {
|
|
||||||
'url': _managerAPI.defaultApiUrl.split('/')[2],
|
|
||||||
},
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
t.homeView.downloadConsentDialogText2(
|
||||||
|
url: _managerAPI.defaultApiUrl.split('/')[2],
|
||||||
|
),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -218,7 +212,6 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -229,7 +222,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
_managerAPI.setDownloadConsent(false);
|
_managerAPI.setDownloadConsent(false);
|
||||||
SystemNavigator.pop();
|
SystemNavigator.pop();
|
||||||
},
|
},
|
||||||
child: I18nText('quitButton'),
|
child: Text(t.quitButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@ -237,7 +230,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
_managerAPI.setPatchesAutoUpdate(autoUpdate.value);
|
_managerAPI.setPatchesAutoUpdate(autoUpdate.value);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -251,7 +244,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (innerContext) => AlertDialog(
|
builder: (innerContext) => AlertDialog(
|
||||||
title: I18nText('homeView.updateDialogTitle'),
|
title: Text(t.homeView.updateDialogTitle),
|
||||||
content: ValueListenableBuilder(
|
content: ValueListenableBuilder(
|
||||||
valueListenable: noShow,
|
valueListenable: noShow,
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
@ -259,33 +252,25 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'homeView.updateDialogText',
|
t.homeView.updateDialogText(
|
||||||
translationParams: {
|
file: isPatches ? 'ReVanced Patches' : 'ReVanced Manager',
|
||||||
'file': isPatches ? 'ReVanced Patches' : 'ReVanced Manager',
|
version: isPatches
|
||||||
'version': isPatches
|
|
||||||
? _currentPatchesVersion
|
? _currentPatchesVersion
|
||||||
: _currentManagerVersion,
|
: _currentManagerVersion,
|
||||||
},
|
),
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
HapticCheckboxListTile(
|
HapticCheckboxListTile(
|
||||||
value: value,
|
value: value,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
title: I18nText(
|
title: Text(t.noShowAgain),
|
||||||
'noShowAgain',
|
subtitle: Text(t.homeView.changeLaterSubtitle),
|
||||||
),
|
|
||||||
subtitle: I18nText(
|
|
||||||
'homeView.changeLaterSubtitle',
|
|
||||||
),
|
|
||||||
onChanged: (selected) {
|
onChanged: (selected) {
|
||||||
noShow.value = selected!;
|
noShow.value = selected!;
|
||||||
},
|
},
|
||||||
@ -300,7 +285,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
_managerAPI.setShowUpdateDialog(!noShow.value);
|
_managerAPI.setShowUpdateDialog(!noShow.value);
|
||||||
Navigator.pop(innerContext);
|
Navigator.pop(innerContext);
|
||||||
},
|
},
|
||||||
child: I18nText('dismissButton'), // Decide later
|
child: Text(t.dismissButton), // Decide later
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@ -308,7 +293,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
Navigator.pop(innerContext);
|
Navigator.pop(innerContext);
|
||||||
await showUpdateConfirmationDialog(context, isPatches);
|
await showUpdateConfirmationDialog(context, isPatches);
|
||||||
},
|
},
|
||||||
child: I18nText('showUpdateButton'),
|
child: Text(t.showUpdateButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -316,7 +301,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updatePatches(BuildContext context) async {
|
Future<void> updatePatches(BuildContext context) async {
|
||||||
_toast.showBottom('homeView.downloadingMessage');
|
_toast.showBottom(t.homeView.downloadingMessage);
|
||||||
final String patchesVersion =
|
final String patchesVersion =
|
||||||
await _managerAPI.getLatestPatchesVersion() ?? '0.0.0';
|
await _managerAPI.getLatestPatchesVersion() ?? '0.0.0';
|
||||||
final String integrationsVersion =
|
final String integrationsVersion =
|
||||||
@ -324,27 +309,27 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
if (patchesVersion != '0.0.0' && integrationsVersion != '0.0.0') {
|
if (patchesVersion != '0.0.0' && integrationsVersion != '0.0.0') {
|
||||||
await _managerAPI.setCurrentPatchesVersion(patchesVersion);
|
await _managerAPI.setCurrentPatchesVersion(patchesVersion);
|
||||||
await _managerAPI.setCurrentIntegrationsVersion(integrationsVersion);
|
await _managerAPI.setCurrentIntegrationsVersion(integrationsVersion);
|
||||||
_toast.showBottom('homeView.downloadedMessage');
|
_toast.showBottom(t.homeView.downloadedMessage);
|
||||||
forceRefresh(context);
|
forceRefresh(context);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('homeView.errorDownloadMessage');
|
_toast.showBottom(t.homeView.errorDownloadMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateManager(BuildContext context) async {
|
Future<void> updateManager(BuildContext context) async {
|
||||||
final ValueNotifier<bool> downloaded = ValueNotifier(false);
|
final ValueNotifier<bool> downloaded = ValueNotifier(false);
|
||||||
try {
|
try {
|
||||||
_toast.showBottom('homeView.downloadingMessage');
|
_toast.showBottom(t.homeView.downloadingMessage);
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => ValueListenableBuilder(
|
builder: (context) => ValueListenableBuilder(
|
||||||
valueListenable: downloaded,
|
valueListenable: downloaded,
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: I18nText(
|
title: Text(
|
||||||
!value
|
!value
|
||||||
? 'homeView.downloadingMessage'
|
? t.homeView.downloadingMessage
|
||||||
: 'homeView.downloadedMessage',
|
: t.homeView.downloadedMessage,
|
||||||
),
|
),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@ -373,7 +358,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
_revancedAPI.disposeManagerUpdateProgress();
|
_revancedAPI.disposeManagerUpdateProgress();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -382,17 +367,14 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'homeView.installUpdate',
|
t.homeView.installUpdate,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 16.0),
|
const SizedBox(height: 16.0),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
@ -403,7 +385,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8.0),
|
const SizedBox(width: 8.0),
|
||||||
@ -416,7 +398,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
downloadedApk!.path,
|
downloadedApk!.path,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: I18nText('updateButton'),
|
child: Text(t.updateButton),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -457,21 +439,21 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
// uiLocalNotificationDateInterpretation:
|
// uiLocalNotificationDateInterpretation:
|
||||||
// UILocalNotificationDateInterpretation.absoluteTime,
|
// UILocalNotificationDateInterpretation.absoluteTime,
|
||||||
// );
|
// );
|
||||||
_toast.showBottom('homeView.installingMessage');
|
_toast.showBottom(t.homeView.installingMessage);
|
||||||
await _patcherAPI.installApk(context, managerApk.path);
|
await _patcherAPI.installApk(context, managerApk.path);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('homeView.errorDownloadMessage');
|
_toast.showBottom(t.homeView.errorDownloadMessage);
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e);
|
print(e);
|
||||||
}
|
}
|
||||||
_toast.showBottom('homeView.errorInstallMessage');
|
_toast.showBottom(t.homeView.errorInstallMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatesAreDisabled() {
|
void updatesAreDisabled() {
|
||||||
_toast.showBottom('homeView.updatesDisabled');
|
_toast.showBottom(t.homeView.updatesDisabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> showUpdateConfirmationDialog(
|
Future<void> showUpdateConfirmationDialog(
|
||||||
@ -510,7 +492,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
|
|
||||||
Future<void> forceRefresh(BuildContext context) async {
|
Future<void> forceRefresh(BuildContext context) async {
|
||||||
_managerAPI.clearAllData();
|
_managerAPI.clearAllData();
|
||||||
_toast.showBottom('homeView.refreshSuccess');
|
_toast.showBottom(t.homeView.refreshSuccess);
|
||||||
initialize(context);
|
initialize(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.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/views/installer/installer_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/installerView/gradient_progress_indicator.dart';
|
import 'package:revanced_manager/ui/widgets/installerView/gradient_progress_indicator.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
@ -26,10 +26,10 @@ class InstallerView extends StatelessWidget {
|
|||||||
floatingActionButton: Visibility(
|
floatingActionButton: Visibility(
|
||||||
visible: !model.isPatching && !model.hasErrors,
|
visible: !model.isPatching && !model.hasErrors,
|
||||||
child: HapticFloatingActionButtonExtended(
|
child: HapticFloatingActionButtonExtended(
|
||||||
label: I18nText(
|
label: Text(
|
||||||
model.isInstalled
|
model.isInstalled
|
||||||
? 'installerView.openButton'
|
? t.installerView.openButton
|
||||||
: 'installerView.installButton',
|
: t.installerView.installButton,
|
||||||
),
|
),
|
||||||
icon: model.isInstalled
|
icon: model.isInstalled
|
||||||
? const Icon(Icons.open_in_new)
|
? const Icon(Icons.open_in_new)
|
||||||
@ -54,19 +54,13 @@ class InstallerView extends StatelessWidget {
|
|||||||
Visibility(
|
Visibility(
|
||||||
visible: !model.hasErrors,
|
visible: !model.hasErrors,
|
||||||
child: IconButton.filledTonal(
|
child: IconButton.filledTonal(
|
||||||
tooltip: FlutterI18n.translate(
|
tooltip: t.installerView.exportApkButtonTooltip,
|
||||||
context,
|
|
||||||
'installerView.exportApkButtonTooltip',
|
|
||||||
),
|
|
||||||
icon: const Icon(Icons.save),
|
icon: const Icon(Icons.save),
|
||||||
onPressed: () => model.onButtonPressed(0),
|
onPressed: () => model.onButtonPressed(0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton.filledTonal(
|
IconButton.filledTonal(
|
||||||
tooltip: FlutterI18n.translate(
|
tooltip: t.installerView.exportLogButtonTooltip,
|
||||||
context,
|
|
||||||
'installerView.exportLogButtonTooltip',
|
|
||||||
),
|
|
||||||
icon: const Icon(Icons.post_add),
|
icon: const Icon(Icons.post_add),
|
||||||
onPressed: () => model.onButtonPressed(1),
|
onPressed: () => model.onButtonPressed(1),
|
||||||
),
|
),
|
||||||
|
@ -4,9 +4,9 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_background/flutter_background.dart';
|
import 'package:flutter_background/flutter_background.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.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/patch.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
@ -49,14 +49,8 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
try {
|
try {
|
||||||
FlutterBackground.initialize(
|
FlutterBackground.initialize(
|
||||||
androidConfig: FlutterBackgroundAndroidConfig(
|
androidConfig: FlutterBackgroundAndroidConfig(
|
||||||
notificationTitle: FlutterI18n.translate(
|
notificationTitle: t.installerView.notificationTitle,
|
||||||
context,
|
notificationText: t.installerView.notificationText,
|
||||||
'installerView.notificationTitle',
|
|
||||||
),
|
|
||||||
notificationText: FlutterI18n.translate(
|
|
||||||
context,
|
|
||||||
'installerView.notificationText',
|
|
||||||
),
|
|
||||||
notificationIcon: const AndroidResource(
|
notificationIcon: const AndroidResource(
|
||||||
name: 'ic_notification',
|
name: 'ic_notification',
|
||||||
),
|
),
|
||||||
@ -280,26 +274,26 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
];
|
];
|
||||||
|
|
||||||
Clipboard.setData(ClipboardData(text: formattedLogs.join('\n')));
|
Clipboard.setData(ClipboardData(text: formattedLogs.join('\n')));
|
||||||
_toast.showBottom('installerView.copiedToClipboard');
|
_toast.showBottom(t.installerView.copiedToClipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> screenshotDetected(BuildContext context) async {
|
Future<void> screenshotDetected(BuildContext context) async {
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'warning',
|
t.warning,
|
||||||
),
|
),
|
||||||
icon: const Icon(Icons.warning),
|
icon: const Icon(Icons.warning),
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: I18nText('installerView.screenshotDetected'),
|
child: Text(t.installerView.screenshotDetected),
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -307,7 +301,7 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
showPopupScreenshotWarning = true;
|
showPopupScreenshotWarning = true;
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -321,8 +315,8 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (innerContext) => AlertDialog(
|
builder: (innerContext) => AlertDialog(
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'installerView.installType',
|
t.installerView.installType,
|
||||||
),
|
),
|
||||||
icon: const Icon(Icons.file_download_outlined),
|
icon: const Icon(Icons.file_download_outlined),
|
||||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
@ -339,10 +333,8 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
horizontal: 20,
|
horizontal: 20,
|
||||||
vertical: 10,
|
vertical: 10,
|
||||||
),
|
),
|
||||||
child: I18nText(
|
|
||||||
'installerView.installTypeDescription',
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
t.installerView.installTypeDescription,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -350,9 +342,8 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
RadioListTile(
|
RadioListTile(
|
||||||
title: I18nText('installerView.installNonRootType'),
|
title: Text(t.installerView.installNonRootType),
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.symmetric(horizontal: 16),
|
const EdgeInsets.symmetric(horizontal: 16),
|
||||||
value: 0,
|
value: 0,
|
||||||
@ -362,7 +353,7 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
RadioListTile(
|
RadioListTile(
|
||||||
title: I18nText('installerView.installRootType'),
|
title: Text(t.installerView.installRootType),
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.symmetric(horizontal: 16),
|
const EdgeInsets.symmetric(horizontal: 16),
|
||||||
value: 1,
|
value: 1,
|
||||||
@ -373,17 +364,14 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: I18nText(
|
|
||||||
'installerView.warning',
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
t.installerView.warning,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context).colorScheme.error,
|
color: Theme.of(context).colorScheme.error,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -394,14 +382,14 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(innerContext).pop();
|
Navigator.of(innerContext).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(innerContext).pop();
|
Navigator.of(innerContext).pop();
|
||||||
installResult(context, installType.value == 1);
|
installResult(context, installType.value == 1);
|
||||||
},
|
},
|
||||||
child: I18nText('installerView.installButton'),
|
child: Text(t.installerView.installButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -411,24 +399,22 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (innerContext) => AlertDialog(
|
builder: (innerContext) => AlertDialog(
|
||||||
title: I18nText(
|
title: Text(t.warning),
|
||||||
'warning',
|
|
||||||
),
|
|
||||||
contentPadding: const EdgeInsets.all(16),
|
contentPadding: const EdgeInsets.all(16),
|
||||||
content: I18nText('installerView.warning'),
|
content: Text(t.installerView.warning),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(innerContext).pop();
|
Navigator.of(innerContext).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(innerContext).pop();
|
Navigator.of(innerContext).pop();
|
||||||
installResult(context, false);
|
installResult(context, false);
|
||||||
},
|
},
|
||||||
child: I18nText('installerView.installButton'),
|
child: Text(t.installerView.installButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -544,11 +530,11 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
if (isPatching) {
|
if (isPatching) {
|
||||||
if (!cancel) {
|
if (!cancel) {
|
||||||
cancel = true;
|
cancel = true;
|
||||||
_toast.showBottom('installerView.pressBackAgain');
|
_toast.showBottom(t.installerView.pressBackAgain);
|
||||||
} else if (!isCanceled) {
|
} else if (!isCanceled) {
|
||||||
await stopPatcher();
|
await stopPatcher();
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('installerView.noExit');
|
_toast.showBottom(t.installerView.noExit);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
import 'package:flutter/material.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/app/app.locator.dart';
|
||||||
|
import 'package:revanced_manager/gen/strings.g.dart';
|
||||||
import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
|
|
||||||
@ -43,30 +43,21 @@ class NavigationView extends StatelessWidget {
|
|||||||
icon: model.isIndexSelected(0)
|
icon: model.isIndexSelected(0)
|
||||||
? const Icon(Icons.dashboard)
|
? const Icon(Icons.dashboard)
|
||||||
: const Icon(Icons.dashboard_outlined),
|
: const Icon(Icons.dashboard_outlined),
|
||||||
label: FlutterI18n.translate(
|
label: t.navigationView.dashboardTab,
|
||||||
context,
|
|
||||||
'navigationView.dashboardTab',
|
|
||||||
),
|
|
||||||
tooltip: '',
|
tooltip: '',
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
icon: model.isIndexSelected(1)
|
icon: model.isIndexSelected(1)
|
||||||
? const Icon(Icons.build)
|
? const Icon(Icons.build)
|
||||||
: const Icon(Icons.build_outlined),
|
: const Icon(Icons.build_outlined),
|
||||||
label: FlutterI18n.translate(
|
label: t.navigationView.patcherTab,
|
||||||
context,
|
|
||||||
'navigationView.patcherTab',
|
|
||||||
),
|
|
||||||
tooltip: '',
|
tooltip: '',
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
icon: model.isIndexSelected(2)
|
icon: model.isIndexSelected(2)
|
||||||
? const Icon(Icons.settings)
|
? const Icon(Icons.settings)
|
||||||
: const Icon(Icons.settings_outlined),
|
: const Icon(Icons.settings_outlined),
|
||||||
label: FlutterI18n.translate(
|
label: t.navigationView.settingsTab,
|
||||||
context,
|
|
||||||
'navigationView.settingsTab',
|
|
||||||
),
|
|
||||||
tooltip: '',
|
tooltip: '',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.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/models/patch.dart';
|
||||||
import 'package:revanced_manager/ui/views/patch_options/patch_options_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patch_options/patch_options_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/patchesSelectorView/patch_options_fields.dart';
|
import 'package:revanced_manager/ui/widgets/patchesSelectorView/patch_options_fields.dart';
|
||||||
@ -25,21 +25,18 @@ class PatchOptionsView extends StatelessWidget {
|
|||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
label: I18nText('patchOptionsView.saveOptions'),
|
label: Text(t.patchOptionsView.saveOptions),
|
||||||
icon: const Icon(Icons.save),
|
icon: const Icon(Icons.save),
|
||||||
),
|
),
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'patchOptionsView.viewTitle',
|
t.patchOptionsView.viewTitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(
|
||||||
color: Theme.of(context).textTheme.titleLarge!.color,
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -48,10 +45,7 @@ class PatchOptionsView extends StatelessWidget {
|
|||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.history,
|
Icons.history,
|
||||||
),
|
),
|
||||||
tooltip: FlutterI18n.translate(
|
tooltip: t.patchOptionsView.resetOptionsTooltip,
|
||||||
context,
|
|
||||||
'patchOptionsView.resetOptionsTooltip',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -111,7 +105,7 @@ class PatchOptionsView extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.add),
|
const Icon(Icons.add),
|
||||||
I18nText('patchOptionsView.addOptions'),
|
Text(t.patchOptionsView.addOptions),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.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.locator.dart';
|
||||||
|
import 'package:revanced_manager/gen/strings.g.dart';
|
||||||
import 'package:revanced_manager/models/patch.dart';
|
import 'package:revanced_manager/models/patch.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||||
@ -137,8 +137,8 @@ class PatchOptionsViewModel extends BaseViewModel {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'patchOptionsView.addOptions',
|
t.patchOptionsView.addOptions,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'',
|
'',
|
||||||
@ -154,7 +154,7 @@ class PatchOptionsViewModel extends BaseViewModel {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
contentPadding: const EdgeInsets.all(8),
|
contentPadding: const EdgeInsets.all(8),
|
||||||
@ -224,7 +224,7 @@ Future<void> showRequiredOptionNullDialog(
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('notice'),
|
title: Text(t.notice),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@ -248,20 +248,19 @@ Future<void> showRequiredOptionNullDialog(
|
|||||||
PatchesSelectorViewModel().showPatchesChangeDialog(context);
|
PatchesSelectorViewModel().showPatchesChangeDialog(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: I18nText('patchOptionsView.deselectPatch'),
|
child: Text(t.patchOptionsView.deselectPatch),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'patchOptionsView.requiredOptionNull',
|
t.patchOptionsView.requiredOptionNull(
|
||||||
translationParams: {
|
options: optionsTitles.join('\n'),
|
||||||
'options': optionsTitles.join('\n'),
|
),
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.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/views/patcher/patcher_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/patcherView/app_selector_card.dart';
|
import 'package:revanced_manager/ui/widgets/patcherView/app_selector_card.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/patcherView/patch_selector_card.dart';
|
import 'package:revanced_manager/ui/widgets/patcherView/patch_selector_card.dart';
|
||||||
@ -21,7 +21,7 @@ class PatcherView extends StatelessWidget {
|
|||||||
floatingActionButton: Visibility(
|
floatingActionButton: Visibility(
|
||||||
visible: model.showPatchButton(),
|
visible: model.showPatchButton(),
|
||||||
child: HapticFloatingActionButtonExtended(
|
child: HapticFloatingActionButtonExtended(
|
||||||
label: I18nText('patcherView.patchButton'),
|
label: Text(t.patcherView.patchButton),
|
||||||
icon: const Icon(Icons.build),
|
icon: const Icon(Icons.build),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (model.checkRequiredPatchOption(context)) {
|
if (model.checkRequiredPatchOption(context)) {
|
||||||
@ -37,16 +37,13 @@ class PatcherView extends StatelessWidget {
|
|||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
CustomSliverAppBar(
|
CustomSliverAppBar(
|
||||||
isMainView: true,
|
isMainView: true,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'patcherView.widgetTitle',
|
t.patcherView.widgetTitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(
|
||||||
color: Theme.of(context).textTheme.titleLarge!.color,
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
|
@ -5,10 +5,10 @@ import 'dart:io';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/app/app.router.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/patch.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
@ -54,24 +54,25 @@ class PatcherViewModel extends BaseViewModel {
|
|||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('notice'),
|
title: Text(t.notice),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'patcherView.removedPatchesWarningDialogText',
|
t.patcherView.removedPatchesWarningDialogText(
|
||||||
translationParams: {'patches': removedPatches.join('\n')},
|
patches: removedPatches.join('\n'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
showArmv7WarningDialog(context);
|
showArmv7WarningDialog(context);
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -94,21 +95,21 @@ class PatcherViewModel extends BaseViewModel {
|
|||||||
showDialog(
|
showDialog(
|
||||||
context: context ?? ctx,
|
context: context ?? ctx,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('notice'),
|
title: Text(t.notice),
|
||||||
content: I18nText('patcherView.requiredOptionDialogText'),
|
content: Text(t.patcherView.requiredOptionDialogText),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
Navigator.of(context).pop(),
|
Navigator.of(context).pop(),
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
Navigator.pop(context),
|
Navigator.pop(context),
|
||||||
navigateToPatchesSelector(),
|
navigateToPatchesSelector(),
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -125,19 +126,19 @@ class PatcherViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: I18nText('patcherView.armv7WarningDialogText'),
|
content: Text(t.patcherView.armv7WarningDialogText),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
navigateToInstaller();
|
navigateToInstaller();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart' hide SearchBar;
|
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/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/manager_api.dart';
|
||||||
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_floating_action_button_extended.dart';
|
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_floating_action_button_extended.dart';
|
||||||
@ -40,7 +40,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
child: HapticFloatingActionButtonExtended(
|
child: HapticFloatingActionButtonExtended(
|
||||||
label: Row(
|
label: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
I18nText('patchesSelectorView.doneButton'),
|
Text(t.patchesSelectorView.doneButton),
|
||||||
Text(' (${model.selectedPatches.length})'),
|
Text(' (${model.selectedPatches.length})'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -58,8 +58,8 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
floating: true,
|
floating: true,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'patchesSelectorView.viewTitle',
|
t.patchesSelectorView.viewTitle,
|
||||||
),
|
),
|
||||||
titleTextStyle: TextStyle(
|
titleTextStyle: TextStyle(
|
||||||
fontSize: 22.0,
|
fontSize: 22.0,
|
||||||
@ -99,8 +99,8 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: 0,
|
value: 0,
|
||||||
child: I18nText(
|
child: Text(
|
||||||
'patchesSelectorView.loadPatchesSelection',
|
t.patchesSelectorView.loadPatchesSelection,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -114,10 +114,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
horizontal: 12.0,
|
horizontal: 12.0,
|
||||||
),
|
),
|
||||||
child: SearchBar(
|
child: SearchBar(
|
||||||
hintText: FlutterI18n.translate(
|
hintText: t.patchesSelectorView.searchBarHint,
|
||||||
context,
|
|
||||||
'patchesSelectorView.searchBarHint',
|
|
||||||
),
|
|
||||||
onQueryChanged: (searchQuery) {
|
onQueryChanged: (searchQuery) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_query = searchQuery;
|
_query = searchQuery;
|
||||||
@ -132,14 +129,11 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: I18nText(
|
|
||||||
'patchesSelectorView.noPatchesFound',
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
t.patchesSelectorView.noPatchesFound,
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: Padding(
|
: Padding(
|
||||||
padding:
|
padding:
|
||||||
@ -151,11 +145,8 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
ActionChip(
|
ActionChip(
|
||||||
label: I18nText('patchesSelectorView.default'),
|
label: Text(t.patchesSelectorView.defaultChip),
|
||||||
tooltip: FlutterI18n.translate(
|
tooltip: t.patchesSelectorView.defaultTooltip,
|
||||||
context,
|
|
||||||
'patchesSelectorView.defaultTooltip',
|
|
||||||
),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_managerAPI.isPatchesChangeEnabled()) {
|
if (_managerAPI.isPatchesChangeEnabled()) {
|
||||||
model.selectDefaultPatches();
|
model.selectDefaultPatches();
|
||||||
@ -166,11 +157,8 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
ActionChip(
|
ActionChip(
|
||||||
label: I18nText('patchesSelectorView.none'),
|
label: Text(t.patchesSelectorView.noneChip),
|
||||||
tooltip: FlutterI18n.translate(
|
tooltip: t.patchesSelectorView.noneTooltip,
|
||||||
context,
|
|
||||||
'patchesSelectorView.noneTooltip',
|
|
||||||
),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_managerAPI.isPatchesChangeEnabled()) {
|
if (_managerAPI.isPatchesChangeEnabled()) {
|
||||||
model.clearPatches();
|
model.clearPatches();
|
||||||
@ -189,7 +177,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
children: [
|
children: [
|
||||||
model.getPatchCategory(
|
model.getPatchCategory(
|
||||||
context,
|
context,
|
||||||
'patchesSelectorView.newPatches',
|
t.patchesSelectorView.newPatches,
|
||||||
),
|
),
|
||||||
...model.getQueriedPatches(_query).map((patch) {
|
...model.getQueriedPatches(_query).map((patch) {
|
||||||
if (model.isPatchNew(patch)) {
|
if (model.isPatchNew(patch)) {
|
||||||
@ -205,7 +193,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
))
|
))
|
||||||
model.getPatchCategory(
|
model.getPatchCategory(
|
||||||
context,
|
context,
|
||||||
'patchesSelectorView.patches',
|
t.patchesSelectorView.patches,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -227,7 +215,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
children: [
|
children: [
|
||||||
model.getPatchCategory(
|
model.getPatchCategory(
|
||||||
context,
|
context,
|
||||||
'patchesSelectorView.universalPatches',
|
t.patchesSelectorView.universalPatches,
|
||||||
),
|
),
|
||||||
...model.getQueriedPatches(_query).map((patch) {
|
...model.getQueriedPatches(_query).map((patch) {
|
||||||
if (patch.compatiblePackages.isEmpty &&
|
if (patch.compatiblePackages.isEmpty &&
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.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.locator.dart';
|
||||||
import 'package:revanced_manager/app/app.router.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/patch.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
@ -92,19 +92,18 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('notice'),
|
title: Text(t.notice),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'patchesSelectorView.setRequiredOption',
|
t.patchesSelectorView.setRequiredOption(
|
||||||
translationParams: {
|
patches: patches.map((patch) => '• $patch').join('\n'),
|
||||||
'patches': patches.map((patch) => '• $patch').join('\n'),
|
),
|
||||||
},
|
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
Navigator.of(context).pop(),
|
Navigator.of(context).pop(),
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -128,21 +127,18 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'patchItem.patchesChangeWarningDialogText',
|
t.patchItem.patchesChangeWarningDialogText,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -150,7 +146,7 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
..pop()
|
..pop()
|
||||||
..pop();
|
..pop();
|
||||||
},
|
},
|
||||||
child: I18nText('patchItem.patchesChangeWarningDialogButton'),
|
child: Text(t.patchItem.patchesChangeWarningDialogButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -257,16 +253,13 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
bottom: 10.0,
|
bottom: 10.0,
|
||||||
left: 5.0,
|
left: 5.0,
|
||||||
),
|
),
|
||||||
child: I18nText(
|
|
||||||
category,
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
category,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +314,7 @@ class PatchesSelectorViewModel extends BaseViewModel {
|
|||||||
this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch));
|
this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
locator<Toast>().showBottom('patchesSelectorView.noSavedPatches');
|
locator<Toast>().showBottom(t.patchesSelectorView.noSavedPatches);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:flutter/material.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/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/manager_api.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
@ -20,7 +20,7 @@ class SManageApiUrl extends BaseViewModel {
|
|||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
I18nText('settingsView.apiURLLabel'),
|
Text(t.settingsView.apiURLLabel),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.manage_history_outlined),
|
icon: const Icon(Icons.manage_history_outlined),
|
||||||
@ -42,10 +42,7 @@ class SManageApiUrl extends BaseViewModel {
|
|||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
labelText: FlutterI18n.translate(
|
labelText: t.settingsView.selectApiURL,
|
||||||
context,
|
|
||||||
'settingsView.selectApiURL',
|
|
||||||
),
|
|
||||||
hintText: apiUrl,
|
hintText: apiUrl,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -58,7 +55,7 @@ class SManageApiUrl extends BaseViewModel {
|
|||||||
_apiUrlController.clear();
|
_apiUrlController.clear();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -69,7 +66,7 @@ class SManageApiUrl extends BaseViewModel {
|
|||||||
_managerAPI.setApiUrl(apiUrl);
|
_managerAPI.setApiUrl(apiUrl);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -80,12 +77,12 @@ class SManageApiUrl extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('settingsView.sourcesResetDialogTitle'),
|
title: Text(t.settingsView.sourcesResetDialogTitle),
|
||||||
content: I18nText('settingsView.apiURLResetDialogText'),
|
content: Text(t.settingsView.apiURLResetDialogText),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -94,7 +91,7 @@ class SManageApiUrl extends BaseViewModel {
|
|||||||
..pop()
|
..pop()
|
||||||
..pop();
|
..pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -111,8 +108,8 @@ class SManageApiUrlUI extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsTileDialog(
|
return SettingsTileDialog(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: 'settingsView.apiURLLabel',
|
title: t.settingsView.apiURLLabel,
|
||||||
subtitle: 'settingsView.apiURLHint',
|
subtitle: t.settingsView.apiURLHint,
|
||||||
onTap: () => sManageApiUrl.showApiUrlDialog(context),
|
onTap: () => sManageApiUrl.showApiUrlDialog(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:flutter/material.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/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/manager_api.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
@ -21,7 +21,7 @@ class SManageKeystorePassword extends BaseViewModel {
|
|||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
I18nText('settingsView.selectKeystorePassword'),
|
Text(t.settingsView.selectKeystorePassword),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.manage_history_outlined),
|
icon: const Icon(Icons.manage_history_outlined),
|
||||||
@ -41,10 +41,7 @@ class SManageKeystorePassword extends BaseViewModel {
|
|||||||
onChanged: (value) => notifyListeners(),
|
onChanged: (value) => notifyListeners(),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
labelText: FlutterI18n.translate(
|
labelText: t.settingsView.selectKeystorePassword,
|
||||||
context,
|
|
||||||
'settingsView.selectKeystorePassword',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -56,7 +53,7 @@ class SManageKeystorePassword extends BaseViewModel {
|
|||||||
_keystorePasswordController.clear();
|
_keystorePasswordController.clear();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -64,7 +61,7 @@ class SManageKeystorePassword extends BaseViewModel {
|
|||||||
_managerAPI.setKeystorePassword(passwd);
|
_managerAPI.setKeystorePassword(passwd);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -81,8 +78,8 @@ class SManageKeystorePasswordUI extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsTileDialog(
|
return SettingsTileDialog(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: 'settingsView.selectKeystorePassword',
|
title: t.settingsView.selectKeystorePassword,
|
||||||
subtitle: 'settingsView.selectKeystorePasswordHint',
|
subtitle: t.settingsView.selectKeystorePasswordHint,
|
||||||
onTap: () => sManageKeystorePassword.showKeystoreDialog(context),
|
onTap: () => sManageKeystorePassword.showKeystoreDialog(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:flutter/material.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/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/manager_api.dart';
|
||||||
import 'package:revanced_manager/services/toast.dart';
|
import 'package:revanced_manager/services/toast.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
||||||
@ -32,7 +32,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
I18nText('settingsView.sourcesLabel'),
|
Text(t.settingsView.sourcesLabel),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.manage_history_outlined),
|
icon: const Icon(Icons.manage_history_outlined),
|
||||||
@ -58,10 +58,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
labelText: FlutterI18n.translate(
|
labelText: t.settingsView.hostRepositoryLabel,
|
||||||
context,
|
|
||||||
'settingsView.hostRepositoryLabel',
|
|
||||||
),
|
|
||||||
hintText: hostRepository,
|
hintText: hostRepository,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -77,10 +74,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
labelText: FlutterI18n.translate(
|
labelText: t.settingsView.orgPatchesLabel,
|
||||||
context,
|
|
||||||
'settingsView.orgPatchesLabel',
|
|
||||||
),
|
|
||||||
hintText: patchesRepo.split('/')[0],
|
hintText: patchesRepo.split('/')[0],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -96,10 +90,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
),
|
),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
labelText: FlutterI18n.translate(
|
labelText: t.settingsView.sourcesPatchesLabel,
|
||||||
context,
|
|
||||||
'settingsView.sourcesPatchesLabel',
|
|
||||||
),
|
|
||||||
hintText: patchesRepo.split('/')[1],
|
hintText: patchesRepo.split('/')[1],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -115,10 +106,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
labelText: FlutterI18n.translate(
|
labelText: t.settingsView.orgIntegrationsLabel,
|
||||||
context,
|
|
||||||
'settingsView.orgIntegrationsLabel',
|
|
||||||
),
|
|
||||||
hintText: integrationsRepo.split('/')[0],
|
hintText: integrationsRepo.split('/')[0],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -134,15 +122,12 @@ class SManageSources extends BaseViewModel {
|
|||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
),
|
),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
labelText: FlutterI18n.translate(
|
labelText: t.settingsView.sourcesIntegrationsLabel,
|
||||||
context,
|
|
||||||
'settingsView.sourcesIntegrationsLabel',
|
|
||||||
),
|
|
||||||
hintText: integrationsRepo.split('/')[1],
|
hintText: integrationsRepo.split('/')[1],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
I18nText('settingsView.sourcesUpdateNote'),
|
Text(t.settingsView.sourcesUpdateNote),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -155,7 +140,7 @@ class SManageSources extends BaseViewModel {
|
|||||||
_intSourceController.clear();
|
_intSourceController.clear();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -168,10 +153,10 @@ class SManageSources extends BaseViewModel {
|
|||||||
);
|
);
|
||||||
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
||||||
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
|
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
|
||||||
_toast.showBottom('settingsView.restartAppForChanges');
|
_toast.showBottom(t.settingsView.restartAppForChanges);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -182,12 +167,12 @@ class SManageSources extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('settingsView.sourcesResetDialogTitle'),
|
title: Text(t.settingsView.sourcesResetDialogTitle),
|
||||||
content: I18nText('settingsView.sourcesResetDialogText'),
|
content: Text(t.settingsView.sourcesResetDialogText),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -196,12 +181,12 @@ class SManageSources extends BaseViewModel {
|
|||||||
_managerAPI.setIntegrationsRepo('');
|
_managerAPI.setIntegrationsRepo('');
|
||||||
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
_managerAPI.setCurrentPatchesVersion('0.0.0');
|
||||||
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
|
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
|
||||||
_toast.showBottom('settingsView.restartAppForChanges');
|
_toast.showBottom(t.settingsView.restartAppForChanges);
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
..pop()
|
..pop()
|
||||||
..pop();
|
..pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -218,8 +203,8 @@ class SManageSourcesUI extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsTileDialog(
|
return SettingsTileDialog(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: 'settingsView.sourcesLabel',
|
title: t.settingsView.sourcesLabel,
|
||||||
subtitle: 'settingsView.sourcesLabelHint',
|
subtitle: t.settingsView.sourcesLabelHint,
|
||||||
onTap: () => sManageSources.showSourcesDialog(context),
|
onTap: () => sManageSources.showSourcesDialog(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,76 +1,101 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
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/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/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/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:timeago/timeago.dart' as timeago;
|
|
||||||
|
|
||||||
final _settingViewModel = SettingsViewModel();
|
final _settingViewModel = SettingsViewModel();
|
||||||
|
|
||||||
class SUpdateLanguage extends BaseViewModel {
|
class SUpdateLanguage extends BaseViewModel {
|
||||||
final Toast _toast = locator<Toast>();
|
final Toast _toast = locator<Toast>();
|
||||||
late SharedPreferences _prefs;
|
late SharedPreferences _prefs;
|
||||||
String selectedLanguage = 'English';
|
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
||||||
String selectedLanguageLocale = prefs.getString('language') ?? 'en_US';
|
|
||||||
List languages = [];
|
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
_prefs = await SharedPreferences.getInstance();
|
_prefs = await SharedPreferences.getInstance();
|
||||||
selectedLanguageLocale =
|
_prefs.getString('language');
|
||||||
_prefs.getString('language') ?? selectedLanguageLocale;
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateLanguage(BuildContext context, String? value) async {
|
Future<void> updateLocale(String locale) async {
|
||||||
if (value != null) {
|
LocaleSettings.setLocaleRaw(locale);
|
||||||
selectedLanguageLocale = value;
|
_managerAPI.setLocale(locale);
|
||||||
_prefs = await SharedPreferences.getInstance();
|
Future.delayed(
|
||||||
await _prefs.setString('language', value);
|
const Duration(milliseconds: 120),
|
||||||
await FlutterI18n.refresh(context, Locale(value));
|
() => _toast.showBottom(t.settingsView.languageUpdated),
|
||||||
timeago.setLocaleMessages(value, timeago.EnMessages());
|
);
|
||||||
locator<NavigationViewModel>().notifyListeners();
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> initLang() async {
|
|
||||||
languages.sort((a, b) => a['name'].compareTo(b['name']));
|
|
||||||
notifyListeners();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> showLanguagesDialog(BuildContext parentContext) {
|
Future<void> showLanguagesDialog(BuildContext parentContext) {
|
||||||
initLang();
|
final ValueNotifier<String> selectedLanguageCode =
|
||||||
|
ValueNotifier(LocaleSettings.currentLocale.languageCode);
|
||||||
|
// 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(
|
return showDialog(
|
||||||
context: parentContext,
|
context: parentContext,
|
||||||
builder: (context) => SimpleDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('settingsView.languageLabel'),
|
title: Text(t.settingsView.languageLabel),
|
||||||
children: [
|
icon: const Icon(Icons.language),
|
||||||
SizedBox(
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
height: 500,
|
contentPadding: EdgeInsets.zero,
|
||||||
child: ListView.builder(
|
content: ValueListenableBuilder(
|
||||||
itemCount: languages.length,
|
valueListenable: selectedLanguageCode,
|
||||||
itemBuilder: (context, index) {
|
builder: (context, value, child) {
|
||||||
return RadioListTile<String>(
|
return SingleChildScrollView(
|
||||||
title: Text(languages[index]['name']),
|
child: ListBody(
|
||||||
subtitle: Text(languages[index]['locale']),
|
children: AppLocale.values.map(
|
||||||
value: languages[index]['locale'],
|
(locale) {
|
||||||
groupValue: selectedLanguageLocale,
|
LanguageCodes? languageCode;
|
||||||
|
Text? languageNativeName;
|
||||||
|
|
||||||
|
try {
|
||||||
|
languageCode =
|
||||||
|
LanguageCodes.fromCode(locale.languageCode);
|
||||||
|
} catch (e) {}
|
||||||
|
if (languageCode != null) {
|
||||||
|
languageNativeName = Text(languageCode.nativeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RadioListTile(
|
||||||
|
title: Text(
|
||||||
|
languageCode?.englishName ?? locale.languageCode,
|
||||||
|
),
|
||||||
|
subtitle: languageNativeName,
|
||||||
|
value: locale.languageCode == selectedLanguageCode.value,
|
||||||
|
groupValue: true,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
selectedLanguage = languages[index]['name'];
|
selectedLanguageCode.value = locale.languageCode;
|
||||||
_toast.showBottom('settingsView.restartAppForChanges');
|
|
||||||
updateLanguage(context, value);
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
).toList(),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(t.cancelButton),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
updateLocale(selectedLanguageCode.value);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -85,8 +110,10 @@ class SUpdateLanguageUI extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsTileDialog(
|
return SettingsTileDialog(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: 'settingsView.languageLabel',
|
title: t.settingsView.languageLabel,
|
||||||
subtitle: _settingViewModel.sUpdateLanguage.selectedLanguage,
|
subtitle:
|
||||||
|
LanguageCodes.fromCode(LocaleSettings.currentLocale.languageCode)
|
||||||
|
.nativeName,
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
_settingViewModel.sUpdateLanguage.showLanguagesDialog(context),
|
_settingViewModel.sUpdateLanguage.showLanguagesDialog(context),
|
||||||
);
|
);
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
import 'package:dynamic_themes/dynamic_themes.dart';
|
import 'package:dynamic_themes/dynamic_themes.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.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/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/manager_api.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_radio_list_tile.dart';
|
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_radio_list_tile.dart';
|
||||||
@ -23,20 +23,17 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsSection(
|
return SettingsSection(
|
||||||
title: 'settingsView.appearanceSectionTitle',
|
title: t.settingsView.appearanceSectionTitle,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.themeModeLabel',
|
t.settingsView.themeModeLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
trailing: FilledButton(
|
trailing: FilledButton(
|
||||||
onPressed: () => {showThemeDialog(context)},
|
onPressed: () => {showThemeDialog(context)},
|
||||||
child: getThemeModeName(),
|
child: getThemeModeName(),
|
||||||
@ -46,17 +43,14 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
if (managerAPI.isDynamicThemeAvailable)
|
if (managerAPI.isDynamicThemeAvailable)
|
||||||
HapticSwitchListTile(
|
HapticSwitchListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.dynamicThemeLabel',
|
t.settingsView.dynamicThemeLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.dynamicThemeHint),
|
||||||
subtitle: I18nText('settingsView.dynamicThemeHint'),
|
|
||||||
value: getDynamicThemeStatus(),
|
value: getDynamicThemeStatus(),
|
||||||
onChanged: (value) => {
|
onChanged: (value) => {
|
||||||
setUseDynamicTheme(
|
setUseDynamicTheme(
|
||||||
@ -101,16 +95,16 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
I18nText getThemeModeName() {
|
Text getThemeModeName() {
|
||||||
switch (getThemeMode()) {
|
switch (getThemeMode()) {
|
||||||
case 0:
|
case 0:
|
||||||
return I18nText('settingsView.systemThemeLabel');
|
return Text(t.settingsView.systemThemeLabel);
|
||||||
case 1:
|
case 1:
|
||||||
return I18nText('settingsView.lightThemeLabel');
|
return Text(t.settingsView.lightThemeLabel);
|
||||||
case 2:
|
case 2:
|
||||||
return I18nText('settingsView.darkThemeLabel');
|
return Text(t.settingsView.darkThemeLabel);
|
||||||
default:
|
default:
|
||||||
return I18nText('settingsView.systemThemeLabel');
|
return Text(t.settingsView.systemThemeLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +114,7 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('settingsView.themeModeLabel'),
|
title: Text(t.settingsView.themeModeLabel),
|
||||||
icon: const Icon(Icons.palette),
|
icon: const Icon(Icons.palette),
|
||||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
@ -132,7 +126,7 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
HapticRadioListTile(
|
HapticRadioListTile(
|
||||||
title: I18nText('settingsView.systemThemeLabel'),
|
title: Text(t.settingsView.systemThemeLabel),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
value: 0,
|
value: 0,
|
||||||
groupValue: value,
|
groupValue: value,
|
||||||
@ -141,7 +135,7 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
HapticRadioListTile(
|
HapticRadioListTile(
|
||||||
title: I18nText('settingsView.lightThemeLabel'),
|
title: Text(t.settingsView.lightThemeLabel),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
value: 1,
|
value: 1,
|
||||||
groupValue: value,
|
groupValue: value,
|
||||||
@ -150,7 +144,7 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
HapticRadioListTile(
|
HapticRadioListTile(
|
||||||
title: I18nText('settingsView.darkThemeLabel'),
|
title: Text(t.settingsView.darkThemeLabel),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
value: 2,
|
value: 2,
|
||||||
groupValue: value,
|
groupValue: value,
|
||||||
@ -168,14 +162,14 @@ class _SUpdateThemeUIState extends State<SUpdateThemeUI> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('cancelButton'),
|
child: Text(t.cancelButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setThemeMode(context, newTheme.value);
|
setThemeMode(context, newTheme.value);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
// ignore_for_file: prefer_const_constructors
|
// ignore_for_file: prefer_const_constructors
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.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/settingsFragment/settings_update_theme.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart';
|
||||||
@ -27,16 +28,13 @@ class SettingsView extends StatelessWidget {
|
|||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
CustomSliverAppBar(
|
CustomSliverAppBar(
|
||||||
isMainView: true,
|
isMainView: true,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.widgetTitle',
|
t.settingsView.widgetTitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(
|
||||||
color: Theme.of(context).textTheme.titleLarge!.color,
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SliverList(
|
SliverList(
|
||||||
delegate: SliverChildListDelegate.fixed(
|
delegate: SliverChildListDelegate.fixed(
|
||||||
<Widget>[
|
<Widget>[
|
||||||
@ -47,7 +45,7 @@ class SettingsView extends StatelessWidget {
|
|||||||
children: const [
|
children: const [
|
||||||
SUpdateThemeUI(),
|
SUpdateThemeUI(),
|
||||||
// _settingsDivider,
|
// _settingsDivider,
|
||||||
// SUpdateLanguageUI(),
|
SUpdateLanguageUI(),
|
||||||
_settingsDivider,
|
_settingsDivider,
|
||||||
SAdvancedSection(),
|
SAdvancedSection(),
|
||||||
_settingsDivider,
|
_settingsDivider,
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
|
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:logcat/logcat.dart';
|
import 'package:logcat/logcat.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/app/app.router.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/manager_api.dart';
|
||||||
import 'package:revanced_manager/services/toast.dart';
|
import 'package:revanced_manager/services/toast.dart';
|
||||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||||
@ -60,17 +61,14 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'settingsView.enablePatchesSelectionWarningText',
|
t.settingsView.enablePatchesSelectionWarningText,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -78,13 +76,13 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
_managerAPI.setPatchesChangeEnabled(true);
|
_managerAPI.setPatchesChangeEnabled(true);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -93,23 +91,20 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'settingsView.disablePatchesSelectionWarningText',
|
t.settingsView.disablePatchesSelectionWarningText,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -118,7 +113,7 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
_managerAPI.setPatchesChangeEnabled(false);
|
_managerAPI.setPatchesChangeEnabled(false);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -156,30 +151,27 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'settingsView.requireSuggestedAppVersionDialogText',
|
t.settingsView.requireSuggestedAppVersionDialogText,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_managerAPI.enableRequireSuggestedAppVersionStatus(false);
|
_managerAPI.enableRequireSuggestedAppVersionStatus(false);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -197,13 +189,13 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
|
|
||||||
void deleteKeystore() {
|
void deleteKeystore() {
|
||||||
_managerAPI.deleteKeystore();
|
_managerAPI.deleteKeystore();
|
||||||
_toast.showBottom('settingsView.regeneratedKeystore');
|
_toast.showBottom(t.settingsView.regeneratedKeystore);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteTempDir() {
|
void deleteTempDir() {
|
||||||
_managerAPI.deleteTempFolder();
|
_managerAPI.deleteTempFolder();
|
||||||
_toast.showBottom('settingsView.deletedTempDir');
|
_toast.showBottom(t.settingsView.deletedTempDir);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,9 +211,9 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
fileName: 'selected_patches_$dateTime.json',
|
fileName: 'selected_patches_$dateTime.json',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
_toast.showBottom('settingsView.exportedPatches');
|
_toast.showBottom(t.settingsView.exportedPatches);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('settingsView.noExportFileFound');
|
_toast.showBottom(t.settingsView.noExportFileFound);
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
@ -245,13 +237,13 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
if (_patcherViewModel.selectedApp != null) {
|
if (_patcherViewModel.selectedApp != null) {
|
||||||
_patcherViewModel.loadLastSelectedPatches();
|
_patcherViewModel.loadLastSelectedPatches();
|
||||||
}
|
}
|
||||||
_toast.showBottom('settingsView.importedPatches');
|
_toast.showBottom(t.settingsView.importedPatches);
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e);
|
print(e);
|
||||||
}
|
}
|
||||||
_toast.showBottom('settingsView.jsonSelectorErrorMessage');
|
_toast.showBottom(t.settingsView.jsonSelectorErrorMessage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_managerAPI.showPatchesChangeWarningDialog(context);
|
_managerAPI.showPatchesChangeWarningDialog(context);
|
||||||
@ -270,9 +262,9 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
fileName: 'keystore_$dateTime.keystore',
|
fileName: 'keystore_$dateTime.keystore',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
_toast.showBottom('settingsView.exportedKeystore');
|
_toast.showBottom(t.settingsView.exportedKeystore);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('settingsView.noKeystoreExportFileFound');
|
_toast.showBottom(t.settingsView.noKeystoreExportFileFound);
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
@ -288,24 +280,24 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
final File inFile = File(result);
|
final File inFile = File(result);
|
||||||
inFile.copySync(_managerAPI.keystoreFile);
|
inFile.copySync(_managerAPI.keystoreFile);
|
||||||
|
|
||||||
_toast.showBottom('settingsView.importedKeystore');
|
_toast.showBottom(t.settingsView.importedKeystore);
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e);
|
print(e);
|
||||||
}
|
}
|
||||||
_toast.showBottom('settingsView.keystoreSelectorErrorMessage');
|
_toast.showBottom(t.settingsView.keystoreSelectorErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetAllOptions() {
|
void resetAllOptions() {
|
||||||
_managerAPI.resetAllOptions();
|
_managerAPI.resetAllOptions();
|
||||||
_toast.showBottom('settingsView.resetStoredOptions');
|
_toast.showBottom(t.settingsView.resetStoredOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetSelectedPatches() {
|
void resetSelectedPatches() {
|
||||||
_managerAPI.resetLastSelectedPatches();
|
_managerAPI.resetLastSelectedPatches();
|
||||||
_toast.showBottom('settingsView.resetStoredPatches');
|
_toast.showBottom(t.settingsView.resetStoredPatches);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteLogs() async {
|
Future<void> deleteLogs() async {
|
||||||
@ -314,7 +306,7 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
if (logsDir.existsSync()) {
|
if (logsDir.existsSync()) {
|
||||||
logsDir.deleteSync(recursive: true);
|
logsDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
_toast.showBottom('settingsView.deletedLogs');
|
_toast.showBottom(t.settingsView.deletedLogs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> exportLogcatLogs() async {
|
Future<void> exportLogcatLogs() async {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.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/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/appInfoView/app_info_viewmodel.dart';
|
import 'package:revanced_manager/ui/widgets/appInfoView/app_info_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
@ -22,16 +22,13 @@ class AppInfoView extends StatelessWidget {
|
|||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
CustomSliverAppBar(
|
CustomSliverAppBar(
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'appInfoView.widgetTitle',
|
t.appInfoView.widgetTitle,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(
|
||||||
color: Theme.of(context).textTheme.titleLarge!.color,
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 20.0),
|
padding: const EdgeInsets.symmetric(vertical: 20.0),
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
@ -86,10 +83,8 @@ class AppInfoView extends StatelessWidget {
|
|||||||
.primary,
|
.primary,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
I18nText(
|
Text(
|
||||||
'appInfoView.openButton',
|
t.appInfoView.openButton,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
@ -97,7 +92,6 @@ class AppInfoView extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -130,10 +124,8 @@ class AppInfoView extends StatelessWidget {
|
|||||||
.primary,
|
.primary,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
I18nText(
|
Text(
|
||||||
'appInfoView.uninstallButton',
|
t.appInfoView.uninstallButton,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
@ -141,7 +133,6 @@ class AppInfoView extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -183,10 +174,8 @@ class AppInfoView extends StatelessWidget {
|
|||||||
.primary,
|
.primary,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
I18nText(
|
Text(
|
||||||
'appInfoView.unmountButton',
|
t.appInfoView.unmountButton,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
@ -194,7 +183,6 @@ class AppInfoView extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -209,77 +197,63 @@ class AppInfoView extends StatelessWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.symmetric(horizontal: 20.0),
|
const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'appInfoView.packageNameLabel',
|
t.appInfoView.packageNameLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
subtitle: Text(app.packageName),
|
subtitle: Text(app.packageName),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.symmetric(horizontal: 20.0),
|
const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'appInfoView.installTypeLabel',
|
t.appInfoView.installTypeLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
subtitle: app.isRooted
|
subtitle: app.isRooted
|
||||||
? I18nText('appInfoView.mountTypeLabel')
|
? Text(t.appInfoView.mountTypeLabel)
|
||||||
: I18nText('appInfoView.regularTypeLabel'),
|
: Text(t.appInfoView.regularTypeLabel),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.symmetric(horizontal: 20.0),
|
const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'appInfoView.patchedDateLabel',
|
t.appInfoView.patchedDateLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
t.appInfoView.patchedDateHint(
|
||||||
|
date: model.getPrettyDate(context, app.patchDate),
|
||||||
|
time: model.getPrettyTime(context, app.patchDate),
|
||||||
),
|
),
|
||||||
subtitle: I18nText(
|
|
||||||
'appInfoView.patchedDateHint',
|
|
||||||
translationParams: {
|
|
||||||
'date': model.getPrettyDate(context, app.patchDate),
|
|
||||||
'time': model.getPrettyTime(context, app.patchDate),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.symmetric(horizontal: 20.0),
|
const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'appInfoView.appliedPatchesLabel',
|
t.appInfoView.appliedPatchesLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
t.appInfoView.appliedPatchesHint(
|
||||||
|
quantity: app.appliedPatches.length.toString(),
|
||||||
),
|
),
|
||||||
subtitle: I18nText(
|
|
||||||
'appInfoView.appliedPatchesHint',
|
|
||||||
translationParams: {
|
|
||||||
'quantity': app.appliedPatches.length.toString(),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
onTap: () => model.showAppliedPatchesDialog(context, app),
|
onTap: () => model.showAppliedPatchesDialog(context, app),
|
||||||
),
|
),
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
import 'package:device_apps/device_apps.dart';
|
import 'package:device_apps/device_apps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.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/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
import 'package:revanced_manager/services/patcher_api.dart';
|
import 'package:revanced_manager/services/patcher_api.dart';
|
||||||
@ -51,7 +51,7 @@ class AppInfoViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateNotImplemented(BuildContext context) {
|
void updateNotImplemented(BuildContext context) {
|
||||||
_toast.showBottom('appInfoView.updateNotImplemented');
|
_toast.showBottom(t.appInfoView.updateNotImplemented);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> showUninstallDialog(
|
Future<void> showUninstallDialog(
|
||||||
@ -64,12 +64,12 @@ class AppInfoViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('appInfoView.rootDialogTitle'),
|
title: Text(t.appInfoView.rootDialogTitle),
|
||||||
content: I18nText('appInfoView.rootDialogText'),
|
content: Text(t.appInfoView.rootDialogText),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -79,16 +79,12 @@ class AppInfoViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText(
|
title: Text(t.appInfoView.unmountButton),
|
||||||
'appInfoView.unmountButton',
|
content: Text(t.appInfoView.unmountDialogText),
|
||||||
),
|
|
||||||
content: I18nText(
|
|
||||||
'appInfoView.unmountDialogText',
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -96,7 +92,7 @@ class AppInfoViewModel extends BaseViewModel {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -105,16 +101,12 @@ class AppInfoViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText(
|
title: Text(t.appInfoView.uninstallButton),
|
||||||
'appInfoView.uninstallButton',
|
content: Text(t.appInfoView.uninstallDialogText),
|
||||||
),
|
|
||||||
content: I18nText(
|
|
||||||
'appInfoView.uninstallDialogText',
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -122,7 +114,7 @@ class AppInfoViewModel extends BaseViewModel {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -148,14 +140,14 @@ class AppInfoViewModel extends BaseViewModel {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('appInfoView.appliedPatchesLabel'),
|
title: Text(t.appInfoView.appliedPatchesLabel),
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: Text(getAppliedPatchesString(app.appliedPatches)),
|
child: Text(getAppliedPatchesString(app.appliedPatches)),
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:flutter/material.dart';
|
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_card.dart';
|
||||||
|
|
||||||
class InstalledAppItem extends StatefulWidget {
|
class InstalledAppItem extends StatefulWidget {
|
||||||
@ -107,16 +107,12 @@ class _InstalledAppItemState extends State<InstalledAppItem> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'suggested',
|
t.suggested(
|
||||||
translationParams: {
|
version: widget.suggestedVersion.isEmpty
|
||||||
'version': widget.suggestedVersion.isEmpty
|
? Text(t.appSelectorCard.anyVersion)
|
||||||
? FlutterI18n.translate(
|
: 'v${widget.suggestedVersion}',
|
||||||
context,
|
),
|
||||||
'appSelectorCard.anyVersion',
|
|
||||||
)
|
|
||||||
: widget.suggestedVersion,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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_card.dart';
|
||||||
|
|
||||||
class NotInstalledAppItem extends StatefulWidget {
|
class NotInstalledAppItem extends StatefulWidget {
|
||||||
@ -91,16 +91,12 @@ class _NotInstalledAppItem extends State<NotInstalledAppItem> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'suggested',
|
t.suggested(
|
||||||
translationParams: {
|
version: widget.suggestedVersion.isEmpty
|
||||||
'version': widget.suggestedVersion.isEmpty
|
? t.appSelectorCard.anyVersion
|
||||||
? FlutterI18n.translate(
|
: 'v${widget.suggestedVersion}',
|
||||||
context,
|
),
|
||||||
'appSelectorCard.anyVersion',
|
|
||||||
)
|
|
||||||
: widget.suggestedVersion,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_cache_manager/file.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/services/download_manager.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
@ -26,17 +25,14 @@ class _ContributorsCardState extends State<ContributorsCard> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 8.0),
|
padding: const EdgeInsets.only(bottom: 8.0),
|
||||||
child: I18nText(
|
child: Text(
|
||||||
widget.title,
|
widget.title,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
CustomCard(
|
CustomCard(
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:device_apps/device_apps.dart';
|
import 'package:device_apps/device_apps.dart';
|
||||||
import 'package:flutter/material.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/app/app.locator.dart';
|
||||||
|
import 'package:revanced_manager/gen/strings.g.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
|
||||||
@ -51,18 +51,14 @@ class InstalledAppsCard extends StatelessWidget {
|
|||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
I18nText(
|
Text(
|
||||||
'homeView.noInstallations',
|
t.homeView.noInstallations,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.titleMedium!
|
.titleMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color:
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.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/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/views/home/home_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
|
|
||||||
@ -39,13 +39,13 @@ class _LatestCommitCardState extends State<LatestCommitCard> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
FutureBuilder<String?>(
|
FutureBuilder<String?>(
|
||||||
future: model.getLatestManagerReleaseTime(),
|
future: model.getLatestManagerReleaseTime(),
|
||||||
builder: (context, snapshot) => snapshot.hasData &&
|
builder: (context, snapshot) =>
|
||||||
snapshot.data!.isNotEmpty
|
snapshot.hasData && snapshot.data!.isNotEmpty
|
||||||
? I18nText(
|
? Text(
|
||||||
'latestCommitCard.timeagoLabel',
|
t.latestCommitCard
|
||||||
translationParams: {'time': snapshot.data!},
|
.timeagoLabel(time: snapshot.data!),
|
||||||
)
|
)
|
||||||
: I18nText('latestCommitCard.loadingLabel'),
|
: Text(t.latestCommitCard.loadingLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -62,8 +62,8 @@ class _LatestCommitCardState extends State<LatestCommitCard> {
|
|||||||
!snapshot.data!,
|
!snapshot.data!,
|
||||||
),
|
),
|
||||||
child: (snapshot.hasData && !snapshot.data!)
|
child: (snapshot.hasData && !snapshot.data!)
|
||||||
? I18nText('showChangelogButton')
|
? Text(t.showChangelogButton)
|
||||||
: I18nText('showUpdateButton'),
|
: Text(t.showUpdateButton),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -89,15 +89,9 @@ class _LatestCommitCardState extends State<LatestCommitCard> {
|
|||||||
future: model.getLatestPatchesReleaseTime(),
|
future: model.getLatestPatchesReleaseTime(),
|
||||||
builder: (context, snapshot) => Text(
|
builder: (context, snapshot) => Text(
|
||||||
snapshot.hasData && snapshot.data!.isNotEmpty
|
snapshot.hasData && snapshot.data!.isNotEmpty
|
||||||
? FlutterI18n.translate(
|
? t.latestCommitCard
|
||||||
context,
|
.timeagoLabel(time: snapshot.data!)
|
||||||
'latestCommitCard.timeagoLabel',
|
: t.latestCommitCard.loadingLabel,
|
||||||
translationParams: {'time': snapshot.data!},
|
|
||||||
)
|
|
||||||
: FlutterI18n.translate(
|
|
||||||
context,
|
|
||||||
'latestCommitCard.loadingLabel',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -115,8 +109,8 @@ class _LatestCommitCardState extends State<LatestCommitCard> {
|
|||||||
!snapshot.data!,
|
!snapshot.data!,
|
||||||
),
|
),
|
||||||
child: (snapshot.hasData && !snapshot.data!)
|
child: (snapshot.hasData && !snapshot.data!)
|
||||||
? I18nText('showChangelogButton')
|
? Text(t.showChangelogButton)
|
||||||
: I18nText('showUpdateButton'),
|
: Text(t.showUpdateButton),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.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/views/home/home_viewmodel.dart';
|
||||||
|
|
||||||
class UpdateConfirmationSheet extends StatelessWidget {
|
class UpdateConfirmationSheet extends StatelessWidget {
|
||||||
@ -51,18 +51,15 @@ class UpdateConfirmationSheet extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
isPatches
|
isPatches
|
||||||
? 'homeView.updatePatchesSheetTitle'
|
? t.homeView.updatePatchesSheetTitle
|
||||||
: 'homeView.updateSheetTitle',
|
: t.homeView.updateSheetTitle,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 4.0),
|
const SizedBox(height: 4.0),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
@ -94,24 +91,20 @@ class UpdateConfirmationSheet extends StatelessWidget {
|
|||||||
? model.updatePatches(context)
|
? model.updatePatches(context)
|
||||||
: model.updateManager(context);
|
: model.updateManager(context);
|
||||||
},
|
},
|
||||||
child: I18nText('updateButton'),
|
child: Text(t.updateButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 12.0, left: 24.0, bottom: 12.0),
|
padding: const EdgeInsets.only(top: 12.0, left: 24.0, bottom: 12.0),
|
||||||
child: I18nText(
|
|
||||||
'homeView.updateChangelogTitle',
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
t.homeView.updateChangelogTitle,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context)
|
color:
|
||||||
.colorScheme
|
Theme.of(context).colorScheme.onSecondaryContainer,
|
||||||
.onSecondaryContainer,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/material.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/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/views/patcher/patcher_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
|
|
||||||
@ -28,21 +29,18 @@ class AppSelectorCard extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
I18nText(
|
Text(
|
||||||
vm.selectedApp == null
|
vm.selectedApp == null
|
||||||
? 'appSelectorCard.widgetTitle'
|
? t.appSelectorCard.widgetTitle
|
||||||
: 'appSelectorCard.widgetTitleSelected',
|
: t.appSelectorCard.widgetTitleSelected,
|
||||||
child: const Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
if (vm.selectedApp == null)
|
if (vm.selectedApp == null)
|
||||||
I18nText('appSelectorCard.widgetSubtitle')
|
Text(t.appSelectorCard.widgetSubtitle)
|
||||||
else
|
else
|
||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@ -96,11 +94,10 @@ class AppSelectorCard extends StatelessWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
Text(
|
||||||
'suggested',
|
t.suggested(
|
||||||
translationParams: {
|
version: suggestedVersion,
|
||||||
'version': suggestedVersion,
|
),
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.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/app/app.locator.dart';
|
||||||
|
import 'package:revanced_manager/gen/strings.g.dart';
|
||||||
import 'package:revanced_manager/models/patch.dart';
|
import 'package:revanced_manager/models/patch.dart';
|
||||||
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
@ -21,18 +21,15 @@ class PatchSelectorCard extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
I18nText(
|
Text(
|
||||||
locator<PatcherViewModel>().selectedPatches.isEmpty
|
locator<PatcherViewModel>().selectedPatches.isEmpty
|
||||||
? 'patchSelectorCard.widgetTitle'
|
? t.patchSelectorCard.widgetTitle
|
||||||
: 'patchSelectorCard.widgetTitleSelected',
|
: t.patchSelectorCard.widgetTitleSelected,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Text(
|
Text(
|
||||||
locator<PatcherViewModel>().selectedPatches.isEmpty
|
locator<PatcherViewModel>().selectedPatches.isEmpty
|
||||||
? ''
|
? ''
|
||||||
@ -46,10 +43,10 @@ class PatchSelectorCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
if (locator<PatcherViewModel>().selectedApp == null)
|
if (locator<PatcherViewModel>().selectedApp == null)
|
||||||
I18nText('patchSelectorCard.widgetSubtitle')
|
Text(t.patchSelectorCard.widgetSubtitle)
|
||||||
else
|
else
|
||||||
locator<PatcherViewModel>().selectedPatches.isEmpty
|
locator<PatcherViewModel>().selectedPatches.isEmpty
|
||||||
? I18nText('patchSelectorCard.widgetEmptySubtitle')
|
? Text(t.patchSelectorCard.widgetEmptySubtitle)
|
||||||
: Text(_getPatchesSelection()),
|
: Text(_getPatchesSelection()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.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/app/app.locator.dart';
|
||||||
|
import 'package:revanced_manager/gen/strings.g.dart';
|
||||||
import 'package:revanced_manager/models/patch.dart';
|
import 'package:revanced_manager/models/patch.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
import 'package:revanced_manager/services/toast.dart';
|
import 'package:revanced_manager/services/toast.dart';
|
||||||
@ -162,7 +162,7 @@ class _PatchItemState extends State<PatchItem> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 8),
|
padding: const EdgeInsets.only(top: 8),
|
||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
label: I18nText('warning'),
|
label: Text(t.warning),
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.warning_amber_outlined,
|
Icons.warning_amber_outlined,
|
||||||
size: 20.0,
|
size: 20.0,
|
||||||
@ -215,19 +215,18 @@ class _PatchItemState extends State<PatchItem> {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: Text(t.warning),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'patchItem.unsupportedDialogText',
|
t.patchItem.unsupportedDialogText(
|
||||||
translationParams: {
|
packageVersion: widget.packageVersion,
|
||||||
'packageVersion': widget.packageVersion,
|
supportedVersions:
|
||||||
'supportedVersions':
|
|
||||||
'• ${widget.supportedPackageVersions.reversed.join('\n• ')}',
|
'• ${widget.supportedPackageVersions.reversed.join('\n• ')}',
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -238,14 +237,14 @@ class _PatchItemState extends State<PatchItem> {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('notice'),
|
title: Text(t.notice),
|
||||||
content: I18nText(
|
content: Text(
|
||||||
'patchItem.unsupportedRequiredOption',
|
t.patchItem.unsupportedRequiredOption,
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('okButton'),
|
child: Text(t.okButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_file_dialog/flutter_file_dialog.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/models/patch.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
|
|
||||||
@ -93,15 +93,12 @@ class IntAndStringPatchOption extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
I18nText(
|
Text(
|
||||||
'patchOptionsView.requiredOption',
|
t.patchOptionsView.requiredOption,
|
||||||
child: Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.error,
|
color: Theme.of(context).colorScheme.error,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -240,16 +237,13 @@ class IntStringLongListPatchOption extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.add, size: 20),
|
const Icon(Icons.add, size: 20),
|
||||||
I18nText(
|
Text(
|
||||||
'add',
|
t.add,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -279,17 +273,14 @@ class UnsupportedPatchOption extends StatelessWidget {
|
|||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: I18nText(
|
child: Text(
|
||||||
'patchOptionsView.unsupportedOption',
|
t.patchOptionsView.unsupportedOption,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
patchOption: patchOption,
|
patchOption: patchOption,
|
||||||
removeOption: (_) {},
|
removeOption: (_) {},
|
||||||
);
|
);
|
||||||
@ -452,17 +443,14 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
|
|||||||
..add(
|
..add(
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
value: '',
|
value: '',
|
||||||
child: I18nText(
|
child: Text(
|
||||||
'patchOptionsView.customValue',
|
t.patchOptionsView.customValue,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (value == '') {
|
if (value == '') {
|
||||||
controller.text = defaultValue!;
|
controller.text = defaultValue!;
|
||||||
@ -491,25 +479,22 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
|
|||||||
isStringOption ? TextInputType.text : TextInputType.number,
|
isStringOption ? TextInputType.text : TextInputType.number,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
suffixIcon: PopupMenuButton(
|
suffixIcon: PopupMenuButton(
|
||||||
tooltip: FlutterI18n.translate(
|
tooltip: t.patchOptionsView.tooltip,
|
||||||
context,
|
|
||||||
'patchOptionsView.tooltip',
|
|
||||||
),
|
|
||||||
itemBuilder: (BuildContext context) {
|
itemBuilder: (BuildContext context) {
|
||||||
return [
|
return [
|
||||||
if (isArrayOption)
|
if (isArrayOption)
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: 'remove',
|
value: t.remove,
|
||||||
child: I18nText('remove'),
|
child: Text(t.remove),
|
||||||
),
|
),
|
||||||
if (isStringOption) ...[
|
if (isStringOption) ...[
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: 'patchOptionsView.selectFilePath',
|
value: t.patchOptionsView.selectFilePath,
|
||||||
child: I18nText('patchOptionsView.selectFilePath'),
|
child: Text(t.patchOptionsView.selectFilePath),
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: 'patchOptionsView.selectFolder',
|
value: t.patchOptionsView.selectFolder,
|
||||||
child: I18nText('patchOptionsView.selectFolder'),
|
child: Text(t.patchOptionsView.selectFolder),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.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';
|
import 'package:revanced_manager/utils/about_info.dart';
|
||||||
|
|
||||||
class AboutWidget extends StatefulWidget {
|
class AboutWidget extends StatefulWidget {
|
||||||
@ -34,23 +34,20 @@ class _AboutWidgetState extends State<AboutWidget> {
|
|||||||
);
|
);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: I18nText('settingsView.snackbarMessage'),
|
content: Text(t.settingsView.snackbarMessage),
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
Theme.of(context).colorScheme.secondary,
|
Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.aboutLabel',
|
t.settingsView.aboutLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
subtitle: snapshot.hasData
|
subtitle: snapshot.hasData
|
||||||
? Column(
|
? Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// ignore_for_file: prefer_const_constructors
|
// ignore_for_file: prefer_const_constructors
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
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_api_url.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.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';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_patches.dart';
|
||||||
@ -17,7 +18,7 @@ class SAdvancedSection extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsSection(
|
return SettingsSection(
|
||||||
title: 'settingsView.advancedSectionTitle',
|
title: t.settingsView.advancedSectionTitle,
|
||||||
children: const <Widget>[
|
children: const <Widget>[
|
||||||
SAutoUpdatePatches(),
|
SAutoUpdatePatches(),
|
||||||
SShowUpdateDialog(),
|
SShowUpdateDialog(),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
||||||
|
|
||||||
@ -17,17 +17,14 @@ class _SAutoUpdatePatchesState extends State<SAutoUpdatePatches> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return HapticSwitchListTile(
|
return HapticSwitchListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.autoUpdatePatchesLabel',
|
t.settingsView.autoUpdatePatchesLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.autoUpdatePatchesHint),
|
||||||
subtitle: I18nText('settingsView.autoUpdatePatchesHint'),
|
|
||||||
value: _settingsViewModel.isPatchesAutoUpdate(),
|
value: _settingsViewModel.isPatchesAutoUpdate(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/about_widget.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/about_widget.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
||||||
@ -12,51 +12,42 @@ class SDebugSection extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsSection(
|
return SettingsSection(
|
||||||
title: 'settingsView.debugSectionTitle',
|
title: t.settingsView.debugSectionTitle,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.logsLabel',
|
t.settingsView.logsLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.logsHint),
|
||||||
subtitle: I18nText('settingsView.logsHint'),
|
|
||||||
onTap: () => _settingsViewModel.exportLogcatLogs(),
|
onTap: () => _settingsViewModel.exportLogcatLogs(),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.deleteLogsLabel',
|
t.settingsView.deleteLogsLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.deleteLogsHint),
|
||||||
subtitle: I18nText('settingsView.deleteLogsHint'),
|
|
||||||
onTap: () => _settingsViewModel.deleteLogs(),
|
onTap: () => _settingsViewModel.deleteLogs(),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.deleteTempDirLabel',
|
t.settingsView.deleteTempDirLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.deleteTempDirHint),
|
||||||
subtitle: I18nText('settingsView.deleteTempDirHint'),
|
|
||||||
onTap: () => _settingsViewModel.deleteTempDir(),
|
onTap: () => _settingsViewModel.deleteTempDir(),
|
||||||
),
|
),
|
||||||
const AboutWidget(
|
const AboutWidget(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
||||||
|
|
||||||
@ -18,17 +18,14 @@ class _SEnablePatchesSelectionState extends State<SEnablePatchesSelection> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return HapticSwitchListTile(
|
return HapticSwitchListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.enablePatchesSelectionLabel',
|
t.settingsView.enablePatchesSelectionLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.enablePatchesSelectionHint),
|
||||||
subtitle: I18nText('settingsView.enablePatchesSelectionHint'),
|
|
||||||
value: _settingsViewModel.isPatchesChangeEnabled(),
|
value: _settingsViewModel.isPatchesChangeEnabled(),
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
await _settingsViewModel.showPatchesChangeEnableDialog(value, context);
|
await _settingsViewModel.showPatchesChangeEnableDialog(value, context);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/settingsFragment/settings_manage_keystore_password.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.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/settings_section.dart';
|
||||||
@ -12,106 +12,88 @@ class SExportSection extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsSection(
|
return SettingsSection(
|
||||||
title: 'settingsView.exportSectionTitle',
|
title: t.settingsView.exportSectionTitle,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.exportPatchesLabel',
|
t.settingsView.exportPatchesLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.exportPatchesHint),
|
||||||
subtitle: I18nText('settingsView.exportPatchesHint'),
|
|
||||||
onTap: () => _settingsViewModel.exportPatches(),
|
onTap: () => _settingsViewModel.exportPatches(),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.importPatchesLabel',
|
t.settingsView.importPatchesLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.importPatchesHint),
|
||||||
subtitle: I18nText('settingsView.importPatchesHint'),
|
|
||||||
onTap: () => _settingsViewModel.importPatches(context),
|
onTap: () => _settingsViewModel.importPatches(context),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.resetStoredPatchesLabel',
|
t.settingsView.resetStoredPatchesLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.resetStoredPatchesHint),
|
||||||
subtitle: I18nText('settingsView.resetStoredPatchesHint'),
|
|
||||||
onTap: () => _showResetDialog(
|
onTap: () => _showResetDialog(
|
||||||
context,
|
context,
|
||||||
'settingsView.resetStoredPatchesDialogTitle',
|
t.settingsView.resetStoredPatchesDialogTitle,
|
||||||
'settingsView.resetStoredPatchesDialogText',
|
t.settingsView.resetStoredPatchesDialogText,
|
||||||
_settingsViewModel.resetSelectedPatches,
|
_settingsViewModel.resetSelectedPatches,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.resetStoredOptionsLabel',
|
t.settingsView.resetStoredOptionsLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.resetStoredOptionsHint),
|
||||||
subtitle: I18nText('settingsView.resetStoredOptionsHint'),
|
|
||||||
onTap: () => _showResetDialog(
|
onTap: () => _showResetDialog(
|
||||||
context,
|
context,
|
||||||
'settingsView.resetStoredOptionsDialogTitle',
|
t.settingsView.resetStoredOptionsDialogTitle,
|
||||||
'settingsView.resetStoredOptionsDialogText',
|
t.settingsView.resetStoredOptionsDialogText,
|
||||||
_settingsViewModel.resetAllOptions,
|
_settingsViewModel.resetAllOptions,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.exportKeystoreLabel',
|
t.settingsView.exportKeystoreLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.exportKeystoreHint),
|
||||||
subtitle: I18nText('settingsView.exportKeystoreHint'),
|
|
||||||
onTap: () => _settingsViewModel.exportKeystore(),
|
onTap: () => _settingsViewModel.exportKeystore(),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.importKeystoreLabel',
|
t.settingsView.importKeystoreLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.importKeystoreHint),
|
||||||
subtitle: I18nText('settingsView.importKeystoreHint'),
|
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await _settingsViewModel.importKeystore();
|
await _settingsViewModel.importKeystore();
|
||||||
final sManageKeystorePassword = SManageKeystorePassword();
|
final sManageKeystorePassword = SManageKeystorePassword();
|
||||||
@ -122,17 +104,14 @@ class SExportSection extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.regenerateKeystoreLabel',
|
t.settingsView.regenerateKeystoreLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.regenerateKeystoreHint),
|
||||||
subtitle: I18nText('settingsView.regenerateKeystoreHint'),
|
|
||||||
onTap: () => _showDeleteKeystoreDialog(context),
|
onTap: () => _showDeleteKeystoreDialog(context),
|
||||||
),
|
),
|
||||||
// SManageKeystorePasswordUI(),
|
// SManageKeystorePasswordUI(),
|
||||||
@ -149,19 +128,19 @@ class SExportSection extends StatelessWidget {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText(dialogTitle),
|
title: Text(dialogTitle),
|
||||||
content: I18nText(dialogText),
|
content: Text(dialogText),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
Navigator.of(context).pop(),
|
Navigator.of(context).pop(),
|
||||||
dialogAction(),
|
dialogAction(),
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -172,19 +151,19 @@ class SExportSection extends StatelessWidget {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('settingsView.regenerateKeystoreDialogTitle'),
|
title: Text(t.settingsView.regenerateKeystoreDialogTitle),
|
||||||
content: I18nText('settingsView.regenerateKeystoreDialogText'),
|
content: Text(t.settingsView.regenerateKeystoreDialogText),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: I18nText('noButton'),
|
child: Text(t.noButton),
|
||||||
),
|
),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
Navigator.of(context).pop(),
|
Navigator.of(context).pop(),
|
||||||
_settingsViewModel.deleteKeystore(),
|
_settingsViewModel.deleteKeystore(),
|
||||||
},
|
},
|
||||||
child: I18nText('yesButton'),
|
child: Text(t.yesButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
||||||
|
|
||||||
@ -19,17 +19,14 @@ class _SRequireSuggestedAppVersionState
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return HapticSwitchListTile(
|
return HapticSwitchListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.requireSuggestedAppVersionLabel',
|
t.settingsView.requireSuggestedAppVersionLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.requireSuggestedAppVersionHint),
|
||||||
subtitle: I18nText('settingsView.requireSuggestedAppVersionHint'),
|
|
||||||
value: _settingsViewModel.isRequireSuggestedAppVersionEnabled(),
|
value: _settingsViewModel.isRequireSuggestedAppVersionEnabled(),
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
await _settingsViewModel.showRequireSuggestedAppVersionDialog(
|
await _settingsViewModel.showRequireSuggestedAppVersionDialog(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
|
|
||||||
class SettingsSection extends StatelessWidget {
|
class SettingsSection extends StatelessWidget {
|
||||||
const SettingsSection({
|
const SettingsSection({
|
||||||
@ -17,16 +16,13 @@ class SettingsSection extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(top: 16.0, bottom: 10.0, left: 20.0),
|
padding: const EdgeInsets.only(top: 16.0, bottom: 10.0, left: 20.0),
|
||||||
child: I18nText(
|
|
||||||
title,
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: children,
|
children: children,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
|
||||||
|
|
||||||
@ -17,17 +17,14 @@ class _SShowUpdateDialogState extends State<SShowUpdateDialog> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return HapticSwitchListTile(
|
return HapticSwitchListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.showUpdateDialogLabel',
|
t.settingsView.showUpdateDialogLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.showUpdateDialogHint),
|
||||||
subtitle: I18nText('settingsView.showUpdateDialogHint'),
|
|
||||||
value: _settingsViewModel.showUpdateDialog(),
|
value: _settingsViewModel.showUpdateDialog(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/social_media_widget.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/social_media_widget.dart';
|
||||||
@ -12,21 +12,18 @@ class STeamSection extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsSection(
|
return SettingsSection(
|
||||||
title: 'settingsView.teamSectionTitle',
|
title: t.settingsView.teamSectionTitle,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.contributorsLabel',
|
t.settingsView.contributorsLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.contributorsHint),
|
||||||
subtitle: I18nText('settingsView.contributorsHint'),
|
|
||||||
onTap: () => _settingsViewModel.navigateToContributors(),
|
onTap: () => _settingsViewModel.navigateToContributors(),
|
||||||
),
|
),
|
||||||
const SocialMediaWidget(
|
const SocialMediaWidget(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
|
|
||||||
class SettingsTileDialog extends StatelessWidget {
|
class SettingsTileDialog extends StatelessWidget {
|
||||||
const SettingsTileDialog({
|
const SettingsTileDialog({
|
||||||
@ -18,17 +17,14 @@ class SettingsTileDialog extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding: padding ?? EdgeInsets.zero,
|
contentPadding: padding ?? EdgeInsets.zero,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
title,
|
title,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(subtitle),
|
||||||
subtitle: I18nText(subtitle),
|
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/patcher/patcher_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||||
@ -21,17 +21,14 @@ class _SUniversalPatchesState extends State<SUniversalPatches> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return HapticSwitchListTile(
|
return HapticSwitchListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.universalPatchesLabel',
|
t.settingsView.universalPatchesLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.universalPatchesHint),
|
||||||
subtitle: I18nText('settingsView.universalPatchesHint'),
|
|
||||||
value: _settingsViewModel.areUniversalPatchesEnabled(),
|
value: _settingsViewModel.areUniversalPatchesEnabled(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
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/patcher/patcher_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||||
@ -24,17 +24,14 @@ class _SVersionCompatibilityCheckState
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return HapticSwitchListTile(
|
return HapticSwitchListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'settingsView.versionCompatibilityCheckLabel',
|
t.settingsView.versionCompatibilityCheckLabel,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.settingsView.versionCompatibilityCheckHint),
|
||||||
subtitle: I18nText('settingsView.versionCompatibilityCheckHint'),
|
|
||||||
value: _settingsViewModel.isVersionCompatibilityCheckEnabled(),
|
value: _settingsViewModel.isVersionCompatibilityCheckEnabled(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.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/settingsView/social_media_item.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_icon.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_icon.dart';
|
||||||
@ -26,17 +26,14 @@ class SocialMediaWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
header: ListTile(
|
header: ListTile(
|
||||||
contentPadding: padding ?? EdgeInsets.zero,
|
contentPadding: padding ?? EdgeInsets.zero,
|
||||||
title: I18nText(
|
title: Text(
|
||||||
'socialMediaCard.widgetTitle',
|
t.socialMediaCard.widgetTitle,
|
||||||
child: const Text(
|
style: const TextStyle(
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
subtitle: Text(t.socialMediaCard.widgetSubtitle),
|
||||||
subtitle: I18nText('socialMediaCard.widgetSubtitle'),
|
|
||||||
),
|
),
|
||||||
expanded: Padding(
|
expanded: Padding(
|
||||||
padding: padding ?? EdgeInsets.zero,
|
padding: padding ?? EdgeInsets.zero,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
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_card.dart';
|
||||||
import 'package:timeago/timeago.dart';
|
import 'package:timeago/timeago.dart';
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ class _ApplicationItemState extends State<ApplicationItem> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: widget.onPressed,
|
onPressed: widget.onPressed,
|
||||||
child: I18nText('applicationItem.infoButton'),
|
child: Text(t.applicationItem.infoButton),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -31,7 +31,6 @@ dependencies:
|
|||||||
ref: 560d21c4148b53933313573e7eafca0b0eb9aadf # Branch: specify-namespace
|
ref: 560d21c4148b53933313573e7eafca0b0eb9aadf # Branch: specify-namespace
|
||||||
flutter_cache_manager: ^3.3.0
|
flutter_cache_manager: ^3.3.0
|
||||||
flutter_file_dialog: ^3.0.2
|
flutter_file_dialog: ^3.0.2
|
||||||
flutter_i18n: ^0.34.0
|
|
||||||
flutter_local_notifications: ^16.1.0
|
flutter_local_notifications: ^16.1.0
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
@ -68,12 +67,14 @@ dependencies:
|
|||||||
timezone: ^0.9.0
|
timezone: ^0.9.0
|
||||||
url_launcher: ^6.1.10
|
url_launcher: ^6.1.10
|
||||||
wakelock_plus: ^1.1.3
|
wakelock_plus: ^1.1.3
|
||||||
|
slang: ^3.25.0
|
||||||
|
slang_flutter: ^3.25.0
|
||||||
|
language_code: ^0.3.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: any
|
build_runner: any
|
||||||
flutter_lints: ^3.0.1
|
flutter_lints: ^3.0.1
|
||||||
injectable_generator: ^2.1.5
|
injectable_generator: ^2.1.5
|
||||||
json_serializable: ^6.6.1
|
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
@ -83,3 +84,6 @@ flutter:
|
|||||||
- asset: fonts/custom-icons.ttf
|
- asset: fonts/custom-icons.ttf
|
||||||
assets:
|
assets:
|
||||||
- assets/i18n/
|
- assets/i18n/
|
||||||
|
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
5
slang.yaml
Normal file
5
slang.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
base_locale: en
|
||||||
|
fallback_strategy: base_locale
|
||||||
|
input_file_pattern: .i18n.json
|
||||||
|
input_directory: assets/i18n
|
||||||
|
output_directory: lib/gen
|
Loading…
Reference in New Issue
Block a user