Compare commits

..

18 Commits

Author SHA1 Message Date
semantic-release-bot
a99406f0a9 chore(release): 1.21.0-dev.4 [skip ci]
# [1.21.0-dev.4](https://github.com/ReVanced/revanced-manager/compare/v1.21.0-dev.3...v1.21.0-dev.4) (2024-06-24)

### Bug Fixes

* Cache external API calls  ([#1911](https://github.com/ReVanced/revanced-manager/issues/1911)) ([2c3e2e6](2c3e2e639f))
* Follow language update immediately ([#1944](https://github.com/ReVanced/revanced-manager/issues/1944)) ([c13827e](c13827e8e1))
* SecurityException when patching application ([#1856](https://github.com/ReVanced/revanced-manager/issues/1856)) ([e0a6de2](e0a6de2c2b))
* Update dialog shows dev version & loading gets stuck in certain circumstances ([#1792](https://github.com/ReVanced/revanced-manager/issues/1792)) ([fc52560](fc52560244))

### Features

* Add ability to set `null` in patch options ([#1947](https://github.com/ReVanced/revanced-manager/issues/1947)) ([5c68d51](5c68d513a3))
2024-06-24 17:03:46 +00:00
Pun Butrach
73368b58be build: Support for Flutter 3.22 (#1921)
Signed-off-by: validcube <pun.butrach@gmail.com>
2024-06-24 23:55:37 +07:00
ReVanced Bot
ca14e77ba3 chore: Sync translations (#1899) 2024-06-24 23:55:03 +07:00
Pun Butrach
cafdfcda47 ci: Don't fail validation on unimportant warnings 2024-06-24 23:52:23 +07:00
aAbed
5c68d513a3 feat: Add ability to set null in patch options (#1947) 2024-06-24 23:37:16 +07:00
kitadai31
fc52560244 fix: Update dialog shows dev version & loading gets stuck in certain circumstances (#1792)
Signed-off-by: validcube <pun.butrach@gmail.com>
Co-authored-by: validcube <pun.butrach@gmail.com>
2024-06-19 14:44:09 +07:00
Pun Butrach
46f6a49a7a ci: Always run on dev branch only 2024-06-15 17:36:25 +07:00
Snehith
c13827e8e1 fix: Follow language update immediately (#1944)
Co-authored-by: surya-technovert <surya.m@technovert.com>
2024-06-15 17:21:47 +07:00
Pun Butrach
e0a6de2c2b fix: SecurityException when patching application (#1856) 2024-05-28 11:36:31 +07:00
yonggamer
afdba00722 build: Fix invalid Gradle wrapper checksum (#1919) 2024-05-28 09:31:48 +07:00
oSumAtrIX
9084c71aa3 build: Bump dependencies 2024-05-26 01:21:14 +02:00
oSumAtrIX
8fc5fb6a80 docs: Improve issue templates 2024-05-26 00:43:38 +02:00
validcube
5f762c5442 build: Update Dart dependencies
Signed-off-by: validcube <pun.butrach@gmail.com>
2024-05-19 19:15:35 +07:00
Pun Butrach
8b21ec1ea3 ci: Switch to Flutter instead 2024-05-19 18:54:48 +07:00
Pun Butrach
e83fbb864e ci: Run slang first before validating translation 2024-05-19 18:46:49 +07:00
KobeW50
f03af17f71 docs: Fix issue template mistakes (#1910) 2024-05-19 01:33:18 +07:00
kitadai31
2c3e2e639f fix: Cache external API calls (#1911) 2024-05-18 10:52:13 -07:00
KobeW50
cc85b393dc docs: Fix punctuation in issue forms (#1909) 2024-05-18 01:18:29 +07:00
43 changed files with 871 additions and 929 deletions

View File

@@ -70,7 +70,7 @@ body:
Before creating a new bug report, please keep the following in mind: Before creating a new bug report, please keep the following in mind:
- **Do not submit a duplicate bug report**: You can review existing bug reports [here](https://github.com/ReVanced/revanced-manager/labels/Bug%20report). - **Do not submit a duplicate bug report**: Search for existing bug reports [here](https://github.com/ReVanced/revanced-manager/issues?q=label%3A%22Bug+report%22).
- **Review the contribution guidelines**: Make sure your bug report adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-manager/blob/main/CONTRIBUTING.md). - **Review the contribution guidelines**: Make sure your bug report adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-manager/blob/main/CONTRIBUTING.md).
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app). - **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
- type: textarea - type: textarea
@@ -99,14 +99,14 @@ body:
- type: textarea - type: textarea
attributes: attributes:
label: ReVanced Manager logs label: ReVanced Manager logs
description: Export logs in ReVanced Manager settings. description: Export logs from the ReVanced Manager settings.
render: shell render: shell
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Patch logs label: Patch logs
description: Export logs in "Patcher" screen. description: Export logs from the "Patcher" screen.
render: shell render: shell
validations: validations:
required: false required: false
@@ -116,11 +116,11 @@ body:
label: Acknowledgements label: Acknowledgements
description: Your bug report will be closed if you don't follow the checklist below. description: Your bug report will be closed if you don't follow the checklist below.
options: options:
- label: This issue is not a duplicate of an existing bug report. - label: I have checked all open and closed bug reports and this is not a duplicate.
required: true required: true
- label: I have chosen an appropriate title. - label: I have chosen an appropriate title.
required: true required: true
- label: All requested information has been provided properly. - label: All requested information has been provided properly.
required: true required: true
- label: The bug is only related to ReVanced Manager - label: The bug is only related to ReVanced Manager.
required: true required: true

View File

@@ -70,7 +70,7 @@ body:
Before creating a new feature request, please keep the following in mind: Before creating a new feature request, please keep the following in mind:
- **Do not submit a duplicate feature request**: You can review existing feature requests [here](https://github.com/ReVanced/revanced-manager//labels/Feature%20request). - **Do not submit a duplicate feature request**: Search for existing feature requests [here](https://github.com/ReVanced/revanced-manager/issues?q=label%3A%22Feature+request%22).
- **Review the contribution guidelines**: Make sure your feature request adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-manager/blob/main/CONTRIBUTING.md). - **Review the contribution guidelines**: Make sure your feature request adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-manager/blob/main/CONTRIBUTING.md).
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app). - **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
- type: textarea - type: textarea
@@ -79,7 +79,6 @@ body:
description: | description: |
- Describe your feature in detail - Describe your feature in detail
- Add images, videos, links, examples, references, etc. if possible - Add images, videos, links, examples, references, etc. if possible
- Add the target application name in case you request a new patch
- type: textarea - type: textarea
attributes: attributes:
label: Motivation label: Motivation
@@ -98,9 +97,9 @@ body:
label: Acknowledgements label: Acknowledgements
description: Your feature request will be closed if you don't follow the checklist below. description: Your feature request will be closed if you don't follow the checklist below.
options: options:
- label: This issue is not a duplicate of an existing feature request. - label: I have checked all open and closed feature requests and this is not a duplicate.
required: true required: true
- label: I have chosen an appropriate title. - label: I have chosen an appropriate title.
required: true required: true
- label: The feature request is only related to ReVanced Manager - label: The feature request is only related to ReVanced Manager.
required: true required: true

View File

@@ -61,6 +61,7 @@ jobs:
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: 3.22.x
cache: ${{ inputs.flutter-cache }} cache: ${{ inputs.flutter-cache }}
- name: Get dependencies - name: Get dependencies

View File

@@ -36,6 +36,7 @@ jobs:
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: 3.22.x
- name: Install dependencies - name: Install dependencies
run: npm install run: npm install

View File

@@ -5,6 +5,7 @@ on:
schedule: schedule:
- cron: 00 12 * * 1 - cron: 00 12 * * 1
push: push:
branches: dev
paths: paths:
- assets/i18n/*.json - assets/i18n/*.json
- assets/i18n/*.dart - assets/i18n/*.dart
@@ -20,8 +21,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Dart - name: Setup Flutter
uses: dart-lang/setup-dart@v1 uses: subosito/flutter-action@v2
with:
cache: true
flutter-version: 3.22.x
- name: Sync translations from Crowdin - name: Sync translations from Crowdin
uses: crowdin/github-action@v1 uses: crowdin/github-action@v1
@@ -51,7 +55,9 @@ jobs:
- name: Validation of Translation Strings - name: Validation of Translation Strings
run: | run: |
dart analyze lib/gen/strings.g.dart dart pub get
dart run slang
flutter analyze lib/gen/strings.g.dart --no-fatal-infos --no-fatal-warnings
- name: Commit translations - name: Commit translations
run: | run: |

View File

@@ -23,10 +23,11 @@ if (flutterVersionName == null) {
} }
android { android {
compileSdk flutter.compileSdkVersion compileSdk 34
ndkVersion flutter.ndkVersion ndkVersion flutter.ndkVersion
compileOptions { compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17 sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17
} }
@@ -113,6 +114,7 @@ flutter {
} }
dependencies { dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") // https://pub.dev/packages/flutter_local_notifications#gradle-setup
implementation("app.revanced:revanced-patcher:19.3.1") implementation("app.revanced:revanced-patcher:19.3.1")
implementation("app.revanced:revanced-library:2.2.1") implementation("app.revanced:revanced-library:2.2.1")
} }

View File

@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -18,8 +18,8 @@ pluginManagement {
plugins { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.1.2" apply false id "com.android.application" version "8.4.1" apply false
id "org.jetbrains.kotlin.android" version "1.9.23" apply false id "org.jetbrains.kotlin.android" version "2.0.0" apply false
} }
include ":app" include ":app"

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Custom value", "customValue": "Custom value",
"setToNull": "Set to null",
"nullValue": "This option value is currently null",
"resetOptionsTooltip": "Reset patch options", "resetOptionsTooltip": "Reset patch options",
"viewTitle": "Patch options", "viewTitle": "Patch options",
"saveOptions": "Save", "saveOptions": "Save",
"addOptions": "Add options", "addOptions": "Add options",
"deselectPatch": "Deselect patch", "unselectPatch": "Unselect patch",
"tooltip": "More input options", "tooltip": "More input options",
"selectFilePath": "Select file path", "selectFilePath": "Select file path",
"selectFolder": "Select folder", "selectFolder": "Select folder",
"selectOption": "Select option", "selectOption": "Select option",
"requiredOption": "This option is required", "requiredOption": "Setting this option is required",
"unsupportedOption": "This option is not supported", "unsupportedOption": "This option is not supported",
"requiredOptionNull": "The following options have to be set:\n\n${options}" "requiredOptionNull": "The following options have to be set:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "تخصيص القيمة", "customValue": "تخصيص القيمة",
"setToNull": "تعيين إلى فارغ",
"nullValue": "قيمة هذا الخيار فارغة حاليا",
"resetOptionsTooltip": "إعادة تعيين خيارات التعديل", "resetOptionsTooltip": "إعادة تعيين خيارات التعديل",
"viewTitle": "خيارات التعديل", "viewTitle": "خيارات التعديل",
"saveOptions": "حفظ", "saveOptions": "حفظ",
"addOptions": "إضافة خيارات", "addOptions": "إضافة خيارات",
"deselectPatch": "إلغاء تحديد التعديل", "unselectPatch": "إلغاء تحديد التصحيح",
"tooltip": "المزيد من خيارات الإدخال", "tooltip": "المزيد من خيارات الإدخال",
"selectFilePath": "تحديد مسار الملف", "selectFilePath": "تحديد مسار الملف",
"selectFolder": "تحديد مجلد", "selectFolder": "تحديد مجلد",
"selectOption": "تحديد خيار", "selectOption": "تحديد خيار",
"requiredOption": "هذا الخيار مطلوب", "requiredOption": "إعداد هذا الخيار مطلوب",
"unsupportedOption": "هذا الخيار غير مدعوم", "unsupportedOption": "هذا الخيار غير مدعوم",
"requiredOptionNull": "يجب تعيين الخيارات التالية:\n\n${options}" "requiredOptionNull": "يجب تعيين الخيارات التالية:\n\n${options}"
}, },
@@ -143,7 +145,7 @@
"installType": "تحديد نوع التثبيت", "installType": "تحديد نوع التثبيت",
"installTypeDescription": "تحديد نوع التثبيت للمتابعة.", "installTypeDescription": "تحديد نوع التثبيت للمتابعة.",
"installButton": "تثبيت", "installButton": "تثبيت",
"installRootType": "تحميل", "installRootType": "Mount",
"installNonRootType": "عادي", "installNonRootType": "عادي",
"warning": "قم بتعطيل التحديثات التلقائية للتطبيق المعدل لتجنب المشكلات غير المتوقعة.", "warning": "قم بتعطيل التحديثات التلقائية للتطبيق المعدل لتجنب المشكلات غير المتوقعة.",
"pressBackAgain": "اضغط رجوع مرة اخرى للإلغاء", "pressBackAgain": "اضغط رجوع مرة اخرى للإلغاء",
@@ -255,14 +257,14 @@
"widgetTitle": "معلومات التطبيق", "widgetTitle": "معلومات التطبيق",
"openButton": "فتح", "openButton": "فتح",
"uninstallButton": "إلغاء التثبيت", "uninstallButton": "إلغاء التثبيت",
"unmountButton": "إلغاء التحميل", "unmountButton": "Unmount",
"rootDialogTitle": "خطأ", "rootDialogTitle": "خطأ",
"unmountDialogText": "هل أنت متأكد أنك تريد إلغاء تحميل هذا التطبيق؟", "unmountDialogText": "هل أنت متأكد من أنك تريد Unmount لهذا التطبيق؟",
"uninstallDialogText": "هل أنت متأكد من أنك تريد إلغاء تثبيت هذا التطبيق؟", "uninstallDialogText": "هل أنت متأكد من أنك تريد إلغاء تثبيت هذا التطبيق؟",
"rootDialogText": "تم تثبيت التطبيق بأذونات المستخدم المتميز، لكن ReVanced Manager ليس لديه أذونات حاليًا.\nالرجاء منح أذونات المستخدم المتميز أولاً.", "rootDialogText": "تم تثبيت التطبيق بأذونات المستخدم المتميز، لكن ReVanced Manager ليس لديه أذونات حاليًا.\nالرجاء منح أذونات المستخدم المتميز أولاً.",
"packageNameLabel": "اسم الحُزْمَة", "packageNameLabel": "اسم الحُزْمَة",
"installTypeLabel": "نوع التثبيت", "installTypeLabel": "نوع التثبيت",
"mountTypeLabel": "تحميل", "mountTypeLabel": "Mount",
"regularTypeLabel": "عادي", "regularTypeLabel": "عادي",
"patchedDateLabel": "تاريخ التعديل", "patchedDateLabel": "تاريخ التعديل",
"appliedPatchesLabel": "التعديلات المطبقة", "appliedPatchesLabel": "التعديلات المطبقة",

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Vlastní hodnota", "customValue": "Vlastní hodnota",
"setToNull": "Nastavit na null",
"nullValue": "Tato hodnota volby je v současné době null",
"resetOptionsTooltip": "Obnovit nastavení záplat", "resetOptionsTooltip": "Obnovit nastavení záplat",
"viewTitle": "Nastavení záplat", "viewTitle": "Nastavení záplat",
"saveOptions": "Uložit", "saveOptions": "Uložit",
"addOptions": "Přidat možnosti", "addOptions": "Přidat možnosti",
"deselectPatch": "Odznačit záplatu", "unselectPatch": "Zrušit výběr patch",
"tooltip": "Další možnosti vstupu", "tooltip": "Další možnosti vstupu",
"selectFilePath": "Zvolte cestu k souboru", "selectFilePath": "Zvolte cestu k souboru",
"selectFolder": "Vybrat složku", "selectFolder": "Vybrat složku",
"selectOption": "Vybrat možnost", "selectOption": "Vybrat možnost",
"requiredOption": "Tato možnost je vyžadována", "requiredOption": "Nastavení této možnosti je vyžadováno",
"unsupportedOption": "Tato možnost není podporována", "unsupportedOption": "Tato možnost není podporována",
"requiredOptionNull": "Tyto možnosti musí být nastaveny:\n\n${options}" "requiredOptionNull": "Tyto možnosti musí být nastaveny:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Tilpasset værdi", "customValue": "Tilpasset værdi",
"setToNull": "Sæt til nul",
"nullValue": "Denne valgmulighed værdi er i øjeblikket nul",
"resetOptionsTooltip": "Nulstil patch indstillinger", "resetOptionsTooltip": "Nulstil patch indstillinger",
"viewTitle": "Patch indstillinger", "viewTitle": "Patch indstillinger",
"saveOptions": "Gem", "saveOptions": "Gem",
"addOptions": "Tilføj indstillinger", "addOptions": "Tilføj indstillinger",
"deselectPatch": "Fravælg patch", "unselectPatch": "Fravælg patch",
"tooltip": "Flere input-indstillinger", "tooltip": "Flere input-indstillinger",
"selectFilePath": "Vælg fil sti", "selectFilePath": "Vælg fil sti",
"selectFolder": "Vælg mappe", "selectFolder": "Vælg mappe",
"selectOption": "Vælg indstilling", "selectOption": "Vælg indstilling",
"requiredOption": "Denne indstilling er påkrævet", "requiredOption": "Indstilling af denne indstilling er påkrævet",
"unsupportedOption": "Denne indstilling understøttes ikke", "unsupportedOption": "Denne indstilling understøttes ikke",
"requiredOptionNull": "Følgende indstillinger skal indstilles:\n\n${options}" "requiredOptionNull": "Følgende indstillinger skal indstilles:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Benutzerdefinierter Wert", "customValue": "Benutzerdefinierter Wert",
"setToNull": "Auf Null setzen",
"nullValue": "Dieser Optionswert ist derzeit null",
"resetOptionsTooltip": "Patch-Optionen zurücksetzen", "resetOptionsTooltip": "Patch-Optionen zurücksetzen",
"viewTitle": "Patch-Optionen", "viewTitle": "Patch-Optionen",
"saveOptions": "Speichern", "saveOptions": "Speichern",
"addOptions": "Option hinzufügen", "addOptions": "Option hinzufügen",
"deselectPatch": "Patch abwählen", "unselectPatch": "Patch entfernen",
"tooltip": "Weitere Eingabeoptionen", "tooltip": "Weitere Eingabeoptionen",
"selectFilePath": "Dateipfad auswählen", "selectFilePath": "Dateipfad auswählen",
"selectFolder": "Ordner auswählen", "selectFolder": "Ordner auswählen",
"selectOption": "Option auswählen", "selectOption": "Option auswählen",
"requiredOption": "Diese Option ist erforderlich.", "requiredOption": "Einstellung dieser Option ist erforderlich",
"unsupportedOption": "Dieser Vorgang ist nicht unterstützt.", "unsupportedOption": "Dieser Vorgang ist nicht unterstützt.",
"requiredOptionNull": "Die folgenden Optionen müssen gesetzt sein:\n\n${options}" "requiredOptionNull": "Die folgenden Optionen müssen gesetzt sein:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Προσαρμοσμένη τιμή", "customValue": "Προσαρμοσμένη τιμή",
"setToNull": "Ορισμός σε null",
"nullValue": "Αυτή η επιλογή είναι κενή",
"resetOptionsTooltip": "Επαναφορά επιλογών τροποποιήσεων", "resetOptionsTooltip": "Επαναφορά επιλογών τροποποιήσεων",
"viewTitle": "Επιλογές τροποποιήσεων", "viewTitle": "Επιλογές τροποποιήσεων",
"saveOptions": "Αποθήκευση", "saveOptions": "Αποθήκευση",
"addOptions": "Προσθήκη επιλογών", "addOptions": "Προσθήκη επιλογών",
"deselectPatch": "Αποεπιλέξτε τροποποιήσεις", "unselectPatch": "Αποεπιλογή patch",
"tooltip": "Περισσότερες επιλογές εισόδου", "tooltip": "Περισσότερες επιλογές εισόδου",
"selectFilePath": "Επιλογή τοποθεσίας αρχείου", "selectFilePath": "Επιλογή τοποθεσίας αρχείου",
"selectFolder": "Επιλογή φακέλου", "selectFolder": "Επιλογή φακέλου",
"selectOption": "Επιλογή ρύθμισης", "selectOption": "Επιλογή ρύθμισης",
"requiredOption": "Αυτή η επιλογή απαιτείται", "requiredOption": "Απαιτείται ρύθμιση αυτής της επιλογής",
"unsupportedOption": "Αυτή η επιλογή δεν υποστηρίζεται", "unsupportedOption": "Αυτή η επιλογή δεν υποστηρίζεται",
"requiredOptionNull": "Πρέπει να οριστούν οι παρακάτω επιλογές:\n\n${options}" "requiredOptionNull": "Πρέπει να οριστούν οι παρακάτω επιλογές:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valor personalizado", "customValue": "Valor personalizado",
"setToNull": "Establecer a nulo",
"nullValue": "Este valor de opción es nulo actualmente",
"resetOptionsTooltip": "Restablecer a los valores por defecto", "resetOptionsTooltip": "Restablecer a los valores por defecto",
"viewTitle": "Configuración\\ndel parche", "viewTitle": "Configuración\\ndel parche",
"saveOptions": "Guardar configuración", "saveOptions": "Guardar configuración",
"addOptions": "Agregar configuración", "addOptions": "Agregar configuración",
"deselectPatch": "Deseleccionar parche", "unselectPatch": "Deseleccionar parche",
"tooltip": "Más opciones de entrada", "tooltip": "Más opciones de entrada",
"selectFilePath": "Seleccionar ruta del archivo", "selectFilePath": "Seleccionar ruta del archivo",
"selectFolder": "Seleccionar carpeta", "selectFolder": "Seleccionar carpeta",
"selectOption": "Seleccionar opción", "selectOption": "Seleccionar opción",
"requiredOption": "Esta opción es requerida", "requiredOption": "La configuración de esta opción es necesaria",
"unsupportedOption": "Esta opción no es compatible", "unsupportedOption": "Esta opción no es compatible",
"requiredOptionNull": "Tenés que configurar las siguientes opciones:\\n\\n${options}" "requiredOptionNull": "Tenés que configurar las siguientes opciones:\\n\\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valor personalizado", "customValue": "Valor personalizado",
"setToNull": "Establecer a nulo",
"nullValue": "Este valor de opción es nulo actualmente",
"resetOptionsTooltip": "Restablecer las opciones de parche", "resetOptionsTooltip": "Restablecer las opciones de parche",
"viewTitle": "Opciones de parche", "viewTitle": "Opciones de parche",
"saveOptions": "Guardar", "saveOptions": "Guardar",
"addOptions": "Añadir opciones", "addOptions": "Añadir opciones",
"deselectPatch": "Deseleccionar parche", "unselectPatch": "Deseleccionar parche",
"tooltip": "Más opciones de entrada", "tooltip": "Más opciones de entrada",
"selectFilePath": "Seleccionar ruta del archivo", "selectFilePath": "Seleccionar ruta del archivo",
"selectFolder": "Seleccionar carpeta", "selectFolder": "Seleccionar carpeta",
"selectOption": "Seleccionar opción", "selectOption": "Seleccionar opción",
"requiredOption": "Esta opción es necesaria", "requiredOption": "La configuración de esta opción es necesaria",
"unsupportedOption": "Esta opción no está disponible", "unsupportedOption": "Esta opción no está disponible",
"requiredOptionNull": "Hay que establecer las siguientes opciones:\n\n${options}" "requiredOptionNull": "Hay que establecer las siguientes opciones:\n\n${options}"
}, },

View File

@@ -41,7 +41,7 @@
"downloadConsentDialogTitle": "¿Descargar archivos necesarios?", "downloadConsentDialogTitle": "¿Descargar archivos necesarios?",
"downloadConsentDialogText": "ReVanced Manager necesita descargar los archivos necesarios para funcionar correctamente.", "downloadConsentDialogText": "ReVanced Manager necesita descargar los archivos necesarios para funcionar correctamente.",
"downloadConsentDialogText2": "Esto te conectará a ${url}.", "downloadConsentDialogText2": "Esto te conectará a ${url}.",
"checkUpdateDialogTitle": "¿Buscar actualizaciones?", "checkUpdateDialogTitle": "¿Comprobar actualizaciones?",
"checkUpdateDialogText": "¿Quieres que ReVanced Manager compruebe si hay actualizaciones automáticamente?", "checkUpdateDialogText": "¿Quieres que ReVanced Manager compruebe si hay actualizaciones automáticamente?",
"notificationTitle": "Actualización descargada", "notificationTitle": "Actualización descargada",
"notificationText": "Toca para instalar la actualización", "notificationText": "Toca para instalar la actualización",
@@ -91,14 +91,14 @@
}, },
"appSelectorView": { "appSelectorView": {
"viewTitle": "Seleccionar una aplicación", "viewTitle": "Seleccionar una aplicación",
"searchBarHint": "Buscar app", "searchBarHint": "Buscar aplicación",
"storageButton": "Almacenamiento", "storageButton": "Almacenamiento",
"selectFromStorageButton": "Seleccionar desde almacenamiento", "selectFromStorageButton": "Seleccionar desde almacenamiento",
"errorMessage": "No se puede usar la aplicación seleccionada", "errorMessage": "No se puede usar la aplicación seleccionada",
"downloadToast": "La función de descarga aún no está disponible", "downloadToast": "La función de descarga aún no está disponible",
"requireSuggestedAppVersionDialogText": "La versión de la aplicación que has seleccionado no coincide con la versión sugerida, lo que podría causar errores inesperados. Por favor, utiliza la versión sugerida.\n\nVersión seleccionada: ${selected}\nVersión sugerida: ${suggested}\n\nPara continuar de todas formas, desactiva \"Requerir versión sugerida de la aplicación\" en la configuración.", "requireSuggestedAppVersionDialogText": "La versión de la aplicación que has seleccionado no coincide con la versión sugerida, lo que podría causar errores inesperados. Por favor, utiliza la versión sugerida.\n\nVersión seleccionada: ${selected}\nVersión sugerida: ${suggested}\n\nPara continuar de todas formas, desactiva \"Requerir versión sugerida de la aplicación\" en la configuración.",
"featureNotAvailable": "Característica no implementada", "featureNotAvailable": "Característica no implementada",
"featureNotAvailableText": "Esta aplicación es un APK dividido y solo puede ser parcheada e instalada de forma fiable mediante el montaje con permisos de root. Sin embargo, puedes parchear e instalar un APK completo seleccionándolo del almacenamiento." "featureNotAvailableText": "Esta aplicación es una APK dividida y solo puede ser parcheada e instalada confiablemente al montar con permisos de root. Sin embargo, puedes parchear e instalar una APK completa seleccionándola en el almacenamiento."
}, },
"patchesSelectorView": { "patchesSelectorView": {
"viewTitle": "Selecciona parches", "viewTitle": "Selecciona parches",
@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valor personalizado", "customValue": "Valor personalizado",
"setToNull": "Establecer a nulo",
"nullValue": "Este valor de opción es nulo actualmente",
"resetOptionsTooltip": "Restablecer las opciones de parche", "resetOptionsTooltip": "Restablecer las opciones de parche",
"viewTitle": "Opciones de parche", "viewTitle": "Opciones de parche",
"saveOptions": "Guardar", "saveOptions": "Guardar",
"addOptions": "Añadir opciones", "addOptions": "Añadir opciones",
"deselectPatch": "Deseleccionar parche", "unselectPatch": "Deseleccionar parche",
"tooltip": "Más opciones de entrada", "tooltip": "Más opciones de entrada",
"selectFilePath": "Selecciona la ruta del archivo", "selectFilePath": "Selecciona la ruta del archivo",
"selectFolder": "Selecciona la carpeta", "selectFolder": "Selecciona la carpeta",
"selectOption": "Seleccionar opción", "selectOption": "Seleccionar opción",
"requiredOption": "Esta opción es requerida", "requiredOption": "La configuración de esta opción es necesaria",
"unsupportedOption": "Esta opción no está disponible", "unsupportedOption": "Esta opción no está disponible",
"requiredOptionNull": "Hay que configurar las siguientes opciones:\n\n${options}" "requiredOptionNull": "Hay que configurar las siguientes opciones:\n\n${options}"
}, },
@@ -196,7 +198,7 @@
"enablePatchesSelectionLabel": "Permitir cambiar la selección de parches", "enablePatchesSelectionLabel": "Permitir cambiar la selección de parches",
"enablePatchesSelectionHint": "No prevenir la selección o deselección de parches", "enablePatchesSelectionHint": "No prevenir la selección o deselección de parches",
"enablePatchesSelectionWarningText": "Cambiar la selección de parches puede cauar problemas inespereados.\n\n¿Quieres activarlo de todas formas?", "enablePatchesSelectionWarningText": "Cambiar la selección de parches puede cauar problemas inespereados.\n\n¿Quieres activarlo de todas formas?",
"disablePatchesSelectionWarningText": "Estás a punto de desactivar cambiar la selección de parches.\nLa selección predeterminada de parches se restaura.\n\n¿Deshabilitar de todos modos?", "disablePatchesSelectionWarningText": "Estás a punto de desactivar cambiar la selección de los parches.\nLa selección predeterminada de los parches se restaurada.\n\n¿Desactivar de todos modos?",
"autoUpdatePatchesLabel": "Actualizar parches automáticamente", "autoUpdatePatchesLabel": "Actualizar parches automáticamente",
"autoUpdatePatchesHint": "Actualiza los parches a la última versión automáticamente", "autoUpdatePatchesHint": "Actualiza los parches a la última versión automáticamente",
"showUpdateDialogLabel": "Mostrar diálogo de actualización", "showUpdateDialogLabel": "Mostrar diálogo de actualización",
@@ -252,7 +254,7 @@
"keystoreSelectorErrorMessage": "No se puede utilizar el archivo de repositorio de claves seleccionado" "keystoreSelectorErrorMessage": "No se puede utilizar el archivo de repositorio de claves seleccionado"
}, },
"appInfoView": { "appInfoView": {
"widgetTitle": "Informacion de la applicacion", "widgetTitle": "Informacion de la aplicación",
"openButton": "Abrir", "openButton": "Abrir",
"uninstallButton": "Desinstalar", "uninstallButton": "Desinstalar",
"unmountButton": "Desmontar", "unmountButton": "Desmontar",

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Oma arvo", "customValue": "Oma arvo",
"setToNull": "Aseta tyhjäksi",
"nullValue": "Tämä valinta arvo on tällä hetkellä nolla",
"resetOptionsTooltip": "Palauta paikkausasetukset", "resetOptionsTooltip": "Palauta paikkausasetukset",
"viewTitle": "Paikkausasetukset", "viewTitle": "Paikkausasetukset",
"saveOptions": "Tallenna", "saveOptions": "Tallenna",
"addOptions": "Lisää asetuksia", "addOptions": "Lisää asetuksia",
"deselectPatch": "Poista paikkauksen valinta", "unselectPatch": "Peru korjauksen valinta",
"tooltip": "Enemmän syöteasetuksia", "tooltip": "Enemmän syöteasetuksia",
"selectFilePath": "Valitse tiedostosijainti", "selectFilePath": "Valitse tiedostosijainti",
"selectFolder": "Valitse kansio", "selectFolder": "Valitse kansio",
"selectOption": "Valitse asetus", "selectOption": "Valitse asetus",
"requiredOption": "Tämä asetus vaaditaan", "requiredOption": "Tämän asetuksen asettaminen on pakollinen",
"unsupportedOption": "Tätä asetusta ei tueta", "unsupportedOption": "Tätä asetusta ei tueta",
"requiredOptionNull": "Seuraavat asetukset on määritettävä:\n\n${options}" "requiredOptionNull": "Seuraavat asetukset on määritettävä:\n\n${options}"
}, },

View File

@@ -29,7 +29,7 @@
"updatesSubtitle": "Mises à jour", "updatesSubtitle": "Mises à jour",
"patchedSubtitle": "Applications patchées", "patchedSubtitle": "Applications patchées",
"changeLaterSubtitle": "Vous pouvez changer cela dans les paramètres ultérieurement.", "changeLaterSubtitle": "Vous pouvez changer cela dans les paramètres ultérieurement.",
"noUpdates": "Aucune mise à jour n'est disponible", "noUpdates": "Aucune mise à jour disponible",
"WIP": "Bientôt disponible...", "WIP": "Bientôt disponible...",
"noInstallations": "Aucune application patchée installée", "noInstallations": "Aucune application patchée installée",
"installUpdate": "Continuer à installer la mise à jour ?", "installUpdate": "Continuer à installer la mise à jour ?",
@@ -51,7 +51,7 @@
"errorDownloadMessage": "Impossible de télécharger la mise à jour", "errorDownloadMessage": "Impossible de télécharger la mise à jour",
"errorInstallMessage": "Impossible d'installer la mise à jour", "errorInstallMessage": "Impossible d'installer la mise à jour",
"noConnection": "Aucune connexion internet", "noConnection": "Aucune connexion internet",
"updatesDisabled": "La mise à jour d'une application patchée est actuellement désactivée. Repatchez l'application à nouveau." "updatesDisabled": "La mise à jour d'une application patchée est actuellement désactivée. Repatchez l'application."
}, },
"applicationItem": { "applicationItem": {
"infoButton": "Info" "infoButton": "Info"
@@ -82,8 +82,8 @@
"patchSelectorCard": { "patchSelectorCard": {
"widgetTitle": "Sélectionner les patchs", "widgetTitle": "Sélectionner les patchs",
"widgetTitleSelected": "Patchs sélectionnés", "widgetTitleSelected": "Patchs sélectionnés",
"widgetSubtitle": "Choisissez d'abord une application", "widgetSubtitle": "Sélectionnez d'abord une application",
"widgetEmptySubtitle": "Aucun patch n'est sélectionné" "widgetEmptySubtitle": "Aucun patch sélectionné"
}, },
"socialMediaCard": { "socialMediaCard": {
"widgetTitle": "Réseaux sociaux", "widgetTitle": "Réseaux sociaux",
@@ -118,24 +118,26 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valeur personnalisée", "customValue": "Valeur personnalisée",
"setToNull": "Définir à NULL",
"nullValue": "Cette valeur d'option est actuellement nulle",
"resetOptionsTooltip": "Réinitialiser les options de patch", "resetOptionsTooltip": "Réinitialiser les options de patch",
"viewTitle": "Options de patch", "viewTitle": "Options de patch",
"saveOptions": "Enregistrer", "saveOptions": "Enregistrer",
"addOptions": "Ajouter des options", "addOptions": "Ajouter des options",
"deselectPatch": "Désélectionner tous les patchs", "unselectPatch": "Désélectionner le patch",
"tooltip": "Plus d'options d'entrée", "tooltip": "Plus d'options d'entrée",
"selectFilePath": "Sélectionner l'emplacement du fichier", "selectFilePath": "Sélectionner l'emplacement du fichier",
"selectFolder": "Sélectionner le dossier", "selectFolder": "Sélectionner le dossier",
"selectOption": "Sélectionner une option", "selectOption": "Sélectionner une option",
"requiredOption": "Cette option est obligatoire", "requiredOption": "Définir cette option est nécessaire",
"unsupportedOption": "Cette option n'est pas supportée", "unsupportedOption": "Cette option n'est pas prise en charge",
"requiredOptionNull": "Les options suivantes doivent être définies :\n\n${options}" "requiredOptionNull": "Les options suivantes doivent être définies :\n\n${options}"
}, },
"patchItem": { "patchItem": {
"unsupportedDialogText": "Sélectionner ce patch pourrait entrainer des erreurs dans la modification.\n\nVersion de l'application : ${packageVersion}\nVersions supportées :\n${supportedVersions}", "unsupportedDialogText": "Sélectionner ce patch peut entrainer des erreurs dans la modification.\n\nVersion de l'application : ${packageVersion}\nVersions prises en charge :\n${supportedVersions}",
"unsupportedPatchVersion": "Le patch n'est pas supporté pour cette version de l'application.", "unsupportedPatchVersion": "Le patch n'est pas pris en charge pour cette version de l'application.",
"unsupportedRequiredOption": "Ce patch contient une option requise qui n'est pas supporté par cette application", "unsupportedRequiredOption": "Ce patch contient une option requise qui n'est pas prise en charge par cette application",
"patchesChangeWarningDialogText": "Il est recommandé d'utiliser les patchs par défaut ainsi que les options. Leur modification peut entraîner des problèmes inattendus.\n\nVous aurez besoin d'activer \"Autoriser la modification de la sélection du patch\" dans les paramètres avant de modifier toute sélection de patch.", "patchesChangeWarningDialogText": "Il est recommandé d'utiliser les patchs et options par défaut. Leur modification peut entraîner des problèmes inattendus.\n\nVous aurez besoin d'activer « Autoriser la modification de la sélection de patchs » dans les paramètres avant de modifier toute sélection de patchs.",
"patchesChangeWarningDialogButton": "Utiliser la sélection par défaut" "patchesChangeWarningDialogButton": "Utiliser la sélection par défaut"
}, },
"installerView": { "installerView": {
@@ -193,7 +195,7 @@
"contributorsHint": "Liste des contributeurs de ReVanced", "contributorsHint": "Liste des contributeurs de ReVanced",
"logsLabel": "Partager les journaux", "logsLabel": "Partager les journaux",
"logsHint": "Partager les logs de ReVanced Manager", "logsHint": "Partager les logs de ReVanced Manager",
"enablePatchesSelectionLabel": "Autoriser la modification de la sélection du patch", "enablePatchesSelectionLabel": "Autoriser la modification de la sélection de patchs",
"enablePatchesSelectionHint": "Ne pas empêcher la sélection ou la désélection des patchs", "enablePatchesSelectionHint": "Ne pas empêcher la sélection ou la désélection des patchs",
"enablePatchesSelectionWarningText": "Le changement de sélection par défaut des patchs peut causer des problèmes inattendus \n\nActiver quand même?", "enablePatchesSelectionWarningText": "Le changement de sélection par défaut des patchs peut causer des problèmes inattendus \n\nActiver quand même?",
"disablePatchesSelectionWarningText": "Vous êtes sur le point de désactiver le changement de sélection par défaut des patchs.\nLa sélection par défaut des patchs sera restaurée.\n\nDésactiver quand même ?", "disablePatchesSelectionWarningText": "Vous êtes sur le point de désactiver le changement de sélection par défaut des patchs.\nLa sélection par défaut des patchs sera restaurée.\n\nDésactiver quand même ?",

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valore personalizzato", "customValue": "Valore personalizzato",
"setToNull": "Imposta a nullo",
"nullValue": "Questo valore di opzione è al momento nullo",
"resetOptionsTooltip": "Ripristina opzioni patch", "resetOptionsTooltip": "Ripristina opzioni patch",
"viewTitle": "Opzioni patch", "viewTitle": "Opzioni patch",
"saveOptions": "Salva", "saveOptions": "Salva",
"addOptions": "Aggiungi opzioni", "addOptions": "Aggiungi opzioni",
"deselectPatch": "Deseleziona patch", "unselectPatch": "Deseleziona patch",
"tooltip": "Più opzioni di input", "tooltip": "Più opzioni di input",
"selectFilePath": "Seleziona percorso file", "selectFilePath": "Seleziona percorso file",
"selectFolder": "Seleziona cartella", "selectFolder": "Seleziona cartella",
"selectOption": "Seleziona opzione", "selectOption": "Seleziona opzione",
"requiredOption": "Questa opzione è richiesta", "requiredOption": "L'impostazione di questa opzione è obbligatoria",
"unsupportedOption": "Questa opzione non è supportata", "unsupportedOption": "Questa opzione non è supportata",
"requiredOptionNull": "È necessario impostare le seguenti opzioni:\n\n${options}" "requiredOptionNull": "È necessario impostare le seguenti opzioni:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "カスタム値", "customValue": "カスタム値",
"setToNull": "null に設定",
"nullValue": "このオプション値は現在nullです",
"resetOptionsTooltip": "パッチ設定をリセット", "resetOptionsTooltip": "パッチ設定をリセット",
"viewTitle": "パッチ設定", "viewTitle": "パッチ設定",
"saveOptions": "保存", "saveOptions": "保存",
"addOptions": "オプションを追加", "addOptions": "オプションを追加",
"deselectPatch": "パッチの選択を解除", "unselectPatch": "パッチの選択を解除",
"tooltip": "他の入力オプション", "tooltip": "他の入力オプション",
"selectFilePath": "ファイルパスを選択", "selectFilePath": "ファイルパスを選択",
"selectFolder": "フォルダーを選択", "selectFolder": "フォルダーを選択",
"selectOption": "オプションを選択", "selectOption": "オプションを選択",
"requiredOption": "このオプションは必須です", "requiredOption": "このオプションを設定する必要があります",
"unsupportedOption": "この設定はサポートされていません", "unsupportedOption": "この設定はサポートされていません",
"requiredOptionNull": "以下のオプションを設定する必要があります:\n\n${options}" "requiredOptionNull": "以下のオプションを設定する必要があります:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Aangepaste waarde", "customValue": "Aangepaste waarde",
"setToNull": "Zet op nul",
"nullValue": "Deze optiewaarde is momenteel leeg",
"resetOptionsTooltip": "Reset patch opties", "resetOptionsTooltip": "Reset patch opties",
"viewTitle": "Patch opties", "viewTitle": "Patch opties",
"saveOptions": "Opslaan", "saveOptions": "Opslaan",
"addOptions": "Opties toevoegen", "addOptions": "Opties toevoegen",
"deselectPatch": "Deselecteer patch", "unselectPatch": "Patch deselecteren",
"tooltip": "Meer invoeropties", "tooltip": "Meer invoeropties",
"selectFilePath": "Bestandspad selecteren", "selectFilePath": "Bestandspad selecteren",
"selectFolder": "Map selecteren", "selectFolder": "Map selecteren",
"selectOption": "Selecteer optie", "selectOption": "Selecteer optie",
"requiredOption": "Deze optie is vereist", "requiredOption": "Het instellen van deze optie is vereist",
"unsupportedOption": "Deze optie wordt niet ondersteund", "unsupportedOption": "Deze optie wordt niet ondersteund",
"requiredOptionNull": "De volgende opties moeten worden ingesteld:\n\n${options}" "requiredOptionNull": "De volgende opties moeten worden ingesteld:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Niestandardowa wartość", "customValue": "Niestandardowa wartość",
"setToNull": "Ustaw na zerowy",
"nullValue": "Ta opcja jest obecnie pusta",
"resetOptionsTooltip": "Zresetuj opcje od łatek", "resetOptionsTooltip": "Zresetuj opcje od łatek",
"viewTitle": "Opcje łatek", "viewTitle": "Opcje łatek",
"saveOptions": "Zapisz", "saveOptions": "Zapisz",
"addOptions": "Dodaj opcje", "addOptions": "Dodaj opcje",
"deselectPatch": "Odznacz łatkę", "unselectPatch": "Odznacz łatkę",
"tooltip": "Więcej opcji wejściowych", "tooltip": "Więcej opcji wejściowych",
"selectFilePath": "Wybierz ścieżkę pliku", "selectFilePath": "Wybierz ścieżkę pliku",
"selectFolder": "Wybierz folder", "selectFolder": "Wybierz folder",
"selectOption": "Wybierz opcję", "selectOption": "Wybierz opcję",
"requiredOption": "Ta opcja jest wymagana", "requiredOption": "Ustawienie tej opcji jest wymagane",
"unsupportedOption": "Ta opcja nie jest wspierana", "unsupportedOption": "Ta opcja nie jest wspierana",
"requiredOptionNull": "Należy ustawić następujące opcje:\n\n${options}" "requiredOptionNull": "Należy ustawić następujące opcje:\n\n${options}"
}, },

View File

@@ -27,7 +27,7 @@
"refreshSuccess": "Atualizado com sucesso", "refreshSuccess": "Atualizado com sucesso",
"widgetTitle": "Painel", "widgetTitle": "Painel",
"updatesSubtitle": "Atualizações", "updatesSubtitle": "Atualizações",
"patchedSubtitle": "Aplicativos patcheados", "patchedSubtitle": "Aplicativos patcheados ",
"changeLaterSubtitle": "Você pode ajustar essa opção nas configurações mais tarde.", "changeLaterSubtitle": "Você pode ajustar essa opção nas configurações mais tarde.",
"noUpdates": "Nenhuma atualização encontrada", "noUpdates": "Nenhuma atualização encontrada",
"WIP": "Trabalho em progresso...", "WIP": "Trabalho em progresso...",
@@ -40,7 +40,7 @@
"updateDialogText": "Uma nova atualização está disponível para ${file}.\n\nA versão atualmente instalada é a ${version}.", "updateDialogText": "Uma nova atualização está disponível para ${file}.\n\nA versão atualmente instalada é a ${version}.",
"downloadConsentDialogTitle": "Baixar os arquivos necessários?", "downloadConsentDialogTitle": "Baixar os arquivos necessários?",
"downloadConsentDialogText": "O ReVanced Manager precisará baixar os arquivos necessários para funcionar corretamente.", "downloadConsentDialogText": "O ReVanced Manager precisará baixar os arquivos necessários para funcionar corretamente.",
"downloadConsentDialogText2": "Isso irá te conectar em ${url}.", "downloadConsentDialogText2": "Isso vai conectar você em ${url}.",
"checkUpdateDialogTitle": "Procurar atualizações?", "checkUpdateDialogTitle": "Procurar atualizações?",
"checkUpdateDialogText": "Você quer que o ReVanced Manager procure atualizações automaticamente?", "checkUpdateDialogText": "Você quer que o ReVanced Manager procure atualizações automaticamente?",
"notificationTitle": "Atualização baixada", "notificationTitle": "Atualização baixada",
@@ -71,9 +71,9 @@
"requiredOptionDialogText": "Algumas opções de patch tiveram que ser definidas." "requiredOptionDialogText": "Algumas opções de patch tiveram que ser definidas."
}, },
"appSelectorCard": { "appSelectorCard": {
"widgetTitle": "Selecione um aplicativo", "widgetTitle": "Selecione um app",
"widgetTitleSelected": "Aplicativo selecionado", "widgetTitleSelected": "App selecionado",
"widgetSubtitle": "Nenhum aplicativo selecionado", "widgetSubtitle": "Nenhum app selecionado",
"noAppsLabel": "Nenhum aplicativo foi encontrado", "noAppsLabel": "Nenhum aplicativo foi encontrado",
"currentVersion": "Atual", "currentVersion": "Atual",
"suggestedVersion": "Sugeridos/sugestões", "suggestedVersion": "Sugeridos/sugestões",
@@ -96,7 +96,7 @@
"selectFromStorageButton": "Selecionar no armazenamento", "selectFromStorageButton": "Selecionar no armazenamento",
"errorMessage": "Não foi possível usar o app selecionado", "errorMessage": "Não foi possível usar o app selecionado",
"downloadToast": "A função de download não está disponível no momento", "downloadToast": "A função de download não está disponível no momento",
"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.", "requireSuggestedAppVersionDialogText": "A versão do app selecionada não corresponde à versão sugerida, o que pode causar problemas inesperados. Por favor, use a versão sugerida.\n\nVersão selecionada: ${selected} \nVersão sugerida: ${suggested}\n\nPara continuar mesmo assim, desative \"Exigir versão sugerida do app\" nas configurações.",
"featureNotAvailable": "Recurso não implementado", "featureNotAvailable": "Recurso não implementado",
"featureNotAvailableText": "Este aplicativo é um APK dividido e só pode ser patcheado e instalado de forma confiável ao ser montado com permissões de root. No entanto, você pode patchear e instalar um APK completo ao selecioná-lo do armazenamento." "featureNotAvailableText": "Este aplicativo é um APK dividido e só pode ser patcheado e instalado de forma confiável ao ser montado com permissões de root. No entanto, você pode patchear e instalar um APK completo ao selecioná-lo do armazenamento."
}, },
@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valor personalizado", "customValue": "Valor personalizado",
"resetOptionsTooltip": "Redefinir opções de patch", "setToNull": "Definir como nulo",
"nullValue": "Atualmente, este valor de opção é nulo",
"resetOptionsTooltip": "Redefinir as opções de patch",
"viewTitle": "Opções de patch", "viewTitle": "Opções de patch",
"saveOptions": "Salvar", "saveOptions": "Salvar",
"addOptions": "Adicionar opções", "addOptions": "Adicionar opções",
"deselectPatch": "Deselecionar patch", "unselectPatch": "Desmarque o patch",
"tooltip": "Mais opções de entrada", "tooltip": "Mais opções de entrada",
"selectFilePath": "Selecione o caminho do arquivo", "selectFilePath": "Selecione o caminho do arquivo",
"selectFolder": "Selecione a pasta", "selectFolder": "Selecione a pasta",
"selectOption": "Selecione uma opção", "selectOption": "Selecione uma opção",
"requiredOption": "Essa opção é necessária", "requiredOption": "Definir esta opção é necessário",
"unsupportedOption": "Essa opção não é suportada", "unsupportedOption": "Essa opção não é suportada",
"requiredOptionNull": "As seguintes opções precisam ser definidas:\n\n${options}" "requiredOptionNull": "As seguintes opções precisam ser definidas:\n\n${options}"
}, },
@@ -178,7 +180,7 @@
"sourcesLabelHint": "Conigure as fontes alternativas para ReVanced Patches e ReVanced Integrations", "sourcesLabelHint": "Conigure as fontes alternativas para ReVanced Patches e ReVanced Integrations",
"sourcesIntegrationsLabel": "Fonte das integrações", "sourcesIntegrationsLabel": "Fonte das integrações",
"useAlternativeSources": "Usar fontes alternativas", "useAlternativeSources": "Usar fontes alternativas",
"useAlternativeSourcesHint": "Use alternative sources for ReVanced Patches and ReVanced Integrations instead of the API", "useAlternativeSourcesHint": "Use fontes alternativas para Patches do ReVanced e Integrações do ReVanced em vez da API",
"sourcesResetDialogTitle": "Redefinir", "sourcesResetDialogTitle": "Redefinir",
"sourcesResetDialogText": "Você tem certeza que deseja redefinir as fontes para os valores padrão?", "sourcesResetDialogText": "Você tem certeza que deseja redefinir as fontes para os valores padrão?",
"apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?", "apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?",
@@ -199,15 +201,15 @@
"disablePatchesSelectionWarningText": "Você irá desabilitar a mudança da pré-seleção dos patches.\nA seleção padrão dos patches será restaurada.\n\nDesabilitar mesmo assim?", "disablePatchesSelectionWarningText": "Você irá desabilitar a mudança da pré-seleção dos patches.\nA seleção padrão dos patches será restaurada.\n\nDesabilitar mesmo assim?",
"autoUpdatePatchesLabel": "Atualizar patches automaticamente", "autoUpdatePatchesLabel": "Atualizar patches automaticamente",
"autoUpdatePatchesHint": "Atualize automaticamente os patches para a versão mais recente", "autoUpdatePatchesHint": "Atualize automaticamente os patches para a versão mais recente",
"showUpdateDialogLabel": "Show update dialog", "showUpdateDialogLabel": "Mostrar alerta de atualização",
"showUpdateDialogHint": "Show a dialog when a new update is available", "showUpdateDialogHint": "Mostra um aviso quando uma nova atualização estiver disponível",
"universalPatchesLabel": "Mostrar patches universais", "universalPatchesLabel": "Mostrar patches universais",
"universalPatchesHint": "Mostra todos os aplicativos e patches universais (pode deixar a lista de aplicativos mais lenta)", "universalPatchesHint": "Mostra todos os aplicativos e patches universais (pode deixar a lista de aplicativos mais lenta)",
"versionCompatibilityCheckLabel": "Verificar compatibilidade de versão", "versionCompatibilityCheckLabel": "Verificar compatibilidade de versão",
"versionCompatibilityCheckHint": "Prevent selecting patches that are not compatible with the selected app version", "versionCompatibilityCheckHint": "Impedir a seleção de patches que não são compatíveis com a versão do app selecionado",
"requireSuggestedAppVersionLabel": "Requer a versão sugerida do app", "requireSuggestedAppVersionLabel": "Exigir versão sugerida do app",
"requireSuggestedAppVersionHint": "Evite selecionar um aplicativo com uma versão diferente da sugerida", "requireSuggestedAppVersionHint": "Evite selecionar um app com uma versão diferente da sugerida",
"requireSuggestedAppVersionDialogText": "Selecionar um aplicativo que não seja a versão sugerida pode causar problemas inesperados.\n\nVocê quer prosseguir mesmo assim?", "requireSuggestedAppVersionDialogText": "Selecionar um app que não seja a versão sugerida pode causar problemas inesperados.\n\nVocê quer prosseguir mesmo assim?",
"aboutLabel": "Sobre", "aboutLabel": "Sobre",
"snackbarMessage": "Copiado para a área de transferência", "snackbarMessage": "Copiado para a área de transferência",
"restartAppForChanges": "Reinicie o aplicativo para aplicar as mudanças", "restartAppForChanges": "Reinicie o aplicativo para aplicar as mudanças",
@@ -221,16 +223,16 @@
"importPatchesLabel": "Importar seleção de patch", "importPatchesLabel": "Importar seleção de patch",
"importPatchesHint": "Importar seleção de patch de um arquivo JSON", "importPatchesHint": "Importar seleção de patch de um arquivo JSON",
"importedPatches": "Seleção de patch importada", "importedPatches": "Seleção de patch importada",
"resetStoredPatchesLabel": "Redefinir seleção de patch", "resetStoredPatchesLabel": "Redefinir a seleção de patch",
"resetStoredPatchesHint": "Redefinir a seleção de patch armazenada", "resetStoredPatchesHint": "Redefinir a seleção de patch armazenada",
"resetStoredPatchesDialogTitle": "Redefinir seleção de patch?", "resetStoredPatchesDialogTitle": "Redefinir a seleção de patch?",
"resetStoredPatchesDialogText": "A seleção padrão de patches será restaurada.", "resetStoredPatchesDialogText": "A seleção padrão de patches será restaurada.",
"resetStoredPatches": "A seleção de patch foi redefinida", "resetStoredPatches": "A seleção de patch foi redefinida",
"resetStoredOptionsLabel": "Redefinir opções de patch", "resetStoredOptionsLabel": "Redefinir as opções de patch",
"resetStoredOptionsHint": "Resetar todas as opções de patch", "resetStoredOptionsHint": "Redefinir todas as opções de patch",
"resetStoredOptionsDialogTitle": "Reset patch options?", "resetStoredOptionsDialogTitle": "Redefinir as opções de patch?",
"resetStoredOptionsDialogText": "Resetting patch options will remove all saved options.", "resetStoredOptionsDialogText": "Redefinir as opções de patch vai remover todas as opções salvas.",
"resetStoredOptions": "As opções foram resetadas", "resetStoredOptions": "As opções foram redefinidas",
"deleteLogsLabel": "Limpar registros", "deleteLogsLabel": "Limpar registros",
"deleteLogsHint": "Delete collected ReVanced Manager logs", "deleteLogsHint": "Delete collected ReVanced Manager logs",
"deletedLogs": "Registros apagados", "deletedLogs": "Registros apagados",
@@ -286,7 +288,7 @@
"status_failure_incompatible": "Instalação incompatível", "status_failure_incompatible": "Instalação incompatível",
"status_failure_timeout": "Tempo limite de instalação", "status_failure_timeout": "Tempo limite de instalação",
"status_unknown": "Falha na instalação", "status_unknown": "Falha na instalação",
"mount_version_mismatch_description": "A instalação falhou devido ao aplicativo instalado ser uma versão diferente do aplicativo patcheado.\n\nInstale a versão do aplicativo que você está montando e tente novamente.", "mount_version_mismatch_description": "A instalação falhou porque o app instalado era de uma versão diferente do app patcheado.\n\nInstale a versão do app que você está montando e tente de novo.",
"mount_no_root_description": "A instalação falhou devido ao acesso root não ter sido concedido.\n\nConceda acesso root ao Gerenciador ReVanced e tente novamente.", "mount_no_root_description": "A instalação falhou devido ao acesso root não ter sido concedido.\n\nConceda acesso root ao Gerenciador ReVanced e tente novamente.",
"mount_missing_installation_description": "A instalação falhou devido ao aplicativo não patcheado não estar instalado neste dispositivo para ser montado sobre ele.\n\nInstale o aplicativo não patcheado antes de montar e tente novamente.", "mount_missing_installation_description": "A instalação falhou devido ao aplicativo não patcheado não estar instalado neste dispositivo para ser montado sobre ele.\n\nInstale o aplicativo não patcheado antes de montar e tente novamente.",
"status_failure_timeout_description": "A instalação demorou muito para terminar.\n\nVocê gostaria de tentar novamente?", "status_failure_timeout_description": "A instalação demorou muito para terminar.\n\nVocê gostaria de tentar novamente?",
@@ -296,7 +298,7 @@
"status_failure_conflict_description": "A instalação foi impedida por uma instalação existente do aplicativo.\n\nDesinstale o aplicativo instalado e tente novamente", "status_failure_conflict_description": "A instalação foi impedida por uma instalação existente do aplicativo.\n\nDesinstale o aplicativo instalado e tente novamente",
"status_failure_blocked_description": "A instalação foi bloqueada por ${packageName}.\n\nAjuste suas configurações de segurança e tente novamente.", "status_failure_blocked_description": "A instalação foi bloqueada por ${packageName}.\n\nAjuste suas configurações de segurança e tente novamente.",
"install_failed_verification_failure_description": "A instalação falhou devido a um problema de verificação.\n\nAjuste suas configurações de segurança e tente novamente.", "install_failed_verification_failure_description": "A instalação falhou devido a um problema de verificação.\n\nAjuste suas configurações de segurança e tente novamente.",
"install_failed_version_downgrade_description": "A instalação falhou devido ao aplicativo patcheado ser uma versão mais baixa que o aplicativo instalado.\n\nDesinstale o aplicativo e tente novamente.", "install_failed_version_downgrade_description": "A instalação falhou porque o app patcheado era uma versão mais baixa que o app instalado.\n\nDesinstalar o app e tentar de novo?",
"status_unknown_description": "A instalação falhou por um motivo desconhecido. Por favor, tente novamente." "status_unknown_description": "A instalação falhou por um motivo desconhecido. Por favor, tente novamente."
} }
} }

View File

@@ -1,7 +1,7 @@
{ {
"okButton": "OK", "okButton": "OK",
"cancelButton": "Cancelar", "cancelButton": "Cancelar",
"dismissButton": "Dispensar", "dismissButton": "Ignorar",
"quitButton": "Sair", "quitButton": "Sair",
"updateButton": "Atualizar", "updateButton": "Atualizar",
"enabledLabel": "Ativado", "enabledLabel": "Ativado",
@@ -27,11 +27,11 @@
"refreshSuccess": "Atualizado com sucesso", "refreshSuccess": "Atualizado com sucesso",
"widgetTitle": "Painel de Controlo", "widgetTitle": "Painel de Controlo",
"updatesSubtitle": "Atualizações", "updatesSubtitle": "Atualizações",
"patchedSubtitle": "Aplicações Modificadas", "patchedSubtitle": "Apps patcheados",
"changeLaterSubtitle": "Podes modificar esta definição mais tarde.", "changeLaterSubtitle": "Podes modificar esta definição mais tarde.",
"noUpdates": "Nenhuma atualização disponível", "noUpdates": "Nenhuma atualização disponível",
"WIP": "Trabalho em progresso...", "WIP": "Trabalho em progresso...",
"noInstallations": "Nenhuma aplicação modificada instalada", "noInstallations": "Nenhum app patcheado instalado",
"installUpdate": "Continuar para instalar a atualização?", "installUpdate": "Continuar para instalar a atualização?",
"updateSheetTitle": "Atualizar o ReVanced Manager", "updateSheetTitle": "Atualizar o ReVanced Manager",
"updateDialogTitle": "Nova atualização disponível", "updateDialogTitle": "Nova atualização disponível",
@@ -51,7 +51,7 @@
"errorDownloadMessage": "Não é possível transferir a atualização", "errorDownloadMessage": "Não é possível transferir a atualização",
"errorInstallMessage": "Não foi possível instalar a atualização", "errorInstallMessage": "Não foi possível instalar a atualização",
"noConnection": "Sem ligação à Internet", "noConnection": "Sem ligação à Internet",
"updatesDisabled": "Atualizar uma aplicação modificada está atualmente desabilitado. Volta a modificar a aplicação." "updatesDisabled": "A atualização de um app patcheado está desativada no momento. Repatch o app de novo."
}, },
"applicationItem": { "applicationItem": {
"infoButton": "Informação" "infoButton": "Informação"
@@ -98,7 +98,7 @@
"downloadToast": "A função de transferência não está disponível", "downloadToast": "A função de transferência não está disponível",
"requireSuggestedAppVersionDialogText": "A versão da aplicação que selecionaste não corresponde à versão sugerida, o que pode levar a problemas inesperados. Utiliza a versão recomendada.\n\nVersão selecionada: ${selected}\nVersão recomendada: ${suggested}\n\nPara continuar na mesma, desactive a opção \"Exigir a versão recomendada da aplicação\" nas definições.", "requireSuggestedAppVersionDialogText": "A versão da aplicação que selecionaste não corresponde à versão sugerida, o que pode levar a problemas inesperados. Utiliza a versão recomendada.\n\nVersão selecionada: ${selected}\nVersão recomendada: ${suggested}\n\nPara continuar na mesma, desactive a opção \"Exigir a versão recomendada da aplicação\" nas definições.",
"featureNotAvailable": "Recurso não implementado", "featureNotAvailable": "Recurso não implementado",
"featureNotAvailableText": "Esta aplicação é um APK dividido e só pode ser modificado e instalado de forma fiável através da montagem com permissões root. No entanto, é possível corrigir e instalar um APK completo selecionando-o a partir do armazenamento." "featureNotAvailableText": "Esse app é um APK dividido e só pode ser modificado e instalado de forma fiável através da montagem com permissões root. No entanto, é possível patchear e instalar um APK completo selecionando ele a partir do armazenamento."
}, },
"patchesSelectorView": { "patchesSelectorView": {
"viewTitle": "Selecionar modificações", "viewTitle": "Selecionar modificações",
@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valor personalizado", "customValue": "Valor personalizado",
"setToNull": "Definir como nulo",
"nullValue": "Atualmente, este valor de opção é nulo",
"resetOptionsTooltip": "Reiniciar as opções da modificação", "resetOptionsTooltip": "Reiniciar as opções da modificação",
"viewTitle": "Opções de modificação", "viewTitle": "Opções de modificação",
"saveOptions": "Guardar", "saveOptions": "Guardar",
"addOptions": "Adicionar opções", "addOptions": "Adicionar opções",
"deselectPatch": "Desselecionar modificação", "unselectPatch": "Desmarque o patch",
"tooltip": "Mais opções de entrada", "tooltip": "Mais opções de entrada",
"selectFilePath": "Selecionar caminho do arquivo", "selectFilePath": "Selecionar caminho do arquivo",
"selectFolder": "Selecionar pasta", "selectFolder": "Selecionar pasta",
"selectOption": "Seleccionar opção", "selectOption": "Seleccionar opção",
"requiredOption": "Esta opção é obrigatória", "requiredOption": "Definir esta opção é necessário",
"unsupportedOption": "Esta opção não é suportada", "unsupportedOption": "Esta opção não é suportada",
"requiredOptionNull": "As seguintes opções devem ser definidas:\n\n${options}" "requiredOptionNull": "As seguintes opções devem ser definidas:\n\n${options}"
}, },
@@ -145,13 +147,13 @@
"installButton": "Instalar", "installButton": "Instalar",
"installRootType": "Montar", "installRootType": "Montar",
"installNonRootType": "Normal", "installNonRootType": "Normal",
"warning": "Desativa as atualizações automáticas da aplicação modificada para evitar problemas inesperados.", "warning": "Desative as atualizações automáticas do app patcheado para evitar problemas inesperados.",
"pressBackAgain": "Pressione voltar novamente para cancelar", "pressBackAgain": "Pressione voltar novamente para cancelar",
"openButton": "Abrir", "openButton": "Abrir",
"shareButton": "Partilhar ficheiro", "shareButton": "Partilhar ficheiro",
"notificationTitle": "O ReVanced Manager está a fazer as modificações", "notificationTitle": "O ReVanced Manager está a fazer as modificações",
"notificationText": "Toca para voltar ao instalador", "notificationText": "Toca para voltar ao instalador",
"exportApkButtonTooltip": "Exportar APK modificado", "exportApkButtonTooltip": "Exportar APK patcheado",
"exportLogButtonTooltip": "Exportar registo", "exportLogButtonTooltip": "Exportar registo",
"screenshotDetected": "Foi detetada uma captura de ecrã. Se estiver a tentar partilhar o registo, partilhe antes uma cópia de texto.\n\nCopiar o registo para a área de transferência?", "screenshotDetected": "Foi detetada uma captura de ecrã. Se estiver a tentar partilhar o registo, partilhe antes uma cópia de texto.\n\nCopiar o registo para a área de transferência?",
"copiedToClipboard": "Registo copiado para a área de transferência", "copiedToClipboard": "Registo copiado para a área de transferência",
@@ -258,13 +260,13 @@
"unmountButton": "Desmontar", "unmountButton": "Desmontar",
"rootDialogTitle": "Erro", "rootDialogTitle": "Erro",
"unmountDialogText": "Tens a certeza que queres remover as modificações desta aplicação?", "unmountDialogText": "Tens a certeza que queres remover as modificações desta aplicação?",
"uninstallDialogText": "Tens a certeza que queres desinstalar esta aplicação?", "uninstallDialogText": "Tem certeza que quer desinstalar esse app?",
"rootDialogText": "A aplicação foi instalada com permissões de Super-Utilizador, mas atualmente o ReVanced Manager não tem permissões.\nPor favor, conceda permissões de Super-Utilizador primeiro.", "rootDialogText": "A aplicação foi instalada com permissões de Super-Utilizador, mas atualmente o ReVanced Manager não tem permissões.\nPor favor, conceda permissões de Super-Utilizador primeiro.",
"packageNameLabel": "Nome do pacote", "packageNameLabel": "Nome do pacote",
"installTypeLabel": "Tipo de instalação", "installTypeLabel": "Tipo de instalação",
"mountTypeLabel": "Montar", "mountTypeLabel": "Montar",
"regularTypeLabel": "Normal", "regularTypeLabel": "Normal",
"patchedDateLabel": "Data da Modificação", "patchedDateLabel": "Data do patch",
"appliedPatchesLabel": "Modificações aplicadas", "appliedPatchesLabel": "Modificações aplicadas",
"patchedDateHint": "${date} às ${time}", "patchedDateHint": "${date} às ${time}",
"appliedPatchesHint": "${quantity} modificação/ões aplicada/s", "appliedPatchesHint": "${quantity} modificação/ões aplicada/s",
@@ -293,10 +295,10 @@
"status_failure_storage_description": "A instalação falhou devido ao armazenamento insuficiente.\n\nLiberta algum espaço e tenta novamente.", "status_failure_storage_description": "A instalação falhou devido ao armazenamento insuficiente.\n\nLiberta algum espaço e tenta novamente.",
"status_failure_invalid_description": "A instalação falhou devido ao facto da aplicação modificada ser inválida.\n\nDesinstalar a aplicação e tentar novamente?", "status_failure_invalid_description": "A instalação falhou devido ao facto da aplicação modificada ser inválida.\n\nDesinstalar a aplicação e tentar novamente?",
"status_failure_incompatible_description": "O aplicativo é incompatível com este dispositivo.\n\nEntre em contacto com o desenvolvedor da aplicação e peça suporte.", "status_failure_incompatible_description": "O aplicativo é incompatível com este dispositivo.\n\nEntre em contacto com o desenvolvedor da aplicação e peça suporte.",
"status_failure_conflict_description": "A instalação foi impedida por uma instalação existente da mesma aplicação.\n\nDesinstalar a aplicação instalada e tentar novamente?", "status_failure_conflict_description": "A instalação foi impedida por uma instalação existente do app.\n\nDesinstalar o app instalado e tentar de novo?",
"status_failure_blocked_description": "A instalação foi bloqueada por ${packageName}.\n\nAjuste as suas definições de segurança e tenta novamente.", "status_failure_blocked_description": "A instalação foi bloqueada por ${packageName}.\n\nAjuste as suas definições de segurança e tenta novamente.",
"install_failed_verification_failure_description": "A instalação falhou por problemas de verificação.\n\nAjusta as tuas definições de segurança e tenta novamente.", "install_failed_verification_failure_description": "A instalação falhou por problemas de verificação.\n\nAjusta as tuas definições de segurança e tenta novamente.",
"install_failed_version_downgrade_description": "A instalação falhou devido ao facto da aplicação modificada ser uma versão inferior à da aplicação instalada.\n\nDesinstalar a aplicação e tentar novamente?", "install_failed_version_downgrade_description": "A instalação falhou porque o app patcheado era uma versão inferior ao aplicativo instalado.\n\nDesinstalar o app e tentar de novo?",
"status_unknown_description": "A instalação falhou por razões desconhecidas. Por favor, tenta novamente." "status_unknown_description": "A instalação falhou por razões desconhecidas. Por favor, tenta novamente."
} }
} }

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Valoare personalizată", "customValue": "Valoare personalizată",
"setToNull": "Setează ca nul",
"nullValue": "Această valoare este în prezent nulă",
"resetOptionsTooltip": "Resetează opțiunile patch-ului", "resetOptionsTooltip": "Resetează opțiunile patch-ului",
"viewTitle": "Opțiuni patch", "viewTitle": "Opțiuni patch",
"saveOptions": "Salvează", "saveOptions": "Salvează",
"addOptions": "Adaugă opțiuni", "addOptions": "Adaugă opțiuni",
"deselectPatch": "Deselectați toate patch-urile", "unselectPatch": "Deselectează patch-ul",
"tooltip": "Mai multe opțiuni de intrare", "tooltip": "Mai multe opțiuni de intrare",
"selectFilePath": "Selectați calea fișierului", "selectFilePath": "Selectați calea fișierului",
"selectFolder": "Selectați dosarul", "selectFolder": "Selectați dosarul",
"selectOption": "Selectați opțiunea", "selectOption": "Selectați opțiunea",
"requiredOption": "Această opțiune este necesară", "requiredOption": "Setarea acestei opțiuni este necesară",
"unsupportedOption": "Această opțiune nu este acceptată", "unsupportedOption": "Această opțiune nu este acceptată",
"requiredOptionNull": "Următoarele opțiuni trebuie setate:\n\n${options}" "requiredOptionNull": "Următoarele opțiuni trebuie setate:\n\n${options}"
}, },

View File

@@ -118,11 +118,13 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Пользовательское значение", "customValue": "Пользовательское значение",
"setToNull": "Установить null",
"nullValue": "Значение этого параметра в настоящее время является нулевым",
"resetOptionsTooltip": "Сброс параметров патчей", "resetOptionsTooltip": "Сброс параметров патчей",
"viewTitle": "Параметры патчей", "viewTitle": "Параметры патчей",
"saveOptions": "Сохранить", "saveOptions": "Сохранить",
"addOptions": "Добавить параметры", "addOptions": "Добавить параметры",
"deselectPatch": "Снять выделение с патча", "unselectPatch": "Отменить выбор патча",
"tooltip": "Другие параметры ввода", "tooltip": "Другие параметры ввода",
"selectFilePath": "Выберите путь к файлу", "selectFilePath": "Выберите путь к файлу",
"selectFolder": "Выберите папку", "selectFolder": "Выберите папку",

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Anpassat värde", "customValue": "Anpassat värde",
"setToNull": "Sätt till noll",
"nullValue": "Detta alternativ värde är för närvarande noll",
"resetOptionsTooltip": "Återställ patchalternativ", "resetOptionsTooltip": "Återställ patchalternativ",
"viewTitle": "Patchalternativ", "viewTitle": "Patchalternativ",
"saveOptions": "Spara", "saveOptions": "Spara",
"addOptions": "Lägg till alternativ", "addOptions": "Lägg till alternativ",
"deselectPatch": "Avmarkera patch", "unselectPatch": "Avmarkera patch",
"tooltip": "Fler inmatningsalternativ", "tooltip": "Fler inmatningsalternativ",
"selectFilePath": "Välj filsökväg", "selectFilePath": "Välj filsökväg",
"selectFolder": "Välj mapp", "selectFolder": "Välj mapp",
"selectOption": "Välj alternativ", "selectOption": "Välj alternativ",
"requiredOption": "Detta alternativ är nödvändigt", "requiredOption": "Inställning av detta alternativ krävs",
"unsupportedOption": "Detta alternativ stöds ej", "unsupportedOption": "Detta alternativ stöds ej",
"requiredOptionNull": "Följande alternativ måste anges:\n\n${options}" "requiredOptionNull": "Följande alternativ måste anges:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "Власне значення", "customValue": "Власне значення",
"setToNull": "Встановити в null",
"nullValue": "Значення опції в даний час null",
"resetOptionsTooltip": "Скинути параметри патчу", "resetOptionsTooltip": "Скинути параметри патчу",
"viewTitle": "Параметри патчу", "viewTitle": "Параметри патчу",
"saveOptions": "Зберегти", "saveOptions": "Зберегти",
"addOptions": "Додати параметри", "addOptions": "Додати параметри",
"deselectPatch": "Зняти вибір патчу", "unselectPatch": "Скасувати вибір патча",
"tooltip": "Більше варіантів вводу", "tooltip": "Більше варіантів вводу",
"selectFilePath": "Оберіть шлях до файлу", "selectFilePath": "Оберіть шлях до файлу",
"selectFolder": "Оберіть теку", "selectFolder": "Оберіть теку",
"selectOption": "Вибрати параметр", "selectOption": "Вибрати параметр",
"requiredOption": "Цей параметр є обовязковим", "requiredOption": "Встановлення цього параметра є обов'язковим",
"unsupportedOption": "Цей параметр не підтримується", "unsupportedOption": "Цей параметр не підтримується",
"requiredOptionNull": "Необхідно встановити наступні параметри:\n\n${options}" "requiredOptionNull": "Необхідно встановити наступні параметри:\n\n${options}"
}, },

View File

@@ -118,16 +118,18 @@
}, },
"patchOptionsView": { "patchOptionsView": {
"customValue": "自定义值", "customValue": "自定义值",
"setToNull": "设置为为空",
"nullValue": "此选项值当前为空",
"resetOptionsTooltip": "重置补丁选项", "resetOptionsTooltip": "重置补丁选项",
"viewTitle": "补丁选项", "viewTitle": "补丁选项",
"saveOptions": "保存", "saveOptions": "保存",
"addOptions": "添加选项", "addOptions": "添加选项",
"deselectPatch": "取消选择补丁", "unselectPatch": "取消选择补丁",
"tooltip": "更多输入选项", "tooltip": "更多输入选项",
"selectFilePath": "选择文件路径", "selectFilePath": "选择文件路径",
"selectFolder": "选择文件夹", "selectFolder": "选择文件夹",
"selectOption": "选择选项", "selectOption": "选择选项",
"requiredOption": "必须填写此选项", "requiredOption": "设置此选项是必需的",
"unsupportedOption": "不支持此选项", "unsupportedOption": "不支持此选项",
"requiredOptionNull": "必须设置以下选项:\n\n${options}" "requiredOptionNull": "必须设置以下选项:\n\n${options}"
}, },

View File

@@ -6,12 +6,14 @@ 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/services/download_manager.dart'; import 'package:revanced_manager/services/download_manager.dart';
import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/manager_api.dart';
import 'package:synchronized/synchronized.dart';
@lazySingleton @lazySingleton
class GithubAPI { class GithubAPI {
late final Dio _dio; late final Dio _dio;
late final ManagerAPI _managerAPI = locator<ManagerAPI>(); late final ManagerAPI _managerAPI = locator<ManagerAPI>();
late final DownloadManager _downloadManager = locator<DownloadManager>(); late final DownloadManager _downloadManager = locator<DownloadManager>();
final Map<String, Lock> _lockMap = {};
Future<void> initialize(String repoUrl) async { Future<void> initialize(String repoUrl) async {
_dio = _downloadManager.initDio(repoUrl); _dio = _downloadManager.initDio(repoUrl);
@@ -21,11 +23,21 @@ class GithubAPI {
await _downloadManager.clearAllCache(); await _downloadManager.clearAllCache();
} }
Future<Response> _dioGetSynchronously(String path) async {
// Create a new Lock for each path
if (!_lockMap.containsKey(path)) {
_lockMap[path] = Lock();
}
return _lockMap[path]!.synchronized(() async {
return await _dio.get(path);
});
}
Future<Map<String, dynamic>?> getLatestRelease( Future<Map<String, dynamic>?> getLatestRelease(
String repoName, String repoName,
) async { ) async {
try { try {
final response = await _dio.get( final response = await _dioGetSynchronously(
'/repos/$repoName/releases/latest', '/repos/$repoName/releases/latest',
); );
return response.data; return response.data;
@@ -37,36 +49,27 @@ class GithubAPI {
} }
} }
Future<Map<String, dynamic>?> getLatestManagerRelease( Future<String?> getManagerChangelogs() async {
String repoName,
) async {
try { try {
final response = await _dio.get( final response = await _dioGetSynchronously(
'/repos/$repoName/releases', '/repos/${_managerAPI.defaultManagerRepo}/releases?per_page=50',
); );
final Map<String, dynamic> releases = response.data[0]; final buffer = StringBuffer();
int updates = 0;
final String currentVersion = final String currentVersion =
await _managerAPI.getCurrentManagerVersion(); await _managerAPI.getCurrentManagerVersion();
while (response.data[updates]['tag_name'] != currentVersion) { for (final release in response.data) {
updates++; if (release['tag_name'] == currentVersion) {
} if (buffer.isEmpty) {
for (int i = 1; i < updates; i++) { buffer.writeln(release['body']);
if (response.data[i]['prerelease']) { }
break;
}
if (release['prerelease']) {
continue; continue;
} }
releases.update( buffer.writeln(release['body']);
'body',
(value) =>
value +
'\n' +
'# ' +
response.data[i]['tag_name'] +
'\n' +
response.data[i]['body'],
);
} }
return releases; return buffer.toString();
} on Exception catch (e) { } on Exception catch (e) {
if (kDebugMode) { if (kDebugMode) {
print(e); print(e);
@@ -87,7 +90,7 @@ class GithubAPI {
url, url,
); );
} }
final response = await _dio.get( final response = await _dioGetSynchronously(
'/repos/$repoName/releases/tags/$version', '/repos/$repoName/releases/tags/$version',
); );
final Map<String, dynamic>? release = response.data; final Map<String, dynamic>? release = response.data;

View File

@@ -31,7 +31,6 @@ class ManagerAPI {
final String cliRepo = 'revanced-cli'; final String cliRepo = 'revanced-cli';
late SharedPreferences _prefs; late SharedPreferences _prefs;
List<Patch> patches = []; List<Patch> patches = [];
List<Option> modifiedOptions = [];
List<Option> options = []; List<Option> options = [];
Patch? selectedPatch; Patch? selectedPatch;
BuildContext? ctx; BuildContext? ctx;

View File

@@ -39,7 +39,8 @@ class HomeViewModel extends BaseViewModel {
List<PatchedApplication> patchedInstalledApps = []; List<PatchedApplication> patchedInstalledApps = [];
String _currentManagerVersion = ''; String _currentManagerVersion = '';
String _currentPatchesVersion = ''; String _currentPatchesVersion = '';
String? _latestManagerVersion = ''; String? latestManagerVersion;
String? latestPatchesVersion;
File? downloadedApk; File? downloadedApk;
Future<void> initialize(BuildContext context) async { Future<void> initialize(BuildContext context) async {
@@ -50,7 +51,6 @@ class HomeViewModel extends BaseViewModel {
await forceRefresh(context); await forceRefresh(context);
return; return;
} }
_latestManagerVersion = await _managerAPI.getLatestManagerVersion();
_currentPatchesVersion = await _managerAPI.getCurrentPatchesVersion(); _currentPatchesVersion = await _managerAPI.getCurrentPatchesVersion();
if (_managerAPI.showUpdateDialog() && await hasManagerUpdates()) { if (_managerAPI.showUpdateDialog() && await hasManagerUpdates()) {
showUpdateDialog(context, false); showUpdateDialog(context, false);
@@ -131,21 +131,21 @@ class HomeViewModel extends BaseViewModel {
if (!_managerAPI.releaseBuild) { if (!_managerAPI.releaseBuild) {
return false; return false;
} }
_latestManagerVersion = latestManagerVersion =
await _managerAPI.getLatestManagerVersion() ?? _currentManagerVersion; await _managerAPI.getLatestManagerVersion() ?? _currentManagerVersion;
if (_latestManagerVersion != _currentManagerVersion) { if (latestManagerVersion != _currentManagerVersion) {
return true; return true;
} }
return false; return false;
} }
Future<bool> hasPatchesUpdates() async { Future<bool> hasPatchesUpdates() async {
final String? latestVersion = await _managerAPI.getLatestPatchesVersion(); latestPatchesVersion = await _managerAPI.getLatestPatchesVersion();
if (latestVersion != null) { if (latestPatchesVersion != null) {
try { try {
final int latestVersionInt = final int latestVersionInt =
int.parse(latestVersion.replaceAll(RegExp('[^0-9]'), '')); int.parse(latestPatchesVersion!.replaceAll(RegExp('[^0-9]'), ''));
final int currentVersionInt = final int currentVersionInt =
int.parse(_currentPatchesVersion.replaceAll(RegExp('[^0-9]'), '')); int.parse(_currentPatchesVersion.replaceAll(RegExp('[^0-9]'), ''));
return latestVersionInt > currentVersionInt; return latestVersionInt > currentVersionInt;
@@ -475,12 +475,14 @@ class HomeViewModel extends BaseViewModel {
); );
} }
Future<Map<String, dynamic>?> getLatestManagerRelease() { Future<String?> getManagerChangelogs() {
return _githubAPI.getLatestManagerRelease(_managerAPI.defaultManagerRepo); return _githubAPI.getManagerChangelogs();
} }
Future<Map<String, dynamic>?> getLatestPatchesRelease() { Future<String?> getLatestPatchesChangelog() async {
return _githubAPI.getLatestRelease(_managerAPI.defaultPatchesRepo); final release =
await _githubAPI.getLatestRelease(_managerAPI.defaultPatchesRepo);
return release?['body'];
} }
Future<String?> getLatestPatchesReleaseTime() { Future<String?> getLatestPatchesReleaseTime() {

View File

@@ -37,79 +37,35 @@ class PatchOptionsView extends StatelessWidget {
color: Theme.of(context).textTheme.titleLarge!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
actions: [
IconButton(
onPressed: () {
model.resetOptions();
},
icon: const Icon(
Icons.history,
),
tooltip: t.patchOptionsView.resetOptionsTooltip,
),
],
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Column( child: Column(
children: [ children: [
for (final Option option in model.visibleOptions) for (final Option option in model.modifiedOptions)
if (option.valueType == 'String' || if (option.valueType == 'String' ||
option.valueType == 'Int') option.valueType == 'Int')
IntAndStringPatchOption( IntAndStringPatchOption(
patchOption: option, patchOption: option,
removeOption: (option) { model: model,
model.removeOption(option);
},
onChanged: (value, option) {
model.modifyOptions(value, option);
},
) )
else if (option.valueType == 'Boolean') else if (option.valueType == 'Boolean')
BooleanPatchOption( BooleanPatchOption(
patchOption: option, patchOption: option,
removeOption: (option) { model: model,
model.removeOption(option);
},
onChanged: (value, option) {
model.modifyOptions(value, option);
},
) )
else if (option.valueType == 'StringArray' || else if (option.valueType == 'StringArray' ||
option.valueType == 'IntArray' || option.valueType == 'IntArray' ||
option.valueType == 'LongArray') option.valueType == 'LongArray')
IntStringLongListPatchOption( IntStringLongListPatchOption(
patchOption: option, patchOption: option,
removeOption: (option) { model: model,
model.removeOption(option);
},
onChanged: (value, option) {
model.modifyOptions(value, option);
},
) )
else else
UnsupportedPatchOption( UnsupportedPatchOption(
patchOption: option, patchOption: option,
), ),
if (model.visibleOptions.length !=
model.options.length) ...[
const SizedBox(
height: 8,
),
FilledButton(
onPressed: () {
model.showAddOptionDialog(context);
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.add),
Text(t.patchOptionsView.addOptions),
],
),
),
],
const SizedBox( const SizedBox(
height: 80, height: 80,
), ),

View File

@@ -5,7 +5,6 @@ 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';
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/custom_card.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
class PatchOptionsViewModel extends BaseViewModel { class PatchOptionsViewModel extends BaseViewModel {
@@ -14,7 +13,7 @@ class PatchOptionsViewModel extends BaseViewModel {
locator<PatcherViewModel>().selectedApp!.packageName; locator<PatcherViewModel>().selectedApp!.packageName;
List<Option> options = []; List<Option> options = [];
List<Option> savedOptions = []; List<Option> savedOptions = [];
List<Option> visibleOptions = []; List<Option> modifiedOptions = [];
Future<void> initialize() async { Future<void> initialize() async {
options = getDefaultOptions(); options = getDefaultOptions();
@@ -28,36 +27,18 @@ class PatchOptionsViewModel extends BaseViewModel {
savedOptions.add(savedOption); savedOptions.add(savedOption);
} }
} }
if (savedOptions.isNotEmpty) { modifiedOptions = [
visibleOptions = [ ...savedOptions,
...savedOptions, ...options.where(
...options.where( (option) => !savedOptions.any((sOption) => sOption.key == option.key),
(option) => ),
option.required && ];
!savedOptions.any((sOption) => sOption.key == option.key),
),
];
} else {
visibleOptions = [
...options.where((option) => option.required),
];
}
}
void addOption(Option option) {
visibleOptions.add(option);
notifyListeners();
}
void removeOption(Option option) {
visibleOptions.removeWhere((vOption) => vOption.key == option.key);
notifyListeners();
} }
bool saveOptions(BuildContext context) { bool saveOptions(BuildContext context) {
final List<Option> requiredNullOptions = []; final List<Option> requiredNullOptions = [];
for (final Option option in options) { for (final Option option in options) {
if (!visibleOptions.any((vOption) => vOption.key == option.key)) { if (modifiedOptions.any((mOption) => mOption.key == option.key)) {
_managerAPI.clearPatchOption( _managerAPI.clearPatchOption(
selectedApp, selectedApp,
_managerAPI.selectedPatch!.name, _managerAPI.selectedPatch!.name,
@@ -65,7 +46,7 @@ class PatchOptionsViewModel extends BaseViewModel {
); );
} }
} }
for (final Option option in visibleOptions) { for (final Option option in modifiedOptions) {
if (option.required && option.value == null) { if (option.required && option.value == null) {
requiredNullOptions.add(option); requiredNullOptions.add(option);
} else { } else {
@@ -98,11 +79,8 @@ class PatchOptionsViewModel extends BaseViewModel {
required: option.required, required: option.required,
key: option.key, key: option.key,
); );
visibleOptions[visibleOptions modifiedOptions.removeWhere((mOption) => mOption.key == option.key);
.indexWhere((vOption) => vOption.key == option.key)] = modifiedOption; modifiedOptions.add(modifiedOption);
_managerAPI.modifiedOptions
.removeWhere((mOption) => mOption.key == option.key);
_managerAPI.modifiedOptions.add(modifiedOption);
} }
List<Option> getDefaultOptions() { List<Option> getDefaultOptions() {
@@ -122,93 +100,11 @@ class PatchOptionsViewModel extends BaseViewModel {
return defaultOptions; return defaultOptions;
} }
void resetOptions() { dynamic getDefaultValue(Option patchOption) => _managerAPI.options
_managerAPI.modifiedOptions.clear(); .firstWhere(
visibleOptions = (option) => option.key == patchOption.key,
getDefaultOptions().where((option) => option.required).toList(); )
notifyListeners(); .value;
}
Future<void> showAddOptionDialog(BuildContext context) async {
await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
t.patchOptionsView.addOptions,
),
Text(
'',
style: TextStyle(
fontSize: 16,
color: Theme.of(context).colorScheme.onSecondaryContainer,
),
),
],
),
actions: [
FilledButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(t.cancelButton),
),
],
contentPadding: const EdgeInsets.all(8),
content: Wrap(
spacing: 14,
runSpacing: 14,
children: options
.where(
(option) =>
!visibleOptions.any((vOption) => vOption.key == option.key),
)
.map((e) {
return CustomCard(
padding: const EdgeInsets.all(4),
backgroundColor: Theme.of(context).colorScheme.surface,
onTap: () {
addOption(e);
Navigator.pop(context);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
e.title,
style: TextStyle(
fontSize: 16,
color: Theme.of(context).colorScheme.onSurface,
),
),
const SizedBox(height: 4),
Text(
e.description,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.onSurface,
),
),
],
),
),
],
),
),
);
}).toList(),
),
),
);
}
} }
Future<void> showRequiredOptionNullDialog( Future<void> showRequiredOptionNullDialog(
@@ -248,7 +144,7 @@ Future<void> showRequiredOptionNullDialog(
PatchesSelectorViewModel().showPatchesChangeDialog(context); PatchesSelectorViewModel().showPatchesChangeDialog(context);
} }
}, },
child: Text(t.patchOptionsView.deselectPatch), child: Text(t.patchOptionsView.unselectPatch),
), ),
FilledButton( FilledButton(
onPressed: () { onPressed: () {

View File

@@ -61,7 +61,6 @@ class PatchesSelectorViewModel extends BaseViewModel {
void navigateToPatchOptions(List<Option> setOptions, Patch patch) { void navigateToPatchOptions(List<Option> setOptions, Patch patch) {
_managerAPI.options = setOptions; _managerAPI.options = setOptions;
_managerAPI.selectedPatch = patch; _managerAPI.selectedPatch = patch;
_managerAPI.modifiedOptions.clear();
_navigationService.navigateToPatchOptionsView(); _navigationService.navigateToPatchOptionsView();
} }

View File

@@ -3,6 +3,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:language_code/language_code.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/app/app.router.dart';
import 'package:revanced_manager/gen/strings.g.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';
@@ -10,8 +11,10 @@ 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:stacked_services/stacked_services.dart';
final _settingViewModel = SettingsViewModel(); final _settingViewModel = SettingsViewModel();
final _navigationService = NavigationService();
class SUpdateLanguage extends BaseViewModel { class SUpdateLanguage extends BaseViewModel {
final Toast _toast = locator<Toast>(); final Toast _toast = locator<Toast>();
@@ -108,10 +111,9 @@ class SUpdateLanguage extends BaseViewModel {
child: Text(t.cancelButton), child: Text(t.cancelButton),
), ),
TextButton( TextButton(
onPressed: () { onPressed: () async {
// TODO(nullcube): Translation will not update until we refresh the page.
updateLocale(selectedLanguageCode.value.languageTag); updateLocale(selectedLanguageCode.value.languageTag);
Navigator.of(context).pop(); await _navigationService.navigateToNavigationView();
}, },
child: Text(t.okButton), child: Text(t.okButton),
), ),

View File

@@ -14,6 +14,7 @@ class UpdateConfirmationSheet extends StatelessWidget {
final bool isPatches; final bool isPatches;
final bool changelog; final bool changelog;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final HomeViewModel model = locator<HomeViewModel>(); final HomeViewModel model = locator<HomeViewModel>();
@@ -25,100 +26,99 @@ class UpdateConfirmationSheet extends StatelessWidget {
builder: (_, scrollController) => SingleChildScrollView( builder: (_, scrollController) => SingleChildScrollView(
controller: scrollController, controller: scrollController,
child: SafeArea( child: SafeArea(
child: FutureBuilder<Map<String, dynamic>?>( child: Column(
future: !isPatches crossAxisAlignment: CrossAxisAlignment.start,
? model.getLatestManagerRelease() children: [
: model.getLatestPatchesRelease(), if (!changelog)
builder: (_, snapshot) { Padding(
if (!snapshot.hasData) { padding: const EdgeInsets.only(
return const SizedBox( top: 40.0,
height: 300, left: 24.0,
child: Center( right: 24.0,
child: CircularProgressIndicator(), bottom: 20.0,
), ),
); child: Row(
} children: [
Expanded(
return Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (!changelog) Text(
Padding( isPatches
padding: const EdgeInsets.only( ? t.homeView.updatePatchesSheetTitle
top: 40.0, : t.homeView.updateSheetTitle,
left: 24.0, style: const TextStyle(
right: 24.0, fontSize: 24,
bottom: 20.0, fontWeight: FontWeight.bold,
), ),
child: Row( ),
children: [ const SizedBox(height: 4.0),
Expanded( Row(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Icon(
Icons.new_releases_outlined,
color:
Theme.of(context).colorScheme.secondary,
),
const SizedBox(width: 8.0),
Text( Text(
isPatches isPatches
? t.homeView.updatePatchesSheetTitle ? model.latestPatchesVersion ?? 'Unknown'
: t.homeView.updateSheetTitle, : model.latestManagerVersion ?? 'Unknown',
style: const TextStyle( style: TextStyle(
fontSize: 24, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w500,
color:
Theme.of(context).colorScheme.secondary,
), ),
), ),
const SizedBox(height: 4.0),
Row(
children: [
Icon(
Icons.new_releases_outlined,
color: Theme.of(context)
.colorScheme
.secondary,
),
const SizedBox(width: 8.0),
Text(
snapshot.data!['tag_name'] ?? 'Unknown',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.colorScheme
.secondary,
),
),
],
),
], ],
), ),
), ],
FilledButton( ),
onPressed: () {
Navigator.of(context).pop();
isPatches
? model.updatePatches(context)
: model.updateManager(context);
},
child: Text(t.updateButton),
),
],
), ),
), FilledButton(
Padding( onPressed: () {
padding: const EdgeInsets.only( Navigator.of(context).pop();
top: 12.0, isPatches
left: 24.0, ? model.updatePatches(context)
bottom: 12.0, : model.updateManager(context);
), },
child: Text( child: Text(t.updateButton),
t.homeView.updateChangelogTitle,
style: TextStyle(
fontSize: changelog ? 24 : 20,
fontWeight: FontWeight.w500,
color:
Theme.of(context).colorScheme.onSecondaryContainer,
), ),
), ],
), ),
Container( ),
Padding(
padding: const EdgeInsets.only(
top: 12.0,
left: 24.0,
bottom: 12.0,
),
child: Text(
t.homeView.updateChangelogTitle,
style: TextStyle(
fontSize: changelog ? 24 : 20,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSecondaryContainer,
),
),
),
FutureBuilder<String?>(
future: !isPatches
? model.getManagerChangelogs()
: model.getLatestPatchesChangelog(),
builder: (_, snapshot) {
if (!snapshot.hasData) {
return Padding(
padding: EdgeInsets.only(top: changelog ? 96 : 24),
child: const Center(
child: CircularProgressIndicator(),
),
);
}
return Container(
margin: const EdgeInsets.symmetric(horizontal: 24.0), margin: const EdgeInsets.symmetric(horizontal: 24.0),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).colorScheme.secondaryContainer, color: Theme.of(context).colorScheme.secondaryContainer,
@@ -139,12 +139,12 @@ class UpdateConfirmationSheet extends StatelessWidget {
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(20.0), padding: const EdgeInsets.all(20.0),
data: snapshot.data!['body'] ?? '', data: snapshot.data ?? '',
), ),
), );
], },
); ),
}, ],
), ),
), ),
), ),

View File

@@ -3,19 +3,18 @@ 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:revanced_manager/gen/strings.g.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/widgets/shared/custom_card.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
class BooleanPatchOption extends StatelessWidget { class BooleanPatchOption extends StatelessWidget {
const BooleanPatchOption({ const BooleanPatchOption({
super.key, super.key,
required this.patchOption, required this.patchOption,
required this.removeOption, required this.model,
required this.onChanged,
}); });
final Option patchOption; final Option patchOption;
final void Function(Option option) removeOption; final PatchOptionsViewModel model;
final void Function(dynamic value, Option option) onChanged;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -30,88 +29,94 @@ class BooleanPatchOption extends StatelessWidget {
value: value ?? false, value: value ?? false,
onChanged: (bool value) { onChanged: (bool value) {
patchOptionValue.value = value; patchOptionValue.value = value;
onChanged(value, patchOption); model.modifyOptions(value, patchOption);
}, },
); );
}, },
), ),
), ),
patchOption: patchOption, patchOption: patchOption,
removeOption: (Option option) { patchOptionValue: patchOptionValue,
removeOption(option); model: model,
},
); );
} }
} }
class IntAndStringPatchOption extends StatelessWidget { class IntAndStringPatchOption extends StatefulWidget {
const IntAndStringPatchOption({ const IntAndStringPatchOption({
super.key, super.key,
required this.patchOption, required this.patchOption,
required this.removeOption, required this.model,
required this.onChanged,
}); });
final Option patchOption; final Option patchOption;
final void Function(Option option) removeOption; final PatchOptionsViewModel model;
final void Function(dynamic value, Option option) onChanged;
@override
State<IntAndStringPatchOption> createState() =>
_IntAndStringPatchOptionState();
}
class _IntAndStringPatchOptionState extends State<IntAndStringPatchOption> {
ValueNotifier? patchOptionValue;
String getKey() {
if (patchOptionValue!.value != null && widget.patchOption.values != null) {
final List values = widget.patchOption.values!.entries
.where((e) => e.value == patchOptionValue!.value)
.toList();
if (values.isNotEmpty) {
return values.first.key;
}
}
return '';
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ValueNotifier patchOptionValue = ValueNotifier(patchOption.value); patchOptionValue ??= ValueNotifier(widget.patchOption.value);
String getKey() {
if (patchOption.value != null && patchOption.values != null) {
final List values = patchOption.values!.entries
.where((e) => e.value == patchOption.value)
.toList();
if (values.isNotEmpty) {
return values.first.key;
}
}
return '';
}
return PatchOption( return PatchOption(
widget: Column( widget: ValueListenableBuilder(
crossAxisAlignment: CrossAxisAlignment.start, valueListenable: patchOptionValue!,
children: [ builder: (context, value, child) {
TextFieldForPatchOption( return Column(
value: patchOption.value, crossAxisAlignment: CrossAxisAlignment.start,
values: patchOption.values, children: [
optionType: patchOption.valueType, TextFieldForPatchOption(
selectedKey: getKey(), value: value,
onChanged: (value) { patchOption: widget.patchOption,
patchOptionValue.value = value; selectedKey: getKey(),
onChanged(value, patchOption); onChanged: (value) {
}, patchOptionValue!.value = value;
), widget.model.modifyOptions(value, widget.patchOption);
ValueListenableBuilder( },
valueListenable: patchOptionValue, ),
builder: (context, value, child) { if (value == null)
if (patchOption.required && value == null) { Column(
return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
t.patchOptionsView.requiredOption, widget.patchOption.required
? t.patchOptionsView.requiredOption
: t.patchOptionsView.nullValue,
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.error, color: widget.patchOption.required
? Theme.of(context).colorScheme.error
: Theme.of(context)
.colorScheme
.onSecondaryContainer
.withOpacity(0.6),
), ),
), ),
], ],
); ),
} else { ],
return const SizedBox(); );
} },
},
),
],
), ),
patchOption: patchOption, patchOption: widget.patchOption,
removeOption: (Option option) { patchOptionValue: patchOptionValue!,
removeOption(option); model: widget.model,
},
); );
} }
} }
@@ -120,13 +125,11 @@ class IntStringLongListPatchOption extends StatelessWidget {
const IntStringLongListPatchOption({ const IntStringLongListPatchOption({
super.key, super.key,
required this.patchOption, required this.patchOption,
required this.removeOption, required this.model,
required this.onChanged,
}); });
final Option patchOption; final Option patchOption;
final void Function(Option option) removeOption; final PatchOptionsViewModel model;
final void Function(dynamic value, Option option) onChanged;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -172,8 +175,7 @@ class IntStringLongListPatchOption extends StatelessWidget {
final e = values[index]; final e = values[index];
return TextFieldForPatchOption( return TextFieldForPatchOption(
value: e.toString(), value: e.toString(),
values: patchOption.values, patchOption: patchOption,
optionType: type,
selectedKey: value.length > 1 ? '' : getKey(e), selectedKey: value.length > 1 ? '' : getKey(e),
showDropdown: index == 0, showDropdown: index == 0,
onChanged: (newValue) { onChanged: (newValue) {
@@ -205,13 +207,13 @@ class IntStringLongListPatchOption extends StatelessWidget {
} }
} }
patchOptionValue.value = List.from(values); patchOptionValue.value = List.from(values);
onChanged(values, patchOption); model.modifyOptions(values, patchOption);
}, },
removeValue: () { removeValue: () {
patchOptionValue.value = List.from(patchOptionValue.value) patchOptionValue.value = List.from(patchOptionValue.value)
..removeAt(index); ..removeAt(index);
values.removeAt(index); values.removeAt(index);
onChanged(values, patchOption); model.modifyOptions(values, patchOption);
}, },
); );
}, },
@@ -231,7 +233,7 @@ class IntStringLongListPatchOption extends StatelessWidget {
List.from(patchOptionValue.value)..add(0); List.from(patchOptionValue.value)..add(0);
values.add(0); values.add(0);
} }
onChanged(values, patchOption); model.modifyOptions(values, patchOption);
}, },
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -254,9 +256,8 @@ class IntStringLongListPatchOption extends StatelessWidget {
}, },
), ),
patchOption: patchOption, patchOption: patchOption,
removeOption: (Option option) { patchOptionValue: patchOptionValue,
removeOption(option); model: model,
},
); );
} }
} }
@@ -282,7 +283,8 @@ class UnsupportedPatchOption extends StatelessWidget {
), ),
), ),
patchOption: patchOption, patchOption: patchOption,
removeOption: (_) {}, patchOptionValue: ValueNotifier(null),
model: PatchOptionsViewModel(),
); );
} }
} }
@@ -292,15 +294,18 @@ class PatchOption extends StatelessWidget {
super.key, super.key,
required this.widget, required this.widget,
required this.patchOption, required this.patchOption,
required this.removeOption, required this.patchOptionValue,
required this.model,
}); });
final Widget widget; final Widget widget;
final Option patchOption; final Option patchOption;
final void Function(Option option) removeOption; final ValueNotifier patchOptionValue;
final PatchOptionsViewModel model;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final defaultValue = model.getDefaultValue(patchOption);
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: CustomCard( child: CustomCard(
@@ -337,11 +342,24 @@ class PatchOption extends StatelessWidget {
], ],
), ),
), ),
if (!patchOption.required) ValueListenableBuilder(
IconButton( valueListenable: patchOptionValue,
onPressed: () => removeOption(patchOption), builder: (context, value, child) {
icon: const Icon(Icons.delete), if (defaultValue != patchOptionValue.value) {
), return IconButton(
onPressed: () {
patchOptionValue.value = defaultValue;
model.modifyOptions(
defaultValue,
patchOption,
);
},
icon: const Icon(Icons.history),
);
}
return const SizedBox();
},
),
], ],
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
@@ -360,17 +378,15 @@ class TextFieldForPatchOption extends StatefulWidget {
const TextFieldForPatchOption({ const TextFieldForPatchOption({
super.key, super.key,
required this.value, required this.value,
required this.values, required this.patchOption,
this.removeValue, this.removeValue,
required this.onChanged, required this.onChanged,
required this.optionType,
required this.selectedKey, required this.selectedKey,
this.showDropdown = true, this.showDropdown = true,
}); });
final String? value; final String? value;
final Map<String, dynamic>? values; final Option patchOption;
final String optionType;
final String selectedKey; final String selectedKey;
final bool showDropdown; final bool showDropdown;
final void Function()? removeValue; final void Function()? removeValue;
@@ -388,20 +404,19 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bool isStringOption = widget.optionType.contains('String'); final bool isStringOption = widget.patchOption.valueType.contains('String');
final bool isArrayOption = widget.optionType.contains('Array'); final bool isArrayOption = widget.patchOption.valueType.contains('Array');
selectedKey ??= widget.selectedKey; selectedKey = selectedKey == '' ? selectedKey : widget.selectedKey;
controller.text = !isStringOption && final bool isValueArray = widget.value?.startsWith('[') ?? false;
isArrayOption && final bool shouldResetValue =
selectedKey == '' && !isStringOption && isArrayOption && selectedKey == '' && isValueArray;
(widget.value != null && widget.value.toString().startsWith('[')) controller.text = shouldResetValue ? '' : widget.value ?? '';
? ''
: widget.value ?? '';
defaultValue ??= controller.text; defaultValue ??= controller.text;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (widget.showDropdown && (widget.values?.isNotEmpty ?? false)) if (widget.showDropdown &&
(widget.patchOption.values?.isNotEmpty ?? false))
DropdownButton<String>( DropdownButton<String>(
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
@@ -410,11 +425,12 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
dropdownColor: Theme.of(context).colorScheme.secondaryContainer, dropdownColor: Theme.of(context).colorScheme.secondaryContainer,
isExpanded: true, isExpanded: true,
value: selectedKey, value: selectedKey,
items: widget.values!.entries items: widget.patchOption.values!.entries
.map( .map(
(e) => DropdownMenuItem( (e) => DropdownMenuItem(
value: e.key, value: e.key,
child: RichText( child: RichText(
overflow: TextOverflow.ellipsis,
text: TextSpan( text: TextSpan(
text: e.key, text: e.key,
style: TextStyle( style: TextStyle(
@@ -427,7 +443,7 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
TextSpan( TextSpan(
text: ' ${e.value}', text: ' ${e.value}',
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 16,
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
.onSecondaryContainer .onSecondaryContainer
@@ -447,9 +463,7 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
t.patchOptionsView.customValue, t.patchOptionsView.customValue,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: Theme.of(context) color: Theme.of(context).colorScheme.onSecondaryContainer,
.colorScheme
.onSecondaryContainer,
), ),
), ),
), ),
@@ -459,9 +473,11 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
controller.text = defaultValue!; controller.text = defaultValue!;
widget.onChanged(controller.text); widget.onChanged(controller.text);
} else { } else {
controller.text = widget.values![value].toString(); controller.text = widget.patchOption.values![value].toString();
widget.onChanged( widget.onChanged(
isArrayOption ? widget.values![value] : controller.text, isArrayOption
? widget.patchOption.values![value]
: controller.text,
); );
} }
setState(() { setState(() {
@@ -472,9 +488,9 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
if (selectedKey == '') if (selectedKey == '')
TextFormField( TextFormField(
inputFormatters: [ inputFormatters: [
if (widget.optionType.contains('Int')) if (widget.patchOption.valueType.contains('Int'))
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
if (widget.optionType.contains('Long')) if (widget.patchOption.valueType.contains('Long'))
FilteringTextInputFormatter.allow(RegExp(r'^[0-9]*\.?[0-9]*')), FilteringTextInputFormatter.allow(RegExp(r'^[0-9]*\.?[0-9]*')),
], ],
controller: controller, controller: controller,
@@ -487,31 +503,36 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
return [ return [
if (isArrayOption) if (isArrayOption)
PopupMenuItem( PopupMenuItem(
value: t.remove, value: 'remove',
child: Text(t.remove), child: Text(t.remove),
), ),
if (isStringOption) ...[ if (isStringOption) ...[
PopupMenuItem( PopupMenuItem(
value: t.patchOptionsView.selectFilePath, value: 'file',
child: Text(t.patchOptionsView.selectFilePath), child: Text(t.patchOptionsView.selectFilePath),
), ),
PopupMenuItem( PopupMenuItem(
value: t.patchOptionsView.selectFolder, value: 'folder',
child: Text(t.patchOptionsView.selectFolder), child: Text(t.patchOptionsView.selectFolder),
), ),
], ],
if (!widget.patchOption.required)
PopupMenuItem(
value: 'null',
child: Text(t.patchOptionsView.setToNull),
),
]; ];
}, },
onSelected: (String selection) async { onSelected: (String selection) async {
switch (selection) { switch (selection) {
case 'patchOptionsView.selectFilePath': case 'file':
final String? result = await FlutterFileDialog.pickFile(); final String? result = await FlutterFileDialog.pickFile();
if (result != null) { if (result != null) {
controller.text = result; controller.text = result;
widget.onChanged(controller.text); widget.onChanged(controller.text);
} }
break; break;
case 'patchOptionsView.selectFolder': case 'folder':
final DirectoryLocation? result = final DirectoryLocation? result =
await FlutterFileDialog.pickDirectory(); await FlutterFileDialog.pickDirectory();
if (result != null) { if (result != null) {
@@ -522,6 +543,10 @@ class _TextFieldForPatchOptionState extends State<TextFieldForPatchOption> {
case 'remove': case 'remove':
widget.removeValue!(); widget.removeValue!();
break; break;
case 'null':
controller.text = '';
widget.onChanged(null);
break;
} }
}, },
), ),

763
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,6 @@
"@semantic-release/changelog": "^6.0.3", "@semantic-release/changelog": "^6.0.3",
"@semantic-release/exec": "^6.0.3", "@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"semantic-release": "^23.0.7" "semantic-release": "^23.0.8"
} }
} }

View File

@@ -323,9 +323,9 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: "560d21c4148b53933313573e7eafca0b0eb9aadf" ref: "900a81501f1f0e4996fe9e2cbf55f1ea8df08b49"
resolved-ref: "560d21c4148b53933313573e7eafca0b0eb9aadf" resolved-ref: "900a81501f1f0e4996fe9e2cbf55f1ea8df08b49"
url: "https://github.com/BenjaminHalko/flutter_background" url: "https://github.com/validcube/flutter_background"
source: git source: git
version: "1.2.0" version: "1.2.0"
flutter_cache_manager: flutter_cache_manager:
@@ -499,10 +499,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: injectable name: injectable
sha256: fb722c86cf8233008e4db41c696a6145721f45dc8aeba91103e3128c3d63c9c6 sha256: "3c8355a29d11ff28c0311bed754649761f345ef7a13ff66a714380954af51226"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.4.2"
injectable_generator: injectable_generator:
dependency: "direct dev" dependency: "direct dev"
description: description:
@@ -571,18 +571,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.4" version: "10.0.5"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.5"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
@@ -644,18 +644,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.0" version: "0.11.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.14.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@@ -732,10 +732,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.4.0"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@@ -989,10 +989,11 @@ packages:
skeletons: skeletons:
dependency: "direct main" dependency: "direct main"
description: description:
name: skeletons path: "."
sha256: "5b2d08ae7f908ee1f7007ca99f8dcebb4bfc1d3cb2143dec8d112a5be5a45c8f" ref: "326fbb4223ac4d8a6301cc2f16b6112ecd308c71"
url: "https://pub.dev" resolved-ref: "326fbb4223ac4d8a6301cc2f16b6112ecd308c71"
source: hosted url: "https://github.com/Ofceab-Studio/skeletons"
source: git
version: "0.0.3" version: "0.0.3"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
@@ -1147,10 +1148,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" sha256: "2419f20b0c8677b2d67c8ac4d1ac7372d862dc6c460cdbb052b40155408cd794"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.1"
timeago: timeago:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -1211,10 +1212,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5" sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.5" version: "6.3.0"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
@@ -1227,10 +1228,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_macos name: url_launcher_macos
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.0" version: "3.2.0"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -1275,10 +1276,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" sha256: "7475cb4dd713d57b6f7464c0e13f06da0d535d8b2067e188962a59bac2cf280b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.1" version: "14.2.2"
wakelock_plus: wakelock_plus:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -4,7 +4,7 @@ homepage: https://github.com/ReVanced/revanced-manager
publish_to: 'none' publish_to: 'none'
version: 1.21.0-dev.3+101800019 version: 1.21.0-dev.4+101800020
environment: environment:
sdk: '>=3.0.0 <4.0.0' sdk: '>=3.0.0 <4.0.0'
@@ -26,9 +26,9 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_background: flutter_background:
git: # remove once https://github.com/JulianAssmann/flutter_background/pull/79 is merged git: # remove once https://github.com/JulianAssmann/flutter_background/pull/83 is merged
url: https://github.com/BenjaminHalko/flutter_background url: https://github.com/validcube/flutter_background
ref: 560d21c4148b53933313573e7eafca0b0eb9aadf # Branch: specify-namespace ref: 900a81501f1f0e4996fe9e2cbf55f1ea8df08b49 # Branch: specify-namespace
flutter_cache_manager: ^3.3.2 flutter_cache_manager: ^3.3.2
flutter_file_dialog: ^3.0.2 flutter_file_dialog: ^3.0.2
flutter_local_notifications: ^17.1.0 flutter_local_notifications: ^17.1.0
@@ -39,7 +39,7 @@ dependencies:
font_awesome_flutter: ^10.7.0 font_awesome_flutter: ^10.7.0
google_fonts: ^6.2.1 google_fonts: ^6.2.1
injectable: ^2.4.0 injectable: ^2.4.0
intl: ^0.18.1 intl: 0.19.0
json_annotation: ^4.9.0 json_annotation: ^4.9.0
language_code: ^0.5.3+2 language_code: ^0.5.3+2
logcat: logcat:
@@ -59,7 +59,10 @@ dependencies:
ref: 1a1616ac91e16cd1f3dd170a81febf27ffce3587 # Branch: master ref: 1a1616ac91e16cd1f3dd170a81febf27ffce3587 # Branch: master
share_plus: ^9.0.0 share_plus: ^9.0.0
shared_preferences: ^2.2.3 shared_preferences: ^2.2.3
skeletons: ^0.0.3 skeletons:
git: # remove once https://github.com/badjio/skeletons/pull/11 is merged
url: https://github.com/Ofceab-Studio/skeletons
ref: 326fbb4223ac4d8a6301cc2f16b6112ecd308c71 # Branch: master
slang: ^3.30.2 slang: ^3.30.2
slang_flutter: ^3.30.0 slang_flutter: ^3.30.0
stacked: ^3.4.2 stacked: ^3.4.2