mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2025-05-19 23:46:55 +08:00
Compare commits
76 Commits
Author | SHA1 | Date | |
---|---|---|---|
08f6724060 | |||
29daf51e64 | |||
b3b2b01c0f | |||
c3212d0308 | |||
aaa114ba13 | |||
8ca6418630 | |||
95632b7f55 | |||
64744b2abf | |||
096b315701 | |||
c27ca08d3a | |||
0011222371 | |||
29db947e25 | |||
fd43ac7581 | |||
e49c19b3cd | |||
06f0e59967 | |||
c5fc5ee93b | |||
159c85bd1f | |||
2460acf0f4 | |||
6495687841 | |||
d229ccb36c | |||
4d6a57ddcf | |||
d161d55aaf | |||
768ad0c9bc | |||
29323d4e20 | |||
630b22e193 | |||
79116f9e67 | |||
eb58475259 | |||
a879ac30fb | |||
c5b0621323 | |||
0462815014 | |||
e64318c947 | |||
b784482788 | |||
2834e8b348 | |||
b23dfd4289 | |||
217d525cb2 | |||
85b166cbda | |||
9a57f8b858 | |||
3bfdc932c2 | |||
48c878af21 | |||
490a7a58fc | |||
567b1a3ace | |||
6a45db8a38 | |||
b272988929 | |||
9828857570 | |||
ecb54d8e44 | |||
344717b021 | |||
da6cf585c0 | |||
9e93177afd | |||
16318efb01 | |||
e83e13b6d4 | |||
7c2c695d88 | |||
c7b227529d | |||
14f49e9d30 | |||
1875c4ee73 | |||
76c68baa1f | |||
68876a4414 | |||
26d7e5b60f | |||
e78af6ae99 | |||
6fe05cd86e | |||
4100d7a391 | |||
c1cc812ea4 | |||
9663e3f0f4 | |||
941f618153 | |||
716a30bf7b | |||
d051ae576b | |||
35e99cb014 | |||
af054fba49 | |||
58d837d641 | |||
6cc1bd21cd | |||
cebfa7c8ae | |||
e2d7ab8f8f | |||
ec77987fcd | |||
b161608d02 | |||
5e7458ff1c | |||
ed06aaa1f5 | |||
13b7179941 |
20
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
20
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
@ -29,7 +29,7 @@ body:
|
|||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Steps to reproduce
|
label: Steps to reproduce
|
||||||
description: Add the steps to reproduce this bug including your environment.
|
description: Add the steps to reproduce this bug, including your environment.
|
||||||
placeholder: Step 1. Download some files. Step 2. ...
|
placeholder: Step 1. Download some files. Step 2. ...
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
@ -74,20 +74,20 @@ body:
|
|||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Device logs (exported using Manager settings).
|
label: Device logs (exported using Manager settings).
|
||||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so there is no need for backticks.
|
||||||
render: shell
|
render: shell
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Installer logs (exported using Installer menu option) [unneeded if issue is not during patching].
|
label: Installer logs (exported using Installer menu option) [unneeded if the issue is not during patching].
|
||||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so there is no need for backticks.
|
||||||
render: shell
|
render: shell
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Screenshots or videos
|
label: Screenshots or video
|
||||||
description: Add screenshots or videos that show the bug here.
|
description: Add screenshots or videos that show the bug here.
|
||||||
placeholder: Drag and drop the screenshots/videos into this box.
|
placeholder: Drag and drop the screenshots/videos into this box.
|
||||||
validations:
|
validations:
|
||||||
@ -105,16 +105,16 @@ body:
|
|||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: acknowledgements
|
id: acknowledgments
|
||||||
attributes:
|
attributes:
|
||||||
label: Acknowledgements
|
label: Acknowledgments
|
||||||
description: Your issue will be closed if you haven't done these steps.
|
description: Your issue will be closed if you haven't done these steps.
|
||||||
options:
|
options:
|
||||||
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
|
- label: I have searched the existing issues; this is new and no duplicate or related to another open issue.
|
||||||
required: true
|
required: true
|
||||||
- label: I have written a short but informative title.
|
- label: I have written a short but informative title.
|
||||||
required: true
|
required: true
|
||||||
- label: I filled out all of the requested information in this issue properly.
|
- label: I properly filled out all of the requested information in this issue.
|
||||||
required: true
|
required: true
|
||||||
- label: The issue is related solely to the ReVanced Manager and not related to patching errors or patches
|
- label: The issue is solely related to ReVanced Manager and not caused by patches.
|
||||||
required: true
|
required: true
|
||||||
|
11
.github/workflows/analyze.yml
vendored
11
.github/workflows/analyze.yml
vendored
@ -1,14 +1,25 @@
|
|||||||
name: Analyze Code
|
name: Analyze Code
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "dev" ]
|
||||||
|
paths:
|
||||||
|
- "**.dart"
|
||||||
|
- ".github/workflows/analyze.yml"
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main", "dev" ]
|
branches: [ "main", "dev" ]
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- reopened
|
||||||
|
- synchronize
|
||||||
|
- ready_for_review
|
||||||
paths:
|
paths:
|
||||||
- "**.dart"
|
- "**.dart"
|
||||||
- ".github/workflows/analyze.yml"
|
- ".github/workflows/analyze.yml"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: "Static analysis & format check"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: PR Build
|
name: PR Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@ -18,7 +18,7 @@ jobs:
|
|||||||
- name: Setup JDK
|
- name: Setup JDK
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '11'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: 'gradle'
|
cache: 'gradle'
|
||||||
- name: Setup Flutter
|
- name: Setup Flutter
|
4
.github/workflows/release-build.yml
vendored
4
.github/workflows/release-build.yml
vendored
@ -12,10 +12,10 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Set env
|
- name: Set env
|
||||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||||
- name: Set up JDK 12
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: "12"
|
java-version: "11"
|
||||||
distribution: "zulu"
|
distribution: "zulu"
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
|||||||
- name: Setup JDK
|
- name: Setup JDK
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '11'
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
cache: 'gradle'
|
cache: 'gradle'
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
|
@ -24,7 +24,7 @@ If you wish to translate ReVanced Manager, we're accepting translations on [Crow
|
|||||||
## 🛠️ Building Manager from source
|
## 🛠️ Building Manager from source
|
||||||
1. Setup flutter environment for your [platform](https://docs.flutter.dev/get-started/install)
|
1. Setup flutter environment for your [platform](https://docs.flutter.dev/get-started/install)
|
||||||
2. Clone the repository locally
|
2. Clone the repository locally
|
||||||
3. Add your github token in gradle.properties like [this](https://github.com/revanced/revanced-manager/blob/docs/docs/5_building-from-source.md)
|
3. Add your github token in gradle.properties like [this](/docs/4_building.md)
|
||||||
4. Open the project in terminal
|
4. Open the project in terminal
|
||||||
5. Run `flutter pub get` in terminal
|
5. Run `flutter pub get` in terminal
|
||||||
6. Then `flutter packages pub run build_runner build --delete-conflicting-outputs` (Must be done on each git pull)
|
6. Then `flutter packages pub run build_runner build --delete-conflicting-outputs` (Must be done on each git pull)
|
||||||
|
@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
|
|||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
compileSdkVersion flutter.compileSdkVersion
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@ -71,7 +71,7 @@ dependencies {
|
|||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
|
||||||
// ReVanced
|
// ReVanced
|
||||||
implementation "app.revanced:revanced-patcher:11.0.1"
|
implementation "app.revanced:revanced-patcher:12.0.0"
|
||||||
|
|
||||||
// Signing & aligning
|
// Signing & aligning
|
||||||
implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
|
implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
|
||||||
|
@ -2,23 +2,29 @@
|
|||||||
package="app.revanced.manager.flutter">
|
package="app.revanced.manager.flutter">
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="32" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
||||||
<application
|
<application
|
||||||
android:label="ReVanced Manager"
|
android:label="ReVanced Manager"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
|
android:requestLegacyExternalStorage="true"
|
||||||
android:extractNativeLibs="true"
|
android:extractNativeLibs="true"
|
||||||
android:enableOnBackInvokedCallback="true">
|
android:enableOnBackInvokedCallback="true">
|
||||||
<activity
|
<activity
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx1536M -XX:+UseParallelGC
|
||||||
|
org.gradle.parallel=true
|
||||||
|
org.gradle.daemon=true
|
||||||
|
org.gradle.caching=true
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
@ -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-7.6.1-bin.zip
|
distributionSha256Sum=a01b6587e15fe7ed120a0ee299c25982a1eee045abd6a9dd5e216b2f628ef9ac
|
||||||
distributionSha256Sum=6147605a23b4eff6c334927a86ff3508cb5d6722cd624c97ded4c2e8640f1f87
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "لم يتم اختيار أي تطبيق",
|
"widgetSubtitle": "لم يتم اختيار أي تطبيق",
|
||||||
"noAppsLabel": "لم يتم العثور على تطبيقات",
|
"noAppsLabel": "لم يتم العثور على تطبيقات",
|
||||||
"currentVersion": "الحالي",
|
"currentVersion": "الحالي",
|
||||||
"recommendedVersion": "موصى به",
|
"recommendedVersion": "موصى به"
|
||||||
"anyVersion": "أي"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "اختر التعديلات",
|
"widgetTitle": "اختر التعديلات",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "تسجيل الحراسة",
|
"sentryLabel": "تسجيل الحراسة",
|
||||||
"sentryHint": "إرسال سجلات مجهولة لمساعدتنا في تحسين ReVanced Manager",
|
"sentryHint": "إرسال سجلات مجهولة لمساعدتنا في تحسين ReVanced Manager",
|
||||||
"restartAppForChanges": "إعادة تشغيل التطبيق لتطبيق التغييرات",
|
"restartAppForChanges": "إعادة تشغيل التطبيق لتطبيق التغييرات",
|
||||||
"deleteKeystoreLabel": "حذف ملف تخزين المفاتيح",
|
"regenerateKeystoreLabel": "حذف ملف تخزين المفاتيح",
|
||||||
"deleteKeystoreHint": "حذف ملف تخزين المفاتيح المستخدم للتوقيع على التطبيق",
|
"regenerateKeystoreHint": "حذف ملف تخزين المفاتيح المستخدم للتوقيع على التطبيق",
|
||||||
"deletedKeystore": "تم حذف مِلَفّ تخزين المفاتيح",
|
"regeneratedKeystore": "تم حذف مِلَفّ تخزين المفاتيح",
|
||||||
"deleteTempDirLabel": "حذف الملفات المؤقتة",
|
"deleteTempDirLabel": "حذف الملفات المؤقتة",
|
||||||
"deleteTempDirHint": "حذف الملفات المؤقتة غير المستخدمة",
|
"deleteTempDirHint": "حذف الملفات المؤقتة غير المستخدمة",
|
||||||
"deletedTempDir": "تم حذف الملفات المؤقتة",
|
"deletedTempDir": "تم حذف الملفات المؤقتة",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Heç bir tətbiq seçilməyib",
|
"widgetSubtitle": "Heç bir tətbiq seçilməyib",
|
||||||
"noAppsLabel": "Heç bir tətbiq tapılmadı",
|
"noAppsLabel": "Heç bir tətbiq tapılmadı",
|
||||||
"currentVersion": "Hazırkı",
|
"currentVersion": "Hazırkı",
|
||||||
"recommendedVersion": "Tövsiyyə edilən",
|
"recommendedVersion": "Tövsiyyə edilən"
|
||||||
"anyVersion": "istənilən"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Yamaqları seçin",
|
"widgetTitle": "Yamaqları seçin",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Keşikçi jurnalı",
|
"sentryLabel": "Keşikçi jurnalı",
|
||||||
"sentryHint": "ReVanced Manager-i inkişaf etdirməyimizə kömək etməsi üçün anonim jurnallar göndərin",
|
"sentryHint": "ReVanced Manager-i inkişaf etdirməyimizə kömək etməsi üçün anonim jurnallar göndərin",
|
||||||
"restartAppForChanges": "Dəyişiklikləri tətbiq etmək üçün tətbiqi yenidən başlat",
|
"restartAppForChanges": "Dəyişiklikləri tətbiq etmək üçün tətbiqi yenidən başlat",
|
||||||
"deleteKeystoreLabel": "Keystore-u sil",
|
"regenerateKeystoreLabel": "Keystore-u sil",
|
||||||
"deleteKeystoreHint": "Tətbiqi imzalamaq üçün istifadə edilən keystoru-u sil",
|
"regenerateKeystoreHint": "Tətbiqi imzalamaq üçün istifadə edilən keystoru-u sil",
|
||||||
"deletedKeystore": "Keystore silindi",
|
"regeneratedKeystore": "Keystore silindi",
|
||||||
"deleteTempDirLabel": "Müvəqqəti faylları sil",
|
"deleteTempDirLabel": "Müvəqqəti faylları sil",
|
||||||
"deleteTempDirHint": "İstifadə edilməyən müvəqqəti faylları sil",
|
"deleteTempDirHint": "İstifadə edilməyən müvəqqəti faylları sil",
|
||||||
"deletedTempDir": "Müvəqqəti fayllar silindi",
|
"deletedTempDir": "Müvəqqəti fayllar silindi",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Няма избрано приложение",
|
"widgetSubtitle": "Няма избрано приложение",
|
||||||
"noAppsLabel": "Няма намерени приложения",
|
"noAppsLabel": "Няма намерени приложения",
|
||||||
"currentVersion": "Текуща",
|
"currentVersion": "Текуща",
|
||||||
"recommendedVersion": "Препоръчана",
|
"recommendedVersion": "Препоръчана"
|
||||||
"anyVersion": "всяка"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Изберете модификации",
|
"widgetTitle": "Изберете модификации",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Sentry логване",
|
"sentryLabel": "Sentry логване",
|
||||||
"sentryHint": "Пращайте анонимни логове за да ни помогнете да подобрим ReVanced Manager",
|
"sentryHint": "Пращайте анонимни логове за да ни помогнете да подобрим ReVanced Manager",
|
||||||
"restartAppForChanges": "Рестартирайте приложението, за да се приложат промените",
|
"restartAppForChanges": "Рестартирайте приложението, за да се приложат промените",
|
||||||
"deleteKeystoreLabel": "Изтриване на keystore",
|
"regenerateKeystoreLabel": "Изтриване на keystore",
|
||||||
"deleteKeystoreHint": "Изтриване на keystore използван за подписване на приложението",
|
"regenerateKeystoreHint": "Изтриване на keystore използван за подписване на приложението",
|
||||||
"deletedKeystore": "Keystore изтрит",
|
"regeneratedKeystore": "Keystore изтрит",
|
||||||
"deleteTempDirLabel": "Изтриване на временни файлове",
|
"deleteTempDirLabel": "Изтриване на временни файлове",
|
||||||
"deleteTempDirHint": "Изтриване на неизползвани временни файлове",
|
"deleteTempDirHint": "Изтриване на неизползвани временни файлове",
|
||||||
"deletedTempDir": "Временните файлове са изтрити",
|
"deletedTempDir": "Временните файлове са изтрити",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "কোনো অ্যাপ্লিকেশন নির্বাচন করা হয়নি",
|
"widgetSubtitle": "কোনো অ্যাপ্লিকেশন নির্বাচন করা হয়নি",
|
||||||
"noAppsLabel": "কোন অ্যাপ্লিকেশন পাওয়া যায়নি",
|
"noAppsLabel": "কোন অ্যাপ্লিকেশন পাওয়া যায়নি",
|
||||||
"currentVersion": "বর্তমান",
|
"currentVersion": "বর্তমান",
|
||||||
"recommendedVersion": "প্রস্তাবিত",
|
"recommendedVersion": "প্রস্তাবিত"
|
||||||
"anyVersion": "যেকোনো সংস্করণ"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "প্যাচ নির্বাচন করুন",
|
"widgetTitle": "প্যাচ নির্বাচন করুন",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "সেন্ট্রি লগিং",
|
"sentryLabel": "সেন্ট্রি লগিং",
|
||||||
"sentryHint": "ReVanced Manager উন্নত করতে আমাদের সাহায্য করতে বেনামী লগ পাঠান",
|
"sentryHint": "ReVanced Manager উন্নত করতে আমাদের সাহায্য করতে বেনামী লগ পাঠান",
|
||||||
"restartAppForChanges": "পরিবর্তনগুলি প্রয়োগ করতে অ্যাপটি পুনরায় চালু করুন",
|
"restartAppForChanges": "পরিবর্তনগুলি প্রয়োগ করতে অ্যাপটি পুনরায় চালু করুন",
|
||||||
"deleteKeystoreLabel": "কীস্টোর মুছুন",
|
"regenerateKeystoreLabel": "কীস্টোর মুছুন",
|
||||||
"deleteKeystoreHint": "প্যাচড অ্যাপ সাইন করতে ব্যবহৃত কীস্টোরটি মুছুন",
|
"regenerateKeystoreHint": "প্যাচড অ্যাপ সাইন করতে ব্যবহৃত কীস্টোরটি মুছুন",
|
||||||
"deletedKeystore": "কীস্টোর মুছে ফেলা হয়েছে",
|
"regeneratedKeystore": "কীস্টোর মুছে ফেলা হয়েছে",
|
||||||
"deleteTempDirLabel": "অস্থায়ী ফাইল মুছুন",
|
"deleteTempDirLabel": "অস্থায়ী ফাইল মুছুন",
|
||||||
"deleteTempDirHint": "অব্যবহৃত অস্থায়ী ফাইল মুছুন",
|
"deleteTempDirHint": "অব্যবহৃত অস্থায়ী ফাইল মুছুন",
|
||||||
"deletedTempDir": "অস্থায়ী ফাইল মুছে ফেলা হয়েছে",
|
"deletedTempDir": "অস্থায়ী ফাইল মুছে ফেলা হয়েছে",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Nebyla vybrána žádná aplikace",
|
"widgetSubtitle": "Nebyla vybrána žádná aplikace",
|
||||||
"noAppsLabel": "Nebyly nalezeny žádné aplikace",
|
"noAppsLabel": "Nebyly nalezeny žádné aplikace",
|
||||||
"currentVersion": "Aktuální",
|
"currentVersion": "Aktuální",
|
||||||
"recommendedVersion": "Doporučeno",
|
"recommendedVersion": "Doporučeno"
|
||||||
"anyVersion": "jakákoliv"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Vybrat záplaty",
|
"widgetTitle": "Vybrat záplaty",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Log Sentry",
|
"sentryLabel": "Log Sentry",
|
||||||
"sentryHint": "Odeslat anonymní protokoly, které nám pomohou zlepšit ReVanced Manager",
|
"sentryHint": "Odeslat anonymní protokoly, které nám pomohou zlepšit ReVanced Manager",
|
||||||
"restartAppForChanges": "Pro aplikování změn restartuj aplikaci",
|
"restartAppForChanges": "Pro aplikování změn restartuj aplikaci",
|
||||||
"deleteKeystoreLabel": "Vymazat úložiště klíčů",
|
"regenerateKeystoreLabel": "Vymazat úložiště klíčů",
|
||||||
"deleteKeystoreHint": "Smazat úložiště klíčů používané k podpisu aplikace",
|
"regenerateKeystoreHint": "Smazat úložiště klíčů používané k podpisu aplikace",
|
||||||
"deletedKeystore": "Úložiště klíčů bylo smazáno",
|
"regeneratedKeystore": "Úložiště klíčů bylo smazáno",
|
||||||
"deleteTempDirLabel": "Odstranit dočasné soubory",
|
"deleteTempDirLabel": "Odstranit dočasné soubory",
|
||||||
"deleteTempDirHint": "Odstranit nepoužité dočasné soubory",
|
"deleteTempDirHint": "Odstranit nepoužité dočasné soubory",
|
||||||
"deletedTempDir": "Dočasné soubory byly smazány",
|
"deletedTempDir": "Dočasné soubory byly smazány",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Ingen applikation valgt",
|
"widgetSubtitle": "Ingen applikation valgt",
|
||||||
"noAppsLabel": "Ingen applikationer fundet",
|
"noAppsLabel": "Ingen applikationer fundet",
|
||||||
"currentVersion": "Nuværende",
|
"currentVersion": "Nuværende",
|
||||||
"recommendedVersion": "Anbefalet",
|
"recommendedVersion": "Anbefalet"
|
||||||
"anyVersion": "enhver"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Vælg patches",
|
"widgetTitle": "Vælg patches",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Sentry logning",
|
"sentryLabel": "Sentry logning",
|
||||||
"sentryHint": "Send anonyme logfiler for at hjælpe os med at forbedre ReVanced Manager",
|
"sentryHint": "Send anonyme logfiler for at hjælpe os med at forbedre ReVanced Manager",
|
||||||
"restartAppForChanges": "Genstart appen for at anvende ændringer",
|
"restartAppForChanges": "Genstart appen for at anvende ændringer",
|
||||||
"deleteKeystoreLabel": "Slet keystore",
|
"regenerateKeystoreLabel": "Slet keystore",
|
||||||
"deleteKeystoreHint": "Slet keystore der bruges til at signere appen",
|
"regenerateKeystoreHint": "Slet keystore der bruges til at signere appen",
|
||||||
"deletedKeystore": "Keystore slettet",
|
"regeneratedKeystore": "Keystore slettet",
|
||||||
"deleteTempDirLabel": "Slet midlertidige filer",
|
"deleteTempDirLabel": "Slet midlertidige filer",
|
||||||
"deleteTempDirHint": "Slet ubrugte midlertidige filer",
|
"deleteTempDirHint": "Slet ubrugte midlertidige filer",
|
||||||
"deletedTempDir": "Midlertidige filer slettet",
|
"deletedTempDir": "Midlertidige filer slettet",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Keine App ausgewählt",
|
"widgetSubtitle": "Keine App ausgewählt",
|
||||||
"noAppsLabel": "Keine Apps gefunden",
|
"noAppsLabel": "Keine Apps gefunden",
|
||||||
"currentVersion": "Aktuell",
|
"currentVersion": "Aktuell",
|
||||||
"recommendedVersion": "Empfohlen",
|
"recommendedVersion": "Empfohlen"
|
||||||
"anyVersion": "beliebig"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Patches auswählen",
|
"widgetTitle": "Patches auswählen",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Sentry-Protokollierung",
|
"sentryLabel": "Sentry-Protokollierung",
|
||||||
"sentryHint": "Sende anonyme Protokolle, um den ReVanced Manager zu verbessern",
|
"sentryHint": "Sende anonyme Protokolle, um den ReVanced Manager zu verbessern",
|
||||||
"restartAppForChanges": "Starte die App neu um die Änderungen zu übernehmen",
|
"restartAppForChanges": "Starte die App neu um die Änderungen zu übernehmen",
|
||||||
"deleteKeystoreLabel": "Den Schlüsselspeicher löschen",
|
"regenerateKeystoreLabel": "Den Schlüsselspeicher löschen",
|
||||||
"deleteKeystoreHint": "Löschen des Schlüsselspeichers, der zum Signieren der Anwendung verwendet wurde",
|
"regenerateKeystoreHint": "Löschen des Schlüsselspeichers, der zum Signieren der Anwendung verwendet wurde",
|
||||||
"deletedKeystore": "Schlüsselspeicher gelöscht",
|
"regeneratedKeystore": "Schlüsselspeicher gelöscht",
|
||||||
"deleteTempDirLabel": "Lösche temporäre Dateien",
|
"deleteTempDirLabel": "Lösche temporäre Dateien",
|
||||||
"deleteTempDirHint": "Unbenutzte temporäre Dateien löschen",
|
"deleteTempDirHint": "Unbenutzte temporäre Dateien löschen",
|
||||||
"deletedTempDir": "Temporäre Dateien gelöscht",
|
"deletedTempDir": "Temporäre Dateien gelöscht",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Δεν έχει επιλεχθεί εφαρμογή",
|
"widgetSubtitle": "Δεν έχει επιλεχθεί εφαρμογή",
|
||||||
"noAppsLabel": "Δεν βρέθηκαν εφαρμογές",
|
"noAppsLabel": "Δεν βρέθηκαν εφαρμογές",
|
||||||
"currentVersion": "Τρέχουσα",
|
"currentVersion": "Τρέχουσα",
|
||||||
"recommendedVersion": "Προτεινόμενη",
|
"recommendedVersion": "Προτεινόμενη"
|
||||||
"anyVersion": "οποιαδήποτε"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Επιλέξτε τροποποιήσεις",
|
"widgetTitle": "Επιλέξτε τροποποιήσεις",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Αρχεία καταγραφής «Sentry»",
|
"sentryLabel": "Αρχεία καταγραφής «Sentry»",
|
||||||
"sentryHint": "Στείλτε ανώνυμα αρχεία καταγραφής για να μας βοηθήσετε να βελτιώσουμε το ReVanced Manager",
|
"sentryHint": "Στείλτε ανώνυμα αρχεία καταγραφής για να μας βοηθήσετε να βελτιώσουμε το ReVanced Manager",
|
||||||
"restartAppForChanges": "Επανεκκινήστε την εφαρμογή για να εφαρμόσετε αλλαγές",
|
"restartAppForChanges": "Επανεκκινήστε την εφαρμογή για να εφαρμόσετε αλλαγές",
|
||||||
"deleteKeystoreLabel": "Διαγραφή κλειδιών",
|
"regenerateKeystoreLabel": "Διαγραφή κλειδιών",
|
||||||
"deleteKeystoreHint": "Διαγράψτε το κλειδί που χρησιμοποιείται για την υπογραφή της εφαρμογής",
|
"regenerateKeystoreHint": "Διαγράψτε το κλειδί που χρησιμοποιείται για την υπογραφή της εφαρμογής",
|
||||||
"deletedKeystore": "Το κλειδί διαγράφηκε",
|
"regeneratedKeystore": "Το κλειδί διαγράφηκε",
|
||||||
"deleteTempDirLabel": "Διαγραφή προσωρινών αρχείων",
|
"deleteTempDirLabel": "Διαγραφή προσωρινών αρχείων",
|
||||||
"deleteTempDirHint": "Διαγραφή των αχρησιμοποίητων προσωρινών αρχείων",
|
"deleteTempDirHint": "Διαγραφή των αχρησιμοποίητων προσωρινών αρχείων",
|
||||||
"deletedTempDir": "Τα προσωρινά αρχεία διαγράφηκαν",
|
"deletedTempDir": "Τα προσωρινά αρχεία διαγράφηκαν",
|
||||||
|
@ -17,21 +17,33 @@
|
|||||||
"homeView": {
|
"homeView": {
|
||||||
"refreshSuccess": "Refreshed successfully",
|
"refreshSuccess": "Refreshed successfully",
|
||||||
"widgetTitle": "Dashboard",
|
"widgetTitle": "Dashboard",
|
||||||
|
|
||||||
"updatesSubtitle": "Updates",
|
"updatesSubtitle": "Updates",
|
||||||
"patchedSubtitle": "Patched applications",
|
"patchedSubtitle": "Patched applications",
|
||||||
|
|
||||||
"updatesAvailable": "Updates available",
|
"updatesAvailable": "Updates available",
|
||||||
"noUpdates": "No updates available",
|
"noUpdates": "No updates available",
|
||||||
|
|
||||||
"WIP": "Work in progress...",
|
"WIP": "Work in progress...",
|
||||||
|
|
||||||
"noInstallations": "No patched applications installed",
|
"noInstallations": "No patched applications installed",
|
||||||
"installed": "Installed",
|
"installed": "Installed",
|
||||||
|
"installUpdate": "Continue to install the update?",
|
||||||
|
|
||||||
"updateDialogTitle": "Update Manager",
|
"updateDialogTitle": "Update Manager",
|
||||||
"updateChangelogTitle": "Changelog",
|
"updateChangelogTitle": "Changelog",
|
||||||
|
|
||||||
"notificationTitle": "Update downloaded",
|
"notificationTitle": "Update downloaded",
|
||||||
"notificationText": "Tap to install the update",
|
"notificationText": "Tap to install the update",
|
||||||
|
|
||||||
"downloadingMessage": "Downloading update...",
|
"downloadingMessage": "Downloading update...",
|
||||||
|
"downloadedMessage": "Update downloaded!",
|
||||||
|
|
||||||
"installingMessage": "Installing update...",
|
"installingMessage": "Installing update...",
|
||||||
|
|
||||||
"errorDownloadMessage": "Unable to download update",
|
"errorDownloadMessage": "Unable to download update",
|
||||||
"errorInstallMessage": "Unable to install update",
|
"errorInstallMessage": "Unable to install update",
|
||||||
|
|
||||||
"noConnection": "No internet connection",
|
"noConnection": "No internet connection",
|
||||||
"updatesDisabled": "Updating a patched app is currently disabled. Repatch the app again."
|
"updatesDisabled": "Updating a patched app is currently disabled. Repatch the app again."
|
||||||
},
|
},
|
||||||
@ -50,21 +62,27 @@
|
|||||||
"patcherView": {
|
"patcherView": {
|
||||||
"widgetTitle": "Patcher",
|
"widgetTitle": "Patcher",
|
||||||
"patchButton": "Patch",
|
"patchButton": "Patch",
|
||||||
|
|
||||||
"patchDialogText": "You have selected a resource patch and a split APK installation has been detected, so patching errors may occur.\nAre you sure you want to proceed?",
|
"patchDialogText": "You have selected a resource patch and a split APK installation has been detected, so patching errors may occur.\nAre you sure you want to proceed?",
|
||||||
"armv7WarningDialogText": "Patching on ARMv7 devices is not yet supported and might fail. Proceed anyways?"
|
"armv7WarningDialogText": "Patching on ARMv7 devices is not yet supported and might fail. Proceed anyways?",
|
||||||
|
"splitApkWarningDialogText": "Patching a split APK is not yet supported and might fail. Proceed anyways?"
|
||||||
},
|
},
|
||||||
"appSelectorCard": {
|
"appSelectorCard": {
|
||||||
"widgetTitle": "Select an application",
|
"widgetTitle": "Select an application",
|
||||||
"widgetTitleSelected": "Selected application",
|
"widgetTitleSelected": "Selected application",
|
||||||
"widgetSubtitle": "No application selected",
|
"widgetSubtitle": "No application selected",
|
||||||
|
|
||||||
"noAppsLabel": "No applications found",
|
"noAppsLabel": "No applications found",
|
||||||
|
"notInstalled":"App not installed",
|
||||||
|
|
||||||
"currentVersion": "Current",
|
"currentVersion": "Current",
|
||||||
"suggestedVersion": "Suggested",
|
"suggestedVersion": "Suggested",
|
||||||
"anyVersion": "any"
|
"allVersions": "All versions"
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Select patches",
|
"widgetTitle": "Select patches",
|
||||||
"widgetTitleSelected": "Selected patches",
|
"widgetTitleSelected": "Selected patches",
|
||||||
|
|
||||||
"widgetSubtitle": "Select an application first",
|
"widgetSubtitle": "Select an application first",
|
||||||
"widgetEmptySubtitle": "No patches selected"
|
"widgetEmptySubtitle": "No patches selected"
|
||||||
},
|
},
|
||||||
@ -75,24 +93,33 @@
|
|||||||
"appSelectorView": {
|
"appSelectorView": {
|
||||||
"viewTitle": "Select an application",
|
"viewTitle": "Select an application",
|
||||||
"searchBarHint": "Search applications",
|
"searchBarHint": "Search applications",
|
||||||
"selectFromStorageButton": "Select from storage",
|
|
||||||
"storageButton": "Storage",
|
"storageButton": "Storage",
|
||||||
|
"selectFromStorageButton": "Select from storage",
|
||||||
|
|
||||||
"errorMessage": "Unable to use selected application",
|
"errorMessage": "Unable to use selected application",
|
||||||
|
|
||||||
"downloadToast": "Download function is not available yet",
|
"downloadToast": "Download function is not available yet",
|
||||||
|
|
||||||
"featureNotAvailable": "Feature not implemented",
|
"featureNotAvailable": "Feature not implemented",
|
||||||
"featureNotAvailableText": "This application is a split APK and cannot be selected. Unfortunately, this feature is only available for rooted users at the moment. However, you can still install the application by selecting its APK files from your device's storage instead"
|
"featureNotAvailableText": "This application is a split APK and cannot be selected. Unfortunately, this feature is only available for rooted users at the moment. However, you can still install the application by selecting its APK files from your device's storage instead"
|
||||||
},
|
},
|
||||||
"patchesSelectorView": {
|
"patchesSelectorView": {
|
||||||
"viewTitle": "Select patches",
|
"viewTitle": "Select patches",
|
||||||
"searchBarHint": "Search patches",
|
"searchBarHint": "Search patches",
|
||||||
|
|
||||||
"doneButton": "Done",
|
"doneButton": "Done",
|
||||||
|
|
||||||
"default": "Default",
|
"default": "Default",
|
||||||
"defaultTooltip": "Select all default patches",
|
"defaultTooltip": "Select all default patches",
|
||||||
|
|
||||||
"none": "None",
|
"none": "None",
|
||||||
"noneTooltip": "Deselect all patches",
|
"noneTooltip": "Deselect all patches",
|
||||||
|
|
||||||
"loadPatchesSelection": "Load patches selection",
|
"loadPatchesSelection": "Load patches selection",
|
||||||
"noSavedPatches": "No saved patches for the selected app.\nPress Done to save current selection.",
|
"noSavedPatches": "No saved patches for the selected app.\nPress Done to save current selection.",
|
||||||
"noPatchesFound": "No patches found for the selected app",
|
"noPatchesFound": "No patches found for the selected app",
|
||||||
|
|
||||||
"selectAllPatchesWarningContent": "You are about to select all patches, that includes non-suggested patches and can cause unwanted behavior."
|
"selectAllPatchesWarningContent": "You are about to select all patches, that includes non-suggested patches and can cause unwanted behavior."
|
||||||
},
|
},
|
||||||
"patchItem": {
|
"patchItem": {
|
||||||
@ -105,11 +132,14 @@
|
|||||||
"installRootButton": "Install as Root",
|
"installRootButton": "Install as Root",
|
||||||
"openButton": "Open",
|
"openButton": "Open",
|
||||||
"shareButton": "Share file",
|
"shareButton": "Share file",
|
||||||
|
|
||||||
"notificationTitle": "ReVanced Manager is patching",
|
"notificationTitle": "ReVanced Manager is patching",
|
||||||
"notificationText": "Tap to return to the installer",
|
"notificationText": "Tap to return to the installer",
|
||||||
|
|
||||||
"shareApkMenuOption": "Share APK",
|
"shareApkMenuOption": "Share APK",
|
||||||
"exportApkMenuOption": "Export APK",
|
"exportApkMenuOption": "Export APK",
|
||||||
"shareLogMenuOption": "Share log",
|
"shareLogMenuOption": "Share log",
|
||||||
|
|
||||||
"installErrorDialogTitle": "Error",
|
"installErrorDialogTitle": "Error",
|
||||||
"installErrorDialogText1": "Root install is not possible with the current patches selection.\nRepatch your app or choose non-root install.",
|
"installErrorDialogText1": "Root install is not possible with the current patches selection.\nRepatch your app or choose non-root install.",
|
||||||
"installErrorDialogText2": "Non-root install is not possible with the current patches selection.\nRepatch your app or choose root install if you have your device rooted.",
|
"installErrorDialogText2": "Non-root install is not possible with the current patches selection.\nRepatch your app or choose root install if you have your device rooted.",
|
||||||
@ -118,74 +148,99 @@
|
|||||||
},
|
},
|
||||||
"settingsView": {
|
"settingsView": {
|
||||||
"widgetTitle": "Settings",
|
"widgetTitle": "Settings",
|
||||||
|
|
||||||
"appearanceSectionTitle": "Appearance",
|
"appearanceSectionTitle": "Appearance",
|
||||||
"teamSectionTitle": "Team",
|
"teamSectionTitle": "Team",
|
||||||
"infoSectionTitle": "Info",
|
"infoSectionTitle": "Info",
|
||||||
"advancedSectionTitle": "Advanced",
|
"advancedSectionTitle": "Advanced",
|
||||||
|
"exportSectionTitle": "Import & export",
|
||||||
"logsSectionTitle": "Logs",
|
"logsSectionTitle": "Logs",
|
||||||
|
|
||||||
"darkThemeLabel": "Dark mode",
|
"darkThemeLabel": "Dark mode",
|
||||||
"darkThemeHint": "Welcome to the dark side",
|
"darkThemeHint": "Welcome to the dark side",
|
||||||
|
|
||||||
"dynamicThemeLabel": "Material You",
|
"dynamicThemeLabel": "Material You",
|
||||||
"dynamicThemeHint": "Enjoy an experience closer to your device",
|
"dynamicThemeHint": "Enjoy an experience closer to your device",
|
||||||
|
|
||||||
"languageLabel": "Language",
|
"languageLabel": "Language",
|
||||||
"englishOption": "English",
|
"englishOption": "English",
|
||||||
|
|
||||||
"sourcesLabel": "Sources",
|
"sourcesLabel": "Sources",
|
||||||
"sourcesLabelHint": "Configure your custom sources",
|
"sourcesLabelHint": "Configure your custom sources",
|
||||||
"hostRepositoryLabel": "Repository API",
|
|
||||||
"orgPatchesLabel": "Patches organization",
|
|
||||||
"sourcesPatchesLabel": "Patches source",
|
|
||||||
"orgIntegrationsLabel": "Integrations organization",
|
|
||||||
"sourcesIntegrationsLabel": "Integrations source",
|
"sourcesIntegrationsLabel": "Integrations source",
|
||||||
"sourcesResetDialogTitle": "Reset",
|
"sourcesResetDialogTitle": "Reset",
|
||||||
"sourcesResetDialogText": "Are you sure you want to reset custom sources to their default values?",
|
"sourcesResetDialogText": "Are you sure you want to reset custom sources to their default values?",
|
||||||
"apiURLResetDialogText": "Are you sure you want to reset API URL to its default value?",
|
"apiURLResetDialogText": "Are you sure you want to reset API URL to its default value?",
|
||||||
"contributorsLabel": "Contributors",
|
|
||||||
"contributorsHint": "A list of contributors of ReVanced",
|
|
||||||
"logsLabel": "Logs",
|
|
||||||
"logsHint": "Share Manager's logs",
|
|
||||||
"apiURLLabel": "API URL",
|
"apiURLLabel": "API URL",
|
||||||
"apiURLHint": "Configure your custom API URL",
|
"apiURLHint": "Configure your custom API URL",
|
||||||
"selectApiURL": "API URL",
|
"selectApiURL": "API URL",
|
||||||
|
"hostRepositoryLabel": "Repository API",
|
||||||
|
"orgPatchesLabel": "Patches organization",
|
||||||
|
"sourcesPatchesLabel": "Patches source",
|
||||||
|
"orgIntegrationsLabel": "Integrations organization",
|
||||||
|
|
||||||
|
"contributorsLabel": "Contributors",
|
||||||
|
"contributorsHint": "A list of contributors of ReVanced",
|
||||||
|
|
||||||
|
"logsLabel": "Logs",
|
||||||
|
"logsHint": "Share Manager's logs",
|
||||||
|
|
||||||
"experimentalUniversalPatchesLabel": "Experimental universal patches support",
|
"experimentalUniversalPatchesLabel": "Experimental universal patches support",
|
||||||
"experimentalUniversalPatchesHint": "Display all applications to use with universal patches, loading list of apps may be slower",
|
"experimentalUniversalPatchesHint": "Display all applications to use with universal patches, loading list of apps may be slower",
|
||||||
"experimentalPatchesLabel": "Experimental patches support",
|
"experimentalPatchesLabel": "Experimental patches support",
|
||||||
"experimentalPatchesHint": "Enable usage of unsupported patches in any app version",
|
"experimentalPatchesHint": "Enable usage of unsupported patches in any app version",
|
||||||
"enabledExperimentalPatches": "Experimental patches support enabled",
|
"enabledExperimentalPatches": "Experimental patches support enabled",
|
||||||
"exportSectionTitle": "Import & export",
|
|
||||||
"aboutLabel": "About",
|
"aboutLabel": "About",
|
||||||
"snackbarMessage": "Copied to clipboard",
|
"snackbarMessage": "Copied to clipboard",
|
||||||
"restartAppForChanges": "Restart the app to apply changes",
|
"restartAppForChanges": "Restart the app to apply changes",
|
||||||
"deleteKeystoreLabel": "Delete keystore",
|
|
||||||
"deleteKeystoreHint": "Delete the keystore used to sign the app",
|
|
||||||
"deleteKeystoreDialogText": "Are you sure you want to delete the keystore used to sign patched applications?",
|
|
||||||
"deletedKeystore": "Keystore deleted",
|
|
||||||
"deleteTempDirLabel": "Delete temporary files",
|
"deleteTempDirLabel": "Delete temporary files",
|
||||||
"deleteTempDirHint": "Delete unused temporary files",
|
"deleteTempDirHint": "Delete unused temporary files",
|
||||||
"deletedTempDir": "Temporary files deleted",
|
"deletedTempDir": "Temporary files deleted",
|
||||||
|
|
||||||
"exportPatchesLabel": "Export patches selection",
|
"exportPatchesLabel": "Export patches selection",
|
||||||
"exportPatchesHint": "Export patches selection to a JSON file",
|
"exportPatchesHint": "Export patches selection to a JSON file",
|
||||||
"exportedPatches": "Patches selection exported",
|
"exportedPatches": "Patches selection exported",
|
||||||
"noExportFileFound": "No patches selection to export",
|
"noExportFileFound": "No patches selection to export",
|
||||||
|
|
||||||
"importPatchesLabel": "Import patches selection",
|
"importPatchesLabel": "Import patches selection",
|
||||||
"importPatchesHint": "Import patches selection from a JSON file",
|
"importPatchesHint": "Import patches selection from a JSON file",
|
||||||
"importedPatches": "Patches selection imported",
|
"importedPatches": "Patches selection imported",
|
||||||
|
|
||||||
"resetStoredPatchesLabel": "Reset patches",
|
"resetStoredPatchesLabel": "Reset patches",
|
||||||
"resetStoredPatchesHint": "Reset the stored patches selection",
|
"resetStoredPatchesHint": "Reset the stored patches selection",
|
||||||
|
|
||||||
|
"resetStoredPatchesDialogTitle": "Reset patches selection?",
|
||||||
|
"resetStoredPatchesDialogText": "Resetting patches selection will remove all selected patches.",
|
||||||
"resetStoredPatches": "Patches selection has been reset",
|
"resetStoredPatches": "Patches selection has been reset",
|
||||||
"jsonSelectorErrorMessage": "Unable to use selected JSON file",
|
|
||||||
"deleteLogsLabel": "Delete logs",
|
"deleteLogsLabel": "Delete logs",
|
||||||
"deleteLogsHint": "Delete collected manager logs",
|
"deleteLogsHint": "Delete collected manager logs",
|
||||||
"deletedLogs": "Logs deleted",
|
"deletedLogs": "Logs deleted",
|
||||||
|
|
||||||
|
"regenerateKeystoreLabel": "Regenerate keystore",
|
||||||
|
"regenerateKeystoreHint": "Regenerate the keystore used to sign the app",
|
||||||
|
|
||||||
|
"regenerateKeystoreDialogTitle": "Regenerate keystore?",
|
||||||
|
"regenerateKeystoreDialogText": "Patched apps signed with the old keystore will no longer be able to update.",
|
||||||
|
"regeneratedKeystore": "Keystore regenerated",
|
||||||
|
|
||||||
"exportKeystoreLabel": "Export keystore",
|
"exportKeystoreLabel": "Export keystore",
|
||||||
"exportKeystoreHint": "Export keystore used to sign apps",
|
"exportKeystoreHint": "Export keystore used to sign apps",
|
||||||
"exportedKeystore": "Keystore exported",
|
"exportedKeystore": "Keystore exported",
|
||||||
"noKeystoreExportFileFound": "No keystore to export",
|
"noKeystoreExportFileFound": "No keystore to export",
|
||||||
|
|
||||||
"importKeystoreLabel": "Import keystore",
|
"importKeystoreLabel": "Import keystore",
|
||||||
"importKeystoreHint": "Import keystore used to sign apps",
|
"importKeystoreHint": "Import keystore used to sign apps",
|
||||||
"importedKeystore": "Keystore imported",
|
"importedKeystore": "Keystore imported",
|
||||||
"keystoreSelectorErrorMessage": "Unable to use selected KEYSTORE file",
|
|
||||||
"selectKeystorePassword": "Keystore Password",
|
"selectKeystorePassword": "Keystore Password",
|
||||||
"selectKeystorePasswordHint": "Select keystore password used to sign the apk"
|
"selectKeystorePasswordHint": "Select keystore password used to sign the apk",
|
||||||
|
|
||||||
|
"jsonSelectorErrorMessage": "Unable to use selected JSON file",
|
||||||
|
"keystoreSelectorErrorMessage": "Unable to use selected KEYSTORE file"
|
||||||
},
|
},
|
||||||
"appInfoView": {
|
"appInfoView": {
|
||||||
"widgetTitle": "App info",
|
"widgetTitle": "App info",
|
||||||
@ -193,18 +248,22 @@
|
|||||||
"uninstallButton": "Uninstall",
|
"uninstallButton": "Uninstall",
|
||||||
"patchButton": "Patch",
|
"patchButton": "Patch",
|
||||||
"unpatchButton": "Unpatch",
|
"unpatchButton": "Unpatch",
|
||||||
"unpatchDialogText": "Are you sure you want to unpatch this app?",
|
|
||||||
"rootDialogTitle": "Error",
|
"rootDialogTitle": "Error",
|
||||||
|
|
||||||
|
"unpatchDialogText": "Are you sure you want to unpatch this app?",
|
||||||
"rootDialogText": "App was installed with superuser permissions, but currently ReVanced Manager has no permissions.\nPlease grant superuser permissions first.",
|
"rootDialogText": "App was installed with superuser permissions, but currently ReVanced Manager has no permissions.\nPlease grant superuser permissions first.",
|
||||||
|
|
||||||
"packageNameLabel": "Package name",
|
"packageNameLabel": "Package name",
|
||||||
"originalPackageNameLabel": "Original package name",
|
"originalPackageNameLabel": "Original package name",
|
||||||
"installTypeLabel": "Installation type",
|
"installTypeLabel": "Installation type",
|
||||||
"rootTypeLabel": "Root",
|
"rootTypeLabel": "Root",
|
||||||
"nonRootTypeLabel": "Non-root",
|
"nonRootTypeLabel": "Non-root",
|
||||||
"patchedDateLabel": "Patched date",
|
"patchedDateLabel": "Patched date",
|
||||||
"patchedDateHint": "{date} at {time}",
|
|
||||||
"appliedPatchesLabel": "Applied patches",
|
"appliedPatchesLabel": "Applied patches",
|
||||||
|
|
||||||
|
"patchedDateHint": "{date} at {time}",
|
||||||
"appliedPatchesHint": "{quantity} applied patches",
|
"appliedPatchesHint": "{quantity} applied patches",
|
||||||
|
|
||||||
"updateNotImplemented": "This feature has not been implemented yet"
|
"updateNotImplemented": "This feature has not been implemented yet"
|
||||||
},
|
},
|
||||||
"contributorsView": {
|
"contributorsView": {
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Ninguna aplicación seleccionada",
|
"widgetSubtitle": "Ninguna aplicación seleccionada",
|
||||||
"noAppsLabel": "No se encontraron aplicaciones",
|
"noAppsLabel": "No se encontraron aplicaciones",
|
||||||
"currentVersion": "Versión actual",
|
"currentVersion": "Versión actual",
|
||||||
"recommendedVersion": "Versión recomendada",
|
"recommendedVersion": "Versión recomendada"
|
||||||
"anyVersion": "cualquiera"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Seleccionar parches",
|
"widgetTitle": "Seleccionar parches",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Registro Sentry",
|
"sentryLabel": "Registro Sentry",
|
||||||
"sentryHint": "Enviar registros anónimos para ayudarnos a mejorar ReVanced Manager",
|
"sentryHint": "Enviar registros anónimos para ayudarnos a mejorar ReVanced Manager",
|
||||||
"restartAppForChanges": "Reinicie la app para aplicar los cambios",
|
"restartAppForChanges": "Reinicie la app para aplicar los cambios",
|
||||||
"deleteKeystoreLabel": "Eliminar keystore",
|
"regenerateKeystoreLabel": "Eliminar keystore",
|
||||||
"deleteKeystoreHint": "Eliminar el keystore usado para firmar la app",
|
"regenerateKeystoreHint": "Eliminar el keystore usado para firmar la app",
|
||||||
"deletedKeystore": "Keystore eliminado",
|
"regeneratedKeystore": "Keystore eliminado",
|
||||||
"deleteTempDirLabel": "Borrar archivos temporales",
|
"deleteTempDirLabel": "Borrar archivos temporales",
|
||||||
"deleteTempDirHint": "Eliminar archivos temporales no utilizados",
|
"deleteTempDirHint": "Eliminar archivos temporales no utilizados",
|
||||||
"deletedTempDir": "Archivos temporales eliminados",
|
"deletedTempDir": "Archivos temporales eliminados",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Ninguna aplicación seleccionada",
|
"widgetSubtitle": "Ninguna aplicación seleccionada",
|
||||||
"noAppsLabel": "No se encontraron aplicaciones",
|
"noAppsLabel": "No se encontraron aplicaciones",
|
||||||
"currentVersion": "Versión actual",
|
"currentVersion": "Versión actual",
|
||||||
"recommendedVersion": "Versión recomendada",
|
"recommendedVersion": "Versión recomendada"
|
||||||
"anyVersion": "Cualquier versión"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Seleccionar parches",
|
"widgetTitle": "Seleccionar parches",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Registro centinela",
|
"sentryLabel": "Registro centinela",
|
||||||
"sentryHint": "Enviar registros anónimos para ayudarnos a mejorar ReVanced Manager",
|
"sentryHint": "Enviar registros anónimos para ayudarnos a mejorar ReVanced Manager",
|
||||||
"restartAppForChanges": "Reinicie la aplicación para aplicar los cambios",
|
"restartAppForChanges": "Reinicie la aplicación para aplicar los cambios",
|
||||||
"deleteKeystoreLabel": "Eliminar keystore",
|
"regenerateKeystoreLabel": "Eliminar keystore",
|
||||||
"deleteKeystoreHint": "Eliminar el keystore usado para firmar la app",
|
"regenerateKeystoreHint": "Eliminar el keystore usado para firmar la app",
|
||||||
"deletedKeystore": "Keystore eliminado",
|
"regeneratedKeystore": "Keystore eliminado",
|
||||||
"deleteTempDirLabel": "Borrar archivos temporales",
|
"deleteTempDirLabel": "Borrar archivos temporales",
|
||||||
"deleteTempDirHint": "Eliminar archivos temporales sin utilizar",
|
"deleteTempDirHint": "Eliminar archivos temporales sin utilizar",
|
||||||
"deletedTempDir": "Archivos temporales eliminados",
|
"deletedTempDir": "Archivos temporales eliminados",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Sovellusta ei ole valittu",
|
"widgetSubtitle": "Sovellusta ei ole valittu",
|
||||||
"noAppsLabel": "Sovelluksia ei löytynyt",
|
"noAppsLabel": "Sovelluksia ei löytynyt",
|
||||||
"currentVersion": "Nykyinen",
|
"currentVersion": "Nykyinen",
|
||||||
"recommendedVersion": "Suositeltu",
|
"recommendedVersion": "Suositeltu"
|
||||||
"anyVersion": "mikä tahansa"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Valitse paikkaukset",
|
"widgetTitle": "Valitse paikkaukset",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Sentry-lokikirjaus",
|
"sentryLabel": "Sentry-lokikirjaus",
|
||||||
"sentryHint": "Lähetä nimettömiä tietoja auttaaksesi ReVanced Managerin kehityksessä",
|
"sentryHint": "Lähetä nimettömiä tietoja auttaaksesi ReVanced Managerin kehityksessä",
|
||||||
"restartAppForChanges": "Käynnistä sovellus uudestaan muutosten käyttöönottamiseksi",
|
"restartAppForChanges": "Käynnistä sovellus uudestaan muutosten käyttöönottamiseksi",
|
||||||
"deleteKeystoreLabel": "Poista avainsäilö",
|
"regenerateKeystoreLabel": "Poista avainsäilö",
|
||||||
"deleteKeystoreHint": "Poista sovelluksen allekirjoitukseen käytetty avainsäilö",
|
"regenerateKeystoreHint": "Poista sovelluksen allekirjoitukseen käytetty avainsäilö",
|
||||||
"deletedKeystore": "Avainsäilö poistettiin",
|
"regeneratedKeystore": "Avainsäilö poistettiin",
|
||||||
"deleteTempDirLabel": "Poista väliaikaistiedostot",
|
"deleteTempDirLabel": "Poista väliaikaistiedostot",
|
||||||
"deleteTempDirHint": "Poista käyttämättömät väliaikaistiedostot",
|
"deleteTempDirHint": "Poista käyttämättömät väliaikaistiedostot",
|
||||||
"deletedTempDir": "Väliaikaistiedostot poistettiin",
|
"deletedTempDir": "Väliaikaistiedostot poistettiin",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Aucune application sélectionnée",
|
"widgetSubtitle": "Aucune application sélectionnée",
|
||||||
"noAppsLabel": "Aucune application trouvée",
|
"noAppsLabel": "Aucune application trouvée",
|
||||||
"currentVersion": "Version actuelle",
|
"currentVersion": "Version actuelle",
|
||||||
"recommendedVersion": "Version recommandée",
|
"recommendedVersion": "Version recommandée"
|
||||||
"anyVersion": "n'importe laquelle"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Sélectionner les patchs",
|
"widgetTitle": "Sélectionner les patchs",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Journal sentinel",
|
"sentryLabel": "Journal sentinel",
|
||||||
"sentryHint": "Envoyer des journaux anonymes pour nous aider à améliorer ReVanced Manager",
|
"sentryHint": "Envoyer des journaux anonymes pour nous aider à améliorer ReVanced Manager",
|
||||||
"restartAppForChanges": "Redémarrez l'application pour appliquer les changements",
|
"restartAppForChanges": "Redémarrez l'application pour appliquer les changements",
|
||||||
"deleteKeystoreLabel": "Supprimer le magasin de clés",
|
"regenerateKeystoreLabel": "Supprimer le magasin de clés",
|
||||||
"deleteKeystoreHint": "Supprimer le magasin de clés utilisé pour signer l'application",
|
"regenerateKeystoreHint": "Supprimer le magasin de clés utilisé pour signer l'application",
|
||||||
"deletedKeystore": "Magasin de clés supprimé",
|
"regeneratedKeystore": "Magasin de clés supprimé",
|
||||||
"deleteTempDirLabel": "Supprimer les fichiers temporaires",
|
"deleteTempDirLabel": "Supprimer les fichiers temporaires",
|
||||||
"deleteTempDirHint": "Supprimer les fichiers temporaires inutilisés",
|
"deleteTempDirHint": "Supprimer les fichiers temporaires inutilisés",
|
||||||
"deletedTempDir": "Fichiers temporaires supprimés",
|
"deletedTempDir": "Fichiers temporaires supprimés",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "कोई ऐप्लकैशन चुना हुआ नहीं",
|
"widgetSubtitle": "कोई ऐप्लकैशन चुना हुआ नहीं",
|
||||||
"noAppsLabel": "कोई एप्लिकेशन नहीं मिला।",
|
"noAppsLabel": "कोई एप्लिकेशन नहीं मिला।",
|
||||||
"currentVersion": "वर्तमान",
|
"currentVersion": "वर्तमान",
|
||||||
"recommendedVersion": "अनुशंसित",
|
"recommendedVersion": "अनुशंसित"
|
||||||
"anyVersion": "कोई"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "पैच चुने",
|
"widgetTitle": "पैच चुने",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "संतरी लॉगिंग",
|
"sentryLabel": "संतरी लॉगिंग",
|
||||||
"sentryHint": "उन्नत प्रबंधक को बेहतर बनाने में हमारी सहायता करने के लिए अनाम लॉग भेजें",
|
"sentryHint": "उन्नत प्रबंधक को बेहतर बनाने में हमारी सहायता करने के लिए अनाम लॉग भेजें",
|
||||||
"restartAppForChanges": "Restart the app to apply changes",
|
"restartAppForChanges": "Restart the app to apply changes",
|
||||||
"deleteKeystoreLabel": "कीस्टोर मिटाएं",
|
"regenerateKeystoreLabel": "कीस्टोर मिटाएं",
|
||||||
"deleteKeystoreHint": "ऐप पर हस्ताक्षर करने के लिए उपयोग की जाने वाली कीस्टोर हटाएं",
|
"regenerateKeystoreHint": "ऐप पर हस्ताक्षर करने के लिए उपयोग की जाने वाली कीस्टोर हटाएं",
|
||||||
"deletedKeystore": "कीस्टोर हटा दिया गया",
|
"regeneratedKeystore": "कीस्टोर हटा दिया गया",
|
||||||
"deleteTempDirLabel": "अस्थाई फ़ाइलें मिटायें",
|
"deleteTempDirLabel": "अस्थाई फ़ाइलें मिटायें",
|
||||||
"deleteTempDirHint": "अप्रयुक्त अस्थाई फ़ाइलें मिटायें",
|
"deleteTempDirHint": "अप्रयुक्त अस्थाई फ़ाइलें मिटायें",
|
||||||
"deletedTempDir": "क्षणिक फ़ाईल मिटाए गए।",
|
"deletedTempDir": "क्षणिक फ़ाईल मिटाए गए।",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Nincs kiválasztott alkalmazás",
|
"widgetSubtitle": "Nincs kiválasztott alkalmazás",
|
||||||
"noAppsLabel": "Nem találhatóak alkalmazások",
|
"noAppsLabel": "Nem találhatóak alkalmazások",
|
||||||
"currentVersion": "Jelenlegi",
|
"currentVersion": "Jelenlegi",
|
||||||
"recommendedVersion": "Ajánlott",
|
"recommendedVersion": "Ajánlott"
|
||||||
"anyVersion": "bármely"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Patchek kiválasztása",
|
"widgetTitle": "Patchek kiválasztása",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Sentry naplózás",
|
"sentryLabel": "Sentry naplózás",
|
||||||
"sentryHint": "Névtelen használati adatok küldésével hozzájárulhatsz, hogy a ReVanced Manager még jobb legyen",
|
"sentryHint": "Névtelen használati adatok küldésével hozzájárulhatsz, hogy a ReVanced Manager még jobb legyen",
|
||||||
"restartAppForChanges": "Indítsd újra az alkalmazást a változások alkalmazásához",
|
"restartAppForChanges": "Indítsd újra az alkalmazást a változások alkalmazásához",
|
||||||
"deleteKeystoreLabel": "Kulcstartó törlése",
|
"regenerateKeystoreLabel": "Kulcstartó törlése",
|
||||||
"deleteKeystoreHint": "Törli az alkalmazás aláírásához használt kulcstartót",
|
"regenerateKeystoreHint": "Törli az alkalmazás aláírásához használt kulcstartót",
|
||||||
"deletedKeystore": "Kulcstartó törölve",
|
"regeneratedKeystore": "Kulcstartó törölve",
|
||||||
"deleteTempDirLabel": "Ideiglenes fájlok törlése",
|
"deleteTempDirLabel": "Ideiglenes fájlok törlése",
|
||||||
"deleteTempDirHint": "Felesleges átmeneti fájlok törlése",
|
"deleteTempDirHint": "Felesleges átmeneti fájlok törlése",
|
||||||
"deletedTempDir": "Ideiglenes fájlok törölve",
|
"deletedTempDir": "Ideiglenes fájlok törölve",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Tidak ada aplikasi yang dipilih",
|
"widgetSubtitle": "Tidak ada aplikasi yang dipilih",
|
||||||
"noAppsLabel": "Aplikasi tidak ditemukan",
|
"noAppsLabel": "Aplikasi tidak ditemukan",
|
||||||
"currentVersion": "Saat ini",
|
"currentVersion": "Saat ini",
|
||||||
"recommendedVersion": "Rekomendasi",
|
"recommendedVersion": "Rekomendasi"
|
||||||
"anyVersion": "semua"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Pilih Modifikasi",
|
"widgetTitle": "Pilih Modifikasi",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Log sentry",
|
"sentryLabel": "Log sentry",
|
||||||
"sentryHint": "Kirim log anonim untuk membantu kami meningkatkan ReVanced Manager",
|
"sentryHint": "Kirim log anonim untuk membantu kami meningkatkan ReVanced Manager",
|
||||||
"restartAppForChanges": "Mulai ulang aplikasi untuk menerapkan perubahan",
|
"restartAppForChanges": "Mulai ulang aplikasi untuk menerapkan perubahan",
|
||||||
"deleteKeystoreLabel": "Hapus penyimpanan kunci",
|
"regenerateKeystoreLabel": "Hapus penyimpanan kunci",
|
||||||
"deleteKeystoreHint": "Hapus penyimpanan kunci yang digunakan untuk menandatangani aplikasi",
|
"regenerateKeystoreHint": "Hapus penyimpanan kunci yang digunakan untuk menandatangani aplikasi",
|
||||||
"deletedKeystore": "Penyimpanan kunci dihapus",
|
"regeneratedKeystore": "Penyimpanan kunci dihapus",
|
||||||
"deleteTempDirLabel": "Hapus berkas sementara",
|
"deleteTempDirLabel": "Hapus berkas sementara",
|
||||||
"deleteTempDirHint": "Hapus berkas sementara yang tidak dipakai",
|
"deleteTempDirHint": "Hapus berkas sementara yang tidak dipakai",
|
||||||
"deletedTempDir": "Berkas sementara dihapus",
|
"deletedTempDir": "Berkas sementara dihapus",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Nessuna applicazione selezionata",
|
"widgetSubtitle": "Nessuna applicazione selezionata",
|
||||||
"noAppsLabel": "Nessuna applicazione trovata",
|
"noAppsLabel": "Nessuna applicazione trovata",
|
||||||
"currentVersion": "Attuale",
|
"currentVersion": "Attuale",
|
||||||
"recommendedVersion": "Consigliata",
|
"recommendedVersion": "Consigliata"
|
||||||
"anyVersion": "qualsiasi"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Seleziona patch",
|
"widgetTitle": "Seleziona patch",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Log di Sentry",
|
"sentryLabel": "Log di Sentry",
|
||||||
"sentryHint": "Invia log anonimi per aiutarci a migliorare ReVanced Manager",
|
"sentryHint": "Invia log anonimi per aiutarci a migliorare ReVanced Manager",
|
||||||
"restartAppForChanges": "Riavvia l'app per applicare le modifiche",
|
"restartAppForChanges": "Riavvia l'app per applicare le modifiche",
|
||||||
"deleteKeystoreLabel": "Elimina keystore",
|
"regenerateKeystoreLabel": "Elimina keystore",
|
||||||
"deleteKeystoreHint": "Elimina il keystore usato per firmare l'applicazione",
|
"regenerateKeystoreHint": "Elimina il keystore usato per firmare l'applicazione",
|
||||||
"deletedKeystore": "Keystore eliminato",
|
"regeneratedKeystore": "Keystore eliminato",
|
||||||
"deleteTempDirLabel": "Elimina file temporanei",
|
"deleteTempDirLabel": "Elimina file temporanei",
|
||||||
"deleteTempDirHint": "Elimina i file temporanei non utilizzati",
|
"deleteTempDirHint": "Elimina i file temporanei non utilizzati",
|
||||||
"deletedTempDir": "File temporanei eliminati",
|
"deletedTempDir": "File temporanei eliminati",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "선택된 앱 없음",
|
"widgetSubtitle": "선택된 앱 없음",
|
||||||
"noAppsLabel": "앱이 발견되지 않음",
|
"noAppsLabel": "앱이 발견되지 않음",
|
||||||
"currentVersion": "현재 버전",
|
"currentVersion": "현재 버전",
|
||||||
"recommendedVersion": "권장 버전",
|
"recommendedVersion": "권장 버전"
|
||||||
"anyVersion": "모든 버전"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "패치를 선택하세요",
|
"widgetTitle": "패치를 선택하세요",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Sentry 로깅",
|
"sentryLabel": "Sentry 로깅",
|
||||||
"sentryHint": "익명의 로그를 보내 ReVanced Manager를 개선할 수 있도록 도와주세요",
|
"sentryHint": "익명의 로그를 보내 ReVanced Manager를 개선할 수 있도록 도와주세요",
|
||||||
"restartAppForChanges": "변경 사항을 적용하려면 앱을 다시 시작하세요",
|
"restartAppForChanges": "변경 사항을 적용하려면 앱을 다시 시작하세요",
|
||||||
"deleteKeystoreLabel": "키스토어 제거",
|
"regenerateKeystoreLabel": "키스토어 제거",
|
||||||
"deleteKeystoreHint": "앱을 서명하기 위해 사용되는 키스토어를 제거합니다.",
|
"regenerateKeystoreHint": "앱을 서명하기 위해 사용되는 키스토어를 제거합니다.",
|
||||||
"deletedKeystore": "키스토어 제거됨",
|
"regeneratedKeystore": "키스토어 제거됨",
|
||||||
"deleteTempDirLabel": "임시 파일 삭제",
|
"deleteTempDirLabel": "임시 파일 삭제",
|
||||||
"deleteTempDirHint": "사용되지 않은 임시 파일 삭제",
|
"deleteTempDirHint": "사용되지 않은 임시 파일 삭제",
|
||||||
"deletedTempDir": "임시 파일 삭제됨",
|
"deletedTempDir": "임시 파일 삭제됨",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Nepasirinkta programa",
|
"widgetSubtitle": "Nepasirinkta programa",
|
||||||
"noAppsLabel": "Nerastos jokios programos",
|
"noAppsLabel": "Nerastos jokios programos",
|
||||||
"currentVersion": "Dabartinė",
|
"currentVersion": "Dabartinė",
|
||||||
"recommendedVersion": "Rekomenduojama",
|
"recommendedVersion": "Rekomenduojama"
|
||||||
"anyVersion": "bet kokia"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Pasirinkite modifikacijas",
|
"widgetTitle": "Pasirinkite modifikacijas",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Klaidų rinkimo įrankio įrašai",
|
"sentryLabel": "Klaidų rinkimo įrankio įrašai",
|
||||||
"sentryHint": "Siųsti anoniminius įrašus, kad padėtumėte mums tobulinti ReVanced Manager",
|
"sentryHint": "Siųsti anoniminius įrašus, kad padėtumėte mums tobulinti ReVanced Manager",
|
||||||
"restartAppForChanges": "Iš naujo paleiskite programą, kad modifikacijos įsigaliotų",
|
"restartAppForChanges": "Iš naujo paleiskite programą, kad modifikacijos įsigaliotų",
|
||||||
"deleteKeystoreLabel": "Ištrinti keystore",
|
"regenerateKeystoreLabel": "Ištrinti keystore",
|
||||||
"deleteKeystoreHint": "Ištrinti keystore kuris naudojamas pasirašyti programą",
|
"regenerateKeystoreHint": "Ištrinti keystore kuris naudojamas pasirašyti programą",
|
||||||
"deletedKeystore": "Keystore ištrintas",
|
"regeneratedKeystore": "Keystore ištrintas",
|
||||||
"deleteTempDirLabel": "Ištrinti laikinus failus",
|
"deleteTempDirLabel": "Ištrinti laikinus failus",
|
||||||
"deleteTempDirHint": "Ištrinti nenaudojamus laikinus failus",
|
"deleteTempDirHint": "Ištrinti nenaudojamus laikinus failus",
|
||||||
"deletedTempDir": "Laikini failai ištrinti",
|
"deletedTempDir": "Laikini failai ištrinti",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Tiada aplikasi dipilih",
|
"widgetSubtitle": "Tiada aplikasi dipilih",
|
||||||
"noAppsLabel": "Tiada aplikasi ditemui",
|
"noAppsLabel": "Tiada aplikasi ditemui",
|
||||||
"currentVersion": "Semasa",
|
"currentVersion": "Semasa",
|
||||||
"recommendedVersion": "Disyorkan",
|
"recommendedVersion": "Disyorkan"
|
||||||
"anyVersion": "mana-mana"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Pilih modifikasi",
|
"widgetTitle": "Pilih modifikasi",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Rekod Sentry",
|
"sentryLabel": "Rekod Sentry",
|
||||||
"sentryHint": "Hantarkan log anonymous untuk bantu kami menambah baik Revanced Manager",
|
"sentryHint": "Hantarkan log anonymous untuk bantu kami menambah baik Revanced Manager",
|
||||||
"restartAppForChanges": "Mulakan semula apl untuk menggunakan tetapan",
|
"restartAppForChanges": "Mulakan semula apl untuk menggunakan tetapan",
|
||||||
"deleteKeystoreLabel": "Buang keystore",
|
"regenerateKeystoreLabel": "Buang keystore",
|
||||||
"deleteKeystoreHint": "Buang keystore yang digunakan untuk mengesahkan apl",
|
"regenerateKeystoreHint": "Buang keystore yang digunakan untuk mengesahkan apl",
|
||||||
"deletedKeystore": "Keystore dibuang",
|
"regeneratedKeystore": "Keystore dibuang",
|
||||||
"deleteTempDirLabel": "Buang fail sementara",
|
"deleteTempDirLabel": "Buang fail sementara",
|
||||||
"deleteTempDirHint": "Buang fail sementara yang tidak digunakan",
|
"deleteTempDirHint": "Buang fail sementara yang tidak digunakan",
|
||||||
"deletedTempDir": "Fail sementara dibuang",
|
"deletedTempDir": "Fail sementara dibuang",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Nie wybrano aplikacji",
|
"widgetSubtitle": "Nie wybrano aplikacji",
|
||||||
"noAppsLabel": "Nie znaleziono aplikacji",
|
"noAppsLabel": "Nie znaleziono aplikacji",
|
||||||
"currentVersion": "Aktualna",
|
"currentVersion": "Aktualna",
|
||||||
"recommendedVersion": "Zalecana",
|
"recommendedVersion": "Zalecana"
|
||||||
"anyVersion": "dowolna"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Wybierz łatki",
|
"widgetTitle": "Wybierz łatki",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Zapisywanie logów",
|
"sentryLabel": "Zapisywanie logów",
|
||||||
"sentryHint": "Wysyłaj anonimowe logi, aby pomóc nam ulepszyć ReVanced Manager",
|
"sentryHint": "Wysyłaj anonimowe logi, aby pomóc nam ulepszyć ReVanced Manager",
|
||||||
"restartAppForChanges": "Zrestartuj aplikację, aby zastosować zmiany",
|
"restartAppForChanges": "Zrestartuj aplikację, aby zastosować zmiany",
|
||||||
"deleteKeystoreLabel": "Usuń klucz",
|
"regenerateKeystoreLabel": "Usuń klucz",
|
||||||
"deleteKeystoreHint": "Usuń klucz używany do podpisywania aplikacji",
|
"regenerateKeystoreHint": "Usuń klucz używany do podpisywania aplikacji",
|
||||||
"deletedKeystore": "Klucz usunięty",
|
"regeneratedKeystore": "Klucz usunięty",
|
||||||
"deleteTempDirLabel": "Usuń pliki tymczasowe",
|
"deleteTempDirLabel": "Usuń pliki tymczasowe",
|
||||||
"deleteTempDirHint": "Usuń nieużywane pliki tymczasowe",
|
"deleteTempDirHint": "Usuń nieużywane pliki tymczasowe",
|
||||||
"deletedTempDir": "Pliki tymczasowe zostały usunięte",
|
"deletedTempDir": "Pliki tymczasowe zostały usunięte",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Nenhum aplicativo selecionado",
|
"widgetSubtitle": "Nenhum aplicativo selecionado",
|
||||||
"noAppsLabel": "Nenhum app foi encontrado",
|
"noAppsLabel": "Nenhum app foi encontrado",
|
||||||
"currentVersion": "Atual",
|
"currentVersion": "Atual",
|
||||||
"recommendedVersion": "Recomendado",
|
"recommendedVersion": "Recomendado"
|
||||||
"anyVersion": "todos"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Selecionar patches",
|
"widgetTitle": "Selecionar patches",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Registro do sentinela de erros",
|
"sentryLabel": "Registro do sentinela de erros",
|
||||||
"sentryHint": "Envie registros anônimos para nos ajudar a melhorar o ReVanced Manager",
|
"sentryHint": "Envie registros anônimos para nos ajudar a melhorar o ReVanced Manager",
|
||||||
"restartAppForChanges": "Reinicie o app para aplicar as mudanças",
|
"restartAppForChanges": "Reinicie o app para aplicar as mudanças",
|
||||||
"deleteKeystoreLabel": "Apagar registro de chaves",
|
"regenerateKeystoreLabel": "Apagar registro de chaves",
|
||||||
"deleteKeystoreHint": "Apagar o registro de chaves usado para assinar o app",
|
"regenerateKeystoreHint": "Apagar o registro de chaves usado para assinar o app",
|
||||||
"deletedKeystore": "Registro de chaves apagado",
|
"regeneratedKeystore": "Registro de chaves apagado",
|
||||||
"deleteTempDirLabel": "Apagar arquivos temporários",
|
"deleteTempDirLabel": "Apagar arquivos temporários",
|
||||||
"deleteTempDirHint": "Apagar os arquivos temporários inutilizados",
|
"deleteTempDirHint": "Apagar os arquivos temporários inutilizados",
|
||||||
"deletedTempDir": "Arquivos temporários apagados",
|
"deletedTempDir": "Arquivos temporários apagados",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Nenhuma aplicação selecionada",
|
"widgetSubtitle": "Nenhuma aplicação selecionada",
|
||||||
"noAppsLabel": "Não foram encontradas aplicações",
|
"noAppsLabel": "Não foram encontradas aplicações",
|
||||||
"currentVersion": "Atual",
|
"currentVersion": "Atual",
|
||||||
"recommendedVersion": "Recomendada",
|
"recommendedVersion": "Recomendada"
|
||||||
"anyVersion": "qualquer"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Selecionar modificações",
|
"widgetTitle": "Selecionar modificações",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Registo do coletor de erros",
|
"sentryLabel": "Registo do coletor de erros",
|
||||||
"sentryHint": "Enviar registos anónimos para nos ajudar a melhorar o ReVanced Manager",
|
"sentryHint": "Enviar registos anónimos para nos ajudar a melhorar o ReVanced Manager",
|
||||||
"restartAppForChanges": "Reinicia a aplicação para aplicar as alterações",
|
"restartAppForChanges": "Reinicia a aplicação para aplicar as alterações",
|
||||||
"deleteKeystoreLabel": "Excluir keystore",
|
"regenerateKeystoreLabel": "Excluir keystore",
|
||||||
"deleteKeystoreHint": "Excluir a keystore usada para assinar a aplicação",
|
"regenerateKeystoreHint": "Excluir a keystore usada para assinar a aplicação",
|
||||||
"deletedKeystore": "Keystore excluída",
|
"regeneratedKeystore": "Keystore excluída",
|
||||||
"deleteTempDirLabel": "Apagar arquivos temporários",
|
"deleteTempDirLabel": "Apagar arquivos temporários",
|
||||||
"deleteTempDirHint": "Apagar arquivos temporários não utilizados",
|
"deleteTempDirHint": "Apagar arquivos temporários não utilizados",
|
||||||
"deletedTempDir": "Arquivos temporários apagados",
|
"deletedTempDir": "Arquivos temporários apagados",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Nicio aplicație selectată",
|
"widgetSubtitle": "Nicio aplicație selectată",
|
||||||
"noAppsLabel": "Nu s-au găsit aplicații",
|
"noAppsLabel": "Nu s-au găsit aplicații",
|
||||||
"currentVersion": "Actual",
|
"currentVersion": "Actual",
|
||||||
"recommendedVersion": "Recomandat",
|
"recommendedVersion": "Recomandat"
|
||||||
"anyVersion": "oricare"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Selectați patch-urile",
|
"widgetTitle": "Selectați patch-urile",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Logging de Santinelă",
|
"sentryLabel": "Logging de Santinelă",
|
||||||
"sentryHint": "Trimite log-uri anonime pentru a ne ajuta să îmbunătățim ReVanced Manager",
|
"sentryHint": "Trimite log-uri anonime pentru a ne ajuta să îmbunătățim ReVanced Manager",
|
||||||
"restartAppForChanges": "Reporniți aplicația pentru a aplica modificările",
|
"restartAppForChanges": "Reporniți aplicația pentru a aplica modificările",
|
||||||
"deleteKeystoreLabel": "Ștergeți keystore-ul",
|
"regenerateKeystoreLabel": "Ștergeți keystore-ul",
|
||||||
"deleteKeystoreHint": "Ștergeți keystore-ul utilizat pentru a însemna aplicația",
|
"regenerateKeystoreHint": "Ștergeți keystore-ul utilizat pentru a însemna aplicația",
|
||||||
"deletedKeystore": "Keystore șters",
|
"regeneratedKeystore": "Keystore șters",
|
||||||
"deleteTempDirLabel": "Ștergeți fișierele temporare",
|
"deleteTempDirLabel": "Ștergeți fișierele temporare",
|
||||||
"deleteTempDirHint": "Șterge fișierele temporare neutilizate",
|
"deleteTempDirHint": "Șterge fișierele temporare neutilizate",
|
||||||
"deletedTempDir": "Fișierele temporare au fost șterse",
|
"deletedTempDir": "Fișierele temporare au fost șterse",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Не выбрано приложение",
|
"widgetSubtitle": "Не выбрано приложение",
|
||||||
"noAppsLabel": "Приложения не найдены",
|
"noAppsLabel": "Приложения не найдены",
|
||||||
"currentVersion": "Текущая",
|
"currentVersion": "Текущая",
|
||||||
"recommendedVersion": "Рекомендуемая",
|
"recommendedVersion": "Рекомендуемая"
|
||||||
"anyVersion": "любая"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Выберите патчи",
|
"widgetTitle": "Выберите патчи",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Логирование Sentry",
|
"sentryLabel": "Логирование Sentry",
|
||||||
"sentryHint": "Отправлять анонимные логи для улучшения ReVanced Manager-а",
|
"sentryHint": "Отправлять анонимные логи для улучшения ReVanced Manager-а",
|
||||||
"restartAppForChanges": "Перезапустите приложение для применения изменений",
|
"restartAppForChanges": "Перезапустите приложение для применения изменений",
|
||||||
"deleteKeystoreLabel": "Удалить хранилище ключей",
|
"regenerateKeystoreLabel": "Удалить хранилище ключей",
|
||||||
"deleteKeystoreHint": "Удалить хранилище ключей, использованных для подписи приложения",
|
"regenerateKeystoreHint": "Удалить хранилище ключей, использованных для подписи приложения",
|
||||||
"deletedKeystore": "Хранилище ключей удалено",
|
"regeneratedKeystore": "Хранилище ключей удалено",
|
||||||
"deleteTempDirLabel": "Удалить временные файлы",
|
"deleteTempDirLabel": "Удалить временные файлы",
|
||||||
"deleteTempDirHint": "Удалить неиспользуемые временные файлы",
|
"deleteTempDirHint": "Удалить неиспользуемые временные файлы",
|
||||||
"deletedTempDir": "Временные файлы удалены",
|
"deletedTempDir": "Временные файлы удалены",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Nie je vybraná žiadna aplikácia",
|
"widgetSubtitle": "Nie je vybraná žiadna aplikácia",
|
||||||
"noAppsLabel": "Nebola nájdená žiadna aplikácia",
|
"noAppsLabel": "Nebola nájdená žiadna aplikácia",
|
||||||
"currentVersion": "Aktuálne",
|
"currentVersion": "Aktuálne",
|
||||||
"recommendedVersion": "Odporúčané",
|
"recommendedVersion": "Odporúčané"
|
||||||
"anyVersion": "akákoľvek"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Vyberte záplaty",
|
"widgetTitle": "Vyberte záplaty",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Log Sentry",
|
"sentryLabel": "Log Sentry",
|
||||||
"sentryHint": "Odoslať anonymné protokoly, ktoré nám pomôžu zlepšiť ReVanced Manager",
|
"sentryHint": "Odoslať anonymné protokoly, ktoré nám pomôžu zlepšiť ReVanced Manager",
|
||||||
"restartAppForChanges": "Ak chcete použiť zmeny, reštartujte aplikáciu",
|
"restartAppForChanges": "Ak chcete použiť zmeny, reštartujte aplikáciu",
|
||||||
"deleteKeystoreLabel": "Odstrániť úložisko kľúčov",
|
"regenerateKeystoreLabel": "Odstrániť úložisko kľúčov",
|
||||||
"deleteKeystoreHint": "Odstrániť úložisko kľúčov použité na podpísanie aplikácie",
|
"regenerateKeystoreHint": "Odstrániť úložisko kľúčov použité na podpísanie aplikácie",
|
||||||
"deletedKeystore": "Úložisko kľúčov odstránené",
|
"regeneratedKeystore": "Úložisko kľúčov odstránené",
|
||||||
"deleteTempDirLabel": "Odstrániť dočasné súbory",
|
"deleteTempDirLabel": "Odstrániť dočasné súbory",
|
||||||
"deleteTempDirHint": "Odstrániť nepoužívané dočasné súbory",
|
"deleteTempDirHint": "Odstrániť nepoužívané dočasné súbory",
|
||||||
"deletedTempDir": "Dočasné súbory odstránené",
|
"deletedTempDir": "Dočasné súbory odstránené",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Nijedna aplikacija nije izabrana",
|
"widgetSubtitle": "Nijedna aplikacija nije izabrana",
|
||||||
"noAppsLabel": "Nijedna aplikacija nije pronađena",
|
"noAppsLabel": "Nijedna aplikacija nije pronađena",
|
||||||
"currentVersion": "Trenutna",
|
"currentVersion": "Trenutna",
|
||||||
"recommendedVersion": "Preporučena",
|
"recommendedVersion": "Preporučena"
|
||||||
"anyVersion": "bilo koja"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Izaberite pečeve",
|
"widgetTitle": "Izaberite pečeve",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Sentry prikupljanje grešaka",
|
"sentryLabel": "Sentry prikupljanje grešaka",
|
||||||
"sentryHint": "Pošaljite anonimnu evidenciju da biste nam pomogli da poboljšamo ReVanced Manager",
|
"sentryHint": "Pošaljite anonimnu evidenciju da biste nam pomogli da poboljšamo ReVanced Manager",
|
||||||
"restartAppForChanges": "Ponovo pokrenite aplikaciju da biste primenili promene",
|
"restartAppForChanges": "Ponovo pokrenite aplikaciju da biste primenili promene",
|
||||||
"deleteKeystoreLabel": "Izbrišite skladište ključeva",
|
"regenerateKeystoreLabel": "Izbrišite skladište ključeva",
|
||||||
"deleteKeystoreHint": "Izbrišite skladište ključeva korišćeno za potpisivanje aplikacije",
|
"regenerateKeystoreHint": "Izbrišite skladište ključeva korišćeno za potpisivanje aplikacije",
|
||||||
"deletedKeystore": "Skladište ključeva je izbrisano",
|
"regeneratedKeystore": "Skladište ključeva je izbrisano",
|
||||||
"deleteTempDirLabel": "Izbrišite privremene datoteke",
|
"deleteTempDirLabel": "Izbrišite privremene datoteke",
|
||||||
"deleteTempDirHint": "Izbrišite nekorišćene privremene datoteke",
|
"deleteTempDirHint": "Izbrišite nekorišćene privremene datoteke",
|
||||||
"deletedTempDir": "Privremene datoteke su izbrisane",
|
"deletedTempDir": "Privremene datoteke su izbrisane",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Ниједна апликација није изабрана",
|
"widgetSubtitle": "Ниједна апликација није изабрана",
|
||||||
"noAppsLabel": "Ниједна апликација није пронађена",
|
"noAppsLabel": "Ниједна апликација није пронађена",
|
||||||
"currentVersion": "Тренутна",
|
"currentVersion": "Тренутна",
|
||||||
"recommendedVersion": "Препоручена",
|
"recommendedVersion": "Препоручена"
|
||||||
"anyVersion": "било која"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Изаберите печеве",
|
"widgetTitle": "Изаберите печеве",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Sentry прикупљање грешака",
|
"sentryLabel": "Sentry прикупљање грешака",
|
||||||
"sentryHint": "Пошаљите анонимну евиденцију да бисте нам помогли да побољшамо ReVanced Manager",
|
"sentryHint": "Пошаљите анонимну евиденцију да бисте нам помогли да побољшамо ReVanced Manager",
|
||||||
"restartAppForChanges": "Поново покрените апликацију да бисте применили промене",
|
"restartAppForChanges": "Поново покрените апликацију да бисте применили промене",
|
||||||
"deleteKeystoreLabel": "Избришите складиште кључева",
|
"regenerateKeystoreLabel": "Избришите складиште кључева",
|
||||||
"deleteKeystoreHint": "Избришите складиште кључева коришћено за потписивање апликације",
|
"regenerateKeystoreHint": "Избришите складиште кључева коришћено за потписивање апликације",
|
||||||
"deletedKeystore": "Складиште кључева је избрисано",
|
"regeneratedKeystore": "Складиште кључева је избрисано",
|
||||||
"deleteTempDirLabel": "Избришите привремене датотеке",
|
"deleteTempDirLabel": "Избришите привремене датотеке",
|
||||||
"deleteTempDirHint": "Избришите некоришћене привремене датотеке",
|
"deleteTempDirHint": "Избришите некоришћене привремене датотеке",
|
||||||
"deletedTempDir": "Привремене датотеке су избрисане",
|
"deletedTempDir": "Привремене датотеке су избрисане",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "Ingen app vald",
|
"widgetSubtitle": "Ingen app vald",
|
||||||
"noAppsLabel": "Inga applikationer hittades",
|
"noAppsLabel": "Inga applikationer hittades",
|
||||||
"currentVersion": "Nuvarande",
|
"currentVersion": "Nuvarande",
|
||||||
"recommendedVersion": "Rekommenderad",
|
"recommendedVersion": "Rekommenderad"
|
||||||
"anyVersion": "alla"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Välj patchar",
|
"widgetTitle": "Välj patchar",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Sentry loggning",
|
"sentryLabel": "Sentry loggning",
|
||||||
"sentryHint": "Hjälp oss förbättra ReVanced Manager genom att skicka anonyma loggar",
|
"sentryHint": "Hjälp oss förbättra ReVanced Manager genom att skicka anonyma loggar",
|
||||||
"restartAppForChanges": "Starta om appen för att tillämpa ändringar",
|
"restartAppForChanges": "Starta om appen för att tillämpa ändringar",
|
||||||
"deleteKeystoreLabel": "Radera keystore",
|
"regenerateKeystoreLabel": "Radera keystore",
|
||||||
"deleteKeystoreHint": "Radera keystore filen som används för att signera appen",
|
"regenerateKeystoreHint": "Radera keystore filen som används för att signera appen",
|
||||||
"deletedKeystore": "Raderade keystore",
|
"regeneratedKeystore": "Raderade keystore",
|
||||||
"deleteTempDirLabel": "Ta bort temporära filer",
|
"deleteTempDirLabel": "Ta bort temporära filer",
|
||||||
"deleteTempDirHint": "Radera oanvända temporära filer",
|
"deleteTempDirHint": "Radera oanvända temporära filer",
|
||||||
"deletedTempDir": "Raderade temporära filer",
|
"deletedTempDir": "Raderade temporära filer",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Hakuna programu iliyochaguliwa",
|
"widgetSubtitle": "Hakuna programu iliyochaguliwa",
|
||||||
"noAppsLabel": "Hakuna programu zilizopatikana",
|
"noAppsLabel": "Hakuna programu zilizopatikana",
|
||||||
"currentVersion": "Sasa",
|
"currentVersion": "Sasa",
|
||||||
"recommendedVersion": "Imependekezwa",
|
"recommendedVersion": "Imependekezwa"
|
||||||
"anyVersion": "yoyote"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Chagua viraka",
|
"widgetTitle": "Chagua viraka",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Sentry logging",
|
"sentryLabel": "Sentry logging",
|
||||||
"sentryHint": "Tuma kumbukumbu bila majina ili utusaidie kuboresha Revanced Manager",
|
"sentryHint": "Tuma kumbukumbu bila majina ili utusaidie kuboresha Revanced Manager",
|
||||||
"restartAppForChanges": "Anzisha tena programu ili kutekeleza mabadiliko",
|
"restartAppForChanges": "Anzisha tena programu ili kutekeleza mabadiliko",
|
||||||
"deleteKeystoreLabel": "Futa Duka la Ufunguo",
|
"regenerateKeystoreLabel": "Futa Duka la Ufunguo",
|
||||||
"deleteKeystoreHint": "Futa Duka la Ufunguo iliyotumika kusaini programu",
|
"regenerateKeystoreHint": "Futa Duka la Ufunguo iliyotumika kusaini programu",
|
||||||
"deletedKeystore": "Duka la ufunguo imefutwa",
|
"regeneratedKeystore": "Duka la ufunguo imefutwa",
|
||||||
"deleteTempDirLabel": "Futa faili za muda",
|
"deleteTempDirLabel": "Futa faili za muda",
|
||||||
"deleteTempDirHint": "Futa faili za muda ambazo hazijatumiwa",
|
"deleteTempDirHint": "Futa faili za muda ambazo hazijatumiwa",
|
||||||
"deletedTempDir": "Faili za muda zimefutwa",
|
"deletedTempDir": "Faili za muda zimefutwa",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Hiçbir uygulama seçilmedi",
|
"widgetSubtitle": "Hiçbir uygulama seçilmedi",
|
||||||
"noAppsLabel": "Hiçbir uygulama bulunamadı",
|
"noAppsLabel": "Hiçbir uygulama bulunamadı",
|
||||||
"currentVersion": "Şu anki",
|
"currentVersion": "Şu anki",
|
||||||
"recommendedVersion": "Önerilen",
|
"recommendedVersion": "Önerilen"
|
||||||
"anyVersion": "herhangi"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Yamaları Seçin",
|
"widgetTitle": "Yamaları Seçin",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Sentry günlükleri",
|
"sentryLabel": "Sentry günlükleri",
|
||||||
"sentryHint": "ReVanced Manager'ı geliştirmemize yardımcı olmak için anonim günlükler gönderin",
|
"sentryHint": "ReVanced Manager'ı geliştirmemize yardımcı olmak için anonim günlükler gönderin",
|
||||||
"restartAppForChanges": "Değişiklikleri uygulamak için uygulamayı yeniden başlatın",
|
"restartAppForChanges": "Değişiklikleri uygulamak için uygulamayı yeniden başlatın",
|
||||||
"deleteKeystoreLabel": "Keystore'u sil",
|
"regenerateKeystoreLabel": "Keystore'u sil",
|
||||||
"deleteKeystoreHint": "Uygulamayı imzalamak için kullanılan keystore'u silin",
|
"regenerateKeystoreHint": "Uygulamayı imzalamak için kullanılan keystore'u silin",
|
||||||
"deletedKeystore": "Keystore silindi",
|
"regeneratedKeystore": "Keystore silindi",
|
||||||
"deleteTempDirLabel": "Geçici dosyaları sil",
|
"deleteTempDirLabel": "Geçici dosyaları sil",
|
||||||
"deleteTempDirHint": "Kullanılmayan geçici dosyaları sil",
|
"deleteTempDirHint": "Kullanılmayan geçici dosyaları sil",
|
||||||
"deletedTempDir": "Geçici dosyalar silindi",
|
"deletedTempDir": "Geçici dosyalar silindi",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "کوئی ایپلیکیشن منتخب نہیں",
|
"widgetSubtitle": "کوئی ایپلیکیشن منتخب نہیں",
|
||||||
"noAppsLabel": "کوئی ایپلیکیشن نہیں ملی",
|
"noAppsLabel": "کوئی ایپلیکیشن نہیں ملی",
|
||||||
"currentVersion": "موجودہ",
|
"currentVersion": "موجودہ",
|
||||||
"recommendedVersion": "تجویز کردہ",
|
"recommendedVersion": "تجویز کردہ"
|
||||||
"anyVersion": "کوئی بھی"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "پیچز منتخب کریں",
|
"widgetTitle": "پیچز منتخب کریں",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "سنتری لاگنگ",
|
"sentryLabel": "سنتری لاگنگ",
|
||||||
"sentryHint": "ریوینسڈ مینیجر کی بہتری میں مدد کے لیے گمنام لاگ بھیجیں",
|
"sentryHint": "ریوینسڈ مینیجر کی بہتری میں مدد کے لیے گمنام لاگ بھیجیں",
|
||||||
"restartAppForChanges": "تبدیلیاں دیکھنے کیلیئے اپلی کیشن کو دوبارہ چلائیں",
|
"restartAppForChanges": "تبدیلیاں دیکھنے کیلیئے اپلی کیشن کو دوبارہ چلائیں",
|
||||||
"deleteKeystoreLabel": "ڈیلیٹ کی سٹور",
|
"regenerateKeystoreLabel": "ڈیلیٹ کی سٹور",
|
||||||
"deleteKeystoreHint": "ایپ پر دستخط کرنے کے لیے استعمال ہونے والے کی اسٹور کو ڈیلیٹ کریں",
|
"regenerateKeystoreHint": "ایپ پر دستخط کرنے کے لیے استعمال ہونے والے کی اسٹور کو ڈیلیٹ کریں",
|
||||||
"deletedKeystore": "کی اسٹور حذف ہو گیا ہے",
|
"regeneratedKeystore": "کی اسٹور حذف ہو گیا ہے",
|
||||||
"deleteTempDirLabel": "عارضی فائلوں کو حذف کریں",
|
"deleteTempDirLabel": "عارضی فائلوں کو حذف کریں",
|
||||||
"deleteTempDirHint": "غیر استعمال شدہ عارضی فائلوں کو حذف کریں",
|
"deleteTempDirHint": "غیر استعمال شدہ عارضی فائلوں کو حذف کریں",
|
||||||
"deletedTempDir": "عارضی فائلیں حذف کردی گئی",
|
"deletedTempDir": "عارضی فائلیں حذف کردی گئی",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "Chưa chọn ứng dụng nào",
|
"widgetSubtitle": "Chưa chọn ứng dụng nào",
|
||||||
"noAppsLabel": "Không tìm thấy ứng dụng nào",
|
"noAppsLabel": "Không tìm thấy ứng dụng nào",
|
||||||
"currentVersion": "Hiện tại",
|
"currentVersion": "Hiện tại",
|
||||||
"recommendedVersion": "Đề xuất",
|
"recommendedVersion": "Đề xuất"
|
||||||
"anyVersion": "bất kỳ"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "Chọn bản vá",
|
"widgetTitle": "Chọn bản vá",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "Nhật ký theo dõi",
|
"sentryLabel": "Nhật ký theo dõi",
|
||||||
"sentryHint": "Gửi nhật ký ẩn danh để giúp chúng tôi cải thiện ReVanced Manager",
|
"sentryHint": "Gửi nhật ký ẩn danh để giúp chúng tôi cải thiện ReVanced Manager",
|
||||||
"restartAppForChanges": "Khởi động lại ứng dụng để áp dụng thay đổi",
|
"restartAppForChanges": "Khởi động lại ứng dụng để áp dụng thay đổi",
|
||||||
"deleteKeystoreLabel": "Xóa kho khóa",
|
"regenerateKeystoreLabel": "Xóa kho khóa",
|
||||||
"deleteKeystoreHint": "Xóa kho khóa dùng để ký ứng dụng",
|
"regenerateKeystoreHint": "Xóa kho khóa dùng để ký ứng dụng",
|
||||||
"deletedKeystore": "Kho khóa đã xóa",
|
"regeneratedKeystore": "Kho khóa đã xóa",
|
||||||
"deleteTempDirLabel": "Xóa tệp tạm thời",
|
"deleteTempDirLabel": "Xóa tệp tạm thời",
|
||||||
"deleteTempDirHint": "Xóa các tệp tạm thời không sử dụng",
|
"deleteTempDirHint": "Xóa các tệp tạm thời không sử dụng",
|
||||||
"deletedTempDir": "Đã xóa các tệp tạm thời",
|
"deletedTempDir": "Đã xóa các tệp tạm thời",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "未选择应用程序",
|
"widgetSubtitle": "未选择应用程序",
|
||||||
"noAppsLabel": "未发现应用程序。",
|
"noAppsLabel": "未发现应用程序。",
|
||||||
"currentVersion": "当前",
|
"currentVersion": "当前",
|
||||||
"recommendedVersion": "推荐",
|
"recommendedVersion": "推荐"
|
||||||
"anyVersion": "任意"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "选择补丁",
|
"widgetTitle": "选择补丁",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "哨兵日志",
|
"sentryLabel": "哨兵日志",
|
||||||
"sentryHint": "发送匿名日志以帮助我们改进ReVanced Manager",
|
"sentryHint": "发送匿名日志以帮助我们改进ReVanced Manager",
|
||||||
"restartAppForChanges": "重启应用以生效",
|
"restartAppForChanges": "重启应用以生效",
|
||||||
"deleteKeystoreLabel": "删除密钥存储",
|
"regenerateKeystoreLabel": "删除密钥存储",
|
||||||
"deleteKeystoreHint": "删除用于签名应用的密钥存储",
|
"regenerateKeystoreHint": "删除用于签名应用的密钥存储",
|
||||||
"deletedKeystore": "密钥存储已删除",
|
"regeneratedKeystore": "密钥存储已删除",
|
||||||
"deleteTempDirLabel": "删除临时文件",
|
"deleteTempDirLabel": "删除临时文件",
|
||||||
"deleteTempDirHint": "删除未使用的临时文件",
|
"deleteTempDirHint": "删除未使用的临时文件",
|
||||||
"deletedTempDir": "临时文件已删除",
|
"deletedTempDir": "临时文件已删除",
|
||||||
|
@ -54,8 +54,7 @@
|
|||||||
"widgetSubtitle": "沒有選擇應用程式",
|
"widgetSubtitle": "沒有選擇應用程式",
|
||||||
"noAppsLabel": "找不到應用程式",
|
"noAppsLabel": "找不到應用程式",
|
||||||
"currentVersion": "目前版本",
|
"currentVersion": "目前版本",
|
||||||
"recommendedVersion": "推薦版本",
|
"recommendedVersion": "推薦版本"
|
||||||
"anyVersion": "任何版本"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "選擇補丁",
|
"widgetTitle": "選擇補丁",
|
||||||
@ -144,9 +143,9 @@
|
|||||||
"sentryLabel": "Sentry 日志記錄",
|
"sentryLabel": "Sentry 日志記錄",
|
||||||
"sentryHint": "發送匿名的日志記錄以幫助我們改善 ReVanced Manager",
|
"sentryHint": "發送匿名的日志記錄以幫助我們改善 ReVanced Manager",
|
||||||
"restartAppForChanges": "重啓應用以套用變更",
|
"restartAppForChanges": "重啓應用以套用變更",
|
||||||
"deleteKeystoreLabel": "刪除 keystore",
|
"regenerateKeystoreLabel": "刪除 keystore",
|
||||||
"deleteKeystoreHint": "刪除登入程序已用的 keystore",
|
"regenerateKeystoreHint": "刪除登入程序已用的 keystore",
|
||||||
"deletedKeystore": "已刪除 keystore",
|
"regeneratedKeystore": "已刪除 keystore",
|
||||||
"deleteTempDirLabel": "刪除暫時文件",
|
"deleteTempDirLabel": "刪除暫時文件",
|
||||||
"deleteTempDirHint": "刪除無用暫時文件",
|
"deleteTempDirHint": "刪除無用暫時文件",
|
||||||
"deletedTempDir": "暫時文件已刪除",
|
"deletedTempDir": "暫時文件已刪除",
|
||||||
|
@ -55,8 +55,7 @@
|
|||||||
"widgetSubtitle": "未選取應用程式",
|
"widgetSubtitle": "未選取應用程式",
|
||||||
"noAppsLabel": "找不到應用程式",
|
"noAppsLabel": "找不到應用程式",
|
||||||
"currentVersion": "目前",
|
"currentVersion": "目前",
|
||||||
"recommendedVersion": "建議",
|
"recommendedVersion": "建議"
|
||||||
"anyVersion": "任何"
|
|
||||||
},
|
},
|
||||||
"patchSelectorCard": {
|
"patchSelectorCard": {
|
||||||
"widgetTitle": "選取修補檔",
|
"widgetTitle": "選取修補檔",
|
||||||
@ -148,9 +147,9 @@
|
|||||||
"sentryLabel": "輸入記錄",
|
"sentryLabel": "輸入記錄",
|
||||||
"sentryHint": "傳送匿名記錄以協助我們改進 ReVanced Manager",
|
"sentryHint": "傳送匿名記錄以協助我們改進 ReVanced Manager",
|
||||||
"restartAppForChanges": "重新啟動應用程式以套用變更",
|
"restartAppForChanges": "重新啟動應用程式以套用變更",
|
||||||
"deleteKeystoreLabel": "刪除金鑰儲存區",
|
"regenerateKeystoreLabel": "刪除金鑰儲存區",
|
||||||
"deleteKeystoreHint": "刪除用於登入應用程式的金鑰儲存區",
|
"regenerateKeystoreHint": "刪除用於登入應用程式的金鑰儲存區",
|
||||||
"deletedKeystore": "已刪除金鑰儲存區",
|
"regeneratedKeystore": "已刪除金鑰儲存區",
|
||||||
"deleteTempDirLabel": "刪除暫存檔案",
|
"deleteTempDirLabel": "刪除暫存檔案",
|
||||||
"deleteTempDirHint": "刪除未使用的暫存檔案",
|
"deleteTempDirHint": "刪除未使用的暫存檔案",
|
||||||
"deletedTempDir": "暫存檔案目錄",
|
"deletedTempDir": "暫存檔案目錄",
|
||||||
|
@ -11,6 +11,6 @@ In order to use ReVanced Manager, certain requirements must be met.
|
|||||||
|
|
||||||
## ⏭️ What's next
|
## ⏭️ What's next
|
||||||
|
|
||||||
The next page will guide you through patching an application.
|
The next page will guide you through patching an app.
|
||||||
|
|
||||||
Continue: [⬇️ Installation](1_installation.md)
|
Continue: [⬇️ Installation](1_installation.md)
|
||||||
|
@ -4,11 +4,11 @@ In order to use ReVanced on your Android device, ReVanced Manager must be instal
|
|||||||
|
|
||||||
## 🪜 Installation steps
|
## 🪜 Installation steps
|
||||||
|
|
||||||
- Download the latest version of ReVanced Manager from [here](https://github.com/revanced/revanced-manager/releases/latest)
|
1. Download the latest version of ReVanced Manager from [here](https://github.com/revanced/revanced-manager/releases/latest)
|
||||||
- Install ReVanced Manager
|
2. Install ReVanced Manager
|
||||||
|
|
||||||
## ⏭️ What's next
|
## ⏭️ What's next
|
||||||
|
|
||||||
The next page will guide you through patching an application.
|
The next page will guide you through using ReVanced Manager.
|
||||||
|
|
||||||
Continue: [🪛 Usage](2_usage.md)
|
Continue: [🪛 Usage](2_usage.md)
|
||||||
|
@ -1,26 +1,24 @@
|
|||||||
# 🧩 Patching applications
|
# 🧩 Patching apps
|
||||||
|
|
||||||
The following pages will guide you through using ReVanced Manager to patch applications.
|
The following pages will guide you through using ReVanced Manager to patch apps.
|
||||||
|
|
||||||
## 🪜 Steps to patch applications
|
## 🪜 Steps to patch apps
|
||||||
|
|
||||||
1. Navigate to the **Patcher** tab from the bottom navigation bar
|
1. Navigate to the **Patcher** tab from the bottom navigation bar
|
||||||
2. Tap on the **Select an application** card
|
2. Tap on the **Select an app** card
|
||||||
3. Choose an application to patch[^1]
|
3. Choose an app to patch[^1]
|
||||||
> **Note**: The application version suggested by ReVanced Manager is visible in each application's card. This is important in step 5. below, as most patches are compatible with this version.
|
> **Note**: The suggested version is visible in each app's card.
|
||||||
4. Tap on the **Select patches** card and select the patches you want to apply[^2]
|
4. Tap on the **Select patches** card and select the patches you want to apply[^2]
|
||||||
> **Warning**: If you see a warning icon next to a patch, it means that the patch is not compatible with the application version you selected in step 3. above. In this case, you should either go back and select a different application version or deselect the patch.
|
> **Warning**: If you see a warning you can click on it for more information.
|
||||||
5. Tap on the **Done** button to confirm your selection
|
5. Tap on the **Done** then **Patch** button
|
||||||
6. Tap on the **Patch** button to start patching
|
> **Warning**: The patching process may take ~5 minutes. Exiting the app may increase the time it takes to patch.
|
||||||
> **Warning**: The patching process can take anywhere from 2 to 5 minutes depending on your device. Refrain from exiting ReVanced Manager while the process is still running, otherwise the patching time will increase significantly.
|
6. Tap on the **Install** button
|
||||||
7. After patching is complete, tap on the **Install** button to install the patched application
|
> **Note**: If you are rooted, you can mount the patched app on top of the original app.[^3]
|
||||||
> **Note**: If you have root access on your device, you may have the option to mount the patched application on top of the original application.[^4]
|
> Optionally, you may export the patched app to storage using the options in the top right corner.
|
||||||
> Optionally, you may tap on the three vertical dots in the top right to export the patched application to storage.
|
|
||||||
|
|
||||||
[^1]: You may be prompted to select an application from storage in case you have no root access on your device. In this case, select the APK file from your device storage.[^3]
|
[^1]: Non-root users may be prompted to select an APK from storage, in which case you have to source the APK file yourself. ReVanced does not provide any APK files.
|
||||||
[^2]: It is suggested to use the default set of patches by tapping on the **Default** chip above the list of patches.
|
[^2]: It is suggested to use the default set of patches by tapping on the **Default** button above the list of patches.
|
||||||
[^3]: You can obtain `.apk` files from sites such as [APKMirror](https://www.apkmirror.com/).
|
[^3]: Mounting the patched app on top of the original app will only work if the installed app version matches the version of the app selected in step 3. above.
|
||||||
[^4]: Mounting the patched application on top of the original application will only work if the installed application version matches the version of the application selected in step 3. above.
|
|
||||||
|
|
||||||
## ⏭️ What's next
|
## ⏭️ What's next
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
# 🧰 Managing patched applications
|
# 🧰 Managing patched apps
|
||||||
|
|
||||||
After patching an application, you may want to manage it. This page will guide you through managing patched applications.
|
After patching an app, you may want to manage it. This page will guide you through managing patched apps.
|
||||||
|
|
||||||
## 🪜 Steps to manage patched applications
|
## 🪜 Steps to manage patched apps
|
||||||
|
|
||||||
1. Tap on the **Dashboard** tab in the bottom navigation bar
|
1. Tap on the **Dashboard** tab in the bottom navigation bar
|
||||||
2. Select the **Installed** chip
|
2. Select the **Installed** chip
|
||||||
3. Tap on the **Info** button for the application you want to manage
|
3. Tap on the **Info** button for the app you want to manage
|
||||||
4. Choose one of the options from the menu
|
4. Choose one of the options from the menu
|
||||||
|
|
||||||
## ⏭️ What's next
|
## ⏭️ What's next
|
||||||
|
@ -14,15 +14,15 @@ ReVanced Manager has settings that can be configured to your liking.
|
|||||||
|
|
||||||
- ### 🧪 Experimental ReVanced Patches support
|
- ### 🧪 Experimental ReVanced Patches support
|
||||||
|
|
||||||
Lift application version constraints from ReVanced Patches. This allows you to patch any version of an application, even if the patch is not explicitly compatible with it.
|
Lift app version constraints from ReVanced Patches. This allows you to patch any version of an app, even if the patch is not explicitly compatible with it.
|
||||||
|
|
||||||
- ### 🧑🔬 Experimental universal support
|
- ### 🧑🔬 Experimental universal support
|
||||||
|
|
||||||
This will show or hide ReVanced Patches, which are not meant for any application in particular but rather for all applications but may not work on all applications.
|
This will show or hide ReVanced Patches, which are not meant for any app in particular but rather for all apps but may not work on all apps.
|
||||||
|
|
||||||
- ### 🔑 Export, import or delete keystore
|
- ### 🔑 Export, import or delete keystore
|
||||||
|
|
||||||
Manage the keystore used to sign patched applications.
|
Manage the keystore used to sign patched apps.
|
||||||
|
|
||||||
- ### 📄 Export, import or reset ReVanced Patches selection
|
- ### 📄 Export, import or reset ReVanced Patches selection
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
# 🛠️ Usage
|
# 🛠️ Usage
|
||||||
|
|
||||||
The following pages will guide you through using ReVanced Manager to patch applications, manage patched applications, and update ReVanced Manager.
|
The following pages will guide you through using ReVanced Manager to patch apps, manage patched apps, and update ReVanced Manager.
|
||||||
|
|
||||||
## 📖 Table of contents
|
## 📖 Table of contents
|
||||||
|
|
||||||
1. [🧩 Patching applications](2_1_patching.md)
|
1. [🧩 Patching apps](2_1_patching.md)
|
||||||
2. [🧰 Managing patched applications](2_2_managing.md)
|
2. [🧰 Managing patched apps](2_2_managing.md)
|
||||||
3. [🔄 Updating ReVanced Manager](2_3_updating.md)
|
3. [🔄 Updating ReVanced Manager](2_3_updating.md)
|
||||||
4. [⚙️ Configuring ReVanced Manager](2_4_settings.md)
|
4. [⚙️ Configuring ReVanced Manager](2_4_settings.md)
|
||||||
|
|
||||||
|
@ -2,23 +2,27 @@
|
|||||||
|
|
||||||
In case you encounter any issues while using ReVanced Manager, please refer to this page for possible solutions.
|
In case you encounter any issues while using ReVanced Manager, please refer to this page for possible solutions.
|
||||||
|
|
||||||
- ### 💥 App not installed as package conflicts with an existing package
|
- 💉 Patching fails with an error
|
||||||
|
|
||||||
An existing installation of the application you're trying to patch is conflicting with the patched application. Uninstall the existing application before installing the patched application.
|
Make sure ReVanced Manager is up to date by following [🔄 Updating ReVanced Manager](2_3_updating.md) and select the **Default** button when choosing patches.
|
||||||
|
|
||||||
|
- 💥 App not installed as package conflicts with an existing package
|
||||||
|
|
||||||
- ### ❗️Error code `135`, `139` or `1` when patching the application
|
An existing installation of the app you're trying to patch is conflicting with the patched app. Uninstall the existing app before installing the patched app.
|
||||||
|
|
||||||
|
- ❗️ Error code `135`, `139` or `1` when patching the app
|
||||||
|
|
||||||
Your device is not supported. Refer to the [Prerequisites](0_prerequisites.md) page for supported devices.
|
Your device is not supported. Refer to the [Prerequisites](0_prerequisites.md) page for supported devices.
|
||||||
|
|
||||||
Alternatively, you can use [ReVanced CLI](https://github.com/revanced/revanced-cli) to patch the application.
|
Alternatively, you can use [ReVanced CLI](https://github.com/revanced/revanced-cli) to patch the app.
|
||||||
|
|
||||||
- ### 🚫 Non-root install is not possible with the current patches selection
|
- 🚫 Non-root install is not possible with the current patches selection
|
||||||
|
|
||||||
Select the **Default** chip when choosing patches.
|
Select the **Default** button when choosing patches.
|
||||||
|
|
||||||
- ### 🚨 Patched application crashes on launch
|
- 🚨 Patched app crashes on launch
|
||||||
|
|
||||||
Select the **Default** chip when choosing patches.
|
Select the **Default** button when choosing patches.
|
||||||
|
|
||||||
## ⏭️ What's next
|
## ⏭️ What's next
|
||||||
|
|
||||||
|
@ -7,9 +7,15 @@ This documentation explains how to use [ReVanced Manager](https://github.com/rev
|
|||||||
0. [💼 Prerequisites](0_prerequisites.md)
|
0. [💼 Prerequisites](0_prerequisites.md)
|
||||||
1. [⬇️ Installation](1_installation.md)
|
1. [⬇️ Installation](1_installation.md)
|
||||||
2. [🛠️ Usage](2_usage.md)
|
2. [🛠️ Usage](2_usage.md)
|
||||||
1. [🧩 Patching applications](2_1_patching.md)
|
1. [🧩 Patching apps](2_1_patching.md)
|
||||||
2. [🧰 Managing patched applications](2_2_managing.md)
|
2. [🧰 Managing patched apps](2_2_managing.md)
|
||||||
3. [🔄 Updating ReVanced Manager](2_3_updating.md)
|
3. [🔄 Updating ReVanced Manager](2_3_updating.md)
|
||||||
4. [⚙️ Configuring ReVanced Manager](2_4_settings.md)
|
4. [⚙️ Configuring ReVanced Manager](2_4_settings.md)
|
||||||
3. [🛟 Troubleshooting](3_troubleshooting.md)
|
3. [🛟 Troubleshooting](3_troubleshooting.md)
|
||||||
4. [🛠 Building from source](4_building.md)
|
4. [🛠 Building from source](4_building.md)
|
||||||
|
|
||||||
|
## ⏭️ Start here
|
||||||
|
|
||||||
|
The next page will tell you about the prerequisites for using ReVanced Manager.
|
||||||
|
|
||||||
|
Continue: [💼 Prerequisites](0_prerequisites.md)
|
||||||
|
@ -1 +1 @@
|
|||||||
Patch your favourite apps, right on your device.
|
Patch your favorite apps, right on your device.
|
||||||
|
@ -8,7 +8,6 @@ class Patch {
|
|||||||
Patch({
|
Patch({
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.description,
|
required this.description,
|
||||||
required this.version,
|
|
||||||
required this.excluded,
|
required this.excluded,
|
||||||
required this.dependencies,
|
required this.dependencies,
|
||||||
required this.compatiblePackages,
|
required this.compatiblePackages,
|
||||||
@ -17,7 +16,6 @@ class Patch {
|
|||||||
factory Patch.fromJson(Map<String, dynamic> json) => _$PatchFromJson(json);
|
factory Patch.fromJson(Map<String, dynamic> json) => _$PatchFromJson(json);
|
||||||
final String name;
|
final String name;
|
||||||
final String description;
|
final String description;
|
||||||
final String version;
|
|
||||||
final bool excluded;
|
final bool excluded;
|
||||||
final List<String> dependencies;
|
final List<String> dependencies;
|
||||||
final List<Package> compatiblePackages;
|
final List<Package> compatiblePackages;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
|
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
|
||||||
@ -8,6 +7,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
import 'package:revanced_manager/models/patch.dart';
|
import 'package:revanced_manager/models/patch.dart';
|
||||||
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
|
|
||||||
@lazySingleton
|
@lazySingleton
|
||||||
class GithubAPI {
|
class GithubAPI {
|
||||||
@ -72,6 +72,41 @@ class GithubAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>?> getLatestManagerRelease(
|
||||||
|
String repoName,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final response = await _dio.get(
|
||||||
|
'/repos/$repoName/releases',
|
||||||
|
);
|
||||||
|
final Map<String, dynamic> releases = response.data[0];
|
||||||
|
int updates = 0;
|
||||||
|
final String currentVersion =
|
||||||
|
await ManagerAPI().getCurrentManagerVersion();
|
||||||
|
while (response.data[updates]['tag_name'] != 'v$currentVersion') {
|
||||||
|
updates++;
|
||||||
|
}
|
||||||
|
for (int i = 1; i < updates; i++) {
|
||||||
|
releases.update(
|
||||||
|
'body',
|
||||||
|
(value) =>
|
||||||
|
value +
|
||||||
|
'\n' +
|
||||||
|
'# ' +
|
||||||
|
response.data[i]['tag_name'] +
|
||||||
|
'\n' +
|
||||||
|
response.data[i]['body'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return releases;
|
||||||
|
} on Exception catch (e) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<String>> getCommits(
|
Future<List<String>> getCommits(
|
||||||
String packageName,
|
String packageName,
|
||||||
String repoName,
|
String repoName,
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:app_installer/app_installer.dart';
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:cr_file_saver/file_saver.dart';
|
import 'package:cr_file_saver/file_saver.dart';
|
||||||
import 'package:device_apps/device_apps.dart';
|
import 'package:device_apps/device_apps.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
|
import 'package:install_plugin/install_plugin.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/models/patch.dart';
|
import 'package:revanced_manager/models/patch.dart';
|
||||||
@ -144,30 +144,9 @@ class PatcherAPI {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getOriginalFilePath(
|
|
||||||
String packageName,
|
|
||||||
String originalFilePath,
|
|
||||||
) async {
|
|
||||||
try {
|
|
||||||
final bool hasRootPermissions = await _rootAPI.hasRootPermissions();
|
|
||||||
if (hasRootPermissions) {
|
|
||||||
originalFilePath = await _rootAPI.getOriginalFilePath(
|
|
||||||
packageName,
|
|
||||||
originalFilePath,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return originalFilePath;
|
|
||||||
} on Exception catch (e) {
|
|
||||||
if (kDebugMode) {
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
return originalFilePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> runPatcher(
|
Future<void> runPatcher(
|
||||||
String packageName,
|
String packageName,
|
||||||
String originalFilePath,
|
String apkFilePath,
|
||||||
List<Patch> selectedPatches,
|
List<Patch> selectedPatches,
|
||||||
) async {
|
) async {
|
||||||
final bool includeSettings = await needsSettingsPatch(selectedPatches);
|
final bool includeSettings = await needsSettingsPatch(selectedPatches);
|
||||||
@ -198,15 +177,13 @@ class PatcherAPI {
|
|||||||
_outFile = File('${workDir.path}/out.apk');
|
_outFile = File('${workDir.path}/out.apk');
|
||||||
final Directory cacheDir = Directory('${workDir.path}/cache');
|
final Directory cacheDir = Directory('${workDir.path}/cache');
|
||||||
cacheDir.createSync();
|
cacheDir.createSync();
|
||||||
|
final String originalFilePath = apkFilePath;
|
||||||
try {
|
try {
|
||||||
await patcherChannel.invokeMethod(
|
await patcherChannel.invokeMethod(
|
||||||
'runPatcher',
|
'runPatcher',
|
||||||
{
|
{
|
||||||
'patchBundleFilePath': patchBundleFile.path,
|
'patchBundleFilePath': patchBundleFile.path,
|
||||||
'originalFilePath': await getOriginalFilePath(
|
'originalFilePath': originalFilePath,
|
||||||
packageName,
|
|
||||||
originalFilePath,
|
|
||||||
),
|
|
||||||
'inputFilePath': inputFile.path,
|
'inputFilePath': inputFile.path,
|
||||||
'patchedFilePath': patchedFile.path,
|
'patchedFilePath': patchedFile.path,
|
||||||
'outFilePath': _outFile!.path,
|
'outFilePath': _outFile!.path,
|
||||||
@ -238,10 +215,8 @@ class PatcherAPI {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await AppInstaller.installApk(_outFile!.path);
|
final install = await InstallPlugin.installApk(_outFile!.path);
|
||||||
return await DeviceApps.isAppInstalled(
|
return install['isSuccess'];
|
||||||
patchedApp.packageName,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
|
@ -140,7 +140,8 @@ class RevancedAPI {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamController<double> managerUpdateProgress = StreamController<double>();
|
StreamController<double> managerUpdateProgress =
|
||||||
|
StreamController<double>.broadcast();
|
||||||
|
|
||||||
void updateManagerDownloadProgress(int progress) {
|
void updateManagerDownloadProgress(int progress) {
|
||||||
managerUpdateProgress.add(progress.toDouble());
|
managerUpdateProgress.add(progress.toDouble());
|
||||||
@ -170,6 +171,7 @@ class RevancedAPI {
|
|||||||
|
|
||||||
updateManagerDownloadProgress(progress);
|
updateManagerDownloadProgress(progress);
|
||||||
} else if (result is FileInfo) {
|
} else if (result is FileInfo) {
|
||||||
|
disposeManagerUpdateProgress();
|
||||||
// The download is complete; convert the FileInfo object to a File object
|
// The download is complete; convert the FileInfo object to a File object
|
||||||
outputFile = File(result.file.path);
|
outputFile = File(result.file.path);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:root/root.dart';
|
import 'package:root/root.dart';
|
||||||
|
|
||||||
class RootAPI {
|
class RootAPI {
|
||||||
final String _managerDirPath = '/data/local/tmp/revanced-manager';
|
// TODO(ponces): remove in the future, keep it for now during migration.
|
||||||
|
final String _revancedOldDirPath = '/data/local/tmp/revanced-manager';
|
||||||
|
final String _revancedDirPath = '/data/adb/revanced';
|
||||||
final String _postFsDataDirPath = '/data/adb/post-fs-data.d';
|
final String _postFsDataDirPath = '/data/adb/post-fs-data.d';
|
||||||
final String _serviceDDirPath = '/data/adb/service.d';
|
final String _serviceDDirPath = '/data/adb/service.d';
|
||||||
|
|
||||||
@ -40,55 +42,62 @@ class RootAPI {
|
|||||||
seLinux,
|
seLinux,
|
||||||
String filePath,
|
String filePath,
|
||||||
) async {
|
) async {
|
||||||
if (permissions.isNotEmpty) {
|
|
||||||
await Root.exec(
|
|
||||||
cmd: 'chmod $permissions "$filePath"',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (ownerGroup.isNotEmpty) {
|
|
||||||
await Root.exec(
|
|
||||||
cmd: 'chown $ownerGroup "$filePath"',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (seLinux.isNotEmpty) {
|
|
||||||
await Root.exec(
|
|
||||||
cmd: 'chcon $seLinux "$filePath"',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isAppInstalled(String packageName) async {
|
|
||||||
if (packageName.isNotEmpty) {
|
|
||||||
String? res = await Root.exec(
|
|
||||||
cmd: 'ls "$_managerDirPath/$packageName"',
|
|
||||||
);
|
|
||||||
if (res != null && res.isNotEmpty) {
|
|
||||||
res = await Root.exec(
|
|
||||||
cmd: 'ls "$_serviceDDirPath/$packageName.sh"',
|
|
||||||
);
|
|
||||||
return res != null && res.isNotEmpty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<String>> getInstalledApps() async {
|
|
||||||
try {
|
try {
|
||||||
final String? res = await Root.exec(
|
if (permissions.isNotEmpty) {
|
||||||
cmd: 'ls "$_managerDirPath"',
|
await Root.exec(
|
||||||
);
|
cmd: 'chmod $permissions "$filePath"',
|
||||||
if (res != null) {
|
);
|
||||||
final List<String> apps = res.split('\n');
|
}
|
||||||
apps.removeWhere((pack) => pack.isEmpty);
|
if (ownerGroup.isNotEmpty) {
|
||||||
return apps.map((pack) => pack.trim()).toList();
|
await Root.exec(
|
||||||
|
cmd: 'chown $ownerGroup "$filePath"',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (seLinux.isNotEmpty) {
|
||||||
|
await Root.exec(
|
||||||
|
cmd: 'chcon $seLinux "$filePath"',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e);
|
print(e);
|
||||||
}
|
}
|
||||||
return List.empty();
|
|
||||||
}
|
}
|
||||||
return List.empty();
|
}
|
||||||
|
|
||||||
|
Future<bool> isAppInstalled(String packageName) async {
|
||||||
|
if (packageName.isNotEmpty) {
|
||||||
|
return fileExists('$_serviceDDirPath/$packageName.sh');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<String>> getInstalledApps() async {
|
||||||
|
final List<String> apps = List.empty(growable: true);
|
||||||
|
try {
|
||||||
|
String? res = await Root.exec(
|
||||||
|
cmd: 'ls "$_revancedDirPath"',
|
||||||
|
);
|
||||||
|
if (res != null) {
|
||||||
|
final List<String> list = res.split('\n');
|
||||||
|
list.removeWhere((pack) => pack.isEmpty);
|
||||||
|
apps.addAll(list.map((pack) => pack.trim()).toList());
|
||||||
|
}
|
||||||
|
// TODO(ponces): remove in the future, keep it for now during migration.
|
||||||
|
res = await Root.exec(
|
||||||
|
cmd: 'ls "$_revancedOldDirPath"',
|
||||||
|
);
|
||||||
|
if (res != null) {
|
||||||
|
final List<String> list = res.split('\n');
|
||||||
|
list.removeWhere((pack) => pack.isEmpty);
|
||||||
|
apps.addAll(list.map((pack) => pack.trim()).toList());
|
||||||
|
}
|
||||||
|
} on Exception catch (e) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apps;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteApp(String packageName, String originalFilePath) async {
|
Future<void> deleteApp(String packageName, String originalFilePath) async {
|
||||||
@ -98,8 +107,12 @@ class RootAPI {
|
|||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'su -mm -c "umount -l $originalFilePath"',
|
cmd: 'su -mm -c "umount -l $originalFilePath"',
|
||||||
);
|
);
|
||||||
|
// TODO(ponces): remove in the future, keep it for now during migration.
|
||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'rm -rf "$_managerDirPath/$packageName"',
|
cmd: 'rm -rf "$_revancedOldDirPath/$packageName"',
|
||||||
|
);
|
||||||
|
await Root.exec(
|
||||||
|
cmd: 'rm -rf "$_revancedDirPath/$packageName"',
|
||||||
);
|
);
|
||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'rm -rf "$_serviceDDirPath/$packageName.sh"',
|
cmd: 'rm -rf "$_serviceDDirPath/$packageName.sh"',
|
||||||
@ -117,13 +130,13 @@ class RootAPI {
|
|||||||
try {
|
try {
|
||||||
await deleteApp(packageName, originalFilePath);
|
await deleteApp(packageName, originalFilePath);
|
||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'mkdir -p "$_managerDirPath/$packageName"',
|
cmd: 'mkdir -p "$_revancedDirPath/$packageName"',
|
||||||
);
|
);
|
||||||
await setPermissions(
|
await setPermissions(
|
||||||
'0755',
|
'0755',
|
||||||
'shell:shell',
|
'shell:shell',
|
||||||
'',
|
'',
|
||||||
'$_managerDirPath/$packageName',
|
'$_revancedDirPath/$packageName',
|
||||||
);
|
);
|
||||||
await saveOriginalFilePath(packageName, originalFilePath);
|
await saveOriginalFilePath(packageName, originalFilePath);
|
||||||
await installServiceDScript(packageName);
|
await installServiceDScript(packageName);
|
||||||
@ -142,7 +155,7 @@ class RootAPI {
|
|||||||
Future<void> installServiceDScript(String packageName) async {
|
Future<void> installServiceDScript(String packageName) async {
|
||||||
final String content = '#!/system/bin/sh\n'
|
final String content = '#!/system/bin/sh\n'
|
||||||
'while [ "\$(getprop sys.boot_completed | tr -d \'"\'"\'\\\\r\'"\'"\')" != "1" ]; do sleep 3; done\n'
|
'while [ "\$(getprop sys.boot_completed | tr -d \'"\'"\'\\\\r\'"\'"\')" != "1" ]; do sleep 3; done\n'
|
||||||
'base_path=$_managerDirPath/$packageName/base.apk\n'
|
'base_path=$_revancedDirPath/$packageName/base.apk\n'
|
||||||
'stock_path=\$(pm path $packageName | grep base | sed \'"\'"\'s/package://g\'"\'"\')\n'
|
'stock_path=\$(pm path $packageName | grep base | sed \'"\'"\'s/package://g\'"\'"\')\n'
|
||||||
r'[ ! -z $stock_path ] && mount -o bind $base_path $stock_path';
|
r'[ ! -z $stock_path ] && mount -o bind $base_path $stock_path';
|
||||||
final String scriptFilePath = '$_serviceDDirPath/$packageName.sh';
|
final String scriptFilePath = '$_serviceDDirPath/$packageName.sh';
|
||||||
@ -164,7 +177,7 @@ class RootAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> installApk(String packageName, String patchedFilePath) async {
|
Future<void> installApk(String packageName, String patchedFilePath) async {
|
||||||
final String newPatchedFilePath = '$_managerDirPath/$packageName/base.apk';
|
final String newPatchedFilePath = '$_revancedDirPath/$packageName/base.apk';
|
||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'cp "$patchedFilePath" "$newPatchedFilePath"',
|
cmd: 'cp "$patchedFilePath" "$newPatchedFilePath"',
|
||||||
);
|
);
|
||||||
@ -177,7 +190,7 @@ class RootAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> mountApk(String packageName, String originalFilePath) async {
|
Future<void> mountApk(String packageName, String originalFilePath) async {
|
||||||
final String newPatchedFilePath = '$_managerDirPath/$packageName/base.apk';
|
final String newPatchedFilePath = '$_revancedDirPath/$packageName/base.apk';
|
||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'am force-stop "$packageName"',
|
cmd: 'am force-stop "$packageName"',
|
||||||
);
|
);
|
||||||
@ -196,37 +209,20 @@ class RootAPI {
|
|||||||
return res != null && res.isNotEmpty;
|
return res != null && res.isNotEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getOriginalFilePath(
|
|
||||||
String packageName,
|
|
||||||
String originalFilePath,
|
|
||||||
) async {
|
|
||||||
final bool isInstalled = await isAppInstalled(packageName);
|
|
||||||
if (isInstalled && await isMounted(packageName)) {
|
|
||||||
originalFilePath = '$_managerDirPath/$packageName/original.apk';
|
|
||||||
await setPermissions(
|
|
||||||
'0644',
|
|
||||||
'shell:shell',
|
|
||||||
'u:object_r:apk_data_file:s0',
|
|
||||||
originalFilePath,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return originalFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> saveOriginalFilePath(
|
Future<void> saveOriginalFilePath(
|
||||||
String packageName,
|
String packageName,
|
||||||
String originalFilePath,
|
String originalFilePath,
|
||||||
) async {
|
) async {
|
||||||
final String originalRootPath =
|
final String originalRootPath =
|
||||||
'$_managerDirPath/$packageName/original.apk';
|
'$_revancedDirPath/$packageName/original.apk';
|
||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'mkdir -p "$_managerDirPath/$packageName"',
|
cmd: 'mkdir -p "$_revancedDirPath/$packageName"',
|
||||||
);
|
);
|
||||||
await setPermissions(
|
await setPermissions(
|
||||||
'0755',
|
'0755',
|
||||||
'shell:shell',
|
'shell:shell',
|
||||||
'',
|
'',
|
||||||
'$_managerDirPath/$packageName',
|
'$_revancedDirPath/$packageName',
|
||||||
);
|
);
|
||||||
await Root.exec(
|
await Root.exec(
|
||||||
cmd: 'cp "$originalFilePath" "$originalRootPath"',
|
cmd: 'cp "$originalFilePath" "$originalRootPath"',
|
||||||
@ -238,4 +234,18 @@ class RootAPI {
|
|||||||
originalFilePath,
|
originalFilePath,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> fileExists(String path) async {
|
||||||
|
try {
|
||||||
|
final String? res = await Root.exec(
|
||||||
|
cmd: 'ls $path',
|
||||||
|
);
|
||||||
|
return res != null && res.isNotEmpty;
|
||||||
|
} on Exception catch (e) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: model.apps.isEmpty
|
: model.allApps.isEmpty
|
||||||
? const AppSkeletonLoader()
|
? const AppSkeletonLoader()
|
||||||
: Padding(
|
: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0)
|
padding: const EdgeInsets.symmetric(horizontal: 12.0)
|
||||||
@ -113,7 +113,9 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||||||
),
|
),
|
||||||
installedVersion: app.versionName!,
|
installedVersion: app.versionName!,
|
||||||
onTap: () => model.canSelectInstalled(
|
onTap: () => model.canSelectInstalled(
|
||||||
context, app.packageName),
|
context,
|
||||||
|
app.packageName,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
|
@ -45,9 +45,7 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
.length
|
.length
|
||||||
.compareTo(_patcherAPI.getFilteredPatches(a.packageName).length),
|
.compareTo(_patcherAPI.getFilteredPatches(a.packageName).length),
|
||||||
);
|
);
|
||||||
noApps = apps.isEmpty;
|
|
||||||
getAllApps();
|
getAllApps();
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ class AppSelectorViewModel extends BaseViewModel {
|
|||||||
.toSet()
|
.toSet()
|
||||||
.where((name) => !apps.any((app) => app.packageName == name))
|
.where((name) => !apps.any((app) => app.packageName == name))
|
||||||
.toList();
|
.toList();
|
||||||
|
noApps = allApps.isEmpty;
|
||||||
return allApps;
|
return allApps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:app_installer/app_installer.dart';
|
|
||||||
import 'package:cross_connectivity/cross_connectivity.dart';
|
import 'package:cross_connectivity/cross_connectivity.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
import 'package:flutter_i18n/flutter_i18n.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
|
import 'package:install_plugin/install_plugin.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/app/app.router.dart';
|
import 'package:revanced_manager/app/app.router.dart';
|
||||||
@ -39,6 +38,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
List<PatchedApplication> patchedInstalledApps = [];
|
List<PatchedApplication> patchedInstalledApps = [];
|
||||||
List<PatchedApplication> patchedUpdatableApps = [];
|
List<PatchedApplication> patchedUpdatableApps = [];
|
||||||
String? _latestManagerVersion = '';
|
String? _latestManagerVersion = '';
|
||||||
|
File? downloadedApk;
|
||||||
|
|
||||||
Future<void> initialize(BuildContext context) async {
|
Future<void> initialize(BuildContext context) async {
|
||||||
_latestManagerVersion = await _managerAPI.getLatestManagerVersion();
|
_latestManagerVersion = await _managerAPI.getLatestManagerVersion();
|
||||||
@ -51,7 +51,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
_toast.showBottom('homeView.installingMessage');
|
_toast.showBottom('homeView.installingMessage');
|
||||||
final File? managerApk = await _managerAPI.downloadManager();
|
final File? managerApk = await _managerAPI.downloadManager();
|
||||||
if (managerApk != null) {
|
if (managerApk != null) {
|
||||||
await AppInstaller.installApk(managerApk.path);
|
await InstallPlugin.installApk(managerApk.path);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('homeView.errorDownloadMessage');
|
_toast.showBottom('homeView.errorDownloadMessage');
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
_toast.showBottom('homeView.installingMessage');
|
_toast.showBottom('homeView.installingMessage');
|
||||||
final File? managerApk = await _managerAPI.downloadManager();
|
final File? managerApk = await _managerAPI.downloadManager();
|
||||||
if (managerApk != null) {
|
if (managerApk != null) {
|
||||||
await AppInstaller.installApk(managerApk.path);
|
await InstallPlugin.installApk(managerApk.path);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('homeView.errorDownloadMessage');
|
_toast.showBottom('homeView.errorDownloadMessage');
|
||||||
}
|
}
|
||||||
@ -112,13 +112,15 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
|
|
||||||
Future<bool> hasManagerUpdates() async {
|
Future<bool> hasManagerUpdates() async {
|
||||||
String currentVersion = await _managerAPI.getCurrentManagerVersion();
|
String currentVersion = await _managerAPI.getCurrentManagerVersion();
|
||||||
_latestManagerVersion = await _managerAPI.getLatestManagerVersion();
|
|
||||||
|
|
||||||
// add v to current version
|
// add v to current version
|
||||||
if (!currentVersion.startsWith('v')) {
|
if (!currentVersion.startsWith('v')) {
|
||||||
currentVersion = 'v$currentVersion';
|
currentVersion = 'v$currentVersion';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_latestManagerVersion =
|
||||||
|
await _managerAPI.getLatestManagerVersion() ?? currentVersion;
|
||||||
|
|
||||||
if (_latestManagerVersion != currentVersion) {
|
if (_latestManagerVersion != currentVersion) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -162,74 +164,135 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateManager(BuildContext context) async {
|
Future<void> updateManager(BuildContext context) async {
|
||||||
|
final ValueNotifier<bool> downloaded = ValueNotifier(false);
|
||||||
try {
|
try {
|
||||||
_toast.showBottom('homeView.downloadingMessage');
|
_toast.showBottom('homeView.downloadingMessage');
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => SimpleDialog(
|
builder: (context) => ValueListenableBuilder(
|
||||||
contentPadding: const EdgeInsets.all(16.0),
|
valueListenable: downloaded,
|
||||||
title: I18nText(
|
builder: (context, value, child) {
|
||||||
'homeView.downloadingMessage',
|
return SimpleDialog(
|
||||||
child: Text(
|
contentPadding: const EdgeInsets.all(16.0),
|
||||||
'',
|
title: I18nText(
|
||||||
style: TextStyle(
|
!value
|
||||||
fontSize: 20,
|
? 'homeView.downloadingMessage'
|
||||||
fontWeight: FontWeight.w500,
|
: 'homeView.downloadedMessage',
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
child: Text(
|
||||||
),
|
'',
|
||||||
),
|
style: TextStyle(
|
||||||
),
|
fontSize: 20,
|
||||||
children: [
|
fontWeight: FontWeight.w500,
|
||||||
Column(
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.new_releases_outlined,
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8.0),
|
|
||||||
Text(
|
|
||||||
'$_latestManagerVersion',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16.0),
|
|
||||||
StreamBuilder<double>(
|
|
||||||
initialData: 0.0,
|
|
||||||
stream: _revancedAPI.managerUpdateProgress.stream,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
return LinearProgressIndicator(
|
|
||||||
value: snapshot.data! * 0.01,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16.0),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: CustomMaterialButton(
|
|
||||||
label: I18nText('cancelButton'),
|
|
||||||
onPressed: () {
|
|
||||||
_revancedAPI.disposeManagerUpdateProgress();
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.new_releases_outlined,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8.0),
|
||||||
|
Text(
|
||||||
|
'$_latestManagerVersion',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16.0),
|
||||||
|
if (!value)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
StreamBuilder<double>(
|
||||||
|
initialData: 0.0,
|
||||||
|
stream: _revancedAPI.managerUpdateProgress.stream,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
return LinearProgressIndicator(
|
||||||
|
value: snapshot.data! * 0.01,
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16.0),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: CustomMaterialButton(
|
||||||
|
label: I18nText('cancelButton'),
|
||||||
|
onPressed: () {
|
||||||
|
_revancedAPI.disposeManagerUpdateProgress();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (value)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
I18nText(
|
||||||
|
'homeView.installUpdate',
|
||||||
|
child: Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16.0),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: CustomMaterialButton(
|
||||||
|
isFilled: false,
|
||||||
|
label: I18nText('cancelButton'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8.0),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: CustomMaterialButton(
|
||||||
|
label: I18nText('updateButton'),
|
||||||
|
onPressed: () async {
|
||||||
|
await InstallPlugin.installApk(
|
||||||
|
downloadedApk!.path,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
],
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final File? managerApk = await downloadManager();
|
final File? managerApk = await downloadManager();
|
||||||
if (managerApk != null) {
|
if (managerApk != null) {
|
||||||
|
downloaded.value = true;
|
||||||
|
downloadedApk = managerApk;
|
||||||
// await flutterLocalNotificationsPlugin.zonedSchedule(
|
// await flutterLocalNotificationsPlugin.zonedSchedule(
|
||||||
// 0,
|
// 0,
|
||||||
// FlutterI18n.translate(
|
// FlutterI18n.translate(
|
||||||
@ -255,7 +318,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
// UILocalNotificationDateInterpretation.absoluteTime,
|
// UILocalNotificationDateInterpretation.absoluteTime,
|
||||||
// );
|
// );
|
||||||
_toast.showBottom('homeView.installingMessage');
|
_toast.showBottom('homeView.installingMessage');
|
||||||
await AppInstaller.installApk(managerApk.path);
|
await InstallPlugin.installApk(managerApk.path);
|
||||||
} else {
|
} else {
|
||||||
_toast.showBottom('homeView.errorDownloadMessage');
|
_toast.showBottom('homeView.errorDownloadMessage');
|
||||||
}
|
}
|
||||||
@ -285,7 +348,7 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>?> getLatestManagerRelease() {
|
Future<Map<String, dynamic>?> getLatestManagerRelease() {
|
||||||
return _githubAPI.getLatestRelease(_managerAPI.defaultManagerRepo);
|
return _githubAPI.getLatestManagerRelease(_managerAPI.defaultManagerRepo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestPatcherReleaseTime() {
|
Future<String?> getLatestPatcherReleaseTime() {
|
||||||
|
@ -166,7 +166,7 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
try {
|
try {
|
||||||
_app.isRooted = installAsRoot;
|
_app.isRooted = installAsRoot;
|
||||||
final bool hasMicroG =
|
final bool hasMicroG =
|
||||||
_patches.any((p) => p.name.endsWith('microg-support'));
|
_patches.any((p) => p.name.endsWith('MicroG support'));
|
||||||
final bool rootMicroG = installAsRoot && hasMicroG;
|
final bool rootMicroG = installAsRoot && hasMicroG;
|
||||||
final bool rootFromStorage = installAsRoot && _app.isFromStorage;
|
final bool rootFromStorage = installAsRoot && _app.isFromStorage;
|
||||||
final bool ytWithoutRootMicroG =
|
final bool ytWithoutRootMicroG =
|
||||||
|
@ -13,55 +13,68 @@ class NavigationView extends StatelessWidget {
|
|||||||
return ViewModelBuilder<NavigationViewModel>.reactive(
|
return ViewModelBuilder<NavigationViewModel>.reactive(
|
||||||
onViewModelReady: (model) => model.initialize(context),
|
onViewModelReady: (model) => model.initialize(context),
|
||||||
viewModelBuilder: () => locator<NavigationViewModel>(),
|
viewModelBuilder: () => locator<NavigationViewModel>(),
|
||||||
builder: (context, model, child) => Scaffold(
|
builder: (context, model, child) => WillPopScope(
|
||||||
body: PageTransitionSwitcher(
|
onWillPop: () async {
|
||||||
duration: const Duration(milliseconds: 400),
|
if (model.currentIndex == 0) {
|
||||||
transitionBuilder: (
|
return true;
|
||||||
Widget child,
|
} else {
|
||||||
Animation<double> animation,
|
model.setIndex(0);
|
||||||
Animation<double> secondaryAnimation,
|
return false;
|
||||||
) {
|
}
|
||||||
return FadeThroughTransition(
|
},
|
||||||
animation: animation,
|
child: Scaffold(
|
||||||
secondaryAnimation: secondaryAnimation,
|
body: PageTransitionSwitcher(
|
||||||
fillColor: Theme.of(context).colorScheme.surface,
|
duration: const Duration(milliseconds: 400),
|
||||||
child: child,
|
transitionBuilder: (
|
||||||
);
|
Widget child,
|
||||||
},
|
Animation<double> animation,
|
||||||
child: model.getViewForIndex(model.currentIndex),
|
Animation<double> secondaryAnimation,
|
||||||
),
|
) {
|
||||||
bottomNavigationBar: NavigationBar(
|
return FadeThroughTransition(
|
||||||
onDestinationSelected: model.setIndex,
|
animation: animation,
|
||||||
selectedIndex: model.currentIndex,
|
secondaryAnimation: secondaryAnimation,
|
||||||
destinations: <Widget>[
|
fillColor: Theme.of(context).colorScheme.surface,
|
||||||
NavigationDestination(
|
child: child,
|
||||||
icon: model.isIndexSelected(0)
|
);
|
||||||
? const Icon(Icons.dashboard)
|
},
|
||||||
: const Icon(Icons.dashboard_outlined),
|
child: model.getViewForIndex(model.currentIndex),
|
||||||
label: FlutterI18n.translate(
|
),
|
||||||
context,
|
bottomNavigationBar: NavigationBar(
|
||||||
'navigationView.dashboardTab',
|
onDestinationSelected: model.setIndex,
|
||||||
|
selectedIndex: model.currentIndex,
|
||||||
|
destinations: <Widget>[
|
||||||
|
NavigationDestination(
|
||||||
|
icon: model.isIndexSelected(0)
|
||||||
|
? const Icon(Icons.dashboard)
|
||||||
|
: const Icon(Icons.dashboard_outlined),
|
||||||
|
label: FlutterI18n.translate(
|
||||||
|
context,
|
||||||
|
'navigationView.dashboardTab',
|
||||||
|
),
|
||||||
|
tooltip: '',
|
||||||
),
|
),
|
||||||
),
|
NavigationDestination(
|
||||||
NavigationDestination(
|
icon: model.isIndexSelected(1)
|
||||||
icon: model.isIndexSelected(1)
|
? const Icon(Icons.build)
|
||||||
? const Icon(Icons.build)
|
: const Icon(Icons.build_outlined),
|
||||||
: const Icon(Icons.build_outlined),
|
label: FlutterI18n.translate(
|
||||||
label: FlutterI18n.translate(
|
context,
|
||||||
context,
|
'navigationView.patcherTab',
|
||||||
'navigationView.patcherTab',
|
),
|
||||||
|
tooltip: '',
|
||||||
),
|
),
|
||||||
),
|
NavigationDestination(
|
||||||
NavigationDestination(
|
icon: model.isIndexSelected(2)
|
||||||
icon: model.isIndexSelected(2)
|
? const Icon(Icons.settings)
|
||||||
? const Icon(Icons.settings)
|
: const Icon(Icons.settings_outlined),
|
||||||
: const Icon(Icons.settings_outlined),
|
label: FlutterI18n.translate(
|
||||||
label: FlutterI18n.translate(
|
context,
|
||||||
context,
|
'navigationView.settingsTab',
|
||||||
'navigationView.settingsTab',
|
),
|
||||||
|
tooltip: '',
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -18,6 +18,8 @@ class NavigationViewModel extends IndexTrackingViewModel {
|
|||||||
Future<void> initialize(BuildContext context) async {
|
Future<void> initialize(BuildContext context) async {
|
||||||
locator<Toast>().initialize(context);
|
locator<Toast>().initialize(context);
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
requestManageExternalStorage();
|
||||||
|
|
||||||
if (prefs.getBool('permissionsRequested') == null) {
|
if (prefs.getBool('permissionsRequested') == null) {
|
||||||
await Permission.storage.request();
|
await Permission.storage.request();
|
||||||
await Permission.manageExternalStorage.request();
|
await Permission.manageExternalStorage.request();
|
||||||
@ -28,6 +30,7 @@ class NavigationViewModel extends IndexTrackingViewModel {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefs.getBool('useDarkTheme') == null) {
|
if (prefs.getBool('useDarkTheme') == null) {
|
||||||
final bool isDark =
|
final bool isDark =
|
||||||
MediaQuery.of(context).platformBrightness != Brightness.light;
|
MediaQuery.of(context).platformBrightness != Brightness.light;
|
||||||
@ -46,6 +49,17 @@ class NavigationViewModel extends IndexTrackingViewModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> requestManageExternalStorage() async {
|
||||||
|
final manageExternalStorageStatus =
|
||||||
|
await Permission.manageExternalStorage.status;
|
||||||
|
if (manageExternalStorageStatus.isDenied) {
|
||||||
|
await Permission.manageExternalStorage.request();
|
||||||
|
}
|
||||||
|
if (manageExternalStorageStatus.isPermanentlyDenied) {
|
||||||
|
await openAppSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Widget getViewForIndex(int index) {
|
Widget getViewForIndex(int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -64,7 +64,7 @@ class PatcherViewModel extends BaseViewModel {
|
|||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: I18nText('warning'),
|
||||||
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
content: I18nText('patcherView.armv7WarningDialogText'),
|
content: I18nText('patcherView.splitApkWarningDialogText'),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
CustomMaterialButton(
|
CustomMaterialButton(
|
||||||
label: I18nText('noButton'),
|
label: I18nText('noButton'),
|
||||||
@ -133,7 +133,7 @@ class PatcherViewModel extends BaseViewModel {
|
|||||||
if (suggestedVersion.isEmpty) {
|
if (suggestedVersion.isEmpty) {
|
||||||
suggestedVersion = FlutterI18n.translate(
|
suggestedVersion = FlutterI18n.translate(
|
||||||
context,
|
context,
|
||||||
'appSelectorCard.anyVersion',
|
'appSelectorCard.allVersions',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
suggestedVersion = 'v$suggestedVersion';
|
suggestedVersion = 'v$suggestedVersion';
|
||||||
|
@ -166,7 +166,6 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||||||
(patch) => PatchItem(
|
(patch) => PatchItem(
|
||||||
name: patch.name,
|
name: patch.name,
|
||||||
simpleName: patch.getSimpleName(),
|
simpleName: patch.getSimpleName(),
|
||||||
version: patch.version,
|
|
||||||
description: patch.description,
|
description: patch.description,
|
||||||
packageVersion: model.getAppVersion(),
|
packageVersion: model.getAppVersion(),
|
||||||
supportedPackageVersions:
|
supportedPackageVersions:
|
||||||
|
@ -93,7 +93,9 @@ class SManageApiUrl extends BaseViewModel {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
_managerAPI.setApiUrl('');
|
_managerAPI.setApiUrl('');
|
||||||
_toast.showBottom('settingsView.restartAppForChanges');
|
_toast.showBottom('settingsView.restartAppForChanges');
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context)
|
||||||
|
..pop()
|
||||||
|
..pop();
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -17,8 +17,7 @@ import 'package:stacked/stacked.dart';
|
|||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
|
||||||
class SettingsViewModel extends BaseViewModel {
|
class SettingsViewModel extends BaseViewModel {
|
||||||
final NavigationService _navigationService =
|
final NavigationService _navigationService = locator<NavigationService>();
|
||||||
locator<NavigationService>();
|
|
||||||
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
||||||
final Toast _toast = locator<Toast>();
|
final Toast _toast = locator<Toast>();
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
|
|
||||||
void deleteKeystore() {
|
void deleteKeystore() {
|
||||||
_managerAPI.deleteKeystore();
|
_managerAPI.deleteKeystore();
|
||||||
_toast.showBottom('settingsView.deletedKeystore');
|
_toast.showBottom('settingsView.regeneratedKeystore');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,11 +62,8 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
try {
|
try {
|
||||||
final File outFile = File(_managerAPI.storedPatchesFile);
|
final File outFile = File(_managerAPI.storedPatchesFile);
|
||||||
if (outFile.existsSync()) {
|
if (outFile.existsSync()) {
|
||||||
final String dateTime = DateTime.now()
|
final String dateTime =
|
||||||
.toString()
|
DateTime.now().toString().replaceAll(' ', '_').split('.').first;
|
||||||
.replaceAll(' ', '_')
|
|
||||||
.split('.')
|
|
||||||
.first;
|
|
||||||
await CRFileSaver.saveFileWithDialog(
|
await CRFileSaver.saveFileWithDialog(
|
||||||
SaveFileDialogParams(
|
SaveFileDialogParams(
|
||||||
sourceFilePath: outFile.path,
|
sourceFilePath: outFile.path,
|
||||||
@ -87,8 +83,7 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
|
|
||||||
Future<void> importPatches() async {
|
Future<void> importPatches() async {
|
||||||
try {
|
try {
|
||||||
final FilePickerResult? result =
|
final FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||||
await FilePicker.platform.pickFiles(
|
|
||||||
type: FileType.custom,
|
type: FileType.custom,
|
||||||
allowedExtensions: ['json'],
|
allowedExtensions: ['json'],
|
||||||
);
|
);
|
||||||
@ -109,7 +104,7 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> exportKeystore() async {
|
Future<void> exportKeystore() async {
|
||||||
try {
|
try {
|
||||||
final File outFile = File(_managerAPI.keystoreFile);
|
final File outFile = File(_managerAPI.keystoreFile);
|
||||||
if (outFile.existsSync()) {
|
if (outFile.existsSync()) {
|
||||||
@ -138,7 +133,7 @@ class SettingsViewModel extends BaseViewModel {
|
|||||||
if (result != null && result.files.single.path != null) {
|
if (result != null && result.files.single.path != null) {
|
||||||
final File inFile = File(result.files.single.path!);
|
final File inFile = File(result.files.single.path!);
|
||||||
inFile.copySync(_managerAPI.keystoreFile);
|
inFile.copySync(_managerAPI.keystoreFile);
|
||||||
|
|
||||||
_toast.showBottom('settingsView.importedKeystore');
|
_toast.showBottom('settingsView.importedKeystore');
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
import 'package:skeletons/skeletons.dart';
|
import 'package:skeletons/skeletons.dart';
|
||||||
|
|
||||||
class AppSkeletonLoader extends StatelessWidget {
|
class AppSkeletonLoader extends StatelessWidget {
|
||||||
@ -7,59 +8,67 @@ class AppSkeletonLoader extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
return Skeleton(
|
return ListView.builder(
|
||||||
isLoading: true,
|
shrinkWrap: true,
|
||||||
skeleton: ListView.builder(
|
itemCount: 7,
|
||||||
shrinkWrap: true,
|
padding: EdgeInsets.zero,
|
||||||
itemCount: 7,
|
itemBuilder: (context, index) => Padding(
|
||||||
itemBuilder: (context, index) => Padding(
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12.0),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8.0),
|
child: CustomCard(
|
||||||
child: SkeletonItem(
|
child: Row(
|
||||||
child: Row(
|
children: [
|
||||||
children: <Widget>[
|
SkeletonAvatar(
|
||||||
SkeletonAvatar(
|
style: SkeletonAvatarStyle(
|
||||||
style: SkeletonAvatarStyle(
|
width: screenWidth * 0.10,
|
||||||
width: screenWidth * 0.15,
|
height: screenWidth * 0.10,
|
||||||
height: screenWidth * 0.15,
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(
|
||||||
|
width: screenWidth * 0.4,
|
||||||
|
child: SkeletonLine(
|
||||||
|
style: SkeletonLineStyle(
|
||||||
|
height: 20,
|
||||||
|
width: screenWidth * 0.4,
|
||||||
|
borderRadius:
|
||||||
|
const BorderRadius.all(Radius.circular(10)),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 12),
|
||||||
const SizedBox(width: 16),
|
SizedBox(
|
||||||
Column(
|
width: screenWidth * 0.6,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: SkeletonLine(
|
||||||
children: <Widget>[
|
style: SkeletonLineStyle(
|
||||||
Container(
|
height: 15,
|
||||||
color: Colors.white,
|
width: screenWidth * 0.6,
|
||||||
height: 34,
|
borderRadius:
|
||||||
width: screenWidth * 0.4,
|
const BorderRadius.all(Radius.circular(10)),
|
||||||
child: SkeletonParagraph(
|
|
||||||
style: const SkeletonParagraphStyle(
|
|
||||||
lines: 1,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
),
|
||||||
Container(
|
const SizedBox(height: 5),
|
||||||
margin: const EdgeInsets.only(bottom: 4),
|
SizedBox(
|
||||||
color: Colors.white,
|
width: screenWidth * 0.5,
|
||||||
height: 34,
|
child: SkeletonLine(
|
||||||
width: screenWidth * 0.6,
|
style: SkeletonLineStyle(
|
||||||
child: SkeletonParagraph(
|
height: 15,
|
||||||
style: const SkeletonParagraphStyle(
|
width: screenWidth * 0.5,
|
||||||
lines: 1,
|
borderRadius:
|
||||||
),
|
const BorderRadius.all(Radius.circular(10)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Center(
|
|
||||||
child: Text('Content'),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
import 'package:flutter_i18n/flutter_i18n.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
@ -52,46 +51,49 @@ class _InstalledAppItemState extends State<InstalledAppItem> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Text(
|
||||||
children: [
|
widget.name,
|
||||||
Text(
|
maxLines: 2,
|
||||||
widget.name,
|
overflow: TextOverflow.visible,
|
||||||
maxLines: 2,
|
style: const TextStyle(
|
||||||
overflow: TextOverflow.visible,
|
fontSize: 16,
|
||||||
style: const TextStyle(
|
fontWeight: FontWeight.w500,
|
||||||
fontSize: 16,
|
),
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
I18nText(
|
|
||||||
widget.installedVersion.isEmpty
|
|
||||||
? 'All versions'
|
|
||||||
: 'v${widget.installedVersion}',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
Text(widget.pkgName),
|
Text(widget.pkgName),
|
||||||
|
I18nText(
|
||||||
|
FlutterI18n.translate(
|
||||||
|
context,
|
||||||
|
'installed',
|
||||||
|
translationParams: {
|
||||||
|
'version': 'v${widget.installedVersion}'
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
I18nText(
|
||||||
FlutterI18n.translate(
|
'suggested',
|
||||||
context,
|
translationParams: {
|
||||||
'suggested',
|
'version': widget.suggestedVersion.isEmpty
|
||||||
translationParams: {
|
? FlutterI18n.translate(
|
||||||
'version': widget.suggestedVersion.isEmpty
|
context,
|
||||||
? 'All versions'
|
'appSelectorCard.allVersions',
|
||||||
: 'v${widget.suggestedVersion}'
|
)
|
||||||
},
|
: 'v${widget.suggestedVersion}',
|
||||||
),
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Flexible(
|
||||||
widget.patchesCount == 1
|
child: Text(
|
||||||
? '• ${widget.patchesCount} patch'
|
widget.patchesCount == 1
|
||||||
: '• ${widget.patchesCount} patches',
|
? '• ${widget.patchesCount} patch'
|
||||||
style: TextStyle(
|
: '• ${widget.patchesCount} patches',
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_i18n/flutter_i18n.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
|
|
||||||
class NotInstalledAppItem extends StatefulWidget {
|
class NotInstalledAppItem extends StatefulWidget {
|
||||||
@ -54,20 +55,39 @@ class _NotInstalledAppItem extends State<NotInstalledAppItem> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
const Text('App not installed.'),
|
I18nText(
|
||||||
const SizedBox(height: 4),
|
'appSelectorCard.notInstalled',
|
||||||
|
child: Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).textTheme.titleLarge!.color,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
I18nText(
|
||||||
'Suggested: ${widget.suggestedVersion.isEmpty ? 'All versions' : 'v${widget.suggestedVersion}'}',
|
'suggested',
|
||||||
|
translationParams: {
|
||||||
|
'version': widget.suggestedVersion.isEmpty
|
||||||
|
? FlutterI18n.translate(
|
||||||
|
context,
|
||||||
|
'appSelectorCard.allVersions',
|
||||||
|
)
|
||||||
|
: 'v${widget.suggestedVersion}',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Flexible(
|
||||||
widget.patchesCount == 1
|
child: Text(
|
||||||
? '• ${widget.patchesCount} patch'
|
widget.patchesCount == 1
|
||||||
: '• ${widget.patchesCount} patches',
|
? '• ${widget.patchesCount} patch'
|
||||||
style: TextStyle(
|
: '• ${widget.patchesCount} patches',
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,61 +1,96 @@
|
|||||||
|
import 'package:device_apps/device_apps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/flutter_i18n.dart';
|
import 'package:flutter_i18n/flutter_i18n.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/models/patched_application.dart';
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/application_item.dart';
|
import 'package:revanced_manager/ui/widgets/shared/application_item.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
|
|
||||||
|
//ignore: must_be_immutable
|
||||||
class InstalledAppsCard extends StatelessWidget {
|
class InstalledAppsCard extends StatelessWidget {
|
||||||
InstalledAppsCard({Key? key}) : super(key: key);
|
InstalledAppsCard({Key? key}) : super(key: key);
|
||||||
|
|
||||||
final List<PatchedApplication> apps =
|
List<PatchedApplication> apps = locator<HomeViewModel>().patchedInstalledApps;
|
||||||
locator<HomeViewModel>().patchedInstalledApps;
|
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
||||||
|
List<PatchedApplication> patchedApps = [];
|
||||||
|
|
||||||
|
Future _getApps() async {
|
||||||
|
if (apps.isNotEmpty) {
|
||||||
|
patchedApps = [...apps];
|
||||||
|
for (final element in apps) {
|
||||||
|
await DeviceApps.getApp(element.packageName).then((value) {
|
||||||
|
if (element.version != value?.versionName) {
|
||||||
|
patchedApps.remove(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (apps.length != patchedApps.length) {
|
||||||
|
await _managerAPI.setPatchedApps(patchedApps);
|
||||||
|
apps.clear();
|
||||||
|
apps = [...patchedApps];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return apps.isEmpty
|
return FutureBuilder(
|
||||||
? CustomCard(
|
future: _getApps(),
|
||||||
child: Center(
|
builder: (context, snapshot) {
|
||||||
child: Column(
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
children: <Widget>[
|
return apps.isEmpty
|
||||||
Icon(
|
? CustomCard(
|
||||||
size: 40,
|
child: Center(
|
||||||
Icons.file_download_off,
|
child: Column(
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
children: <Widget>[
|
||||||
),
|
Icon(
|
||||||
const SizedBox(height: 16),
|
size: 40,
|
||||||
I18nText(
|
Icons.file_download_off,
|
||||||
'homeView.noInstallations',
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
child: Text(
|
),
|
||||||
'',
|
const SizedBox(height: 16),
|
||||||
textAlign: TextAlign.center,
|
I18nText(
|
||||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
'homeView.noInstallations',
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
child: Text(
|
||||||
|
'',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium!
|
||||||
|
.copyWith(
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: ListView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
|
||||||
children: apps
|
|
||||||
.map(
|
|
||||||
(app) => ApplicationItem(
|
|
||||||
icon: app.icon,
|
|
||||||
name: app.name,
|
|
||||||
patchDate: app.patchDate,
|
|
||||||
changelog: app.changelog,
|
|
||||||
isUpdatableApp: false,
|
|
||||||
onPressed: () =>
|
|
||||||
locator<HomeViewModel>().navigateToAppInfo(app),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList(),
|
: ListView(
|
||||||
);
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
children: apps
|
||||||
|
.map(
|
||||||
|
(app) => ApplicationItem(
|
||||||
|
icon: app.icon,
|
||||||
|
name: app.name,
|
||||||
|
patchDate: app.patchDate,
|
||||||
|
changelog: app.changelog,
|
||||||
|
isUpdatableApp: false,
|
||||||
|
onPressed: () =>
|
||||||
|
locator<HomeViewModel>().navigateToAppInfo(app),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,7 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment:
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
I18nText(
|
||||||
'homeView.updateDialogTitle',
|
'homeView.updateDialogTitle',
|
||||||
@ -63,14 +62,12 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
Icons.new_releases_outlined,
|
Icons.new_releases_outlined,
|
||||||
color: Theme.of(context)
|
color:
|
||||||
.colorScheme
|
Theme.of(context).colorScheme.secondary,
|
||||||
.secondary,
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8.0),
|
const SizedBox(width: 8.0),
|
||||||
Text(
|
Text(
|
||||||
snapshot.data!['tag_name'] ??
|
snapshot.data!['tag_name'] ?? 'Unknown',
|
||||||
'Unknown',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -96,8 +93,7 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(left: 24.0, bottom: 12.0),
|
||||||
const EdgeInsets.only(left: 24.0, bottom: 12.0),
|
|
||||||
child: I18nText(
|
child: I18nText(
|
||||||
'homeView.updateChangelogTitle',
|
'homeView.updateChangelogTitle',
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -113,12 +109,9 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
margin:
|
margin: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||||
const EdgeInsets.symmetric(horizontal: 24.0),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
.colorScheme
|
|
||||||
.secondaryContainer,
|
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
child: Markdown(
|
child: Markdown(
|
||||||
|
@ -59,7 +59,7 @@ class PatchSelectorCard extends StatelessWidget {
|
|||||||
String _getPatchesSelection() {
|
String _getPatchesSelection() {
|
||||||
String text = '';
|
String text = '';
|
||||||
for (final Patch p in locator<PatcherViewModel>().selectedPatches) {
|
for (final Patch p in locator<PatcherViewModel>().selectedPatches) {
|
||||||
text += '\u2022 ${p.getSimpleName()} (v${p.version})\n';
|
text += '\u2022 ${p.getSimpleName()}\n';
|
||||||
}
|
}
|
||||||
return text.substring(0, text.length - 1);
|
return text.substring(0, text.length - 1);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter_i18n/flutter_i18n.dart';
|
|||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
import 'package:revanced_manager/services/manager_api.dart';
|
import 'package:revanced_manager/services/manager_api.dart';
|
||||||
import 'package:revanced_manager/services/toast.dart';
|
import 'package:revanced_manager/services/toast.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_patches.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||||
|
|
||||||
@ -13,7 +14,6 @@ class PatchItem extends StatefulWidget {
|
|||||||
required this.name,
|
required this.name,
|
||||||
required this.simpleName,
|
required this.simpleName,
|
||||||
required this.description,
|
required this.description,
|
||||||
required this.version,
|
|
||||||
required this.packageVersion,
|
required this.packageVersion,
|
||||||
required this.supportedPackageVersions,
|
required this.supportedPackageVersions,
|
||||||
required this.isUnsupported,
|
required this.isUnsupported,
|
||||||
@ -24,7 +24,6 @@ class PatchItem extends StatefulWidget {
|
|||||||
final String name;
|
final String name;
|
||||||
final String simpleName;
|
final String simpleName;
|
||||||
final String description;
|
final String description;
|
||||||
final String version;
|
|
||||||
final String packageVersion;
|
final String packageVersion;
|
||||||
final List<String> supportedPackageVersions;
|
final List<String> supportedPackageVersions;
|
||||||
final bool isUnsupported;
|
final bool isUnsupported;
|
||||||
@ -41,137 +40,140 @@ class PatchItem extends StatefulWidget {
|
|||||||
class _PatchItemState extends State<PatchItem> {
|
class _PatchItemState extends State<PatchItem> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
widget.isSelected = widget.isSelected &&
|
||||||
|
(!widget.isUnsupported ||
|
||||||
|
widget._managerAPI.areExperimentalPatchesEnabled());
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
child: CustomCard(
|
child: Opacity(
|
||||||
backgroundColor: widget.isUnsupported &&
|
opacity: widget.isUnsupported &&
|
||||||
widget._managerAPI.areExperimentalPatchesEnabled() == false
|
widget._managerAPI.areExperimentalPatchesEnabled() == false
|
||||||
? Theme.of(context).colorScheme.brightness == Brightness.light
|
? 0.5
|
||||||
? Colors.grey[400]
|
: 1,
|
||||||
: Colors.grey[700]
|
child: CustomCard(
|
||||||
: null,
|
onTap: () {
|
||||||
onTap: () {
|
setState(() {
|
||||||
setState(() {
|
if (widget.isUnsupported &&
|
||||||
if (widget.isUnsupported &&
|
!widget._managerAPI.areExperimentalPatchesEnabled()) {
|
||||||
!widget._managerAPI.areExperimentalPatchesEnabled()) {
|
widget.isSelected = false;
|
||||||
widget.isSelected = false;
|
widget.toast.showBottom('patchItem.unsupportedPatchVersion');
|
||||||
widget.toast.showBottom('patchItem.unsupportedPatchVersion');
|
} else {
|
||||||
} else {
|
widget.isSelected = !widget.isSelected;
|
||||||
widget.isSelected = !widget.isSelected;
|
}
|
||||||
}
|
});
|
||||||
});
|
widget.onChanged(widget.isSelected);
|
||||||
widget.onChanged(widget.isSelected);
|
},
|
||||||
},
|
child: Column(
|
||||||
child: Column(
|
children: <Widget>[
|
||||||
children: <Widget>[
|
Row(
|
||||||
Row(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
children: <Widget>[
|
||||||
children: <Widget>[
|
Flexible(
|
||||||
Flexible(
|
child: Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: <Widget>[
|
||||||
children: <Widget>[
|
Row(
|
||||||
Row(
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
children: <Widget>[
|
||||||
children: <Widget>[
|
Expanded(
|
||||||
Expanded(
|
child: Text(
|
||||||
child: Text(
|
widget.simpleName,
|
||||||
widget.simpleName,
|
maxLines: 2,
|
||||||
maxLines: 2,
|
overflow: TextOverflow.visible,
|
||||||
overflow: TextOverflow.visible,
|
style: const TextStyle(
|
||||||
style: const TextStyle(
|
fontSize: 16,
|
||||||
fontSize: 16,
|
fontWeight: FontWeight.w600,
|
||||||
fontWeight: FontWeight.w600,
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
widget.description,
|
||||||
|
softWrap: true,
|
||||||
|
overflow: TextOverflow.visible,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSecondaryContainer,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Transform.scale(
|
||||||
|
scale: 1.2,
|
||||||
|
child: Checkbox(
|
||||||
|
value: widget.isSelected,
|
||||||
|
activeColor: Theme.of(context).colorScheme.primary,
|
||||||
|
checkColor:
|
||||||
|
Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
side: BorderSide(
|
||||||
|
width: 2.0,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
onChanged: (newValue) {
|
||||||
|
setState(() {
|
||||||
|
if (widget.isUnsupported &&
|
||||||
|
!widget._managerAPI
|
||||||
|
.areExperimentalPatchesEnabled()) {
|
||||||
|
widget.isSelected = false;
|
||||||
|
widget.toast.showBottom(
|
||||||
|
'patchItem.unsupportedPatchVersion',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
widget.isSelected = newValue!;
|
||||||
|
}
|
||||||
|
if (widget.isUnsupported &&
|
||||||
|
widget.isSelected &&
|
||||||
|
!selectedUnsupportedPatches
|
||||||
|
.contains(widget.name)) {
|
||||||
|
selectedUnsupportedPatches.add(widget.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
widget.onChanged(widget.isSelected);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (widget.isUnsupported &&
|
||||||
|
widget._managerAPI.areExperimentalPatchesEnabled())
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8),
|
||||||
|
child: TextButton.icon(
|
||||||
|
label: I18nText('warning'),
|
||||||
|
icon: const Icon(Icons.warning, size: 20.0),
|
||||||
|
onPressed: () => _showUnsupportedWarningDialog(),
|
||||||
|
style: ButtonStyle(
|
||||||
|
shape: MaterialStateProperty.all(
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
side: BorderSide(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
backgroundColor: MaterialStateProperty.all(
|
||||||
),
|
Colors.transparent,
|
||||||
const SizedBox(height: 1),
|
),
|
||||||
Text(
|
foregroundColor: MaterialStateProperty.all(
|
||||||
widget.version,
|
Theme.of(context).colorScheme.secondary,
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
widget.description,
|
|
||||||
softWrap: true,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.onSecondaryContainer,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Transform.scale(
|
|
||||||
scale: 1.2,
|
|
||||||
child: Checkbox(
|
|
||||||
value: widget.isSelected,
|
|
||||||
activeColor: Theme.of(context).colorScheme.primary,
|
|
||||||
checkColor:
|
|
||||||
Theme.of(context).colorScheme.secondaryContainer,
|
|
||||||
side: BorderSide(
|
|
||||||
width: 2.0,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
onChanged: (newValue) {
|
|
||||||
setState(() {
|
|
||||||
if (widget.isUnsupported &&
|
|
||||||
!widget._managerAPI
|
|
||||||
.areExperimentalPatchesEnabled()) {
|
|
||||||
widget.isSelected = false;
|
|
||||||
widget.toast
|
|
||||||
.showBottom('patchItem.unsupportedPatchVersion');
|
|
||||||
} else {
|
|
||||||
widget.isSelected = newValue!;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
widget.onChanged(widget.isSelected);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (widget.isUnsupported)
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8),
|
|
||||||
child: TextButton.icon(
|
|
||||||
label: I18nText('warning'),
|
|
||||||
icon: const Icon(Icons.warning, size: 20.0),
|
|
||||||
onPressed: () => _showUnsupportedWarningDialog(),
|
|
||||||
style: ButtonStyle(
|
|
||||||
shape: MaterialStateProperty.all(
|
|
||||||
RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
side: BorderSide(
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
backgroundColor: MaterialStateProperty.all(
|
|
||||||
Colors.transparent,
|
|
||||||
),
|
|
||||||
foregroundColor: MaterialStateProperty.all(
|
|
||||||
Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
)
|
||||||
)
|
else
|
||||||
else
|
Container(),
|
||||||
Container(),
|
widget.child ?? const SizedBox(),
|
||||||
widget.child ?? const SizedBox(),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -28,7 +28,7 @@ class SAdvancedSection extends StatelessWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
title: I18nText(
|
title: I18nText(
|
||||||
'settingsView.deleteKeystoreLabel',
|
'settingsView.regenerateKeystoreLabel',
|
||||||
child: const Text(
|
child: const Text(
|
||||||
'',
|
'',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@ -37,7 +37,7 @@ class SAdvancedSection extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: I18nText('settingsView.deleteKeystoreHint'),
|
subtitle: I18nText('settingsView.regenerateKeystoreHint'),
|
||||||
onTap: () => _showDeleteKeystoreDialog(context),
|
onTap: () => _showDeleteKeystoreDialog(context),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -78,11 +78,9 @@ class SAdvancedSection extends StatelessWidget {
|
|||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
title: I18nText('warning'),
|
title: I18nText('settingsView.regenerateKeystoreDialogTitle'),
|
||||||
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
content: I18nText(
|
content: I18nText('settingsView.regenerateKeystoreDialogText'),
|
||||||
'settingsView.deleteKeystoreDialogText',
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
CustomMaterialButton(
|
CustomMaterialButton(
|
||||||
isFilled: false,
|
isFilled: false,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_i18n/widgets/I18nText.dart';
|
import 'package:flutter_i18n/widgets/I18nText.dart';
|
||||||
|
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||||
|
|
||||||
class SExperimentalPatches extends StatefulWidget {
|
class SExperimentalPatches extends StatefulWidget {
|
||||||
@ -10,6 +11,7 @@ class SExperimentalPatches extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final _settingsViewModel = SettingsViewModel();
|
final _settingsViewModel = SettingsViewModel();
|
||||||
|
final List<String> selectedUnsupportedPatches = [];
|
||||||
|
|
||||||
class _SExperimentalPatchesState extends State<SExperimentalPatches> {
|
class _SExperimentalPatchesState extends State<SExperimentalPatches> {
|
||||||
@override
|
@override
|
||||||
@ -32,6 +34,14 @@ class _SExperimentalPatchesState extends State<SExperimentalPatches> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
_settingsViewModel.useExperimentalPatches(value);
|
_settingsViewModel.useExperimentalPatches(value);
|
||||||
});
|
});
|
||||||
|
if (!value) {
|
||||||
|
for (final patch in selectedUnsupportedPatches) {
|
||||||
|
PatchesSelectorViewModel()
|
||||||
|
.selectedPatches
|
||||||
|
.removeWhere((element) => patch == element.name);
|
||||||
|
}
|
||||||
|
selectedUnsupportedPatches.clear();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter_i18n/widgets/I18nText.dart';
|
|||||||
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_keystore_password.dart';
|
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_keystore_password.dart';
|
||||||
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
|
||||||
|
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
||||||
|
|
||||||
final _settingsViewModel = SettingsViewModel();
|
final _settingsViewModel = SettingsViewModel();
|
||||||
|
|
||||||
@ -91,9 +92,36 @@ class SExportSection extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: I18nText('settingsView.resetStoredPatchesHint'),
|
subtitle: I18nText('settingsView.resetStoredPatchesHint'),
|
||||||
onTap: () => _settingsViewModel.resetSelectedPatches(),
|
onTap: () => _showResetStoredPatchesDialog(context),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _showResetStoredPatchesDialog(context) {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: I18nText('settingsView.resetStoredPatchesDialogTitle'),
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
content: I18nText(
|
||||||
|
'settingsView.resetStoredPatchesDialogText',
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
CustomMaterialButton(
|
||||||
|
isFilled: false,
|
||||||
|
label: I18nText('noButton'),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('yesButton'),
|
||||||
|
onPressed: () => {
|
||||||
|
Navigator.of(context).pop(),
|
||||||
|
_settingsViewModel.resetSelectedPatches()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
10
pubspec.yaml
10
pubspec.yaml
@ -1,17 +1,16 @@
|
|||||||
name: revanced_manager
|
name: revanced_manager
|
||||||
description: The official ReVanced Manager.
|
description: Patch your favorite apps, right on your device.
|
||||||
homepage: https://github.com/revanced/revanced-manager
|
homepage: https://github.com/revanced/revanced-manager
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 1.3.4+100300004
|
version: 1.5.0+100400004
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
animations: ^2.0.7
|
animations: ^2.0.7
|
||||||
app_installer: ^1.1.0
|
|
||||||
collection: ^1.17.0
|
collection: ^1.17.0
|
||||||
cross_connectivity: ^3.0.5
|
cross_connectivity: ^3.0.5
|
||||||
cr_file_saver:
|
cr_file_saver:
|
||||||
@ -59,8 +58,8 @@ dependencies:
|
|||||||
pull_to_refresh: ^2.0.0
|
pull_to_refresh: ^2.0.0
|
||||||
root:
|
root:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/gokul1630/root
|
url: https://github.com/EvadeMaster/root
|
||||||
ref: main
|
ref: 82803aa40f63cddff81c3e4d27ce8ce3e7c83f60
|
||||||
share_extend: ^2.0.0
|
share_extend: ^2.0.0
|
||||||
shared_preferences: ^2.1.0
|
shared_preferences: ^2.1.0
|
||||||
skeletons: ^0.0.3
|
skeletons: ^0.0.3
|
||||||
@ -75,6 +74,7 @@ dependencies:
|
|||||||
flutter_dotenv: ^5.0.2
|
flutter_dotenv: ^5.0.2
|
||||||
flutter_markdown: ^0.6.14
|
flutter_markdown: ^0.6.14
|
||||||
dio_cache_interceptor: ^3.4.0
|
dio_cache_interceptor: ^3.4.0
|
||||||
|
install_plugin: ^2.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
json_serializable: ^6.6.1
|
json_serializable: ^6.6.1
|
||||||
|
Reference in New Issue
Block a user