0
0
Fork 0
mirror of https://github.com/YTVanced/VancedManager synced 2024-11-17 00:35:11 +00:00

Merge pull request #359 from YTVanced/dev

Manager 2.2.0 Update
- Added ability to adjust root script timer
- Added an app launch button
- Improved root installer (again)
- Updated logo (again)
- Fixed issues with downloader
- UI fixes and improvements
- Stock YouTube/Music apps should no longer show up as installed
This commit is contained in:
KevinX8 2021-01-16 23:20:05 +00:00 committed by GitHub
commit b8f6ac9bf1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
148 changed files with 1950 additions and 1243 deletions

142
app/build.gradle.kts Normal file
View file

@ -0,0 +1,142 @@
plugins {
id("com.android.application")
kotlin("android")
kotlin("kapt")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
id("com.google.firebase.firebase-perf")
id("androidx.navigation.safeargs.kotlin")
}
android {
compileSdkVersion(30)
defaultConfig {
applicationId = "com.vanced.manager"
minSdkVersion(21)
targetSdkVersion(30)
versionCode = 220
versionName = "2.2.0 (RootedFirebase)"
vectorDrawables.useSupportLibrary = true
buildConfigField("String[]", "MANAGER_LANGUAGES", "{" + 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")}\"")
buildConfigField("String", "CROWDIN_CLIENT_SECRET", "\"${System.getenv("CROWDIN_CLIENT_SECRET")}\"")
}
lintOptions {
disable("MissingTranslation", "ExtraTranslation")
}
applicationVariants.all {
resValue("string", "versionName", versionName)
}
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
buildFeatures {
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)
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
fun getLanguages(): String {
val langs = arrayListOf("en", "bn_BD", "bn_IN", "pa_IN", "pa_PK", "pt_BR", "pt_PT", "zh_CN", "zh_TW")
val exceptions = arrayOf("bn", "pa", "pt", "zh")
File("$projectDir/src/main/res").listFiles()?.forEach { dir ->
if (dir.name.startsWith("values-") && !dir.name.contains("v23")) {
val dirname = dir.name.substringAfter("-").substringBefore("-")
if (!exceptions.any { dirname == it }) {
langs.add(dirname)
}
}
}
return langs.joinToString(", ") { "\"$it\"" }
}
dependencies {
implementation(project(":core-presentation"))
implementation(project(":core-ui"))
implementation(project(":library-network"))
// Kotlin
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("reflect"))
// AndroidX
implementation("androidx.appcompat:appcompat: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.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")
//Appearance
implementation("com.github.madrapps:pikolo:2.0.1")
implementation("com.google.android.material:material:1.3.0-rc01")
// JSON parser
implementation("com.beust:klaxon:5.4")
// Crowdin
implementation("com.crowdin.platform:mobile-sdk:1.2.0")
// Tips
implementation("com.github.florent37:viewtooltip:1.2.2")
// HTTP networking
implementation("com.github.kittinunf.fuel:fuel:2.3.0")
implementation("com.github.kittinunf.fuel:fuel-coroutines:2.2.3")
implementation("com.github.kittinunf.fuel:fuel-json:2.2.3")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
// Root permissions
implementation("com.github.topjohnwu.libsu:core:3.0.2")
implementation("com.github.topjohnwu.libsu:io:3.0.2")
// Layout
implementation("com.google.android:flexbox:2.0.1")
// Firebase
implementation("com.google.firebase:firebase-analytics-ktx:18.0.1")
implementation("com.google.firebase:firebase-crashlytics:17.3.0")
implementation("com.google.firebase:firebase-messaging:21.0.1")
implementation("com.google.firebase:firebase-perf:19.1.0")
}

View file

@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# proguardFiles setting in build.gradle.kts.kts.kts.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

View file

