mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2025-07-04 16:12:53 +08:00
Compare commits
92 Commits
settings-r
...
docs/readm
Author | SHA1 | Date | |
---|---|---|---|
a5d09b2bf5 | |||
8731e7267a | |||
c2a942b46c | |||
b9401b5f89 | |||
0eee869b99 | |||
15cfeb6ba7 | |||
d47819cae7 | |||
351e00c380 | |||
046179db1b | |||
5993dc34cb | |||
91f6672711 | |||
d3748cf305 | |||
db304a70c8 | |||
8f9ea54790 | |||
a53a0bd2d4 | |||
1c6a9dbbbd | |||
802330c062 | |||
d1ef14a25a | |||
617481f26f | |||
6598db5078 | |||
5b790a86e2 | |||
bec0d823dc | |||
2616576b3d | |||
44fc4551aa | |||
6dfb2a2de0 | |||
03c91687ae | |||
91e06cbce6 | |||
b0624a3544 | |||
04a2a78914 | |||
4364f2e4c2 | |||
177b716fd0 | |||
d987845bba | |||
50c46dc20d | |||
5125084279 | |||
911201ad9f | |||
8442bf2e14 | |||
05bf940cdf | |||
3bbad156c4 | |||
db4ce6bb77 | |||
a290369d8d | |||
adf5f9f6e8 | |||
ace6701aaf | |||
94de170490 | |||
3c56db4121 | |||
62bb0d34ce | |||
1521d21e4e | |||
35996b6c69 | |||
d32a213457 | |||
2a3395ce15 | |||
944b57c336 | |||
bc09af9d0b | |||
0419b2f86b | |||
2f31fc7d6e | |||
dcf51c1777 | |||
94eb893a01 | |||
af49457bfc | |||
a8682d671d | |||
10815c8f73 | |||
891fb57531 | |||
07ee005613 | |||
a3c48d14ab | |||
f14b697769 | |||
d06fb08239 | |||
cf9a14c762 | |||
7b49af21d0 | |||
18774084c9 | |||
a70ad3d666 | |||
0d2d879603 | |||
8acdc17cc4 | |||
1f5331dbfe | |||
98747f4afb | |||
2f782b4963 | |||
3c083edfda | |||
7bf1a5af65 | |||
8a3d163266 | |||
d58fd96bb0 | |||
259f76379e | |||
b8378fbb02 | |||
2f0cdfff59 | |||
cd5787a4f7 | |||
a280fc2446 | |||
a503f4830b | |||
f732df1b9a | |||
9b9525ece5 | |||
e0dfbaf4a3 | |||
949b1dad0e | |||
830a666a58 | |||
26b9652135 | |||
85c6e7283d | |||
67603f64cd | |||
676eb1e9e2 | |||
e7b94868d6 |
8
.github/workflows/release-build.yml
vendored
8
.github/workflows/release-build.yml
vendored
@ -9,9 +9,6 @@ jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set env
|
||||
@ -44,11 +41,6 @@ jobs:
|
||||
- name: Add version to APK
|
||||
run: mv ${{ steps.sign_apk.outputs.signedFile }} revanced-manager-${{ env.RELEASE_VERSION }}.apk
|
||||
|
||||
- name: Generate artifact attestation
|
||||
uses: actions/attest-build-provenance@v1
|
||||
with:
|
||||
subject-path: revanced-manager-${{ env.RELEASE_VERSION }}.apk
|
||||
|
||||
- name: Publish release APK
|
||||
uses: "marvinpinto/action-automatic-releases@latest"
|
||||
with:
|
||||
|
111
CONTRIBUTING.md
Normal file
111
CONTRIBUTING.md
Normal file
@ -0,0 +1,111 @@
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
width="256px"
|
||||
src="assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="assets/revanced-logo/revanced-logo.svg" />
|
||||
<img height="24px" src="assets/revanced-logo/revanced-logo.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://github.com/ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://x.com/revancedapp">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/93124920/270180600-7c1b38bf-889b-4d68-bd5e-b9d86f91421a.png">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/93124920/270108715-d80743fa-b330-4809-b1e6-79fbdc60d09c.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
# 👋 Contribution guidelines
|
||||
|
||||
Welcome to contribution guidelines, this document contains
|
||||
everything you'll need to contribute to ReVanced Manager (and might even possibly apply to our other project like ReVanced Patches!)
|
||||
|
||||
There are many ways to contribute like writing docs and code, opening issues,
|
||||
helping people out in our community, translating or sponsoring our project, etc.
|
||||
|
||||
## 📖 Resources to help you get started
|
||||
|
||||
* The [documentation](/docs/developer/README.md) provides steps to build ReVanced Manager from source
|
||||
* Our [backlog](https://github.com/orgs/ReVanced/projects/12) is where we keep track of what we're working on
|
||||
* [Issues](https://github.com/ReVanced/revanced-manager/issues) are where we keep track of bugs and feature requests
|
||||
|
||||
## 🙏 Submitting a feature request
|
||||
|
||||
Features can be requested by opening an issue using the
|
||||
[feature request issue template](https://github.com/ReVanced/revanced-manager/issues/new?assignees=&labels=feature-request&projects=&template=feature-issue.yml&title=feat%3A+%3Ctitle%3E).
|
||||
|
||||
> [!NOTE]
|
||||
> Requests can be accepted or rejected at the discretion of maintainers of ReVanced Manager.
|
||||
> Good motivation has to be provided for a request to be accepted.
|
||||
|
||||
## 🐞 Submitting a bug report
|
||||
|
||||
If you encounter a bug while using the ReVanced Manager app, open an issue using the
|
||||
[bug report issue template](https://github.com/ReVanced/revanced-manager/issues/new?assignees=&labels=bug&projects=&template=bug-issue.yml&title=bug%3A+%3Ctitle%3E).
|
||||
|
||||
## 🌐 Submitting translations
|
||||
|
||||
You can contribute translations at translate.revanced.app
|
||||
|
||||
> [!TIP]
|
||||
> * Try to keep the translated text roughly the same length as the original.
|
||||
> * Consider opting for gender-neutral words for language with variations of words based on gender.
|
||||
|
||||
## 🧑💻 Developing for ReVanced Manager
|
||||
|
||||
See the guidelines for developing for ReVanced Manager [here](/docs/developer/README.md)
|
||||
|
||||
## 🔒 Submitting a vulnerability
|
||||
|
||||
See the guideline for reporting security vulnerability [here](/SECURITY.md)
|
||||
|
||||
## 🤚 I don't want to do any of that but I want to contribute either way
|
||||
|
||||
You can still contribute by spreading positive word about us or if you'd like to sponsor us, checkout https://revanced.app/donate
|
||||
to learn more about how you can sponsor via GitHub, Open Collective, and cryptocurrencies.
|
||||
|
||||
❤️ Thank you for considering contributing to ReVanced Manager,
|
||||
ReVanced
|
119
README.md
119
README.md
@ -1,55 +1,104 @@
|
||||
# ReVanced Manager (Compose Rewrite)
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
width="256px"
|
||||
src="assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="assets/revanced-logo/revanced-logo.svg" />
|
||||
<img height="24px" src="assets/revanced-logo/revanced-logo.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://github.com/ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://x.com/revancedapp">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/93124920/270180600-7c1b38bf-889b-4d68-bd5e-b9d86f91421a.png">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/93124920/270108715-d80743fa-b330-4809-b1e6-79fbdc60d09c.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
[](../../blob/main/LICENSE)
|
||||
[](https://github.com/ReVanced/revanced-manager/commits/compose-dev)
|
||||
[](https://github.com/ReVanced/revanced-manager/commits/compose-dev)
|
||||
# 💊 ReVanced Manager
|
||||
|
||||
_(Yet another)_ rewrite of the ReVanced Manager using Kotlin and Jetpack Compose.
|
||||
[](https://github.com/ReVanced/revanced-manager/actions/workflows/release.yml)
|
||||
[](#️-license)
|
||||
|
||||
## Design system
|
||||
Application to use ReVanced on Android
|
||||
|
||||
In this rewrite, we are adopting the latest Material Design principles and guidelines by using Material 3 and Material You.
|
||||
## ❓ About
|
||||
|
||||
Material Design is a design system developed by Google that provides a unified visual language for building beautiful and consistent user interfaces across all platforms and devices. Material You is an extension of Material Design that provides even more customization options for users, making it possible for them to personalize their device and create a unique look and feel.
|
||||
ReVanced Manager is an application that uses [ReVanced Patcher](https://github.com/revanced/revanced-patcher) to patch Android apps.
|
||||
|
||||
### Why Material 3?
|
||||
## 💪 Features
|
||||
|
||||
* **Consistent design language**
|
||||
* **Improved accessibility**
|
||||
* **Better user experience**
|
||||
Some of the features ReVanced Manager provides are:
|
||||
|
||||
By using Material 3 and Material You, we are ensuring that the app's user interface is consistent, customizable, accessible, and engaging for our users. This will help to improve the overall user experience and increase user satisfaction with the the manager.
|
||||
|
||||
## Technology stack
|
||||
|
||||
* Kotlin: Kotlin is a modern and concise programming language that is fully interoperable with Java and provides improved safety, readability, and maintainability compared to Java.
|
||||
* Jetpack Compose: Jetpack Compose is a modern UI toolkit for Android development that allows developers to build beautiful and performant user interfaces using declarative programming. It provides a unified and efficient way of building UI that is well-integrated with the Android framework.
|
||||
|
||||
## Why Kotlin and Compose?
|
||||
|
||||
* **Improved safety:** Kotlin provides improved safety compared to Java, which reduces the likelihood of common programming mistakes that can cause security vulnerabilities or crashes.
|
||||
* **Concise and readable code:** Kotlin's concise syntax and expressive type system make the code more readable, which makes it easier for developers to understand and maintain the codebase.
|
||||
* **Better performance:** Jetpack Compose uses the power of the Android framework to provide smooth and fast performance, which enhances the user experience.
|
||||
* **Modern and efficient UI development:** Jetpack Compose provides a modern and efficient way of building UI, which makes it easier for developers to create beautiful and performant user interfaces.
|
||||
- 💉 **Patch apps**: Apply any patch of your choice to Android apps
|
||||
- 📱 **Portable**: ReVanced Patcher that fits in your pocket
|
||||
- 🤗 **Simple UI**: Quickly understand the ins and outs of ReVanced Manager
|
||||
- 🛠️ **Customization**: Configurable API, custom sources, language, signing keystore, theme and more
|
||||
|
||||
## 🔽 Download
|
||||
|
||||
You can obtain ReVanced Manager by downloading it from either [revanced.app/download](https://revanced.app/download) or [GitHub Releases](https://github.com/ReVanced/revanced-manager/releases)
|
||||
You can get the most recent version of ReVanced Manager by downloading from
|
||||
the [ReVanced site](https://revanced.app/download).
|
||||
|
||||
## 📝 Prerequisites
|
||||
Learn how to use ReVanced Manager by following the [documentation](/docs).
|
||||
|
||||
For a list of prerequisites, refer to [docs/0_prerequisites.md](docs/0_prerequisites.md)
|
||||
## 📚 Everything else
|
||||
|
||||
## 🔴 Issues
|
||||
### 📙 Contributing
|
||||
|
||||
For suggestions and bug reports, open an issue [here](https://github.com/revanced/revanced-manager/issues/new/choose).
|
||||
Thank you for considering contributing to ReVanced Manager.
|
||||
|
||||
## 🌐 Translation
|
||||
The [contribution guidelines](CONTRIBUTING.md) provides information you'll need to open an issue, develop for ReVanced Manager and translations.
|
||||
|
||||
[](https://crowdin.com/project/revanced)
|
||||
### 📄 Documentation
|
||||
|
||||
We're accepting translations on [Crowdin](https://translate.revanced.app)
|
||||
You can find the documentation for ReVanced Manager [here](/docs).
|
||||
|
||||
## 🛠️ Building Manager from source
|
||||
## ⚖️ License
|
||||
|
||||
For instructions on how to build ReVanced Manager from source, refer to [docs/4_building.md](docs/4_building.md)
|
||||
ReVanced Manager is licensed under the GPLv3 license. Please see the [license file](LICENSE) for more information.
|
||||
[tl;dr](https://www.tldrlegal.com/license/gnu-general-public-license-v3-gpl-3) you may copy, distribute and modify ReVanced Manager as long as you track changes/dates in source files.
|
||||
Any modifications to ReVanced Manager must also be made available under the GPL, along with build & install instructions.
|
||||
|
20
SECURITY.md
20
SECURITY.md
@ -64,14 +64,20 @@ This document describes how to report security vulnerabilities for ReVanced Mana
|
||||
|
||||
## 🚨 Reporting a Vulnerability
|
||||
|
||||
Please open an issue in our [advisory tracker](https://github.com/ReVanced/revanced-manager/security/advisories/new) or reach out privately to us on [Discord](https://discord.gg/revanced).
|
||||
Please open an issue in our [advisory tracker](https://github.com/ReVanced/revanced-manager/security/advisories/new)
|
||||
or reach out privately to us on [Discord](https://discord.gg/revanced).
|
||||
|
||||
If a vulnerability is confirmed and accepted, you can join our [Discord](https://discord.gg/revanced) server to receive a special contributor role.
|
||||
If a vulnerability is confirmed and accepted, they will be published and
|
||||
you can join our [Discord](https://discord.gg/revanced) server to receive a
|
||||
special contributor role.
|
||||
|
||||
### ⏳ Supported Versions
|
||||
|
||||
| Version | Branch | Supported |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------ |
|
||||
|  | main | :white_check_mark: |
|
||||
|  | dev | :white_check_mark: |
|
||||
|  | compose-dev | :white_check_mark: |
|
||||
| Version | Branch | Supported |
|
||||
|------------------------------------------|---------------|--------------------|
|
||||
| ![Latest stable release][LatestRelBadge] | `main` | :white_check_mark: |
|
||||
| ![Latest version][LatestVerBadge] | `dev` | :white_check_mark: |
|
||||
| ![Latest version][LatestVerBadge] | `compose-dev` | :white_check_mark: |
|
||||
|
||||
[LatestRelBadge]: https://img.shields.io/github/v/release/ReVanced/revanced-manager?style=for-the-badge "Latest stable release"
|
||||
[LatestVerBadge]: https://img.shields.io/badge/version-latest-brightgreen?style=for-the-badge "Latest version"
|
||||
|
@ -13,7 +13,7 @@ plugins {
|
||||
android {
|
||||
namespace = "app.revanced.manager"
|
||||
compileSdk = 35
|
||||
buildToolsVersion = "35.0.1"
|
||||
buildToolsVersion = "35.0.0"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "app.revanced.manager"
|
||||
@ -28,7 +28,6 @@ android {
|
||||
debug {
|
||||
applicationIdSuffix = ".debug"
|
||||
resValue("string", "app_name", "ReVanced Manager (dev)")
|
||||
isPseudoLocalesEnabled = true
|
||||
|
||||
buildConfigField("long", "BUILD_ID", "${Random.nextLong()}L")
|
||||
}
|
||||
@ -44,8 +43,6 @@ android {
|
||||
applicationIdSuffix = ".debug"
|
||||
resValue("string", "app_name", "ReVanced Manager Debug")
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
|
||||
isPseudoLocalesEnabled = true
|
||||
}
|
||||
|
||||
buildConfigField("long", "BUILD_ID", "0L")
|
||||
|
@ -9,8 +9,6 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -25,32 +23,11 @@ import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.navigation
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.toRoute
|
||||
import app.revanced.manager.ui.model.navigation.AppSelector
|
||||
import app.revanced.manager.ui.model.navigation.ComplexParameter
|
||||
import app.revanced.manager.ui.model.navigation.Dashboard
|
||||
import app.revanced.manager.ui.model.navigation.InstalledApplicationInfo
|
||||
import app.revanced.manager.ui.model.navigation.Patcher
|
||||
import app.revanced.manager.ui.model.navigation.SelectedApplicationInfo
|
||||
import app.revanced.manager.ui.model.navigation.Settings
|
||||
import app.revanced.manager.ui.model.navigation.Update
|
||||
import app.revanced.manager.ui.screen.AppSelectorScreen
|
||||
import app.revanced.manager.ui.screen.DashboardScreen
|
||||
import app.revanced.manager.ui.screen.InstalledAppInfoScreen
|
||||
import app.revanced.manager.ui.screen.PatcherScreen
|
||||
import app.revanced.manager.ui.screen.PatchesSelectorScreen
|
||||
import app.revanced.manager.ui.screen.RequiredOptionsScreen
|
||||
import app.revanced.manager.ui.screen.SelectedAppInfoScreen
|
||||
import app.revanced.manager.ui.screen.SettingsScreen
|
||||
import app.revanced.manager.ui.screen.UpdateScreen
|
||||
import app.revanced.manager.ui.screen.settings.AboutSettingsScreen
|
||||
import app.revanced.manager.ui.screen.settings.AdvancedSettingsScreen
|
||||
import app.revanced.manager.ui.screen.settings.BackupRestoreSettingsScreen
|
||||
import app.revanced.manager.ui.screen.settings.ContributorScreen
|
||||
import app.revanced.manager.ui.screen.settings.DeveloperOptionsScreen
|
||||
import app.revanced.manager.ui.screen.settings.DownloadsSettingsScreen
|
||||
import app.revanced.manager.ui.screen.settings.GeneralSettingsScreen
|
||||
import app.revanced.manager.ui.screen.settings.LicensesScreen
|
||||
import app.revanced.manager.ui.model.navigation.*
|
||||
import app.revanced.manager.ui.screen.*
|
||||
import app.revanced.manager.ui.screen.settings.*
|
||||
import app.revanced.manager.ui.screen.settings.update.ChangelogsScreen
|
||||
import app.revanced.manager.ui.screen.settings.update.UpdatesSettingsScreen
|
||||
import app.revanced.manager.ui.theme.ReVancedManagerTheme
|
||||
import app.revanced.manager.ui.theme.Theme
|
||||
import app.revanced.manager.ui.viewmodel.MainViewModel
|
||||
@ -112,10 +89,6 @@ private fun ReVancedManager(vm: MainViewModel) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = Dashboard,
|
||||
enterTransition = { slideInHorizontally(initialOffsetX = { it }) },
|
||||
exitTransition = { slideOutHorizontally(targetOffsetX = { -it / 3 }) },
|
||||
popEnterTransition = { slideInHorizontally(initialOffsetX = { -it / 3 }) },
|
||||
popExitTransition = { slideOutHorizontally(targetOffsetX = { it }) },
|
||||
) {
|
||||
composable<Dashboard> {
|
||||
DashboardScreen(
|
||||
@ -269,28 +242,32 @@ private fun ReVancedManager(vm: MainViewModel) {
|
||||
}
|
||||
|
||||
composable<Settings.General> {
|
||||
GeneralSettingsScreen(
|
||||
onBackClick = navController::popBackStack,
|
||||
onUpdateClick = { navController.navigate(Update()) }
|
||||
)
|
||||
GeneralSettingsScreen(onBackClick = navController::popBackStack)
|
||||
}
|
||||
|
||||
composable<Settings.Advanced> {
|
||||
AdvancedSettingsScreen(onBackClick = navController::popBackStack)
|
||||
}
|
||||
|
||||
composable<Settings.Updates> {
|
||||
UpdatesSettingsScreen(
|
||||
onBackClick = navController::popBackStack,
|
||||
onChangelogClick = { navController.navigate(Settings.Changelogs) },
|
||||
onUpdateClick = { navController.navigate(Update()) }
|
||||
)
|
||||
}
|
||||
|
||||
composable<Settings.Downloads> {
|
||||
DownloadsSettingsScreen(onBackClick = navController::popBackStack)
|
||||
}
|
||||
|
||||
composable<Settings.ImportExport> {
|
||||
BackupRestoreSettingsScreen(onBackClick = navController::popBackStack)
|
||||
ImportExportSettingsScreen(onBackClick = navController::popBackStack)
|
||||
}
|
||||
|
||||
composable<Settings.About> {
|
||||
AboutSettingsScreen(
|
||||
onBackClick = navController::popBackStack,
|
||||
onChangelogClick = { navController.navigate(Settings.Changelogs) },
|
||||
navigate = navController::navigate
|
||||
)
|
||||
}
|
||||
|
@ -4,20 +4,9 @@ import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -55,14 +44,9 @@ fun AppTopBar(
|
||||
)
|
||||
},
|
||||
actions: @Composable (RowScope.() -> Unit) = {},
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
applyContainerColor: Boolean = false
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||
) {
|
||||
val containerColor = if (applyContainerColor) {
|
||||
MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
|
||||
} else {
|
||||
Color.Unspecified
|
||||
}
|
||||
val containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
|
||||
|
||||
TopAppBar(
|
||||
title = { Text(title) },
|
||||
|
@ -70,6 +70,9 @@ object Settings {
|
||||
@Serializable
|
||||
data object Advanced : Destination
|
||||
|
||||
@Serializable
|
||||
data object Updates : Destination
|
||||
|
||||
@Serializable
|
||||
data object Downloads : Destination
|
||||
|
||||
|
@ -3,26 +3,12 @@ package app.revanced.manager.ui.screen
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Storage
|
||||
import androidx.compose.material.icons.outlined.Search
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -31,7 +17,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -153,13 +138,10 @@ fun AppSelectorScreen(
|
||||
}
|
||||
}
|
||||
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.select_app),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick,
|
||||
actions = {
|
||||
IconButton(onClick = { search = true }) {
|
||||
@ -167,8 +149,7 @@ fun AppSelectorScreen(
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
LazyColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
|
@ -7,46 +7,17 @@ import android.provider.Settings
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.BatteryAlert
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.outlined.Apps
|
||||
import androidx.compose.material.icons.outlined.BugReport
|
||||
import androidx.compose.material.icons.outlined.DeleteOutline
|
||||
import androidx.compose.material.icons.outlined.Download
|
||||
import androidx.compose.material.icons.outlined.Refresh
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.Source
|
||||
import androidx.compose.material.icons.outlined.Update
|
||||
import androidx.compose.material.icons.outlined.WarningAmber
|
||||
import androidx.compose.material3.Badge
|
||||
import androidx.compose.material3.BadgedBox
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.TabRow
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.material.icons.outlined.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -62,9 +33,9 @@ import app.revanced.manager.ui.component.AutoUpdatesDialog
|
||||
import app.revanced.manager.ui.component.AvailableUpdateDialog
|
||||
import app.revanced.manager.ui.component.NotificationCard
|
||||
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
||||
import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog
|
||||
import app.revanced.manager.ui.component.haptics.HapticFloatingActionButton
|
||||
import app.revanced.manager.ui.component.haptics.HapticTab
|
||||
import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog
|
||||
import app.revanced.manager.ui.viewmodel.DashboardViewModel
|
||||
import app.revanced.manager.util.RequestInstallAppsContract
|
||||
import app.revanced.manager.util.toast
|
||||
@ -200,7 +171,11 @@ fun DashboardScreen(
|
||||
) {
|
||||
BadgedBox(
|
||||
badge = {
|
||||
Badge(modifier = Modifier.size(6.dp))
|
||||
Badge(
|
||||
// A size value above 6.dp forces the Badge icon to be closer to the center, fixing a clipping issue
|
||||
modifier = Modifier.size(7.dp),
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
) {
|
||||
Icon(Icons.Outlined.Update, stringResource(R.string.update))
|
||||
@ -210,8 +185,7 @@ fun DashboardScreen(
|
||||
IconButton(onClick = onSettingsClick) {
|
||||
Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
|
||||
}
|
||||
},
|
||||
applyContainerColor = true
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -264,9 +238,7 @@ fun DashboardScreen(
|
||||
}
|
||||
}
|
||||
|
||||
val showBatteryOptimizationsWarning by vm.showBatteryOptimizationsWarningFlow.collectAsStateWithLifecycle(
|
||||
false
|
||||
)
|
||||
val showBatteryOptimizationsWarning by vm.showBatteryOptimizationsWarningFlow.collectAsStateWithLifecycle(false)
|
||||
Notifications(
|
||||
if (!Aapt.supportsDevice()) {
|
||||
{
|
||||
|
@ -21,8 +21,6 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -31,7 +29,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@ -67,17 +64,13 @@ fun InstalledAppInfoScreen(
|
||||
onConfirm = { viewModel.uninstall() }
|
||||
)
|
||||
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.app_info),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
ColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
|
@ -121,10 +121,9 @@ fun PatcherScreen(
|
||||
}
|
||||
|
||||
AppScaffold(
|
||||
topBar = { scrollBehavior ->
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.patcher),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = ::leaveScreen
|
||||
)
|
||||
},
|
||||
|
@ -76,8 +76,8 @@ import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionBut
|
||||
import app.revanced.manager.ui.component.haptics.HapticTab
|
||||
import app.revanced.manager.ui.component.patches.OptionItem
|
||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
|
||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNSUPPORTED
|
||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
||||
import app.revanced.manager.util.Options
|
||||
import app.revanced.manager.util.PatchSelection
|
||||
import app.revanced.manager.util.isScrollingUp
|
||||
|
@ -15,8 +15,6 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.ScrollableTabRow
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
@ -24,7 +22,6 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
@ -69,13 +66,10 @@ fun RequiredOptionsScreen(
|
||||
}
|
||||
val composableScope = rememberCoroutineScope()
|
||||
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.required_options_screen),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
@ -96,8 +90,7 @@ fun RequiredOptionsScreen(
|
||||
onContinue(vm.getCustomSelection(), vm.getOptions())
|
||||
}
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
Modifier
|
||||
|
@ -12,21 +12,12 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
|
||||
import androidx.compose.material.icons.filled.AutoFixHigh
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -84,14 +75,10 @@ fun SelectedAppInfoScreen(
|
||||
val composableScope = rememberCoroutineScope()
|
||||
|
||||
val error by vm.errorFlow.collectAsStateWithLifecycle(null)
|
||||
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.app_info),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
@ -127,8 +114,7 @@ fun SelectedAppInfoScreen(
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
val plugins by vm.plugins.collectAsStateWithLifecycle(emptyList())
|
||||
|
||||
|
@ -4,14 +4,8 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Download
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.SwapVert
|
||||
import androidx.compose.material.icons.outlined.Tune
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material.icons.outlined.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@ -28,13 +22,18 @@ private val settingsSections = listOf(
|
||||
Icons.Outlined.Settings
|
||||
) to Settings.General,
|
||||
Triple(
|
||||
R.string.extensions,
|
||||
R.string.extensions_description,
|
||||
R.string.updates,
|
||||
R.string.updates_description,
|
||||
Icons.Outlined.Update
|
||||
) to Settings.Updates,
|
||||
Triple(
|
||||
R.string.downloads,
|
||||
R.string.downloads_description,
|
||||
Icons.Outlined.Download
|
||||
) to Settings.Downloads,
|
||||
Triple(
|
||||
R.string.backup_restore,
|
||||
R.string.backup_restore_description,
|
||||
R.string.import_export,
|
||||
R.string.import_export_description,
|
||||
Icons.Outlined.SwapVert
|
||||
) to Settings.ImportExport,
|
||||
Triple(
|
||||
|
@ -24,13 +24,10 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -55,17 +52,13 @@ fun UpdateScreen(
|
||||
onBackClick: () -> Unit,
|
||||
vm: UpdateViewModel = koinViewModel()
|
||||
) {
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.update),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
AnimatedVisibility(visible = vm.showInternetCheckDialog) {
|
||||
MeteredDownloadConfirmationDialog(
|
||||
|
@ -24,13 +24,10 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedCard
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -51,7 +48,6 @@ import org.koin.androidx.compose.koinViewModel
|
||||
@Composable
|
||||
fun AboutSettingsScreen(
|
||||
onBackClick: () -> Unit,
|
||||
onChangelogClick: () -> Unit,
|
||||
navigate: (Settings.Destination) -> Unit,
|
||||
viewModel: AboutViewModel = koinViewModel()
|
||||
) {
|
||||
@ -109,11 +105,6 @@ fun AboutSettingsScreen(
|
||||
}
|
||||
|
||||
val listItems = listOfNotNull(
|
||||
Triple(
|
||||
stringResource(R.string.changelog),
|
||||
stringResource(R.string.changelog_description),
|
||||
third = { onChangelogClick }
|
||||
),
|
||||
Triple(stringResource(R.string.submit_feedback),
|
||||
stringResource(R.string.submit_feedback_description),
|
||||
third = {
|
||||
@ -136,17 +127,13 @@ fun AboutSettingsScreen(
|
||||
)
|
||||
)
|
||||
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.about),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
ColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
|
@ -10,34 +10,14 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Api
|
||||
import androidx.compose.material.icons.outlined.Edit
|
||||
import androidx.compose.material.icons.outlined.Restore
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
@ -73,17 +53,14 @@ fun AdvancedSettingsScreen(
|
||||
activityManager.largeMemoryClass
|
||||
)
|
||||
}
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.advanced),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
ColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
@ -101,10 +78,17 @@ fun AdvancedSettingsScreen(
|
||||
defaultUrl = vm.prefs.api.default,
|
||||
onSubmit = {
|
||||
showApiUrlDialog = false
|
||||
it?.let(vm::setApiSource)
|
||||
it?.let(vm::setApiUrl)
|
||||
}
|
||||
)
|
||||
}
|
||||
SettingsListItem(
|
||||
headlineContent = stringResource(R.string.api_url),
|
||||
supportingContent = stringResource(R.string.api_url_description),
|
||||
modifier = Modifier.clickable {
|
||||
showApiUrlDialog = true
|
||||
}
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.patcher))
|
||||
BooleanItem(
|
||||
@ -120,28 +104,13 @@ fun AdvancedSettingsScreen(
|
||||
description = R.string.process_runtime_memory_limit_description,
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.manager))
|
||||
SettingsListItem(
|
||||
headlineContent = stringResource(R.string.api_url),
|
||||
supportingContent = apiUrl,
|
||||
modifier = Modifier.clickable {
|
||||
showApiUrlDialog = true
|
||||
},
|
||||
trailingContent = {
|
||||
IconButton(onClick = { showApiUrlDialog = true }) {
|
||||
Icon(
|
||||
Icons.Outlined.Edit,
|
||||
contentDescription = stringResource(R.string.edit)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
GroupHeader(stringResource(R.string.safeguards))
|
||||
SafeguardBooleanItem(
|
||||
preference = vm.prefs.disablePatchVersionCompatCheck,
|
||||
coroutineScope = vm.viewModelScope,
|
||||
headline = R.string.allow_compatibility_mixing,
|
||||
description = R.string.allow_compatibility_mixing_description,
|
||||
confirmationText = R.string.allow_compatibility_mixing_confirmation
|
||||
headline = R.string.patch_compat_check,
|
||||
description = R.string.patch_compat_check_description,
|
||||
confirmationText = R.string.patch_compat_check_confirmation
|
||||
)
|
||||
SafeguardBooleanItem(
|
||||
preference = vm.prefs.disableUniversalPatchWarning,
|
||||
@ -150,6 +119,13 @@ fun AdvancedSettingsScreen(
|
||||
description = R.string.universal_patches_safeguard_description,
|
||||
confirmationText = R.string.universal_patches_safeguard_confirmation
|
||||
)
|
||||
SafeguardBooleanItem(
|
||||
preference = vm.prefs.suggestedVersionSafeguard,
|
||||
coroutineScope = vm.viewModelScope,
|
||||
headline = R.string.suggested_version_safeguard,
|
||||
description = R.string.suggested_version_safeguard_description,
|
||||
confirmationText = R.string.suggested_version_safeguard_confirmation
|
||||
)
|
||||
SafeguardBooleanItem(
|
||||
preference = vm.prefs.disableSelectionWarning,
|
||||
coroutineScope = vm.viewModelScope,
|
||||
@ -158,21 +134,6 @@ fun AdvancedSettingsScreen(
|
||||
confirmationText = R.string.patch_selection_safeguard_confirmation
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.update))
|
||||
BooleanItem(
|
||||
preference = vm.prefs.showManagerUpdateDialogOnLaunch,
|
||||
headline = R.string.show_manager_update_dialog_on_launch,
|
||||
description = R.string.check_for_update_auto_description
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.experimental_features))
|
||||
BooleanItem(
|
||||
preference = vm.prefs.useProcessRuntime,
|
||||
coroutineScope = vm.viewModelScope,
|
||||
headline = R.string.process_runtime,
|
||||
description = R.string.process_runtime_description,
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.debugging))
|
||||
val exportDebugLogsLauncher =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) {
|
||||
|
@ -25,14 +25,11 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@ -56,17 +53,13 @@ fun ContributorScreen(
|
||||
viewModel: ContributorViewModel = koinViewModel()
|
||||
) {
|
||||
val repositories = viewModel.repositories
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.contributors),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
) { paddingValues ->
|
||||
LazyColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
|
@ -5,11 +5,8 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.revanced.manager.R
|
||||
import app.revanced.manager.ui.component.AppTopBar
|
||||
@ -24,17 +21,13 @@ fun DeveloperOptionsScreen(
|
||||
onBackClick: () -> Unit,
|
||||
vm: DeveloperOptionsViewModel = koinViewModel()
|
||||
) {
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.developer_options),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(modifier = Modifier.padding(paddingValues)) {
|
||||
GroupHeader(stringResource(R.string.patch_bundles_section))
|
||||
@ -44,13 +37,7 @@ fun DeveloperOptionsScreen(
|
||||
)
|
||||
SettingsListItem(
|
||||
headlineContent = stringResource(R.string.patch_bundles_reset),
|
||||
modifier = Modifier.clickable(onClick = vm::resetBundles)
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.testing))
|
||||
SettingsListItem(
|
||||
headlineContent = stringResource(R.string.disable_safeguard),
|
||||
modifier = Modifier.clickable(onClick = vm::disableSafeguard)
|
||||
modifier = Modifier.clickable(onClick = vm::redownloadBundles)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,9 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults
|
||||
import androidx.compose.material3.pulltorefresh.pullToRefresh
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -30,7 +28,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -58,13 +55,11 @@ fun DownloadsSettingsScreen(
|
||||
val pullRefreshState = rememberPullToRefreshState()
|
||||
val downloadedApps by viewModel.downloadedApps.collectAsStateWithLifecycle(emptyList())
|
||||
val pluginStates by viewModel.downloaderPluginStates.collectAsStateWithLifecycle()
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.extensions),
|
||||
scrollBehavior = scrollBehavior,
|
||||
title = stringResource(R.string.downloads),
|
||||
onBackClick = onBackClick,
|
||||
actions = {
|
||||
if (viewModel.appSelection.isNotEmpty()) {
|
||||
@ -74,8 +69,7 @@ fun DownloadsSettingsScreen(
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
Box(
|
||||
contentAlignment = Alignment.TopCenter,
|
||||
|
@ -8,14 +8,11 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FilledTonalButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -23,7 +20,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.revanced.manager.R
|
||||
@ -43,7 +39,6 @@ import org.koin.compose.koinInject
|
||||
@Composable
|
||||
fun GeneralSettingsScreen(
|
||||
onBackClick: () -> Unit,
|
||||
onUpdateClick: () -> Unit,
|
||||
viewModel: GeneralSettingsViewModel = koinViewModel()
|
||||
) {
|
||||
val prefs = viewModel.prefs
|
||||
@ -56,17 +51,14 @@ fun GeneralSettingsScreen(
|
||||
onConfirm = { viewModel.setTheme(it) }
|
||||
)
|
||||
}
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.general),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
ColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
@ -78,10 +70,10 @@ fun GeneralSettingsScreen(
|
||||
val theme by prefs.theme.getAsState()
|
||||
SettingsListItem(
|
||||
modifier = Modifier.clickable { showThemePicker = true },
|
||||
headlineContent = stringResource(R.string.theme_mode),
|
||||
supportingContent = stringResource(R.string.theme_mode_description),
|
||||
headlineContent = stringResource(R.string.theme),
|
||||
supportingContent = stringResource(R.string.theme_description),
|
||||
trailingContent = {
|
||||
Button(
|
||||
FilledTonalButton(
|
||||
onClick = {
|
||||
showThemePicker = true
|
||||
}
|
||||
@ -94,24 +86,11 @@ fun GeneralSettingsScreen(
|
||||
BooleanItem(
|
||||
preference = prefs.dynamicColor,
|
||||
coroutineScope = coroutineScope,
|
||||
headline = R.string.personalized_color,
|
||||
description = R.string.personalized_color_description
|
||||
headline = R.string.dynamic_color,
|
||||
description = R.string.dynamic_color_description
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
GroupHeader(stringResource(R.string.update))
|
||||
BooleanItem(
|
||||
preference = prefs.managerAutoUpdates,
|
||||
headline = R.string.check_for_update,
|
||||
description = R.string.check_for_update_auto_description
|
||||
)
|
||||
FilledTonalButton (
|
||||
modifier = Modifier.padding(top = paddingValues.calculateTopPadding()),
|
||||
onClick = onUpdateClick
|
||||
) {
|
||||
Text(stringResource(R.string.check_for_update))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,7 +104,7 @@ private fun ThemePicker(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.theme_mode)) },
|
||||
title = { Text(stringResource(R.string.theme)) },
|
||||
text = {
|
||||
Column {
|
||||
Theme.entries.forEach {
|
||||
|
@ -13,17 +13,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Key
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -32,7 +22,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
@ -48,82 +37,118 @@ import app.revanced.manager.ui.component.bundle.BundleSelector
|
||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
||||
import app.revanced.manager.ui.viewmodel.ImportExportViewModel
|
||||
import app.revanced.manager.util.toast
|
||||
import app.revanced.manager.util.uiSafe
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun BackupRestoreSettingsScreen(
|
||||
fun ImportExportSettingsScreen(
|
||||
onBackClick: () -> Unit,
|
||||
viewModel: ImportExportViewModel = koinViewModel()
|
||||
vm: ImportExportViewModel = koinViewModel()
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val importKeystoreLauncher =
|
||||
rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()) {
|
||||
it?.let { uri -> viewModel.startKeystoreImport(uri) }
|
||||
it?.let { uri -> vm.startKeystoreImport(uri) }
|
||||
}
|
||||
val exportKeystoreLauncher =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("*/*")) {
|
||||
it?.let(viewModel::exportKeystore)
|
||||
it?.let(vm::exportKeystore)
|
||||
}
|
||||
|
||||
val patchBundles by viewModel.patchBundles.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||
val packagesWithOptions by viewModel.packagesWithOptions.collectAsStateWithLifecycle(initialValue = emptySet())
|
||||
val patchBundles by vm.patchBundles.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||
val packagesWithOptions by vm.packagesWithOptions.collectAsStateWithLifecycle(initialValue = emptySet())
|
||||
|
||||
viewModel.selectionAction?.let { action ->
|
||||
vm.selectionAction?.let { action ->
|
||||
val launcher = rememberLauncherForActivityResult(action.activityContract) { uri ->
|
||||
if (uri == null) {
|
||||
viewModel.clearSelectionAction()
|
||||
vm.clearSelectionAction()
|
||||
} else {
|
||||
viewModel.executeSelectionAction(uri)
|
||||
vm.executeSelectionAction(uri)
|
||||
}
|
||||
}
|
||||
|
||||
if (viewModel.selectedBundle == null) {
|
||||
if (vm.selectedBundle == null) {
|
||||
BundleSelector(patchBundles) {
|
||||
if (it == null) {
|
||||
viewModel.clearSelectionAction()
|
||||
vm.clearSelectionAction()
|
||||
} else {
|
||||
viewModel.selectBundle(it)
|
||||
vm.selectBundle(it)
|
||||
launcher.launch(action.activityArg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (viewModel.showCredentialsDialog) {
|
||||
if (vm.showCredentialsDialog) {
|
||||
KeystoreCredentialsDialog(
|
||||
onDismissRequest = viewModel::cancelKeystoreImport,
|
||||
onDismissRequest = vm::cancelKeystoreImport,
|
||||
onSubmit = { cn, pass ->
|
||||
viewModel.viewModelScope.launch {
|
||||
uiSafe(context, R.string.failed_to_import_keystore, "Failed to import keystore") {
|
||||
val result = viewModel.tryKeystoreImport(cn, pass)
|
||||
if (!result) context.toast(context.getString(R.string.restore_keystore_wrong_credentials))
|
||||
}
|
||||
vm.viewModelScope.launch {
|
||||
val result = vm.tryKeystoreImport(cn, pass)
|
||||
if (!result) context.toast(context.getString(R.string.import_keystore_wrong_credentials))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.backup_restore),
|
||||
scrollBehavior = scrollBehavior,
|
||||
title = stringResource(R.string.import_export),
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
ColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
) {
|
||||
GroupHeader(stringResource(R.string.signing))
|
||||
GroupItem(
|
||||
onClick = {
|
||||
importKeystoreLauncher.launch("*/*")
|
||||
},
|
||||
headline = R.string.import_keystore,
|
||||
description = R.string.import_keystore_description
|
||||
)
|
||||
GroupItem(
|
||||
onClick = {
|
||||
if (!vm.canExport()) {
|
||||
context.toast(context.getString(R.string.export_keystore_unavailable))
|
||||
return@GroupItem
|
||||
}
|
||||
exportKeystoreLauncher.launch("Manager.keystore")
|
||||
},
|
||||
headline = R.string.export_keystore,
|
||||
description = R.string.export_keystore_description
|
||||
)
|
||||
GroupItem(
|
||||
onClick = vm::regenerateKeystore,
|
||||
headline = R.string.regenerate_keystore,
|
||||
description = R.string.regenerate_keystore_description
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.patches))
|
||||
GroupItem(
|
||||
onClick = vm::importSelection,
|
||||
headline = R.string.import_patch_selection,
|
||||
description = R.string.import_patch_selection_description
|
||||
)
|
||||
GroupItem(
|
||||
onClick = vm::exportSelection,
|
||||
headline = R.string.export_patch_selection,
|
||||
description = R.string.export_patch_selection_description
|
||||
)
|
||||
// TODO: allow resetting selection for specific bundle or package name.
|
||||
GroupItem(
|
||||
onClick = vm::resetSelection,
|
||||
headline = R.string.reset_patch_selection,
|
||||
description = R.string.reset_patch_selection_description
|
||||
)
|
||||
|
||||
var showPackageSelector by rememberSaveable {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
@ -131,108 +156,37 @@ fun BackupRestoreSettingsScreen(
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
if (showPackageSelector) {
|
||||
if (showPackageSelector)
|
||||
PackageSelector(packages = packagesWithOptions) { selected ->
|
||||
selected?.let(viewModel::resetOptionsForPackage)
|
||||
selected?.let(vm::resetOptionsForPackage)
|
||||
|
||||
showPackageSelector = false
|
||||
}
|
||||
}
|
||||
|
||||
if (showBundleSelector) {
|
||||
if (showBundleSelector)
|
||||
BundleSelector(bundles = patchBundles) { bundle ->
|
||||
bundle?.let(viewModel::clearOptionsForBundle)
|
||||
bundle?.let(vm::clearOptionsForBundle)
|
||||
|
||||
showBundleSelector = false
|
||||
}
|
||||
}
|
||||
|
||||
GroupHeader(stringResource(R.string.keystore))
|
||||
GroupItem(
|
||||
onClick = {
|
||||
if (!viewModel.canExport()) {
|
||||
context.toast(context.getString(R.string.backup_keystore_unavailable))
|
||||
return@GroupItem
|
||||
}
|
||||
exportKeystoreLauncher.launch("Manager.keystore")
|
||||
},
|
||||
headline = R.string.backup,
|
||||
description = R.string.backup_keystore_description
|
||||
)
|
||||
GroupItem(
|
||||
onClick = {
|
||||
importKeystoreLauncher.launch("*/*")
|
||||
},
|
||||
headline = R.string.restore,
|
||||
description = R.string.restore_keystore_description
|
||||
)
|
||||
GroupItem(
|
||||
onClick = viewModel::regenerateKeystore,
|
||||
headline = {
|
||||
Text(
|
||||
stringResource(R.string.regenerate_keystore),
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
},
|
||||
description = R.string.regenerate_keystore_description
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.patch_selection))
|
||||
GroupItem(
|
||||
onClick = viewModel::exportSelection,
|
||||
headline = R.string.backup,
|
||||
description = R.string.restore_patch_selection_description
|
||||
)
|
||||
GroupItem(
|
||||
onClick = viewModel::importSelection,
|
||||
headline = R.string.restore,
|
||||
description = R.string.backup_patch_selection_description
|
||||
)
|
||||
GroupItem(
|
||||
onClick = viewModel::resetSelection, // TODO: allow resetting selection for specific bundle or package name.
|
||||
headline = {
|
||||
Text(
|
||||
stringResource(R.string.reset),
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
},
|
||||
description = R.string.reset_patch_selection_description
|
||||
)
|
||||
|
||||
GroupHeader(stringResource(R.string.patch_options))
|
||||
// TODO: patch options import/export.
|
||||
GroupItem(
|
||||
onClick = viewModel::resetOptions,
|
||||
headline = {
|
||||
Text(
|
||||
stringResource(R.string.reset),
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
},
|
||||
onClick = vm::resetOptions,
|
||||
headline = R.string.patch_options_reset_all,
|
||||
description = R.string.patch_options_reset_all_description,
|
||||
)
|
||||
GroupItem(
|
||||
onClick = { showPackageSelector = true },
|
||||
headline = {
|
||||
Text(
|
||||
stringResource(R.string.patch_options_reset_package),
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
},
|
||||
headline = R.string.patch_options_reset_package,
|
||||
description = R.string.patch_options_reset_package_description
|
||||
)
|
||||
if (patchBundles.size > 1) {
|
||||
if (patchBundles.size > 1)
|
||||
GroupItem(
|
||||
onClick = { showBundleSelector = true },
|
||||
headline = {
|
||||
Text(
|
||||
stringResource(R.string.patch_options_reset_bundle),
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
},
|
||||
headline = R.string.patch_options_reset_bundle,
|
||||
description = R.string.patch_options_reset_bundle_description,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -308,19 +262,6 @@ private fun GroupItem(
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun GroupItem(
|
||||
onClick: () -> Unit,
|
||||
headline: @Composable () -> Unit,
|
||||
@StringRes description: Int? = null
|
||||
) {
|
||||
SettingsListItem(
|
||||
modifier = Modifier.clickable { onClick() },
|
||||
headlineContent = headline,
|
||||
supportingContent = description?.let { stringResource(it) }
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun KeystoreCredentialsDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
@ -337,7 +278,7 @@ fun KeystoreCredentialsDialog(
|
||||
onSubmit(cn, pass)
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.restore_keystore_dialog_button))
|
||||
Text(stringResource(R.string.import_keystore_dialog_button))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
@ -350,7 +291,7 @@ fun KeystoreCredentialsDialog(
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(R.string.restore_keystore_dialog_title),
|
||||
text = stringResource(R.string.import_keystore_dialog_title),
|
||||
style = MaterialTheme.typography.headlineSmall.copy(textAlign = TextAlign.Center),
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
@ -361,19 +302,19 @@ fun KeystoreCredentialsDialog(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.restore_keystore_dialog_description),
|
||||
text = stringResource(R.string.import_keystore_dialog_description),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = cn,
|
||||
onValueChange = { cn = it },
|
||||
label = { Text(stringResource(R.string.restore_keystore_dialog_alias_field)) }
|
||||
label = { Text(stringResource(R.string.import_keystore_dialog_alias_field)) }
|
||||
)
|
||||
PasswordField(
|
||||
value = pass,
|
||||
onValueChange = { pass = it },
|
||||
label = { Text(stringResource(R.string.restore_keystore_dialog_password_field)) }
|
||||
label = { Text(stringResource(R.string.import_keystore_dialog_password_field)) }
|
||||
)
|
||||
}
|
||||
}
|
@ -7,12 +7,9 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -31,17 +28,13 @@ fun ChangelogsScreen(
|
||||
onBackClick: () -> Unit,
|
||||
vm: ChangelogsViewModel = koinViewModel()
|
||||
) {
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.changelog),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
},
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
}
|
||||
) { paddingValues ->
|
||||
ColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
|
@ -0,0 +1,75 @@
|
||||
package app.revanced.manager.ui.screen.settings.update
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.revanced.manager.R
|
||||
import app.revanced.manager.ui.component.AppTopBar
|
||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||
import app.revanced.manager.ui.component.settings.BooleanItem
|
||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
||||
import app.revanced.manager.ui.viewmodel.UpdatesSettingsViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun UpdatesSettingsScreen(
|
||||
onBackClick: () -> Unit,
|
||||
onChangelogClick: () -> Unit,
|
||||
onUpdateClick: () -> Unit,
|
||||
vm: UpdatesSettingsViewModel = koinViewModel(),
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppTopBar(
|
||||
title = stringResource(R.string.updates),
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
ColumnWithScrollbar(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
) {
|
||||
SettingsListItem(
|
||||
modifier = Modifier.clickable {
|
||||
coroutineScope.launch {
|
||||
if (vm.checkForUpdates()) onUpdateClick()
|
||||
}
|
||||
},
|
||||
headlineContent = stringResource(R.string.manual_update_check),
|
||||
supportingContent = stringResource(R.string.manual_update_check_description)
|
||||
)
|
||||
|
||||
SettingsListItem(
|
||||
modifier = Modifier.clickable(onClick = onChangelogClick),
|
||||
headlineContent = stringResource(R.string.changelog),
|
||||
supportingContent = stringResource(
|
||||
R.string.changelog_description
|
||||
)
|
||||
)
|
||||
|
||||
BooleanItem(
|
||||
preference = vm.managerAutoUpdates,
|
||||
headline = R.string.update_checking_manager,
|
||||
description = R.string.update_checking_manager_description
|
||||
)
|
||||
|
||||
BooleanItem(
|
||||
preference = vm.showManagerUpdateDialogOnLaunch,
|
||||
headline = R.string.show_manager_update_dialog_on_launch,
|
||||
description = R.string.update_checking_manager_description
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ class AdvancedSettingsViewModel(
|
||||
return "revanced-manager_logcat_$time"
|
||||
}
|
||||
|
||||
fun setApiSource(value: String) = viewModelScope.launch(Dispatchers.Default) {
|
||||
fun setApiUrl(value: String) = viewModelScope.launch(Dispatchers.Default) {
|
||||
if (value == prefs.api.get()) return@launch
|
||||
|
||||
prefs.api.update(value)
|
||||
|
@ -24,10 +24,4 @@ class DeveloperOptionsViewModel(
|
||||
fun resetBundles() = viewModelScope.launch {
|
||||
patchBundleRepository.reset()
|
||||
}
|
||||
|
||||
fun disableSafeguard() = viewModelScope.launch {
|
||||
prefs.disablePatchVersionCompatCheck.update(true)
|
||||
prefs.disableSelectionWarning.update(true)
|
||||
prefs.disableUniversalPatchWarning.update(true)
|
||||
}
|
||||
}
|
@ -69,27 +69,25 @@ class ImportExportViewModel(
|
||||
}
|
||||
|
||||
fun startKeystoreImport(content: Uri) = viewModelScope.launch {
|
||||
uiSafe(app, R.string.failed_to_import_keystore, "Failed to import keystore") {
|
||||
val path = withContext(Dispatchers.IO) {
|
||||
File.createTempFile("signing", "ks", app.cacheDir).toPath().also {
|
||||
Files.copy(
|
||||
contentResolver.openInputStream(content)!!,
|
||||
it,
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
)
|
||||
}
|
||||
val path = withContext(Dispatchers.IO) {
|
||||
File.createTempFile("signing", "ks", app.cacheDir).toPath().also {
|
||||
Files.copy(
|
||||
contentResolver.openInputStream(content)!!,
|
||||
it,
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
)
|
||||
}
|
||||
|
||||
aliases.forEach { alias ->
|
||||
knownPasswords.forEach { pass ->
|
||||
if (tryKeystoreImport(alias, pass, path)) {
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keystoreImportPath = path
|
||||
}
|
||||
|
||||
aliases.forEach { alias ->
|
||||
knownPasswords.forEach { pass ->
|
||||
if (tryKeystoreImport(alias, pass, path)) {
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keystoreImportPath = path
|
||||
}
|
||||
|
||||
fun cancelKeystoreImport() {
|
||||
@ -103,7 +101,7 @@ class ImportExportViewModel(
|
||||
private suspend fun tryKeystoreImport(cn: String, pass: String, path: Path): Boolean {
|
||||
path.inputStream().use { stream ->
|
||||
if (keystoreManager.import(cn, pass, stream)) {
|
||||
app.toast(app.getString(R.string.restore_keystore_success))
|
||||
app.toast(app.getString(R.string.import_keystore_success))
|
||||
cancelKeystoreImport()
|
||||
return true
|
||||
}
|
||||
@ -122,7 +120,7 @@ class ImportExportViewModel(
|
||||
|
||||
fun exportKeystore(target: Uri) = viewModelScope.launch {
|
||||
keystoreManager.export(contentResolver.openOutputStream(target)!!)
|
||||
app.toast(app.getString(R.string.backup_keystore_success))
|
||||
app.toast(app.getString(R.string.export_keystore_success))
|
||||
}
|
||||
|
||||
fun regenerateKeystore() = viewModelScope.launch {
|
||||
@ -171,7 +169,7 @@ class ImportExportViewModel(
|
||||
override val activityArg = JSON_MIMETYPE
|
||||
override suspend fun execute(bundleUid: Int, location: Uri) = uiSafe(
|
||||
app,
|
||||
R.string.restore_patch_selection_fail,
|
||||
R.string.import_patch_selection_fail,
|
||||
"Failed to restore patch selection"
|
||||
) {
|
||||
val selection = withContext(Dispatchers.IO) {
|
||||
@ -181,7 +179,7 @@ class ImportExportViewModel(
|
||||
}
|
||||
|
||||
selectionRepository.import(bundleUid, selection)
|
||||
app.toast(app.getString(R.string.restore_patch_selection_success))
|
||||
app.toast(app.getString(R.string.import_patch_selection_success))
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +188,7 @@ class ImportExportViewModel(
|
||||
override val activityArg = "selection.json"
|
||||
override suspend fun execute(bundleUid: Int, location: Uri) = uiSafe(
|
||||
app,
|
||||
R.string.backup_patch_selection_fail,
|
||||
R.string.export_patch_selection_fail,
|
||||
"Failed to backup patch selection"
|
||||
) {
|
||||
val selection = selectionRepository.export(bundleUid)
|
||||
@ -200,7 +198,7 @@ class ImportExportViewModel(
|
||||
Json.Default.encodeToStream(selection, it)
|
||||
}
|
||||
}
|
||||
app.toast(app.getString(R.string.backup_patch_selection_success))
|
||||
app.toast(app.getString(R.string.export_patch_selection_success))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,8 +137,8 @@ class MainViewModel(
|
||||
updateCheck()
|
||||
}
|
||||
}
|
||||
settings.patchesChangeEnabled?.let { allowChangingPatchSelection ->
|
||||
prefs.allowChangingPatchSelection.update(allowChangingPatchSelection)
|
||||
settings.patchesChangeEnabled?.let { disableSelectionWarning ->
|
||||
prefs.disableSelectionWarning.update(disableSelectionWarning)
|
||||
}
|
||||
settings.keystore?.let { keystore ->
|
||||
val keystoreBytes = Base64.decode(keystore, Base64.DEFAULT)
|
||||
|
@ -66,7 +66,7 @@ class PatchesSelectorViewModel(input: SelectedApplicationInfo.PatchesSelector.Vi
|
||||
viewModelScope.launch {
|
||||
universalPatchWarningEnabled = !prefs.disableUniversalPatchWarning.get()
|
||||
|
||||
if (prefs.allowChangingPatchSelection.get()) {
|
||||
if (prefs.disableSelectionWarning.get()) {
|
||||
selectionWarningEnabled = false
|
||||
return@launch
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ class SelectedAppInfoViewModel(
|
||||
|
||||
// Try to get the previous selection if customization is enabled.
|
||||
viewModelScope.launch {
|
||||
if (!prefs.allowChangingPatchSelection.get()) return@launch
|
||||
if (!prefs.disableSelectionWarning.get()) return@launch
|
||||
|
||||
val previous = selectionRepository.getSelection(packageName)
|
||||
if (previous.values.sumOf { it.size } == 0) return@launch
|
||||
|
@ -108,19 +108,14 @@ class UpdateViewModel(
|
||||
val extra =
|
||||
intent.getStringExtra(InstallService.EXTRA_INSTALL_STATUS_MESSAGE)!!
|
||||
|
||||
when(pmStatus) {
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
app.toast(app.getString(R.string.install_app_success))
|
||||
state = State.SUCCESS
|
||||
}
|
||||
PackageInstaller.STATUS_FAILURE_ABORTED -> {
|
||||
state = State.CAN_INSTALL
|
||||
}
|
||||
else -> {
|
||||
app.toast(app.getString(R.string.install_app_fail, extra))
|
||||
installError = extra
|
||||
state = State.FAILED
|
||||
}
|
||||
if (pmStatus == PackageInstaller.STATUS_SUCCESS) {
|
||||
app.toast(app.getString(R.string.install_app_success))
|
||||
state = State.SUCCESS
|
||||
} else {
|
||||
state = State.FAILED
|
||||
// TODO: handle install fail with a popup
|
||||
installError = extra
|
||||
app.toast(app.getString(R.string.install_app_fail, extra))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,8 @@
|
||||
<string name="cli">CLI</string>
|
||||
<string name="manager">Manager</string>
|
||||
|
||||
<string name="revanced_patcher">ReVanced Patcher</string>
|
||||
|
||||
<string name="plugin_host_permission_label">ReVanced Manager plugin host</string>
|
||||
<string name="plugin_host_permission_description">Used to control access to ReVanced Manager
|
||||
plugins. Only ReVanced Manager has this.</string>
|
||||
<string name="plugin_host_permission_description">Used to control access to ReVanced Manager plugins. Only ReVanced Manager has this.</string>
|
||||
|
||||
<string name="toast_copied_to_clipboard">Copied!</string>
|
||||
<string name="copy_to_clipboard">Copy to clipboard</string>
|
||||
@ -19,10 +16,8 @@
|
||||
<string name="select_app">Select an app</string>
|
||||
<string name="patches_selected">%1$d/%2$d selected</string>
|
||||
|
||||
<string name="new_downloader_plugins_notification">New downloader plugins available. Click here
|
||||
to configure them.</string>
|
||||
<string name="unsupported_architecture_warning">Patching on this device architecture is
|
||||
unsupported and will most likely fail.</string>
|
||||
<string name="new_downloader_plugins_notification">New downloader plugins available. Click here to configure them.</string>
|
||||
<string name="unsupported_architecture_warning">Patching on this device architecture is unsupported and will most likely fail.</string>
|
||||
|
||||
<string name="import_">Import</string>
|
||||
<string name="import_bundle">Import patch bundle</string>
|
||||
@ -41,20 +36,15 @@
|
||||
<string name="bundle_name_fallback">Unnamed</string>
|
||||
|
||||
<string name="android_11_bug_dialog_title">Android 11 bug</string>
|
||||
<string name="android_11_bug_dialog_description">The app installation permission must be granted
|
||||
ahead of time to avoid a bug in the Android 11 system that will negatively affect the user
|
||||
experience.</string>
|
||||
<string name="android_11_bug_dialog_description">The app installation permission must be granted ahead of time to avoid a bug in the Android 11 system that will negatively affect the user experience.</string>
|
||||
|
||||
<string name="selected_app_meta_any_version">Any available version</string>
|
||||
<string name="app_source_dialog_title">Select source</string>
|
||||
<string name="app_source_dialog_option_auto">Auto</string>
|
||||
<string name="app_source_dialog_option_auto_description">Use all installed downloaders to find a
|
||||
suitable APK file</string>
|
||||
<string name="app_source_dialog_option_auto_description">Use all installed downloaders to find a suitable APK file</string>
|
||||
<string name="app_source_dialog_option_auto_unavailable">No plugins available</string>
|
||||
<string name="app_source_dialog_option_installed_no_root">Mounted apps cannot be patched again
|
||||
without root access</string>
|
||||
<string name="app_source_dialog_option_installed_version_not_suggested">Version %s does not
|
||||
match the suggested version</string>
|
||||
<string name="app_source_dialog_option_installed_no_root">Mounted apps cannot be patched again without root access</string>
|
||||
<string name="app_source_dialog_option_installed_version_not_suggested">Version %s does not match the suggested version</string>
|
||||
|
||||
<string name="patch_item_description">Start patching the application</string>
|
||||
<string name="patch_selector_item">Patch selection and options</string>
|
||||
@ -70,91 +60,77 @@
|
||||
<string name="legacy_import_failed">Could not import legacy settings</string>
|
||||
|
||||
<string name="auto_updates_dialog_title">Configure updates</string>
|
||||
<string name="auto_updates_dialog_description">Do you want ReVanced Manager to periodically
|
||||
check for updates for the following components?</string>
|
||||
<string name="auto_updates_dialog_description">Do you want ReVanced Manager to periodically check for updates for the following components?</string>
|
||||
<string name="auto_updates_dialog_manager">ReVanced Manager</string>
|
||||
<string name="auto_updates_dialog_patches">ReVanced Patches</string>
|
||||
<string name="auto_updates_dialog_note">These settings can be changed later.</string>
|
||||
|
||||
<string name="general">General</string>
|
||||
<string name="general_description">Appearances, Updates</string>
|
||||
|
||||
<string name="general_description">Theme, dynamic color</string>
|
||||
<string name="updates">Updates</string>
|
||||
<string name="updates_description">Check for updates and view changelogs</string>
|
||||
|
||||
<string name="extensions">Extensions</string>
|
||||
<string name="extensions_description">Downloader plugins, downloaded apps</string>
|
||||
<string name="backup_restore">Backup & Restore</string>
|
||||
<string name="backup_restore_description">Keystore, Patch selections, Patch options</string>
|
||||
<string name="downloads">Downloads</string>
|
||||
<string name="downloads_description">Downloader plugins and downloaded apps</string>
|
||||
<string name="import_export">Import & export</string>
|
||||
<string name="import_export_description">Keystore, patch options and selection</string>
|
||||
<string name="advanced">Advanced</string>
|
||||
<string name="advanced_description">API Source, memory limits, debug logs</string>
|
||||
<string name="experimental_features">Experimental features</string>
|
||||
|
||||
|
||||
<string name="advanced_description">API URL, memory limit, debugging</string>
|
||||
<string name="about">About</string>
|
||||
<string name="opensource_licenses">Open source licenses</string>
|
||||
<string name="opensource_licenses_description">View all the libraries used to make this
|
||||
application</string>
|
||||
<string name="opensource_licenses_description">View all the libraries used to make this application</string>
|
||||
|
||||
<string name="contributors">Contributors</string>
|
||||
<string name="contributors_description">View the contributors of ReVanced</string>
|
||||
<string name="personalized_color">Personalized color</string>
|
||||
<string name="personalized_color_description">Use color provided by your device\'s palette</string>
|
||||
<string name="theme_mode">Theme mode</string>
|
||||
<string name="theme_mode_description">Choose between light, dark, and system provided mode</string>
|
||||
<string name="dynamic_color">Dynamic color</string>
|
||||
<string name="dynamic_color_description">Adapt colors to the wallpaper</string>
|
||||
<string name="theme">Theme</string>
|
||||
<string name="theme_description">Choose between light or dark theme</string>
|
||||
<string name="safeguards">Safeguards</string>
|
||||
<string name="allow_compatibility_mixing">Allow unsupported compatibility</string>
|
||||
<string name="allow_compatibility_mixing_description">Permit apps and patches to be mixed in
|
||||
unsupported state</string>
|
||||
<string name="allow_compatibility_mixing_confirmation">Selecting incompatible patches can result
|
||||
in a broken app.\n\nAllow anyways?</string>
|
||||
<string name="patch_compat_check">Disable version compatibility check</string>
|
||||
<string name="patch_compat_check_description">The check restricts patches to supported app versions</string>
|
||||
<string name="patch_compat_check_confirmation">Selecting incompatible patches can result in a broken app.\n\nDo you want to proceed anyways?</string>
|
||||
<string name="suggested_version_safeguard">Require suggested app version</string>
|
||||
<string name="suggested_version_safeguard_description">Enforce selection of the suggested app version</string>
|
||||
<string name="suggested_version_safeguard_confirmation">Selecting an app that is not the suggested version may cause unexpected issues.\n\nDo you want to proceed anyways?</string>
|
||||
<string name="patch_selection_safeguard">Allow changing patch selection</string>
|
||||
<string name="patch_selection_safeguard_description">Permit selecting or deselecting patches
|
||||
from default</string>
|
||||
<string name="patch_selection_safeguard_confirmation">Changing the selection of patches may
|
||||
cause unexpected issues.\n\nAllow anyways?</string>
|
||||
<string name="universal_patches_safeguard">Allow universal patch</string>
|
||||
<string name="universal_patches_safeguard_description">Permit selecting app\'s generic patch</string>
|
||||
<string name="universal_patches_safeguard_confirmation">Universal patch are not as well tested
|
||||
as those that target specific apps.\n\nAllow anyways?</string>
|
||||
<string name="backup">Backup</string>
|
||||
<string name="restore">Restore</string>
|
||||
<string name="keystore">Keystore</string>
|
||||
<string name="patch_selection">Patch selection</string>
|
||||
<string name="patch_options">Patch options</string>
|
||||
<string name="restore_keystore_description">Restore keystore from external source</string>
|
||||
<string name="restore_keystore_dialog_title">Enter keystore credentials</string>
|
||||
<string name="restore_keystore_dialog_description">You\'ll need enter the keystore’s credentials
|
||||
to restore it.</string>
|
||||
<string name="restore_keystore_dialog_alias_field">Username (Alias)</string>
|
||||
<string name="restore_keystore_dialog_password_field">Password</string>
|
||||
<string name="restore_keystore_dialog_button">Import</string>
|
||||
<string name="restore_keystore_wrong_credentials">Wrong keystore credentials</string>
|
||||
<string name="restore_keystore_success">Keystore successfully restored</string>
|
||||
<string name="backup_keystore_description">Export app’s keystore into usable file</string>
|
||||
<string name="backup_keystore_unavailable">No keystore to backup</string>
|
||||
<string name="backup_keystore_success">Keystore successfully backed up</string>
|
||||
<string name="regenerate_keystore">Regeneration</string>
|
||||
<string name="regenerate_keystore_description">Replace current keystore with new one</string>
|
||||
<string name="patch_selection_safeguard_description">Do not prevent selecting or deselecting patches</string>
|
||||
<string name="patch_selection_safeguard_confirmation">Changing the selection of patches may cause unexpected issues.\n\nEnable anyways?</string>
|
||||
<string name="universal_patches_safeguard">Disable universal patch warning</string>
|
||||
<string name="universal_patches_safeguard_description">Disables the warning that appears when you try to select universal patches</string>
|
||||
<string name="universal_patches_safeguard_confirmation">Universal patches are not as well tested as those that target specific apps.\n\nEnable anyways?</string>
|
||||
<string name="import_keystore">Import keystore</string>
|
||||
<string name="import_keystore_description">Import a custom keystore</string>
|
||||
<string name="import_keystore_dialog_title">Enter keystore credentials</string>
|
||||
<string name="import_keystore_dialog_description">You\'ll need enter the keystore’s credentials to import it.</string>
|
||||
<string name="import_keystore_dialog_alias_field">Username (Alias)</string>
|
||||
<string name="import_keystore_dialog_password_field">Password</string>
|
||||
<string name="import_keystore_dialog_button">Import</string>
|
||||
<string name="import_keystore_wrong_credentials">Wrong keystore credentials</string>
|
||||
<string name="import_keystore_success">Imported keystore</string>
|
||||
<string name="export_keystore">Export keystore</string>
|
||||
<string name="export_keystore_description">Export the current keystore</string>
|
||||
<string name="export_keystore_unavailable">No keystore to export</string>
|
||||
<string name="export_keystore_success">Exported keystore</string>
|
||||
<string name="regenerate_keystore">Regenerate keystore</string>
|
||||
<string name="regenerate_keystore_description">Generate a new keystore</string>
|
||||
<string name="regenerate_keystore_success">The keystore has been successfully replaced</string>
|
||||
<string name="restore_patch_selection_description">Export app’s patch selections into usable
|
||||
file</string>
|
||||
<string name="restore_patch_selection_fail">Could not import patch selection: %s</string>
|
||||
<string name="restore_patch_selection_success">Patch selection successfully restored</string>
|
||||
<string name="backup_patch_selection_description">Import app’s patch selections from external
|
||||
source</string>
|
||||
<string name="backup_patch_selection_fail">Could not backup patch selection: %s</string>
|
||||
<string name="backup_patch_selection_success">Patch selection successfully restored</string>
|
||||
<string name="import_patch_selection">Import patch selection</string>
|
||||
<string name="import_patch_selection_description">Import patch selection from a JSON file</string>
|
||||
<string name="import_patch_selection_fail">Could not import patch selection: %s</string>
|
||||
<string name="import_patch_selection_success">Imported patch selection</string>
|
||||
<string name="export_patch_selection">Export patch selection</string>
|
||||
<string name="export_patch_selection_description">Export patch selection to a JSON file</string>
|
||||
<string name="export_patch_selection_fail">Could not export patch selection: %s</string>
|
||||
<string name="export_patch_selection_success">Exported patch selection</string>
|
||||
<string name="reset_patch_selection">Reset patch selection</string>
|
||||
<string name="reset_patch_selection_description">Reset the stored patch selection</string>
|
||||
<string name="reset_patch_selection_success">Patch selection successfully reset</string>
|
||||
<string name="patch_options_reset_package">Reset for app</string>
|
||||
<string name="patch_options_reset_package_description">Use the default patch options
|
||||
configuration for a single app</string>
|
||||
<string name="patch_options_reset_bundle">Reset for bundle</string>
|
||||
<string name="patch_options_reset_bundle_description">Use the default patch options
|
||||
configuration for all patches in a bundle</string>
|
||||
<string name="patch_options_reset_all_description">Use the default patch options configuration</string>
|
||||
<string name="reset_patch_selection_success">Patch selection has been reset</string>
|
||||
<string name="patch_options_reset_package">Reset patch options for app</string>
|
||||
<string name="patch_options_reset_package_description">Resets patch options for a single app</string>
|
||||
<string name="patch_options_reset_bundle">Resets patch options for bundle</string>
|
||||
<string name="patch_options_reset_bundle_description">Resets patch options for all patches in a bundle</string>
|
||||
<string name="patch_options_reset_all">Reset patch options</string>
|
||||
<string name="patch_options_reset_all_description">Resets all patch options</string>
|
||||
<string name="downloader_plugins">Plugins</string>
|
||||
<string name="downloader_plugin_state_trusted">Trusted</string>
|
||||
<string name="downloader_plugin_state_failed">Failed to load. Click for more details</string>
|
||||
@ -194,25 +170,21 @@
|
||||
<string name="dark">Dark</string>
|
||||
<string name="appearance">Appearance</string>
|
||||
<string name="downloaded_apps">Downloaded apps</string>
|
||||
<string name="process_runtime">Run patcher in another process</string>
|
||||
<string name="process_runtime_description">Faster and allows patcher to use more memory</string>
|
||||
<string name="process_runtime">Run Patcher in another process (experimental)</string>
|
||||
<string name="process_runtime_description">This is faster and allows Patcher to use more memory.</string>
|
||||
<string name="process_runtime_memory_limit">Patcher process memory limit</string>
|
||||
<string name="process_runtime_memory_limit_description">The max amount of memory that the
|
||||
patcher process can use (in megabytes)</string>
|
||||
<string name="process_runtime_memory_limit_description">The max amount of memory that the Patcher process can use (in megabytes)</string>
|
||||
<string name="debug_logs_export">Export debug logs</string>
|
||||
<string name="debug_logs_export_read_failed">Failed to read logs (exit code %d)</string>
|
||||
<string name="debug_logs_export_failed">Failed to export logs</string>
|
||||
<string name="debug_logs_export_success">Exported logs</string>
|
||||
<string name="api_url">API Source</string>
|
||||
<string name="api_url_dialog_title">Set custom API Source</string>
|
||||
<string name="api_url_dialog_description">Set the API Source of ReVanced Manager. ReVanced
|
||||
Manager uses the API to download patches and updates.</string>
|
||||
<string name="api_url_dialog_warning">ReVanced Manager connects to the API to download patches
|
||||
and updates. Make sure that you trust it.</string>
|
||||
<string name="api_url">API URL</string>
|
||||
<string name="api_url_description">The API used to download necessary files.</string>
|
||||
<string name="api_url_dialog_title">Set custom API URL</string>
|
||||
<string name="api_url_dialog_description">Set the API URL of ReVanced Manager. ReVanced Manager uses the API to download patches and updates.</string>
|
||||
<string name="api_url_dialog_warning">ReVanced Manager connects to the API to download patches and updates. Make sure that you trust it.</string>
|
||||
<string name="api_url_dialog_save">Set</string>
|
||||
<string name="api_url_dialog_reset">Reset API Source</string>
|
||||
<string name="testing">Testing</string>
|
||||
<string name="disable_safeguard">Disable all safeguards</string>
|
||||
<string name="api_url_dialog_reset">Reset API URL</string>
|
||||
<string name="device">Device</string>
|
||||
<string name="device_android_version">Android version</string>
|
||||
<string name="device_model">Model</string>
|
||||
@ -241,32 +213,22 @@
|
||||
<string name="bundles_selected">%s selected</string>
|
||||
<string name="unsupported_patches">Incompatible patches</string>
|
||||
<string name="universal_patches">Universal patches</string>
|
||||
<string name="patch_selection_reset_toast">Patch selection and options has been reset to
|
||||
recommended defaults</string>
|
||||
<string name="patch_selection_reset_toast">Patch selection and options has been reset to recommended defaults</string>
|
||||
<string name="patch_options_reset_toast">Patch options have been reset</string>
|
||||
<string name="non_suggested_version_warning_title">Non suggested version</string>
|
||||
<string name="non_suggested_version_warning_description">The version of the app you have
|
||||
selected does not match the suggested version.\nPlease use the suggested version: %s\n\nTo
|
||||
continue anyway, disable \"Require suggested app version\" in the advanced settings.</string>
|
||||
<string name="non_suggested_version_warning_description">The version of the app you have selected does not match the suggested version.\nPlease use the suggested version: %s\n\nTo continue anyway, disable \"Require suggested app version\" in the advanced settings.</string>
|
||||
<string name="selection_warning_title">Stop using defaults?</string>
|
||||
<string name="selection_warning_description">It is recommended to use the default patch
|
||||
selection and options. Changing them may result in unexpected issues.\n\nYou need to turn on
|
||||
\"Allow changing patch selection\" in the advanced settings before toggling patches.</string>
|
||||
<string name="universal_patch_warning_description">Universal patches have a more generalized use
|
||||
and do not work as reliably as patches that target specific apps. You may encounter issues
|
||||
while using them.\n\nThis warning can be disabled in the advanced settings.</string>
|
||||
<string name="selection_warning_description">It is recommended to use the default patch selection and options. Changing them may result in unexpected issues.\n\nYou need to turn on \"Allow changing patch selection\" in the advanced settings before toggling patches.</string>
|
||||
<string name="universal_patch_warning_description">Universal patches have a more generalized use and do not work as reliably as patches that target specific apps. You may encounter issues while using them.\n\nThis warning can be disabled in the advanced settings.</string>
|
||||
<string name="supported">This version</string>
|
||||
<string name="universal">Any app</string>
|
||||
<string name="unsupported">Unsupported</string>
|
||||
<string name="search_patches">Search patches</string>
|
||||
<string name="app_not_supported">This patch is not compatible with the selected app version
|
||||
(%1$s).\n\nIt only supports the following version(s): %2$s.</string>
|
||||
<string name="app_not_supported">This patch is not compatible with the selected app version (%1$s).\n\nIt only supports the following version(s): %2$s.</string>
|
||||
<string name="continue_with_version">Continue with this version?</string>
|
||||
<string name="version_not_supported">Not all patches support this version (%s). Do you want to
|
||||
continue anyway?</string>
|
||||
<string name="version_not_supported">Not all patches support this version (%s). Do you want to continue anyway?</string>
|
||||
<string name="download_application">Download application?</string>
|
||||
<string name="app_not_installed">The app you selected isn\'t installed. Do you want to download
|
||||
it?</string>
|
||||
<string name="app_not_installed">The app you selected isn\'t installed. Do you want to download it?</string>
|
||||
<string name="failed_to_load_apk">Failed to load APK</string>
|
||||
<string name="loading">Loading…</string>
|
||||
<string name="not_installed">Not installed</string>
|
||||
@ -296,8 +258,7 @@
|
||||
<string name="downloader_app_not_found">Downloader did not find the app</string>
|
||||
<string name="downloader_error">Downloader error: %s</string>
|
||||
<string name="downloader_no_plugins_installed">No plugins installed.</string>
|
||||
<string name="downloader_no_plugins_available">No trusted plugins available for use. Check your
|
||||
settings.</string>
|
||||
<string name="downloader_no_plugins_available">No trusted plugins available for use. Check your settings.</string>
|
||||
<string name="already_patched">Already patched</string>
|
||||
|
||||
<string name="patch_selector_sheet_filter_title">Filter</string>
|
||||
@ -325,8 +286,7 @@
|
||||
<string name="save_apk_success">APK Saved</string>
|
||||
<string name="sign_fail">Failed to sign APK: %s</string>
|
||||
<string name="save_logs">Save logs</string>
|
||||
<string name="plugin_activity_dialog_body">User interaction is required in order to proceed with
|
||||
this plugin.</string>
|
||||
<string name="plugin_activity_dialog_body">User interaction is required in order to proceed with this plugin.</string>
|
||||
<string name="select_install_type">Select installation type</string>
|
||||
|
||||
<string name="patcher_step_group_preparing">Preparing</string>
|
||||
@ -368,33 +328,28 @@
|
||||
<string name="bundle_update_success">Successfully updated %s</string>
|
||||
<string name="bundle_update_unavailable">No update available for %s</string>
|
||||
<string name="bundle_auto_update">Auto update</string>
|
||||
<string name="bundle_auto_update_description">Automatically update this bundle when ReVanced
|
||||
starts</string>
|
||||
<string name="bundle_auto_update_description">Automatically update this bundle when ReVanced starts</string>
|
||||
<string name="bundle_view_patches">View patches</string>
|
||||
<string name="bundle_view_patches_any_version">Any version</string>
|
||||
<string name="bundle_view_patches_any_package">Any package</string>
|
||||
|
||||
<string name="about_revanced_manager">About ReVanced Manager</string>
|
||||
<string name="revanced_manager_description">ReVanced Manager is an application designed to work
|
||||
with ReVanced Patcher, which allows for long-lasting patches to be created for Android apps.
|
||||
The patching system is designed to automatically work with new versions of apps with minimal
|
||||
maintenance.</string>
|
||||
<string name="revanced_manager_description">ReVanced Manager is an application designed to work with ReVanced Patcher, which allows for long-lasting patches to be created for Android apps. The patching system is designed to automatically work with new versions of apps with minimal maintenance.</string>
|
||||
<string name="update_available">An update is available</string>
|
||||
<string name="current_version">Current version: %s</string>
|
||||
<string name="new_version">New version: %s</string>
|
||||
<string name="ready_to_install_update">Ready to install update</string>
|
||||
<string name="update_completed">Update installed</string>
|
||||
<string name="install_update_manager_failed">Failed to install update</string>
|
||||
<string name="check_for_update">Check for update</string>
|
||||
<string name="check_for_update_auto_description">Automatically check for new version when the
|
||||
app launched</string>
|
||||
<string name="manual_update_check">Check for updates</string>
|
||||
<string name="manual_update_check_description">Manually check for updates</string>
|
||||
<string name="update_checking_manager">Auto check for updates</string>
|
||||
<string name="update_checking_manager_description">Check for new versions of ReVanced Manager when the application starts</string>
|
||||
<string name="changelog">View changelogs</string>
|
||||
<string name="changelog_loading">Loading changelog</string>
|
||||
<string name="changelog_download_fail">Failed to download changelog: %s</string>
|
||||
<string name="changelog_description">Check out the latest changes in this update</string>
|
||||
<string name="battery_optimization_notification">Battery optimizations must be turned off in
|
||||
order for ReVanced Manager to work correctly in the background. Click here to turn off
|
||||
optimizations.</string>
|
||||
<string name="battery_optimization_notification">Battery optimizations must be turned off in order for ReVanced Manager to work correctly in the background. Click here to turn off optimizations.</string>
|
||||
<string name="installing_manager_update">Installing update…</string>
|
||||
<string name="downloading_manager_update">Downloading update…</string>
|
||||
<string name="download_manager_failed">Failed to download update: %s</string>
|
||||
@ -403,8 +358,7 @@
|
||||
<string name="save_with_count">Save (%1$s)</string>
|
||||
<string name="update">Update</string>
|
||||
<string name="empty">Empty</string>
|
||||
<string name="installing_message">Tap on <b>Update</b> when prompted. \n ReVanced Manager will
|
||||
close when updating.</string>
|
||||
<string name="installing_message">Tap on <b>Update</b> when prompted. \n ReVanced Manager will close when updating.</string>
|
||||
<string name="no_changelogs_found">No changelogs found</string>
|
||||
<string name="just_now">Just now</string>
|
||||
<string name="minutes_ago">%sm ago</string>
|
||||
@ -420,22 +374,18 @@
|
||||
<string name="no_update_available">No update available</string>
|
||||
<string name="update_check">Checking for updates…</string>
|
||||
<string name="dismiss_temporary">Not now</string>
|
||||
<string name="update_available_dialog_description">A new version of ReVanced Manager (%s) is
|
||||
available.</string>
|
||||
<string name="update_available_dialog_description">A new version of ReVanced Manager (%s) is available.</string>
|
||||
<string name="failed_to_download_update">Failed to download update: %s</string>
|
||||
<string name="download">Download</string>
|
||||
<string name="download_confirmation_metered">You are currently on a metered connection, and data
|
||||
charges from your service provider may apply.\n\nDo you still want to continue?</string>
|
||||
<string name="download_confirmation_metered">You are currently on a metered connection, and data charges from your service provider may apply.\n\nDo you still want to continue?</string>
|
||||
<string name="download_update_confirmation">Download update?</string>
|
||||
<string name="no_contributors_found">No contributors found</string>
|
||||
<string name="select">Select</string>
|
||||
<string name="select_deselect_all">Select or deselect all</string>
|
||||
<string name="select_bundle_type_dialog_title">Add new bundle</string>
|
||||
<string name="select_bundle_type_dialog_description">Add a new bundle from a URL or storage</string>
|
||||
<string name="local_bundle_description">Import local files from your storage, does not
|
||||
automatically update</string>
|
||||
<string name="remote_bundle_description">Import remote files from a URL, can automatically
|
||||
update</string>
|
||||
<string name="local_bundle_description">Import local files from your storage, does not automatically update</string>
|
||||
<string name="remote_bundle_description">Import remote files from a URL, can automatically update</string>
|
||||
<string name="recommended">Recommended</string>
|
||||
|
||||
<string name="installation_failed_dialog_title">Installation failed</string>
|
||||
@ -446,20 +396,13 @@
|
||||
<string name="installation_invalid_dialog_title">Installation invalid</string>
|
||||
<string name="installation_storage_issue_dialog_title">Not enough storage</string>
|
||||
<string name="installation_timeout_dialog_title">Installation timed out</string>
|
||||
<string name="installation_failed_description">The installation failed due to an unknown reason.
|
||||
Try again?</string>
|
||||
<string name="installation_aborted_description">The installation was cancelled manually. Try
|
||||
again?</string>
|
||||
<string name="installation_blocked_description">The installation was blocked. Review your device
|
||||
security settings and try again.</string>
|
||||
<string name="installation_conflict_description">The installation was prevented by an existing
|
||||
installation of the app. Uninstall the installed app and try again?</string>
|
||||
<string name="installation_incompatible_description">The app is incompatible with this device.
|
||||
Use an APK that is supported by this device and try again.</string>
|
||||
<string name="installation_invalid_description">The app is invalid. Uninstall the app and try
|
||||
again?</string>
|
||||
<string name="installation_storage_issue_description">The app could not be installed due to
|
||||
insufficient storage. Free up some space and try again.</string>
|
||||
<string name="installation_failed_description">The installation failed due to an unknown reason. Try again?</string>
|
||||
<string name="installation_aborted_description">The installation was cancelled manually. Try again?</string>
|
||||
<string name="installation_blocked_description">The installation was blocked. Review your device security settings and try again.</string>
|
||||
<string name="installation_conflict_description">The installation was prevented by an existing installation of the app. Uninstall the installed app and try again?</string>
|
||||
<string name="installation_incompatible_description">The app is incompatible with this device. Use an APK that is supported by this device and try again.</string>
|
||||
<string name="installation_invalid_description">The app is invalid. Uninstall the app and try again?</string>
|
||||
<string name="installation_storage_issue_description">The app could not be installed due to insufficient storage. Free up some space and try again.</string>
|
||||
<string name="installation_timeout_description">The installation took too long. Try again?</string>
|
||||
<string name="reinstall">Reinstall</string>
|
||||
<string name="show">Show</string>
|
||||
@ -470,14 +413,10 @@
|
||||
<string name="add_patch_bundle">Add patch bundle</string>
|
||||
<string name="bundle_url">Bundle URL</string>
|
||||
<string name="auto_update">Auto update</string>
|
||||
<string name="unsupported_patches_dialog">These patches are not compatible with the selected app
|
||||
version (%1$s).\n\nClick on the patches to see more details.</string>
|
||||
<string name="unsupported_patches_dialog">These patches are not compatible with the selected app version (%1$s).\n\nClick on the patches to see more details.</string>
|
||||
<string name="unsupported_patch">Unsupported patch</string>
|
||||
<string name="any_version">Any</string>
|
||||
<string name="never_show_again">Never show again</string>
|
||||
<string name="show_manager_update_dialog_on_launch">Show update message on launch</string>
|
||||
<string name="show_manager_update_dialog_on_launch_description">Shows a popup notification
|
||||
whenever there is a new update available on launch.</string>
|
||||
<string name="failed_to_import_keystore">Failed to import keystore</string>
|
||||
<string name="export">Export</string>
|
||||
</resources>
|
||||
<string name="show_manager_update_dialog_on_launch_description">Shows a popup notification whenever there is a new update available on launch.</string>
|
||||
</resources>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
@ -1,10 +1,11 @@
|
||||
# 💼 Prerequisites
|
||||
|
||||
In order to use ReVanced Manager, certain requirements must be met.
|
||||
To use ReVanced Manager, certain requirements have to be met.
|
||||
|
||||
## 🤝 Requirements
|
||||
|
||||
- An Android device running Android 8 or higher
|
||||
- Android device running Android 8.0 or higher
|
||||
- **Optionally** Rooted Android device with latest version of [KernelSU](https://github.com/tiann/KernelSU) or [Magisk](https://github.com/topjohnwu/Magisk)
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
|
@ -1,14 +1,26 @@
|
||||
# ⬇️ Installation
|
||||
|
||||
In order to use ReVanced on your Android device, ReVanced Manager must be installed.
|
||||
To use ReVanced on your Android device, ReVanced Manager have to be install,
|
||||
refer to the [Prerequisites](0_prerequisites.md) if haven't already.
|
||||
|
||||
## ✅ Installation steps
|
||||
## 🪜 Installation steps
|
||||
|
||||
1. Download the latest version of ReVanced Manager from [here](https://github.com/revanced/revanced-manager/releases/latest)
|
||||
1. Get the latest version of ReVanced Manager from the [ReVanced site][Official ReVanced Download].
|
||||
2. Install ReVanced Manager
|
||||
|
||||
### ✒️ Verifying authenticity of ReVanced Manager
|
||||
|
||||
> [!NOTE]
|
||||
> It's always advisable that you download from trusted sources like the [ReVanced site][Official ReVanced Download]
|
||||
> or GitHub releases as it's the safest way to download ReVanced without potential risk of malware.
|
||||
|
||||
To verify if your ReVanced Manager is provided without sign of tampering,
|
||||
we have signed the APK with hashes corresponding to `b6362c6ea7888efd15c0800f480786ad0f5b133b4f84e12d46afba5f9eac1223` *unless otherwise stated*.
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
The next page will guide you through using ReVanced Manager.
|
||||
|
||||
Continue: [🛠️ Usage](2_usage.md)
|
||||
|
||||
[Official ReVanced Download]: https://revanced.app/download
|
||||
|
@ -8,16 +8,26 @@ The following pages will guide you through using ReVanced Manager to patch apps.
|
||||
2. Tap the + button in the bottom right corner
|
||||
3. Choose an app to patch[^1]
|
||||
4. Tap on the version of the app you want to patch[^2]
|
||||
5. Select the patches you want to apply
|
||||
6. Tap the Patch button
|
||||
7. Tap on the **Install** button
|
||||
> **Note**: If you are rooted, you can mount the patched app on top of the original app.[^3]
|
||||
> Optionally, you may export the patched app to storage using the options in the top right corner.
|
||||
5. Tap the 🪄 **Patch** button
|
||||
6. Tap on the 📲 **Install** button
|
||||
> [!Note]
|
||||
> If the **Install** Button isn't there, it could be that something went wrong. Refer to [3. ❔ Troubleshooting](3_troubleshooting.md)
|
||||
> [!Tip]
|
||||
> If you are rooted, you can mount the patched app on top of the original app.[^3]
|
||||
> Optionally, you may export the patched app to storage using the options in the bottom left corner.
|
||||
|
||||
[^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.
|
||||
[^1]: You need 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 version with the most patches to get the most out of ReVanced.
|
||||
[^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 4. above.
|
||||
|
||||
### Change patch selection and options
|
||||
|
||||
Before you can change the selection of patches, follow the step below to allow changing the selection of patches.
|
||||
|
||||
1. Tap ⚙️ Settings button in the top right corner
|
||||
2. Go to Advanced Settings
|
||||
3. Toggle "Allow changing patch selection" on
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
The next page will bring you back to the usage page.
|
||||
|
@ -6,10 +6,13 @@ After patching an app, you may want to manage it. This page will guide you throu
|
||||
|
||||
1. Navigate to the Apps tab from the top navigation bar
|
||||
2. Select the app you want to manage
|
||||
3.
|
||||
|
||||
Inside you will be able to open, and uninstall the app within the manager,
|
||||
additionally you will be able to repatch the app by patching the app again, see [🧩 Patching apps](2_1_patching.md),
|
||||
and view all patches applied to the patched app.
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
The next page will bring you back to the usage page.
|
||||
|
||||
Continue: [🛠️ Usage](2_usage.md)
|
||||
|
||||
|
@ -4,7 +4,25 @@ In order to keep up with the latest features and bug fixes, it is recommended to
|
||||
|
||||
## ✅ Updating steps
|
||||
|
||||
> Currently not implemented
|
||||
1. Tap the ↻ Update button in the top right corner right next to the ⚙️ Settings icon
|
||||
2. Tap the **Update** button in the bottom right corner
|
||||
3. Wait for the update to be downloaded
|
||||
4. Tap the **Install** button to install[^1]
|
||||
> [!Note]
|
||||
> If you see a prompt regarding your device is unable to install application for security reason
|
||||
> you may need to allow ReVanced Manager to install APK file on your device.
|
||||
> 1. Tap on Settings
|
||||
> 2. Toggle "Allow from this source" on
|
||||
5. Wait for installation prompt to show then tap **Install** again
|
||||
6. Open ReVanced Manager again to see the new version
|
||||
|
||||
## 🔎 Check for update
|
||||
|
||||
Usually ReVanced Manager always check update on first startup, so it's not need to manually check for update yourself.
|
||||
To trigger the check for update function follow the step bellow:
|
||||
|
||||
1. Go to ⚙️ Settings menu and ↻ Update section
|
||||
2. Tap on "Check for updates"
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
|
@ -8,30 +8,44 @@ ReVanced Manager has settings that can be configured to your liking.
|
||||
|
||||
Specify the URL of the API to use. This is used to fetch ReVanced Patches and update ReVanced Manager.
|
||||
|
||||
Location: `⚙️ Settings -> Advanced -> API URL`
|
||||
|
||||
- ### 🧬 Sources
|
||||
|
||||
Override the API and change the source of ReVanced Patches.
|
||||
|
||||
- ### 🧪 Experimental ReVanced Patches support
|
||||
Location: `Patch bundles -> + Button`
|
||||
|
||||
- ### 🧪 Experimental patches
|
||||
|
||||
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.
|
||||
|
||||
Location: `⚙️ Settings -> Advanced -> Safeguards`
|
||||
|
||||
- ### 🧑🔬 Experimental universal support
|
||||
|
||||
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.
|
||||
|
||||
Location: `⚙️ Settings -> Advanced -> Safeguards`
|
||||
|
||||
- ### 🔑 Export, import or delete keystore
|
||||
|
||||
Manage the keystore used to sign patched apps.
|
||||
|
||||
- ### 📄 Export, import or reset ReVanced Patches selection
|
||||
Location: `⚙️ Settings -> Import & export -> Signing`
|
||||
|
||||
Manage the ReVanced Patches selection. This is useful if you want to share your ReVanced Patches selection with others or reset it to the default selection.
|
||||
- ### 📄 Export, import or reset patch selection
|
||||
|
||||
Manage the ReVanced Patches selection. This is useful if you want to share your patch selection with others or reset it to the default selection.
|
||||
|
||||
Location: `⚙️ Settings -> Import & export -> Patches`
|
||||
|
||||
- ### ℹ️ About
|
||||
|
||||
View information about your device and ReVanced Manager. This includes the version of ReVanced Manager and supported architectures of your device.
|
||||
|
||||
Location: `⚙️ Settings -> About`
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
The next page will bring you back to the usage page.
|
||||
|
@ -10,11 +10,19 @@ In case you encounter any issues while using ReVanced Manager, please refer to t
|
||||
|
||||
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.
|
||||
|
||||
- 🥛 Out Of Memory error
|
||||
|
||||
This indicates that your device is not giving ReVanced Manager enough memory to patch the app.
|
||||
|
||||
Turning on `⚙️ Settings -> Advanced -> toggle "Run Patcher in another process (experimental)"` may solve the issue.
|
||||
|
||||
- ❗️ 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.
|
||||
|
||||
Alternatively, you can use [ReVanced CLI](https://github.com/revanced/revanced-cli) to patch the app.
|
||||
Alternatively, you can use [ReVanced CLI][ReVanced CLI GitHub]) to patch the app.
|
||||
|
||||
[ReVanced CLI GitHub]: https://github.com/revanced/revanced-cli
|
||||
|
||||
- 🚫 Non-root install is not possible with the current patches selection
|
||||
|
||||
@ -22,10 +30,14 @@ In case you encounter any issues while using ReVanced Manager, please refer to t
|
||||
|
||||
- 🚨 Patched app crashes on launch
|
||||
|
||||
Select the **Default** button when choosing patches.
|
||||
Try selecting the **Default** button when choosing patches, if the patched app still failed, file an issue at [ReVanced Patches][ReVanced Patches GitHub].
|
||||
|
||||
[ReVanced Patches GitHub]: https://github.com/revanced/revanced-patches
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
The next page will teach you how to build ReVanced Manager from source.
|
||||
You have successfully finished the guide for on how to use ReVanced Manager.
|
||||
|
||||
Continue: [🔨 Building from source](4_building.md)
|
||||
If you wish to review the Table of Content for how to use ReVanced Manager, feel free to do so.
|
||||
|
||||
Continue: [💊 ReVanced Manager](/docs/README.md)
|
||||
|
@ -1,38 +0,0 @@
|
||||
# 🛠️ Building from source
|
||||
|
||||
This page will guide you through building ReVanced Manager from source.
|
||||
|
||||
1. Download Java SDK 17 ([Azul JDK](https://www.azul.com/downloads/?version=java-17-lts&package=jdk#zulu) or [OpenJDK](https://jdk.java.net/java-se-ri/17)) and add it to path
|
||||
|
||||
2. Clone the repository
|
||||
|
||||
```sh
|
||||
git clone https://github.com/revanced/revanced-manager.git && cd revanced-manager
|
||||
```
|
||||
|
||||
3. Create a GitHub personal access token with the `read:packages` scope [here](https://github.com/settings/tokens/new?scopes=read:packages&description=ReVanced)
|
||||
|
||||
4. Add your GitHub username and the token to `~/.gradle/gradle.properties`
|
||||
|
||||
```properties
|
||||
gpr.user = YourUsername
|
||||
gpr.key = ghp_longrandomkey
|
||||
```
|
||||
|
||||
5. Set the `sdk.dir` property in `local.properties` to your Android SDK location
|
||||
|
||||
```properties
|
||||
sdk.dir = /path/to/android/sdk
|
||||
```
|
||||
|
||||
6. Build the APK
|
||||
|
||||
Debug:
|
||||
```sh
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
|
||||
Release:
|
||||
```sh
|
||||
./gradlew assembleRelease -Psign
|
||||
```
|
@ -1,6 +1,6 @@
|
||||
# 💊 ReVanced Manager
|
||||
|
||||
This documentation explains how to use [ReVanced Manager](https://github.com/revanced/revanced-manager).
|
||||
This documentation explains how to use [ReVanced Manager](https://github.com/ReVanced/revanced-manager).
|
||||
|
||||
## 📖 Table of contents
|
||||
|
||||
@ -12,7 +12,10 @@ This documentation explains how to use [ReVanced Manager](https://github.com/rev
|
||||
3. [🔄 Updating ReVanced Manager](2_3_updating.md)
|
||||
4. [⚙️ Configuring ReVanced Manager](2_4_settings.md)
|
||||
3. [❔ Troubleshooting](3_troubleshooting.md)
|
||||
4. [🔨 Building from source](4_building.md)
|
||||
|
||||
## 🧑💻 Developing for ReVanced Manager
|
||||
|
||||
Checkout the documentation for developer [here](developer/README.md).
|
||||
|
||||
## ⏭️ Start here
|
||||
|
||||
|
28
docs/developer/0_prerequisites.md
Normal file
28
docs/developer/0_prerequisites.md
Normal file
@ -0,0 +1,28 @@
|
||||
# 💼 Prerequisites
|
||||
|
||||
Here's everything you'll need to develop on ReVanced Manager
|
||||
|
||||
## 🤝 Recommended environment
|
||||
|
||||
- Any environment that is capable of running the latest Android Studio, latest Android SDK, and JDK 17 with at least 4 GB of memory for coding
|
||||
- Any devices with preferably the latest Android version or at least higher than the [`minSdk`](/app/build.gradle.kts) for testing
|
||||
- **Optionally** A device with root capabilities using the latest version of [KernelSU](https://github.com/tiann/KernelSU) or [Magisk](https://github.com/topjohnwu/Magisk)
|
||||
|
||||
## ⚙️ Setting up
|
||||
|
||||
### Authenticating to GitHub Registry
|
||||
|
||||
ReVanced Manager use dependency from the GitHub Registry (i.e., [ReVanced Patcher](https://github.com/ReVanced/revanced-patcher/packages)) and so your build may fail without authenticating to the service,
|
||||
to authenticate you must create a personal access token with the scope `read:packages` [here](https://github.com/settings/tokens/new?scopes=read:packages&description=ReVanced)
|
||||
and add your token to `~/.gradle/gradle.properties`, create the file if it does not exist.
|
||||
|
||||
```properties
|
||||
gpr.user = username
|
||||
gpr.key = ghp_******************************
|
||||
```
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
The next page will guide you through developing for ReVanced Manager.
|
||||
|
||||
Continue: [🧑💻 Developing for ReVanced Manager](1_develop.md)
|
25
docs/developer/1_develop.md
Normal file
25
docs/developer/1_develop.md
Normal file
@ -0,0 +1,25 @@
|
||||
# 🧑💻 Developing for ReVanced Manager
|
||||
|
||||
ReVanced Manager is developed on Kotlin using [Jetpack Compose](https://developer.android.com/compose), here are some tips to help you get started.
|
||||
|
||||
## Code style
|
||||
|
||||
The styling is based on https://kotlinlang.org/docs/coding-conventions.html
|
||||
|
||||
## Commit
|
||||
|
||||
At ReVanced, we adopt a naming convention for commit called [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) so for example when you're adding a new feature you must add `feat: ` before the description of your commit.
|
||||
|
||||
## Building
|
||||
|
||||
To build ReVanced Manager, simply hit build button on your IDE or run:
|
||||
|
||||
```sh
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
The next page will guide you through developing for ReVanced Manager.
|
||||
|
||||
Continue: [🎉 Submitting your Pull Request](2_submitting.md)
|
21
docs/developer/2_submitting.md
Normal file
21
docs/developer/2_submitting.md
Normal file
@ -0,0 +1,21 @@
|
||||
# 🎉 Submitting your Pull Request
|
||||
|
||||
> [!TIP]
|
||||
> We recommend that you discuss your changes with
|
||||
> the maintainers of ReVanced Manager before contributing.
|
||||
> This will help you determine whether your change is acceptable.
|
||||
|
||||
1. Fork the repository and create your branch from `dev`
|
||||
2. Commit your changes in [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) style
|
||||
3. Submit a pull request to the `dev` branch of the repository and reference issues that your pull request closes in the description of your pull request
|
||||
4. Our team will review your pull request and provide feedback. Once your pull request is approved, it will be merged into the `dev` branch and will be included in
|
||||
the next release of ReVanced Manager
|
||||
|
||||
## ⏭️ What's next
|
||||
|
||||
You have successfully finished the guide for developing for ReVanced Manager.
|
||||
|
||||
This next section will be verifying the authenticity of ReVanced Manager
|
||||
which may be relevant for store provider or those who's looking to verify prebuilt librar(ies).
|
||||
|
||||
Continue: [✒️ Verification and Authenticity of ReVanced Manager](3_verifying.md)
|
19
docs/developer/3_verifying.md
Normal file
19
docs/developer/3_verifying.md
Normal file
@ -0,0 +1,19 @@
|
||||
# ✒️ Verification and Authenticity of ReVanced Manager
|
||||
|
||||
> [!NOTE]
|
||||
> This information is more relevant to alternative store providers
|
||||
|
||||
To distribute ReVanced Manager safely and recommended way is to provide the users with a link to
|
||||
[1. ⬇️ Installation, ✒️ Verifying authenticity of ReVanced Manager (user-side)][installation authenticity].
|
||||
|
||||
The certificate SHA-256 of the APK will always be `b6362c6ea7888efd15c0800f480786ad0f5b133b4f84e12d46afba5f9eac1223` unless otherwise noted.
|
||||
|
||||
[installation authenticity]: /docs/1_installation.md#%EF%B8%8F-verifying-authenticity-of-revanced-manager
|
||||
|
||||
## `libaapt2.so`
|
||||
|
||||
ReVanced Manager includes prebuilt binaries of [`libaapt2.so`][location of libaapt2.so] from https://github.com/ReVanced/aapt2
|
||||
|
||||
which fixes issues on ARM32-based systems. Attestation is provided here: https://github.com/ReVanced/aapt2/attestations
|
||||
|
||||
[location of libaapt2.so]: /app/src/main/jniLibs/
|
25
docs/developer/README.md
Normal file
25
docs/developer/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# 💊 ReVanced Manager
|
||||
|
||||
> [!WARNING]
|
||||
> This guide is for people who want to develop for ReVanced Manager, may feature technical words or jargons.
|
||||
> For regular user you may want to view this [documentation](/docs/README.md) instead.
|
||||
|
||||
This documentation explains how to develop for [ReVanced Manager](https://github.com/ReVanced/revanced-manager).
|
||||
|
||||
## 📖 Table of contents
|
||||
|
||||
## Developing
|
||||
|
||||
0. [💼 Prerequisites](0_prerequisites.md)
|
||||
1. [🧑💻 Developing for ReVanced Manager](1_developing.md)
|
||||
2. [🎉 Submitting your Pull Request](2_submitting.md)
|
||||
|
||||
## Transparency
|
||||
|
||||
1. [✒️ Verification and Authenticity of ReVanced Manager](3_verifying.md)
|
||||
|
||||
## ⏭️ Start here
|
||||
|
||||
The next page will tell you about the prerequisites for developing for ReVanced Manager.
|
||||
|
||||
Continue: [💼 Prerequisites](0_prerequisites.md)
|
@ -1,41 +1,41 @@
|
||||
[versions]
|
||||
ktx = "1.15.0"
|
||||
material3 = "1.3.1"
|
||||
ui-tooling = "1.7.7"
|
||||
ui-tooling = "1.7.6"
|
||||
viewmodel-lifecycle = "2.8.7"
|
||||
splash-screen = "1.0.1"
|
||||
activity = "1.10.0"
|
||||
activity = "1.9.3"
|
||||
appcompat = "1.7.0"
|
||||
preferences-datastore = "1.1.2"
|
||||
preferences-datastore = "1.1.1"
|
||||
work-runtime = "2.10.0"
|
||||
compose-bom = "2025.01.01"
|
||||
navigation = "2.8.6"
|
||||
accompanist = "0.37.0"
|
||||
compose-bom = "2024.12.01"
|
||||
navigation = "2.8.5"
|
||||
accompanist = "0.34.0"
|
||||
placeholder = "1.1.2"
|
||||
reorderable = "2.4.3"
|
||||
serialization = "1.8.0"
|
||||
reorderable = "1.5.2"
|
||||
serialization = "1.7.3"
|
||||
collection = "0.3.8"
|
||||
datetime = "0.6.1"
|
||||
datetime = "0.6.0"
|
||||
room-version = "2.6.1"
|
||||
revanced-patcher = "21.0.0"
|
||||
revanced-library = "3.0.2"
|
||||
koin = "3.5.3"
|
||||
ktor = "2.3.9"
|
||||
markdown-renderer = "0.30.0"
|
||||
markdown-renderer = "0.22.0"
|
||||
fading-edges = "1.0.4"
|
||||
kotlin = "2.1.10"
|
||||
kotlin = "2.1.0"
|
||||
android-gradle-plugin = "8.8.0"
|
||||
dev-tools-gradle-plugin = "2.1.10-1.0.29"
|
||||
about-libraries-gradle-plugin = "11.5.0"
|
||||
dev-tools-gradle-plugin = "2.1.0-1.0.29"
|
||||
about-libraries-gradle-plugin = "11.1.1"
|
||||
binary-compatibility-validator = "0.17.0"
|
||||
coil = "2.7.0"
|
||||
coil = "2.6.0"
|
||||
app-icon-loader-coil = "1.5.0"
|
||||
skrapeit = "1.2.2"
|
||||
libsu = "6.0.0"
|
||||
libsu = "5.2.2"
|
||||
scrollbars = "1.0.4"
|
||||
enumutil = "1.1.1"
|
||||
enumutil = "1.1.0"
|
||||
compose-icons = "1.2.4"
|
||||
kotlin-process = "1.5.1"
|
||||
kotlin-process = "1.4.1"
|
||||
hidden-api-stub = "4.3.3"
|
||||
|
||||
[libraries]
|
||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=8d97a97984f6cbd2b85fe4c60a743440a347544bf18818048e611f5288d46c94
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||
distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
Reference in New Issue
Block a user