Merge pull request #318 from YTVanced/dev

Manager 2.1.0
This commit is contained in:
KevinX8 2020-12-19 13:07:59 +00:00 committed by GitHub
commit b5fb17a527
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
238 changed files with 4899 additions and 2561 deletions

View File

@ -8,12 +8,11 @@ assignees: ''
---
**Please only report your issue here, if all points below are true**
- I installed the App from [vanced.app](https://vanced.app), this github repository or the Vanced Discord server
- I installed the App from [vancedapp.com](https://vancedapp.com), this github repository or the Vanced Discord server
- I am using the latest version
- This is an issue in the Vanced Manager app (NOT Youtube Vanced)
- This issue keeps re-occurring every time I try
- For MIUI users: I disabled MIUI optimisation
- For root users: I disabled apk Signature Verification
**Phone Specifications:**
- Brand:

View File

@ -2,14 +2,14 @@ Pull requests should be made to the Dev branch as that is the working branch, ma
======
For anyone who wants to provide translations please submit them to https://crowdin.com/project/vanced-manager as we also use it for YouTube Vanced. Any issues with translations should be posted there too.
======
[![Github All Releases](https://img.shields.io/github/downloads/YTVanced/VancedManager/total.svg)]() [![Github All Releases](https://img.shields.io/github/release/YTVanced/VancedManager.svg)]()
[![Github All Releases](https://img.shields.io/github/downloads/YTVanced/VancedManager/total.svg)](https://github.com/YTVanced/VancedManager/releases/latest) [![Github All Releases](https://img.shields.io/github/release/YTVanced/VancedManager.svg)](https://github.com/YTVanced/VancedManager/releases/latest)
# Vanced Manager
Hi, when we released Vanced 15.05.54, people were upset because it used the .apks format, which was way harder to install than a traditional .apk file. Even though we wrote clear instructions on how to install the new Vanced build, people still couldn't figure it out.
Then we thought, "why don't we make a manager for vanced, which will download, update and uninstall Vanced and MicroG, have an easy and understandable UI and be less than 10mb?" and that's how Vanced Manager was born.
After 3 months of development, we are finally ready to introduce Vanced Manager to the masses. Vanced manager can easily install and uninstall vanced and microg, has various settings for customisation and better experience. The Manager comes with an easy-to-use interface
##### Background download/installation feature is no longer supported due to problems with some ROMs, please do NOT report problems regarding background activity.
##### Background download/installation feature is no longer supported due to problems with some ROMs, please do NOT report issues regarding background activity.
## Vanced Developers
- xfileFIN
@ -22,11 +22,11 @@ After 3 months of development, we are finally ready to introduce Vanced Manager
- Koopah (ostajic)
## Contributors
- AioiLight
- AioiLight
- HaliksaR
## Credits
- topjohnwu for his wonderful [LibSU](https://github.com/topjohnwu/libsu)
- Mindorks for their amazing [PRDownloader](https://github.com/MindorksOpenSource/PRDownloader)
- aefyr for [SAI](https://github.com/aefyr/SAI), which was an inspiration for our Manager
- kittinunf for [Fuel](https://github.com/kittinunf/Fuel) HTTP client
- cbeust for [klaxon](https://github.com/cbeust/klaxon) JSON parser

View File

@ -10,8 +10,6 @@ apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'androidx.navigation.safeargs.kotlin'
ext.langs = getLanguages()
android {
compileSdkVersion 30
@ -19,12 +17,12 @@ android {
applicationId "com.vanced.manager"
minSdkVersion 21
targetSdkVersion 30
versionCode 201
versionName "2.0.1 (Android5and6suck)"
versionCode 210
versionName "2.1.0 (CyberManager2077)"
vectorDrawables.useSupportLibrary true
buildConfigField "String[]", "MANAGER_LANGUAGES", "{" + surroundWithQuotes(langs) + "}"
buildConfigField "String[]", "MANAGER_LANGUAGES", "{" + surroundWithQuotes(getLanguages()) + "}"
buildConfigField "Boolean", "ENABLE_CROWDIN_AUTH", "false"
buildConfigField "String", "CROWDIN_HASH", "\"${System.getenv('CROWDIN_HASH')}\""
buildConfigField "String", "CROWDIN_CLIENT_ID", "\"${System.getenv('CROWDIN_CLIENT_ID')}\""
@ -47,10 +45,15 @@ android {
}
buildFeatures {
dataBinding true
dataBinding true // ObservableField migrate to flow or liveData
viewBinding true
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude "META-INF/*.kotlin_module"
}
// To inline the bytecode built with JVM target 1.8 into
// bytecode that is being built with JVM target 1.6. (e.g. navArgs)
@ -74,7 +77,7 @@ def getLanguages() {
langs.add("pt_PT")
langs.add("zh_CN")
langs.add("zh_TW")
List<String> exceptions = [ "bn", "pt", "zh"]
List<String> exceptions = ["bn", "pt", "zh"]
Pattern pattern = Pattern.compile("-(\\w+)-")
new File("${projectDir}/src/main/res").eachDir { dir ->
if (dir.name.startsWith("values-") && !dir.name.contains("v23")) {
@ -97,24 +100,32 @@ static def surroundWithQuotes(Object[] arr) {
dependencies {
implementation project(':core-presentation')
implementation project(":core-ui")
implementation project(':library-network')
// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
// AndroidX
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.browser:browser:1.2.0'
implementation 'androidx.browser:browser:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
implementation 'androidx.lifecycle:lifecycle-livedata-core-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'com.google.android.material:material:1.3.0-alpha03'
//Appearance
implementation 'com.github.madrapps:pikolo:2.0.1'
implementation 'com.google.android.material:material:1.3.0-beta01'
// JSON parser
implementation 'com.beust:klaxon:5.4'
@ -138,12 +149,9 @@ dependencies {
// Layout
implementation 'com.google.android:flexbox:2.0.1'
// File downloader
implementation 'com.mindorks.android:prdownloader:0.6.0'
// Firebase
implementation 'com.google.firebase:firebase-analytics-ktx:18.0.0'
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
implementation 'com.google.firebase:firebase-messaging:21.0.0'
implementation 'com.google.firebase:firebase-perf:19.0.10'
implementation 'com.google.firebase:firebase-messaging:21.0.1'
implementation 'com.google.firebase:firebase-perf:19.0.11'
}

View File

@ -31,12 +31,14 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:largeHeap="true"
tools:ignore="UnusedAttribute">
<activity
android:name=".ui.core.SplashScreenActivity"
android:label="@string/app_name"
android:theme="@style/SplashTheme">
android:theme="@style/SplashTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -50,14 +52,16 @@
<activity
android:name=".ui.WelcomeActivity"
android:theme="@style/DarkTheme_Blue"/>
android:theme="@style/DarkTheme"
android:screenOrientation="portrait"/>
<activity
android:name=".ui.MainActivity"
android:configChanges="layoutDirection|locale"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/DarkTheme_Blue">
android:theme="@style/DarkTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

View File

@ -2,7 +2,9 @@ package com.vanced.manager.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.RecyclerView
import com.github.florent37.viewtooltip.ViewTooltip
@ -15,6 +17,7 @@ import com.vanced.manager.ui.viewmodels.HomeViewModel
class AppListAdapter(
private val context: FragmentActivity,
private val viewModel: HomeViewModel,
private val lifecycleOwner: LifecycleOwner,
private val tooltip: ViewTooltip
) : RecyclerView.Adapter<AppListAdapter.ListViewHolder>() {
@ -28,16 +31,38 @@ class AppListAdapter(
inner class ListViewHolder(private val binding: ViewAppBinding) : RecyclerView.ViewHolder(binding.root) {
val appCard = binding.appCard
fun bind(position: Int) {
binding.viewModel = viewModel
binding.dataModel = if (isRoot) rootDataModels[position] else dataModels[position]
binding.app = apps[position]
val dataModel = if (isRoot) rootDataModels[position] else dataModels[position]
with(binding) {
appName.text = dataModel?.appName
appInstallButton.text = dataModel?.buttonTxt?.value
dataModel?.buttonTxt?.observe(lifecycleOwner) {
appInstallButton.text = it
}
appInstallButton.setOnClickListener {
viewModel.openInstallDialog(it, apps[position])
}
appUninstall.setOnClickListener {
dataModel?.appPkg?.let { it1 -> viewModel.uninstallPackage(it1) }
}
appUninstall.isVisible = dataModel?.isAppInstalled?.value == true
dataModel?.isAppInstalled?.observe(lifecycleOwner) {
appUninstall.isVisible = it
}
appRemoteVersion.text = dataModel?.versionName?.value
dataModel?.versionName?.observe(lifecycleOwner) {
appRemoteVersion.text = it
}
appInstalledVersion.text = dataModel?.installedVersionName?.value
dataModel?.installedVersionName?.observe(lifecycleOwner) {
appInstalledVersion.text = it
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view = ViewAppBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val view = ViewAppBinding.inflate(LayoutInflater.from(context), parent, false)
return ListViewHolder(view)
}
@ -49,7 +74,7 @@ class AppListAdapter(
AppInfoDialog.newInstance(
appName = apps[position],
appIcon = dataModels[position]?.appIcon,
changelog = dataModels[position]?.changelog?.get()
changelog = dataModels[position]?.changelog?.value
).show(context.supportFragmentManager, "info")
}
}
@ -59,21 +84,21 @@ class AppListAdapter(
init {
if (prefs.getBoolean("enable_vanced", true)) {
dataModels.add(viewModel.vanced.get())
rootDataModels.add(viewModel.vancedRoot.get())
dataModels.add(viewModel.vanced.value)
rootDataModels.add(viewModel.vancedRoot.value)
apps.add(context.getString(R.string.vanced))
itemCount++
}
if (prefs.getBoolean("enable_music", false)) {
dataModels.add(viewModel.music.get())
rootDataModels.add(viewModel.musicRoot.get())
if (prefs.getBoolean("enable_music", true)) {
dataModels.add(viewModel.music.value)
rootDataModels.add(viewModel.musicRoot.value)
apps.add(context.getString(R.string.music))
itemCount++
}
if (!isRoot) {
dataModels.add(viewModel.microg.get())
dataModels.add(viewModel.microg.value)
apps.add(context.getString(R.string.microg))
itemCount++
}

View File

@ -9,19 +9,20 @@ import com.vanced.manager.R
import com.vanced.manager.databinding.ViewNotificationSettingBinding
import com.vanced.manager.model.NotifModel
class GetNotifAdapter(context: Context) : RecyclerView.Adapter<GetNotifAdapter.GetNotifViewHolder>() {
class GetNotifAdapter(private val context: Context) :
RecyclerView.Adapter<GetNotifAdapter.GetNotifViewHolder>() {
private val vanced = NotifModel(
"Vanced-Update",
context.getString(R.string.push_notifications, context.getString(R.string.vanced)),
context.getString(R.string.push_notifications_summary, context.getString(R.string.vanced)),
"vanced_notifs"
"Vanced-Update",
context.getString(R.string.push_notifications, context.getString(R.string.vanced)),
context.getString(R.string.push_notifications_summary, context.getString(R.string.vanced)),
"vanced_notifs"
)
private val music = NotifModel(
"MicroG-Update",
context.getString(R.string.push_notifications, context.getString(R.string.music)),
context.getString(R.string.push_notifications_summary, context.getString(R.string.music)),
"music_notifs"
"MicroG-Update",
context.getString(R.string.push_notifications, context.getString(R.string.music)),
context.getString(R.string.push_notifications_summary, context.getString(R.string.music)),
"music_notifs"
)
private val microg = NotifModel(
"Music-Update",
@ -36,12 +37,18 @@ class GetNotifAdapter(context: Context) : RecyclerView.Adapter<GetNotifAdapter.G
val switch = binding.notifSwitch
fun bind(position: Int) {
binding.app = apps[position]
with(binding.notifSwitch) {
setKey(apps[position].key)
setSummary(apps[position].switchSummary)
setTitle(apps[position].switchTitle)
setDefaultValue(false)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GetNotifViewHolder {
val view = ViewNotificationSettingBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val view =
ViewNotificationSettingBinding.inflate(LayoutInflater.from(context), parent, false)
return GetNotifViewHolder(view)
}

View File

@ -10,61 +10,66 @@ import com.vanced.manager.databinding.ViewSocialLinkBinding
import com.vanced.manager.model.LinkModel
import com.vanced.manager.ui.viewmodels.HomeViewModel
class LinkAdapter(context: Context, private val viewModel: HomeViewModel) : RecyclerView.Adapter<LinkAdapter.LinkViewHolder>() {
class LinkAdapter(
private val context: Context,
private val viewModel: HomeViewModel
) : RecyclerView.Adapter<LinkAdapter.LinkViewHolder>() {
private val instagram = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_instagram),
"https://instagram.com/vanced.youtube"
INSTAGRAM
)
private val youtube = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_youtube),
"https://youtube.com/c/YouTubeVanced"
YOUTUBE
)
private val github = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_github),
"https://github.com/YTVanced/VancedManager"
GITHUB
)
private val website = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_website),
"https://vancedapp.com"
WEBSITE
)
private val telegram = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_telegram),
"https://t.me/joinchat/AAAAAEHf-pi4jH1SDlAL4w"
TELEGRAM
)
private val twitter = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_twitter),
"https://twitter.com/YTVanced"
TWITTER
)
private val discord = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_discord),
"https://discord.gg/WCGNdRruzb"
DISCORD
)
private val reddit = LinkModel(
AppCompatResources.getDrawable(context, R.drawable.ic_reddit),
"https://www.reddit.com/r/Vanced/"
REDDIT
)
val links = arrayOf(instagram, youtube, github, website, telegram, twitter, discord, reddit)
inner class LinkViewHolder(private val binding: ViewSocialLinkBinding) : RecyclerView.ViewHolder(binding.root) {
val logo = binding.linkImage
fun bind(position: Int) {
binding.viewModel = viewModel
binding.linkModel = links[position]
}
val logo = binding.linkImage
fun bind(position: Int) {
binding.linkBg.setOnClickListener {
viewModel.openUrl(links[position].linkUrl)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LinkViewHolder {
val view = ViewSocialLinkBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val view = ViewSocialLinkBinding.inflate(LayoutInflater.from(context), parent, false)
return LinkViewHolder(view)
}
@ -75,4 +80,15 @@ class LinkAdapter(context: Context, private val viewModel: HomeViewModel) : Recy
override fun getItemCount(): Int = links.size
companion object {
const val INSTAGRAM = "https://instagram.com/vanced.youtube"
const val YOUTUBE = "https://youtube.com/c/YouTubeVanced"
const val GITHUB = "https://github.com/YTVanced/VancedManager"
const val WEBSITE = "https://vancedapp.com"
const val TELEGRAM = "https://t.me/joinchat/AAAAAEHf-pi4jH1SDlAL4w"
const val TWITTER = "https://twitter.com/YTVanced"
const val DISCORD = "https://discord.gg/WCGNdRruzb"
const val REDDIT = "https://www.reddit.com/r/Vanced/"
}
}

View File

@ -9,7 +9,8 @@ import com.vanced.manager.R
import com.vanced.manager.databinding.ViewAppCheckboxBinding
import com.vanced.manager.model.SelectAppModel
class SelectAppsAdapter(context: Context) : RecyclerView.Adapter<SelectAppsAdapter.SelectAppsViewHolder>() {
class SelectAppsAdapter(private val context: Context) :
RecyclerView.Adapter<SelectAppsAdapter.SelectAppsViewHolder>() {
private val prefs by lazy { getDefaultSharedPreferences(context) }
@ -37,7 +38,7 @@ class SelectAppsAdapter(context: Context) : RecyclerView.Adapter<SelectAppsAdapt
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SelectAppsViewHolder {
val view = ViewAppCheckboxBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val view = ViewAppCheckboxBinding.inflate(LayoutInflater.from(context), parent, false)
return SelectAppsViewHolder(view)
}

View File

@ -11,7 +11,7 @@ import com.vanced.manager.model.SponsorModel
import com.vanced.manager.ui.viewmodels.HomeViewModel
class SponsorAdapter(
context: Context,
private val context: Context,
private val viewModel: HomeViewModel,
//private val json: ObservableField<JsonObject?>
) : RecyclerView.Adapter<SponsorAdapter.LinkViewHolder>() {
@ -19,13 +19,13 @@ class SponsorAdapter(
private val brave = SponsorModel(
AppCompatResources.getDrawable(context, R.drawable.ic_brave),
"Brave",
"https://vancedapp.com/brave"
BRAVE
)
private val adguard = SponsorModel(
AppCompatResources.getDrawable(context, R.drawable.ic_adguard),
"AdGuard",
"https://adguard.com/?aid=31141&source=manager"
ADGUARD
)
val sponsors = arrayListOf(brave, adguard)
@ -35,14 +35,17 @@ class SponsorAdapter(
) {
val logo = binding.sponsorLogo
fun bind(position: Int) {
binding.viewModel = viewModel
binding.sponsor = sponsors[position]
with(binding) {
sponsorName.text = sponsors[position].name
cardSponsor.setOnClickListener {
viewModel.openUrl(sponsors[position].url)
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LinkViewHolder {
val view = ViewSponsorBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val view = ViewSponsorBinding.inflate(LayoutInflater.from(context), parent, false)
return LinkViewHolder(view)
}
@ -73,4 +76,9 @@ class SponsorAdapter(
// })
// }
companion object {
const val BRAVE = "https://vancedapp.com/brave"
const val ADGUARD = "https://adguard.com/?aid=31141&source=manager"
}
}

View File

@ -8,7 +8,6 @@ import com.crowdin.platform.Crowdin
import com.crowdin.platform.CrowdinConfig
import com.crowdin.platform.data.model.AuthConfig
import com.crowdin.platform.data.remote.NetworkType
import com.downloader.PRDownloader
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.utils.InternetTools.loadJson
import kotlinx.coroutines.CoroutineScope
@ -24,7 +23,6 @@ open class App: Application() {
override fun onCreate() {
scope.launch { loadJson(this@App) }
super.onCreate()
PRDownloader.initialize(this)
Crowdin.init(this,
CrowdinConfig.Builder().apply {

View File

@ -1,48 +1,30 @@
package com.vanced.manager.core.downloader
import android.content.Context
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.DownloadHelper.fuelDownload
import com.vanced.manager.utils.InternetTools.microg
import com.vanced.manager.utils.PackageHelper.install
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
object MicrogDownloader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
object MicrogDownloader {
fun downloadMicrog(
context: Context,
) = launch {
val url = microg.get()?.string("url")
private const val fileName = "microg.apk"
private const val folderName = "microg"
downloadProgress.value?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk")
.build()
.setOnStartOrResumeListener {
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) })
}
.setOnProgressListener { progress ->
downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
startMicrogInstall(context)
}
fun downloadMicrog(context: Context) {
val url = microg.value?.string("url") ?: ""
fuelDownload(url, folderName, fileName, context, onDownloadComplete = {
startMicrogInstall(context)
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, fileName))
})
override fun onError(error: Error?) {
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, "microG")
}
})
}
}
fun startMicrogInstall(context: Context) {
downloadProgress.value?.installing?.value = true
downloadProgress.value?.reset()
install("${context.getExternalFilesDir("microg")}/microg.apk", context)
downloadProgress.value?.installing?.postValue(true)
downloadProgress.value?.postReset()
install("${context.getExternalFilesDir(folderName)}/$fileName", context)
}
}

View File

@ -2,105 +2,76 @@ package com.vanced.manager.core.downloader
import android.content.Context
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.utils.AppUtils.musicRootPkg
import com.vanced.manager.utils.AppUtils.validateTheme
import com.vanced.manager.utils.DeviceUtils.getArch
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.DownloadHelper.fuelDownload
import com.vanced.manager.utils.Extensions.getInstallUrl
import com.vanced.manager.utils.Extensions.getLatestAppVersion
import com.vanced.manager.utils.InternetTools.backupUrl
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.InternetTools.music
import com.vanced.manager.utils.InternetTools.musicVersions
import com.vanced.manager.utils.PackageHelper.downloadStockCheck
import com.vanced.manager.utils.PackageHelper.install
import com.vanced.manager.utils.PackageHelper.installMusicRoot
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.coroutines.suspendCoroutine
object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
object MusicDownloader {
private var variant: String? = null
private var version: String? = null
private var versionCode: Int? = null
private var baseurl = ""
private var folderName: String? = null
private var downloadPath: String? = null
private var hashUrl: String? = null
fun downloadMusic(context: Context) {
val prefs = getDefaultSharedPreferences(context)
version = prefs.getString("music_version", "latest")?.getLatestAppVersion(musicVersions.get()?.value ?: listOf(""))
versionCode = music.get()?.int("versionCode")
version = prefs.getString("music_version", "latest")?.getLatestAppVersion(musicVersions.value?.value ?: listOf(""))
versionCode = music.value?.int("versionCode")
variant = prefs.getString("vanced_variant", "nonroot")
baseurl = "${prefs.getInstallUrl()}/music/v$version"
downloadPath = context.getExternalFilesDir("music/$variant")?.path
folderName = "music/$variant"
downloadPath = context.getExternalFilesDir(folderName)?.path
hashUrl = "$baseurl/hash.json"
downloadApk(context)
}
private fun downloadApk(context: Context, apk: String = "music") {
launch {
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
suspendCoroutine {
downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener {
downloadProgress.value?.downloadingFile?.value =context.getString(R.string.downloading_file, getFileNameFromUrl(url))
}
.setOnProgressListener { progress ->
downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock") // recursive in coroutine its so bad...
return
}
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
}
}
startMusicInstall(context)
}
override fun onError(error: Error?) {
if (baseurl != backupUrl) {
baseurl = "$backupUrl/music/v$version"
downloadApk(context, apk)
return
}
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, "Music")
}
})
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock")
return@fuelDownload
}
}
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
}
"stock" -> startMusicInstall(context)
}
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, getFileNameFromUrl(url)))
})
}
fun startMusicInstall(context: Context) {
downloadProgress.value?.installing?.value = true
downloadProgress.value?.reset()
downloadProgress.value?.installing?.postValue(true)
downloadProgress.value?.postReset()
if (variant == "root")
installMusicRoot(context)
else

View File

@ -3,9 +3,6 @@ package com.vanced.manager.core.downloader
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.logEvent
import com.vanced.manager.R
@ -13,9 +10,9 @@ import com.vanced.manager.utils.AppUtils.validateTheme
import com.vanced.manager.utils.AppUtils.vancedRootPkg
import com.vanced.manager.utils.DeviceUtils.getArch
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.DownloadHelper.fuelDownload
import com.vanced.manager.utils.Extensions.getInstallUrl
import com.vanced.manager.utils.Extensions.getLatestAppVersion
import com.vanced.manager.utils.InternetTools.backupUrl
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.InternetTools.vanced
import com.vanced.manager.utils.InternetTools.vancedVersions
@ -23,12 +20,9 @@ import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages
import com.vanced.manager.utils.PackageHelper.downloadStockCheck
import com.vanced.manager.utils.PackageHelper.installVanced
import com.vanced.manager.utils.PackageHelper.installVancedRoot
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
object VancedDownloader {
private lateinit var prefs: SharedPreferences
private lateinit var defPrefs: SharedPreferences
@ -48,111 +42,88 @@ object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
private var vancedVersion: String? = null
private var downloadPath: String? = null
private var folderName: String? = null
fun downloadVanced(context: Context) {
defPrefs = getDefaultSharedPreferences(context)
prefs = context.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
variant = defPrefs.getString("vanced_variant", "nonroot")
downloadPath = context.getExternalFilesDir("vanced/$variant")?.path
folderName = "vanced/$variant"
downloadPath = context.getExternalFilesDir(folderName)?.path
File(downloadPath.toString()).deleteRecursively()
installUrl = defPrefs.getInstallUrl()
prefs.getString("lang", getDefaultVancedLanguages())?.let {
lang = it.split(", ").toMutableList()
}
theme = prefs.getString("theme", "dark")
vancedVersion = defPrefs.getString("vanced_version", "latest")?.getLatestAppVersion(vancedVersions.get()?.value ?: listOf(""))
vancedVersion = defPrefs.getString("vanced_version", "latest")?.getLatestAppVersion(vancedVersions.value?.value ?: listOf(""))
themePath = "$installUrl/apks/v$vancedVersion/$variant/Theme"
hashUrl = "apks/v$vancedVersion/$variant/Theme/hash.json"
//newInstaller = defPrefs.getBoolean("new_installer", false)
arch = getArch()
count = 0
vancedVersionCode = vanced.get()?.int("versionCode") ?: 0
vancedVersionCode = vanced.value?.int("versionCode") ?: 0
downloadSplits(context)
}
private fun downloadSplits(
context: Context,
type: String = "theme"
) {
launch {
val url =
when (type) {
"theme" -> "$themePath/$theme.apk"
"arch" -> "$installUrl/apks/v$vancedVersion/$variant/Arch/split_config.$arch.apk"
"stock" -> "$themePath/stock.apk"
"dpi" -> "$themePath/dpi.apk"
"lang" -> "$installUrl/apks/v$vancedVersion/$variant/Language/split_config.${lang[count]}.apk"
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
}
downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener {
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.downloading_file, getFileNameFromUrl(url))
}
.setOnProgressListener { progress ->
downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
when (type) {
"theme" ->
if (variant == "root") {
if (validateTheme(downloadPath!!, theme!!, hashUrl, context)) {
if (downloadStockCheck(vancedRootPkg, vancedVersionCode, context))
downloadSplits(context, "arch")
else
startVancedInstall(context)
} else
downloadSplits(context, "theme")
} else
downloadSplits(context, "arch")
"arch" -> if (variant == "root") downloadSplits(context, "stock") else downloadSplits(context, "lang")
"stock" -> downloadSplits(context, "dpi")
"dpi" -> downloadSplits(context, "lang")
"lang" -> {
count++
succesfulLangCount++
if (count < lang.size)
downloadSplits(context, "lang")
else
startVancedInstall(context)
}
}
}
override fun onError(error: Error?) {
if (installUrl != backupUrl) {
installUrl = backupUrl
themePath = "$installUrl/apks/v$vancedVersion/$variant/Theme"
downloadSplits(context, type)
return
}
if (type == "lang") {
count++
when {
count < lang.size -> downloadSplits(context, "lang")
succesfulLangCount == 0 -> {
lang.add("en")
downloadSplits(context, "lang")
}
else -> startVancedInstall(context)
}
} else {
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, getFileNameFromUrl(url))
}
}
})
private fun downloadSplits(context: Context, type: String = "theme") {
val url = when (type) {
"theme" -> "$themePath/$theme.apk"
"arch" -> "$installUrl/apks/v$vancedVersion/$variant/Arch/split_config.$arch.apk"
"stock" -> "$themePath/stock.apk"
"dpi" -> "$themePath/dpi.apk"
"lang" -> "$installUrl/apks/v$vancedVersion/$variant/Language/split_config.${lang[count]}.apk"
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
}
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
when (type) {
"theme" ->
if (variant == "root") {
if (validateTheme(downloadPath!!, theme!!, hashUrl, context)) {
if (downloadStockCheck(vancedRootPkg, vancedVersionCode, context))
downloadSplits(context, "arch")
else
startVancedInstall(context)
} else
downloadSplits(context, "theme")
} else
downloadSplits(context, "arch")
"arch" -> if (variant == "root") downloadSplits(context, "stock") else downloadSplits(context, "lang")
"stock" -> downloadSplits(context, "dpi")
"dpi" -> downloadSplits(context, "lang")
"lang" -> {
count++
succesfulLangCount++
if (count < lang.size)
downloadSplits(context, "lang")
else
startVancedInstall(context)
}
}
}, onError = {
if (type == "lang") {
count++
when {
count < lang.size -> downloadSplits(context, "lang")
succesfulLangCount == 0 -> {
lang.add("en")
downloadSplits(context, "lang")
}
else -> startVancedInstall(context)
}
} else {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, getFileNameFromUrl(url)))
}
})
}
fun startVancedInstall(context: Context, variant: String? = this.variant) {
downloadProgress.value?.installing?.value = true
downloadProgress.value?.reset()
downloadProgress.value?.installing?.postValue(true)
downloadProgress.value?.postReset()
FirebaseAnalytics.getInstance(context).logEvent(FirebaseAnalytics.Event.SELECT_ITEM) {
variant?.let { param("vanced_variant", it) }
theme?.let { param("vanced_theme", it) }

View File

@ -30,7 +30,7 @@ class AppInstallerService: Service() {
}
else -> {
sendCloseDialog(this)
sendFailure(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999), this)
sendFailure(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999), intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE),this)
}
}
stopSelf()

View File

@ -3,57 +3,70 @@ package com.vanced.manager.model
import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Build
import androidx.databinding.Observable
import androidx.databinding.ObservableBoolean
import androidx.databinding.ObservableField
import androidx.databinding.ObservableInt
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.beust.klaxon.JsonObject
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.lifecycleOwner
import com.vanced.manager.utils.PackageHelper.isPackageInstalled
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
open class DataModel(
private val jsonObject: ObservableField<JsonObject?>,
private val jsonObject: LiveData<JsonObject?>,
private val context: Context,
val appPkg: String,
val appName: String,
val appIcon: Drawable?,
) {
private val versionCode = ObservableInt()
private val installedVersionCode = ObservableInt()
private val versionCode = MutableLiveData<Int>()
private val installedVersionCode = MutableLiveData<Int>()
val isAppInstalled = ObservableBoolean()
val versionName = ObservableField<String>()
val installedVersionName = ObservableField<String>()
val buttonTxt = ObservableField<String>()
val changelog = ObservableField<String>()
val isAppInstalled = MutableLiveData<Boolean>()
val versionName = MutableLiveData<String>()
val installedVersionName = MutableLiveData<String>()
val buttonTxt = MutableLiveData<String>()
val changelog = MutableLiveData<String>()
fun fetch() = CoroutineScope(Dispatchers.IO).launch {
val jobj = jsonObject.get()
isAppInstalled.set(isPackageInstalled(appPkg, context.packageManager))
versionName.set(jobj?.string("version")?.removeSuffix("-vanced") ?: context.getString(R.string.unavailable))
installedVersionName.set(getPkgVersionName(isAppInstalled.get(), appPkg))
versionCode.set(jobj?.int("versionCode") ?: 0)
installedVersionCode.set(getPkgVersionCode(isAppInstalled.get(), appPkg))
buttonTxt.set(compareInt(installedVersionCode.get(), versionCode.get()))
changelog.set(jobj?.string("changelog") ?: context.getString(R.string.unavailable))
private fun fetch() = CoroutineScope(Dispatchers.IO).launch {
val jobj = jsonObject.value
isAppInstalled.postValue(isPackageInstalled(appPkg, context.packageManager))
versionCode.postValue(jobj?.int("versionCode") ?: 0)
versionName.postValue(jobj?.string("version")?.removeSuffix("-vanced") ?: context.getString(
R.string.unavailable
))
changelog.postValue(jobj?.string("changelog") ?: context.getString(R.string.unavailable))
}
init {
fetch()
jsonObject.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
fetch()
with(context.lifecycleOwner()) {
this?.let {
jsonObject.observe(it) {
fetch()
}
}
})
this?.let {
isAppInstalled.observe(it) {
installedVersionCode.postValue(getPkgVersionCode(appPkg))
installedVersionName.postValue(getPkgVersionName(appPkg))
}
}
this?.let {
versionCode.observe(it) { versionCode ->
installedVersionCode.observe(it) { installedVersionCode ->
buttonTxt.value = compareInt(installedVersionCode, versionCode)
}
}
}
}
}
private fun getPkgVersionName(toCheck: Boolean, pkg: String): String {
private fun getPkgVersionName(pkg: String): String {
val pm = context.packageManager
return if (toCheck) {
return if (isAppInstalled.value == true) {
pm.getPackageInfo(pkg, 0).versionName.removeSuffix("-vanced")
} else {
context.getString(R.string.unavailable)
@ -61,23 +74,25 @@ open class DataModel(
}
@Suppress("DEPRECATION")
private fun getPkgVersionCode(toCheck: Boolean, pkg: String): Int {
return if (toCheck) {
private fun getPkgVersionCode(pkg: String): Int {
return if (isAppInstalled.value == true) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
context.packageManager.getPackageInfo(pkg, 0).longVersionCode.and(0xFFFFFFFF).toInt()
context.packageManager.getPackageInfo(pkg, 0).longVersionCode.and(0xFFFFFFFF)
.toInt()
else
context.packageManager.getPackageInfo(pkg, 0).versionCode
} else 0
}
private fun compareInt(int1: Int, int2: Int): String {
return when {
int1 == 0 -> context.getString(R.string.install)
int2 > int1 -> context.getString(R.string.update)
int2 == int1 || int1 > int2 -> context.getString(R.string.button_reinstall)
else -> context.getString(R.string.install)
private fun compareInt(int1: Int?, int2: Int?): String {
if (int2 != null && int1 != null) {
return when {
int1 == 0 -> context.getString(R.string.install)
int2 > int1 -> context.getString(R.string.update)
int2 == int1 || int1 > int2 -> context.getString(R.string.button_reinstall)
else -> context.getString(R.string.install)
}
}
return context.getString(R.string.install)
}
}
}

View File

@ -1,6 +1,7 @@
package com.vanced.manager.model
import androidx.lifecycle.MutableLiveData
import com.github.kittinunf.fuel.core.requests.CancellableRequest
open class ProgressModel {
@ -8,13 +9,18 @@ open class ProgressModel {
val downloadingFile = MutableLiveData<String>()
val installing = MutableLiveData<Boolean>()
var currentDownload: Int = 0
var currentDownload: CancellableRequest? = null
fun reset() {
downloadProgress.value = 0
downloadingFile.value = ""
}
fun postReset() {
downloadProgress.postValue(0)
downloadingFile.postValue("")
}
init {
installing.value = false
reset()

View File

@ -8,16 +8,16 @@ import android.util.Log
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.navigation.NavDestination
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin
import com.crowdin.platform.LoadingStateListener
import com.google.firebase.messaging.FirebaseMessaging
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.BuildConfig.ENABLE_CROWDIN_AUTH
import com.vanced.manager.BuildConfig.VERSION_CODE
import com.vanced.manager.R
import com.vanced.manager.databinding.ActivityMainBinding
import com.vanced.manager.ui.dialogs.DialogContainer
@ -26,13 +26,14 @@ import com.vanced.manager.ui.dialogs.URLChangeDialog
import com.vanced.manager.ui.fragments.HomeFragmentDirections
import com.vanced.manager.ui.fragments.SettingsFragmentDirections
import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.utils.InternetTools
import com.vanced.manager.utils.InternetTools.manager
import com.vanced.manager.utils.LanguageContextWrapper
import com.vanced.manager.utils.LanguageHelper.authCrowdin
import com.vanced.manager.utils.LanguageHelper.onActivityResult
import com.vanced.manager.utils.PackageHelper
import com.vanced.manager.utils.ThemeHelper.setFinalTheme
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
@ -56,18 +57,26 @@ class MainActivity : AppCompatActivity() {
if (ENABLE_CROWDIN_AUTH)
authCrowdin()
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
with(binding) {
lifecycleOwner = this@MainActivity
setSupportActionBar(toolbar)
toolbar.setupWithNavController(this@MainActivity.navHost, AppBarConfiguration(this@MainActivity.navHost.graph))
toolbar.setupWithNavController(
this@MainActivity.navHost,
AppBarConfiguration(this@MainActivity.navHost.graph)
)
}
navHost.addOnDestinationChangedListener { _, currFrag: NavDestination, _ ->
setDisplayHomeAsUpEnabled(currFrag.id != R.id.home_fragment)
}
initDialogs(intent.getBooleanExtra("firstLaunch", false))
manager.observe(this) {
if (manager.value?.int("versionCode") ?: 0 > VERSION_CODE) {
ManagerUpdateDialog.newInstance(false).show(this)
}
}
}
override fun onBackPressed() {
@ -104,7 +113,6 @@ class MainActivity : AppCompatActivity() {
navHost.navigate(HomeFragmentDirections.toSettingsFragment())
return true
}
R.id.toolbar_update_manager -> {
ManagerUpdateDialog.newInstance(false).show(supportFragmentManager, "manager_update")
}
@ -173,14 +181,6 @@ class MainActivity : AppCompatActivity() {
)
}
}
checkUpdates()
}
private fun checkUpdates() {
if (InternetTools.isUpdateAvailable()) {
ManagerUpdateDialog.newInstance(false).show(supportFragmentManager, "UpdateCheck")
}
}
}

View File

@ -2,19 +2,16 @@ package com.vanced.manager.ui
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import com.vanced.manager.R
import com.vanced.manager.databinding.ActivityWelcomeBinding
class WelcomeActivity : AppCompatActivity() {
private lateinit var binding: ActivityWelcomeBinding
private val navHost by lazy { findNavController(R.id.welcome_navhost) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_welcome)
setContentView(R.layout.activity_welcome)
}
override fun onBackPressed() {

View File

@ -6,10 +6,9 @@ import android.view.LayoutInflater
import android.widget.CompoundButton
import android.widget.FrameLayout
import androidx.core.content.edit
import androidx.databinding.BindingAdapter
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.vanced.manager.R
import kotlinx.android.synthetic.main.view_preference_switch.view.*
import com.vanced.manager.databinding.ViewPreferenceSwitchBinding
class PreferenceSwitch @JvmOverloads constructor(
context: Context,
@ -18,26 +17,50 @@ class PreferenceSwitch @JvmOverloads constructor(
defStyleRes: Int = 0
) : FrameLayout(context, attrs, defStyle, defStyleRes) {
interface OnCheckedListener {
fun onChecked(buttonView: CompoundButton, isChecked: Boolean)
}
private val prefs by lazy { getDefaultSharedPreferences(context) }
var prefKey: String = ""
private set
var defValue: Boolean = false
private set
private var mListener: OnCheckedListener? = null
private var _binding: ViewPreferenceSwitchBinding? = null
val binding: ViewPreferenceSwitchBinding
get() = requireNotNull(_binding)
init {
LayoutInflater.from(context).inflate(R.layout.view_preference_switch, this, true)
initAttrs(context, attrs)
_binding = ViewPreferenceSwitchBinding.inflate(LayoutInflater.from(context), this, true)
attrs?.let { mAttrs ->
with(context.obtainStyledAttributes(mAttrs, R.styleable.PreferenceSwitch, 0, 0)) {
val title = getText(R.styleable.PreferenceSwitch_switch_title)
val summary = getText(R.styleable.PreferenceSwitch_switch_summary)
val key = getText(R.styleable.PreferenceSwitch_switch_key)
setDefaultValue(getBoolean(R.styleable.PreferenceSwitch_switch_def_value, false))
setKey(key)
setTitle(title)
setSummary(summary)
recycle()
}
}
}
override fun onFinishInflate() {
super.onFinishInflate()
setOnClickListener {
preference_switch.isChecked = !preference_switch.isChecked
binding.preferenceSwitch.isChecked = !binding.preferenceSwitch.isChecked
}
preference_switch.setOnCheckedChangeListener { buttonView, isChecked ->
binding.preferenceSwitch.setOnCheckedChangeListener { buttonView, isChecked ->
prefs.edit { putBoolean(prefKey, isChecked) }
mListener?.onChecked(buttonView, isChecked)
}
}
fun setOnCheckedListener(method: (buttonView: CompoundButton, isChecked: Boolean) -> Unit) {
@ -52,62 +75,21 @@ class PreferenceSwitch @JvmOverloads constructor(
mListener = listener
}
private fun initAttrs(context: Context, attrs: AttributeSet?) {
attrs?.let { mAttrs ->
val typedArray = context.obtainStyledAttributes(mAttrs, R.styleable.PreferenceSwitch, 0, 0)
val title = typedArray.getText(R.styleable.PreferenceSwitch_switch_title)
val summary = typedArray.getText(R.styleable.PreferenceSwitch_switch_summary)
val key = typedArray.getText(R.styleable.PreferenceSwitch_switch_key)
val value = typedArray.getBoolean(R.styleable.PreferenceSwitch_switch_def_value, false)
if (key != null) {
prefKey = key.toString()
preference_switch.isChecked = prefs.getBoolean(key.toString(), value)
}
defValue = value
preference_switch_title.text = title
if (summary != null) {
preference_switch_summary.text = summary
}
typedArray.recycle()
}
fun setTitle(title: CharSequence?) {
binding.preferenceSwitchTitle.text = title
}
interface OnCheckedListener {
fun onChecked(buttonView: CompoundButton, isChecked: Boolean)
fun setSummary(summary: CharSequence?) {
binding.preferenceSwitchSummary.text = summary
}
companion object {
@JvmStatic
@BindingAdapter("app:switch_title")
fun setTitle(view: PreferenceSwitch, newTitle: String) {
view.preference_switch_title.text = newTitle
}
@JvmStatic
@BindingAdapter("app:switch_summary")
fun setSummary(view: PreferenceSwitch, newSummary: String) {
view.preference_switch_summary.text = newSummary
}
@JvmStatic
@BindingAdapter("app:switch_key")
fun setKey(view: PreferenceSwitch, newKey: String) {
view.prefKey = newKey
view.preference_switch.isChecked = view.prefs.getBoolean(view.prefKey, view.defValue)
}
@JvmStatic
@BindingAdapter("app:switch_def_value")
fun setDefaultValue(view: PreferenceSwitch, newVal: Boolean) {
view.defValue = newVal
view.preference_switch.isChecked = view.prefs.getBoolean(view.prefKey, view.defValue)
}
fun setKey(key: CharSequence?) {
prefKey = key.toString()
binding.preferenceSwitch.isChecked = prefs.getBoolean(prefKey, defValue)
}
fun setDefaultValue(newVal: Boolean) {
defValue = newVal
binding.preferenceSwitch.isChecked = prefs.getBoolean(prefKey, defValue)
}
}

View File

@ -13,10 +13,10 @@ class SplashScreenActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
if (getDefaultSharedPreferences(this).getBoolean("firstLaunch", true)) {
startActivity(Intent(this@SplashScreenActivity, WelcomeActivity::class.java))
startActivity(Intent(this, WelcomeActivity::class.java))
finish()
} else {
startActivity(Intent(this@SplashScreenActivity, MainActivity::class.java))
startActivity(Intent(this, MainActivity::class.java))
finish()
}

View File

@ -0,0 +1,37 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.util.AttributeSet
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.ColorUtils
import com.google.android.material.button.MaterialButton
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.lifecycleOwner
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
class ThemedMaterialButton @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : MaterialButton(context, attributeSet, defStyleAttr) {
init {
setBgColor(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
setBgColor(color.toInt())
}
}
}
private fun setBgColor(color: Int) {
setBackgroundColor(color)
if (ColorUtils.calculateLuminance(color) < 0.7) {
setTextColor(ResourcesCompat.getColor(resources, R.color.White, null))
} else {
setTextColor(ResourcesCompat.getColor(resources, R.color.Black, null))
}
}
}

View File

@ -0,0 +1,25 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import com.google.android.material.checkbox.MaterialCheckBox
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.lifecycleOwner
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
class ThemedMaterialCheckbox @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
) : MaterialCheckBox(context, attributeSet, R.attr.checkboxStyle) {
init {
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
buttonTintList = ColorStateList.valueOf(color.toInt())
}
}
}
}

View File

@ -0,0 +1,25 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.lifecycleOwner
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
class ThemedMaterialRadioButton @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
) : MaterialRadioButton(context, attributeSet, R.attr.radioButtonStyle) {
init {
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
buttonTintList = ColorStateList.valueOf(color.toInt())
}
}
}
}

View File

@ -0,0 +1,32 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import androidx.core.graphics.ColorUtils
import com.google.android.material.button.MaterialButton
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.lifecycleOwner
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
class ThemedOutlinedMaterialButton @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : MaterialButton(context, attributeSet, defStyleAttr) {
init {
applyAccent(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
applyAccent(color.toInt())
}
}
}
private fun applyAccent(color: Int) {
setTextColor(color)
rippleColor = ColorStateList(arrayOf(intArrayOf()), intArrayOf(ColorUtils.setAlphaComponent(color, 50)))
}
}

View File

@ -0,0 +1,38 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.util.AttributeSet
import androidx.appcompat.widget.SwitchCompat
import androidx.core.graphics.ColorUtils
import androidx.core.graphics.drawable.DrawableCompat
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.lifecycleOwner
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
class ThemedSwitchCompat @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
) : SwitchCompat(context, attributeSet, R.attr.switchStyle) {
private val states = arrayOf(intArrayOf(-android.R.attr.state_checked), intArrayOf(android.R.attr.state_checked))
init {
setSwitchColors(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
setSwitchColors(color.toInt())
}
}
}
private fun setSwitchColors(color: Int) {
val thumbColors = intArrayOf(Color.LTGRAY, color)
val trackColors = intArrayOf(Color.GRAY, ColorUtils.setAlphaComponent(color, 70))
DrawableCompat.setTintList(DrawableCompat.wrap(thumbDrawable), ColorStateList(states, thumbColors))
DrawableCompat.setTintList(DrawableCompat.wrap(trackDrawable), ColorStateList(states, trackColors))
}
}

View File

@ -0,0 +1,24 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.lifecycleOwner
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
class ThemedTextView @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatTextView(context, attributeSet, defStyleAttr) {
init {
setTextColor(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
setTextColor(color.toInt())
}
}
}
}

View File

@ -11,14 +11,14 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.core.downloader.MicrogDownloader.downloadMicrog
import com.vanced.manager.core.downloader.MusicDownloader.downloadMusic
import com.vanced.manager.core.downloader.VancedDownloader.downloadVanced
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogAppDownloadBinding
import com.vanced.manager.ui.core.BindingDialogFragment
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.Extensions.applyAccent
class AppDownloadDialog : BindingDialogFragment<DialogAppDownloadBinding>() {
@ -63,6 +63,8 @@ class AppDownloadDialog : BindingDialogFragment<DialogAppDownloadBinding>() {
private fun bindData() {
with(binding) {
isCancelable = false
binding.appDownloadProgressbar.applyAccent()
binding.appInstallProgressbar.applyAccent()
bindDownloadProgress()
val app = arguments?.getString(TAG_APP)
appDownloadHeader.text = app
@ -91,7 +93,8 @@ class AppDownloadDialog : BindingDialogFragment<DialogAppDownloadBinding>() {
if (installing) {
return@setOnClickListener
}
PRDownloader.cancel(progressModel.currentDownload)
progressModel.currentDownload?.cancel()
progressModel.downloadProgress.value = 0
dismiss()
}
}

View File

@ -8,8 +8,8 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.graphics.drawable.toBitmap
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogAppInfoBinding
import com.vanced.manager.ui.core.BindingDialogFragment
class AppInfoDialog : BindingDialogFragment<DialogAppInfoBinding>() {

View File

@ -2,17 +2,17 @@ package com.vanced.manager.ui.dialogs
import android.content.DialogInterface
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.DialogBottomRadioButtonBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.ui.core.ThemedMaterialRadioButton
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.show
class AppVersionSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomRadioButtonBinding>() {
@ -74,7 +74,7 @@ class AppVersionSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomRa
private fun loadBoxes() =
arguments?.getStringArrayList(TAG_VERSIONS)?.map { version ->
MaterialRadioButton(requireActivity()).apply {
ThemedMaterialRadioButton(requireActivity()).apply {
text = version
tag = version
textSize = 18f
@ -84,9 +84,9 @@ class AppVersionSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomRa
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
if (arguments?.getString(TAG_APP) == "vanced") {
VancedPreferencesDialog().show(requireActivity())
showDialog(VancedPreferencesDialog())
} else {
MusicPreferencesDialog().show(requireActivity())
showDialog(MusicPreferencesDialog())
}
}
}

View File

@ -9,6 +9,7 @@ import androidx.core.content.edit
import androidx.preference.PreferenceManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.applyAccent
import com.vanced.manager.utils.InternetTools.openUrl
import com.vanced.manager.utils.MiuiHelper
@ -23,22 +24,22 @@ object DialogContainer {
}
setOnDismissListener {
if (MiuiHelper.isMiui()) {
showMiuiDialog(context)
applyAccentMiuiDialog(context)
}
}
setOnCancelListener {
if (MiuiHelper.isMiui()) {
showMiuiDialog(context)
applyAccentMiuiDialog(context)
}
}
create()
show()
applyAccent()
}
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs.edit { putBoolean("firstLaunch", false) }
}
private fun showMiuiDialog(context: Context) {
private fun applyAccentMiuiDialog(context: Context) {
MaterialAlertDialogBuilder(context).apply {
setTitle(context.getString(R.string.miui_one_title))
setMessage(context.getString(R.string.miui_one))
@ -52,7 +53,7 @@ object DialogContainer {
}
setCancelable(false)
create()
show()
applyAccent()
}
}
@ -62,7 +63,7 @@ object DialogContainer {
setMessage("So this statement is false huh? I'll go with True!")
setPositiveButton("wut?") { dialog, _ -> dialog.dismiss() }
create()
show()
applyAccent()
}
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
@ -97,7 +98,7 @@ object DialogContainer {
}
}
create()
show()
applyAccent()
}
}
@ -107,7 +108,7 @@ object DialogContainer {
setMessage(msg)
setPositiveButton(context.getString(R.string.close)) { dialog, _ -> dialog.dismiss() }
create()
show()
applyAccent()
}
}
@ -127,7 +128,7 @@ object DialogContainer {
}
setNegativeButton(context.getString(R.string.close)) { dialog, _ -> dialog.dismiss() }
create()
show()
applyAccent()
}
}
@ -142,7 +143,7 @@ object DialogContainer {
}
setNegativeButton(activity.getString(R.string.close)) { dialog, _ -> dialog.dismiss() }
create()
show()
applyAccent()
}
}

View File

@ -3,14 +3,14 @@ package com.vanced.manager.ui.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.vanced.manager.R
import com.vanced.manager.core.downloader.MicrogDownloader.startMicrogInstall
import com.vanced.manager.core.downloader.MusicDownloader.startMusicInstall
import com.vanced.manager.core.downloader.VancedDownloader.startVancedInstall
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.show
class InstallationFilesDetectedDialog : BindingBottomSheetDialogFragment<DialogInstallationFilesDetectedBinding>() {
@ -45,23 +45,30 @@ class InstallationFilesDetectedDialog : BindingBottomSheetDialogFragment<DialogI
installationDetectedRedownload.setOnClickListener {
dismiss()
if (app == getString(R.string.vanced))
VancedPreferencesDialog().show(requireActivity())
showDialog(VancedPreferencesDialog())
else {
AppDownloadDialog.newInstance(app).show(requireActivity())
showDialog(AppDownloadDialog.newInstance(app))
}
}
installationDetectedInstall.setOnClickListener {
dismiss()
when (app) {
getString(R.string.vanced) -> startVancedInstall(requireContext(),
getDefaultSharedPreferences(requireContext()).getString("vanced_variant", "nonroot"))
getString(R.string.vanced) -> startVancedInstall(
requireContext(),
getDefaultSharedPreferences(requireContext()).getString(
"vanced_variant",
"nonroot"
)
)
getString(R.string.music) -> startMusicInstall(requireContext())
getString(R.string.microg) -> startMicrogInstall(requireContext())
}
AppDownloadDialog.newInstance(
app = app,
installing = true
).show(requireActivity())
showDialog(
AppDownloadDialog.newInstance(
app = app,
installing = true
)
)
}
}
}

View File

@ -1,21 +1,27 @@
package com.vanced.manager.ui.dialogs
import android.content.DialogInterface
import android.graphics.Color
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.radiobutton.MaterialRadioButton
import com.madrapps.pikolo.listeners.OnColorSelectionListener
import com.vanced.manager.R
import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogManagerAccentColorBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.Extensions.toHex
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
import com.vanced.manager.utils.ThemeHelper.mutableAccentColor
class ManagerAccentColorDialog : BindingBottomSheetDialogFragment<DialogManagerAccentColorBinding>() {
class ManagerAccentColorDialog : BindingDialogFragment<DialogManagerAccentColorBinding>() {
companion object {
fun newInstance(): ManagerAccentColorDialog = ManagerAccentColorDialog().apply {
@ -35,19 +41,73 @@ class ManagerAccentColorDialog : BindingBottomSheetDialogFragment<DialogManagerA
bindData()
}
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
mutableAccentColor.value = prefs.getInt("manager_accent", defAccentColor)
}
private fun bindData() {
with(binding) {
val accent = prefs.getString("manager_accent", "Blue")
root.findViewWithTag<MaterialRadioButton>(accent).isChecked = true
val accent = prefs.getInt("manager_accent", defAccentColor)
hexEdittext.apply {
setText(accent.toHex(), TextView.BufferType.EDITABLE)
addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (length() == 0) {
setText("#")
setSelection(1)
}
if (accentColor.value?.toHex() != text.toString() && length() == 7) {
try {
val colorFromEditText = Color.parseColor(text.toString())
accentPicker.setColor(colorFromEditText)
mutableAccentColor.value = colorFromEditText
} catch (e: IllegalArgumentException) {}
}
}
override fun afterTextChanged(s: Editable?) {}
})
}
accentPicker.apply {
setColor(accent)
setColorSelectionListener(object : OnColorSelectionListener {
override fun onColorSelected(color: Int) {
mutableAccentColor.value = color
hexEdittext.setText(color.toHex(), TextView.BufferType.EDITABLE)
}
override fun onColorSelectionEnd(color: Int) {}
override fun onColorSelectionStart(color: Int) {}
})
}
accentCancel.setOnClickListener {
mutableAccentColor.value = accent
dismiss()
}
accentSave.setOnClickListener {
val newPref = binding.accentRadiogroup.getCheckedButtonTag()
if (accent != newPref) {
prefs.edit { putString("manager_accent", newPref) }
dismiss()
requireActivity().recreate()
} else {
dismiss()
try {
val colorFromEditText = Color.parseColor(hexEdittext.text.toString())
mutableAccentColor.value = colorFromEditText
prefs.edit { putInt("manager_accent", colorFromEditText) }
} catch (e: IllegalArgumentException) {
Log.d("VMTheme", getString(R.string.failed_accent))
Toast.makeText(requireActivity(), getString(R.string.failed_accent), Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
dismiss()
}
accentReset.setOnClickListener {
prefs.edit { putInt("manager_accent", defAccentColor) }
mutableAccentColor.value = defAccentColor
dismiss()
}
}
}

View File

@ -3,13 +3,14 @@ package com.vanced.manager.ui.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.*
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.BuildConfig.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.vanced.manager.BuildConfig.MANAGER_LANGUAGES
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.databinding.DialogManagerLanguageBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.ui.core.ThemedMaterialRadioButton
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.LanguageHelper.getLanguageFormat
@ -40,7 +41,7 @@ class ManagerLanguageDialog : BindingBottomSheetDialogFragment<DialogManagerLang
languageRadiogroup.addView(mrb, MATCH_PARENT, WRAP_CONTENT)
}
val language = prefs.getString("manager_lang", "System Default")
root.findViewWithTag<MaterialRadioButton>(language).isChecked = true
root.findViewWithTag<ThemedMaterialRadioButton>(language).isChecked = true
languageSave.setOnClickListener {
val newPref = binding.languageRadiogroup.getCheckedButtonTag()
if (language != newPref) {
@ -56,7 +57,7 @@ class ManagerLanguageDialog : BindingBottomSheetDialogFragment<DialogManagerLang
private fun addRadioButtons() =
(arrayOf("System Default") + MANAGER_LANGUAGES).map { lang ->
MaterialRadioButton(requireActivity()).apply {
ThemedMaterialRadioButton(requireActivity()).apply {
text = getLanguageFormat(requireActivity(), lang)
textSize = 18f
tag = lang

View File

@ -4,10 +4,10 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.databinding.DialogManagerThemeBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
class ManagerThemeDialog : BindingBottomSheetDialogFragment<DialogManagerThemeBinding>() {

View File

@ -10,22 +10,21 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader
import com.vanced.manager.BuildConfig.VERSION_CODE
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogManagerUpdateBinding
import com.vanced.manager.ui.core.BindingDialogFragment
import com.vanced.manager.utils.DownloadHelper.downloadManager
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.isUpdateAvailable
import kotlinx.coroutines.launch
import com.vanced.manager.utils.Extensions.applyAccent
import com.vanced.manager.utils.InternetTools.manager
class ManagerUpdateDialog : BindingDialogFragment<DialogManagerUpdateBinding>() {
companion object {
const val CLOSE_DIALOG = "close_dialog"
const val CLOSE_DIALOG = "CLOSE_DIALOG"
private const val TAG_FORCE_UPDATE = "TAG_FORCE_UPDATE"
fun newInstance(
@ -56,24 +55,25 @@ class ManagerUpdateDialog : BindingDialogFragment<DialogManagerUpdateBinding>()
override fun otherSetups() {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
bindData()
lifecycleScope.launch {
if (arguments?.getBoolean(TAG_FORCE_UPDATE) == true) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else {
checkUpdates()
}
binding.managerUpdateCancel.setOnClickListener {
PRDownloader.cancel(downloadProgress.value?.currentDownload)
dismiss()
}
if (arguments?.getBoolean(TAG_FORCE_UPDATE) == true) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else {
checkUpdates()
}
}
private fun bindData() {
with(binding) {
isCancelable = false
managerUpdateProgressbar.applyAccent()
managerUpdateCancel.setOnClickListener {
with(downloadProgress.value) {
this?.downloadProgress?.value = 0
this?.currentDownload?.cancel()
}
dismiss()
}
bindDownloadProgress()
}
}
@ -94,8 +94,8 @@ class ManagerUpdateDialog : BindingDialogFragment<DialogManagerUpdateBinding>()
registerReceiver()
}
private suspend fun checkUpdates() {
if (isUpdateAvailable()) {
private fun checkUpdates() {
if (manager.value?.int("versionCode") ?: 0 > VERSION_CODE) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else {

View File

@ -4,11 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.radiobutton.MaterialRadioButton
import com.topjohnwu.superuser.Shell
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.databinding.DialogManagerVariantBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
class ManagerVariantDialog : BindingBottomSheetDialogFragment<DialogManagerVariantBinding>() {

View File

@ -4,11 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.DialogMusicPreferencesBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.convertToAppVersions
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.utils.InternetTools.musicVersions
class MusicPreferencesDialog : BindingBottomSheetDialogFragment<DialogMusicPreferencesBinding>() {
@ -34,21 +34,25 @@ class MusicPreferencesDialog : BindingBottomSheetDialogFragment<DialogMusicPrefe
private fun bindData() {
with(binding) {
val musicVersionsConv = musicVersions.get()?.value?.reversed()?.convertToAppVersions()
val musicVersionsConv = musicVersions.value?.value?.reversed()?.convertToAppVersions()
musicInstallTitle.text = getString(R.string.app_installation_preferences, getString(R.string.music))
musicVersion.text = getString(R.string.chosen_version, prefs.getString("music_version", "latest"))
openVersionSelector.setOnClickListener {
dismiss()
AppVersionSelectorDialog.newInstance(
versions = musicVersionsConv,
app = "music"
).show(requireActivity())
showDialog(
AppVersionSelectorDialog.newInstance(
versions = musicVersionsConv,
app = "music"
)
)
}
musicInstall.setOnClickListener {
dismiss()
AppDownloadDialog.newInstance(
app = getString(R.string.music)
).show(requireActivity())
showDialog(
AppDownloadDialog.newInstance(
app = getString(R.string.music)
)
)
}
}
}

View File

@ -5,12 +5,12 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.LinearLayoutManager
import com.vanced.manager.R
import com.vanced.manager.adapter.SelectAppsAdapter
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.databinding.DialogSelectAppsBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
class SelectAppsDialog : BindingBottomSheetDialogFragment<DialogSelectAppsBinding>() {

View File

@ -9,10 +9,10 @@ import android.widget.TextView
import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogCustomUrlBinding
import com.vanced.manager.ui.core.BindingDialogFragment
import com.vanced.manager.utils.Extensions.fetchData
import com.vanced.manager.utils.InternetTools.baseUrl
import com.vanced.manager.utils.InternetTools.loadJson
import kotlinx.coroutines.launch
class URLChangeDialog : BindingDialogFragment<DialogCustomUrlBinding>() {
@ -37,7 +37,6 @@ class URLChangeDialog : BindingDialogFragment<DialogCustomUrlBinding>() {
private fun bindData() {
with(binding) {
urlInput.setText(
if (arguments != null) {
arguments?.getString("url")
@ -61,7 +60,7 @@ class URLChangeDialog : BindingDialogFragment<DialogCustomUrlBinding>() {
private fun saveUrl(url: String) {
lifecycleScope.launch {
getDefaultSharedPreferences(requireActivity()).edit { putString("install_url", url) }
requireActivity().fetchData()
loadJson(requireActivity())
dismiss()
}
}

View File

@ -5,16 +5,18 @@ import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.*
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.content.edit
import androidx.core.content.res.ResourcesCompat
import com.google.android.material.checkbox.MaterialCheckBox
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.DialogVancedLanguageSelectionBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.ui.core.ThemedMaterialCheckbox
import com.vanced.manager.utils.InternetTools.vanced
import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages
import java.util.*
@ -28,7 +30,7 @@ class VancedLanguageSelectionDialog : BindingBottomSheetDialogFragment<DialogVan
}
}
private val langs = vanced.get()?.array<String>("langs")?.value
private val langs = vanced.value?.array<String>("langs")?.value
private val prefs by lazy { requireActivity().getSharedPreferences("installPrefs", Context.MODE_PRIVATE) }
override fun binding(
@ -65,7 +67,7 @@ class VancedLanguageSelectionDialog : BindingBottomSheetDialogFragment<DialogVan
val langPrefs = prefs.getString("lang", getDefaultVancedLanguages())
langs?.forEach { lang ->
val loc = Locale(lang)
val box: MaterialCheckBox = MaterialCheckBox(requireActivity()).apply {
val box = ThemedMaterialCheckbox(requireActivity()).apply {
tag = lang
isChecked = langPrefs?.contains(lang) ?: false
text = loc.getDisplayLanguage(loc).capitalize(Locale.ROOT)
@ -78,6 +80,6 @@ class VancedLanguageSelectionDialog : BindingBottomSheetDialogFragment<DialogVan
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
VancedPreferencesDialog().show(requireActivity())
showDialog(VancedPreferencesDialog())
}
}

View File

@ -5,12 +5,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.DialogVancedPreferencesBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.convertToAppTheme
import com.vanced.manager.utils.Extensions.convertToAppVersions
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.utils.InternetTools.vancedVersions
import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages
import java.util.*
@ -44,31 +44,35 @@ class VancedPreferencesDialog : BindingBottomSheetDialogFragment<DialogVancedPre
val loc = Locale(lang)
showLang.add(loc.getDisplayLanguage(loc).capitalize(Locale.ROOT))
}
val vancedVersionsConv = vancedVersions.get()?.value?.reversed()?.convertToAppVersions()
val vancedVersionsConv = vancedVersions.value?.value?.reversed()?.convertToAppVersions()
vancedInstallTitle.text = getString(R.string.app_installation_preferences, getString(R.string.vanced))
vancedTheme.text = getString(R.string.chosen_theme, installPrefs.getString("theme", "dark")?.convertToAppTheme(requireActivity()))
vancedVersion.text = getString(R.string.chosen_version, defPrefs.getString("vanced_version", "latest"))
vancedLang.text = getString(R.string.chosen_lang, showLang)
openThemeSelector.setOnClickListener {
dismiss()
VancedThemeSelectorDialog().show(requireActivity())
showDialog(VancedThemeSelectorDialog())
}
openVersionSelector.setOnClickListener {
dismiss()
AppVersionSelectorDialog.newInstance(
versions = vancedVersionsConv,
app = "vanced"
).show(requireActivity())
showDialog(
AppVersionSelectorDialog.newInstance(
versions = vancedVersionsConv,
app = "vanced"
)
)
}
openLanguageSelector.setOnClickListener {
dismiss()
VancedLanguageSelectionDialog().show(requireActivity())
showDialog(VancedLanguageSelectionDialog())
}
vancedInstall.setOnClickListener {
dismiss()
AppDownloadDialog.newInstance(
app = getString(R.string.vanced)
).show(requireActivity())
showDialog(
AppDownloadDialog.newInstance(
app = getString(R.string.vanced)
)
)
}
}
}

View File

@ -4,18 +4,15 @@ import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingBottomSheetDialogFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.DialogBottomRadioButtonBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.ui.core.ThemedMaterialRadioButton
import com.vanced.manager.utils.Extensions.convertToAppTheme
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.utils.InternetTools.vanced
class VancedThemeSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomRadioButtonBinding>() {
@ -49,7 +46,7 @@ class VancedThemeSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomR
)
}
dialogTitle.text = requireActivity().getString(R.string.theme)
val tag = root.findViewWithTag<MaterialRadioButton>(prefs.getString("theme", "dark"))
val tag = root.findViewWithTag<ThemedMaterialRadioButton>(prefs.getString("theme", "dark"))
if (tag != null) {
tag.isChecked = true
}
@ -63,8 +60,8 @@ class VancedThemeSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomR
}
}
private fun loadButtons() = vanced.get()?.array<String>("themes")?.value?.map {theme ->
MaterialRadioButton(requireActivity()).apply {
private fun loadButtons() = vanced.value?.array<String>("themes")?.value?.map {theme ->
ThemedMaterialRadioButton(requireActivity()).apply {
text = theme.convertToAppTheme(requireActivity())
tag = theme
textSize = 18f
@ -73,6 +70,6 @@ class VancedThemeSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomR
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
VancedPreferencesDialog().show(requireActivity())
showDialog(VancedPreferencesDialog())
}
}

View File

@ -11,9 +11,9 @@ import androidx.core.content.edit
import androidx.fragment.app.viewModels
import androidx.preference.PreferenceManager
import com.vanced.manager.R
import com.vanced.manager.core.ext.showDialog
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.FragmentAboutBinding
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.dialogs.AppInfoDialog
import com.vanced.manager.ui.viewmodels.AboutViewModel
import com.vanced.manager.utils.InternetTools.manager
@ -42,7 +42,7 @@ class AboutFragment : BindingFragment<FragmentAboutBinding>() {
AppInfoDialog.newInstance(
appName = getString(R.string.app_name),
appIcon = AppCompatResources.getDrawable(requireActivity(), R.mipmap.ic_launcher),
changelog = manager.get()?.string("changelog")
changelog = manager.value?.string("changelog")
)
)
}

View File

@ -10,7 +10,7 @@ import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.preference.*
import com.crowdin.platform.Crowdin
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.BuildConfig.ENABLE_CROWDIN_AUTH
import com.vanced.manager.R
import com.vanced.manager.ui.WelcomeActivity
import com.vanced.manager.ui.dialogs.ManagerUpdateDialog

View File

@ -9,9 +9,9 @@ import androidx.core.content.edit
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.topjohnwu.superuser.Shell
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.databinding.FragmentGrantRootBinding
import com.vanced.manager.ui.MainActivity
import com.vanced.manager.ui.core.BindingFragment
class GrantRootFragment : BindingFragment<FragmentGrantRootBinding>() {

View File

@ -23,17 +23,18 @@ import com.vanced.manager.R
import com.vanced.manager.adapter.AppListAdapter
import com.vanced.manager.adapter.LinkAdapter
import com.vanced.manager.adapter.SponsorAdapter
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.databinding.FragmentHomeBinding
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.dialogs.DialogContainer.installAlertBuilder
import com.vanced.manager.ui.viewmodels.HomeViewModel
import com.vanced.manager.ui.viewmodels.HomeViewModelFactory
import com.vanced.manager.utils.InternetTools.isFetching
open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
companion object {
const val INSTALL_FAILED = "install_failed"
const val REFRESH_HOME = "refresh_home"
const val INSTALL_FAILED = "INSTALL_FAILED"
const val REFRESH_HOME = "REFRESH_HOME"
}
private val viewModel: HomeViewModel by viewModels {
@ -57,8 +58,9 @@ open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
private fun bindData() {
requireActivity().title = getString(R.string.title_home)
setHasOptionsMenu(true)
with(binding) {
with (binding) {
homeRefresh.setOnRefreshListener { viewModel.fetchData() }
isFetching.observe(viewLifecycleOwner) { homeRefresh.isRefreshing = it }
tooltip = ViewTooltip
.on(recyclerAppList)
.position(ViewTooltip.Position.TOP)
@ -77,7 +79,7 @@ open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
recyclerAppList.apply {
layoutManager = LinearLayoutManager(requireActivity())
adapter = AppListAdapter(requireActivity(), this@HomeFragment.viewModel, tooltip)
adapter = AppListAdapter(requireActivity(), viewModel, viewLifecycleOwner, tooltip)
setHasFixedSize(true)
}
@ -86,7 +88,7 @@ open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
lm.justifyContent = JustifyContent.SPACE_EVENLY
layoutManager = lm
setHasFixedSize(true)
adapter = SponsorAdapter(requireActivity(), this@HomeFragment.viewModel)
adapter = SponsorAdapter(requireActivity(), viewModel)
}
recyclerLinks.apply {
@ -94,7 +96,7 @@ open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
lm.justifyContent = JustifyContent.SPACE_EVENLY
layoutManager = lm
setHasFixedSize(true)
adapter = LinkAdapter(requireActivity(), this@HomeFragment.viewModel)
adapter = LinkAdapter(requireActivity(), viewModel)
}
}
}
@ -108,13 +110,11 @@ open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
super.onPause()
localBroadcastManager.unregisterReceiver(broadcastReceiver)
tooltip.close()
//binding.mainTablayout.removeOnTabSelectedListener(tabListener)
}
override fun onResume() {
super.onResume()
registerReceivers()
// binding.mainTablayout.addOnTabSelectedListener(tabListener)
}
private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {

View File

@ -10,8 +10,8 @@ import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.LinearLayoutManager
import com.vanced.manager.R
import com.vanced.manager.adapter.SelectAppsAdapter
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.databinding.FragmentSelectAppsBinding
import com.vanced.manager.ui.core.BindingFragment
class SelectAppsFragment : BindingFragment<FragmentSelectAppsBinding>() {

View File

@ -13,11 +13,14 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.perf.FirebasePerformance
import com.vanced.manager.R
import com.vanced.manager.adapter.GetNotifAdapter
import com.vanced.manager.core.ext.showDialogRefl
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.FragmentSettingsBinding
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.dialogs.*
import com.vanced.manager.utils.Extensions.toHex
import com.vanced.manager.utils.LanguageHelper.getLanguageFormat
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
import java.io.File
class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
@ -26,10 +29,6 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
const val LIGHT = "Light"
const val DARK = "Dark"
const val BLUE = "Blue"
const val RED = "Red"
const val GREEN = "Green"
const val YELLOW = "Yellow"
}
private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) }
@ -54,7 +53,7 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
bindManagerTheme()
bindManagerAccentColor()
bindManagerLanguage()
selectApps.setOnClickListener { showDialogRefl<SelectAppsDialog>() }
selectApps.setOnClickListener { showDialog(SelectAppsDialog()) }
}
}
@ -76,7 +75,7 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
private fun FragmentSettingsBinding.bindManagerVariant() {
managerVariant.apply {
prefs.getString("vanced_variant", "nonroot")?.let { setSummary(it) }
setOnClickListener { showDialogRefl<ManagerVariantDialog>() }
setOnClickListener { showDialog(ManagerVariantDialog()) }
}
}
private fun FragmentSettingsBinding.bindClearFiles() {
@ -96,27 +95,21 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
setSummary(
when (themePref) {
LIGHT -> getString(R.string.theme_light)
DARK -> getString(R.string.theme_dark)
else -> getString(R.string.system_default)
DARK -> getString(R.string.theme_dark)
else -> getString(R.string.system_default)
}
)
setOnClickListener { showDialogRefl<ManagerThemeDialog>() }
setOnClickListener { showDialog(ManagerThemeDialog()) }
}
}
private fun FragmentSettingsBinding.bindManagerAccentColor() {
val accentPref = prefs.getString("manager_accent", "Blue")
managerAccentColor.setSummary(prefs.getInt("manager_accent", defAccentColor).toHex())
managerAccentColor.apply {
setSummary(
when (accentPref) {
BLUE -> getString(R.string.accent_blue)
RED -> getString(R.string.accent_red)
GREEN -> getString(R.string.accent_green)
YELLOW -> getString(R.string.accent_yellow)
else -> getString(R.string.accent_purple)
}
)
setOnClickListener { showDialogRefl<ManagerAccentColorDialog>() }
setOnClickListener { showDialog(ManagerAccentColorDialog()) }
accentColor.observe(viewLifecycleOwner) {
managerAccentColor.setSummary(prefs.getInt("manager_accent", defAccentColor).toHex())
}
}
}
@ -124,7 +117,7 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
val langPref = prefs.getString("manager_lang", "System Default")
managerLanguage.apply {
setSummary(getLanguageFormat(requireActivity(), requireNotNull(langPref)))
setOnClickListener { showDialogRefl<ManagerLanguageDialog>() }
setOnClickListener { showDialog(ManagerLanguageDialog()) }
}
}

View File

@ -4,8 +4,8 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.databinding.FragmentWelcomeBinding
import com.vanced.manager.ui.core.BindingFragment
class WelcomeFragment : BindingFragment<FragmentWelcomeBinding>() {

View File

@ -1,20 +1,21 @@
package com.vanced.manager.ui.viewmodels
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.view.View
import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat.startActivity
import androidx.databinding.ObservableField
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin
import com.google.android.material.button.MaterialButton
import com.vanced.manager.R
import com.vanced.manager.adapter.LinkAdapter.Companion.DISCORD
import com.vanced.manager.adapter.LinkAdapter.Companion.REDDIT
import com.vanced.manager.adapter.LinkAdapter.Companion.TELEGRAM
import com.vanced.manager.adapter.LinkAdapter.Companion.TWITTER
import com.vanced.manager.adapter.SponsorAdapter.Companion.BRAVE
import com.vanced.manager.model.DataModel
import com.vanced.manager.ui.dialogs.AppDownloadDialog
import com.vanced.manager.ui.dialogs.InstallationFilesDetectedDialog
@ -26,8 +27,6 @@ import com.vanced.manager.utils.AppUtils.musicPkg
import com.vanced.manager.utils.AppUtils.musicRootPkg
import com.vanced.manager.utils.AppUtils.vancedPkg
import com.vanced.manager.utils.AppUtils.vancedRootPkg
import com.vanced.manager.utils.Extensions.fetchData
import com.vanced.manager.utils.Extensions.setRefreshing
import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.utils.InternetTools
import com.vanced.manager.utils.InternetTools.loadJson
@ -42,47 +41,30 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
private val prefs = getDefaultSharedPreferences(activity)
val vanced = ObservableField<DataModel>()
val vancedRoot = ObservableField<DataModel>()
val microg = ObservableField<DataModel>()
val music = ObservableField<DataModel>()
val musicRoot = ObservableField<DataModel>()
val manager = ObservableField<DataModel>()
val vanced = MutableLiveData<DataModel>()
val vancedRoot = MutableLiveData<DataModel>()
val microg = MutableLiveData<DataModel>()
val music = MutableLiveData<DataModel>()
val musicRoot = MutableLiveData<DataModel>()
val manager = MutableLiveData<DataModel>()
fun fetchData() {
viewModelScope.launch {
activity.setRefreshing(true)
loadJson(activity)
Crowdin.forceUpdate(activity)
activity.setRefreshing(false)
}
}
private val microgToast = Toast.makeText(activity, R.string.no_microg, Toast.LENGTH_LONG)
fun openMicrogSettings() {
try {
val intent = Intent()
intent.component = ComponentName(
"com.mgoogle.android.gms",
"org.microg.gms.ui.SettingsActivity"
)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(activity, intent, null)
} catch (e: ActivityNotFoundException) {
Toast.makeText(activity, "Error", Toast.LENGTH_SHORT).show()
}
}
fun openUrl(url: String) {
val color: Int =
when (url) {
"https://discord.gg/TUVd7rd" -> R.color.Discord
"https://t.me/joinchat/AAAAAEHf-pi4jH1SDlAL4w" -> R.color.Telegram
"https://twitter.com/YTVanced" -> R.color.Twitter
"https://reddit.com/r/vanced" -> R.color.Reddit
"https://vanced.activity" -> R.color.Vanced
"https://brave.com/van874" -> R.color.Brave
DISCORD -> R.color.Discord
TELEGRAM -> R.color.Telegram
TWITTER -> R.color.Twitter
REDDIT -> R.color.Reddit
BRAVE -> R.color.Brave
else -> R.color.Vanced
}
@ -91,7 +73,7 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
fun openInstallDialog(view: View, app: String) {
val variant = prefs.getString("vanced_variant", "nonroot")
if (variant == "nonroot" && app != activity.getString(R.string.microg) && !microg.get()?.isAppInstalled?.get()!!) {
if (variant == "nonroot" && app != activity.getString(R.string.microg) && !microg.value?.isAppInstalled?.value!!) {
microgToast.show()
return
}
@ -148,20 +130,18 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
fun uninstallPackage(pkg: String) {
if (prefs.getString("vanced_variant", "nonroot") == "root" && uninstallRootApk(pkg)) {
viewModelScope.launch { activity.fetchData() }
viewModelScope.launch { loadJson(activity) }
} else {
uninstallApk(pkg, activity)
}
}
init {
activity.setRefreshing(true)
vanced.set(DataModel(InternetTools.vanced, activity, vancedPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced)))
vancedRoot.set(DataModel(InternetTools.vanced, activity, vancedRootPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced)))
music.set(DataModel(InternetTools.music, activity, musicPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music)))
musicRoot.set(DataModel(InternetTools.music, activity, musicRootPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music)))
microg.set(DataModel(InternetTools.microg, activity, microgPkg, activity.getString(R.string.microg), AppCompatResources.getDrawable(activity, R.drawable.ic_microg)))
manager.set(DataModel(InternetTools.manager, activity, managerPkg, activity.getString(R.string.app_name), AppCompatResources.getDrawable(activity, R.mipmap.ic_launcher)))
activity.setRefreshing(false)
vanced.value = DataModel(InternetTools.vanced, activity, vancedPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced))
vancedRoot.value = DataModel(InternetTools.vanced, activity, vancedRootPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced))
music.value = DataModel(InternetTools.music, activity, musicPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music))
musicRoot.value = DataModel(InternetTools.music, activity, musicRootPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music))
microg.value = DataModel(InternetTools.microg, activity, microgPkg, activity.getString(R.string.microg), AppCompatResources.getDrawable(activity, R.drawable.ic_microg))
manager.value = DataModel(InternetTools.manager, activity, managerPkg, activity.getString(R.string.app_name), AppCompatResources.getDrawable(activity, R.mipmap.ic_launcher))
}
}

View File

@ -39,12 +39,13 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
}
}
fun sendFailure(status: Int, context: Context): Job {
fun sendFailure(status: Int, fullError: String?, context: Context): Job {
//Delay error broadcast until activity (and fragment) get back to the screen
return launch {
delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED)
intent.putExtra("errorMsg", getErrorMessage(status, context))
intent.putExtra("fullErrorMsg", fullError)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
}
}

View File

@ -10,5 +10,4 @@ object DeviceUtils {
else -> "armeabi_v7a"
}
}

View File

@ -1,37 +1,42 @@
package com.vanced.manager.utils
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.core.content.getSystemService
import androidx.core.net.toUri
import androidx.lifecycle.MutableLiveData
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.github.kittinunf.fuel.Fuel
import com.vanced.manager.R
import com.vanced.manager.model.ProgressModel
import com.vanced.manager.utils.AppUtils.sendCloseDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.launch
import java.io.File
object DownloadHelper {
object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun download(url: String, dir: String, child: String, context: Context): Long {
val request = DownloadManager.Request(url.toUri()).apply {
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI)
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
setTitle(context.getString(R.string.downloading_file, child))
setDestinationInExternalFilesDir(context, dir, child)
}
val downloadManager = context.getSystemService<DownloadManager>()!!
return downloadManager.enqueue(request)
fun fuelDownload(url: String, fileFolder: String, fileName: String, context: Context, onDownloadComplete: () -> Unit, onError: (error: String) -> Unit) = launch {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.downloading_file, fileName))
downloadProgress.value?.currentDownload = Fuel.download(url)
.fileDestination { _, _ ->
File(context.getExternalFilesDir(fileFolder)?.path, fileName)
}
.progress { readBytes, totalBytes ->
downloadProgress.value?.downloadProgress?.postValue((readBytes * 100 / totalBytes).toInt())
}
.responseString { _, _, result ->
result.fold(success = {
downloadProgress.value?.downloadProgress?.postValue(0)
onDownloadComplete()
}, failure = { error ->
downloadProgress.value?.downloadProgress?.postValue(0)
Log.d("VMDownloader", error.cause.toString())
onError(error.errorData.toString())
})
}
}
val downloadProgress = MutableLiveData<ProgressModel>()
@ -40,46 +45,25 @@ object DownloadHelper {
downloadProgress.value = ProgressModel()
}
suspend fun downloadManager(context: Context) =
withContext(Dispatchers.IO) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
downloadProgress.value?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk")
.build()
.setOnProgressListener { progress ->
val mProgress = progress.currentBytes * 100 / progress.totalBytes
downloadProgress.value?.downloadProgress?.value = mProgress.toInt()
}
.setOnCancelListener {
downloadProgress.value?.downloadProgress?.value = 0
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
downloadProgress.value?.downloadProgress?.value = 0
val apk =
File("${context.getExternalFilesDir("manager")?.path}/manager.apk")
val uri =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
FileProvider.getUriForFile(
context,
"${context.packageName}.provider",
apk
)
else
Uri.fromFile(apk)
fun downloadManager(context: Context) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
fuelDownload(url, "manager", "manager.apk", context, onDownloadComplete = {
val apk = File("${context.getExternalFilesDir("manager")?.path}/manager.apk")
val uri =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
FileProvider.getUriForFile(context, "${context.packageName}.provider", apk)
else
Uri.fromFile(apk)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(uri, "application/vnd.android.package-archive")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.startActivity(intent)
sendCloseDialog(context)
}
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(uri, "application/vnd.android.package-archive")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.startActivity(intent)
sendCloseDialog(context)
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, "manager.apk"))
})
}
override fun onError(error: com.downloader.Error?) {
Toast.makeText(context, error.toString(), Toast.LENGTH_SHORT).show()
Log.e("VMUpgrade", error.toString())
}
})
}
}

View File

@ -1,17 +1,22 @@
package com.vanced.manager.utils
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.DialogInterface
import android.content.SharedPreferences
import android.widget.RadioGroup
import androidx.core.graphics.ColorUtils
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.R
import com.vanced.manager.utils.InternetTools.baseUrl
import com.vanced.manager.utils.InternetTools.loadJson
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
import java.util.*
object Extensions {
@ -20,34 +25,10 @@ object Extensions {
return findViewById<MaterialRadioButton>(checkedRadioButtonId)?.tag?.toString()
}
fun RadioGroup.getCheckedButtonText(): String {
return findViewById<MaterialRadioButton>(checkedRadioButtonId).text.toString()
}
fun DialogFragment.show(activity: FragmentActivity) {
show(activity.supportFragmentManager, "")
}
suspend fun Activity.fetchData() {
val refreshLayout = findViewById<SwipeRefreshLayout>(R.id.home_refresh)
setRefreshing(true, refreshLayout)
loadJson(this)
setRefreshing(false, refreshLayout)
}
fun Activity.setRefreshing(isRefreshing: Boolean) {
val refreshLayout = findViewById<SwipeRefreshLayout>(R.id.home_refresh)
if (refreshLayout != null) {
refreshLayout.isRefreshing = isRefreshing
}
}
fun Activity.setRefreshing(isRefreshing: Boolean, refreshLayout: SwipeRefreshLayout?) {
if (refreshLayout != null) {
refreshLayout.isRefreshing = isRefreshing
}
}
fun Context.getDefaultPrefs(): SharedPreferences = getDefaultSharedPreferences(this)
//Not sure how much this can affect performance
@ -71,4 +52,38 @@ object Extensions {
fun SharedPreferences.getInstallUrl() = getString("install_url", baseUrl)
fun Context.lifecycleOwner(): LifecycleOwner? {
var curContext = this
var maxDepth = 20
while (maxDepth-- > 0 && curContext !is LifecycleOwner) {
curContext = (curContext as ContextWrapper).baseContext
}
return if (curContext is LifecycleOwner) {
curContext
} else {
null
}
}
fun Int.toHex(): String = java.lang.String.format("#%06X", 0xFFFFFF and this)
//Material team decided to keep their LinearProgressIndicator final
//At least extension methods exist
fun LinearProgressIndicator.applyAccent() {
with(accentColor.value ?: context.getDefaultPrefs().getInt("manager_accent", defAccentColor)) {
setIndicatorColor(this)
trackColor = ColorUtils.setAlphaComponent(this, 70)
}
}
fun MaterialAlertDialogBuilder.applyAccent() {
with(accentColor.value ?: context.getDefaultPrefs().getInt("manager_accent", defAccentColor)) {
show().apply {
getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(this@with)
getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(this@with)
getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(this@with)
}
}
}
}

View File

@ -3,44 +3,44 @@ package com.vanced.manager.utils
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.databinding.ObservableField
import androidx.lifecycle.MutableLiveData
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject
import com.vanced.manager.BuildConfig
import com.vanced.manager.R
import com.vanced.manager.utils.AppUtils.generateChecksum
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
object InternetTools {
private const val TAG = "VMNetTools"
var vanced = ObservableField<JsonObject?>()
var music = ObservableField<JsonObject?>()
var microg = ObservableField<JsonObject?>()
var manager = ObservableField<JsonObject?>()
val vanced = MutableLiveData<JsonObject?>()
val music = MutableLiveData<JsonObject?>()
val microg = MutableLiveData<JsonObject?>()
val manager = MutableLiveData<JsonObject?>()
var vancedVersions = ObservableField<JsonArray<String>>()
var musicVersions = ObservableField<JsonArray<String>>()
val vancedVersions = MutableLiveData<JsonArray<String>>()
val musicVersions = MutableLiveData<JsonArray<String>>()
const val backupUrl = "https://mirror.codebucket.de/vanced/api/v1"
val isFetching = MutableLiveData<Boolean>()
//var braveTiers = ObservableField<JsonObject?>()
//var braveTiers = MutableLiveData<JsonObject?>()
fun openUrl(url: String, color: Int, context: Context) {
val customTabPrefs = getDefaultSharedPreferences(context).getBoolean("use_custom_tabs", true)
if (customTabPrefs) {
val builder = CustomTabsIntent.Builder()
builder.setToolbarColor(ContextCompat.getColor(context, color))
val params = CustomTabColorSchemeParams.Builder().setToolbarColor(ContextCompat.getColor(context, color))
builder.setDefaultColorSchemeParams(params.build())
val customTabsIntent = builder.build()
customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
customTabsIntent.launchUrl(context, url.toUri())
@ -51,36 +51,30 @@ object InternetTools {
fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/') + 1, url.length)
suspend fun loadJson(context: Context) = withContext(Dispatchers.IO) {
isFetching.postValue(true)
val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl)
val latest = JsonHelper.getJson("$installUrl/latest.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
val versions = JsonHelper.getJson("$installUrl/versions.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
val calendar = Calendar.getInstance()
val hour = calendar.get(Calendar.HOUR_OF_DAY)
val minute = calendar.get(Calendar.MINUTE)
val second = calendar.get(Calendar.SECOND)
val fetchTime = "fetchTime=$hour$minute$second"
val latest = JsonHelper.getJson("$installUrl/latest.json?$fetchTime")
val versions = JsonHelper.getJson("$installUrl/versions.json?$fetchTime")
// braveTiers.apply {
// set(getJson("$installUrl/sponsor.json"))
// notifyChange()
// }
vanced.apply {
set(latest?.obj("vanced"))
notifyChange()
}
vancedVersions.set(versions?.array("vanced"))
music.apply {
set(latest?.obj("music"))
notifyChange()
}
musicVersions.set(versions?.array("music"))
microg.apply {
set(latest?.obj("microg"))
notifyChange()
}
manager.apply {
set(latest?.obj("manager"))
notifyChange()
}
vanced.postValue(latest?.obj("vanced"))
vancedVersions.postValue(versions?.array("vanced") )
music.postValue(latest?.obj("music"))
musicVersions.postValue(versions?.array("music"))
microg.postValue(latest?.obj("microg"))
manager.postValue(latest?.obj("manager"))
isFetching.postValue(false)
}
suspend fun getJsonString(file: String, obj: String, context: Context): String {
private suspend fun getJsonString(file: String, obj: String, context: Context): String {
val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl)
return try {
JsonHelper.getJson("$installUrl/$file")?.string(obj) ?: context.getString(R.string.unavailable)
@ -90,12 +84,6 @@ object InternetTools {
}
}
fun isUpdateAvailable(): Boolean {
val result = manager.get()?.int("versionCode") ?: 0
return result > BuildConfig.VERSION_CODE
}
suspend fun getSha256(hashUrl: String, obj: String, context: Context): String {
return getJsonString(hashUrl, obj, context)
}
@ -106,7 +94,7 @@ object InternetTools {
// Generate the checksum
val sum = generateChecksum(dataBuffer)
sum.toLowerCase(Locale.ENGLISH) == sha256.toLowerCase(Locale.ENGLISH)
sum.equals(sha256, ignoreCase = true)
} catch (e: Exception) {
e.printStackTrace()
false

View File

@ -36,7 +36,7 @@ object LanguageHelper {
@Suppress("DEPRECATION")
fun getDefaultVancedLanguages(): String {
val serverLangs = vanced.get()?.array("langs") ?: mutableListOf("")
val serverLangs = vanced.value?.array("langs") ?: mutableListOf("")
val sysLocales = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) Resources.getSystem().configuration.locales.toLangTags() else arrayOf(Resources.getSystem().configuration.locale.language)
val finalLangs = mutableListOf<String>()
sysLocales.forEach { sysLocale ->

View File

@ -10,6 +10,7 @@ import android.os.Build
import android.util.Log
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.BuildConfig
import com.vanced.manager.core.installer.AppInstallerService
import com.vanced.manager.core.installer.AppUninstallerService
@ -35,6 +36,23 @@ object PackageHelper {
private const val apkInstallPath = "/data/adb"
private val vancedThemes = arrayOf("black", "dark", "pink", "blue")
init {
Shell.enableVerboseLogging = BuildConfig.DEBUG
Shell.setDefaultBuilder(
Shell.Builder.create()
.setFlags(Shell.FLAG_REDIRECT_STDERR)
.setTimeout(10)
)
}
private fun getAppName(pkg: String): String {
return when (pkg) {
vancedRootPkg -> "vanced"
musicRootPkg -> "music"
else -> ""
}
}
fun isPackageInstalled(packageName: String, packageManager: PackageManager): Boolean {
return try {
packageManager.getPackageInfo(packageName, 0)
@ -92,29 +110,27 @@ object PackageHelper {
val files = apksPath.listFiles()
if (files?.isNotEmpty() == true) {
for (file in files) {
when {
vancedThemes.any { file.name == "$it.apk" } && !splitFiles.contains("base") -> splitFiles.add("base")
file.name.matches(Regex("split_config\\.(..)\\.apk")) && !splitFiles.contains("lang") -> splitFiles.add("lang")
(file.name.startsWith("split_config.arm") || file.name.startsWith("split_config.x86")) && !splitFiles.contains("arch") -> splitFiles.add("arch")
}
Log.d("test", splitFiles.joinToString())
if (splitFiles.size == 3) {
return true
}
}
}
return false
}
return false
}
fun uninstallRootApk(pkg: String): Boolean {
val app = getAppName(pkg)
Shell.su("rm -rf $apkInstallPath/${app.capitalize(Locale.ROOT)}").exec()
Shell.su("rm $apkInstallPath/post-fs-data.d/$app.sh").exec()
Shell.su("rm $apkInstallPath/service.d/$app.sh").exec()
return Shell.su("pm uninstall $pkg").exec().isSuccess
}
@ -164,32 +180,22 @@ object PackageHelper {
return false
}
fun installMusicRoot(context: Context) = CoroutineScope(Dispatchers.IO).launch {
Shell.enableVerboseLogging = BuildConfig.DEBUG
Shell.setDefaultBuilder(
Shell.Builder.create()
.setFlags(Shell.FLAG_REDIRECT_STDERR)
.setTimeout(10)
)
private fun installRootApp(context: Context, app: String, appVerCode: Int, pkg: String, modApkBool: (fileName: String) -> Boolean) = CoroutineScope(Dispatchers.IO).launch {
Shell.getShell {
val musicVersionCode = music.get()?.int("versionCode")
val apkFilesPath = context.getExternalFilesDir("music/root")?.path
val apkFilesPath = context.getExternalFilesDir("$app/root")?.path
val fileInfoList = apkFilesPath?.let { it1 -> getFileInfoList(it1) }
if (fileInfoList != null) {
val modApk: FileInfo? = fileInfoList.lastOrNull { it.name == "root.apk" }
val modApk: FileInfo? = fileInfoList.lastOrNull { modApkBool(it.name) }
if (modApk != null) {
if (overwriteBase(modApk, fileInfoList, musicVersionCode!!, musicRootPkg, "music", context)) {
if (overwriteBase(modApk, fileInfoList, appVerCode, pkg, app, context)) {
sendRefresh(context)
sendCloseDialog(context)
}
}
else {
} else {
sendFailure(listOf("ModApk_Missing").toMutableList(), context)
sendCloseDialog(context)
}
}
else {
} else {
sendFailure(listOf("Files_Missing_VA").toMutableList(), context)
sendCloseDialog(context)
}
@ -198,6 +204,28 @@ object PackageHelper {
}
fun installMusicRoot(context: Context) {
installRootApp(
context,
"music",
music.value?.int("versionCode")!!,
musicRootPkg
) {
it == "root.apk"
}
}
fun installVancedRoot(context: Context) {
installRootApp(
context,
"vanced",
vanced.value?.int("versionCode")!!,
vancedRootPkg
) { fileName ->
vancedThemes.any { fileName == "$it.apk" }
}
}
fun installVanced(context: Context): Int {
val apkFolderPath = context.getExternalFilesDir("vanced/nonroot")?.path.toString() + "/"
val nameSizeMap = HashMap<String, Long>()
@ -300,43 +328,6 @@ object PackageHelper {
}
}
fun installVancedRoot(context: Context) = CoroutineScope(Dispatchers.IO).launch {
Shell.enableVerboseLogging = BuildConfig.DEBUG
Shell.setDefaultBuilder(
Shell.Builder.create()
.setFlags(Shell.FLAG_REDIRECT_STDERR)
.setTimeout(10)
)
Shell.getShell {
val vancedVersionCode = vanced.get()?.int("versionCode")
val apkFilesPath = context.getExternalFilesDir("vanced/root")?.path
val fileInfoList = apkFilesPath?.let { it1 -> getFileInfoList(it1) }
if (fileInfoList != null) {
val modApk: FileInfo? = fileInfoList.lastOrNull { file ->
vancedThemes.any { file.name == "$it.apk" }
}
if (modApk != null) {
if (overwriteBase(modApk, fileInfoList, vancedVersionCode!!, vancedRootPkg, "vanced", context)) {
sendRefresh(context)
sendCloseDialog(context)
}
}
else {
sendFailure(listOf("ModApk_Missing").toMutableList(), context)
sendCloseDialog(context)
}
}
else {
sendFailure(listOf("Files_Missing_VA").toMutableList(), context)
sendCloseDialog(context)
}
}
}
private fun installSplitApkFiles(apkFiles: ArrayList<FileInfo>, context: Context) : Boolean {
var sessionId: Int?
val filenames = arrayOf("black.apk", "dark.apk", "blue.apk", "pink.apk", "hash.json")
@ -441,25 +432,32 @@ object PackageHelper {
val apkFPath = "$apkInstallPath/${app.capitalize(Locale.ROOT)}/base.apk"
if (moveAPK(apath, apkFPath, pkg, context)) {
if (chConV(apkFPath, context)) {
if (setupScript(apkFPath, path, app)) {
if (setupScript(apkFPath, path, app, pkg)) {
return linkApp(apkFPath, pkg, path)
}
}
}
}
}
}
return false
}
private fun setupScript(apkFPath: String, path: String, app: String): Boolean
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String): Boolean
{
if(Shell.su("""echo "#!/system/bin/sh\nwhile [ "`getprop sys.boot_completed | tr -d '\r' `" != "1" ] ; do sleep 1; done\nmount -o bind $apkFPath $path" > /data/adb/service.d/$app.sh""").exec().isSuccess)
{
Shell.su("""echo "#!/system/bin/sh\nwhile read line; do echo \${"$"}{line} | grep youtube | awk '{print \${'$'}2}' | xargs umount -l; done< /proc/mounts" > /data/adb/post-fs-data.d/$app.sh""").exec()
return Shell.su("chmod 744 /data/adb/service.d/$app.sh").exec().isSuccess
val shellFileZ = SuFile.open("/data/adb/service.d/$app.sh")
shellFileZ.createNewFile()
val code = """#!/system/bin/sh${"\n"}while [ "`getprop sys.boot_completed | tr -d '\r' `" != "1" ]; do sleep 1; done${"\n"}mount -o bind $apkFPath $path"""
if (shellFileZ.exists()) {
try {
SuFileOutputStream(shellFileZ).use { out -> out.write(code.toByteArray())}
Shell.su("""echo "#!/system/bin/sh\nwhile read line; do echo \${"$"}{line} | grep $pkg | awk '{print \${'$'}2}' | xargs umount -l; done< /proc/mounts" > /data/adb/post-fs-data.d/$app.sh""").exec()
return Shell.su("chmod 744 /data/adb/service.d/$app.sh").exec().isSuccess
} catch (e: IOException) {
e.printStackTrace()
}
}
return false
}

View File

@ -2,46 +2,29 @@ package com.vanced.manager.utils
import android.app.Activity
import android.content.res.Configuration
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.getDefaultPrefs
object ThemeHelper {
const val defAccentColor: Int = -13732865
val mutableAccentColor = MutableLiveData<Int>()
val accentColor: LiveData<Int> = mutableAccentColor
fun Activity.setFinalTheme() {
val prefs = getDefaultPrefs()
val currentAccent = prefs.getString("manager_accent", "Blue")
when (prefs.getString("manager_theme", "System Default")) {
"Light" -> setTheme(getLightAccent(currentAccent))
"Dark" -> setTheme(getDarkAccent(currentAccent))
when (getDefaultPrefs().getString("manager_theme", "System Default")) {
"Light" -> setTheme(R.style.LightTheme)
"Dark" -> setTheme(R.style.DarkTheme)
"System Default" -> {
when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
Configuration.UI_MODE_NIGHT_YES -> setTheme(getDarkAccent(currentAccent))
Configuration.UI_MODE_NIGHT_NO -> setTheme(getLightAccent(currentAccent))
Configuration.UI_MODE_NIGHT_YES -> setTheme(R.style.DarkTheme)
Configuration.UI_MODE_NIGHT_NO -> setTheme(R.style.LightTheme)
}
}
else -> setTheme(getLightAccent("Blue"))
}
}
private fun getDarkAccent(accentColor: String?): Int {
return when (accentColor) {
"Blue" -> R.style.DarkTheme_Blue
"Red" -> R.style.DarkTheme_Red
"Green" -> R.style.DarkTheme_Green
"Yellow" -> R.style.DarkTheme_Yellow
"Purple" -> R.style.DarkTheme_Purple
else -> R.style.DarkTheme_Blue
}
}
private fun getLightAccent(accentColor: String?): Int {
return when (accentColor) {
"Blue" -> R.style.LightTheme_Blue
"Red" -> R.style.LightTheme_Red
"Green" -> R.style.LightTheme_Green
"Yellow" -> R.style.LightTheme_Yellow
"Purple" -> R.style.LightTheme_Purple
else -> R.style.LightTheme_Blue
else -> setTheme(R.style.LightTheme)
}
}

View File

@ -2,45 +2,177 @@
xmlns:aapt="http://schemas.android.com/aapt"
android:width="24dp"
android:height="24dp"
android:viewportWidth="2373.913"
android:viewportHeight="2373.913"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF">
<group android:translateX="186.95653"
android:translateY="186.95653">
<group android:scaleX="0.01215859"
android:scaleY="0.01215859"
android:translateX="-0.1585903"
android:translateY="-0.1585903">
<path
android:pathData="M1004.92,1881.1c-38.2,0.05 -76.47,-1.45 -114.57,0.42c-51.76,2.55 -81.84,-18.16 -90.74,-70.96c-7.49,-44.41 -13.2,-90.61 -30.51,-131.43c-15.34,-36.18 -40.29,-72.3 -70.22,-97.5c-83.85,-70.62 -178.04,-88.12 -279.91,-36c-16.76,8.57 -36.28,11.64 -54.35,17.76c-44.7,15.15 -76.87,1.99 -100.01,-39.68c-37.07,-66.74 -75.6,-132.69 -114.44,-198.43c-26.16,-44.27 -21.81,-81.72 19.36,-114.5c18.97,-15.11 34.6,-34.64 54.31,-48.55c72.54,-51.21 94,-120.05 91.6,-207.5c-2.02,-73.79 -23.93,-128.07 -79.03,-177.07c-131.04,-116.54 -130.5,-96.77 -38.4,-254.62c19.24,-32.97 38.08,-66.16 57.32,-99.13c41.41,-70.96 54.33,-75.72 134.39,-49.89c34.65,11.18 69.02,23.28 103.91,33.66c101.86,30.29 254.34,-57.92 278.42,-161.01c11.05,-47.28 20.7,-94.88 31.43,-142.24c8.42,-37.18 32.04,-56.47 70.31,-56.57c83.34,-0.23 166.68,0.02 250.01,-0.19c40.55,-0.11 65.26,19.16 73.99,58.78c10.44,47.42 14.73,97.39 33.08,141.51c15.63,37.56 42.09,74.68 73.09,100.99c82.04,69.63 174.55,87.18 274.79,35.85c18.26,-9.35 39.69,-12.3 59.29,-19.26c42.92,-15.23 73.52,-2.18 95.76,37.26c39.19,69.52 79.65,138.32 119.78,207.31c22.41,38.53 18.11,72.63 -15.69,102.47c-13.01,11.49 -24.36,25.49 -38.81,34.62c-105.9,66.87 -127.21,167.78 -109.49,281c5,31.96 22.73,65.36 43.68,90.58c29.68,35.74 67.12,65.23 102.43,96.04c33.98,29.66 40.49,63.13 18.36,101.95c-40.4,70.85 -81.55,141.28 -121.74,212.25c-21.43,37.85 -52.64,47.95 -92.63,35.44c-43.04,-13.47 -85.74,-28.06 -128.91,-41.12c-106.14,-32.11 -256.7,54.16 -281.98,161.54c-10.73,45.58 -20.37,91.42 -30.39,137.17c-8.68,39.59 -32.96,59.33 -73.71,59.05C1084.79,1880.83 1044.85,1881.04 1004.92,1881.1z"
android:strokeLineJoin="round"
android:strokeWidth="76"
android:fillColor="#00000000"
android:strokeLineCap="round">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1642.6245"
android:startX="322.9971"
android:endY="287.2871"
android:endX="1678.3345"
android:type="linear">
<item android:offset="1.065558E-7" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1270.42,895.24L886.12,647.3c-16.68,-9.72 -38.08,-4.08 -47.8,12.59l-0.75,1.28c-9.72,16.67 -4.09,38.07 12.59,47.79l367.49,221.11c23.91,14.39 23.77,49.1 -0.25,63.29l-369.18,218.11c-16.76,9.58 -22.58,30.93 -13,47.69l0.73,1.29c9.58,16.76 30.93,22.57 47.69,12.99l386.24,-244.83C1318.69,997.67 1318.97,926.57 1270.42,895.24z"
android:pathData="M719.6,939.4c-3.9,-5.5 -6.1,-12 -5.5,-18.8c1.3,-13.8 2.7,-27.6 4.6,-41.3c8,-58.7 16.3,-117.4 24.3,-176.2c4.1,-29.8 7.7,-59.7 11.7,-89.5c0.5,-3.6 -0.3,-5.9 -3.2,-8.2c-6.8,-5.4 -12.9,-11.3 -17.7,-18.6c-10.6,-16.4 -14.3,-34.2 -11.1,-53.4c2.6,-15.2 9.9,-28 20.7,-38.9c0.8,-0.9 1.7,-1.8 2.6,-2.5c1.4,-1.1 2.2,-0.8 2.3,1c0.1,1.9 0.1,3.8 -0.1,5.6c-1.2,12 -2.6,24 -3.8,35.9c-0.5,5.4 -0.7,10.9 -1,16.3c-0.1,1.9 0.6,3.5 2.2,4.7c13.8,9.9 27.5,19.7 41.2,29.6c1.4,1 2.8,1.1 4.3,0.4c15.6,-6.4 31.2,-12.8 46.8,-19.2c1.9,-0.8 3,-2.2 3.3,-4.2c1.2,-7.4 2.5,-14.8 3.5,-22.3c1.6,-12.2 3,-24.4 4.5,-36.7c0.1,-0.6 0.2,-1.3 0.4,-2.1c22.5,30.2 19.2,66 0.1,90.4c-7,8.9 -15.8,15.6 -26,20.6c-7.2,3.6 -7.3,3.6 -8.1,11.5c-4.4,44.4 -8.9,88.8 -13.2,133.2c-5,51 -9.8,102 -14.7,152.9c-0.5,5.4 -1.5,10.8 -2.1,16.2c-1.3,10.9 -7.3,18.5 -16.2,24.3c-7.4,4.8 -15.4,5.8 -23.9,4.9C734.2,954 725.9,948.3 719.6,939.4z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M1074.21,926.45L884.98,819.87c-24.49,-13.8 -54.77,3.9 -54.77,32v213.18c0,28.11 30.28,45.8 54.77,32l189.22,-106.59C1099.15,976.41 1099.15,940.5 1074.21,926.45z">
android:pathData="M747.3,491.3c0.6,0 0.9,0.6 1,1.7c0.1,1.9 0.1,3.8 -0.1,5.6c-1.2,12 -2.6,24 -3.8,35.9c-0.5,5.4 -0.7,10.9 -1,16.3c-0.1,1.9 0.6,3.5 2.2,4.7c13.8,9.9 27.5,19.7 41.2,29.6c0.8,0.6 1.6,0.8 2.4,0.8c0.6,0 1.3,-0.2 1.9,-0.4c15.6,-6.4 31.2,-12.8 46.8,-19.2c1.9,-0.8 3,-2.2 3.3,-4.2c1.2,-7.4 2.5,-14.8 3.5,-22.3c1.6,-12.2 3,-24.4 4.5,-36.7c0.1,-0.6 0.2,-1.3 0.4,-2.1c22.5,30.2 19.2,66 0.1,90.4c-7,8.9 -15.8,15.6 -26,20.6c-7.2,3.6 -7.3,3.6 -8.1,11.5c-4.4,44.4 -8.9,88.8 -13.2,133.2c-5,51 -9.8,102 -14.7,152.9c-0.5,5.4 -1.5,10.8 -2.1,16.2c-1.3,10.9 -7.3,18.5 -16.2,24.3c-5.8,3.8 -12,5.2 -18.6,5.2c-1.8,0 -3.6,-0.1 -5.4,-0.3c-11.2,-1.1 -19.5,-6.9 -25.8,-15.7c-3.9,-5.5 -6.1,-12 -5.5,-18.8c1.3,-13.8 2.7,-27.6 4.6,-41.3c8,-58.7 16.3,-117.4 24.3,-176.2c4.1,-29.8 7.7,-59.7 11.7,-89.5c0.5,-3.6 -0.3,-5.9 -3.2,-8.2c-6.8,-5.4 -12.9,-11.3 -17.7,-18.6c-10.6,-16.4 -14.3,-34.2 -11.1,-53.4c2.6,-15.2 9.9,-28 20.7,-38.9c0.8,-0.9 1.7,-1.8 2.6,-2.5C746.5,491.5 747,491.3 747.3,491.3M747.3,478.3c-2.3,0 -5.9,0.6 -9.5,3.5c-1.4,1.1 -2.5,2.2 -3.3,3.1c-0.2,0.2 -0.3,0.3 -0.5,0.5c-13.2,13.5 -21.4,28.9 -24.2,45.9c-3.8,22.4 0.6,43.5 13,62.6c4.6,7.1 10.6,13.6 18.7,20.3c-1.8,13.2 -3.5,26.5 -5.1,39.4c-2,15.7 -4.1,31.9 -6.3,47.9c-4,29.3 -8.2,59.2 -12.2,88c-4,28.9 -8.2,58.7 -12.2,88.1c-2,14.6 -3.5,29.4 -4.6,41.9c-0.9,9.6 1.8,19.1 7.8,27.6c9,12.6 20.8,19.7 35.1,21.1c2.4,0.2 4.5,0.3 6.7,0.3c9.7,0 18.1,-2.4 25.7,-7.3c13,-8.5 20.4,-19.8 22,-33.7c0.3,-2.2 0.6,-4.3 0.9,-6.6c0.4,-3.2 0.9,-6.5 1.2,-9.9c2.2,-23 4.5,-46.3 6.6,-68.9c2.6,-27.6 5.4,-56 8.1,-84.1c4.4,-45.2 8.9,-90.5 13.2,-133.2c0,-0.2 0,-0.5 0.1,-0.7c0.3,-0.1 0.5,-0.3 0.8,-0.4l0.1,0c12.4,-6.1 22.6,-14.2 30.5,-24.3c11.4,-14.5 17.9,-32.5 18.4,-50.7c0.5,-19.6 -5.8,-38.8 -18.2,-55.5c-2.5,-3.3 -6.4,-5.2 -10.4,-5.2c-1,0 -2,0.1 -3,0.3c-5,1.2 -8.9,5.3 -9.8,10.4c0,0.2 -0.1,0.4 -0.1,0.6c-0.1,0.6 -0.3,1.4 -0.4,2.3c-0.5,3.9 -0.9,7.7 -1.4,11.6c-1,8.2 -2,16.6 -3.1,24.9c-0.7,5.3 -1.6,10.5 -2.5,16.1c-0.1,0.6 -0.2,1.2 -0.3,1.7c-14.1,5.8 -26.8,11 -38.6,15.9c-12.9,-9.3 -23.9,-17.2 -33.9,-24.4c0,-0.2 0,-0.3 0,-0.5c0.2,-3.9 0.4,-7.5 0.7,-11.1c0.7,-6.9 1.4,-13.9 2.2,-20.7c0.5,-5 1.1,-10.1 1.6,-15.2c0.3,-2.6 0.3,-5.2 0.1,-7.8C760.7,483.1 753.8,478.3 747.3,478.3L747.3,478.3z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="1058.4124"
android:startX="808.329"
android:endY="858.5059"
android:endX="1008.2355"
android:startY="859.293"
android:startX="620.1221"
android:endY="556.2224"
android:endX="923.1927"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M299.9,1252.2c1.7,7.9 19.5,10.3 34.3,11c21.7,0.9 48.3,-1.6 74.9,-7.2s52,-13.9 71.5,-23.5c13.2,-6.5 28.6,-15.9 27,-23.8c-0.1,-0.5 -3.9,-18.8 -3.9,-18.8c-1.4,-6.5 -7.7,-10.6 -14.2,-9.3c0,0 -7.8,1.6 -10.4,2.2c-3.9,0.8 -6.5,-2 -6.5,-2L430,1132c-2.4,-2.8 -5.2,-8.4 -6,-12l-6.3,-30c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.9,3.5 -7.8,10 -6.8,15c0.6,2.8 0.1,8.4 -1,11.9l-19.5,62.5c0,0 -1,2.8 -3.8,3.4c-2.9,0.6 -11.5,2.4 -11.5,2.4c-6.5,1.4 -10.6,7.7 -9.3,14.2C295.9,1233.5 299.8,1251.8 299.9,1252.2z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1292.4099"
android:startX="354.8105"
android:endY="1106.054"
android:endX="462.39334"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M320.2,998.2c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.8,-3.5 7.7,-10.7 6.5,-16.5l-3.1,-14.9c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.8,3.5 -7.7,10.7 -6.5,16.5l3.1,14.9C310.9,996.1 315.3,999.3 320.2,998.2z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1005.80145"
android:startX="318.80777"
android:endY="910.2987"
android:endX="373.94147"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M331.7,1053.1c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.8,-3.5 7.7,-10.7 6.5,-16.5l-3.1,-14.9c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.8,3.5 -7.7,10.7 -6.5,16.5l3.1,14.9C322.4,1051 326.8,1054.1 331.7,1053.1z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1060.6891"
android:startX="330.33954"
android:endY="965.1862"
android:endX="385.4732"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M308.6,943.3c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.3,-3.1 8.2,-8.1 7.3,-12.4c-0.8,-3.6 -5.3,-8 -9.1,-10.6l-32.6,-21.7c-2.7,-1.8 -5.9,-2.4 -9,-1.7c-3.1,0.7 -5.8,2.5 -7.5,5.2l-21.1,32.9c-3,4.6 -4.3,12.2 -3.2,17.5l5.2,24.7C299.4,941.2 303.7,944.4 308.6,943.3z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="948.92065"
android:startX="303.82504"
android:endY="862.8324"
android:endX="353.52368"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M343.2,1108c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.8,-3.5 7.7,-10.7 6.5,-16.5l-3.1,-14.9c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.8,3.5 -7.7,10.7 -6.5,16.5l3.1,14.9C334,1105.9 338.3,1109 343.2,1108z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1115.5784"
android:startX="341.87146"
android:endY="1020.0755"
android:endX="397.00513"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1616.8,1020.7c-0.9,-33.7 -2.6,-78.5 -6,-123.1c-3.8,-49.3 -9.6,-98.4 -18.7,-132.5c-14.1,-53 -55.5,-94.7 -108.1,-108.8c-5,-1.3 -10.8,-2.6 -17.2,-3.8c-5.5,-1 -11.5,-2 -17.9,-2.9c-1.5,-0.2 -3,-0.4 -4.5,-0.6c-0.6,-0.1 -1.3,-0.2 -1.9,-0.3c-6.2,-0.8 -12.8,-1.6 -19.7,-2.4v-90c0,-58.4 -22.7,-113.3 -64,-154.6c-41.3,-41.3 -96.2,-64 -154.6,-64H795.8c-58.4,0 -113.3,22.7 -154.6,64c-41.3,41.3 -64,96.2 -64,154.6v91.4c-20.1,2.5 -36.9,5.3 -49,8.6c-52.6,14.2 -94.1,55.9 -108.1,108.8c-25.6,96 -25.6,312.3 -25.6,312.3s0,217.9 25.6,313.9c14.1,53 55.5,94.7 108.1,108.8c77.9,21 347.1,24.9 443.4,25.6h0c21.6,0.2 34.5,0.2 34.5,0.2s90.4,0 194.3,-3c109.8,-3.1 234.6,-9.5 283.6,-22.8c52.6,-14.2 94.1,-55.9 108.1,-108.8c8.8,-33 14.6,-80.4 18.3,-128.4c3.5,-43.8 5.3,-88.2 6.2,-122.6c1,-37.4 1,-63 1,-63S1617.7,1054.7 1616.8,1020.7zM677.2,556.3c0,-65.4 53.2,-118.6 118.6,-118.6h408.3c65.4,0 118.6,53.2 118.6,118.6v82.2c-3.1,-0.2 -6.3,-0.3 -9.5,-0.5c-19,-1 -38.5,-1.9 -58,-2.6c-9.3,-0.4 -18.6,-0.7 -27.9,-1c-1.4,0 -2.8,-0.1 -4.3,-0.1c-7.2,-0.2 -14.4,-0.5 -21.5,-0.7c-104.4,-3 -195.5,-3 -195.5,-3s-11.4,0 -30.7,0.1c-34.7,0.2 -94.9,0.9 -160.8,2.7c-45.2,1.3 -93.1,3.1 -137.3,5.7V556.3z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M1149.9,1045.3L955.2,932.9c-25.3,-14.6 -57,3.7 -57,32.9v224.8c0,29.3 31.7,47.5 57,32.9l194.7,-112.4C1175.3,1096.5 1175.3,1059.9 1149.9,1045.3z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="1181.9095"
android:startX="873.7143"
android:endY="974.5546"
android:endX="1081.0692"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M975.4,630.7c-15.6,-18.9 -18.6,-46.3 -5.5,-68.7l1.3,-2.2c16.8,-28.8 53.7,-38.5 82.5,-21.7l148,95.5c-104.4,-3 -195.5,-3 -195.5,-3S994.7,630.6 975.4,630.7z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="668.5132"
android:startX="1013.1392"
android:endY="556.8019"
android:endX="1124.8505"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1715.9,1196.1l-105.4,66.8l-410.1,260l-151,95.7c-28.9,16.5 -65.8,6.5 -82.3,-22.4l-1.3,-2.2c-12.8,-22.4 -9.7,-49.5 5.8,-68.3h0c4.5,-5.5 10.1,-10.3 16.6,-14l628.5,-371.3l8.6,-5.1c41.5,-24.5 41.7,-84.4 0.4,-109.2l-8.9,-5.4c-0.9,-33.7 -2.6,-78.4 -6,-123.1l106,68.4C1800.6,1020 1800.1,1142.7 1715.9,1196.1z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="1669.5327"
android:startX="1037.3125"
android:endY="975.7731"
android:endX="1731.0721"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1116.8,1061.1c-0.9,0 -1.9,-0.2 -2.8,-0.7l-43.4,-25.1c-2.7,-1.5 -3.6,-5 -2,-7.6c1.5,-2.7 5,-3.6 7.6,-2l43.4,25.1c2.7,1.5 3.6,5 2,7.6C1120.6,1060.1 1118.7,1061.1 1116.8,1061.1z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M1133.5,1063.9m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M1547.9,840.1c-5.5,0 -10.5,-3.8 -11.8,-9.4c-0.9,-3.8 -1.8,-7.4 -2.7,-10.8c-10,-37.5 -35.3,-69.7 -69.4,-88.2c-9.5,-5.2 -19.7,-9.2 -30.1,-12.1c-5.5,-1.3 -11.3,-2.6 -16.5,-3.7c-4.5,-0.8 -14.8,-2.6 -25.5,-4.1c-6.6,-0.9 -11.2,-7 -10.3,-13.6c0.9,-6.6 7,-11.2 13.6,-10.3c13.7,1.9 25.3,4.1 26.6,4.3c0,0 0.1,0 0.1,0c5.6,1.1 11.9,2.5 17.8,4c0.1,0 0.2,0 0.2,0.1c12.3,3.3 24.3,8.1 35.5,14.2c39.9,21.7 69.5,59.3 81.2,103.2c1,3.7 1.9,7.6 2.9,11.7c1.5,6.5 -2.6,13 -9.1,14.5C1549.7,840 1548.8,840.1 1547.9,840.1z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="853.7486"
android:startX="1527.6058"
android:endY="669.9293"
android:endX="1421.4778"
android:type="linear">
<item android:offset="4.04912E-7" android:color="#FF953A9A"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1556.3,867.6m-12.6,0a12.6,12.6 0,1 1,25.2 0a12.6,12.6 0,1 1,-25.2 0"
android:fillColor="#953A9A"/>
</group>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@ -4,65 +4,174 @@
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.034267887"
android:scaleY="0.034267887"
android:translateX="21.822453"
android:translateY="21">
<group
android:translateX="-61"
android:translateY="-44.97">
<path
android:pathData="M1004.71 1916.4c-38.2 0 -76.47 -1.46 -114.57 0.42 -51.76 2.55 -81.85 -18.16 -90.74 -71 -7.49 -44.41 -13.2 -90.61 -30.51 -131.44 -15.34 -36.17 -40.29 -72.29 -70.22 -97.5 -83.85 -70.61 -178 -88.12 -279.91 -36 -16.75 8.57 -36.27 11.63 -54.34 17.76 -44.7 15.14 -76.87 2 -100 -39.69 -37.07 -66.74 -75.59 -132.69 -114.44 -198.43 -26.16 -44.26 -21.81 -81.71 19.36 -114.5 19 -15.1 34.6 -34.64 54.31 -48.55 72.54 -51.2 94 -120 91.6 -207.49 -2 -73.79 -23.93 -128.07 -79 -177.07 -131 -116.54 -130.49 -96.77 -38.39 -254.62 19.23 -33 38.07 -66.16 57.31 -99.12 41.42 -71 54.34 -75.73 134.4 -49.89 34.65 11.18 69 23.29 103.91 33.66 101.86 30.29 254.34 -57.92 278.42 -161 11 -47.28 20.71 -94.88 31.43 -142.24 8.43 -37.18 32.05 -56.46 70.31 -56.56 83.34 -0.23 166.68 0 250 -0.2 40.55 -0.1 65.27 19.16 74 58.78 10.44 47.42 14.73 97.39 33.08 141.51 15.63 37.56 42.09 74.68 73.1 101 82 69.63 174.55 87.18 274.79 35.85 18.26 -9.35 39.69 -12.3 59.29 -19.26 42.91 -15.23 73.51 -2.18 95.75 37.27 39.2 69.51 79.66 138.32 119.78 207.3C1875.8 684 1871.49 718 1837.7 747.88c-13 11.49 -24.36 25.5 -38.82 34.63 -105.89 66.87 -127.2 167.78 -109.49 281 5 32 22.74 65.36 43.69 90.58 29.68 35.74 67.12 65.23 102.42 96.05 34 29.65 40.5 63.13 18.36 101.94 -40.4 70.85 -81.55 141.28 -121.73 212.25 -21.43 37.85 -52.64 48 -92.63 35.44 -43 -13.47 -85.75 -28.06 -128.91 -41.12 -106.14 -32.11 -256.7 54.16 -282 161.54 -10.73 45.58 -20.36 91.42 -30.39 137.16 -8.68 39.6 -33 59.33 -73.71 59.05C1084.58 1916.13 1044.64 1916.34 1004.71 1916.4Z"
android:strokeWidth="76"
android:strokeLineCap="round"
android:strokeLineJoin="round">
<aapt:attr
name="android:strokeColor">
<gradient
android:startX="322.79"
android:startY="1677.92"
android:endX="1678.13"
android:endY="322.59"
android:tileMode="clamp">
<item
android:color="#2E73FF"
android:offset="0" />
<item
android:color="#FF0032"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
</group>
<group
android:translateX="-61"
android:translateY="-44.97">
<path
android:pathData="M1270.21 935L885.92 687a35 35 0 0 0 -47.81 12.59l-0.74 1.28A34.94 34.94 0 0 0 850 748.67l367.49 221.11c23.91 14.38 23.77 49.09 -0.26 63.29L848 1251.18a34.94 34.94 0 0 0 -13 47.68l0.74 1.29a35 35 0 0 0 47.69 13l386.24 -244.82C1318.48 1037.38 1318.76 966.28 1270.21 935Z"
android:fillColor="#FFFFFF" />
</group>
<group
android:translateX="-61"
android:translateY="-44.97">
<path
android:pathData="M1074 968L884.77 861.41c-24.49 -13.8 -54.77 3.89 -54.77 32v213.18c0 28.11 30.28 45.8 54.77 32L1074 1032C1098.94 1018 1098.94 982 1074 968Z">
<aapt:attr
name="android:fillColor">
<gradient
android:startX="808.12"
android:startY="1099.95"
android:endX="1008.03"
android:endY="900.05"
android:tileMode="clamp">
<item
android:color="#2E73FF"
android:offset="0" />
<item
android:color="#FF0032"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
</group>
<group android:scaleX="0.0405"
android:scaleY="0.0405"
android:translateX="13.5"
android:translateY="13.5">
<path
android:pathData="M719.6,939.4c-3.9,-5.5 -6.1,-12 -5.5,-18.8c1.3,-13.8 2.7,-27.6 4.6,-41.3c8,-58.7 16.3,-117.4 24.3,-176.2c4.1,-29.8 7.7,-59.7 11.7,-89.5c0.5,-3.6 -0.3,-5.9 -3.2,-8.2c-6.8,-5.4 -12.9,-11.3 -17.7,-18.6c-10.6,-16.4 -14.3,-34.2 -11.1,-53.4c2.6,-15.2 9.9,-28 20.7,-38.9c0.8,-0.9 1.7,-1.8 2.6,-2.5c1.4,-1.1 2.2,-0.8 2.3,1c0.1,1.9 0.1,3.8 -0.1,5.6c-1.2,12 -2.6,24 -3.8,35.9c-0.5,5.4 -0.7,10.9 -1,16.3c-0.1,1.9 0.6,3.5 2.2,4.7c13.8,9.9 27.5,19.7 41.2,29.6c1.4,1 2.8,1.1 4.3,0.4c15.6,-6.4 31.2,-12.8 46.8,-19.2c1.9,-0.8 3,-2.2 3.3,-4.2c1.2,-7.4 2.5,-14.8 3.5,-22.3c1.6,-12.2 3,-24.4 4.5,-36.7c0.1,-0.6 0.2,-1.3 0.4,-2.1c22.5,30.2 19.2,66 0.1,90.4c-7,8.9 -15.8,15.6 -26,20.6c-7.2,3.6 -7.3,3.6 -8.1,11.5c-4.4,44.4 -8.9,88.8 -13.2,133.2c-5,51 -9.8,102 -14.7,152.9c-0.5,5.4 -1.5,10.8 -2.1,16.2c-1.3,10.9 -7.3,18.5 -16.2,24.3c-7.4,4.8 -15.4,5.8 -23.9,4.9C734.2,954 725.9,948.3 719.6,939.4z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M747.3,491.3c0.6,0 0.9,0.6 1,1.7c0.1,1.9 0.1,3.8 -0.1,5.6c-1.2,12 -2.6,24 -3.8,35.9c-0.5,5.4 -0.7,10.9 -1,16.3c-0.1,1.9 0.6,3.5 2.2,4.7c13.8,9.9 27.5,19.7 41.2,29.6c0.8,0.6 1.6,0.8 2.4,0.8c0.6,0 1.3,-0.2 1.9,-0.4c15.6,-6.4 31.2,-12.8 46.8,-19.2c1.9,-0.8 3,-2.2 3.3,-4.2c1.2,-7.4 2.5,-14.8 3.5,-22.3c1.6,-12.2 3,-24.4 4.5,-36.7c0.1,-0.6 0.2,-1.3 0.4,-2.1c22.5,30.2 19.2,66 0.1,90.4c-7,8.9 -15.8,15.6 -26,20.6c-7.2,3.6 -7.3,3.6 -8.1,11.5c-4.4,44.4 -8.9,88.8 -13.2,133.2c-5,51 -9.8,102 -14.7,152.9c-0.5,5.4 -1.5,10.8 -2.1,16.2c-1.3,10.9 -7.3,18.5 -16.2,24.3c-5.8,3.8 -12,5.2 -18.6,5.2c-1.8,0 -3.6,-0.1 -5.4,-0.3c-11.2,-1.1 -19.5,-6.9 -25.8,-15.7c-3.9,-5.5 -6.1,-12 -5.5,-18.8c1.3,-13.8 2.7,-27.6 4.6,-41.3c8,-58.7 16.3,-117.4 24.3,-176.2c4.1,-29.8 7.7,-59.7 11.7,-89.5c0.5,-3.6 -0.3,-5.9 -3.2,-8.2c-6.8,-5.4 -12.9,-11.3 -17.7,-18.6c-10.6,-16.4 -14.3,-34.2 -11.1,-53.4c2.6,-15.2 9.9,-28 20.7,-38.9c0.8,-0.9 1.7,-1.8 2.6,-2.5C746.5,491.5 747,491.3 747.3,491.3M747.3,478.3c-2.3,0 -5.9,0.6 -9.5,3.5c-1.4,1.1 -2.5,2.2 -3.3,3.1c-0.2,0.2 -0.3,0.3 -0.5,0.5c-13.2,13.5 -21.4,28.9 -24.2,45.9c-3.8,22.4 0.6,43.5 13,62.6c4.6,7.1 10.6,13.6 18.7,20.3c-1.8,13.2 -3.5,26.5 -5.1,39.4c-2,15.7 -4.1,31.9 -6.3,47.9c-4,29.3 -8.2,59.2 -12.2,88c-4,28.9 -8.2,58.7 -12.2,88.1c-2,14.6 -3.5,29.4 -4.6,41.9c-0.9,9.6 1.8,19.1 7.8,27.6c9,12.6 20.8,19.7 35.1,21.1c2.4,0.2 4.5,0.3 6.7,0.3c9.7,0 18.1,-2.4 25.7,-7.3c13,-8.5 20.4,-19.8 22,-33.7c0.3,-2.2 0.6,-4.3 0.9,-6.6c0.4,-3.2 0.9,-6.5 1.2,-9.9c2.2,-23 4.5,-46.3 6.6,-68.9c2.6,-27.6 5.4,-56 8.1,-84.1c4.4,-45.2 8.9,-90.5 13.2,-133.2c0,-0.2 0,-0.5 0.1,-0.7c0.3,-0.1 0.5,-0.3 0.8,-0.4l0.1,0c12.4,-6.1 22.6,-14.2 30.5,-24.3c11.4,-14.5 17.9,-32.5 18.4,-50.7c0.5,-19.6 -5.8,-38.8 -18.2,-55.5c-2.5,-3.3 -6.4,-5.2 -10.4,-5.2c-1,0 -2,0.1 -3,0.3c-5,1.2 -8.9,5.3 -9.8,10.4c0,0.2 -0.1,0.4 -0.1,0.6c-0.1,0.6 -0.3,1.4 -0.4,2.3c-0.5,3.9 -0.9,7.7 -1.4,11.6c-1,8.2 -2,16.6 -3.1,24.9c-0.7,5.3 -1.6,10.5 -2.5,16.1c-0.1,0.6 -0.2,1.2 -0.3,1.7c-14.1,5.8 -26.8,11 -38.6,15.9c-12.9,-9.3 -23.9,-17.2 -33.9,-24.4c0,-0.2 0,-0.3 0,-0.5c0.2,-3.9 0.4,-7.5 0.7,-11.1c0.7,-6.9 1.4,-13.9 2.2,-20.7c0.5,-5 1.1,-10.1 1.6,-15.2c0.3,-2.6 0.3,-5.2 0.1,-7.8C760.7,483.1 753.8,478.3 747.3,478.3L747.3,478.3z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="859.293"
android:startX="620.1221"
android:endY="556.2224"
android:endX="923.1927"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M299.9,1252.2c1.7,7.9 19.5,10.3 34.3,11c21.7,0.9 48.3,-1.6 74.9,-7.2s52,-13.9 71.5,-23.5c13.2,-6.5 28.6,-15.9 27,-23.8c-0.1,-0.5 -3.9,-18.8 -3.9,-18.8c-1.4,-6.5 -7.7,-10.6 -14.2,-9.3c0,0 -7.8,1.6 -10.4,2.2c-3.9,0.8 -6.5,-2 -6.5,-2L430,1132c-2.4,-2.8 -5.2,-8.4 -6,-12l-6.3,-30c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.9,3.5 -7.8,10 -6.8,15c0.6,2.8 0.1,8.4 -1,11.9l-19.5,62.5c0,0 -1,2.8 -3.8,3.4c-2.9,0.6 -11.5,2.4 -11.5,2.4c-6.5,1.4 -10.6,7.7 -9.3,14.2C295.9,1233.5 299.8,1251.8 299.9,1252.2z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1292.4099"
android:startX="354.8105"
android:endY="1106.054"
android:endX="462.39334"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M320.2,998.2c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.8,-3.5 7.7,-10.7 6.5,-16.5l-3.1,-14.9c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.8,3.5 -7.7,10.7 -6.5,16.5l3.1,14.9C310.9,996.1 315.3,999.3 320.2,998.2z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1005.80145"
android:startX="318.80777"
android:endY="910.2987"
android:endX="373.94147"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M331.7,1053.1c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.8,-3.5 7.7,-10.7 6.5,-16.5l-3.1,-14.9c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.8,3.5 -7.7,10.7 -6.5,16.5l3.1,14.9C322.4,1051 326.8,1054.1 331.7,1053.1z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1060.6891"
android:startX="330.33954"
android:endY="965.1862"
android:endX="385.4732"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M308.6,943.3c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.3,-3.1 8.2,-8.1 7.3,-12.4c-0.8,-3.6 -5.3,-8 -9.1,-10.6l-32.6,-21.7c-2.7,-1.8 -5.9,-2.4 -9,-1.7c-3.1,0.7 -5.8,2.5 -7.5,5.2l-21.1,32.9c-3,4.6 -4.3,12.2 -3.2,17.5l5.2,24.7C299.4,941.2 303.7,944.4 308.6,943.3z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="948.92065"
android:startX="303.82504"
android:endY="862.8324"
android:endX="353.52368"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M343.2,1108c1.4,-0.3 2.7,-0.9 4,-1.8l55.6,-39.7c4.8,-3.5 7.7,-10.7 6.5,-16.5l-3.1,-14.9c-1.1,-5.3 -5.5,-8.5 -10.4,-7.4l0,0c-1.4,0.3 -2.7,0.9 -4,1.8l-55.6,39.7c-4.8,3.5 -7.7,10.7 -6.5,16.5l3.1,14.9C334,1105.9 338.3,1109 343.2,1108z"
android:strokeWidth="10"
android:fillColor="#FFFFFF">
<aapt:attr name="android:strokeColor">
<gradient
android:startY="1115.5784"
android:startX="341.87146"
android:endY="1020.0755"
android:endX="397.00513"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1616.8,1020.7c-0.9,-33.7 -2.6,-78.5 -6,-123.1c-3.8,-49.3 -9.6,-98.4 -18.7,-132.5c-14.1,-53 -55.5,-94.7 -108.1,-108.8c-5,-1.3 -10.8,-2.6 -17.2,-3.8c-5.5,-1 -11.5,-2 -17.9,-2.9c-1.5,-0.2 -3,-0.4 -4.5,-0.6c-0.6,-0.1 -1.3,-0.2 -1.9,-0.3c-6.2,-0.8 -12.8,-1.6 -19.7,-2.4v-90c0,-58.4 -22.7,-113.3 -64,-154.6c-41.3,-41.3 -96.2,-64 -154.6,-64H795.8c-58.4,0 -113.3,22.7 -154.6,64c-41.3,41.3 -64,96.2 -64,154.6v91.4c-20.1,2.5 -36.9,5.3 -49,8.6c-52.6,14.2 -94.1,55.9 -108.1,108.8c-25.6,96 -25.6,312.3 -25.6,312.3s0,217.9 25.6,313.9c14.1,53 55.5,94.7 108.1,108.8c77.9,21 347.1,24.9 443.4,25.6h0c21.6,0.2 34.5,0.2 34.5,0.2s90.4,0 194.3,-3c109.8,-3.1 234.6,-9.5 283.6,-22.8c52.6,-14.2 94.1,-55.9 108.1,-108.8c8.8,-33 14.6,-80.4 18.3,-128.4c3.5,-43.8 5.3,-88.2 6.2,-122.6c1,-37.4 1,-63 1,-63S1617.7,1054.7 1616.8,1020.7zM677.2,556.3c0,-65.4 53.2,-118.6 118.6,-118.6h408.3c65.4,0 118.6,53.2 118.6,118.6v82.2c-3.1,-0.2 -6.3,-0.3 -9.5,-0.5c-19,-1 -38.5,-1.9 -58,-2.6c-9.3,-0.4 -18.6,-0.7 -27.9,-1c-1.4,0 -2.8,-0.1 -4.3,-0.1c-7.2,-0.2 -14.4,-0.5 -21.5,-0.7c-104.4,-3 -195.5,-3 -195.5,-3s-11.4,0 -30.7,0.1c-34.7,0.2 -94.9,0.9 -160.8,2.7c-45.2,1.3 -93.1,3.1 -137.3,5.7V556.3z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M1149.9,1045.3L955.2,932.9c-25.3,-14.6 -57,3.7 -57,32.9v224.8c0,29.3 31.7,47.5 57,32.9l194.7,-112.4C1175.3,1096.5 1175.3,1059.9 1149.9,1045.3z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="1181.9095"
android:startX="873.7143"
android:endY="974.5546"
android:endX="1081.0692"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M975.4,630.7c-15.6,-18.9 -18.6,-46.3 -5.5,-68.7l1.3,-2.2c16.8,-28.8 53.7,-38.5 82.5,-21.7l148,95.5c-104.4,-3 -195.5,-3 -195.5,-3S994.7,630.6 975.4,630.7z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="668.5132"
android:startX="1013.1392"
android:endY="556.8019"
android:endX="1124.8505"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1715.9,1196.1l-105.4,66.8l-410.1,260l-151,95.7c-28.9,16.5 -65.8,6.5 -82.3,-22.4l-1.3,-2.2c-12.8,-22.4 -9.7,-49.5 5.8,-68.3h0c4.5,-5.5 10.1,-10.3 16.6,-14l628.5,-371.3l8.6,-5.1c41.5,-24.5 41.7,-84.4 0.4,-109.2l-8.9,-5.4c-0.9,-33.7 -2.6,-78.4 -6,-123.1l106,68.4C1800.6,1020 1800.1,1142.7 1715.9,1196.1z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="1669.5327"
android:startX="1037.3125"
android:endY="975.7731"
android:endX="1731.0721"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1116.8,1061.1c-0.9,0 -1.9,-0.2 -2.8,-0.7l-43.4,-25.1c-2.7,-1.5 -3.6,-5 -2,-7.6c1.5,-2.7 5,-3.6 7.6,-2l43.4,25.1c2.7,1.5 3.6,5 2,7.6C1120.6,1060.1 1118.7,1061.1 1116.8,1061.1z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M1133.5,1063.9m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M1547.9,840.1c-5.5,0 -10.5,-3.8 -11.8,-9.4c-0.9,-3.8 -1.8,-7.4 -2.7,-10.8c-10,-37.5 -35.3,-69.7 -69.4,-88.2c-9.5,-5.2 -19.7,-9.2 -30.1,-12.1c-5.5,-1.3 -11.3,-2.6 -16.5,-3.7c-4.5,-0.8 -14.8,-2.6 -25.5,-4.1c-6.6,-0.9 -11.2,-7 -10.3,-13.6c0.9,-6.6 7,-11.2 13.6,-10.3c13.7,1.9 25.3,4.1 26.6,4.3c0,0 0.1,0 0.1,0c5.6,1.1 11.9,2.5 17.8,4c0.1,0 0.2,0 0.2,0.1c12.3,3.3 24.3,8.1 35.5,14.2c39.9,21.7 69.5,59.3 81.2,103.2c1,3.7 1.9,7.6 2.9,11.7c1.5,6.5 -2.6,13 -9.1,14.5C1549.7,840 1548.8,840.1 1547.9,840.1z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="853.7486"
android:startX="1527.6058"
android:endY="669.9293"
android:endX="1421.4778"
android:type="linear">
<item android:offset="4.04912E-7" android:color="#FF953A9A"/>
<item android:offset="1" android:color="#FFFF0032"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M1556.3,867.6m-12.6,0a12.6,12.6 0,1 1,25.2 0a12.6,12.6 0,1 1,-25.2 0"
android:fillColor="#953A9A"/>
</group>
</vector>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 848 B

View File

@ -1,10 +0,0 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="25dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@ -2,11 +2,11 @@
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?colorSurface" />
<item android:drawable="@color/splash" />
<item>
<bitmap
android:src="@drawable/splash192"
android:src="@drawable/ic_splash"
android:gravity="center" />
</item>

View File

@ -1,40 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface"
tools:context=".ui.MainActivity">
<RelativeLayout
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorSurface"
app:elevation="0dp">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorSurface"
app:titleTextAppearance="@style/ToolbarTextTitle"
tools:title="Manager" />
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface"
tools:context=".ui.MainActivity">
android:layout_below="@id/app_bar"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorSurface"
app:elevation="0dp">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorSurface"
app:titleTextAppearance="@style/ToolbarTextTitle"
tools:title="Manager" />
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/app_bar"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
</RelativeLayout>
</layout>
</RelativeLayout>

View File

@ -1,21 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.WelcomeActivity">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<fragment
android:id="@+id/welcome_navhost"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.WelcomeActivity">
<fragment
android:id="@+id/welcome_navhost"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/welcome_navigation" />
</RelativeLayout>
</layout>
app:defaultNavHost="true"
app:navGraph="@navigation/welcome_navigation" />
</RelativeLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.dialogs.AppDownloadDialog"
@ -13,26 +12,24 @@
<TextView
android:id="@+id/app_download_header"
tools:text="Installing Vanced"
style="@style/DialogCardTitle"/>
style="@style/DialogCardTitle" />
<TextView
android:id="@+id/app_download_patient"
android:layout_below="@id/app_download_header"
android:text="@string/please_be_patient"
style="@style/DialogCardSubtitle"/>
style="@style/DialogCardSubtitle" />
<com.google.android.material.progressindicator.ProgressIndicator
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/app_download_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/app_download_patient"
android:layout_marginTop="24dp"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
tools:progress="10"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"/>
app:trackCornerRadius="15dp"
tools:progress="10" />
<com.google.android.material.progressindicator.ProgressIndicator
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/app_install_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -41,9 +38,7 @@
android:layout_below="@id/app_download_progressbar"
android:layout_marginTop="24dp"
android:indeterminate="true"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"/>
app:trackCornerRadius="15dp" />
<RelativeLayout
android:layout_width="match_parent"
@ -59,14 +54,17 @@
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/app_download_cancel"
android:textSize="15sp"
tools:text="Downloading base.apk..."/>
tools:text="Downloading base.apk..." />
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
android:id="@+id/app_download_cancel"
android:layout_alignParentEnd="true"
android:text="@string/cancel"
app:layout_constraintEnd_toEndOf="parent"
style="@style/OutlinedButtonStyle"/>
style="@style/OutlinedButtonStyle" />
</RelativeLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@ -22,7 +21,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="About YouTube Vanced"
style="@style/DialogCardTitle"/>
style="@style/DialogCardTitle" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/about_app_image"
@ -32,16 +31,16 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/about_app_name"
tools:src="@drawable/ic_vanced"/>
tools:src="@drawable/ic_vanced" />
<TextView
<com.vanced.manager.ui.core.ThemedTextView
android:id="@+id/about_app_changelog_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/changelog"
app:layout_constraintTop_toBottomOf="@id/about_app_image"
style="@style/CardTextHeader"/>
style="@style/CardTextHeader" />
<TextView
android:id="@+id/about_app_changelog"
@ -50,6 +49,8 @@
android:layout_marginHorizontal="4dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/about_app_changelog_header"
tools:text="@tools:sample/lorem/random"/>
tools:text="@tools:sample/lorem/random" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/BottomDialogCard">
<LinearLayout
@ -10,7 +9,7 @@
<TextView
android:id="@+id/dialog_title"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -24,9 +23,9 @@
</RadioGroup>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/dialog_save"
android:text="@string/save"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/DialogCard">
@ -38,13 +37,13 @@
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
android:id="@+id/url_reset"
style="@style/OutlinedButtonStyle"
android:layout_alignParentStart="true"
android:text="@string/reset" />
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/url_save"
style="@style/ButtonStyle"
android:layout_alignParentEnd="true"

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/BottomDialogCard">
@ -12,22 +11,24 @@
<TextView
android:id="@+id/installation_detected_title"
tools:text="@string/app_install_files_detected"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<TextView
android:id="@+id/installation_detected_summary"
tools:text="@string/app_install_files_detected_summary"
style="@style/DialogCardSubtitle"/>
style="@style/DialogCardSubtitle" />
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/installation_detected_install"
android:layout_marginTop="16dp"
android:text="@string/install"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/installation_detected_redownload"
android:text="@string/redownload"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,66 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:contentPaddingLeft="0dp"
app:contentPaddingRight="0dp"
style="@style/BottomDialogCard">
<ImageButton
android:id="@+id/accent_cancel"
android:layout_width="48dp"
android:layout_height="36dp"
android:src="@drawable/ic_baseline_close_24"
android:layout_marginTop="4dp"
android:layout_gravity="end"
android:background="@android:color/transparent"
android:tint="?colorSettingsTitle"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="8dp"
android:orientation="vertical">
<TextView
android:text="@string/accent_color"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<androidx.core.widget.NestedScrollView
<com.madrapps.pikolo.HSLColorPicker
android:id="@+id/accent_picker"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center"
app:lightness_radius_offset="40dp"
app:saturation_radius_offset="40dp"/>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/hex_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:maxLength="7"/>
<RadioGroup
android:id="@+id/accent_radiogroup"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="Blue"
android:text="@string/accent_blue"
android:textSize="18sp"/>
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
android:id="@+id/accent_reset"
style="@style/OutlinedButtonStyle"
android:layout_alignParentStart="true"
android:text="@string/reset" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="Red"
android:text="@string/accent_red"
android:textSize="18sp"/>
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/accent_save"
style="@style/ButtonStyle"
android:layout_alignParentEnd="true"
android:text="@string/save" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="Green"
android:text="@string/accent_green"
android:textSize="18sp"/>
</RelativeLayout>
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="Yellow"
android:text="@string/accent_yellow"
android:textSize="18sp"/>
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="Purple"
android:text="@string/accent_purple"
android:textSize="18sp"/>
</RadioGroup>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.button.MaterialButton
android:id="@+id/accent_save"
android:text="@string/save"
style="@style/BottomDialogButtonStyle"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/BottomDialogCard">
<LinearLayout
@ -10,7 +9,7 @@
<TextView
android:text="@string/language_title"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -19,12 +18,12 @@
<RadioGroup
android:id="@+id/language_radiogroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content" />
</androidx.core.widget.NestedScrollView>
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/language_save"
android:text="@string/save"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/BottomDialogCard">
<LinearLayout
@ -10,7 +9,7 @@
<TextView
android:text="@string/theme"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -21,32 +20,35 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.radiobutton.MaterialRadioButton
<com.vanced.manager.ui.core.ThemedMaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="System Default"
android:text="@string/system_default"
android:textSize="18sp"/>
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
<com.vanced.manager.ui.core.ThemedMaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="Light"
android:text="@string/theme_light"
android:textSize="18sp"/>
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
<com.vanced.manager.ui.core.ThemedMaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="Dark"
android:text="@string/theme_dark"
android:textSize="18sp"/>
android:textSize="18sp" />
</RadioGroup>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/theme_save"
android:text="@string/save"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@ -16,7 +15,7 @@
<TextView
android:id="@+id/manager_update_header"
android:text="@string/update_center"
style="@style/DialogCardTitle"/>
style="@style/DialogCardTitle" />
<TextView
android:id="@+id/manager_update_patient"
@ -28,29 +27,28 @@
android:layout_marginTop="8dp"
android:gravity="center"
android:text="@string/checking_updates"
android:textSize="16sp"/>
android:textSize="16sp" />
<com.google.android.material.progressindicator.ProgressIndicator
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/manager_update_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/manager_update_patient"
android:layout_marginTop="32dp"
android:paddingBottom="8dp"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
app:trackCornerRadius="15dp"
tools:progress="10"
tools:visibility="visible"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"/>
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
android:id="@+id/manager_update_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="@id/manager_update_progressbar"
android:text="@string/cancel"
app:strokeWidth="2dp"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"/>
style="@style/OutlinedButtonStyle" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/BottomDialogCard">
@ -11,7 +10,7 @@
<TextView
android:text="@string/variant"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -23,25 +22,25 @@
android:layout_height="wrap_content"
tools:ignore="HardcodedText">
<com.google.android.material.radiobutton.MaterialRadioButton
<com.vanced.manager.ui.core.ThemedMaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="nonroot"
android:text="nonroot"
android:textSize="18sp"/>
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
<com.vanced.manager.ui.core.ThemedMaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="root"
android:text="root"
android:textSize="18sp"/>
android:textSize="18sp" />
</RadioGroup>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/variant_save"
android:text="@string/save"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/BottomDialogCard">
<LinearLayout
@ -10,7 +9,7 @@
<TextView
android:id="@+id/music_install_title"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<RelativeLayout
android:layout_width="match_parent"
@ -22,7 +21,7 @@
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/open_version_selector"
style="@style/BottomDialogCardTextItem"/>
style="@style/BottomDialogCardTextItem" />
<ImageButton
android:id="@+id/open_version_selector"
@ -32,12 +31,12 @@
android:background="@android:color/transparent"
android:maxWidth="24dp"
android:maxHeight="24dp"
android:src="@drawable/ic_baseline_navigate_next_36"/>
android:src="@drawable/ic_baseline_navigate_next_36" />
</RelativeLayout>
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/music_install"
android:text="@string/install"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/BottomDialogCard">
@ -11,20 +10,20 @@
<TextView
style="@style/BottomDialogCardTitle"
android:text="@string/select_apps" />
android:text="@string/select_apps" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/select_apps_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:itemCount="2"
tools:listitem="@layout/view_app_checkbox"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/select_apps_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:itemCount="2"
tools:listitem="@layout/view_app_checkbox" />
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/select_apps_save"
style="@style/BottomDialogButtonStyle"
android:layout_marginTop="4dp"
android:text="@string/save"/>
android:text="@string/save" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/BottomDialogCard"
@ -27,10 +26,10 @@
android:id="@+id/lang_button_ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
android:orientation="vertical" />
</androidx.core.widget.NestedScrollView>
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/vanced_install_finish"
style="@style/BottomDialogButtonStyle"
android:text="@string/save" />

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:contentPaddingBottom="4dp"
style="@style/BottomDialogCard">
@ -12,7 +11,7 @@
<TextView
android:id="@+id/vanced_install_title"
style="@style/BottomDialogCardTitle"/>
style="@style/BottomDialogCardTitle" />
<RelativeLayout
android:layout_width="match_parent"
@ -24,7 +23,7 @@
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/open_theme_selector"
style="@style/BottomDialogCardTextItem"/>
style="@style/BottomDialogCardTextItem" />
<ImageButton
android:id="@+id/open_theme_selector"
@ -34,58 +33,58 @@
android:background="@android:color/transparent"
android:maxWidth="24dp"
android:maxHeight="24dp"
android:src="@drawable/ic_baseline_navigate_next_36"/>
android:src="@drawable/ic_baseline_navigate_next_36" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
<TextView
android:id="@+id/vanced_version"
style="@style/BottomDialogCardTextItem"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/open_version_selector" />
<ImageButton
android:id="@+id/open_version_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
android:layout_alignParentEnd="true"
android:background="@android:color/transparent"
android:maxWidth="24dp"
android:maxHeight="24dp"
android:src="@drawable/ic_baseline_navigate_next_36" />
</RelativeLayout>
<TextView
android:id="@+id/vanced_version"
style="@style/BottomDialogCardTextItem"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/open_version_selector" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<ImageButton
android:id="@+id/open_version_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:background="@android:color/transparent"
android:maxWidth="24dp"
android:maxHeight="24dp"
android:src="@drawable/ic_baseline_navigate_next_36" />
</RelativeLayout>
<TextView
android:id="@+id/vanced_lang"
style="@style/BottomDialogCardTextItem"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/open_language_selector" />
<RelativeLayout
android:layout_width="match_parent"
<ImageButton
android:id="@+id/open_language_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
android:layout_alignParentEnd="true"
android:background="@android:color/transparent"
android:maxWidth="24dp"
android:maxHeight="24dp"
android:src="@drawable/ic_baseline_navigate_next_36" />
</RelativeLayout>
<TextView
android:id="@+id/vanced_lang"
style="@style/BottomDialogCardTextItem"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/open_language_selector" />
<ImageButton
android:id="@+id/open_language_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:background="@android:color/transparent"
android:maxWidth="24dp"
android:maxHeight="24dp"
android:src="@drawable/ic_baseline_navigate_next_36"/>
</RelativeLayout>
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/vanced_install"
android:text="@string/install"
style="@style/BottomDialogButtonStyle"/>
style="@style/BottomDialogButtonStyle" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
@ -26,20 +25,20 @@
layout="@layout/include_about_vanced_devs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/stdp"/>
android:layout_marginTop="@dimen/stdp" />
<include
layout="@layout/include_about_app_devs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/stdp"/>
android:layout_marginTop="@dimen/stdp" />
<include
android:id="@+id/about_sources"
layout="@layout/include_about_sources"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/stdp"/>
android:layout_marginTop="@dimen/stdp" />
</LinearLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.vanced.manager.ui.core.SlidingConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<com.vanced.manager.ui.core.SlidingConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -10,14 +9,14 @@
android:id="@+id/grant_root_header"
android:text="@string/are_you_rooted"
app:layout_constraintTop_toTopOf="parent"
style="@style/WelcomeHeaderTitle"/>
style="@style/WelcomeHeaderTitle" />
<TextView
android:id="@+id/grant_root_description"
android:text="@string/willing_to_use_root"
android:textSize="13sp"
app:layout_constraintTop_toBottomOf="@id/grant_root_header"
style="@style/WelcomeHeaderSubtitle"/>
style="@style/WelcomeHeaderSubtitle" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/grant_root_fab"
@ -31,7 +30,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/grant_root_header"
app:maxImageSize="44dp"/>
app:maxImageSize="44dp" />
<TextView
android:layout_width="wrap_content"
@ -42,7 +41,7 @@
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/grant_root_fab"/>
app:layout_constraintTop_toBottomOf="@id/grant_root_fab" />
<TextView
android:layout_width="wrap_content"
@ -52,7 +51,7 @@
app:layout_constraintBottom_toTopOf="@id/grant_root_finish_fab"
app:layout_constraintEnd_toEndOf="@id/grant_root_finish_fab"
app:layout_constraintStart_toStartOf="@id/grant_root_finish_fab"
android:layout_marginBottom="8dp"/>
android:layout_marginBottom="8dp" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/grant_root_finish_fab"
@ -64,5 +63,5 @@
android:src="@drawable/ic_baseline_navigate_next_48"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:maxImageSize="48dp"/>
app:maxImageSize="48dp" />
</com.vanced.manager.ui.core.SlidingConstraintLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home_refresh"
android:layout_width="match_parent"
@ -25,13 +24,13 @@
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="3"
tools:listitem="@layout/view_app"/>
tools:listitem="@layout/view_app" />
<TextView
<com.vanced.manager.ui.core.ThemedTextView
android:layout_marginHorizontal="24dp"
android:layout_marginTop="12dp"
android:text="@string/useful_links"
style="@style/CardTextHeader"/>
android:text="@string/support_us"
style="@style/CardTextHeader" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_sponsors"
@ -41,7 +40,13 @@
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="2"
tools:listitem="@layout/view_sponsor"/>
tools:listitem="@layout/view_sponsor" />
<com.vanced.manager.ui.core.ThemedTextView
android:layout_marginHorizontal="24dp"
android:layout_marginTop="12dp"
android:text="@string/social_media"
style="@style/CardTextHeader" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_links"
@ -51,7 +56,7 @@
android:nestedScrollingEnabled="false"
android:paddingBottom="8dp"
tools:itemCount="6"
tools:listitem="@layout/view_social_link"/>
tools:listitem="@layout/view_social_link" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.vanced.manager.ui.core.SlidingConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<com.vanced.manager.ui.core.SlidingConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@ -13,7 +12,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
style="@style/WelcomeHeaderTitle"/>
style="@style/WelcomeHeaderTitle" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/select_apps_recycler"
@ -24,7 +23,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:itemCount="2"
tools:listitem="@layout/view_app_checkbox"/>
tools:listitem="@layout/view_app_checkbox" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/select_apps_fab"
@ -36,6 +35,6 @@
android:src="@drawable/ic_baseline_navigate_next_48"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:maxImageSize="48dp"/>
app:maxImageSize="48dp" />
</com.vanced.manager.ui.core.SlidingConstraintLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@ -23,10 +22,10 @@
android:id="@+id/use_custom_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:switch_key="@string/use_custom_tabs"
app:switch_def_value="true"
app:switch_key="@{@string/use_custom_tabs}"
app:switch_summary="@string/link_custom_tabs"
app:switch_title="@string/link_title"/>
app:switch_title="@string/link_title" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/notifications_recycler"
@ -34,61 +33,59 @@
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
tools:itemCount="3"
tools:listitem="@layout/view_preference_switch"/>
tools:listitem="@layout/view_preference_switch" />
<com.vanced.manager.ui.core.PreferenceSwitch
android:id="@+id/firebase"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:switch_def_value="true"
app:switch_key="@{@string/firebase}"
app:switch_summary="@string/firebase_summary"
app:switch_title="@string/firebase_title"/>
app:switch_title="@string/firebase_title" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_variant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/variant"/>
app:preference_title="@string/variant" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/clearFiles"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/clear_files"/>
app:preference_title="@string/clear_files" />
</com.vanced.manager.ui.core.PreferenceCategory>
<com.vanced.manager.ui.core.PreferenceCategory
<com.vanced.manager.ui.core.PreferenceCategory
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/category_background"
app:category_title="@string/category_appearance">
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/category_background"
app:category_title="@string/category_appearance">
app:preference_title="@string/theme" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/theme" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_accent_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/accent_color" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_accent_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/accent_color" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_language"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/language_title" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_language"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/language_title"/>
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/select_apps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/select_apps"/>
</com.vanced.manager.ui.core.PreferenceCategory>
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/select_apps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/select_apps" />
</com.vanced.manager.ui.core.PreferenceCategory>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.vanced.manager.ui.core.SlidingConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<com.vanced.manager.ui.core.SlidingConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -13,9 +12,9 @@
android:layout_marginTop="@dimen/top_header_margin"
app:srcCompat="@drawable/ic_launch_text"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/welcome_get_started"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -28,5 +27,5 @@
app:cornerRadius="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
app:layout_constraintStart_toStartOf="parent" />
</com.vanced.manager.ui.core.SlidingConstraintLayout>

View File

@ -14,7 +14,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
<com.vanced.manager.ui.core.ThemedTextView
android:id="@+id/about_card_vancedTeam"
style="@style/CardTextHeader"
android:text="@string/manager_dev"

View File

@ -8,7 +8,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/rectangle_2"
android:background="@drawable/vanced_gradient"
android:orientation="vertical"
android:paddingVertical="8dp">

View File

@ -1,5 +1,4 @@
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@ -14,7 +13,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
<com.vanced.manager.ui.core.ThemedTextView
android:id="@+id/about_card_vancedTeam"
style="@style/CardTextHeader"
android:layout_marginStart="16dp"

View File

@ -14,7 +14,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
<com.vanced.manager.ui.core.ThemedTextView
android:id="@+id/about_card_vancedTeam"
style="@style/CardTextHeader"
android:text="@string/vanced_team"

View File

@ -1,140 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/app_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardBackgroundColor="?colorLinkBG"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
app:contentPaddingBottom="4dp"
app:contentPaddingLeft="16dp"
app:contentPaddingRight="16dp"
app:contentPaddingTop="8dp">
<data>
<import type="android.view.View" />
<variable
name="dataModel"
type="com.vanced.manager.model.DataModel" />
<variable
name="viewModel"
type="com.vanced.manager.ui.viewmodels.HomeViewModel" />
<variable
name="app"
type="String" />
</data>
<com.google.android.material.card.MaterialCardView
android:id="@+id/app_card"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/app_view_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardBackgroundColor="?colorLinkBG"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
app:contentPaddingBottom="4dp"
app:contentPaddingLeft="16dp"
app:contentPaddingRight="16dp"
app:contentPaddingTop="8dp">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/app_view_container"
<com.vanced.manager.ui.core.ThemedTextView
android:id="@+id/app_name"
style="@style/CardTextHeader"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/vanced" />
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
android:id="@+id/app_install_button"
style="@style/OutlinedButtonStyle"
android:layout_marginTop="4dp"
android:textColor="?colorPrimary"
app:layout_constraintBottom_toTopOf="@id/app_uninstall"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/app_uninstall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/ic_delete_black_24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_install_button"
app:tint="?colorLinkImage" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/app_remote_version_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@id/app_installed_version_container"
app:layout_constraintEnd_toStartOf="@id/app_install_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintTop_toBottomOf="@id/app_name">
<TextView
android:id="@+id/app_name"
style="@style/CardTextHeader"
android:text="@{dataModel.appName}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/vanced" />
style="@style/AppVersionText"
android:text="@string/latest" />
<com.google.android.material.button.MaterialButton
android:id="@+id/app_install_button"
style="@style/OutlinedButtonStyle"
android:layout_marginTop="4dp"
android:onClick="@{(v)-> viewModel.openInstallDialog(v, app)}"
android:text="@{dataModel.buttonTxt}"
android:textColor="?colorPrimary"
app:layout_constraintBottom_toTopOf="@id/app_uninstall"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/app_remote_version"
style="@style/AppVersionText"
android:layout_marginStart="4dp" />
</com.google.android.flexbox.FlexboxLayout>
<ImageButton
android:id="@+id/app_uninstall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:onClick="@{()-> viewModel.uninstallPackage(dataModel.appPkg)}"
android:scaleType="fitCenter"
android:src="@drawable/ic_delete_black_24dp"
android:visibility="@{dataModel.isAppInstalled() ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_install_button"
app:tint="?colorLinkImage" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/app_installed_version_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/app_install_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_remote_version_container">
<ImageButton
android:id="@+id/app_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:background="@android:color/transparent"
android:onClick="@{()-> viewModel.openMicrogSettings()}"
android:src="@drawable/ic_app_settings_black_24dp"
android:visibility="@{(app.equals(@string/microg) &amp;&amp; dataModel.isAppInstalled()) ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toStartOf="@id/app_uninstall"
app:layout_constraintTop_toBottomOf="@id/app_install_button"
app:tint="?colorLinkImage" />
<TextView
style="@style/AppVersionText"
android:text="@string/version_installed" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/app_remote_version_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@id/app_installed_version_container"
app:layout_constraintEnd_toStartOf="@id/app_install_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_name">
<TextView
android:id="@+id/app_installed_version"
style="@style/AppVersionText"
android:layout_marginStart="4dp" />
<TextView
style="@style/AppVersionText"
android:text="@string/latest" />
</com.google.android.flexbox.FlexboxLayout>
<TextView
android:id="@+id/app_remote_version"
style="@style/AppVersionText"
android:layout_marginStart="4dp"
android:text="@{dataModel.versionName}" />
</com.google.android.flexbox.FlexboxLayout>
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/app_installed_version_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/app_install_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_remote_version_container">
<TextView
style="@style/AppVersionText"
android:text="@string/version_installed" />
<TextView
android:id="@+id/app_installed_version"
style="@style/AppVersionText"
android:layout_marginStart="4dp"
android:text="@{dataModel.installedVersionName}" />
</com.google.android.flexbox.FlexboxLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</layout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>

Some files were not shown because too many files have changed in this diff Show More