@ -31,14 +31,12 @@
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:screenOrientation="portrait">
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -52,16 +50,14 @@
<activity
android:name=".ui.WelcomeActivity"
android:theme="@style/DarkTheme"
android:screenOrientation="portrait"/>
android:theme="@style/DarkTheme"/>
<activity
android:name=".ui.MainActivity"
android:configChanges="layoutDirection|locale"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/DarkTheme"
android:screenOrientation="portrait">
android:theme="@style/DarkTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -11,6 +11,7 @@ import com.github.florent37.viewtooltip.ViewTooltip
import com.vanced.manager.R
import com.vanced.manager.databinding.ViewAppBinding
import com.vanced.manager.model.DataModel
import com.vanced.manager.model.RootDataModel
import com.vanced.manager.ui.dialogs.AppInfoDialog
import com.vanced.manager.ui.viewmodels.HomeViewModel
@ -23,7 +24,7 @@ class AppListAdapter(
val apps = mutableListOf<String>()
private val dataModels = mutableListOf<DataModel?>()
private val rootDataModels = mutableListOf<DataModel?>()
private val rootDataModels = mutableListOf<RootDataModel?>()
private val prefs = getDefaultSharedPreferences(context)
private var itemCount = 0
@ -45,9 +46,16 @@ class AppListAdapter(
appUninstall.setOnClickListener {
dataModel?.appPkg?.let { it1 -> viewModel.uninstallPackage(it1) }
}
appUninstall.isVisible = dataModel?.isAppInstalled?.value == true
appLaunch.setOnClickListener {
viewModel.launchApp(apps[position], isRoot)
}
with(dataModel?.isAppInstalled?.value) {
appUninstall.isVisible = this == true
appLaunch.isVisible = this == true
}
dataModel?.isAppInstalled?.observe(lifecycleOwner) {
appUninstall.isVisible = it
appLaunch.isVisible = it
}
appRemoteVersion.text = dataModel?.versionName?.value
dataModel?.versionName?.observe(lifecycleOwner) {
@ -84,21 +92,21 @@ class AppListAdapter(
init {
if (prefs.getBoolean("enable_vanced", true)) {
dataModels.add(viewModel.vanced.value)
rootDataModels.add(viewModel.vancedRoot.value)
dataModels.add(viewModel.vancedModel.value)
rootDataModels.add(viewModel.vancedRootModel.value)
apps.add(context.getString(R.string.vanced))
itemCount++
}
if (prefs.getBoolean("enable_music", true)) {
dataModels.add(viewModel.music.value)
rootDataModels.add(viewModel.musicRoot.value)
dataModels.add(viewModel.musicModel.value)
rootDataModels.add(viewModel.musicRootModel.value)
apps.add(context.getString(R.string.music))
itemCount++
}
if (!isRoot) {
dataModels.add(viewModel.microg.value)
dataModels.add(viewModel.microgModel.value)
apps.add(context.getString(R.string.microg))
itemCount++
}

View file

@ -9,7 +9,7 @@ import com.crowdin.platform.CrowdinConfig
import com.crowdin.platform.data.model.AuthConfig
import com.crowdin.platform.data.remote.NetworkType
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.utils.InternetTools.loadJson
import com.vanced.manager.utils.loadJson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob

View file

@ -2,10 +2,12 @@ package com.vanced.manager.core.downloader
import android.content.Context
import com.vanced.manager.R
import com.vanced.manager.utils.DownloadHelper.download
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.DownloadHelper.fuelDownload
import com.vanced.manager.utils.InternetTools.microg
import com.vanced.manager.utils.PackageHelper.install
import com.vanced.manager.utils.getDefaultPrefs
import com.vanced.manager.utils.getInstallUrl
import com.vanced.manager.utils.microg
object MicrogDownloader {
@ -14,11 +16,13 @@ object MicrogDownloader {
fun downloadMicrog(context: Context) {
val url = microg.value?.string("url") ?: ""
fuelDownload(url, folderName, fileName, context, onDownloadComplete = {
context.getDefaultPrefs().getInstallUrl()?.let {
download(url, "$it/", folderName, fileName, context, onDownloadComplete = {
startMicrogInstall(context)
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, fileName))
})
}
}

View file

@ -3,16 +3,11 @@ package com.vanced.manager.core.downloader
import android.content.Context
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.vanced.manager.R
import com.vanced.manager.utils.*
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.download
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.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
@ -42,10 +37,10 @@ object MusicDownloader {
private fun downloadApk(context: Context, apk: String = "music") {
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
download(url, baseurl + "/", folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock")
return@fuelDownload
return@download
}
when (apk) {

View file

@ -6,17 +6,11 @@ import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.logEvent
import com.vanced.manager.R
import com.vanced.manager.utils.*
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.download
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.getFileNameFromUrl
import com.vanced.manager.utils.InternetTools.vanced
import com.vanced.manager.utils.InternetTools.vancedVersions
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
@ -77,7 +71,8 @@ object VancedDownloader {
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
}
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
installUrl?.let {
download(url, "$it/", folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
when (type) {
"theme" ->
if (variant == "root") {
@ -120,6 +115,7 @@ object VancedDownloader {
}
})
}
}
fun startVancedInstall(context: Context, variant: String? = this.variant) {
downloadProgress.value?.installing?.postValue(true)

View file

@ -7,8 +7,8 @@ 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 com.vanced.manager.utils.lifecycleOwner
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -16,9 +16,9 @@ import kotlinx.coroutines.launch
open class DataModel(
private val jsonObject: LiveData<JsonObject?>,
private val context: Context,
val appPkg: String,
val appName: String,
val appIcon: Drawable?,
open val appPkg: String,
open val appName: String,
open val appIcon: Drawable?,
) {
private val versionCode = MutableLiveData<Int>()
@ -64,7 +64,7 @@ open class DataModel(
}
}
private fun getPkgVersionName(pkg: String): String {
open fun getPkgVersionName(pkg: String): String {
val pm = context.packageManager
return if (isAppInstalled.value == true) {
pm.getPackageInfo(pkg, 0).versionName.removeSuffix("-vanced")
@ -84,7 +84,7 @@ open class DataModel(
} else 0
}
private fun compareInt(int1: Int?, int2: Int?): String {
open fun compareInt(int1: Int?, int2: Int?): String {
if (int2 != null && int1 != null) {
return when {
int1 == 0 -> context.getString(R.string.install)

View file

@ -1,7 +1,8 @@
package com.vanced.manager.model
import androidx.lifecycle.MutableLiveData
import com.github.kittinunf.fuel.core.requests.CancellableRequest
import okhttp3.ResponseBody
import retrofit2.Call
open class ProgressModel {
@ -9,7 +10,7 @@ open class ProgressModel {
val downloadingFile = MutableLiveData<String>()
val installing = MutableLiveData<Boolean>()
var currentDownload: CancellableRequest? = null
var currentDownload: Call<ResponseBody>? = null
fun reset() {
downloadProgress.value = 0

View file

@ -0,0 +1,37 @@
package com.vanced.manager.model
import android.content.Context
import android.graphics.drawable.Drawable
import androidx.lifecycle.LiveData
import com.beust.klaxon.JsonObject
import com.vanced.manager.R
import com.vanced.manager.utils.PackageHelper
open class RootDataModel(
jsonObject: LiveData<JsonObject?>,
private val context: Context,
override val appPkg: String,
override val appName: String,
override val appIcon: Drawable?,
private val scriptName: String
): DataModel(
jsonObject, context, appPkg, appName, appIcon
) {
override fun getPkgVersionName(pkg: String): String {
return if (PackageHelper.scriptExists(scriptName)) {
super.getPkgVersionName(pkg)
} else {
context.getString(R.string.unavailable)
}
}
override fun compareInt(int1: Int?, int2: Int?): String {
return if (PackageHelper.scriptExists(scriptName)) {
super.compareInt(int1, int2)
} else {
context.getString(R.string.install)
}
}
}

View file

@ -25,13 +25,7 @@ import com.vanced.manager.ui.dialogs.ManagerUpdateDialog
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.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
import com.vanced.manager.utils.*
class MainActivity : AppCompatActivity() {

View file

@ -7,7 +7,7 @@ import android.widget.FrameLayout
import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.vanced.manager.R
import kotlinx.android.synthetic.main.view_preference.view.*
import com.vanced.manager.databinding.ViewPreferenceBinding
class EmptyPreference @JvmOverloads constructor(
context: Context,
@ -16,19 +16,26 @@ class EmptyPreference @JvmOverloads constructor(
defStyleRes: Int = 0
) : FrameLayout(context, attrs, defStyle, defStyleRes) {
private var _binding: ViewPreferenceBinding? = null
val binding: ViewPreferenceBinding
get() = requireNotNull(_binding)
init {
LayoutInflater.from(context).inflate(R.layout.view_preference, this, true)
_binding = ViewPreferenceBinding.inflate(LayoutInflater.from(context), this, true)
initAttrs(context, attrs)
}
fun setTitle(newTitle: String) {
preference_title.text = newTitle
binding.preferenceTitle.text = newTitle
}
fun setSummary(newSummary: String) {
preference_summary.text = newSummary
preference_summary.isVisible = true
preference_title.setPadding(0, 0, 0, 0)
with (binding) {
preferenceSummary.text = newSummary
preferenceSummary.isVisible = true
preferenceTitle.setPadding(0, 0, 0, 0)
}
}
private fun initAttrs(context: Context, attrs: AttributeSet?) {
@ -36,13 +43,15 @@ class EmptyPreference @JvmOverloads constructor(
val typedArray = context.obtainStyledAttributes(mAttrs, R.styleable.EmptyPreference, 0, 0)
val title = typedArray.getText(R.styleable.EmptyPreference_preference_title)
val summary = typedArray.getText(R.styleable.EmptyPreference_preference_summary)
with (binding) {
if (summary != null) {
preference_summary.text = summary
preferenceSummary.text = summary
} else {
preference_summary.isGone = true
preference_title.setPadding(0, 12, 0, 12)
preferenceSummary.isGone = true
preferenceTitle.setPadding(0, 12, 0, 12)
}
preferenceTitle.text = title
}
preference_title.text = title
typedArray.recycle()
}

View file

@ -5,7 +5,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import com.vanced.manager.R
import kotlinx.android.synthetic.main.view_preference_category.view.*
import com.vanced.manager.databinding.ViewPreferenceCategoryBinding
class PreferenceCategory @JvmOverloads constructor(
context: Context,
@ -13,8 +13,13 @@ class PreferenceCategory @JvmOverloads constructor(
defStyle: Int = 0,
) : LinearLayout(context, attrs, defStyle) {
private var _binding: ViewPreferenceCategoryBinding? = null
val binding: ViewPreferenceCategoryBinding
get() = requireNotNull(_binding)
init {
LayoutInflater.from(context).inflate(R.layout.view_preference_category, this, true)
_binding = ViewPreferenceCategoryBinding.inflate(LayoutInflater.from(context), this, true)
initAttrs(context, attrs)
setPadding(0, 4, 0, 0)
orientation = VERTICAL
@ -25,7 +30,7 @@ class PreferenceCategory @JvmOverloads constructor(
val typedArray = context.obtainStyledAttributes(mAttrs, R.styleable.PreferenceCategory, 0, 0)
val title = typedArray.getText(R.styleable.PreferenceCategory_category_title)
category_title.text = title
binding.categoryTitle.text = title
typedArray.recycle()
}
}

View file

@ -43,8 +43,9 @@ class PreferenceSwitch @JvmOverloads constructor(
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))
val defValue = getBoolean(R.styleable.PreferenceSwitch_switch_def_value, false)
setKey(key)
setDefaultValue(defValue)
setTitle(title)
setSummary(summary)
recycle()
@ -64,7 +65,7 @@ class PreferenceSwitch @JvmOverloads constructor(
}
fun setOnCheckedListener(method: (buttonView: CompoundButton, isChecked: Boolean) -> Unit) {
mListener = object : OnCheckedListener{
mListener = object : OnCheckedListener {
override fun onChecked(buttonView: CompoundButton, isChecked: Boolean) {
method(buttonView, isChecked)
}
@ -85,11 +86,11 @@ class PreferenceSwitch @JvmOverloads constructor(
fun setKey(key: CharSequence?) {
prefKey = key.toString()
binding.preferenceSwitch.isChecked = prefs.getBoolean(prefKey, defValue)
binding.preferenceSwitch.isChecked = prefs.getBoolean(key.toString(), defValue)
}
fun setDefaultValue(newVal: Boolean) {
defValue = newVal
binding.preferenceSwitch.isChecked = prefs.getBoolean(prefKey, defValue)
binding.preferenceSwitch.isChecked = prefs.getBoolean(prefKey, newVal)
}
}

View file

@ -6,10 +6,10 @@ 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
import com.vanced.manager.utils.accentColor
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
import com.vanced.manager.utils.lifecycleOwner
class ThemedMaterialButton @JvmOverloads constructor(
context: Context,
@ -18,7 +18,7 @@ class ThemedMaterialButton @JvmOverloads constructor(
) : MaterialButton(context, attributeSet, defStyleAttr) {
init {
setBgColor(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
setBgColor(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
setBgColor(color.toInt())

View file

@ -5,21 +5,14 @@ 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
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
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())
}
}
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
}
}

View file

@ -5,21 +5,14 @@ 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
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
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())
}
}
buttonTintList = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
}
}

View file

@ -0,0 +1,20 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import com.google.android.material.slider.Slider
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
class ThemedMaterialSlider@JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : Slider(context, attributeSet, defStyleAttr) {
init {
thumbStrokeColor = ColorStateList.valueOf(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
}
}

View file

@ -5,10 +5,10 @@ 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
import com.vanced.manager.utils.accentColor
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
import com.vanced.manager.utils.lifecycleOwner
class ThemedOutlinedMaterialButton @JvmOverloads constructor(
@ -17,7 +17,7 @@ class ThemedOutlinedMaterialButton @JvmOverloads constructor(
defStyleAttr: Int = 0
) : MaterialButton(context, attributeSet, defStyleAttr) {
init {
applyAccent(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
applyAccent(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
applyAccent(color.toInt())

View file

@ -0,0 +1,25 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.util.AttributeSet
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.vanced.manager.R
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
class ThemedSwipeRefreshlayout @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null
) : SwipeRefreshLayout(context, attributeSet) {
init {
setColorSchemeColors(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
initAttrs(context, attributeSet)
}
private fun initAttrs(context: Context, attributeSet: AttributeSet?) {
attributeSet.let {
val typedAttrs = context.obtainStyledAttributes(it, R.styleable.ThemedSwipeRefreshlayout, 0, 0)
setProgressBackgroundColorSchemeColor(typedAttrs.getColor(R.styleable.ThemedSwipeRefreshlayout_progressBackgroundColor, 0))
typedAttrs.recycle()
}
}
}

View file

@ -8,10 +8,10 @@ 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
import com.vanced.manager.utils.accentColor
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
import com.vanced.manager.utils.lifecycleOwner
class ThemedSwitchCompat @JvmOverloads constructor(
context: Context,
@ -21,7 +21,7 @@ class ThemedSwitchCompat @JvmOverloads constructor(
private val states = arrayOf(intArrayOf(-android.R.attr.state_checked), intArrayOf(android.R.attr.state_checked))
init {
setSwitchColors(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
setSwitchColors(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
setSwitchColors(color.toInt())

View file

@ -3,10 +3,10 @@ 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
import com.vanced.manager.utils.accentColor
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getDefaultPrefs
import com.vanced.manager.utils.lifecycleOwner
class ThemedTextView @JvmOverloads constructor(
context: Context,
@ -14,7 +14,7 @@ class ThemedTextView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : AppCompatTextView(context, attributeSet, defStyleAttr) {
init {
setTextColor(context.getDefaultPrefs().getInt("manager_accent", defAccentColor))
setTextColor(context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor))
context.lifecycleOwner()?.let { owner ->
accentColor.observe(owner) { color ->
setTextColor(color.toInt())

View file

@ -18,7 +18,7 @@ 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.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.Extensions.applyAccent
import com.vanced.manager.utils.applyAccent
class AppDownloadDialog : BindingDialogFragment<DialogAppDownloadBinding>() {

View file

@ -11,8 +11,8 @@ 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.ThemedMaterialRadioButton
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.getCheckedButtonTag
import com.vanced.manager.utils.getDefaultPrefs
class AppVersionSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomRadioButtonBinding>() {

View file

@ -1,17 +1,13 @@
package com.vanced.manager.ui.dialogs
import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat.startActivity
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
import com.vanced.manager.utils.applyAccent
import com.vanced.manager.utils.isMiui
import com.vanced.manager.utils.openUrl
object DialogContainer {
@ -23,12 +19,12 @@ object DialogContainer {
dialog.dismiss()
}
setOnDismissListener {
if (MiuiHelper.isMiui()) {
if (isMiui()) {
applyAccentMiuiDialog(context)
}
}
setOnCancelListener {
if (MiuiHelper.isMiui()) {
if (isMiui()) {
applyAccentMiuiDialog(context)
}
}
@ -112,39 +108,4 @@ object DialogContainer {
}
}
fun launchVanced(context: Context) {
val intent = Intent()
intent.component =
if (PreferenceManager.getDefaultSharedPreferences(context).getString("vanced_variant", "nonroot") == "root")
ComponentName("com.google.android.youtube", "com.google.android.youtube.HomeActivity")
else
ComponentName("com.vanced.android.youtube", "com.google.android.youtube.HomeActivity")
MaterialAlertDialogBuilder(context).apply {
setTitle(context.getString(R.string.success))
setMessage(context.getString(R.string.vanced_installed))
setPositiveButton(context.getString(R.string.launch)) { _, _ ->
startActivity(context, intent, null)
}
setNegativeButton(context.getString(R.string.close)) { dialog, _ -> dialog.dismiss() }
create()
applyAccent()
}
}
fun launchMusic(activity: Activity) {
val intent = Intent()
intent.component = ComponentName("com.vanced.android.youtube.music", "com.vanced.android.youtube.music.MusicActivity")
MaterialAlertDialogBuilder(activity).apply {
setTitle(activity.getString(R.string.success))
setMessage(activity.getString(R.string.music_installed))
setPositiveButton(activity.getString(R.string.launch)) { _, _ ->
startActivity(activity, intent, null)
}
setNegativeButton(activity.getString(R.string.close)) { dialog, _ -> dialog.dismiss() }
create()
applyAccent()
}
}
}

View file

@ -16,10 +16,10 @@ import com.madrapps.pikolo.listeners.OnColorSelectionListener
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogManagerAccentColorBinding
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
import com.vanced.manager.utils.accentColor
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.mutableAccentColor
import com.vanced.manager.utils.toHex
class ManagerAccentColorDialog : BindingDialogFragment<DialogManagerAccentColorBinding>() {
@ -43,12 +43,12 @@ class ManagerAccentColorDialog : BindingDialogFragment<DialogManagerAccentColorB
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
mutableAccentColor.value = prefs.getInt("manager_accent", defAccentColor)
mutableAccentColor.value = prefs.getInt("manager_accent_color", defAccentColor)
}
private fun bindData() {
with(binding) {
val accent = prefs.getInt("manager_accent", defAccentColor)
val accent = prefs.getInt("manager_accent_color", defAccentColor)
hexEdittext.apply {
setText(accent.toHex(), TextView.BufferType.EDITABLE)
addTextChangedListener(object : TextWatcher {
@ -95,7 +95,7 @@ class ManagerAccentColorDialog : BindingDialogFragment<DialogManagerAccentColorB
try {
val colorFromEditText = Color.parseColor(hexEdittext.text.toString())
mutableAccentColor.value = colorFromEditText
prefs.edit { putInt("manager_accent", colorFromEditText) }
prefs.edit { putInt("manager_accent_color", colorFromEditText) }
} catch (e: IllegalArgumentException) {
Log.d("VMTheme", getString(R.string.failed_accent))
Toast.makeText(requireActivity(), getString(R.string.failed_accent), Toast.LENGTH_SHORT).show()
@ -105,7 +105,7 @@ class ManagerAccentColorDialog : BindingDialogFragment<DialogManagerAccentColorB
dismiss()
}
accentReset.setOnClickListener {
prefs.edit { putInt("manager_accent", defAccentColor) }
prefs.edit { putInt("manager_accent_color", defAccentColor) }
mutableAccentColor.value = defAccentColor
dismiss()
}

View file

@ -11,8 +11,8 @@ 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.ThemedMaterialRadioButton
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.LanguageHelper.getLanguageFormat
import com.vanced.manager.utils.getCheckedButtonTag
import com.vanced.manager.utils.getLanguageFormat
class ManagerLanguageDialog : BindingBottomSheetDialogFragment<DialogManagerLanguageBinding>() {
@ -41,7 +41,7 @@ class ManagerLanguageDialog : BindingBottomSheetDialogFragment<DialogManagerLang
languageRadiogroup.addView(mrb, MATCH_PARENT, WRAP_CONTENT)
}
val language = prefs.getString("manager_lang", "System Default")
root.findViewWithTag<ThemedMaterialRadioButton>(language).isChecked = true
root.findViewWithTag<ThemedMaterialRadioButton>(language)?.isChecked = true
languageSave.setOnClickListener {
val newPref = binding.languageRadiogroup.getCheckedButtonTag()
if (language != newPref) {

View file

@ -8,7 +8,7 @@ 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.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.getCheckedButtonTag
class ManagerThemeDialog : BindingBottomSheetDialogFragment<DialogManagerThemeBinding>() {

View file

@ -17,8 +17,8 @@ import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogManagerUpdateBinding
import com.vanced.manager.utils.DownloadHelper.downloadManager
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.Extensions.applyAccent
import com.vanced.manager.utils.InternetTools.manager
import com.vanced.manager.utils.applyAccent
import com.vanced.manager.utils.manager
class ManagerUpdateDialog : BindingDialogFragment<DialogManagerUpdateBinding>() {

View file

@ -9,7 +9,7 @@ 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.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.getCheckedButtonTag
class ManagerVariantDialog : BindingBottomSheetDialogFragment<DialogManagerVariantBinding>() {

View file

@ -7,9 +7,9 @@ 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.utils.Extensions.convertToAppVersions
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.InternetTools.musicVersions
import com.vanced.manager.utils.convertToAppVersions
import com.vanced.manager.utils.getDefaultPrefs
import com.vanced.manager.utils.musicVersions
class MusicPreferencesDialog : BindingBottomSheetDialogFragment<DialogMusicPreferencesBinding>() {

View file

@ -0,0 +1,61 @@
package com.vanced.manager.ui.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.edit
import com.vanced.manager.R
import com.vanced.manager.core.ui.base.BindingDialogFragment
import com.vanced.manager.databinding.DialogServicedTimerBinding
import com.vanced.manager.utils.PackageHelper
import com.vanced.manager.utils.PackageHelper.getPackageDir
import com.vanced.manager.utils.PackageHelper.getPkgNameRoot
import com.vanced.manager.utils.PackageHelper.scriptExists
import com.vanced.manager.utils.getDefaultPrefs
import com.vanced.manager.utils.writeServiceDScript
import java.io.IOException
import java.util.*
class ServiceDTimerDialog : BindingDialogFragment<DialogServicedTimerBinding>() {
private val prefs by lazy { requireActivity().getDefaultPrefs() }
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): DialogServicedTimerBinding = DialogServicedTimerBinding.inflate(inflater, container, false)
override fun otherSetups() {
bindData()
}
private fun bindData() {
with (binding) {
servicedSlider.value = prefs.getInt("serviced_sleep_timer", 1).toFloat()
servicedCancel.setOnClickListener {
dismiss()
}
servicedSave.setOnClickListener {
try {
arrayOf("vanced", "music").forEach { app ->
if (scriptExists(app)) {
val apkFPath = "${PackageHelper.apkInstallPath}/${app.capitalize(Locale.ROOT)}/base.apk"
getPackageDir(requireActivity(), getPkgNameRoot(app))?.let { it1 -> requireActivity().writeServiceDScript(apkFPath, it1, app) }
}
}
} catch (e: IOException) {
Toast.makeText(requireActivity(), R.string.script_save_failed, Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
prefs.edit {
putInt("serviced_sleep_timer", servicedSlider.value.toInt())
}
dismiss()
}
}
}
}

View file

@ -11,8 +11,8 @@ 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.utils.InternetTools.baseUrl
import com.vanced.manager.utils.InternetTools.loadJson
import com.vanced.manager.utils.baseUrl
import com.vanced.manager.utils.loadJson
import kotlinx.coroutines.launch
class URLChangeDialog : BindingDialogFragment<DialogCustomUrlBinding>() {

View file

@ -10,15 +10,14 @@ 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.ThemedMaterialCheckbox
import com.vanced.manager.utils.InternetTools.vanced
import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages
import com.vanced.manager.utils.getDefaultVancedLanguages
import com.vanced.manager.utils.vanced
import java.util.*
class VancedLanguageSelectionDialog : BindingBottomSheetDialogFragment<DialogVancedLanguageSelectionBinding>() {
@ -72,7 +71,6 @@ class VancedLanguageSelectionDialog : BindingBottomSheetDialogFragment<DialogVan
isChecked = langPrefs?.contains(lang) ?: false
text = loc.getDisplayLanguage(loc).capitalize(Locale.ROOT)
textSize = 18F
typeface = ResourcesCompat.getFont(requireActivity(), R.font.exo_bold)
}
addView(box, MATCH_PARENT, WRAP_CONTENT)
}

View file

@ -4,15 +4,12 @@ import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit
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.utils.Extensions.convertToAppTheme
import com.vanced.manager.utils.Extensions.convertToAppVersions
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import com.vanced.manager.utils.InternetTools.vancedVersions
import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages
import com.vanced.manager.utils.*
import java.util.*
class VancedPreferencesDialog : BindingBottomSheetDialogFragment<DialogVancedPreferencesBinding>() {
@ -67,6 +64,11 @@ class VancedPreferencesDialog : BindingBottomSheetDialogFragment<DialogVancedPre
showDialog(VancedLanguageSelectionDialog())
}
vancedInstall.setOnClickListener {
if (showLang.isEmpty()) {
installPrefs.edit {
putString("lang", "en")
}
}
dismiss()
showDialog(
AppDownloadDialog.newInstance(

View file

@ -11,9 +11,9 @@ 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.ThemedMaterialRadioButton
import com.vanced.manager.utils.Extensions.convertToAppTheme
import com.vanced.manager.utils.Extensions.getCheckedButtonTag
import com.vanced.manager.utils.InternetTools.vanced
import com.vanced.manager.utils.convertToAppTheme
import com.vanced.manager.utils.getCheckedButtonTag
import com.vanced.manager.utils.vanced
class VancedThemeSelectorDialog : BindingBottomSheetDialogFragment<DialogBottomRadioButtonBinding>() {

View file

@ -16,7 +16,7 @@ import com.vanced.manager.core.ui.ext.showDialog
import com.vanced.manager.databinding.FragmentAboutBinding
import com.vanced.manager.ui.dialogs.AppInfoDialog
import com.vanced.manager.ui.viewmodels.AboutViewModel
import com.vanced.manager.utils.InternetTools.manager
import com.vanced.manager.utils.manager
class AboutFragment : BindingFragment<FragmentAboutBinding>() {

View file

@ -4,57 +4,84 @@ import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.preference.*
import androidx.core.view.isVisible
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin
import com.vanced.manager.BuildConfig.ENABLE_CROWDIN_AUTH
import com.vanced.manager.R
import com.vanced.manager.BuildConfig
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.databinding.FragmentDevSettingsBinding
import com.vanced.manager.ui.WelcomeActivity
import com.vanced.manager.ui.dialogs.ManagerUpdateDialog
import com.vanced.manager.ui.dialogs.URLChangeDialog
import com.vanced.manager.utils.LanguageHelper.authCrowdin
import com.vanced.manager.utils.authCrowdin
class DevSettingsFragment: PreferenceFragmentCompat() {
class DevSettingsFragment : BindingFragment<FragmentDevSettingsBinding>() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.dev_settings, rootKey)
private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) }
val ftSwitch: Preference? = findPreference("firstlaunch_switch")
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = FragmentDevSettingsBinding.inflate(inflater, container, false)
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
ftSwitch?.setOnPreferenceClickListener {
override fun otherSetups() {
setHasOptionsMenu(true)
bindData()
}
AlertDialog.Builder(requireContext())
.setTitle("FirstLaunch activated")
.setMessage("boolean will be activated on next app start")
.setPositiveButton("Restart") { _, _ ->
run {
startActivity(Intent(requireContext(), WelcomeActivity::class.java))
activity?.finish()
private fun bindData() {
with(binding) {
bindWelcomeLauncher()
bindForceUpdate()
bindChannelURL()
bindCrowdin()
bindKernelArch()
bindAndroidVersion()
}
}
.create()
.show()
private fun FragmentDevSettingsBinding.bindWelcomeLauncher() {
welcomeScreenLauncher.setOnClickListener {
prefs.edit {
putBoolean("firstLaunch", true)
putBoolean("show_changelog_tooltip", true)
}
true
startActivity(Intent(requireContext(), WelcomeActivity::class.java))
requireActivity().finish()
}
}
if (ENABLE_CROWDIN_AUTH) {
findPreference<PreferenceCategory>("crowdin_pref_category")?.isVisible = true
private fun FragmentDevSettingsBinding.bindForceUpdate() {
forceManagerUpdate.setOnClickListener {
ManagerUpdateDialog.newInstance(true).show(
requireActivity().supportFragmentManager,
"update_manager"
)
}
}
findPreference<Preference>("crowdin_auth")?.isVisible = !Crowdin.isAuthorized()
findPreference<SwitchPreferenceCompat>("crowdin_upload_screenshot")?.isVisible = Crowdin.isAuthorized()
findPreference<SwitchPreferenceCompat>("crowdin_real_time")?.isVisible = Crowdin.isAuthorized()
private fun FragmentDevSettingsBinding.bindChannelURL() {
channelUrl.setOnClickListener {
URLChangeDialog().show(childFragmentManager.beginTransaction(), null)
}
}
findPreference<Preference>("crowdin_auth")?.setOnPreferenceClickListener {
private fun FragmentDevSettingsBinding.bindCrowdin() {
if (BuildConfig.ENABLE_CROWDIN_AUTH) {
val isAuthorized = Crowdin.isAuthorized()
crowdinCategory.isVisible = true
crowdinAuth.isVisible = !isAuthorized
screenshotUploading.isVisible = isAuthorized
realTimeUpdates.isVisible = isAuthorized
crowdinAuth.setOnClickListener {
requireActivity().authCrowdin()
@RequiresApi(Build.VERSION_CODES.M)
if (!Settings.canDrawOverlays(requireActivity())) {
@ -63,39 +90,26 @@ class DevSettingsFragment: PreferenceFragmentCompat() {
("package:" + requireActivity().packageName).toUri()
)
startActivityForResult(intent, 69)
return@setOnPreferenceClickListener true
}
Crowdin.authorize(requireActivity())
true
}
}
}
findPreference<Preference>("install_url")?.setOnPreferenceClickListener {
URLChangeDialog().show(childFragmentManager.beginTransaction(), "Install URL")
true
}
private fun FragmentDevSettingsBinding.bindKernelArch() {
val supportedAbis: Array<String> = Build.SUPPORTED_ABIS
findPreference<Preference>("device_arch")?.summary =
kernelArch.setSummary(
if (supportedAbis.contains("arm64-v8a") || supportedAbis.contains("x86_64")) {
"64bit"
} else {
"32bit"
}
findPreference<Preference>("device_os")?.summary = "${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})"
val forceUpdate: Preference? = findPreference("force_update")
forceUpdate?.setOnPreferenceClickListener {
ManagerUpdateDialog.newInstance(true).show(
requireActivity().supportFragmentManager,
"update_manager"
)
true
}
private fun FragmentDevSettingsBinding.bindAndroidVersion() {
androidVersion.setSummary("${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})")
}
}

View file

@ -28,7 +28,7 @@ import com.vanced.manager.databinding.FragmentHomeBinding
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
import com.vanced.manager.utils.isFetching
open class HomeFragment : BindingFragment<FragmentHomeBinding>() {

View file

@ -6,6 +6,7 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.analytics.FirebaseAnalytics
@ -17,22 +18,23 @@ 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.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 com.vanced.manager.utils.accentColor
import com.vanced.manager.utils.defAccentColor
import com.vanced.manager.utils.getLanguageFormat
import com.vanced.manager.utils.toHex
import java.io.File
class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
private companion object {
const val LIGHT = "Light"
const val DARK = "Dark"
}
private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) }
private lateinit var variant: String
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
@ -46,9 +48,11 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
private fun bindData() {
with(binding) {
variant = prefs.getString("vanced_variant", "nonroot").toString()
bindRecycler()
bindFirebase()
bindManagerVariant()
bindServiceDTimer()
bindClearFiles()
bindManagerTheme()
bindManagerAccentColor()
@ -74,10 +78,18 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
private fun FragmentSettingsBinding.bindManagerVariant() {
managerVariant.apply {
prefs.getString("vanced_variant", "nonroot")?.let { setSummary(it) }
setSummary(variant)
setOnClickListener { showDialog(ManagerVariantDialog()) }
}
}
private fun FragmentSettingsBinding.bindServiceDTimer() {
servicedTimer.apply {
if (variant == "root") this.isVisible = true
setOnClickListener { showDialog(ServiceDTimerDialog()) }
}
}
private fun FragmentSettingsBinding.bindClearFiles() {
clearFiles.setOnClickListener {
with(requireActivity()) {
@ -104,11 +116,11 @@ class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
}
private fun FragmentSettingsBinding.bindManagerAccentColor() {
managerAccentColor.setSummary(prefs.getInt("manager_accent", defAccentColor).toHex())
managerAccentColor.apply {
managerAccentColor.apply{
setSummary(prefs.getInt("manager_accent_color", defAccentColor).toHex())
setOnClickListener { showDialog(ManagerAccentColorDialog()) }
accentColor.observe(viewLifecycleOwner) {
managerAccentColor.setSummary(prefs.getInt("manager_accent", defAccentColor).toHex())
setSummary(it.toHex())
}
}
}

View file

@ -3,12 +3,12 @@ package com.vanced.manager.ui.viewmodels
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import com.vanced.manager.R
import com.vanced.manager.utils.InternetTools
import com.vanced.manager.utils.openUrl
class AboutViewModel(application: Application): AndroidViewModel(application) {
fun openUrl(url: String) {
InternetTools.openUrl(url, R.color.GitHub, getApplication())
openUrl(url, R.color.GitHub, getApplication())
}
}

View file

@ -1,5 +1,9 @@
package com.vanced.manager.ui.viewmodels
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources
@ -17,19 +21,18 @@ 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.model.RootDataModel
import com.vanced.manager.ui.dialogs.AppDownloadDialog
import com.vanced.manager.ui.dialogs.InstallationFilesDetectedDialog
import com.vanced.manager.ui.dialogs.MusicPreferencesDialog
import com.vanced.manager.ui.dialogs.VancedPreferencesDialog
import com.vanced.manager.utils.*
import com.vanced.manager.utils.AppUtils.managerPkg
import com.vanced.manager.utils.AppUtils.microgPkg
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.show
import com.vanced.manager.utils.InternetTools
import com.vanced.manager.utils.InternetTools.loadJson
import com.vanced.manager.utils.PackageHelper.apkExist
import com.vanced.manager.utils.PackageHelper.musicApkExists
import com.vanced.manager.utils.PackageHelper.uninstallApk
@ -41,12 +44,12 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
private val prefs = getDefaultSharedPreferences(activity)
val vanced = MutableLiveData<DataModel>()
val vancedRoot = MutableLiveData<DataModel>()
val microg = MutableLiveData<DataModel>()
val music = MutableLiveData<DataModel>()
val musicRoot = MutableLiveData<DataModel>()
val manager = MutableLiveData<DataModel>()
val vancedModel = MutableLiveData<DataModel>()
val vancedRootModel = MutableLiveData<RootDataModel>()
val microgModel = MutableLiveData<DataModel>()
val musicModel = MutableLiveData<DataModel>()
val musicRootModel = MutableLiveData<RootDataModel>()
val managerModel = MutableLiveData<DataModel>()
fun fetchData() {
viewModelScope.launch {
@ -68,12 +71,27 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
else -> R.color.Vanced
}
InternetTools.openUrl(url, color, activity)
openUrl(url, color, activity)
}
fun launchApp(app: String, isRoot: Boolean) {
val componentName = when (app) {
activity.getString(R.string.vanced) -> if (isRoot) ComponentName(vancedRootPkg, "$vancedRootPkg.HomeActivity") else ComponentName(vancedPkg, "$vancedRootPkg.HomeActivity")
activity.getString(R.string.music) -> if (isRoot) ComponentName(musicRootPkg, "$musicRootPkg.activities.MusicActivity") else ComponentName(musicPkg, "$musicRootPkg.activities.MusicActivity")
activity.getString(R.string.microg) -> ComponentName(microgPkg, "org.microg.gms.ui.SettingsActivity")
else -> throw IllegalArgumentException("Can't open this app")
}
try {
activity.startActivity(Intent().setComponent(componentName))
} catch (e: ActivityNotFoundException) {
Log.d("VMHMV", e.toString())
}
}
fun openInstallDialog(view: View, app: String) {
val variant = prefs.getString("vanced_variant", "nonroot")
if (variant == "nonroot" && app != activity.getString(R.string.microg) && !microg.value?.isAppInstalled?.value!!) {
if (variant == "nonroot" && app != activity.getString(R.string.microg) && !microgModel.value?.isAppInstalled?.value!!) {
microgToast.show()
return
}
@ -137,11 +155,11 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
}
init {
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))
vancedModel.value = DataModel(vanced, activity, vancedPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced))
vancedRootModel.value = RootDataModel(vanced, activity, vancedRootPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced), "vanced")
musicModel.value = DataModel(music, activity, musicPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music))
musicRootModel.value = RootDataModel(music, activity, musicRootPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music), "music")
microgModel.value = DataModel(microg, activity, microgPkg, activity.getString(R.string.microg), AppCompatResources.getDrawable(activity, R.drawable.ic_microg))
managerModel.value = DataModel(manager, activity, managerPkg, activity.getString(R.string.app_name), AppCompatResources.getDrawable(activity, R.mipmap.ic_launcher))
}
}

View file

@ -9,7 +9,6 @@ import com.vanced.manager.R
import com.vanced.manager.ui.dialogs.AppDownloadDialog
import com.vanced.manager.ui.fragments.HomeFragment
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.getSha256
import kotlinx.coroutines.*
import java.io.File
import java.io.IOException
@ -92,7 +91,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
context: Context,
): Boolean {
val themeF = File(downloadPath, "$apk.apk")
return runBlocking { InternetTools.checkSHA256(getSha256(hashUrl, apk, context), themeF) }
return runBlocking { checkSHA256(getSha256(hashUrl, apk, context), themeF) }
}
private fun getErrorMessage(status: String, context: Context): String {
@ -111,7 +110,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
status.contains("Files_Missing_VA") -> context.getString(R.string.files_missing_va)
status.contains("Path_Missing") -> context.getString(R.string.path_missing)
else ->
if (MiuiHelper.isMiui())
if (isMiui())
context.getString(R.string.installation_miui)
else
context.getString(R.string.installation_failed)
@ -127,7 +126,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
PackageInstaller.STATUS_FAILURE_INVALID -> context.getString(R.string.installation_invalid)
PackageInstaller.STATUS_FAILURE_STORAGE -> context.getString(R.string.installation_storage)
else ->
if (MiuiHelper.isMiui())
if (isMiui())
context.getString(R.string.installation_miui)
else
context.getString(R.string.installation_failed)

View file

@ -2,12 +2,8 @@ package com.vanced.manager.utils
import android.os.Build
object DeviceUtils {
fun getArch(): String = when {
fun getArch(): String = when {
Build.SUPPORTED_ABIS.contains("x86") -> "x86"
Build.SUPPORTED_ABIS.contains("arm64-v8a") -> "arm64_v8a"
else -> "armeabi_v7a"
}
}

View file

@ -7,36 +7,106 @@ import android.os.Build
import android.util.Log
import androidx.core.content.FileProvider
import androidx.lifecycle.MutableLiveData
import com.github.kittinunf.fuel.Fuel
import com.vanced.manager.R
import com.vanced.manager.library.network.providers.createService
import com.vanced.manager.model.ProgressModel
import com.vanced.manager.utils.AppUtils.sendCloseDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Streaming
import retrofit2.http.Url
import java.io.*
object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun fuelDownload(url: String, fileFolder: String, fileName: String, context: Context, onDownloadComplete: () -> Unit, onError: (error: String) -> Unit) = launch {
interface DownloadHelper {
@Streaming
@GET
fun download(@Url url: String): Call<ResponseBody>
}
fun download(
url: String,
baseUrl: String,
fileFolder: String,
fileName: String,
context: Context,
onDownloadComplete: () -> Unit,
onError: (error: String) -> Unit
) {
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)
val downloadInterface = createService(DownloadHelper::class, baseUrl)
val download = downloadInterface.download(url)
downloadProgress.value?.currentDownload = download
download.enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
if (response.isSuccessful) {
CoroutineScope(Dispatchers.IO).launch {
if (response.body()?.let { writeFile(it, context.getExternalFilesDir(fileFolder)?.path + "/" + fileName) } == true) {
onDownloadComplete()
}, failure = { error ->
} else {
onError("Could not save file")
downloadProgress.value?.downloadProgress?.postValue(0)
Log.d("VMDownloader", error.cause.toString())
onError(error.errorData.toString())
Log.d("VMDownloader", "Failed to save file: $url")
}
}
} else {
onError(response.errorBody().toString())
downloadProgress.value?.downloadProgress?.postValue(0)
Log.d("VMDownloader", "Failed to download file: $url")
}
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
if (call.isCanceled) {
Log.d("VMDownloader", "Download canceled")
downloadProgress.value?.downloadProgress?.postValue(0)
} else {
onError(t.stackTraceToString())
downloadProgress.value?.downloadProgress?.postValue(0)
Log.d("VMDownloader", "Failed to download file: $url")
}
}
})
}
fun writeFile(body: ResponseBody, filePath: String): Boolean {
return try {
val file = File(filePath)
val totalBytes = body.contentLength()
var inputStream: InputStream? = null
var outputStream: OutputStream? = null
try {
val fileReader = ByteArray(4096)
var downloadedBytes: Long = 0
inputStream = body.byteStream()
outputStream = FileOutputStream(file)
var read: Int
while (inputStream.read(fileReader).also { read = it } != -1) {
outputStream.write(fileReader, 0, read)
downloadedBytes += read.toLong()
downloadProgress.value?.downloadProgress?.postValue((downloadedBytes * 100 / totalBytes).toInt())
}
outputStream.flush()
true
} catch (e: IOException) {
false
} finally {
inputStream?.close()
outputStream?.close()
}
} catch (e: IOException) {
false
}
}
val downloadProgress = MutableLiveData<ProgressModel>()
@ -47,7 +117,7 @@ object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun downloadManager(context: Context) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
fuelDownload(url, "manager", "manager.apk", context, onDownloadComplete = {
download(url,"https://github.com/YTVanced/VancedManager", "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)
@ -62,7 +132,12 @@ object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
context.startActivity(intent)
sendCloseDialog(context)
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, "manager.apk"))
downloadProgress.value?.downloadingFile?.postValue(
context.getString(
R.string.error_downloading,
"manager.apk"
)
)
})
}

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.content.ContextWrapper
import android.content.DialogInterface
import android.content.SharedPreferences
import android.util.Log
import android.widget.RadioGroup
import androidx.core.graphics.ColorUtils
import androidx.fragment.app.DialogFragment
@ -13,46 +14,48 @@ import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.google.android.material.radiobutton.MaterialRadioButton
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.R
import com.vanced.manager.utils.InternetTools.baseUrl
import com.vanced.manager.utils.ThemeHelper.accentColor
import com.vanced.manager.utils.ThemeHelper.defAccentColor
import java.util.*
object Extensions {
fun RadioGroup.getCheckedButtonTag(): String? {
fun RadioGroup.getCheckedButtonTag(): String? {
return findViewById<MaterialRadioButton>(checkedRadioButtonId)?.tag?.toString()
}
}
fun DialogFragment.show(activity: FragmentActivity) {
fun DialogFragment.show(activity: FragmentActivity) {
try {
show(activity.supportFragmentManager, "")
} catch (e: Exception) {
Log.d("VMUI", e.stackTraceToString())
}
fun Context.getDefaultPrefs(): SharedPreferences = getDefaultSharedPreferences(this)
}
//Not sure how much this can affect performance
//but if anyone can improve this even slightly,
//feel free to open a PR
fun List<String>.convertToAppVersions(): List<String> {
fun Context.getDefaultPrefs(): SharedPreferences = getDefaultSharedPreferences(this)
//Not sure how much this can affect performance
//but if anyone can improve this even slightly,
//feel free to open a PR
fun List<String>.convertToAppVersions(): List<String> {
val versionsModel = arrayListOf("latest")
for (i in reversed().indices) {
versionsModel.add(this[i])
}
return versionsModel
}
}
fun String.convertToAppTheme(context: Context): String {
fun String.convertToAppTheme(context: Context): String {
return context.getString(R.string.light_plus_other, this.capitalize(Locale.ROOT))
}
}
fun String.getLatestAppVersion(versions: List<String>): String {
fun String.getLatestAppVersion(versions: List<String>): String {
return if (this == "latest") versions.reversed()[0] else this
}
}
fun SharedPreferences.getInstallUrl() = getString("install_url", baseUrl)
fun SharedPreferences.getInstallUrl() = getString("install_url", baseUrl)
fun Context.lifecycleOwner(): LifecycleOwner? {
fun Context.lifecycleOwner(): LifecycleOwner? {
var curContext = this
var maxDepth = 20
while (maxDepth-- > 0 && curContext !is LifecycleOwner) {
@ -63,27 +66,32 @@ object Extensions {
} else {
null
}
}
}
fun Int.toHex(): String = java.lang.String.format("#%06X", 0xFFFFFF and this)
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)) {
//Material team decided to keep their LinearProgressIndicator final
//At least extension methods exist
fun LinearProgressIndicator.applyAccent() {
with(accentColor.value ?: context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor)) {
setIndicatorColor(this)
trackColor = ColorUtils.setAlphaComponent(this, 70)
}
}
}
fun MaterialAlertDialogBuilder.applyAccent() {
with(accentColor.value ?: context.getDefaultPrefs().getInt("manager_accent", defAccentColor)) {
fun MaterialAlertDialogBuilder.applyAccent() {
with(accentColor.value ?: context.getDefaultPrefs().getInt("manager_accent_color", defAccentColor)) {
show().apply {
getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(this@with)
getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(this@with)
getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(this@with)
}
}
}
}
fun Context.writeServiceDScript(apkFPath: String, path: String, app: String) {
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 ${getDefaultPrefs().getInt("serviced_sleep_timer", 1)}; done${"\n"}chcon u:object_r:apk_data_file:s0 $apkFPath${"\n"}mount -o bind $apkFPath $path"""
SuFileOutputStream(shellFileZ).use { out -> out.write(code.toByteArray())}
}

View file

@ -1,8 +1,10 @@
package com.vanced.manager.utils
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat
@ -13,29 +15,27 @@ import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject
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.util.*
object InternetTools {
private const val TAG = "VMNetTools"
private const val TAG = "VMNetTools"
val vanced = MutableLiveData<JsonObject?>()
val music = MutableLiveData<JsonObject?>()
val microg = MutableLiveData<JsonObject?>()
val manager = MutableLiveData<JsonObject?>()
val vanced = MutableLiveData<JsonObject?>()
val music = MutableLiveData<JsonObject?>()
val microg = MutableLiveData<JsonObject?>()
val manager = MutableLiveData<JsonObject?>()
val vancedVersions = MutableLiveData<JsonArray<String>>()
val musicVersions = MutableLiveData<JsonArray<String>>()
val vancedVersions = MutableLiveData<JsonArray<String>>()
val musicVersions = MutableLiveData<JsonArray<String>>()
val isFetching = MutableLiveData<Boolean>()
val isFetching = MutableLiveData<Boolean>()
//var braveTiers = MutableLiveData<JsonObject?>()
//var braveTiers = MutableLiveData<JsonObject?>()
fun openUrl(url: String, color: Int, context: Context) {
fun openUrl(url: String, color: Int, context: Context) {
try {
val customTabPrefs = getDefaultSharedPreferences(context).getBoolean("use_custom_tabs", true)
if (customTabPrefs) {
val builder = CustomTabsIntent.Builder()
@ -46,11 +46,15 @@ object InternetTools {
customTabsIntent.launchUrl(context, url.toUri())
} else
context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
} catch (e: ActivityNotFoundException) {
Toast.makeText(context, R.string.error, Toast.LENGTH_SHORT).show()
}
}
fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/') + 1, url.length)
fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/') + 1, url.length)
suspend fun loadJson(context: Context) = withContext(Dispatchers.IO) {
suspend fun loadJson(context: Context) = withContext(Dispatchers.IO) {
isFetching.postValue(true)
val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl)
val calendar = Calendar.getInstance()
@ -58,8 +62,8 @@ object InternetTools {
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")
val latest = getJson("$installUrl/latest.json?$fetchTime")
val versions = getJson("$installUrl/versions.json?$fetchTime")
// braveTiers.apply {
// set(getJson("$installUrl/sponsor.json"))
// notifyChange()
@ -72,23 +76,23 @@ object InternetTools {
microg.postValue(latest?.obj("microg"))
manager.postValue(latest?.obj("manager"))
isFetching.postValue(false)
}
}
private 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)
getJson("$installUrl/$file")?.string(obj) ?: context.getString(R.string.unavailable)
} catch (e: Exception) {
Log.e(TAG, "Error: ", e)
context.getString(R.string.unavailable)
}
}
}
suspend fun getSha256(hashUrl: String, obj: String, context: Context): String {
suspend fun getSha256(hashUrl: String, obj: String, context: Context): String {
return getJsonString(hashUrl, obj, context)
}
}
fun checkSHA256(sha256: String, updateFile: File): Boolean {
fun checkSHA256(sha256: String, updateFile: File): Boolean {
return try {
val dataBuffer = updateFile.readBytes()
// Generate the checksum
@ -99,8 +103,6 @@ object InternetTools {
e.printStackTrace()
false
}
}
const val baseUrl = "https://vancedapp.com/api/v1"
}
const val baseUrl = "https://vancedapp.com/api/v1"

View file

@ -7,11 +7,9 @@ import com.beust.klaxon.Parser
import com.github.kittinunf.fuel.coroutines.awaitString
import com.github.kittinunf.fuel.httpGet
object JsonHelper {
private var dataMap: HashMap<String, JsonObject> = HashMap()
private var dataMap: HashMap<String, JsonObject> = HashMap()
suspend fun getJson(url: String): JsonObject? {
suspend fun getJson(url: String): JsonObject? {
return try {
if (dataMap.containsKey(url)) {
dataMap[url]
@ -23,16 +21,14 @@ object JsonHelper {
//This null is NEEDED, do NOT try to "fix" NPE here!!!
null
}
}
}
private suspend fun getSuspendJson(url: String): JsonObject =
private suspend fun getSuspendJson(url: String): JsonObject =
Parser.default().parse(
StringBuilder(url.httpGet().awaitString())
) as JsonObject
suspend fun getJsonArray(url: String): JsonArray<String> =
suspend fun getJsonArray(url: String): JsonArray<String> =
Klaxon().parseArray<String>(
url.httpGet().awaitString()
) as JsonArray<String>
}

View file

@ -11,18 +11,15 @@ import android.provider.Settings
import androidx.annotation.RequiresApi
import com.crowdin.platform.Crowdin
import com.vanced.manager.R
import com.vanced.manager.utils.InternetTools.vanced
import java.util.*
object LanguageHelper {
fun getLanguageFormat(context: Context, language: String): String {
fun getLanguageFormat(context: Context, language: String): String {
return when {
language == "System Default" -> context.getString(R.string.system_default)
language.length > 2 -> {
language.contains("_") -> {
val loc = Locale(
language.substring(0, language.length - 3),
language.substring(language.length - 2)
language.substringBefore("_"),
language.substringAfter("_")
)
loc.getDisplayName(loc).capitalize(Locale.ENGLISH)
}
@ -32,10 +29,10 @@ object LanguageHelper {
}
}
}
}
@Suppress("DEPRECATION")
fun getDefaultVancedLanguages(): String {
@Suppress("DEPRECATION")
fun getDefaultVancedLanguages(): String {
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>()
@ -47,18 +44,18 @@ object LanguageHelper {
}
return finalLangs.distinct().sorted().joinToString(", ")
}
}
@RequiresApi(Build.VERSION_CODES.N)
fun LocaleList.toLangTags(): Array<String> {
@RequiresApi(Build.VERSION_CODES.N)
fun LocaleList.toLangTags(): Array<String> {
val langTags: Array<String> = this.toLanguageTags().split(",").toTypedArray()
for (i in 0 until this.size()) {
langTags[i] = langTags[i].substring(0, 2)
}
return langTags
}
}
fun Activity.authCrowdin() {
fun Activity.authCrowdin() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
val intent = Intent(
@ -70,14 +67,12 @@ object LanguageHelper {
}
Crowdin.authorize(this)
}
}
}
fun Activity.onActivityResult(requestCode: Int) {
fun Activity.onActivityResult(requestCode: Int) {
if (requestCode == 69 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
Crowdin.authorize(this)
}
}
}
}

View file

@ -4,13 +4,11 @@ import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
object MiuiHelper {
private const val MIUI_PROP_NAME = "ro.miui.ui.version.name"
private const val MIUI_PROP_NAME = "ro.miui.ui.version.name"
fun isMiui(): Boolean = !getSystemProps(MIUI_PROP_NAME).isNullOrEmpty()
fun isMiui(): Boolean = !getSystemProps(MIUI_PROP_NAME).isNullOrEmpty()
private fun getSystemProps(propname: String): String? {
private fun getSystemProps(propname: String): String? {
var input: BufferedReader? = null
return try {
val process = Runtime.getRuntime().exec("getprop $propname")
@ -21,5 +19,4 @@ object MiuiHelper {
} finally {
input?.close()
}
}
}

View file

@ -10,7 +10,6 @@ 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
@ -19,8 +18,6 @@ import com.vanced.manager.utils.AppUtils.sendCloseDialog
import com.vanced.manager.utils.AppUtils.sendFailure
import com.vanced.manager.utils.AppUtils.sendRefresh
import com.vanced.manager.utils.AppUtils.vancedRootPkg
import com.vanced.manager.utils.InternetTools.music
import com.vanced.manager.utils.InternetTools.vanced
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -33,7 +30,8 @@ import kotlin.collections.HashMap
object PackageHelper {
private const val apkInstallPath = "/data/adb"
const val apkInstallPath = "/data/adb"
private const val INSTALLER_TAG = "VMInstall"
private val vancedThemes = arrayOf("black", "dark", "pink", "blue")
init {
@ -45,7 +43,7 @@ object PackageHelper {
)
}
private fun getAppName(pkg: String): String {
private fun getAppNameRoot(pkg: String): String {
return when (pkg) {
vancedRootPkg -> "vanced"
musicRootPkg -> "music"
@ -53,6 +51,23 @@ object PackageHelper {
}
}
fun scriptExists(scriptName: String): Boolean {
val serviceDScript = SuFile.open("$apkInstallPath/service.d/$scriptName.sh")
val postFsDataScript = SuFile.open("$apkInstallPath/post-fs-data.d/$scriptName.sh")
if (serviceDScript.exists() && postFsDataScript.exists()) {
return true
}
return false
}
fun getPkgNameRoot(app: String): String {
return when (app) {
"vanced" -> vancedRootPkg
"music" -> musicRootPkg
else -> ""
}
}
fun isPackageInstalled(packageName: String, packageManager: PackageManager): Boolean {
return try {
packageManager.getPackageInfo(packageName, 0)
@ -127,7 +142,7 @@ object PackageHelper {
}
fun uninstallRootApk(pkg: String): Boolean {
val app = getAppName(pkg)
val app = getAppNameRoot(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()
@ -188,6 +203,7 @@ object PackageHelper {
val modApk: FileInfo? = fileInfoList.lastOrNull { modApkBool(it.name) }
if (modApk != null) {
if (overwriteBase(modApk, fileInfoList, appVerCode, pkg, app, context)) {
Log.d(INSTALLER_TAG, "Finished installation")
sendRefresh(context)
sendCloseDialog(context)
}
@ -236,7 +252,7 @@ object PackageHelper {
try {
for (listOfFile in listOfFiles!!) {
if (listOfFile.isFile) {
Log.d("AppLog", "installApk: " + listOfFile.name)
Log.d(INSTALLER_TAG, "installApk: " + listOfFile.name)
nameSizeMap[listOfFile.name] = listOfFile.length()
totalSize += listOfFile.length()
}
@ -249,12 +265,12 @@ object PackageHelper {
installParams.setSize(totalSize)
try {
sessionId = context.packageManager.packageInstaller.createSession(installParams)
Log.d("AppLog","Success: created install session [$sessionId]")
Log.d(INSTALLER_TAG,"Success: created install session [$sessionId]")
for ((key, value) in nameSizeMap) {
doWriteSession(sessionId, apkFolderPath + key, value, key, context)
}
doCommitSession(sessionId, context)
Log.d("AppLog","Success")
Log.d(INSTALLER_TAG,"Success")
} catch (e: IOException) {
e.printStackTrace()
}
@ -291,10 +307,10 @@ object PackageHelper {
out.write(buffer, 0, c)
}
session.fsync(out)
Log.d("AppLog", "Success: streamed $total bytes")
Log.d(INSTALLER_TAG, "Success: streamed $total bytes")
return PackageInstaller.STATUS_SUCCESS
} catch (e: IOException) {
Log.e("AppLog", "Error: failed to write; " + e.message)
Log.e(INSTALLER_TAG, "Error: failed to write; " + e.message)
return PackageInstaller.STATUS_FAILURE
} finally {
try {
@ -316,9 +332,9 @@ object PackageHelper {
val pendingIntent = PendingIntent.getService(context, 0, callbackIntent, 0)
session.commit(pendingIntent.intentSender)
session.close()
Log.d("AppLog", "install request sent")
Log.d("AppLog", "doCommitSession: " + context.packageManager.packageInstaller.mySessions)
Log.d("AppLog", "doCommitSession: after session commit ")
Log.d(INSTALLER_TAG, "install request sent")
Log.d(INSTALLER_TAG, "doCommitSession: " + context.packageManager.packageInstaller.mySessions)
Log.d(INSTALLER_TAG, "doCommitSession: after session commit ")
} catch (e: IOException) {
e.printStackTrace()
}
@ -331,7 +347,7 @@ object PackageHelper {
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")
Log.d("AppLog", "installing split apk files: $apkFiles")
Log.d(INSTALLER_TAG, "installing split apk files: $apkFiles")
run {
val sessionIdResult = Shell.su("pm install-create -r -t").exec().out
val sessionIdPattern = Pattern.compile("(\\d+)")
@ -341,7 +357,7 @@ object PackageHelper {
}
apkFiles.forEach { apkFile ->
if (!filenames.any { apkFile.name == it }) {
Log.d("AppLog", "installing APK: ${apkFile.name} ${apkFile.fileSize}")
Log.d(INSTALLER_TAG, "installing APK: ${apkFile.name} ${apkFile.fileSize}")
val command = arrayOf("su", "-c", "pm", "install-write", "-S", "${apkFile.fileSize}", "$sessionId", apkFile.name)
val process: Process = Runtime.getRuntime().exec(command)
val inputPipe = apkFile.getInputStream()
@ -353,12 +369,13 @@ object PackageHelper {
else
process.destroy()
throw RuntimeException(e)
sendFailure(e.stackTrace.map { it.toString() }.toMutableList(), context)
sendCloseDialog(context)
}
process.waitFor()
}
}
Log.d("AppLog", "committing...")
Log.d(INSTALLER_TAG, "committing...")
val installResult = Shell.su("pm install-commit $sessionId").exec()
if (installResult.isSuccess) {
return true
@ -432,7 +449,7 @@ 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, pkg)) {
if (setupScript(apkFPath, path, app, pkg, context)) {
return linkApp(apkFPath, pkg, path)
}
}
@ -443,26 +460,21 @@ object PackageHelper {
return false
}
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String): Boolean
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String, context: Context): Boolean
{
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())}
Log.d(INSTALLER_TAG, "Setting up script")
context.writeServiceDScript(apkFPath, path, app)
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
}
private fun linkApp(apkFPath: String, pkg:String, path: String): Boolean {
private fun linkApp(apkFPath: String, pkg: String, path: String): Boolean {
Log.d(INSTALLER_TAG, "Linking app")
Shell.su("am force-stop $pkg").exec()
Shell.su("""for i in ${'$'}(ls /data/app/ | grep $pkg | tr " "); do umount -l "/data/app/${"$"}i/base.apk"; done """).exec()
val response = Shell.su("""su -mm -c "mount -o bind $apkFPath $path"""").exec()
@ -477,6 +489,7 @@ object PackageHelper {
//check version and perform action based on result
private fun checkVersion(versionCode: Int, baseApkFiles: ArrayList<FileInfo>, pkg: String, context: Context): Boolean {
Log.d(INSTALLER_TAG, "Checking stock version")
val path = getPackageDir(context, pkg)
if (path != null) {
if (path.contains("/data/app/")) {
@ -495,7 +508,7 @@ object PackageHelper {
return try {
context.packageManager.getPackageInfo(pkg, 0)
} catch (e:Exception) {
Log.d("VMpm", "Unable to get package info")
Log.d(INSTALLER_TAG, "Unable to get package info")
null
}
}
@ -510,6 +523,7 @@ object PackageHelper {
//uninstall current update and install base that works with patch
private fun fixHigherVer(apkFiles: ArrayList<FileInfo>, pkg: String, context: Context) : Boolean {
Log.d(INSTALLER_TAG, "Downgrading stock")
if (uninstallRootApk(pkg)) {
return if (pkg == vancedRootPkg) installSplitApkFiles(apkFiles, context) else installRootMusic(apkFiles, context)
}
@ -520,12 +534,14 @@ object PackageHelper {
//install stock youtube matching vanced version
private fun installStock(baseApkFiles: ArrayList<FileInfo>, pkg: String, context: Context): Boolean {
Log.d(INSTALLER_TAG, "Installing stock")
return if (pkg == vancedRootPkg) installSplitApkFiles(baseApkFiles, context) else installRootMusic(baseApkFiles, context)
}
//set chcon to apk_data_file
private fun chConV(path: String, context: Context): Boolean {
val response = Shell.su("chcon u:object_r:apk_data_file:s0 $path").exec()
private fun chConV(apkFPath: String, context: Context): Boolean {
Log.d(INSTALLER_TAG, "Running chcon")
val response = Shell.su("chcon u:object_r:apk_data_file:s0 $apkFPath").exec()
//val response = Shell.su("chcon -R u:object_r:system_file:s0 $path").exec()
return if (response.isSuccess) {
true
@ -538,6 +554,7 @@ object PackageHelper {
//move patch to data/app
private fun moveAPK(apkFile: String, path: String, pkg: String, context: Context) : Boolean {
Log.d(INSTALLER_TAG, "Moving app")
val apkinF = SuFile.open(apkFile)
val apkoutF = SuFile.open(path)
@ -603,7 +620,7 @@ object PackageHelper {
}
//get path of the installed youtube
private fun getPackageDir(context: Context, pkg: String): String?
fun getPackageDir(context: Context, pkg: String): String?
{
val p = getPkgInfo(pkg, context)
return if(p != null)

View file

@ -5,16 +5,13 @@ 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
const val defAccentColor: Int = -13732865
val mutableAccentColor = MutableLiveData<Int>()
val accentColor: LiveData<Int> = mutableAccentColor
val mutableAccentColor = MutableLiveData<Int>()
val accentColor: LiveData<Int> = mutableAccentColor
fun Activity.setFinalTheme() {
fun Activity.setFinalTheme() {
when (getDefaultPrefs().getString("manager_theme", "System Default")) {
"Light" -> setTheme(R.style.LightTheme)
"Dark" -> setTheme(R.style.DarkTheme)
@ -26,6 +23,4 @@ object ThemeHelper {
}
else -> setTheme(R.style.LightTheme)
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View file

@ -4,21 +4,21 @@
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.0405"
android:scaleY="0.0405"
android:translateX="13.5"
android:translateY="13.5">
<group android:scaleX="0.26784"
android:scaleY="0.26784"
android:translateX="20.52"
android:translateY="20.52">
<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:pathData="M217.5,128.1c-0.1,-5 -0.4,-11.8 -1,-18.5c-0.6,-7.4 -1.4,-14.8 -2.8,-19.9c-2.2,-7.9 -8.3,-14.2 -16.2,-16.3c-0.7,-0.2 -1.7,-0.4 -2.5,-0.6c-0.8,-0.1 -1.7,-0.2 -2.6,-0.5c-0.2,0 -0.5,-0.1 -0.7,-0.1c-0.1,0 -0.2,0 -0.2,0c-1,-0.1 -1.9,-0.2 -3,-0.4V58.4c0,-8.8 -3.4,-17 -9.6,-23.2c-6.2,-6.1 -14.4,-9.6 -23.2,-9.6H94.4c-8.8,0 -17,3.4 -23.2,9.6c-6.2,6.2 -9.6,14.4 -9.6,23.2v13.8c-3,0.4 -5.5,0.8 -7.3,1.3c-7.9,2.2 -14.2,8.4 -16.2,16.3c-3.8,14.4 -3.8,46.8 -3.8,46.8s0,32.6 3.8,47c2.2,7.9 8.3,14.2 16.2,16.3c6.2,1.7 20.4,2.6 34.6,3.1c12.6,0.5 25.1,0.6 31.9,0.7l0,0c3.2,0 5.2,0 5.2,0s13.6,0 29.2,-0.5c16.4,-0.5 35.2,-1.4 42.5,-3.5c7.9,-2.2 14.2,-8.4 16.2,-16.3c1.3,-4.9 2.2,-12.1 2.8,-19.3c0.5,-6.6 0.8,-13.2 1,-18.4c0.1,-5.6 0.1,-9.5 0.1,-9.5S217.6,133.2 217.5,128.1zM76.6,58.4c0,-9.8 8,-17.8 17.8,-17.8h61.2c9.8,0 17.8,8 17.8,17.8v12.4c-0.5,0 -1,0 -1.4,-0.1c-2.9,-0.1 -5.8,-0.2 -8.6,-0.4c-1.4,-0.1 -2.8,-0.1 -4.2,-0.1c-0.2,0 -0.5,0 -0.6,0c-1.1,0 -2.2,-0.1 -3.2,-0.1c-15.7,-0.5 -29.3,-0.5 -29.3,-0.5s-1.7,0 -4.6,0c-5.2,0 -14.3,0.1 -24.1,0.4c-6.8,0.2 -13.9,0.5 -20.6,0.8L76.6,58.4L76.6,58.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">
android:pathData="M147.4,131.8l-29.2,-16.9c-3.8,-2.2 -8.5,0.6 -8.5,4.9v33.7c0,4.4 4.8,7.1 8.5,4.9l29.2,-16.9C151.3,139.5 151.3,134 147.4,131.8z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="859.293"
android:startX="620.1221"
android:endY="556.2224"
android:endX="923.1927"
android:startY="152.2642"
android:startX="106.0378"
android:endY="121.1624"
android:endX="137.1398"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
@ -26,15 +26,13 @@
</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">
android:pathData="M121.3,69.6c-2.3,-2.9 -2.8,-7 -0.8,-10.3l0.2,-0.4c2.5,-4.3 8,-5.8 12.4,-3.2l22.2,14.3c-15.7,-0.5 -29.3,-0.5 -29.3,-0.5S124.2,69.6 121.3,69.6zM232.5,120l-15.8,-10.3c0.5,6.7 0.7,13.4 1,18.5l1.3,0.8c6.2,3.7 6.1,12.7 -0.1,16.3l-1.3,0.7l-94.3,55.8c-1,0.6 -1.8,1.3 -2.5,2.2l0,0c-2.3,2.9 -2.8,6.8 -0.8,10.2l0.2,0.4c2.5,4.3 8,5.9 12.4,3.4l22.7,-14.4l61.6,-39l15.8,-10.1C245,146.4 245.1,128 232.5,120z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="1292.4099"
android:startX="354.8105"
android:endY="1106.054"
android:endX="462.39334"
android:startY="189.1184"
android:startX="94.245"
android:endY="85.0525"
android:endX="198.3112"
android:type="linear">
<item android:offset="0" android:color="#FF2E73FF"/>
<item android:offset="1" android:color="#FFFF0032"/>
@ -42,128 +40,19 @@
</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:pathData="M142.5,134.1c-0.1,0 -0.2,0 -0.5,-0.1l-6.5,-3.7c-0.4,-0.2 -0.5,-0.7 -0.2,-1.1s0.7,-0.5 1.1,-0.2l6.5,3.7c0.4,0.2 0.5,0.7 0.2,1.1C143.1,134 142.8,134.1 142.5,134.1z"
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:pathData="M145,134.6m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
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">
android:pathData="M207.2,101c-0.8,0 -1.6,-0.6 -1.8,-1.4c-0.1,-0.6 -0.2,-1.1 -0.4,-1.6c-1.4,-5.6 -5.3,-10.4 -10.4,-13.2c-1.4,-0.8 -3,-1.4 -4.6,-1.8c-0.8,-0.2 -1.7,-0.4 -2.5,-0.6c-0.7,-0.1 -2.3,-0.4 -3.8,-0.6c-1,-0.1 -1.7,-1.1 -1.6,-2s1.1,-1.7 2,-1.6c2,0.2 3.8,0.6 4,0.6l0,0c0.8,0.1 1.8,0.4 2.6,0.6l0,0c1.8,0.5 3.6,1.2 5.3,2.2c6,3.2 10.4,8.9 12.1,15.5c0.1,0.6 0.2,1.1 0.5,1.8c0.2,1 -0.4,1.9 -1.3,2.2C207.4,101 207.3,101 207.2,101z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="853.7486"
android:startX="1527.6058"
android:endY="669.9293"
android:endX="1421.4778"
android:startY="103.1504"
android:startX="203.9691"
android:endY="75.571"
android:endX="188.0462"
android:type="linear">
<item android:offset="4.04912E-7" android:color="#FF953A9A"/>
<item android:offset="1" android:color="#FFFF0032"/>
@ -171,7 +60,24 @@
</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:pathData="M208.4,105.1m-1.9,0a1.9,1.9 0,1 1,3.8 0a1.9,1.9 0,1 1,-3.8 0"
android:fillColor="#953A9A"/>
<path
android:pathData="M45.6,171.8c0.8,0 1.6,0.6 1.8,1.4c0.1,0.6 0.2,1.1 0.4,1.7c1.4,5.6 5.3,10.4 10.4,13.2c1.4,0.7 3,1.3 4.6,1.8c0.8,0.2 1.7,0.4 2.5,0.6c0.7,0.1 2.2,0.4 3.8,0.6c1,0.1 1.7,1.1 1.6,2s-1.1,1.7 -2,1.6c-2,-0.2 -3.8,-0.6 -4,-0.6l0,0c-0.8,-0.1 -1.8,-0.4 -2.6,-0.6l0,0c-1.8,-0.5 -3.6,-1.2 -5.3,-2.2c-6,-3.2 -10.4,-8.9 -12.2,-15.5c-0.1,-0.6 -0.2,-1.1 -0.5,-1.8c-0.2,-1 0.4,-1.9 1.3,-2.2C45.3,171.8 45.4,171.8 45.6,171.8z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="194.67688"
android:startX="57.299984"
android:endY="171.82997"
android:endX="57.299984"
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="M44.148,169.66a1.9,1.9 46.907,1 0,0.126 -3.798a1.9,1.9 46.907,1 0,-0.126 3.798z"
android:fillColor="#FF0032"/>
</group>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -3,10 +3,10 @@
android:shape="rectangle">
<corners
android:topRightRadius="8dp"
android:topLeftRadius="8dp"
android:bottomRightRadius="8dp"
android:bottomLeftRadius="8dp" />
android:topRightRadius="12dp"
android:topLeftRadius="12dp"
android:bottomRightRadius="12dp"
android:bottomLeftRadius="12dp" />
<solid
android:color="?colorLinkBG" />

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,19H5V5h7V3H5c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2v7zM14,3v2h3.59l-9.83,9.83 1.41,1.41L19,6.41V10h2V3h-7z"/>
</vector>

View file

@ -1,22 +1,44 @@
<vector android:height="63dp" android:viewportHeight="1775.6"
android:viewportWidth="1775.6" android:width="63dp"
<vector android:height="64dp" android:viewportHeight="2000"
android:viewportWidth="2000" android:width="64dp"
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#0c0c0f"
android:pathData="M887.8,887.8m-852.8,0a852.8,852.8 0,1 1,1705.6 0a852.8,852.8 0,1 1,-1705.6 0" android:strokeWidth="70">
<aapt:attr name="android:strokeColor">
<gradient android:endX="1515.57" android:endY="260.02994"
android:startX="260.03" android:startY="1515.57" android:type="linear">
<item android:color="#FF3370FA" android:offset="0"/>
<item android:color="#FFF80439" android:offset="1"/>
<path android:fillColor="?colorSettingsTitle" android:pathData="M1388.1,1415.4L1388.1,1415.4c-91.4,84.5 -216.9,133.3 -365.8,133.3c-208.7,0 -399.6,-117.6 -493.3,-304.1c-78.3,-156 -78.3,-339.8 0,-495.7c93.7,-186.6 284.6,-304.3 493.3,-304.3c137.1,-1.6 269.6,49.9 369.4,143.6L1234,745.9c-57,-54.4 -133.1,-84 -211.8,-82.8c-144,0 -266.3,97.2 -309.9,228c-23.1,68.6 -23.1,142.8 0,211.4h0.2c43.8,130.6 165.9,227.8 309.9,227.8c74.4,0 138.2,-19 187.6,-52.6v-0.1c58.2,-38.5 98,-99.2 110.3,-167.7h-298.2V897.2H1543c6.5,36.9 9.5,74.6 9.5,112.2C1552.5,1177.2 1492.5,1319.2 1388.1,1415.4z"/>
<path android:fillColor="#953A9A" android:pathData="M1293.9,595.9m-14.5,0a14.5,14.5 0,1 1,29 0a14.5,14.5 0,1 1,-29 0"/>
<path android:pathData="M1256.2,582.2c-2.7,0 -5.3,-0.7 -7.8,-2.3c-54.3,-34.7 -120.6,-56.3 -186.8,-61c-7.9,-0.6 -13.9,-7.5 -13.4,-15.4c0.6,-7.9 7.4,-13.9 15.4,-13.4c70.9,5 142,28.2 200.3,65.4c6.7,4.3 8.7,13.2 4.4,19.9C1265.6,579.8 1261,582.2 1256.2,582.2z">
<aapt:attr name="android:fillColor">
<gradient android:endX="1048.1708" android:endY="536.1355"
android:startX="1270.5692" android:startY="536.1355" android:type="linear">
<item android:color="#FF953A9A" android:offset="4.04912E-7"/>
<item android:color="#FFFF0032" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:pathData="M1342.5,1147.5v0.5c0,31.7 2.1,100.4 -1.9,133.3h0c-8.9,49.7 -51.3,84.7 -107.9,85.2 -111.1,1.1 -222.2,0.3 -333.3,0.3 0,0 -109.2,0.5 -163.8,0.5h0q-72.45,0 -144.9,-0.2 -14.7,0 -29.4,-0.9c-8.4,-0.5 -16.8,-1.2 -25.1,-2.2 -52.6,-6.1 -89.3,-38.1 -99.8,-85.6v-0.1a131.48,131.48 0,0 1,-3.1 -27.1c-0.7,-46.4 -0.5,-92.9 -0.3,-139.4v-0.2c0,-5.4 0.1,-10.8 0.1,-16.2 0.2,-33.3 4.4,-36.9 38.5,-37.7 17.3,-0.4 34.7,0.3 51.9,-1.1 103.3,-8.1 168,-114.5 122.2,-207.8 -22.8,-46.3 -63,-77.7 -119,-79.5 -22.8,-0.7 -45.5,-0.9 -68.3,-1 -16.9,-0.1 -25.1,-8.3 -25,-25.2 0.1,-18.8 -0.1,-37.7 -0.3,-56.5v-0.4c-0.3,-31.2 -0.6,-62.4 0.1,-93.5v-0.1c0.3,-11.8 1.6,-37.9 1.7,-39.3h0c5.5,-58.6 56.6,-92.9 115.3,-88.7 61,1.6 121.9,2.2 182.9,2.6 22.2,0.1 29.3,-13.1 30.5,-33.5 1.8,-31.7 2.5,-63.8 8.7,-94.8 8.9,-44.3 45.3,-86.6 104.4,-86.6 62.2,0.2 113.8,33 125.9,84.6 7.2,30.7 9,62.9 10.3,94.5 0.9,21.8 8.4,33.3 27.1,35.8h0a52.59,52.59 0,0 0,9.1 0.5c55.1,-0.4 110.1,-0.6 165.2,0.5 8.4,0.5 16.8,1.2 25.1,2.2 52.6,6.1 89.3,38.1 99.8,85.6 1.1,7 2,14.7 2.7,22.9 0.3,46.3 0.5,93.7 0.7,141.9v0.4C1342.9,861.8 1342.7,1008 1342.5,1147.5Z">
<path android:pathData="M663.5,709.5L663.5,709.5L663.5,709.5l-8,10.6l-3.9,5.3l-3.7,5.5c-2.4,3.7 -4.9,7.3 -7.3,11l-6.8,11.3c-1.1,1.9 -2.3,3.8 -3.4,5.7l-3.1,5.8c-2.1,3.9 -4.2,7.8 -6.2,11.7l-5.6,11.9c-0.9,2 -1.9,4 -2.8,6l-2.5,6.1l-5,12.2l-4.4,12.4l-2.2,6.2l-1.9,6.3l-3.8,12.6c-4.5,17 -8.6,34 -11.1,51.4l-1,6.5c-0.3,2.2 -0.7,4.3 -0.9,6.5l-1.5,13.1c-0.2,2.2 -0.5,4.3 -0.7,6.5l-0.4,6.6l-0.9,13.1l-0.1,1.6v1.6l-0.1,3.3l-0.2,6.6l-0.2,6.6c0,2.2 -0.1,4.4 -0.1,6.6l0.3,13.1l0.1,6.6c0.1,2.2 0.3,4.4 0.4,6.6c0.8,17.5 2.6,34.8 5.3,52l2.2,12.9l2.7,12.8c0.2,1.1 0.4,2.1 0.7,3.2l0.8,3.2l1.6,6.3c0.5,2.1 1,4.2 1.6,6.3l1.8,6.3c9.3,33.5 22.7,65.8 39.2,96.2c8.3,15.2 17.6,29.8 27.5,43.9c10,14.1 20.7,27.7 32.2,40.5c46,51.5 103.7,91.8 167.1,117.4l0,0c7.7,3.1 11.4,11.8 8.3,19.5s-11.8,11.4 -19.5,8.3c-0.1,-0.1 -0.3,-0.1 -0.5,-0.2c-66.6,-29.7 -126.2,-74.6 -172.5,-130.3c-11.7,-13.8 -22.3,-28.5 -32.3,-43.6c-9.9,-15.1 -19,-30.7 -27.1,-46.8c-16.1,-32.2 -28.8,-66.2 -37.2,-101.1l-1.6,-6.5c-0.5,-2.2 -0.9,-4.4 -1.4,-6.6l-1.4,-6.6l-0.7,-3.3c-0.2,-1.1 -0.4,-2.2 -0.6,-3.3l-2.3,-13.3l-1.8,-13.3c-2.2,-17.8 -3.4,-35.7 -3.6,-53.5c0,-2.2 -0.1,-4.5 -0.2,-6.7l0.1,-6.7l0.2,-13.4c0,-2.2 0.2,-4.5 0.3,-6.7l0.4,-6.7l0.4,-6.7l0.2,-3.3l0.1,-1.7l0.2,-1.7l1.4,-13.3l0.7,-6.6c0.3,-2.2 0.6,-4.4 1,-6.6l2,-13.2c0.3,-2.2 0.8,-4.4 1.2,-6.6l1.3,-6.6C587.3,830.2 618.1,763.6 663.5,709.5L663.5,709.5L663.5,709.5z">
<aapt:attr name="android:fillColor">
<gradient android:endX="1304.97" android:endY="497.16"
android:startX="467.76" android:startY="1334.37" android:type="linear">
<item android:color="#FF366EF7" android:offset="0"/>
<item android:color="#FFF7043A" android:offset="1"/>
<gradient android:endX="555.1798" android:endY="1071.7072"
android:startX="870.6317" android:startY="1073.554" android:type="linear">
<item android:color="#FF953A9A" android:offset="4.04912E-7"/>
<item android:color="#FFFF0032" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:fillColor="#00000000"
android:pathData="M1332.5,1204.5" android:strokeLineCap="round"
android:strokeLineJoin="round" android:strokeWidth="29">
<aapt:attr name="android:strokeColor">
<gradient android:endX="1332.5" android:endY="1204.5"
android:startX="1332.5" android:startY="1204.5" android:type="linear">
<item android:color="#FF953A9A" android:offset="4.04912E-7"/>
<item android:color="#FFFF0032" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:fillColor="#953A9A" android:pathData="M912.6,1444.6m-16.5,0a16.5,16.5 0,1 1,33 0a16.5,16.5 0,1 1,-33 0"/>
<path android:pathData="M1543,897.2c-27.8,20 -57.3,51 -65.9,76.6c-6.5,18 -17.4,29.8 -28.3,30.3c-9.6,0 -23,-12.8 -28.4,-30.9c-8.6,-23.9 -23.1,-50.6 -50,-76L1543,897.2L1543,897.2zM1442.6,1039c1.3,6.7 7.3,9.9 14,8.6s11.7,-6.6 10.4,-13.4c-1.3,-6.7 -14.1,-17.6 -14.1,-17.6S1441.2,1032.2 1442.6,1039z">
<aapt:attr name="android:fillColor">
<gradient android:endX="1456.7" android:endY="1047.8848"
android:startX="1456.7" android:startY="897.2" android:type="linear">
<item android:color="#FF953A9A" android:offset="4.04912E-7"/>
<item android:color="#FFFF0032" android:offset="1"/>
</gradient>
</aapt:attr>
</path>

View file

@ -0,0 +1,50 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.dialogs.AppDownloadDialog"
style="@style/DialogCard">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/serviced_header"
android:text="@string/script_sleep_timer"
style="@style/DialogCardTitle" />
<com.vanced.manager.ui.core.ThemedMaterialSlider
android:id="@+id/serviced_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/serviced_header"
android:layout_marginTop="24dp"
android:valueFrom="1"
android:valueTo="15"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/serviced_slider"
android:layout_marginTop="8dp">
<com.vanced.manager.ui.core.ThemedOutlinedMaterialButton
android:id="@+id/serviced_cancel"
android:layout_alignParentStart="true"
android:textSize="15sp"
android:text="@string/cancel"
style="@style/OutlinedButtonStyle"/>
<com.vanced.manager.ui.core.ThemedMaterialButton
android:id="@+id/serviced_save"
android:layout_alignParentEnd="true"
android:text="@string/save"
app:layout_constraintEnd_toEndOf="parent"
style="@style/ButtonStyle"/>
</RelativeLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="8dp"
android:paddingTop="16dp">
<com.vanced.manager.ui.core.PreferenceCategory
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/category_background"
app:category_title="General">
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/welcome_screen_launcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Welcome screen launcher"
app:preference_summary="Title says it all" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/force_manager_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Force Manager Update"
app:preference_summary="Update manager without comparing versionCode"/>
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/channel_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/update_url" />
</com.vanced.manager.ui.core.PreferenceCategory>
<com.vanced.manager.ui.core.PreferenceCategory
android:id="@+id/crowdin_category"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/category_background"
app:category_title="Crowdin"
android:visibility="gone"
tools:visibility="visible">
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/crowdin_auth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Authorize" />
<com.vanced.manager.ui.core.PreferenceSwitch
android:id="@+id/screenshot_uploading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Screenshot Uploading (ADMIN ONLY)"
android:visibility="gone"/>
<com.vanced.manager.ui.core.PreferenceSwitch
android:id="@+id/real_time_updates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Real-time Updates"
android:visibility="gone" />
</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="Device Info">
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/kernel_arch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Kernel Architecture"/>
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/android_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="Android Version"/>
</com.vanced.manager.ui.core.PreferenceCategory>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.vanced.manager.ui.core.ThemedSwipeRefreshlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/home_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
app:progressBackgroundColor="?colorSurface">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -20,15 +22,14 @@
android:id="@+id/recycler_app_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
android:layout_marginHorizontal="8dp"
tools:itemCount="3"
tools:listitem="@layout/view_app" />
<com.vanced.manager.ui.core.ThemedTextView
android:layout_marginHorizontal="24dp"
android:layout_marginTop="12dp"
android:layout_marginStart="20dp"
android:text="@string/support_us"
style="@style/CardTextHeader" />
@ -36,15 +37,13 @@
android:id="@+id/recycler_sponsors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="2"
tools:listitem="@layout/view_sponsor" />
<com.vanced.manager.ui.core.ThemedTextView
android:layout_marginHorizontal="24dp"
android:layout_marginTop="12dp"
android:layout_marginStart="20dp"
android:text="@string/social_media"
style="@style/CardTextHeader" />
@ -57,6 +56,9 @@
android:paddingBottom="8dp"
tools:itemCount="6"
tools:listitem="@layout/view_social_link" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</com.vanced.manager.ui.core.ThemedSwipeRefreshlayout>

View file

@ -49,11 +49,20 @@
android:layout_height="wrap_content"
app:preference_title="@string/variant" />
<com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/serviced_timer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:preference_title="@string/script_sleep_timer"
app:preference_summary="@string/script_sleep_timer_description"
android:visibility="gone"/>
<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" />
</com.vanced.manager.ui.core.PreferenceCategory>
<com.vanced.manager.ui.core.PreferenceCategory
@ -86,6 +95,9 @@
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>

View file

@ -7,11 +7,11 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardBackgroundColor="?colorLinkBG"
app:cardCornerRadius="16dp"
app:cardCornerRadius="12dp"
app:cardElevation="0dp"
app:contentPaddingBottom="4dp"
app:contentPaddingLeft="16dp"
app:contentPaddingRight="16dp"
app:contentPaddingLeft="12dp"
app:contentPaddingRight="12dp"
app:contentPaddingTop="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
@ -31,7 +31,6 @@
<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"
@ -48,6 +47,18 @@
app:layout_constraintTop_toBottomOf="@id/app_install_button"
app:tint="?colorLinkImage" />
<ImageButton
android:id="@+id/app_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/ic_baseline_launch_24"
app:layout_constraintEnd_toStartOf="@id/app_uninstall"
app:layout_constraintTop_toBottomOf="@id/app_install_button"
android:layout_marginEnd="4dp"
app:tint="?colorLinkImage" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/app_remote_version_container"
android:layout_width="match_parent"

View file

@ -6,6 +6,7 @@
android:layout_width="165dp"
android:layout_height="97dp"
android:layout_marginTop="8dp"
android:layout_marginStart="8dp"
app:cardBackgroundColor="?colorLinkBG"
app:cardCornerRadius="12dp"
app:cardElevation="0dp">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<!-- Global Strings -->
<string name="cancel">Cancel</string>
<string name="cancel">What is your favourite song</string>
<string name="close">Maak toe</string>
<string name="reset">Herstel</string>
<string name="save">Stoor</string>
@ -51,10 +51,12 @@
<string name="link_title">Use Chrome Custom Tabs</string>
<string name="link_custom_tabs">Links will open in Chrome Custom Tabs</string>
<string name="system_default">System Default</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">Theme</string>
<string name="theme_dark">Dark Theme</string>
<string name="theme_light">Light Theme</string>
<string name="update_url">Update Channel URL</string>
<string name="push_notifications">%1$s Push Notifications</string>
<string name="push_notifications_summary">Receive push notifications when an update for %1$s is released</string>
<string name="update_center">Manager Update Center</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Installation failed because the user aborted the installation.</string>
<string name="installation_blocked">Installation failed because the user blocked the installation.</string>
<string name="installation_downgrade">Installation failed because the user tried to downgrade the package. Uninstall updates from the stock YouTube app, then try again.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_failed">Installation failed for unknown reasons, join our Telegram or Discord for further support.</string>
<string name="installation_incompatible">Installation failed because the installation file is incompatible with your device. Clear downloaded files in the Settings, then try again.</string>
<string name="installation_invalid">Installation failed because the apk files are corrupted, please try again.</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">استخدم علامات تبويب مخصصة لمتصفح كروم</string>
<string name="link_custom_tabs">سيتم فتح الروابط في علامات تبويب مخصصة لمتصفح كروم</string>
<string name="system_default">الوضع الافتراضي</string>
<string name="script_save_failed">فشل حفظ قيمة الوقت الجديد</string>
<string name="script_sleep_timer">Script sleep time للروت</string>
<string name="script_sleep_timer_description">ضبط القيمة الزمنية للنوم المستخدمة في /data/adb/service.d/app.sh script، مفيد لإصلاح مشاكل التركيب</string>
<string name="theme">السمة</string>
<string name="theme_dark">السمة الداكنة</string>
<string name="theme_light">السمة الفاتحة</string>
<string name="update_url">تحديث رابط القناة</string>
<string name="push_notifications">إشعارات %1$s</string>
<string name="push_notifications_summary">تلقي الإشعارات عند إصدار تحديث لـ %1$s</string>
<string name="update_center">مركز التحديث</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">فشل التثبيت لأن المستخدم ألغى التثبيت.</string>
<string name="installation_blocked">فشل التثبيت لأن المستخدم قام بحظر التثبيت.</string>
<string name="installation_downgrade">فشل التثبيت لأن المستخدم حاول تثبيت إصدار قديم. قم بألغاء تثبيت التحديثات الخاصة باليوتيوب الأصلي، ثم حاول مرة أخرى.</string>
<string name="installation_conflict">فشل التثبيت لأن التطبيق يتعارض مع تطبيق مثبت بالفعل. قم بإلغاء تثبيت الإصدار الحالي من ڤانسد، ثم حاول مرة أخرى.</string>
<string name="installation_conflict">فشل التثبيت، لأن هذا التطبيق يتعارض مع تطبيق مثبت بالفعل. قم بإلغاء تثبيت الإصدار الحالي من Vanced، ثم حاول مرة أخرى.</string>
<string name="installation_failed">فشل التثبيت لأسباب غير معروفة، انضم إلى التيليجرام أو الديسكورد الخاص بنا لمزيد من الدعم.</string>
<string name="installation_incompatible">فشل التثبيت لأن ملف التثبيت غير متوافق مع جهازك. امسح الملفات التي تم تنزيلها في الإعدادات، ثم حاول مرة أخرى.</string>
<string name="installation_invalid">فشل التثبيت لأن حزم التثبيت تالفة، الرجاء المحاولة مرة أخرى.</string>

View file

@ -36,7 +36,7 @@
<string name="support_us">Bizi dəstəklə</string>
<!-- Settings -->
<string name="accent_color">Tema rəngi</string>
<string name="accent_blue">Mavi</string>
<string name="accent_blue">Göy</string>
<string name="accent_green">Yaşıl</string>
<string name="accent_purple">Bənövşəyi</string>
<string name="accent_red">Qırmızı</string>
@ -51,10 +51,12 @@
<string name="link_title">Chrome Özəl Vərəqlərini istifadə et</string>
<string name="link_custom_tabs">Bağlantılar Chrome Özəl Vərəqlərində açılacaq</string>
<string name="system_default">İlkin Sistem</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">Tema</string>
<string name="theme_dark">Tünd mövzu</string>
<string name="theme_light">ıq mövzu</string>
<string name="update_url">Yeniləmə Kanal URL-si</string>
<string name="push_notifications">%1$s Ani Bildirişlər</string>
<string name="push_notifications_summary">%1$s üçün yeni buraxılış olanda ani bildirişlər alın</string>
<string name="update_center">Menecer Yeniləmə Mərkəzi</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">İstifadəçi quraşdırmanı ləğv etdiyi üçün quraşdırılma uğursuz oldu.</string>
<string name="installation_blocked">İstifadəçi quraşdırmanı əngəllədiyi üçün quraşdırılma uğursuz oldu.</string>
<string name="installation_downgrade">İstifadəçi paketi alt versiyaya keçirməyə çalışdığı üçün quraşdırılma uğursuz oldu. Stok YouTube tətbiqindən yeniləmələri silib yenidən sınayın.</string>
<string name="installation_conflict">Tətbiq əvvəlcədən quraşdırılmış bir tətbiqlə toqquşduğu üçün quraşdırılma uğursuz oldu. Vanced-in cari versiyasını silib yenidən sınayın.</string>
<string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_failed">Bilinməyən səbəblərə görə quraşdırılma uğursuz oldu. Dəstək üçün Telegram və ya Discord-a qoşulun.</string>
<string name="installation_incompatible">Quraşdırma faylı cihazınıza uyğun gəlmədiyi üçün quraşdırılma uğursuz oldu. Tənzimləmələrdən endirilmiş faylları təmizləyib yenidən sınayın.</string>
<string name="installation_invalid">Apk faylları zədəli olduğu üçün quraşdırılma uğursuz oldu, yenidən sınayın.</string>

View file

@ -36,11 +36,11 @@
<string name="support_us">Support us</string>
<!-- Settings -->
<string name="accent_color">অ্যাকসেন্ট রঙ</string>
<string name="accent_blue">নীল</string>
<string name="accent_green">সবুজ</string>
<string name="accent_purple">বেগুনী</string>
<string name="accent_red">লাল</string>
<string name="accent_yellow">হলুদ</string>
<string name="accent_blue">Blue</string>
<string name="accent_green">Green</string>
<string name="accent_purple">Purple</string>
<string name="accent_red">Red</string>
<string name="accent_yellow">Yellow</string>
<string name="category_appearance">চেহারা</string>
<string name="category_behaviour">আচরণ</string>
<string name="clear_files">ডাউনলোড করা ফাইলগুলি সাফ করুন</string>
@ -51,10 +51,12 @@
<string name="link_title">ক্রোম কাস্টম ট্যাবস ব্যবহার করুন</string>
<string name="link_custom_tabs">লিঙ্কগুলি ক্রোম কাস্টম ট্যাবসে খোলা হবে</string>
<string name="system_default">সিস্টেম দ্বারা নির্ধারিত</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">থিম</string>
<string name="theme_dark">গাঢ় থিম</string>
<string name="theme_light">হালকা থিম</string>
<string name="update_url">চ্যানেল URL আপডেট করুন</string>
<string name="push_notifications">%1$s পুশ বিজ্ঞপ্তি</string>
<string name="push_notifications_summary">%1$s এর আপডেট প্রকাশিত হলে পুশ বিজ্ঞপ্তি পান</string>
<string name="update_center">ম্যানেজার আপডেট কেন্দ্র</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Installation failed because the user aborted the installation.</string>
<string name="installation_blocked">Installation failed because the user blocked the installation.</string>
<string name="installation_downgrade">Installation failed because the user tried to downgrade the package. Uninstall updates from the stock YouTube app, then try again.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_failed">অজানা কারণে ইনস্টলেশন ব্যর্থ হয়েছে, আরও সহায়তার জন্য আমাদের টেলিগ্রাম বা ডিসকর্ডে যোগ দিন।.</string>
<string name="installation_incompatible">ইনস্টলেশন ব্যর্থ হয়েছে কারণ ইনস্টলেশন ফাইলটি আপনার ডিভাইসের সাথে বেমানান। সেটিংসে ডাউনলোড করা ফাইল সাফ করুন, তারপরে আবার চেষ্টা করুন।.</string>
<string name="installation_invalid">অ্যাপ্লিকেশন ব্যর্থ হয়েছে কারণ এপিপি ফাইলগুলি দূষিত হয়েছে, দয়া করে আবার চেষ্টা করুন।.</string>

View file

@ -32,13 +32,13 @@
<string name="root_not_granted">রুট অনুমতি দেয়া হয়নি</string>
<string name="unavailable">অনুপলব্ধ</string>
<string name="update">আপডেট</string>
<string name="social_media">Social Media</string>
<string name="support_us">Support us</string>
<string name="social_media">সামাজিক মাধ্যম</string>
<string name="support_us">আমাদের সমর্থন</string>
<!-- Settings -->
<string name="accent_color">অ্যাকসেন্ট রঙ</string>
<string name="accent_blue">নীল</string>
<string name="accent_green">সবুজ</string>
<string name="accent_purple">বেগুন</string>
<string name="accent_purple">বেগুনি</string>
<string name="accent_red">লাল</string>
<string name="accent_yellow">হলুদ</string>
<string name="category_appearance">রূপ</string>
@ -51,10 +51,12 @@
<string name="link_title">ক্রোম কাস্টম ট্যাবস ব্যবহার করুন</string>
<string name="link_custom_tabs">লিঙ্কগুলি ক্রোম কাস্টম ট্যাবসে খুলবে</string>
<string name="system_default">সিস্টেম দ্বারা র্নির্ধারিত</string>
<string name="script_save_failed">নতুন সময়ের মান সংরক্ষণ করতে ব্যর্থ</string>
<string name="script_sleep_timer">রুট স্ক্রিপ্ট ঘুম সময়</string>
<string name="script_sleep_timer_description">মাউন্টিং ইস্যু সমাধানের জন্য দরকারী /data/adb/service.d/app.sh স্ক্রিপ্টে ব্যবহৃত ঘুমের মানটি সামঞ্জস্য করুন</string>
<string name="theme">থিম</string>
<string name="theme_dark">গাঢ় থিম</string>
<string name="theme_light">হালকা থিম</string>
<string name="update_url">চ্যানেল URL আপডেট করুন</string>
<string name="push_notifications">%1$s পুশ বিজ্ঞপ্তিগুলি</string>
<string name="push_notifications_summary">%1$s এর আপডেট প্রকাশিত হলে পুশ বিজ্ঞপ্তি পান</string>
<string name="update_center">ম্যানেজার আপডেট কেন্দ্র</string>
@ -96,13 +98,13 @@
<string name="chown_fail">System owner কে APK `chown` করতে ব্যর্থ, দয়া করে আবার চেষ্টা করুন।</string>
<string name="error_downloading">%1$s ডাউনলোড করার সময় ত্রুটি</string>
<string name="failed_uninstall">%1$s পেকেজ আন‌ইনস্টল করা যাইনি</string>
<string name="failed_accent">Failed to apply new accent color</string>
<string name="failed_accent">নতুন অ্যাকসেন্ট রঙ প্রয়োগ করতে ব্যর্থ</string>
<string name="files_missing_va">ইনস্টলেশনের জন্য প্রয়োজনীয় ফাইলগুলি খুঁজে পাওয়া যায় নি। ইনস্টল করার জন্য ফাইলগুলি পুনরায় ডাউনলোড করুন, তারপরে আবার চেষ্টা করুন।</string>
<string name="ifile_missing">স্টোরেজ থেকে কালো/গাঢ় থিমের জন্য এপিকে ফাইল সনাক্ত করতে ব্যর্থ, দয়া করে আবার চেষ্টা করুন।</string>
<string name="installation_aborted">ইনস্টল করা যায়নি কারণ ব্যবহারকারী ইনস্টল করা বাতিল করে দিয়েছেন।</string>
<string name="installation_blocked">ইনস্টল করা যায়নি কারণ ব্যবহারকারী ইনস্টল করা অবরুদ্ধ করেছেন।</string>
<string name="installation_downgrade">ইনস্টল করা যায়নি কারণ ব্যবহারকারী প্যাকেজটি ডাউনগ্রেড করার চেষ্টা করছিলেন। স্টক ইউটিউব অ্যাপ্লিকেশন থেকে আপডেটগুলি আনইনস্টল করুন, তারপরে আবার চেষ্টা করুন।</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">ইনস্টলেশন ব্যর্থ হয়েছে কারণ অ্যাপ্লিকেশনটি ইতিমধ্যে ইনস্টল হওয়া অ্যাপ্লিকেশানের সাথে দ্বন্দ্ব রয়েছে ts অ্যাপ্লিকেশনটির বর্তমান সংস্করণটি আনইনস্টল করুন, তারপরে আবার চেষ্টা করুন।.</string>
<string name="installation_failed">অজানা কারণে ইনস্টলেশন ব্যর্থ হয়েছে, আরও সহায়তার জন্য আমাদের টেলিগ্রাম বা ডিসকর্ডে যোগ দিন।</string>
<string name="installation_incompatible">ইনস্টলেশন ব্যর্থ হয়েছে কারণ ইনস্টলেশন ফাইলটি আপনার ডিভাইসের উপযুক্ত নয়। সেটিংসে ডাউনলোড করা ফাইল মুছে ফেলুন, তারপরে আবার চেষ্টা করুন।</string>
<string name="installation_invalid">ইনস্টলেশন ব্যর্থ হয়েছে কারণ এপিকে ফাইলগুলি দূষিত, দয়া করে আবার চেষ্টা করুন।</string>

View file

@ -36,11 +36,11 @@
<string name="support_us">Support us</string>
<!-- Settings -->
<string name="accent_color">Color d\'èmfasi</string>
<string name="accent_blue">Blau</string>
<string name="accent_green">Verd</string>
<string name="accent_purple">Porpra</string>
<string name="accent_red">Vermell</string>
<string name="accent_yellow">Groc</string>
<string name="accent_blue">Blue</string>
<string name="accent_green">Green</string>
<string name="accent_purple">Purple</string>
<string name="accent_red">Red</string>
<string name="accent_yellow">Yellow</string>
<string name="category_appearance">Appearance</string>
<string name="category_behaviour">Behavior</string>
<string name="clear_files">Esborrar fitxers descarregats</string>
@ -51,10 +51,12 @@
<string name="link_title">Utilitza pestanyes personalitzades del Chrome</string>
<string name="link_custom_tabs">Els enllaços s\'obriran en pestanyes personalitzades del Chrome</string>
<string name="system_default">System Default</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">Tema</string>
<string name="theme_dark">Tema fosc</string>
<string name="theme_light">Tema clar</string>
<string name="update_url">Actualitza la URL del canal</string>
<string name="push_notifications">%1$s notificacions automàtiques</string>
<string name="push_notifications_summary">Rebeu notificacions automàtiques quan es publiqui una actualització de%1$s</string>
<string name="update_center">Gestor d\'actualitzacions</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Installation failed because the user aborted the installation.</string>
<string name="installation_blocked">Installation failed because the user blocked the installation.</string>
<string name="installation_downgrade">Installation failed because the user tried to downgrade the package. Uninstall updates from the stock YouTube app, then try again.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_failed">La instal·lació ha fallat per motius desconeguts. Uniu-vos al nostre Telegram o Discord per obtenir més assistència.</string>
<string name="installation_incompatible">La instal·lació ha fallat perquè el fitxer d\'instal·lació és incompatible amb el dispositiu. Esborreu els fitxers descarregats a Configuració i torneu-ho a provar.</string>
<string name="installation_invalid">La instal·lació ha fallat perquè els fitxers apk estan danyats. Torneu-ho a provar.</string>

View file

@ -32,8 +32,8 @@
<string name="root_not_granted">ڕێگەپێدانی Root نەدراوە</string>
<string name="unavailable">بەردەست نیە</string>
<string name="update">نوێکردنەوە</string>
<string name="social_media">Social Media</string>
<string name="support_us">Support us</string>
<string name="social_media">تۆڕە کۆمەڵایەتییەکان</string>
<string name="support_us">پشتگیریکردن</string>
<!-- Settings -->
<string name="accent_color">ڕەنگی سەرەکی</string>
<string name="accent_blue">شین</string>
@ -51,10 +51,12 @@
<string name="link_title">بەکارهێنانی پەنجەرەی تایبەتی گۆگڵ کرۆم</string>
<string name="link_custom_tabs">بەستەرەکان لە پەنجەرەی تایبەتی گۆگڵ کرۆمدا دەکرێنەوە</string>
<string name="system_default">سیستەم</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">ڕووکار</string>
<string name="theme_dark">تاریک</string>
<string name="theme_light">ڕووناک</string>
<string name="update_url">بەستەری کەناڵی نوێکردنەوە</string>
<string name="push_notifications">%1$s وەرگرتنی ئاگادارکردنەوەکان</string>
<string name="push_notifications_summary">وەرگرتنی ئاگادارکردنەوە کاتێ نوێکردنەوەی %1$s بەردەست کرا</string>
<string name="update_center">ناوەندی نوێکردنەوە</string>
@ -96,13 +98,13 @@
<string name="chown_fail">سەرکەوتو نەبوو `chown` بۆ دانان وەک بەرنامەی سیستەم, تکایە دووبارە هەوڵبدەرەوە.</string>
<string name="error_downloading">کێشە ڕوویدا لە داگرتنی %1$s</string>
<string name="failed_uninstall">سڕینەوەی %1$s سەرکەوتو نەبوو</string>
<string name="failed_accent">Failed to apply new accent color</string>
<string name="failed_accent">گۆڕینی ڕەنگ سەرکەوتو نەبوو</string>
<string name="files_missing_va">سەرکەوتو نەبوو لە دۆزینەوەی فایلە پێویستەکان بۆ دامەزراندن، فایلە پێویستیەکان دووبارە دابگرەوە بۆ جێگیرکردن، پاشان دووبارە هەوڵبدەرەوە.</string>
<string name="ifile_missing">سەرکەوتوو نەبوو لەدۆزینەوەی شوێنی فایلی Apk بۆ ڕووکاری ڕەش/تاریک لە بیرگەدا، تکایە دووبارە هەوڵبدەرەوە.</string>
<string name="installation_aborted">دامەزراندن سەرکەوتو نەبوو، لەبەر ئەوەی بەکارهێنەر کۆتاییهێنا بە دابەزاندنەکە.</string>
<string name="installation_blocked">دامەزراندن سەرکەوتو نەبوو، لەبەر ئەوەی بەکارهێنەر ڕێگریکرد لە دابەزاندنەکە.</string>
<string name="installation_downgrade">دامەزراندن سەرکەوتو نەبوو، لەبەر ئەوەی بەکارهێنەر هەوڵیدا بۆ نزمکردنەوەی وەشان، نوێکارییەکانی بەرنامەی بنەڕەتی YouTube بسڕەوە و دووبارە هەوڵبدەرەوە.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_failed">دامەزراندن سەرکەوتو نەبوو لەبەر هۆکاری نادیار، پەیوەندی بکە بە تێلێگرامەکەمان یان Discord بۆ پشتگیری زیاتر.</string>
<string name="installation_incompatible">دامەزراندن سەرکەوتو نەبوو لەبەرئەوەی فایلی دابەزاندن گونجاو نییە لەگەڵ ئامێرەکەت، فایلە داگیراوەکان بسڕەوە و پاشان دووبارە هەوڵبدەرەوە.</string>
<string name="installation_invalid">دامەزراندن سەرکەوتوو نەبوو لەبەرئەوەی فایلی apk تێکچووە، تکایە دووبارە هەوڵبدرەوە.</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">Používat vlastní karty prohlížeče Chrome</string>
<string name="link_custom_tabs">Odkazy se otevřou na vlastních kartách prohlížeče Chrome</string>
<string name="system_default">Výchozí systémové nastavení</string>
<string name="script_save_failed">Nepodařilo se uložit novou hodnotu času</string>
<string name="script_sleep_timer">Doba nečinnosti kořenového skriptu</string>
<string name="script_sleep_timer_description">Upravte hodnotu doby nečinnosti použitou ve skriptu /data/adb/service.d/app.sh, která je užitečná pro opravu problémů s připojením</string>
<string name="theme">Vzhled</string>
<string name="theme_dark">Tmavý vzhled</string>
<string name="theme_light">Světlý vzhled</string>
<string name="update_url">URL aktualizačního kanálu</string>
<string name="push_notifications">%1$s vyskakovací oznámení</string>
<string name="push_notifications_summary">Po vydání aktualizace pro %1$s obdržíte vyskakovací oznámení</string>
<string name="update_center">Centrum aktualizací</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">Brug Chrome Custom Faner</string>
<string name="link_custom_tabs">Links vil åbne i Chrome Custom Faner</string>
<string name="system_default">System Standard</string>
<string name="script_save_failed">Kunne ikke gemme ny tidsværdi</string>
<string name="script_sleep_timer">Root script dvale tid</string>
<string name="script_sleep_timer_description">Justér dvale tid brugt i /data/adb/service.d/app.sh script, bruges til at rette monteringsproblemer</string>
<string name="theme">Tema</string>
<string name="theme_dark">Mørkt tema</string>
<string name="theme_light">Lyst tema</string>
<string name="update_url">Opdateringskanal URL</string>
<string name="push_notifications">%1$s Push Notifikationer</string>
<string name="push_notifications_summary">Modtag push meddelelser når der er en ny opdatering til %1$s</string>
<string name="update_center">Manager opdaterings center</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Installationen fejlede fordi brugeren lukkede installationen.</string>
<string name="installation_blocked">Installationen fejlede fordi brugeren blokerede installationen.</string>
<string name="installation_downgrade">Installationen fejlede fordi brugeren prøvede at nedgradere pakken. Fjern opdateringer fra Youtube appen og prøv igen.</string>
<string name="installation_conflict">Installationen fejlede fordi appen konflikter med en allerede installeret app. Fjern den nuværende version af Vanced og prøv igen.</string>
<string name="installation_conflict">Installationen fejlede fordi appen konflikter med en allerede installeret app. Fjern den nuværende version af appen og prøv igen.</string>
<string name="installation_failed">Installationen fejlede af en ukendt årsag, join vores Telegram eller Discord for hjælp.</string>
<string name="installation_incompatible">Installationen fejlede fordi installationsfilen er inkompatibel med din enhed. Ryd de downloadede filer i indstillingerne og prøv igen.</string>
<string name="installation_invalid">Installationen fejlede fordi apk filerne er beskadiget, prøv igen.</string>

View file

@ -22,7 +22,7 @@
<!-- Home Page -->
<string name="about_app">Über %1$s</string>
<string name="app_changelog_tooltip">Tippe auf die Karte, um den Changelog zu sehen.</string>
<string name="changelog">Changelog</string>
<string name="changelog">Änderungen</string>
<string name="downloading_file">%1$s wird heruntergeladen</string>
<string name="install">Installieren</string>
<string name="button_reinstall">Neu installieren</string>
@ -32,8 +32,8 @@
<string name="root_not_granted">Root-Zugriff nicht erteilt</string>
<string name="unavailable">Nicht verfügbar</string>
<string name="update">Aktualisieren</string>
<string name="social_media">Social Media</string>
<string name="support_us">Support us</string>
<string name="social_media">Soziale Medien</string>
<string name="support_us">Unterstütze uns</string>
<!-- Settings -->
<string name="accent_color">Akzentfarbe</string>
<string name="accent_blue">Blau</string>
@ -51,10 +51,12 @@
<string name="link_title">Verwende Chrome Custom Tabs</string>
<string name="link_custom_tabs">Links werden in Chrome Custom Tabs geöffnet</string>
<string name="system_default">Systemstandard</string>
<string name="script_save_failed">Speichern des neuen Zeitwertes fehlgeschlagen</string>
<string name="script_sleep_timer">Haupt Skript Wartezeit</string>
<string name="script_sleep_timer_description">Anpassen des Wertes für die Ruhezeit, der im Skript /data/adb/service.d/app.sh verwendet wird, nützlich zur Behebung von Problemen beim Einbinden</string>
<string name="theme">Theme</string>
<string name="theme_dark">Dunkles Theme</string>
<string name="theme_light">Helles Theme</string>
<string name="update_url">Kanal-Url updaten</string>
<string name="push_notifications">%1$s Push-Benachrichtigungen</string>
<string name="push_notifications_summary">Push-Benachrichtigungen erhalten, wenn ein Update für %1$s veröffentlicht wird</string>
<string name="update_center">Update Center</string>
@ -98,17 +100,17 @@
<string name="failed_uninstall">Entfernen von %1$s fehlgeschlagen</string>
<string name="failed_accent">Neue Akzentfarbe konnte nicht angewendet werden</string>
<string name="files_missing_va">Die benötigten Dateien für die Installation konnten nicht gefunden werden. Laden Sie die Installationsdateien erneut herunter und versuchen Sie es erneut.</string>
<string name="ifile_missing">Apk-Datei für schwarz/dunkles Theme konnte nicht gefunden werden, bitte versuchen Sie es erneut.</string>
<string name="ifile_missing">Apk-Datei für schwarzes/dunkles Theme konnte nicht gefunden werden, bitte versuchen Sie es erneut.</string>
<string name="installation_aborted">Installation fehlgeschlagen, da der Benutzer die Installation abgebrochen hat.</string>
<string name="installation_blocked">Installation fehlgeschlagen, da der Benutzer die Installation blockiert hat.</string>
<string name="installation_downgrade">Installation fehlgeschlagen, da der Benutzer versucht hat, das Paket herunterzustufen. Aktualisierungen von YouTube deinstallieren und dann erneut versuchen.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Die Installation ist fehlgeschlagen, weil die App in Konflikt mit einer bereits installierten App steht. Deinstalliere die aktuell installierte Version der App und versuchen es dann erneut.</string>
<string name="installation_failed">Installation aus unbekannten Grund fehlgeschlagen. Treten Sie bitte unserem Telegram-Chat oder Discord-Server bei, um Support zu erhalten.</string>
<string name="installation_incompatible">Installation fehlgeschlagen, da die Installationsdatei nicht mit Ihrem Gerät kompatibel ist. Löschen Sie heruntergeladene Dateien in den Einstellungen, dann versuchen Sie es erneut.</string>
<string name="installation_invalid">Installation fehlgeschlagen, da die apk-Dateien beschädigt sind, bitte versuchen Sie es erneut.</string>
<string name="installation_signature">Installation fehlgeschlagen, da die apk Signaturüberprüfung aktiviert ist. Deaktivieren Sie die apk Signaturüberprüfung, dann versuchen Sie es erneut.</string>
<string name="installation_miui">Installation fehlgeschlagen, da die MIUI-Optimierung aktiviert ist. Deaktivieren Sie die MIUI-Optimierung, und versuchen Sie es erneut.</string>
<string name="installation_storage">Die Installation ist aufgrund eines Speicherfehlers fehlgeschlagen.</string>
<string name="modapk_missing">Apk-Datei für schwarz/dunkles Theme konnte nicht gefunden werden. Löschen Sie die App-Daten des Managers und versuchen Sie es erneut.</string>
<string name="modapk_missing">Apk-Datei für schwarzes/dunkles Theme konnte nicht gefunden werden. Löschen Sie die App-Daten des Managers und versuchen Sie es erneut.</string>
<string name="path_missing">Fehler beim Auffinden des YouTube-Installationspfades nach der geteilten Installation.</string>
</resources>

View file

@ -51,10 +51,12 @@
<string name="link_title">Χρήση προσαρμοσμένων καρτέλων Chrome</string>
<string name="link_custom_tabs">Οι σύνδεσμοι θα ανοίγουν σε προσαρμοσμένες καρτέλες chrome</string>
<string name="system_default">Προεπιλογή Συστήματος</string>
<string name="script_save_failed">Αποτυχία αποθήκευσης νέας τιμής χρόνου</string>
<string name="script_sleep_timer">Σενάριο Χρόνου Αδράνειας Root</string>
<string name="script_sleep_timer_description">Ρυθμίστε στην τιμη του χρόνου αδράνειας που βρίσκετε στο αρχείο σενάριο /data/adb/service.d/app.sh, χρήσιμο για επιδιόρθωση προβλημάτων προσάρτησης</string>
<string name="theme">Θέμα</string>
<string name="theme_dark">Σκουρόχρωμο Θέμα</string>
<string name="theme_light">Ανοιχτόχρωμο Θέμα</string>
<string name="update_url">Ενημερώστε το URL του καναλιού ενημέρωσης</string>
<string name="push_notifications">Ειδοποιήσεις Push για το %1$s</string>
<string name="push_notifications_summary">Λάβεται ειδοποιήσεις push όταν υπάρχουν διαθέσιμες ενημερώσεις για το %1$s</string>
<string name="update_center">Κέντρο ενημερώσεων</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Η εγκατάσταση απέτυχε διότι ο χρήστης ακύρωσε την εγκατάσταση.</string>
<string name="installation_blocked">Η εγκατάσταση απέτυχε διότι ο χρήστης απέκλεισε την εγκατάσταση.</string>
<string name="installation_downgrade">Η εγκατάσταση απέτυχε διότι ο χρήστης προσπάθησε να υποβαθμίσει το πακέτο. Απεγκαταστήστε τις ενημερώσεις της αρχικής εφαρμογής YouTube, στη συνέχεια προσπαθήστε ξανά.</string>
<string name="installation_conflict">Η εγκατάσταση απέτυχε διότι η εφαρμογή αντικρούεται με μια ήδη εγκατεστημένη εφαρμογή. Απεγκαταστήστε την τρέχουσα έκδοση της εφαρμογής, και μετά προσπαθήστε ξανά.</string>
<string name="installation_conflict">Η εγκατάσταση απέτυχε διότι η εφαρμογή αντικρούεται με μια ήδη εγκατεστημένη εφαρμογή. Κάντε απεγκατάσταση την τρέχουσα έκδοση της εφαρμογής, και μετά προσπαθήστε ξανά.</string>
<string name="installation_failed">Η εγκατάσταση απέτυχε για άγνωστους λόγους, παρακαλούμε μπείτε στο Telegram ή στο Discord μας για περαιτέρω βοήθεια.</string>
<string name="installation_incompatible">Η εγκατάσταση απέτυχε διότι το αρχείο εγκατάστασης είναι μη συμβατό με την συσκευή σας. Κάντε εκκαθάριση των ληφθέντων αρχείων στις ρυθμίσεις, στην συνέχεια προσπαθήστε ξανά.</string>
<string name="installation_invalid">Η εγκατάσταση απέτυχε διότι τα αρχεία apk έχουν διαφθαρεί, παρακαλώ προσπαθήστε ξανά.</string>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<!-- Global Strings -->
<string name="cancel">Cancelado</string>
<string name="cancel">Cancelar</string>
<string name="close">Cerrar</string>
<string name="reset">Restablecer</string>
<string name="save">Guardar</string>
@ -32,13 +32,13 @@
<string name="root_not_granted">Acceso root no concedido</string>
<string name="unavailable">No Disponible</string>
<string name="update">Actualizar</string>
<string name="social_media">Social Media</string>
<string name="support_us">Support us</string>
<string name="social_media">Redes Sociales</string>
<string name="support_us">Apóyanos</string>
<!-- Settings -->
<string name="accent_color">Color de Acento</string>
<string name="accent_blue">Azul</string>
<string name="accent_green">Verde</string>
<string name="accent_purple">Purpura</string>
<string name="accent_purple">Morado</string>
<string name="accent_red">Rojo</string>
<string name="accent_yellow">Amarillo</string>
<string name="category_appearance">Apariencia</string>
@ -51,10 +51,12 @@
<string name="link_title">Usar Chrome Custom Tabs</string>
<string name="link_custom_tabs">Links serán abiertos en Chrome Custom Tabs</string>
<string name="system_default">Predeterminado del sistema</string>
<string name="script_save_failed">Error al guardar el nuevo valor de tiempo</string>
<string name="script_sleep_timer">Script Root de Tiempo para Dormir</string>
<string name="script_sleep_timer_description">Ajustar el valor de tiempo para dormir en el script /data/adb/service.d/app.sh, útil para arreglar problemas de montaje</string>
<string name="theme">Tema</string>
<string name="theme_dark">Tema Oscuro</string>
<string name="theme_light">Tema Claro</string>
<string name="update_url">URL del canal de actualizacion</string>
<string name="push_notifications">Notificaciones push de %1$s</string>
<string name="push_notifications_summary">Recibir notificaciones push cuando una actualización para %1$s sea lanzada</string>
<string name="update_center">Centro de Actualizaciones</string>
@ -70,7 +72,7 @@
<string name="chosen_version">Versión: %1$s</string>
<string name="guide">Guía</string>
<string name="hold_on">¡Detente!</string>
<string name="magisk_vanced">Estás usando la versión Magisk/TWRP de Vanced, que está descontinuada y no se puede actualizar usando esta aplicación. Por favor, elimínelo eliminando el módulo Magisk o con el desinstalador TWRP Vanced.</string>
<string name="magisk_vanced">Estás usando la versión Magisk/TWRP de Vanced, la cual está descontinuada y no puede ser actualizada usando esta aplicación. Por favor, remuevala eliminando el módulo Magisk o usando el desinstalador TWRP Vanced.</string>
<string name="miui_one_title">MIUI detectado!</string>
<string name="miui_one">Para instalar Vanced, DEBES desactivar las optimizaciones de MIUI en las opciones de desarrollador. (Puedes omitir este paso si estás utilizando un ROM basado en xiaomi.eu 20.2.20 o posterior)</string>
<string name="error">Error</string>
@ -96,13 +98,13 @@
<string name="chown_fail">Fallo al ejecutar `chown` al propietario del sistema, por favor inténtalo de nuevo.</string>
<string name="error_downloading">Error al descargar %1$s</string>
<string name="failed_uninstall">Falla al desinstalar paquete %1$s</string>
<string name="failed_accent">No se pudo aplicar el nuevo color de acento</string>
<string name="failed_accent">Falla al aplicar el nuevo color de acento</string>
<string name="files_missing_va">Falla al localizar los archivos necesarios para la instalación. Vuelva a descargar los archivos de instalación y vuelva a intentarlo.</string>
<string name="ifile_missing">Falla al localizar en el almacenamiento el archivo apk para el tema negro/oscuro, por favor intente otra vez.</string>
<string name="installation_aborted">La instalación ha fallado debido a que el usuario ha abortado la instalación.</string>
<string name="installation_blocked">La instalación ha fallado debido a que el usuario bloqueo la instalación.</string>
<string name="installation_downgrade">La instalación ha fallado debido a que el usuario intento degradar el paquete. Desinstale las actualizaciones de la app original de YouTube y vuelva a intentarlo.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">La instalación ha fallado porque la aplicación entra en conflicto con una aplicación ya instalada. Desinstala la versión actual de la aplicación y vuelve a intentarlo.</string>
<string name="installation_failed">La instalación ha fallado por razones desconocidas, únete a nuestro grupo de Telegram o Discord para brindarte soporte.</string>
<string name="installation_incompatible">La instalación ha fallado porque el archivo de instalación es incompatible con tu dispositivo. Limpia los archivos descargados en la ajustes y vuelve a intentarlo.</string>
<string name="installation_invalid">La instalación falló porque los archivos apk están corruptos, por favor inténtalo de nuevo.</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">Kasuta Chrome kohandatud vahekaarte</string>
<string name="link_custom_tabs">Lingid avatakse Chrome kohandatud vahekaartides</string>
<string name="system_default">Süsteemi vaikimisi</string>
<string name="script_save_failed">Aja uue väärtuse salvestamine ebaõnnestus</string>
<string name="script_sleep_timer">Uneaja skript</string>
<string name="script_sleep_timer_description">Reguleerige uneaja väärtust, mis on kasutatav /data/adb/service.d/app.sh skriptis, see on kasulik paigaldusprobleemide parandamiseks</string>
<string name="theme">Kujundus</string>
<string name="theme_dark">Tume Kujundus</string>
<string name="theme_light">Hele Kujundus</string>
<string name="update_url">Uuenduskanali link</string>
<string name="push_notifications">%1$s Hüpikteated</string>
<string name="push_notifications_summary">Saa hüpikteateid kui %1$s uuendus on saadaval</string>
<string name="update_center">Halduri värskenduskeskus</string>

View file

@ -36,11 +36,11 @@
<string name="support_us">Support us</string>
<!-- Settings -->
<string name="accent_color">Aksenttiväri</string>
<string name="accent_blue">Sininen</string>
<string name="accent_green">Vihreä</string>
<string name="accent_purple">Violetti</string>
<string name="accent_red">Punainen</string>
<string name="accent_yellow">Keltainen</string>
<string name="accent_blue">Blue</string>
<string name="accent_green">Green</string>
<string name="accent_purple">Purple</string>
<string name="accent_red">Red</string>
<string name="accent_yellow">Yellow</string>
<string name="category_appearance">Ulkoasu</string>
<string name="category_behaviour">Käyttäytyminen</string>
<string name="clear_files">Tyhjennä ladatut tiedostot</string>
@ -51,10 +51,12 @@
<string name="link_title">Käytä Chromen mukautettuja välilehtiä</string>
<string name="link_custom_tabs">Linkit aukeavat Chromen mukautetuissa välilehdissä</string>
<string name="system_default">Järjestelmän oletus</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">Teema</string>
<string name="theme_dark">Tumma teema</string>
<string name="theme_light">Vaalea teema</string>
<string name="update_url">Päivityskanavan URL-osoite</string>
<string name="push_notifications">%1$s Push-ilmoitusta</string>
<string name="push_notifications_summary">Vastaanota push-ilmoituksia, kun %1$s:lle on julkaistu päivitys</string>
<string name="update_center">Managerin päivityskeskus</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Asennus epäonnistui, koska käyttäjä keskeytti asennuksen.</string>
<string name="installation_blocked">Asennus epäonnistui, koska käyttäjä on estänyt asennuksen.</string>
<string name="installation_downgrade">Asennus epäonnistui, koska käyttäjä yritti heikentää pakettia. Poista päivitykset YouTube-sovelluksesta ja yritä sitten uudelleen.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_failed">Asennus epäonnistui tuntemattomista syistä, liity Telegramiin tai Discordiin saadaksesi lisätukea.</string>
<string name="installation_incompatible">Asennus epäonnistui, koska asennustiedosto ei ole yhteensopiva laitteesi kanssa. Tyhjennä ladatut tiedostot asetuksista ja yritä uudelleen.</string>
<string name="installation_invalid">Asennus epäonnistui, koska APK-tiedostot ovat vioittuneet, yritä uudelleen.</string>

View file

@ -36,11 +36,11 @@
<string name="support_us">Support us</string>
<!-- Settings -->
<string name="accent_color">Kulay ng font</string>
<string name="accent_blue">Asul</string>
<string name="accent_green">Berde</string>
<string name="accent_purple">Lila</string>
<string name="accent_red">Pula</string>
<string name="accent_yellow">Dilaw</string>
<string name="accent_blue">Blue</string>
<string name="accent_green">Green</string>
<string name="accent_purple">Purple</string>
<string name="accent_red">Red</string>
<string name="accent_yellow">Yellow</string>
<string name="category_appearance">Hitsura</string>
<string name="category_behaviour">Kilos</string>
<string name="clear_files">Tanggalin ang naka-download na files</string>
@ -51,10 +51,12 @@
<string name="link_title">Gamitin ang Chrome Custom Tabs</string>
<string name="link_custom_tabs">Mabubuksan ang mga links sa Chrome Custom Tabs</string>
<string name="system_default">Sistemang Default</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">Tema</string>
<string name="theme_dark">Itim na tema</string>
<string name="theme_light">Puti na tema</string>
<string name="update_url">I-update ang Channel URL</string>
<string name="push_notifications">%1$s Push Notifications</string>
<string name="push_notifications_summary">Tumanggap ng push notifications kapag ang update sa %1$s ay nailabas</string>
<string name="update_center">Manager Update Center</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Nabigo ang pag-install dahil kinansela ito.</string>
<string name="installation_blocked">Nabigo ang pag-install dahil binlock ito.</string>
<string name="installation_downgrade">Nabigo ang pag-install dahil dinowngrade ng gumagamit ang pakete. I-uninstall ang mga updates galing sa stock Youtube app, at ulitin muli.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_failed">Nabigo ang pag-install dahil sa hindi tukoy na dahilan, makiisa sa aming Telegram o Discord para sa karagdagang suporta.</string>
<string name="installation_incompatible">Nabigo ang pag-install dahil ang installation file ay hindi tugma sa iyong device. Tanggalin ang mga downloaded files sa Settings, at ulitin muli.</string>
<string name="installation_invalid">Nabigo ang pag-install dahil ang mga apk files ay nasira, ulitin muli.</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">Utiliser les onglets personnalisés Chrome</string>
<string name="link_custom_tabs">Les liens s\'ouvriront dans les onglets personnalisés Chrome</string>
<string name="system_default">Système par défaut</string>
<string name="script_save_failed">Impossible d\'enregistrer la nouvelle valeur de temps</string>
<string name="script_sleep_timer">Définir un arrêt programmé</string>
<string name="script_sleep_timer_description">Ajuster la valeur de l\'heure de veille utilisée dans le script /data/adb/service.d/app.sh, utile pour résoudre les problèmes de montage</string>
<string name="theme">Thème</string>
<string name="theme_dark">Thème sombre</string>
<string name="theme_light">Thème clair</string>
<string name="update_url">URL du canal de mise à jour</string>
<string name="push_notifications">%1$s Notifications Push</string>
<string name="push_notifications_summary">Recevoir une notification push quand une nouvelle version pour %1$s est publiée</string>
<string name="update_center">Centre de mise à jour du Manager</string>

View file

@ -32,8 +32,8 @@
<string name="root_not_granted">रूट एक्सेस प्रदान नहीं किया गया</string>
<string name="unavailable">अनुपलब्ध</string>
<string name="update">अपडेट करें</string>
<string name="social_media">Social Media</string>
<string name="support_us">Support us</string>
<string name="social_media">सामाजिक नेटवर्क</string>
<string name="support_us">हमें सहयोग दीजिये</string>
<!-- Settings -->
<string name="accent_color">ऊपरी रंग</string>
<string name="accent_blue">नीला</string>
@ -51,10 +51,12 @@
<string name="link_title">क्रोम कस्टम टैब का उपयोग करें</string>
<string name="link_custom_tabs">क्रोम कस्टम टैब में लिंक खुलेंगे</string>
<string name="system_default">सिस्टम डिफ़ॉल्ट</string>
<string name="script_save_failed">नया समय मान सहेजने में विफल</string>
<string name="script_sleep_timer">रूट स्क्रिप्ट नींद का समय</string>
<string name="script_sleep_timer_description">बढ़ते मुद्दों को ठीक करने के लिए उपयोगी /data/adb/service.d/app.sh स्क्रिप्ट में उपयोग की गई नींद के समय को समायोजित करें</string>
<string name="theme">थीम</string>
<string name="theme_dark">डार्क थीम</string>
<string name="theme_light">लाइट थीम</string>
<string name="update_url">चैनल URL अपडेट करें</string>
<string name="push_notifications">%1$s पुश सूचनाएँ</string>
<string name="push_notifications_summary">जब %1$s का अपडेट जारी किया जाता है, तो पुश सूचनाएँ प्राप्त करें</string>
<string name="update_center">अपडेट केंद्र</string>
@ -96,13 +98,13 @@
<string name="chown_fail">सिस्टम के मालिक को APK को Chown करने में विफल, फिर से प्रयास करें।</string>
<string name="error_downloading">डाउनलोड करने में त्रुटि %1$s</string>
<string name="failed_uninstall">पैकेज की स्थापना रद्द करने में विफल %1$s</string>
<string name="failed_accent">Failed to apply new accent color</string>
<string name="failed_accent">नया उच्चारण रंग लागू करने में विफल</string>
<string name="files_missing_va">स्थापना के लिए आवश्यक फ़ाइलों का पता लगाने में विफल। स्थापना फ़ाइलों को फिर से डाउनलोड करें, फिर पुनः प्रयास करें।</string>
<string name="ifile_missing">भंडारण से काले / अंधेरे विषय के लिए apk फ़ाइल खोजने में विफल, कृपया पुनः प्रयास करें।</string>
<string name="installation_aborted">स्थापना विफल रही क्योंकि उपयोगकर्ता ने स्थापना रद्द कर दी।</string>
<string name="installation_blocked">स्थापना विफल रही क्योंकि उपयोगकर्ता ने स्थापना को ब्लॉक कर दिया।</string>
<string name="installation_downgrade">स्थापना विफल रही क्योंकि उपयोगकर्ता ने पैकेज को डाउनग्रेड करने का प्रयास किया। असली YouTube ऐप से अपडेट अनइंस्टॉल करें, फिर प्रयास करें।</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">इंस्टॉलेशन विफल रहा क्योंकि ऐप पहले से इंस्टॉल किए गए ऐप के साथ टकराव करता है। एप्लिकेशन के वर्तमान संस्करण को अनइंस्टॉल करें, फिर प्रयास करें।</string>
<string name="installation_failed">अज्ञात कारणों से स्थापना विफल हो गई, आगे के समर्थन के लिए हमारे टेलीग्राम या डिसॉर्ड में शामिल हों।</string>
<string name="installation_incompatible">इंस्टॉलेशन विफल हो गया क्योंकि इंस्टॉलेशन फ़ाइल आपके डिवाइस के साथ असंगत है। सेटिंग्स में डाउनलोड की गई फ़ाइलों को साफ़ करें, फिर प्रयास करें।</string>
<string name="installation_invalid">स्थापना विफल रही क्योंकि एपीके फ़ाइलें दूषित हैं, कृपया पुनः प्रयास करें।</string>

View file

@ -10,7 +10,7 @@
<string name="title_about">O autorima</string>
<string name="title_home">Upravitelj</string>
<string name="title_settings">Postavke</string>
<string name="update_manager">Ažuriraj upravitelja</string>
<string name="update_manager">Ažuriranje upravitelja</string>
<!-- Welcome Page -->
<string name="are_you_rooted">Je li vaš uređaj rootan?</string>
<string name="grant_root">Dopusti root dozvolu</string>
@ -18,7 +18,7 @@
<string name="select_apps_music">Vanced, ali za YouTube Glazbu!\nS manje značajki ali tako da ispunjava vaše potrebe.</string>
<string name="select_apps_vanced">YouTube Vanced je izvorna Android YouTube aplikacija, ali mnogo bolja!</string>
<string name="lets_get_started">Započnite</string>
<string name="willing_to_use_root">Ne znate što je ovo ili ne želite koristiti root inačicu? Jednostavno kliknite na plavu strelicu ispod!</string>
<string name="willing_to_use_root">Ne znate što je ovo ili ne želite koristiti root izdanje? Jednostavno kliknite na plavu strelicu ispod!</string>
<!-- Home Page -->
<string name="about_app">O %1$s</string>
<string name="app_changelog_tooltip">Dodirnite karticu kako bi vidjeli zapis promjena.</string>
@ -32,8 +32,8 @@
<string name="root_not_granted">Root pristup nije dopušten</string>
<string name="unavailable">Nedostupno</string>
<string name="update">Ažuriraj</string>
<string name="social_media">Social Media</string>
<string name="support_us">Support us</string>
<string name="social_media">Društvene mreže</string>
<string name="support_us">Podržite nas</string>
<!-- Settings -->
<string name="accent_color">Boja naglašavanja</string>
<string name="accent_blue">Plava</string>
@ -50,16 +50,18 @@
<string name="language_title">Jezik</string>
<string name="link_title">Koristi prilagođene kartice Chroma</string>
<string name="link_custom_tabs">Poveznice će se otvarati u prilagođenim karticama Chroma</string>
<string name="system_default">Zadan sustavom</string>
<string name="system_default">Zadano sustavom</string>
<string name="script_save_failed">Failed to save new time value</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">Tema</string>
<string name="theme_dark">Tamna tema</string>
<string name="theme_light">Svjetla tema</string>
<string name="update_url">Ažuriraj URL kanala</string>
<string name="push_notifications">%1$s skočnih obavijesti</string>
<string name="push_notifications">%1$s skočne obavijesti</string>
<string name="push_notifications_summary">Primite skočnu obavijest kada je ažuriranje za %1$s dostupno</string>
<string name="update_center">Središte ažuriranja upravitelja</string>
<string name="update_not_found">Nema novih ažuriranja</string>
<string name="variant">Inačica</string>
<string name="variant">Izdanje</string>
<!-- Dialogs -->
<string name="advanced">Napredno</string>
<string name="app_install_files_detected">%1$s instalacijska datoteka je otkrivena!</string>
@ -89,7 +91,7 @@
<string name="light_plus_other">Svjetla + %1$s</string>
<string name="select_at_least_one_lang">Odaberite najmanje jedan jezik!</string>
<!-- About Page -->
<string name="manager_dev">Manager razvijatelji</string>
<string name="manager_dev">Razvijatelji Vanced upravitelja</string>
<string name="sources">Izvori</string>
<string name="vanced_team">Vanced tim</string>
<!-- Error messages -->
@ -102,7 +104,7 @@
<string name="installation_aborted">Instalacija je prekinuta zato jer ju je korisnik prekinuo.</string>
<string name="installation_blocked">Instalacija nije uspjela jer je korisnik blokirao instalaciju.</string>
<string name="installation_downgrade">Instalacija nije uspjela jer je korisnik pokušao instalirati stariju inačicu paketa. Deinstalirajte ažuriranja izvorne YouTube aplikacije, zatim pokušajte ponovno.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">Instalacija nije uspjela jer je aplikacija u sukobu s već instaliranom aplikacijom. Deinstalirajte trenutnu inačicu aplikacije zatim pokušajte ponovno.</string>
<string name="installation_failed">Instalacija nije uspjela iz nepoznatih razloga, pridružite nam se na Telegramu ili Discordu za daljnju podršku.</string>
<string name="installation_incompatible">Instalacija nije uspjela zato jer datoteka instalacije nije kompatibilna s vašim uređajem. Uklonite preuzete datoteke u postavkama, zatim pokušajte ponovno.</string>
<string name="installation_invalid">Instalacija nije uspjela zato jer je apk datoteka oštećena.</string>

View file

@ -15,8 +15,8 @@
<string name="are_you_rooted">Rootolt az eszközöd?</string>
<string name="grant_root">Root hozzáférés engedélyezése</string>
<string name="select_at_least_one_app">Legalább egy appot válassz!</string>
<string name="select_apps_music">Vanced a YouTube Music-ra!\nkevesebb funkciő, de minden ami kellhet.</string>
<string name="select_apps_vanced">A Youtube Vanced egy gyári Android YouTube alkalmazás, csak jobb!</string>
<string name="select_apps_music">Vanced, a YouTube Music-ra!\nKevésbé funkciógazdag, de kielégíti az igényeidet.</string>
<string name="select_apps_vanced">A Youtube Vanced a gyári Android YouTube alkalmazás, csak jobb nála!</string>
<string name="lets_get_started">Lássunk neki</string>
<string name="willing_to_use_root">Nem tudod mi ez vagy csak nem akarod használni a root verziót? Csak kattins a lenti kék nyílra!</string>
<!-- Home Page -->
@ -29,11 +29,11 @@
<string name="version_installed">Telepítve:</string>
<string name="latest">Legújabb:</string>
<string name="no_microg">microG nincs telepítve</string>
<string name="root_not_granted">Nincs root jogosultság</string>
<string name="root_not_granted">A root hozzáférés nincs megadva</string>
<string name="unavailable">Nem elérhető</string>
<string name="update">Frissítés</string>
<string name="social_media">Social Media</string>
<string name="support_us">Support us</string>
<string name="social_media">Közösségi média</string>
<string name="support_us">Támogass minket</string>
<!-- Settings -->
<string name="accent_color">Kiemelés színe</string>
<string name="accent_blue">Kék</string>
@ -51,10 +51,12 @@
<string name="link_title">Egyéni Chrome lapok használata</string>
<string name="link_custom_tabs">A linkek egyéni Chrome ablakban nyílnak meg</string>
<string name="system_default">Rendszer alapértelmezett</string>
<string name="script_save_failed">Nem sikerült az időzítő új értékének mentése</string>
<string name="script_sleep_timer">Alvás idő script (Root)</string>
<string name="script_sleep_timer_description">Alvás idő beállítás a /data/adb/service.d/app.sh scriptben, hasznos a csatlakoztatási problémák javítására</string>
<string name="theme">Kinézet</string>
<string name="theme_dark">Sötét téma</string>
<string name="theme_light">Világos téma</string>
<string name="update_url">Frissítési csatorna</string>
<string name="push_notifications">%1$s Leküldéses (Push) Értesítések</string>
<string name="push_notifications_summary">Értesítések fogadása, amikor a %1$s számára frissítés érhető el</string>
<string name="update_center">Frissítő központ</string>
@ -97,14 +99,14 @@ Akarod telepíteni?</string>
<string name="chown_fail">Nem sikerült az APK beállítása a rendszer tulajdonoshoz, kérjük próbálja újra.</string>
<string name="error_downloading">%1$s letöltése nem sikerült</string>
<string name="failed_uninstall">A %1$s-t nem sikerült eltávolítani</string>
<string name="failed_accent">Failed to apply new accent color</string>
<string name="failed_accent">Nem sikerült az új kiemelés szín beállítása</string>
<string name="files_missing_va">A telepítéshez szükséges file-ok megtalálása meghiúsult. Töltse le újra a telepítőfile-okat és próbálja újra.</string>
<string name="ifile_missing">Nem sikerült az apk file-t megtalálni a fekete/sötét kinézethez, kérjük próbálja újra.</string>
<string name="installation_aborted">A művelet végrehajtása nem sikerült, mert a felhasználó megszakította a telepítést.</string>
<string name="installation_blocked">A telepítés nem sikerült, mert a felhasználó megszakította azt.</string>
<string name="installation_downgrade">A telepítés nem sikerült, mert a felhasználó régebbi verziót próbált telepíteni.
Távolítsd el a gyári YouTube app frissítéseit, majd próbáld újra.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">A telepítés nem sikerült, mert az alkalmazás egy másik, már telepített alkalmazással ütközik. Távolítsd el a jelenlegi verziót és próbáld újra.</string>
<string name="installation_failed">A telepítés ismeretlen okok miatt nem sikerült, támogatásért csatlakozz a Telegram vagy a Discord csoportunkhoz.</string>
<string name="installation_incompatible">A telepítés nem sikerült, mert a telepítő fájl nem kompatibilis az eszközöddel. Töröld ki a letöltött fájlokat a beállításokban és próbáld újra.</string>
<string name="installation_invalid">A telepítés nem sikerült, mert az apk fájlok korruptak, próbáld újra.</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">Gunakan Chrome Custom Tabs</string>
<string name="link_custom_tabs">Tautan akan terbuka di Chrome Custom Tabs</string>
<string name="system_default">Standar Sistem</string>
<string name="script_save_failed">Gagal untuk menyimpan nilai waktu baru</string>
<string name="script_sleep_timer">Waktu Root Script Sleep</string>
<string name="script_sleep_timer_description">Sesuaikan nilai sleep time yang digunakan dalam skript /data/adb/service.d/app.sh, berguna untuk memperbaiki masalah pemasangan</string>
<string name="theme">Tema</string>
<string name="theme_dark">Tema Gelap</string>
<string name="theme_light">Tema Terang</string>
<string name="update_url">Perbarui URL Channel</string>
<string name="push_notifications">Notifikasi Push %1$s</string>
<string name="push_notifications_summary">Terima notifikasi push saat pembaruan untuk %1$s dirilis</string>
<string name="update_center">Pusat Pembaruan Manager</string>
@ -62,7 +64,7 @@
<string name="variant">Varian</string>
<!-- Dialogs -->
<string name="advanced">Tingkat Lanjut</string>
<string name="app_install_files_detected">%1$s file instalasi terdeteksi!</string>
<string name="app_install_files_detected">File instalasi %1$s terdeteksi!</string>
<string name="app_install_files_detected_summary">Manager mendeteksi bahwa semua file yang diperlukan untuk instalasi %1$s ditemukan. Apakah anda ingin memasangnya?</string>
<string name="checking_updates">Memeriksa pembaruan…</string>
<string name="chosen_lang">Bahasa: %1$s</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Pemasangan gagal karena pengguna membatalkan pemasangan.</string>
<string name="installation_blocked">Pemasangan gagal karena pengguna memblokir pemasangan.</string>
<string name="installation_downgrade">Pemasangan gagal karena pengguna mencoba untuk menurunkan versi paket. Hapus pembaruan dari aplikasi YouTube bawaan, lalu coba lagi.</string>
<string name="installation_conflict">Pemasangan gagal dikarenakan aplikasi konflik dengan aplikasi yang sudah terpasang. Hapus versi aplikasi yang sekarang, lalu coba lagi.</string>
<string name="installation_conflict">Pemasangan gagal karena aplikasi konflik dengan aplikasi yang sudah terpasang. Copot pemasangan aplikasi versi saat ini, lalu coba lagi.</string>
<string name="installation_failed">Pemasangan gagal untuk alasan yang tidak diketahui, gabung Telegram atau Discord kami untuk bantuan lebih lanjut.</string>
<string name="installation_incompatible">Pemasangan gagal karena file pemasangan tidak kompatibel dengan perangkat anda. Hapus file yang diunduh di pengaturan, lalu coba lagi.</string>
<string name="installation_invalid">Pemasangan gagal karena file apk rusak, mohon coba lagi.</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">Utilizza le Schede Personalizzate di Chrome</string>
<string name="link_custom_tabs">I link verranno aperti nelle Schede Personalizzate di Chrome</string>
<string name="system_default">Predefinito di Sistema</string>
<string name="script_save_failed">Impossibile salvare il nuovo valore temporale</string>
<string name="script_sleep_timer">Tempo Di Sospensione Script Root</string>
<string name="script_sleep_timer_description">Regola il valore del tempo di sospensione utilizzato nello script /data/adb/service.d/app.sh, utile per risolvere i problemi di montaggio</string>
<string name="theme">Tema</string>
<string name="theme_dark">Tema Scuro</string>
<string name="theme_light">Tema Chiaro</string>
<string name="update_url">Aggiorna l\'URL del Canale</string>
<string name="push_notifications">Notifiche Push di %1$s</string>
<string name="push_notifications_summary">Ricevi notifiche push quando un aggiornamento per %1$s è disponibile</string>
<string name="update_center">Centro Aggiornamenti</string>
@ -102,7 +104,7 @@
<string name="installation_aborted">Installazione non riuscita. L\'utente ha annullato l\'installazione.</string>
<string name="installation_blocked">Installazione non riuscita. L\'utente ha bloccato l\'installazione.</string>
<string name="installation_downgrade">Installazione non riuscita. L\'utente ha provato ad eseguire il downgrade del pacchetto. Disinstalla gli aggiornamenti dell\'app predefinita di YouTube, poi riprova.</string>
<string name="installation_conflict">Installazione fallita a causa di conflitti con un\'app già installata. Disinstalla la versione corrente dell\'app, quindi riprova.</string>
<string name="installation_conflict">Installazione fallita perché l\'applicazione è in conflitto con un\'app già installata. Disinstallare la versione corrente dell\'applicazione, quindi riprovare.</string>
<string name="installation_failed">Installazione non riuscita a causa di un errore sconosciuto, unisciti al nostro gruppo Telegram o al server di Discord per ricevere ulteriore assistenza.</string>
<string name="installation_incompatible">Installazione non riuscita, il file di installazione non è compatibile con il tuo dispositivo. Elimina i file scaricati nelle impostazioni, poi riprova.</string>
<string name="installation_invalid">Installazione non riuscita a causa di file apk corrotti, si prega di riprovare.</string>

View file

@ -51,10 +51,12 @@
<string name="link_title">השתמש בכרטיסייה מותאמת אישית של Chrome</string>
<string name="link_custom_tabs">קישורים יפתחו בכרטיסיות מותאמות אישית של Chrome</string>
<string name="system_default">ברירת מחדל</string>
<string name="script_save_failed">נכשל בשמירת ערך הזמן החדש</string>
<string name="script_sleep_timer">Root Script Sleep Time</string>
<string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string>
<string name="theme">ערכת נושא</string>
<string name="theme_dark">ערכת נושא כהה</string>
<string name="theme_light">ערכת נושא בהירה</string>
<string name="update_url">עדכן את כתובת האתר של הערוץ</string>
<string name="push_notifications">%1$s התראות דחיפה</string>
<string name="push_notifications_summary">קבל התראות דחיפה כשעדכון ל־%1$s משתחרר</string>
<string name="update_center">מרכז העדכונים</string>
@ -96,13 +98,13 @@
<string name="chown_fail">נכשל בהחלפת הבעלים של קובץ ה־APK, אנא נסה בשנית.</string>
<string name="error_downloading">תקלה בהורדה של %1$s</string>
<string name="failed_uninstall">נכשל במחיקת החבילה %1$s</string>
<string name="failed_accent">Failed to apply new accent color</string>
<string name="failed_accent">נכשל בהחלת ערכת הנושא החדשה</string>
<string name="files_missing_va">איתור הקבצים הנדרשים להתקנה נכשל. הורד מחדש את קבצי ההתקנה ונסה שוב.</string>
<string name="ifile_missing">נכשל האיתור של קובץ APK לערכת נושא שחורה/כהה מהאחסון, אנא נסה שוב.</string>
<string name="installation_aborted">ההתקנה נכשלה כיוון שהמשתמש ביטל אותה.</string>
<string name="installation_blocked">ההתקנה נכשלה כיוון שהמשתמש חסם אותה.</string>
<string name="installation_downgrade">ההתקנה נכשלה כיוון שהמשתמש ניסה לשנמך את גרסת האפליקציה. מחק עדכונים מאפליקציית YouTube הרגילה, ולאחר מכן נסה שוב.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string>
<string name="installation_conflict">ההתקנה נכשלה כיוון שהאפליקציה מתנגשת עם גרסה מותקנת שלה, מחק את הגרסה הנוכחית של Vanced ולאחר מכן נסה שוב.</string>
<string name="installation_failed">הפעולה נכשלה בגלל סיבה אינה ידועה, בבקשה הצטרפו לטלגרם או דיסקורד שלנו בשביל עזרה.</string>
<string name="installation_incompatible">ההתקנה נכשלה מכיוון שההתקנה או הקובץ לא תואמים עם מכשירך. נקה הורדות שהושלמו מתוך ההגדרות, ואז נסה שוב.</string>
<string name="installation_invalid">ההתקנה נכשלה מכיוון שקבצי הישום הרוסים, בבקשה נסה שוב.</string>

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