fixed conflict

This commit is contained in:
Xinto 2020-11-15 14:24:32 +04:00
commit 411bb08ba3
40 changed files with 759 additions and 764 deletions

View File

@ -53,6 +53,7 @@ android {
buildFeatures { buildFeatures {
dataBinding true dataBinding true
viewBinding true
} }
// To inline the bytecode built with JVM target 1.8 into // To inline the bytecode built with JVM target 1.8 into
@ -120,7 +121,6 @@ dependencies {
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'com.google.android.material:material:1.3.0-alpha03' implementation 'com.google.android.material:material:1.3.0-alpha03'
// Other
// JSON parser // JSON parser
implementation 'com.beust:klaxon:5.4' implementation 'com.beust:klaxon:5.4'

View File

@ -11,13 +11,15 @@ import com.crowdin.platform.data.remote.NetworkType
import com.downloader.PRDownloader import com.downloader.PRDownloader
import com.vanced.manager.BuildConfig.* import com.vanced.manager.BuildConfig.*
import com.vanced.manager.utils.InternetTools.loadJson import com.vanced.manager.utils.InternetTools.loadJson
import kotlinx.coroutines.*
open class App: Application() { open class App: Application() {
private val prefs by lazy { getDefaultSharedPreferences(this) } private val prefs by lazy { getDefaultSharedPreferences(this) }
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
override fun onCreate() { override fun onCreate() {
loadJson(this) scope.launch { loadJson(this@App) }
super.onCreate() super.onCreate()
PRDownloader.initialize(this) PRDownloader.initialize(this)
@ -46,6 +48,4 @@ open class App: Application() {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
Crowdin.onConfigurationChanged() Crowdin.onConfigurationChanged()
} }
} }

View File

@ -13,22 +13,21 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
object MicrogDownloader { object MicrogDownloader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun downloadMicrog( fun downloadMicrog(
context: Context, context: Context,
) { ) = launch {
CoroutineScope(Dispatchers.IO).launch { val url = microg.get()?.string("url")
val url = microg.get()?.string("url")
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk") downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk")
.build() .build()
.setOnStartOrResumeListener { .setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) })) downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) }))
} }
.setOnProgressListener { progress -> .setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt())
} }
.start(object : OnDownloadListener { .start(object : OnDownloadListener {
override fun onDownloadComplete() { override fun onDownloadComplete() {
startMicrogInstall(context) startMicrogInstall(context)
@ -40,12 +39,10 @@ object MicrogDownloader {
}) })
} }
}
fun startMicrogInstall(context: Context) { fun startMicrogInstall(context: Context) {
downloadProgress.get()?.installing?.set(true) downloadProgress.get()?.installing?.set(true)
downloadProgress.get()?.reset() downloadProgress.get()?.reset()
install("${context.getExternalFilesDir("microg")}/microg.apk", context) install("${context.getExternalFilesDir("microg")}/microg.apk", context)
} }
} }

View File

@ -1,7 +1,7 @@
package com.vanced.manager.core.downloader package com.vanced.manager.core.downloader
import android.content.Context import android.content.Context
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.*
import com.downloader.Error import com.downloader.Error
import com.downloader.OnDownloadListener import com.downloader.OnDownloadListener
import com.downloader.PRDownloader import com.downloader.PRDownloader
@ -22,8 +22,9 @@ import com.vanced.manager.utils.PackageHelper.installMusicRoot
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.coroutines.suspendCoroutine
object MusicDownloader { object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
private var variant: String? = null private var variant: String? = null
private var version: String? = null private var version: String? = null
@ -45,60 +46,56 @@ object MusicDownloader {
} }
private fun downloadApk(context: Context, apk: String = "music") { private fun downloadApk(context: Context, apk: String = "music") {
CoroutineScope(Dispatchers.IO).launch { launch {
val url = val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
if (apk == "stock") suspendCoroutine {
"$baseurl/stock/${getArch()}.apk" downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
else .build()
"$baseurl/$variant.apk" .setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url)))
downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) }
.build() .setOnProgressListener { progress ->
.setOnStartOrResumeListener { downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt())
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url))) }
} .start(object : OnDownloadListener {
.setOnProgressListener { progress -> override fun onDownloadComplete() {
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) if (variant == "root" && apk != "stock") {
} downloadApk(context, "stock") // recursive in coroutine its so bad...
.start(object : OnDownloadListener { return
override fun onDownloadComplete() {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock")
return
}
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
} }
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
}
}
startMusicInstall(context)
} }
startMusicInstall(context) override fun onError(error: Error?) {
} if (baseurl != backupUrl) {
baseurl = "$backupUrl/music/v$version"
downloadApk(context, apk)
return
}
override fun onError(error: Error?) { downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "Music"))
if (baseurl != backupUrl) {
baseurl = "$backupUrl/music/v$version"
downloadApk(context, apk)
return
} }
})
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "Music")) }
}
})
} }
} }
fun startMusicInstall(context: Context) { fun startMusicInstall(context: Context) {
@ -109,5 +106,4 @@ object MusicDownloader {
else else
install("${context.getExternalFilesDir("music/nonroot")}/nonroot.apk", context) install("${context.getExternalFilesDir("music/nonroot")}/nonroot.apk", context)
} }
} }

View File

@ -28,7 +28,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
object VancedDownloader { object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
private lateinit var prefs: SharedPreferences private lateinit var prefs: SharedPreferences
private lateinit var defPrefs: SharedPreferences private lateinit var defPrefs: SharedPreferences
@ -36,7 +36,7 @@ object VancedDownloader {
private var installUrl: String? = null private var installUrl: String? = null
private var variant: String? = null private var variant: String? = null
private var theme: String? = null private var theme: String? = null
private var lang: MutableList<String>? = null private var lang = mutableListOf<String>()
private lateinit var themePath: String private lateinit var themePath: String
@ -56,7 +56,9 @@ object VancedDownloader {
downloadPath = context.getExternalFilesDir("vanced/$variant")?.path downloadPath = context.getExternalFilesDir("vanced/$variant")?.path
File(downloadPath.toString()).deleteRecursively() File(downloadPath.toString()).deleteRecursively()
installUrl = defPrefs.getInstallUrl() installUrl = defPrefs.getInstallUrl()
lang = prefs.getString("lang", getDefaultVancedLanguages())?.split(", ")?.toMutableList() prefs.getString("lang", getDefaultVancedLanguages())?.let {
lang = it.split(", ").toMutableList()
}
theme = prefs.getString("theme", "dark") theme = prefs.getString("theme", "dark")
vancedVersion = defPrefs.getString("vanced_version", "latest")?.getLatestAppVersion(vancedVersions.get()?.value ?: listOf("")) vancedVersion = defPrefs.getString("vanced_version", "latest")?.getLatestAppVersion(vancedVersions.get()?.value ?: listOf(""))
themePath = "$installUrl/apks/v$vancedVersion/$variant/Theme" themePath = "$installUrl/apks/v$vancedVersion/$variant/Theme"
@ -73,7 +75,7 @@ object VancedDownloader {
context: Context, context: Context,
type: String = "theme" type: String = "theme"
) { ) {
CoroutineScope(Dispatchers.IO).launch { launch {
val url = val url =
when (type) { when (type) {
"theme" -> "$themePath/$theme.apk" "theme" -> "$themePath/$theme.apk"
@ -112,7 +114,7 @@ object VancedDownloader {
"lang" -> { "lang" -> {
count++ count++
succesfulLangCount++ succesfulLangCount++
if (count < lang?.size!!) if (count < lang.size)
downloadSplits(context, "lang") downloadSplits(context, "lang")
else else
startVancedInstall(context) startVancedInstall(context)
@ -132,9 +134,9 @@ object VancedDownloader {
if (type == "lang") { if (type == "lang") {
count++ count++
when { when {
count < lang?.size!! -> downloadSplits(context, "lang") count < lang.size -> downloadSplits(context, "lang")
succesfulLangCount == 0 -> { succesfulLangCount == 0 -> {
lang?.add("en") lang.add("en")
downloadSplits(context, "lang") downloadSplits(context, "lang")
} }
else -> startVancedInstall(context) else -> startVancedInstall(context)
@ -160,8 +162,4 @@ object VancedDownloader {
else else
installVanced(context) installVanced(context)
} }
}
}

View File

@ -0,0 +1,15 @@
package com.vanced.manager.core.ext
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import kotlin.reflect.full.createInstance
fun Fragment.requireSupportFM() = requireActivity().supportFragmentManager
inline fun <reified D : DialogFragment> Fragment.showDialogRefl() {
D::class.createInstance().show(requireSupportFM(), D::class.simpleName)
}
fun <D : DialogFragment> Fragment.showDialog(dialog: D) {
dialog.show(requireSupportFM(), dialog::class.simpleName)
}

View File

@ -0,0 +1,37 @@
package com.vanced.manager.ui.core
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
abstract class BindingFragment<VB : ViewBinding> : Fragment() {
private var _binding: VB? = null
protected val binding: VB get() = requireNotNull(_binding)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = binding(inflater, container, savedInstanceState)
otherSetups()
return binding.root
}
protected abstract fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): VB
protected open fun otherSetups() = Unit
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.vanced.manager.R import com.vanced.manager.R
@ -13,6 +14,7 @@ import com.vanced.manager.core.downloader.MusicDownloader.startMusicInstall
import com.vanced.manager.core.downloader.VancedDownloader.startVancedInstall import com.vanced.manager.core.downloader.VancedDownloader.startVancedInstall
import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding
import com.vanced.manager.utils.Extensions.show import com.vanced.manager.utils.Extensions.show
import kotlinx.coroutines.launch
class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() { class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() {

View File

@ -12,6 +12,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader import com.downloader.PRDownloader
import com.vanced.manager.R import com.vanced.manager.R
@ -19,6 +20,7 @@ import com.vanced.manager.databinding.DialogManagerUpdateBinding
import com.vanced.manager.utils.DownloadHelper.downloadManager import com.vanced.manager.utils.DownloadHelper.downloadManager
import com.vanced.manager.utils.DownloadHelper.downloadProgress import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.isUpdateAvailable import com.vanced.manager.utils.InternetTools.isUpdateAvailable
import kotlinx.coroutines.launch
class ManagerUpdateDialog( class ManagerUpdateDialog(
private val forceUpdate: Boolean private val forceUpdate: Boolean
@ -51,15 +53,18 @@ class ManagerUpdateDialog(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
if (forceUpdate) { lifecycleScope.launch {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient) if (forceUpdate) {
downloadManager(requireActivity()) binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
} else downloadManager(requireActivity())
checkUpdates() } else {
checkUpdates()
}
binding.managerUpdateCancel.setOnClickListener { binding.managerUpdateCancel.setOnClickListener {
PRDownloader.cancel(downloadProgress.get()!!.currentDownload) PRDownloader.cancel(downloadProgress.get()!!.currentDownload)
dismiss() dismiss()
}
} }
} }
@ -68,12 +73,13 @@ class ManagerUpdateDialog(
registerReceiver() registerReceiver()
} }
private fun checkUpdates() { private suspend fun checkUpdates() {
if (isUpdateAvailable()) { if (isUpdateAvailable()) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient) binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity()) downloadManager(requireActivity())
} else } else {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.update_not_found) binding.managerUpdatePatient.text = requireActivity().getString(R.string.update_not_found)
}
} }
private fun registerReceiver() { private fun registerReceiver() {

View File

@ -10,11 +10,13 @@ import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import androidx.core.content.edit import androidx.core.content.edit
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.fetchData import com.vanced.manager.utils.Extensions.fetchData
import com.vanced.manager.utils.InternetTools.baseUrl import com.vanced.manager.utils.InternetTools.baseUrl
import kotlinx.coroutines.launch
class URLChangeDialog : DialogFragment() { class URLChangeDialog : DialogFragment() {
@ -46,9 +48,10 @@ class URLChangeDialog : DialogFragment() {
} }
private fun saveUrl(url: String) { private fun saveUrl(url: String) {
getDefaultSharedPreferences(requireActivity()).edit { putString("install_url", url) } lifecycleScope.launch {
requireActivity().fetchData() getDefaultSharedPreferences(requireActivity()).edit { putString("install_url", url) }
dismiss() requireActivity().fetchData()
dismiss()
}
} }
} }

View File

@ -12,6 +12,8 @@ import android.widget.LinearLayout
import android.widget.Toast import android.widget.Toast
import androidx.core.content.edit import androidx.core.content.edit
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.checkbox.MaterialCheckBox import com.google.android.material.checkbox.MaterialCheckBox
@ -23,6 +25,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.* import java.util.*
import kotlin.coroutines.coroutineContext
class VancedLanguageSelectionDialog : BottomSheetDialogFragment() { class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
@ -36,7 +39,6 @@ class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
return inflater.inflate(R.layout.dialog_vanced_language_selection, container, false) return inflater.inflate(R.layout.dialog_vanced_language_selection, container, false)
} }
@ExperimentalStdlibApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
langs = vanced.get()?.array<String>("langs")?.value ?: mutableListOf("null") langs = vanced.get()?.array<String>("langs")?.value ?: mutableListOf("null")
@ -60,9 +62,8 @@ class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
} }
} }
@ExperimentalStdlibApi
private fun loadBoxes(ll: LinearLayout) { private fun loadBoxes(ll: LinearLayout) {
CoroutineScope(Dispatchers.Main).launch { lifecycleScope.launch { // default Main //// But why is it here?
val langPrefs = prefs.getString("lang", getDefaultVancedLanguages()) val langPrefs = prefs.getString("lang", getDefaultVancedLanguages())
if (this@VancedLanguageSelectionDialog::langs.isInitialized) { if (this@VancedLanguageSelectionDialog::langs.isInitialized) {
if (!langs.contains("null")) { if (!langs.contains("null")) {
@ -70,7 +71,7 @@ class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
val loc = Locale(lang) val loc = Locale(lang)
val box: MaterialCheckBox = MaterialCheckBox(requireActivity()).apply { val box: MaterialCheckBox = MaterialCheckBox(requireActivity()).apply {
tag = lang tag = lang
isChecked = langPrefs!!.contains(lang) isChecked = langPrefs?.contains(lang) ?: false
text = loc.getDisplayLanguage(loc).capitalize(Locale.ROOT) text = loc.getDisplayLanguage(loc).capitalize(Locale.ROOT)
textSize = 18F textSize = 18F
typeface = ResourcesCompat.getFont(requireActivity(), R.font.exo_bold) typeface = ResourcesCompat.getFont(requireActivity(), R.font.exo_bold)
@ -78,8 +79,9 @@ class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
ll.addView(box, MATCH_PARENT, WRAP_CONTENT) ll.addView(box, MATCH_PARENT, WRAP_CONTENT)
} }
} }
} else } else {
loadBoxes(ll) loadBoxes(ll)
}
} }
} }

View File

@ -4,46 +4,41 @@ import android.annotation.SuppressLint
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.edit import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.databinding.FragmentAboutBinding import com.vanced.manager.databinding.FragmentAboutBinding
import com.vanced.manager.ui.dialogs.AppInfoDialog import com.vanced.manager.ui.dialogs.AppInfoDialog
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.viewmodels.AboutViewModel import com.vanced.manager.ui.viewmodels.AboutViewModel
import com.vanced.manager.utils.Extensions.show import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.utils.InternetTools.manager import com.vanced.manager.utils.InternetTools.manager
class AboutFragment : Fragment() { class AboutFragment : BindingFragment<FragmentAboutBinding>() {
private lateinit var binding: FragmentAboutBinding
private val viewModel: AboutViewModel by viewModels() private val viewModel: AboutViewModel by viewModels()
private var count = 0 private var count = 0
private var startMillSec: Long = 0 private var startMillSec: Long = 0
override fun onCreateView( override fun binding(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = FragmentAboutBinding.inflate(inflater, container, false)
requireActivity().title = getString(R.string.title_about)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_about, container, false) override fun otherSetups() {
binding.viewModel = viewModel dataBind()
return binding.root
} }
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { private fun dataBind() {
super.onViewCreated(view, savedInstanceState) requireActivity().title = getString(R.string.title_about)
binding.aboutHeader.setOnClickListener { AppInfoDialog(getString(R.string.app_name), AppCompatResources.getDrawable(requireActivity(), R.mipmap.ic_launcher), manager.get()?.string("changelog")).show(requireActivity()) } binding.aboutHeader.root.setOnClickListener { AppInfoDialog(getString(R.string.app_name), AppCompatResources.getDrawable(requireActivity(), R.mipmap.ic_launcher), manager.get()?.string("changelog")).show(requireActivity()) }
view.setOnTouchListener { _, event: MotionEvent -> binding.root.setOnTouchListener { _, event: MotionEvent ->
val eventAction = event.action val eventAction = event.action
if (eventAction == MotionEvent.ACTION_UP) { if (eventAction == MotionEvent.ACTION_UP) {
val time = System.currentTimeMillis() val time = System.currentTimeMillis()
@ -68,5 +63,7 @@ class AboutFragment : Fragment() {
} }
false false
} }
binding.aboutSources.aboutGithubButton.setOnClickListener { viewModel.openUrl("https://github.com/YTVanced/VancedInstaller") }
binding.aboutSources.aboutLicenseButton.setOnClickListener { viewModel.openUrl("https://raw.githubusercontent.com/YTVanced/VancedInstaller/dev/LICENSE") }
} }
} }

View File

@ -3,52 +3,47 @@ package com.vanced.manager.ui.fragments
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.core.content.edit import androidx.core.content.edit
import androidx.databinding.DataBindingUtil import androidx.preference.PreferenceManager.*
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.databinding.FragmentGrantRootBinding import com.vanced.manager.databinding.FragmentGrantRootBinding
import com.vanced.manager.ui.MainActivity import com.vanced.manager.ui.MainActivity
import com.vanced.manager.ui.core.BindingFragment
class GrantRootFragment : Fragment(), View.OnClickListener { class GrantRootFragment : BindingFragment<FragmentGrantRootBinding>() {
private lateinit var binding: FragmentGrantRootBinding override fun binding(
inflater: LayoutInflater,
override fun onCreateView( container: ViewGroup?,
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = FragmentGrantRootBinding.inflate(inflater, container, false)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_grant_root, container, false)
return binding.root override fun otherSetups() {
bindData()
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { private fun bindData() {
super.onViewCreated(view, savedInstanceState) with(binding) {
binding.grantRootFinishFab.setOnClickListener(this) grantRootFinishFab.setOnClickListener { navigateToFirstLaunch() }
binding.grantRootFab.setOnClickListener(this) grantRootFab.setOnClickListener { grantRoot() }
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.grant_root_fab -> {
if (Shell.rootAccess()) {
getDefaultSharedPreferences(requireActivity()).edit { putString("vanced_variant", "root") }
} else {
Toast.makeText(requireActivity(), R.string.root_not_granted, Toast.LENGTH_SHORT).show()
}
}
R.id.grant_root_finish_fab -> {
val intent = Intent(requireActivity(), MainActivity::class.java)
intent.putExtra("firstLaunch", true)
startActivity(intent)
requireActivity().finish()
}
} }
} }
private fun navigateToFirstLaunch() {
val intent = Intent(requireActivity(), MainActivity::class.java)
intent.putExtra("firstLaunch", true)
startActivity(intent)
requireActivity().finish()
}
private fun grantRoot() {
if (Shell.rootAccess()) {
getDefaultSharedPreferences(requireActivity()).edit { putString("vanced_variant", "root") }
} else {
Toast.makeText(requireActivity(), R.string.root_not_granted, Toast.LENGTH_SHORT).show()
}
}
} }

View File

@ -22,37 +22,43 @@ import com.vanced.manager.R
import com.vanced.manager.adapter.AppListAdapter import com.vanced.manager.adapter.AppListAdapter
import com.vanced.manager.adapter.LinkAdapter import com.vanced.manager.adapter.LinkAdapter
import com.vanced.manager.adapter.SponsorAdapter import com.vanced.manager.adapter.SponsorAdapter
import com.vanced.manager.databinding.FragmentGrantRootBinding
import com.vanced.manager.databinding.FragmentHomeBinding import com.vanced.manager.databinding.FragmentHomeBinding
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.dialogs.DialogContainer.installAlertBuilder import com.vanced.manager.ui.dialogs.DialogContainer.installAlertBuilder
import com.vanced.manager.ui.viewmodels.HomeViewModel import com.vanced.manager.ui.viewmodels.HomeViewModel
import com.vanced.manager.ui.viewmodels.HomeViewModelFactory import com.vanced.manager.ui.viewmodels.HomeViewModelFactory
open class HomeFragment : Fragment() { open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
companion object {
const val INSTALL_FAILED = "install_failed"
const val REFRESH_HOME = "refresh_home"
}
private lateinit var binding: FragmentHomeBinding
private val viewModel: HomeViewModel by viewModels { private val viewModel: HomeViewModel by viewModels {
HomeViewModelFactory(requireActivity()) HomeViewModelFactory(requireActivity())
} }
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) } private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) }
private val prefs by lazy { PreferenceManager.getDefaultSharedPreferences(requireActivity()) } private val prefs by lazy { PreferenceManager.getDefaultSharedPreferences(requireActivity()) }
private lateinit var tooltip: ViewTooltip private lateinit var tooltip: ViewTooltip
override fun onCreateView( override fun binding(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = FragmentHomeBinding.inflate(inflater, container, false)
requireActivity().title = getString(R.string.title_home)
setHasOptionsMenu(true) override fun otherSetups() {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false) bindData()
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { private fun bindData() {
super.onViewCreated(view, savedInstanceState) requireActivity().title = getString(R.string.title_home)
setHasOptionsMenu(true)
with(binding) { with(binding) {
viewModel = this@HomeFragment.viewModel homeRefresh.setOnRefreshListener { viewModel.fetchData() }
tooltip = ViewTooltip tooltip = ViewTooltip
.on(recyclerAppList) .on(recyclerAppList)
.position(ViewTooltip.Position.TOP) .position(ViewTooltip.Position.TOP)
@ -91,9 +97,13 @@ open class HomeFragment : Fragment() {
adapter = LinkAdapter(requireActivity(), this@HomeFragment.viewModel) adapter = LinkAdapter(requireActivity(), this@HomeFragment.viewModel)
} }
} }
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflateWithCrowdin(R.menu.toolbar_menu, menu, resources)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
localBroadcastManager.unregisterReceiver(broadcastReceiver) localBroadcastManager.unregisterReceiver(broadcastReceiver)
@ -122,15 +132,5 @@ open class HomeFragment : Fragment() {
intentFilter.addAction(REFRESH_HOME) intentFilter.addAction(REFRESH_HOME)
localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter) localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter)
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflateWithCrowdin(R.menu.toolbar_menu, menu, resources)
super.onCreateOptionsMenu(menu, inflater)
}
companion object {
const val INSTALL_FAILED = "install_failed"
const val REFRESH_HOME = "refresh_home"
}
} }

View File

@ -2,53 +2,56 @@ package com.vanced.manager.ui.fragments
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.core.content.edit import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.*
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.adapter.SelectAppsAdapter import com.vanced.manager.adapter.SelectAppsAdapter
import com.vanced.manager.databinding.FragmentSelectAppsBinding import com.vanced.manager.databinding.FragmentSelectAppsBinding
import com.vanced.manager.ui.core.BindingFragment
class SelectAppsFragment : Fragment() { class SelectAppsFragment : BindingFragment<FragmentSelectAppsBinding>() {
private lateinit var binding: FragmentSelectAppsBinding private lateinit var selectAdapter: SelectAppsAdapter
override fun onCreateView( override fun binding(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = FragmentSelectAppsBinding.inflate(inflater, container, false)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_select_apps, container, false)
return binding.root override fun otherSetups() {
bindData()
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { private fun bindData() {
super.onViewCreated(view, savedInstanceState) with(binding) {
val selectAdapter = SelectAppsAdapter(requireActivity()) initRecycler()
val prefs = getDefaultSharedPreferences(requireActivity()) selectAppsFab.setOnClickListener { actionOnClickAppsFab() }
binding.selectAppsRecycler.apply { }
}
private fun FragmentSelectAppsBinding.initRecycler() {
selectAdapter = SelectAppsAdapter(requireActivity())
selectAppsRecycler.apply {
layoutManager = LinearLayoutManager(requireActivity()) layoutManager = LinearLayoutManager(requireActivity())
setHasFixedSize(true) setHasFixedSize(true)
adapter = selectAdapter adapter = selectAdapter
} }
binding.selectAppsFab.setOnClickListener {
if (selectAdapter.apps.all { app -> !app.isChecked }) {
Toast.makeText(requireActivity(), R.string.select_at_least_one_app, Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
selectAdapter.apps.forEach { app ->
prefs.edit { putBoolean("enable_${app.tag}", app.isChecked) }
}
findNavController().navigate(SelectAppsFragmentDirections.selectAppsToGrantRoot())
}
} }
private fun actionOnClickAppsFab() {
if (selectAdapter.apps.all { app -> !app.isChecked }) {
Toast.makeText(requireActivity(), R.string.select_at_least_one_app, Toast.LENGTH_SHORT).show()
return
}
val prefs = getDefaultSharedPreferences(requireActivity())
selectAdapter.apps.forEach { app ->
prefs.edit { putBoolean("enable_${app.tag}", app.isChecked) }
}
findNavController().navigate(SelectAppsFragmentDirections.selectAppsToGrantRoot())
}
} }

View File

@ -1,59 +1,86 @@
package com.vanced.manager.ui.fragments package com.vanced.manager.ui.fragments
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.databinding.DataBindingUtil import androidx.preference.PreferenceManager.*
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.perf.FirebasePerformance import com.google.firebase.perf.FirebasePerformance
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.adapter.GetNotifAdapter import com.vanced.manager.adapter.GetNotifAdapter
import com.vanced.manager.core.ext.showDialogRefl
import com.vanced.manager.databinding.FragmentSettingsBinding import com.vanced.manager.databinding.FragmentSettingsBinding
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.dialogs.* import com.vanced.manager.ui.dialogs.*
import com.vanced.manager.utils.LanguageHelper.getLanguageFormat import com.vanced.manager.utils.LanguageHelper.getLanguageFormat
import java.io.File import java.io.File
class SettingsFragment : Fragment() { class SettingsFragment : BindingFragment<FragmentSettingsBinding>() {
private companion object {
const val LIGHT = "Light"
const val DARK = "Dark"
const val BLUE = "Blue"
const val RED = "Red"
const val GREEN = "Green"
const val YELLOW = "Yellow"
}
private lateinit var binding: FragmentSettingsBinding
private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) } private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) }
override fun onCreateView( override fun binding(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = FragmentSettingsBinding.inflate(inflater, container, false)
override fun otherSetups() {
setHasOptionsMenu(true) setHasOptionsMenu(true)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_settings, container, false) bindData()
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { private fun bindData() {
super.onViewCreated(view, savedInstanceState) with(binding) {
bindRecycler()
bindFirebase()
bindManagerVariant()
bindClearFiles()
bindManagerTheme()
bindManagerAccentColor()
bindManagerLanguage()
selectApps.setOnClickListener { showDialogRefl<SelectAppsDialog>() }
}
}
binding.notificationsRecycler.apply { private fun FragmentSettingsBinding.bindRecycler() {
notificationsRecycler.apply {
layoutManager = LinearLayoutManager(requireActivity()) layoutManager = LinearLayoutManager(requireActivity())
adapter = GetNotifAdapter(requireActivity()) adapter = GetNotifAdapter(requireActivity())
} }
}
binding.firebase.setOnCheckedListener { _, isChecked -> private fun FragmentSettingsBinding.bindFirebase() {
firebase.setOnCheckedListener { _, isChecked ->
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(isChecked) FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(isChecked)
FirebasePerformance.getInstance().isPerformanceCollectionEnabled = isChecked FirebasePerformance.getInstance().isPerformanceCollectionEnabled = isChecked
FirebaseAnalytics.getInstance(requireActivity()).setAnalyticsCollectionEnabled(isChecked) FirebaseAnalytics.getInstance(requireActivity()).setAnalyticsCollectionEnabled(isChecked)
} }
}
binding.managerVariant.apply { private fun FragmentSettingsBinding.bindManagerVariant() {
managerVariant.apply {
prefs.getString("vanced_variant", "nonroot")?.let { setSummary(it) } prefs.getString("vanced_variant", "nonroot")?.let { setSummary(it) }
setOnClickListener { setOnClickListener { showDialogRefl<ManagerVariantDialog>() }
ManagerVariantDialog().show(requireActivity().supportFragmentManager, "")
}
} }
}
binding.clearFiles.setOnClickListener { private fun FragmentSettingsBinding.bindClearFiles() {
clearFiles.setOnClickListener {
with(requireActivity()) { with(requireActivity()) {
listOf("vanced/nonroot", "vanced/root", "music/nonroot", "music/root", "microg").forEach { dir -> listOf("vanced/nonroot", "vanced/root", "music/nonroot", "music/root", "microg").forEach { dir ->
File(getExternalFilesDir(dir)?.path.toString()).deleteRecursively() File(getExternalFilesDir(dir)?.path.toString()).deleteRecursively()
@ -61,47 +88,43 @@ class SettingsFragment : Fragment() {
Toast.makeText(this, getString(R.string.cleared_files), Toast.LENGTH_SHORT).show() Toast.makeText(this, getString(R.string.cleared_files), Toast.LENGTH_SHORT).show()
} }
} }
}
private fun FragmentSettingsBinding.bindManagerTheme() {
val themePref = prefs.getString("manager_theme", "System Default") val themePref = prefs.getString("manager_theme", "System Default")
binding.managerTheme.apply { managerTheme.apply {
setSummary( setSummary(
when (themePref) { when (themePref) {
"Light" -> getString(R.string.theme_light) LIGHT -> getString(R.string.theme_light)
"Dark" -> getString(R.string.theme_dark) DARK -> getString(R.string.theme_dark)
else -> getString(R.string.system_default) else -> getString(R.string.system_default)
} }
) )
setOnClickListener { setOnClickListener { showDialogRefl<ManagerThemeDialog>() }
ManagerThemeDialog().show(requireActivity().supportFragmentManager, "")
}
} }
}
private fun FragmentSettingsBinding.bindManagerAccentColor() {
val accentPref = prefs.getString("manager_accent", "Blue") val accentPref = prefs.getString("manager_accent", "Blue")
binding.managerAccentColor.apply { managerAccentColor.apply {
setSummary( setSummary(
when (accentPref) { when (accentPref) {
"Blue" -> getString(R.string.accent_blue) BLUE -> getString(R.string.accent_blue)
"Red" -> getString(R.string.accent_red) RED -> getString(R.string.accent_red)
"Green" -> getString(R.string.accent_green) GREEN -> getString(R.string.accent_green)
"Yellow" -> getString(R.string.accent_yellow) YELLOW -> getString(R.string.accent_yellow)
else -> getString(R.string.accent_purple) else -> getString(R.string.accent_purple)
} }
) )
setOnClickListener { setOnClickListener { showDialogRefl<ManagerAccentColorDialog>() }
ManagerAccentColorDialog().show(requireActivity().supportFragmentManager, "")
}
} }
}
private fun FragmentSettingsBinding.bindManagerLanguage() {
val langPref = prefs.getString("manager_lang", "System Default") val langPref = prefs.getString("manager_lang", "System Default")
binding.managerLanguage.apply { managerLanguage.apply {
setSummary(getLanguageFormat(requireActivity(), langPref!!)) setSummary(getLanguageFormat(requireActivity(), requireNotNull(langPref)))
setOnClickListener { setOnClickListener { showDialogRefl<ManagerLanguageDialog>() }
ManagerLanguageDialog().show(requireActivity().supportFragmentManager, "")
}
}
binding.selectApps.setOnClickListener {
SelectAppsDialog().show(requireActivity().supportFragmentManager, "")
} }
} }
@ -113,5 +136,4 @@ class SettingsFragment : Fragment() {
} }
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
} }
} }

View File

@ -2,31 +2,28 @@ package com.vanced.manager.ui.fragments
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.vanced.manager.R
import com.vanced.manager.databinding.FragmentWelcomeBinding import com.vanced.manager.databinding.FragmentWelcomeBinding
import com.vanced.manager.ui.core.BindingFragment
class WelcomeFragment : Fragment() { class WelcomeFragment : BindingFragment<FragmentWelcomeBinding>() {
private lateinit var binding: FragmentWelcomeBinding override fun binding(
inflater: LayoutInflater,
override fun onCreateView( container: ViewGroup?,
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = FragmentWelcomeBinding.inflate(inflater, container, false)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_welcome, container, false)
return binding.root override fun otherSetups() {
bindData()
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { private fun bindData() {
super.onViewCreated(view, savedInstanceState) binding.welcomeGetStarted.setOnClickListener { navigateToWelcome() }
binding.welcomeGetStarted.setOnClickListener {
findNavController().navigate(WelcomeFragmentDirections.welcomeToSelectApps())
}
} }
private fun navigateToWelcome() {
findNavController().navigate(WelcomeFragmentDirections.welcomeToSelectApps())
}
} }

View File

@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat.startActivity
import androidx.databinding.ObservableField import androidx.databinding.ObservableField
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin import com.crowdin.platform.Crowdin
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
@ -35,6 +36,7 @@ import com.vanced.manager.utils.PackageHelper.musicApkExists
import com.vanced.manager.utils.PackageHelper.uninstallApk import com.vanced.manager.utils.PackageHelper.uninstallApk
import com.vanced.manager.utils.PackageHelper.uninstallRootApk import com.vanced.manager.utils.PackageHelper.uninstallRootApk
import com.vanced.manager.utils.PackageHelper.vancedInstallFilesExist import com.vanced.manager.utils.PackageHelper.vancedInstallFilesExist
import kotlinx.coroutines.launch
open class HomeViewModel(private val activity: FragmentActivity): ViewModel() { open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
@ -48,10 +50,12 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
val manager = ObservableField<DataModel>() val manager = ObservableField<DataModel>()
fun fetchData() { fun fetchData() {
activity.setRefreshing(true) viewModelScope.launch {
loadJson(activity) activity.setRefreshing(true)
Crowdin.forceUpdate(activity) loadJson(activity)
activity.setRefreshing(false) Crowdin.forceUpdate(activity)
activity.setRefreshing(false)
}
} }
private val microgToast = Toast.makeText(activity, R.string.no_microg, Toast.LENGTH_LONG) private val microgToast = Toast.makeText(activity, R.string.no_microg, Toast.LENGTH_LONG)
@ -122,7 +126,13 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
} }
fun uninstallPackage(pkg: String) = if (prefs.getString("vanced_variant", "nonroot") == "root" && uninstallRootApk(pkg)) activity.fetchData() else uninstallApk(pkg, activity) fun uninstallPackage(pkg: String) {
if (prefs.getString("vanced_variant", "nonroot") == "root" && uninstallRootApk(pkg)) {
viewModelScope.launch { activity.fetchData() }
} else {
uninstallApk(pkg, activity)
}
}
init { init {
activity.setRefreshing(true) activity.setRefreshing(true)
@ -134,5 +144,4 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
manager.set(DataModel(InternetTools.manager, activity, managerPkg, activity.getString(R.string.app_name), AppCompatResources.getDrawable(activity, R.mipmap.ic_launcher))) manager.set(DataModel(InternetTools.manager, activity, managerPkg, activity.getString(R.string.app_name), AppCompatResources.getDrawable(activity, R.mipmap.ic_launcher)))
activity.setRefreshing(false) activity.setRefreshing(false)
} }
} }

View File

@ -15,7 +15,7 @@ import java.io.File
import java.io.IOException import java.io.IOException
import java.security.MessageDigest import java.security.MessageDigest
object AppUtils { object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
const val vancedPkg = "com.vanced.android.youtube" const val vancedPkg = "com.vanced.android.youtube"
const val vancedRootPkg = "com.google.android.youtube" const val vancedRootPkg = "com.google.android.youtube"
@ -24,25 +24,25 @@ object AppUtils {
const val microgPkg = "com.mgoogle.android.gms" const val microgPkg = "com.mgoogle.android.gms"
const val managerPkg = APPLICATION_ID const val managerPkg = APPLICATION_ID
fun sendRefresh(context: Context) { fun sendRefresh(context: Context): Job {
CoroutineScope(Dispatchers.IO).launch { return launch {
delay(700) delay(700)
LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(HomeFragment.REFRESH_HOME)) LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(HomeFragment.REFRESH_HOME))
} }
} }
fun sendCloseDialog(context: Context) { fun sendCloseDialog(context: Context): Job {
downloadProgress.get()?.installing?.set(false) downloadProgress.get()?.installing?.set(false)
CoroutineScope(Dispatchers.IO).launch { return launch {
delay(700) delay(700)
LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(AppDownloadDialog.CLOSE_DIALOG)) LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(AppDownloadDialog.CLOSE_DIALOG))
} }
} }
fun sendFailure(status: Int, context: Context) { fun sendFailure(status: Int, context: Context): Job {
downloadProgress.get()?.installing?.set(false) downloadProgress.get()?.installing?.set(false)
//Delay error broadcast until activity (and fragment) get back to the screen //Delay error broadcast until activity (and fragment) get back to the screen
CoroutineScope(Dispatchers.IO).launch { return launch {
delay(700) delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED) val intent = Intent(HomeFragment.INSTALL_FAILED)
intent.putExtra("errorMsg", getErrorMessage(status, context)) intent.putExtra("errorMsg", getErrorMessage(status, context))
@ -50,9 +50,9 @@ object AppUtils {
} }
} }
fun sendFailure(error: MutableList<String>, context: Context) { fun sendFailure(error: MutableList<String>, context: Context): Job {
downloadProgress.get()?.installing?.set(false) downloadProgress.get()?.installing?.set(false)
CoroutineScope(Dispatchers.IO).launch { return launch {
delay(700) delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED) val intent = Intent(HomeFragment.INSTALL_FAILED)
intent.putExtra("errorMsg", getErrorMessage(error.joinToString(), context)) intent.putExtra("errorMsg", getErrorMessage(error.joinToString(), context))
@ -134,6 +134,4 @@ object AppUtils {
context.getString(R.string.installation_failed) context.getString(R.string.installation_failed)
} }
} }
}
}

View File

@ -16,9 +16,8 @@ import com.downloader.PRDownloader
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.model.ProgressModel import com.vanced.manager.model.ProgressModel
import com.vanced.manager.utils.AppUtils.sendCloseDialog import com.vanced.manager.utils.AppUtils.sendCloseDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.withContext
import java.io.File import java.io.File
object DownloadHelper { object DownloadHelper {
@ -41,8 +40,8 @@ object DownloadHelper {
downloadProgress.set(ProgressModel()) downloadProgress.set(ProgressModel())
} }
fun downloadManager(context: Context) { suspend fun downloadManager(context: Context) =
CoroutineScope(Dispatchers.IO).launch { withContext(Dispatchers.IO) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk" val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk") downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk")
.build() .build()
@ -82,6 +81,4 @@ object DownloadHelper {
}) })
} }
}
} }

View File

@ -28,7 +28,7 @@ object Extensions {
show(activity.supportFragmentManager, "") show(activity.supportFragmentManager, "")
} }
fun Activity.fetchData() { suspend fun Activity.fetchData() {
val refreshLayout = findViewById<SwipeRefreshLayout>(R.id.home_refresh) val refreshLayout = findViewById<SwipeRefreshLayout>(R.id.home_refresh)
setRefreshing(true, refreshLayout) setRefreshing(true, refreshLayout)
loadJson(this) loadJson(this)

View File

@ -7,16 +7,15 @@ import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.databinding.ObservableField import androidx.databinding.ObservableField
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.*
import com.beust.klaxon.JsonArray import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject import com.beust.klaxon.JsonObject
import com.vanced.manager.BuildConfig import com.vanced.manager.BuildConfig
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.utils.AppUtils.generateChecksum import com.vanced.manager.utils.AppUtils.generateChecksum
import com.vanced.manager.utils.Extensions.getDefaultPrefs import com.vanced.manager.utils.Extensions.getDefaultPrefs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -49,19 +48,20 @@ object InternetTools {
context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
} }
fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/')+1, url.length) fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/') + 1, url.length)
fun loadJson(context: Context) = CoroutineScope(Dispatchers.IO).launch { suspend fun loadJson(context: Context) =
val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl) withContext(Dispatchers.IO) {
val latest = JsonHelper.getJson("$installUrl/latest.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}") val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl)
val versions = JsonHelper.getJson("$installUrl/versions.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}") val latest = JsonHelper.getJson("$installUrl/latest.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
val versions = JsonHelper.getJson("$installUrl/versions.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
// braveTiers.apply { // braveTiers.apply {
// set(getJson("$installUrl/sponsor.json")) // set(getJson("$installUrl/sponsor.json"))
// notifyChange() // notifyChange()
// } // }
vanced.apply { vanced.apply {
set(latest?.obj("vanced")) set(latest?.obj("vanced"))
notifyChange() notifyChange()
} }
vancedVersions.set(versions?.array("vanced")) vancedVersions.set(versions?.array("vanced"))
@ -100,9 +100,9 @@ object InternetTools {
return getJsonString(hashUrl, obj, context) return getJsonString(hashUrl, obj, context)
} }
fun checkSHA256(sha256: String, updateFile: File?): Boolean { fun checkSHA256(sha256: String, updateFile: File): Boolean {
return try { return try {
val dataBuffer = updateFile!!.readBytes() val dataBuffer = updateFile.readBytes()
// Generate the checksum // Generate the checksum
val sum = generateChecksum(dataBuffer) val sum = generateChecksum(dataBuffer)

View File

@ -12,15 +12,11 @@ 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 { return if (dataMap.containsKey(url)) {
if(dataMap.containsKey(url)) { dataMap[url]
dataMap[url]!! } else {
} else { dataMap[url] = getSuspendJson(url)
dataMap[url] = getSuspendJson(url) dataMap[url]
dataMap[url]!!
}
} catch (e: Exception) {
null
} }
} }

View File

@ -6,28 +6,20 @@ import java.io.InputStreamReader
object MiuiHelper { object MiuiHelper {
fun isMiui(): Boolean = getSystemProps("ro.miui.ui.version.name")!!.isNotEmpty() private const val MIUI_PROP_NAME = "ro.miui.ui.version.name"
fun isMiui(): Boolean = !getSystemProps(MIUI_PROP_NAME).isNullOrEmpty()
private fun getSystemProps(propname: String): String? { private fun getSystemProps(propname: String): String? {
val line: String
var input: BufferedReader? = null var input: BufferedReader? = null
try { return try {
val p = Runtime.getRuntime().exec("getprop $propname") val process = Runtime.getRuntime().exec("getprop $propname")
input = BufferedReader(InputStreamReader(p.inputStream), 1024) input = BufferedReader(InputStreamReader(process.inputStream), 1024)
line = input.readLine() input.readLine()
input.close()
} catch (e: IOException) { } catch (e: IOException) {
return null null
} finally { } finally {
if (input != null) { input?.close()
try {
input.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
} }
return line
} }
} }

View File

@ -298,7 +298,7 @@ object PackageHelper {
} }
} finally { } finally {
session!!.close() session?.close()
} }
} }
@ -579,8 +579,8 @@ object PackageHelper {
@Throws(IOException::class) @Throws(IOException::class)
fun copy(src: File?, dst: File?) { fun copy(src: File, dst: File) {
val cmd = Shell.su("mv ${src!!.absolutePath} ${dst!!.absolutePath}").exec().isSuccess val cmd = Shell.su("mv ${src.absolutePath} ${dst.absolutePath}").exec().isSuccess
Log.d("ZLog", cmd.toString()) Log.d("ZLog", cmd.toString())
} }

View File

@ -1,59 +1,46 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.core.widget.NestedScrollView
xmlns:bind="http://schemas.android.com/tools"> xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">
<data> <LinearLayout
<variable
name="viewModel"
type="com.vanced.manager.ui.viewmodels.AboutViewModel" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true" android:layout_marginEnd="16dp"
android:scrollbars="none"> android:layout_marginStart="16dp"
android:layout_marginTop="@dimen/twelvedp"
android:clipToPadding="false"
android:orientation="vertical">
<LinearLayout <include
android:id="@+id/about_header"
layout="@layout/include_about_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginTop="@dimen/twelvedp" />
android:layout_marginTop="@dimen/twelvedp"
android:layout_marginEnd="16dp"
android:clipToPadding="false"
android:orientation="vertical">
<include <include
android:id="@+id/about_header" layout="@layout/include_about_vanced_devs"
layout="@layout/include_about_header" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" /> android:layout_marginTop="@dimen/stdp"/>
<include <include
layout="@layout/include_about_vanced_devs" layout="@layout/include_about_app_devs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/stdp" /> android:layout_marginTop="@dimen/stdp"/>
<include <include
layout="@layout/include_about_app_devs" android:id="@+id/about_sources"
android:layout_width="match_parent" layout="@layout/include_about_sources"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:layout_marginTop="@dimen/stdp" /> android:layout_height="wrap_content"
android:layout_marginTop="@dimen/stdp"/>
<include
layout="@layout/include_about_sources"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/stdp"
bind:viewModel="@{viewModel}" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</layout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -1,62 +1,58 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout> <com.vanced.manager.ui.core.SlidingConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface">
<com.vanced.manager.ui.core.SlidingConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <TextView
xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/grant_root_header"
android:layout_width="match_parent" android:text="@string/are_you_rooted"
android:layout_height="match_parent" app:layout_constraintTop_toTopOf="parent"
android:background="?colorSurface"> style="@style/WelcomeHeaderTitle"/>
<TextView <TextView
android:id="@+id/grant_root_header" android:id="@+id/grant_root_description"
style="@style/WelcomeHeaderTitle" android:text="@string/willing_to_use_root"
android:text="@string/are_you_rooted" android:textSize="13sp"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@id/grant_root_header"
style="@style/WelcomeHeaderSubtitle"/>
<TextView <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/grant_root_description" android:id="@+id/grant_root_fab"
style="@style/WelcomeHeaderSubtitle" android:layout_width="wrap_content"
android:text="@string/willing_to_use_root" android:layout_height="wrap_content"
android:textSize="13sp" android:backgroundTint="#1F1F1F"
app:layout_constraintTop_toBottomOf="@id/grant_root_header" /> android:padding="16dp"
android:src="@drawable/ic_magisk"
app:borderWidth="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/grant_root_header"
app:maxImageSize="44dp"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton <TextView
android:id="@+id/grant_root_fab" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginTop="8dp"
android:backgroundTint="#1F1F1F" android:text="@string/grant_root"
android:padding="16dp" android:textColor="#ffffff"
android:src="@drawable/ic_magisk" android:textSize="13sp"
app:borderWidth="0dp" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/grant_root_fab"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/grant_root_header"
app:maxImageSize="44dp" />
<TextView <com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content" android:id="@+id/grant_root_finish_fab"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_marginTop="8dp" android:layout_height="wrap_content"
android:text="@string/grant_root" android:layout_marginBottom="45dp"
android:textColor="#ffffff" android:layout_marginEnd="45dp"
android:textSize="13sp" android:backgroundTint="?colorPrimary"
app:layout_constraintEnd_toEndOf="parent" android:src="@drawable/ic_baseline_navigate_next_48"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/grant_root_fab" /> app:layout_constraintEnd_toEndOf="parent"
app:maxImageSize="48dp"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton </com.vanced.manager.ui.core.SlidingConstraintLayout>
android:id="@+id/grant_root_finish_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="45dp"
android:layout_marginBottom="45dp"
android:backgroundTint="?colorPrimary"
android:src="@drawable/ic_baseline_navigate_next_48"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:maxImageSize="48dp" />
</com.vanced.manager.ui.core.SlidingConstraintLayout>
</layout>

View File

@ -1,75 +1,57 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:bind="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<data> <androidx.core.widget.NestedScrollView
<import type="android.view.View" />
<variable
name="viewModel"
type="com.vanced.manager.ui.viewmodels.HomeViewModel" />
</data>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/home_refresh"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
bind:onRefreshListener="@{()-> viewModel.fetchData()}"> android:fillViewport="true"
android:scrollbars="none">
<androidx.core.widget.NestedScrollView <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true" android:orientation="vertical">
android:scrollbars="none">
<LinearLayout <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_app_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical"> android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="3"
tools:listitem="@layout/view_app"/>
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/recycler_app_list" android:layout_marginHorizontal="24dp"
android:layout_width="match_parent" android:layout_marginTop="12dp"
android:layout_height="wrap_content" android:text="@string/useful_links"
android:layout_marginStart="8dp" style="@style/CardTextHeader"/>
android:layout_marginEnd="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="3"
tools:listitem="@layout/view_app" />
<TextView <androidx.recyclerview.widget.RecyclerView
style="@style/CardTextHeader" android:id="@+id/recycler_sponsors"
android:layout_marginHorizontal="24dp" android:layout_width="match_parent"
android:layout_marginTop="12dp" android:layout_height="wrap_content"
android:text="@string/useful_links" /> android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="2"
tools:listitem="@layout/view_sponsor"/>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_sponsors" android:id="@+id/recycler_links"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginTop="4dp"
android:layout_marginEnd="8dp" android:nestedScrollingEnabled="false"
android:nestedScrollingEnabled="false" android:paddingBottom="8dp"
tools:itemCount="2" tools:itemCount="6"
tools:listitem="@layout/view_sponsor" /> tools:listitem="@layout/view_social_link"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView </androidx.core.widget.NestedScrollView>
android:id="@+id/recycler_links" </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:nestedScrollingEnabled="false"
android:paddingBottom="8dp"
tools:itemCount="6"
tools:listitem="@layout/view_social_link" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>

View File

@ -1,43 +1,41 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto" <com.vanced.manager.ui.core.SlidingConstraintLayout
xmlns:tools="http://schemas.android.com/tools"> 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"
android:background="?colorSurface">
<com.vanced.manager.ui.core.SlidingConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <TextView
android:id="@+id/select_apps_header"
android:text="@string/select_apps"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
style="@style/WelcomeHeaderTitle"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/select_apps_recycler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:background="?colorSurface"> android:layout_marginHorizontal="24dp"
android:nestedScrollingEnabled="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:itemCount="2"
tools:listitem="@layout/view_app_checkbox"/>
<TextView <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/select_apps_header" android:id="@+id/select_apps_fab"
style="@style/WelcomeHeaderTitle" android:layout_width="wrap_content"
android:text="@string/select_apps" android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginBottom="45dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginEnd="45dp"
app:layout_constraintTop_toTopOf="parent" /> android:backgroundTint="?colorPrimary"
android:src="@drawable/ic_baseline_navigate_next_48"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:maxImageSize="48dp"/>
<androidx.recyclerview.widget.RecyclerView </com.vanced.manager.ui.core.SlidingConstraintLayout>
android:id="@+id/select_apps_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:nestedScrollingEnabled="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:itemCount="2"
tools:listitem="@layout/view_app_checkbox" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/select_apps_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="45dp"
android:layout_marginBottom="45dp"
android:backgroundTint="?colorPrimary"
android:src="@drawable/ic_baseline_navigate_next_48"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:maxImageSize="48dp" />
</com.vanced.manager.ui.core.SlidingConstraintLayout>
</layout>

View File

@ -1,64 +1,63 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout> <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">
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="8dp"
android:paddingTop="16dp">
<LinearLayout <com.vanced.manager.ui.core.PreferenceCategory
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:background="@drawable/category_background"
android:paddingHorizontal="8dp" app:category_title="@string/category_behaviour">
android:paddingTop="16dp">
<com.vanced.manager.ui.core.PreferenceCategory <com.vanced.manager.ui.core.PreferenceSwitch
android:id="@+id/use_custom_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/category_background" app:switch_def_value="true"
app:category_title="@string/category_behaviour"> app:switch_key="@{@string/use_custom_tabs}"
app:switch_summary="@string/link_custom_tabs"
app:switch_title="@string/link_title"/>
<com.vanced.manager.ui.core.PreferenceSwitch <androidx.recyclerview.widget.RecyclerView
android:id="@+id/use_custom_tabs" android:id="@+id/notifications_recycler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:switch_def_value="true" android:nestedScrollingEnabled="false"
app:switch_key="@{@string/use_custom_tabs}" tools:itemCount="3"
app:switch_summary="@string/link_custom_tabs" tools:listitem="@layout/view_preference_switch"/>
app:switch_title="@string/link_title" />
<androidx.recyclerview.widget.RecyclerView <com.vanced.manager.ui.core.PreferenceSwitch
android:id="@+id/notifications_recycler" android:id="@+id/firebase"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" app:switch_def_value="true"
tools:itemCount="3" app:switch_key="@{@string/firebase}"
tools:listitem="@layout/view_preference_switch" /> app:switch_summary="@string/firebase_summary"
app:switch_title="@string/firebase_title"/>
<com.vanced.manager.ui.core.PreferenceSwitch <com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/firebase" android:id="@+id/manager_variant"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:switch_def_value="true" app:preference_title="@string/variant"/>
app:switch_key="@{@string/firebase}"
app:switch_summary="@string/firebase_summary"
app:switch_title="@string/firebase_title" />
<com.vanced.manager.ui.core.EmptyPreference <com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/manager_variant" android:id="@+id/clearFiles"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:preference_title="@string/variant" /> app:preference_title="@string/clear_files"/>
<com.vanced.manager.ui.core.EmptyPreference </com.vanced.manager.ui.core.PreferenceCategory>
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 <com.vanced.manager.ui.core.PreferenceCategory
android:layout_width="match_parent" android:layout_width="match_parent"
@ -83,19 +82,13 @@
android:id="@+id/manager_language" android:id="@+id/manager_language"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:preference_title="@string/language_title" /> app:preference_title="@string/language_title"/>
<com.vanced.manager.ui.core.EmptyPreference <com.vanced.manager.ui.core.EmptyPreference
android:id="@+id/select_apps" android:id="@+id/select_apps"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:preference_title="@string/select_apps" /> app:preference_title="@string/select_apps"/>
</com.vanced.manager.ui.core.PreferenceCategory> </com.vanced.manager.ui.core.PreferenceCategory>
</LinearLayout>
</LinearLayout> </androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>
</layout>

View File

@ -1,37 +1,32 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout> <com.vanced.manager.ui.core.SlidingConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface">
<com.vanced.manager.ui.core.SlidingConstraintLayout <ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:background="?colorSurface"> android:layout_alignParentTop="true"
android:layout_marginTop="@dimen/top_header_margin"
android:src="@drawable/ic_launch_text"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView <com.google.android.material.button.MaterialButton
android:layout_width="match_parent" android:id="@+id/welcome_get_started"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_alignParentTop="true" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/top_header_margin" android:layout_marginBottom="32dp"
app:srcCompat="@drawable/ic_launch_text" android:letterSpacing="0.15"
android:textAlignment="center" android:padding="22dp"
app:layout_constraintTop_toTopOf="parent" /> android:text="@string/lets_get_started"
android:textAllCaps="false"
<com.google.android.material.button.MaterialButton android:textSize="13sp"
android:id="@+id/welcome_get_started" app:cornerRadius="50dp"
android:layout_width="wrap_content" app:layout_constraintBottom_toBottomOf="parent"
android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="32dp" app:layout_constraintStart_toStartOf="parent"/>
android:letterSpacing="0.15" </com.vanced.manager.ui.core.SlidingConstraintLayout>
android:padding="22dp"
android:text="@string/lets_get_started"
android:textAllCaps="false"
android:textSize="13sp"
app:cornerRadius="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</com.vanced.manager.ui.core.SlidingConstraintLayout>
</layout>

View File

@ -1,73 +1,55 @@
<?xml version="1.0" encoding="utf-8"?> <com.google.android.material.card.MaterialCardView
<layout> 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="wrap_content"
app:cardBackgroundColor="?colorLinkBG"
app:cardElevation="0dp"
app:contentPaddingBottom="8dp"
app:contentPaddingTop="2dp">
<data> <LinearLayout
<variable
name="viewModel"
type="com.vanced.manager.ui.viewmodels.AboutViewModel" />
</data>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
app:cardBackgroundColor="?colorLinkBG" android:orientation="vertical">
app:cardElevation="0dp"
app:contentPaddingBottom="8dp"
app:contentPaddingTop="2dp">
<LinearLayout <TextView
android:id="@+id/about_card_vancedTeam"
style="@style/CardTextHeader"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="@string/sources"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical"> app:alignItems="center"
app:flexDirection="row"
app:justifyContent="space_evenly">
<TextView <com.google.android.material.button.MaterialButton
android:id="@+id/about_card_vancedTeam" android:id="@+id/about_github_button"
style="@style/CardTextHeader" style="@style/SocialButtonStyle"
android:layout_marginStart="16dp" app:icon="@drawable/ic_github"
android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent"
android:text="@string/sources" app:layout_constraintEnd_toStartOf="@id/about_license_button"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.google.android.flexbox.FlexboxLayout <com.google.android.material.button.MaterialButton
android:layout_width="match_parent" android:id="@+id/about_license_button"
android:layout_height="wrap_content" style="@style/SocialButtonStyle"
app:alignItems="center" android:fontFamily="@font/exo_semibold"
app:flexDirection="row" android:text="GPL"
app:justifyContent="space_evenly"> android:textSize="21sp"
app:layout_constraintBottom_toBottomOf="parent"
<com.google.android.material.button.MaterialButton app:layout_constraintEnd_toEndOf="parent"
android:id="@+id/about_github_button" app:layout_constraintStart_toEndOf="@id/about_github_button"
style="@style/SocialButtonStyle" app:layout_constraintTop_toTopOf="parent"
android:onClick='@{()-> viewModel.openUrl("https://github.com/YTVanced/VancedInstaller")}' tools:ignore="HardcodedText" />
app:icon="@drawable/ic_github" </com.google.android.flexbox.FlexboxLayout>
app:layout_constraintBottom_toBottomOf="parent" </LinearLayout>
app:layout_constraintEnd_toStartOf="@id/about_license_button" </com.google.android.material.card.MaterialCardView>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/about_license_button"
style="@style/SocialButtonStyle"
android:fontFamily="@font/exo_semibold"
android:onClick='@{()-> viewModel.openUrl("https://raw.githubusercontent.com/YTVanced/VancedInstaller/dev/LICENSE")}'
android:text="GPL"
android:textSize="21sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/about_github_button"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</com.google.android.flexbox.FlexboxLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</layout>

View File

@ -15,9 +15,9 @@
<string name="are_you_rooted">Er Din Enhed Rooted?</string> <string name="are_you_rooted">Er Din Enhed Rooted?</string>
<string name="grant_root">Tildel Root Tilladelse</string> <string name="grant_root">Tildel Root Tilladelse</string>
<string name="select_at_least_one_app">Vælg mindst én app!</string> <string name="select_at_least_one_app">Vælg mindst én app!</string>
<string name="select_apps_music">Vanced, but for YouTube Music!\nrelatively less feature rich but fulfils your needs.</string> <string name="select_apps_music">Vanced, men for YouTube Music!\nrelativt mindre funktionsrig men opfylder dine behov.</string>
<string name="select_apps_vanced">YouTube Vanced is the stock Android YouTube App, but better!</string> <string name="select_apps_vanced">YouTube Vanced er standard YouTube App, men bedre!</string>
<string name="lets_get_started">Let\'s get started</string> <string name="lets_get_started">Lad os komme igang</string>
<string name="willing_to_use_root">Vil du bruge root version? Tryk blot på knappen nedenfor, ellers tryk fotsæt</string> <string name="willing_to_use_root">Vil du bruge root version? Tryk blot på knappen nedenfor, ellers tryk fotsæt</string>
<!-- Home Page --> <!-- Home Page -->
<string name="about_app">Om %1$s</string> <string name="about_app">Om %1$s</string>
@ -61,7 +61,7 @@
<string name="update_not_found">Ingen nye opdateringer</string> <string name="update_not_found">Ingen nye opdateringer</string>
<string name="variant">Variant</string> <string name="variant">Variant</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="advanced">Advanced</string> <string name="advanced">Avanceret</string>
<string name="app_install_files_detected">%1$s installationsfiler fundet!</string> <string name="app_install_files_detected">%1$s installationsfiler fundet!</string>
<string name="app_install_files_detected_summary">Manageren opdagede, at alle nødvendige filer til %1$s installationen blev fundet. Vil du installere?</string> <string name="app_install_files_detected_summary">Manageren opdagede, at alle nødvendige filer til %1$s installationen blev fundet. Vil du installere?</string>
<string name="checking_updates">Søger efter opdateringer…</string> <string name="checking_updates">Søger efter opdateringer…</string>

View File

@ -10,7 +10,7 @@
<string name="title_about">Información</string> <string name="title_about">Información</string>
<string name="title_home">Manager</string> <string name="title_home">Manager</string>
<string name="title_settings">Ajustes</string> <string name="title_settings">Ajustes</string>
<string name="update_manager">Actualizar Manager</string> <string name="update_manager">Gestor de actualizaciones</string>
<!-- Welcome Page --> <!-- Welcome Page -->
<string name="are_you_rooted">¿Su dispositivo está rooteado?</string> <string name="are_you_rooted">¿Su dispositivo está rooteado?</string>
<string name="grant_root">Conceder permiso root</string> <string name="grant_root">Conceder permiso root</string>

View File

@ -7,35 +7,35 @@
<string name="save">Salva</string> <string name="save">Salva</string>
<string name="select_apps">Seleziona le Tue App</string> <string name="select_apps">Seleziona le Tue App</string>
<!-- Main Activity --> <!-- Main Activity -->
<string name="title_about">Autori</string> <string name="title_about">Informazioni</string>
<string name="title_home">Manager</string> <string name="title_home">Manager</string>
<string name="title_settings">Impostazioni</string> <string name="title_settings">Impostazioni</string>
<string name="update_manager">Aggiorna Manager</string> <string name="update_manager">Aggiorna Manager</string>
<!-- Welcome Page --> <!-- Welcome Page -->
<string name="are_you_rooted">Il tuo dispositivo ha i permessi di root?</string> <string name="are_you_rooted">Il tuo dispositivo ha i permessi di root?</string>
<string name="grant_root">Concedi Permessi Root</string> <string name="grant_root">Concedi i Permessi di Root</string>
<string name="select_at_least_one_app">Seleziona almeno un\'app!</string> <string name="select_at_least_one_app">Seleziona almeno un\'app!</string>
<string name="select_apps_music">Vanced, ma per YouTube Music!\nrelativamente meno ricco di caratteristiche ma ugualmente adattabile alle tue esigenze.</string> <string name="select_apps_music">Vanced, ma per YouTube Music!\nrelativamente meno ricco di caratteristiche ma ugualmente adattabile alle tue esigenze.</string>
<string name="select_apps_vanced">YouTube Vanced è l\'App di YouTube preinstallata di Android, ma migliore!</string> <string name="select_apps_vanced">YouTube Vanced è l\'App di YouTube preinstallata di Android, ma migliorata!</string>
<string name="lets_get_started">Iniziamo</string> <string name="lets_get_started">Iniziamo</string>
<string name="willing_to_use_root">Vorresti usare la versione di root? Basta premere il pulsante sotto, altrimenti tocca per continuare</string> <string name="willing_to_use_root">Sei disposto ad utilizzare la versione root? È sufficiente premere il pulsante in basso, altrimenti tocca per continuare</string>
<!-- Home Page --> <!-- Home Page -->
<string name="about_app">A proposito di %1$s</string> <string name="about_app">Informazioni su %1$s</string>
<string name="app_changelog_tooltip">Tocca sulla scheda per vedere il changelog.</string> <string name="app_changelog_tooltip">Tocca la scheda per vedere le novità.</string>
<string name="changelog">Changelog</string> <string name="changelog">Novità</string>
<string name="downloading_file">Download in corso di %1$s</string> <string name="downloading_file">Download in corso di %1$s</string>
<string name="install">Installa</string> <string name="install">Installa</string>
<string name="button_reinstall">Reinstalla</string> <string name="button_reinstall">Reinstalla</string>
<string name="version_installed">Versione installata:</string> <string name="version_installed">Installata:</string>
<string name="latest">Ultima versione:</string> <string name="latest">Disponibile:</string>
<string name="no_microg">microG non è installato</string> <string name="no_microg">microG non è installato</string>
<string name="root_not_granted">Non è stato fornito l\'accesso di root</string> <string name="root_not_granted">Accesso root non consentito</string>
<string name="unavailable">Non disponibile</string> <string name="unavailable">Non disponibile</string>
<string name="update">Aggiorna</string> <string name="update">Aggiorna</string>
<string name="useful_links">Link utili</string> <string name="useful_links">Link Utili</string>
<string name="support_us">Sostienici!</string> <string name="support_us">Sostienici!</string>
<!-- Settings --> <!-- Settings -->
<string name="accent_color">Colore evidenziatore</string> <string name="accent_color">Colore in Evidenza</string>
<string name="accent_blue">Blu</string> <string name="accent_blue">Blu</string>
<string name="accent_green">Verde</string> <string name="accent_green">Verde</string>
<string name="accent_purple">Viola</string> <string name="accent_purple">Viola</string>
@ -45,26 +45,26 @@
<string name="category_behaviour">Comportamento</string> <string name="category_behaviour">Comportamento</string>
<string name="clear_files">Cancella i file scaricati</string> <string name="clear_files">Cancella i file scaricati</string>
<string name="cleared_files">File cancellati con successo</string> <string name="cleared_files">File cancellati con successo</string>
<string name="firebase_title">Analitica Firebase</string> <string name="firebase_title">Analisi Firebase</string>
<string name="firebase_summary">Questo ci consente di raccogliere informazioni sulle prestazioni dell\'app ed i registri dei crash</string> <string name="firebase_summary">Questo ci consente di raccogliere informazioni sulle prestazioni dell\'app ed i registri sui crash</string>
<string name="language_title">Lingua</string> <string name="language_title">Lingua</string>
<string name="link_title">Utilizza le schede personalizzate di Chrome</string> <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="link_custom_tabs">I link verranno aperti nelle Schede Personalizzate di Chrome</string>
<string name="system_default">Predefinito di Sistema</string> <string name="system_default">Predefinito di Sistema</string>
<string name="theme">Tema</string> <string name="theme">Tema</string>
<string name="theme_dark">Tema scuro</string> <string name="theme_dark">Tema Scuro</string>
<string name="theme_light">Tema chiaro</string> <string name="theme_light">Tema Chiaro</string>
<string name="update_url">Aggiorna l\'URL del canale</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">Notifiche Push di %1$s</string>
<string name="push_notifications_summary">Ricevi notifiche push quando un aggiornamento per %1$s è disponibile</string> <string name="push_notifications_summary">Ricevi notifiche push quando un aggiornamento per %1$s è disponibile</string>
<string name="update_center">Centro aggiornamenti</string> <string name="update_center">Centro Aggiornamenti</string>
<string name="update_not_found">Nessun nuovo aggiornamento</string> <string name="update_not_found">Nessun nuovo aggiornamento</string>
<string name="variant">Variante</string> <string name="variant">Variante</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="advanced">Avanzate</string> <string name="advanced">Avanzate</string>
<string name="app_install_files_detected">%1$s file d\'installazione rilevati!</string> <string name="app_install_files_detected">%1$s file d\'installazione rilevati!</string>
<string name="app_install_files_detected_summary">Il manager ha rilevato che tutti i file necessari per l\'installazione di %1$s sono stati trovati. Vuoi installarli?</string> <string name="app_install_files_detected_summary">Manager ha rilevato tutti i file necessari per l\'installazione di %1$s. Vuoi installarli?</string>
<string name="checking_updates">Verificando gli aggiornamenti…</string> <string name="checking_updates">Verifica aggiornamenti…</string>
<string name="chosen_lang">Lingue: %1$s</string> <string name="chosen_lang">Lingue: %1$s</string>
<string name="chosen_theme">Tema: %1$s</string> <string name="chosen_theme">Tema: %1$s</string>
<string name="chosen_version">Versione: %1$s</string> <string name="chosen_version">Versione: %1$s</string>
@ -75,30 +75,30 @@
<string name="miui_one_title">Rilevata l\'interfaccia MIUI!</string> <string name="miui_one_title">Rilevata l\'interfaccia MIUI!</string>
<string name="miui_one">Per poter installare Vanced, DEVI PER FORZA disattivare le ottimizzazioni di MIUI nelle impostazioni da sviluppatore (puoi ignorare questo avviso se stai utilizzando la versione 20.2.20 o successive di una ROM basata su xiaomi.eu).</string> <string name="miui_one">Per poter installare Vanced, DEVI PER FORZA disattivare le ottimizzazioni di MIUI nelle impostazioni da sviluppatore (puoi ignorare questo avviso se stai utilizzando la versione 20.2.20 o successive di una ROM basata su xiaomi.eu).</string>
<string name="error">Errore</string> <string name="error">Errore</string>
<string name="redownload">Scarica di nuovo</string> <string name="redownload">Scarica nuovamente</string>
<string name="security_context">Assicurati di aver scaricato l\'app da vancedapp.com, dal server Discord di Vanced o dalla pagina GitHub di Vanced</string> <string name="security_context">Assicurati di aver scaricato l\'app da vancedapp.com, dal server di Discord di Vanced o dalla pagina GitHub di Vanced</string>
<string name="success">Fatto!</string> <string name="success">Riuscito!</string>
<string name="app_installation_preferences">Preferenze di installazione %1$s</string> <string name="app_installation_preferences">Preferenze di installazione %1$s</string>
<string name="vanced_installed">Vanced è stato installato con successo. Vuoi avviarlo ora?</string> <string name="vanced_installed">Vanced è stato installato con successo. Vuoi avviarlo ora?</string>
<string name="version">Versione</string> <string name="version">Versione</string>
<string name="music_installed">Vanced Music è stato installato con successo! Vuoi eseguirlo ora?</string> <string name="music_installed">Vanced Music è stato installato con successo! Vuoi eseguirlo ora?</string>
<string name="please_be_patient">Sei pregato di essere paziente…</string> <string name="please_be_patient">Si prega di attendere…</string>
<string name="launch">Avvia</string> <string name="launch">Avvia</string>
<string name="welcome">Benvenuto</string> <string name="welcome">Benvenuto</string>
<!-- Install Page --> <!-- Install Page -->
<string name="choose_preferred_language">Scegli le tue lingue preferite per Vanced</string> <string name="choose_preferred_language">Scegli le tue lingue preferite per Vanced</string>
<string name="light_plus_other">Luce + %1$s</string> <string name="light_plus_other">Chiaro + %1$s</string>
<string name="select_at_least_one_lang">Seleziona almeno una lingua!</string> <string name="select_at_least_one_lang">Seleziona almeno una lingua!</string>
<!-- About Page --> <!-- About Page -->
<string name="manager_dev">Sviluppatori di Manager</string> <string name="manager_dev">Sviluppatori di Manager</string>
<string name="sources">Codice sorgente</string> <string name="sources">Codice sorgente</string>
<string name="vanced_team">Il team di Vanced</string> <string name="vanced_team">Il Team di Vanced</string>
<!-- Error messages --> <!-- Error messages -->
<string name="chown_fail">Impossibile cambiare il proprietario dell\'apk in proprietario del sistema, sei pregato di riprovare.</string> <string name="chown_fail">Impossibile modificare il proprietario dell\'apk nel proprietario di sistema, per favore riprova.</string>
<string name="error_downloading">Errore nel download di %1$s</string> <string name="error_downloading">Errore nel Download di %1$s</string>
<string name="failed_uninstall">Impossibile disinstallare il pacchetto %1$s</string> <string name="failed_uninstall">Impossibile disinstallare il pacchetto %1$s</string>
<string name="files_missing_va">Impossibile trovare i file richiesti per l\'installazione. Scarica di nuovo i file di installazione, poi riprova.</string> <string name="files_missing_va">Impossibile individuare i file richiesti per l\'installazione. Scaricali nuovamente e riprova.</string>
<string name="ifile_missing">Impossibile trovare il file apk per il tema nero/scuro dall\'archiviazione, sei pregato di riprovare.</string> <string name="ifile_missing">Impossibile individuare il file apk per il tema nero/scuro dalla memoria, per favore riprova.</string>
<string name="installation_aborted">Installazione non riuscita, l\'utente ha annullato l\'installazione.</string> <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_blocked">Installazione non riuscita, l\'utente ha bloccato l\'installazione.</string>
<string name="installation_downgrade">Installazione non riuscita, l\'utente ha provato a eseguire il downgrade del pacchetto. Disinstalla gli aggiornamenti dell\'app predefinita di YouTube, poi riprova.</string> <string name="installation_downgrade">Installazione non riuscita, l\'utente ha provato a eseguire il downgrade del pacchetto. Disinstalla gli aggiornamenti dell\'app predefinita di YouTube, poi riprova.</string>
@ -109,6 +109,6 @@
<string name="installation_signature">Installazione non riuscita, la verifica della firma apk è attivata. Disattiva la verifica della firma apk, poi riprova.</string> <string name="installation_signature">Installazione non riuscita, la verifica della firma apk è attivata. Disattiva la verifica della firma apk, poi riprova.</string>
<string name="installation_miui">Installazione non riuscita, le ottimizzazioni di MIUI sono attivate. Disattiva le ottimizzazioni di MIUI, poi riprova.</string> <string name="installation_miui">Installazione non riuscita, le ottimizzazioni di MIUI sono attivate. Disattiva le ottimizzazioni di MIUI, poi riprova.</string>
<string name="installation_storage">Installazione non riuscita, errore dello spazio di archiviazione.</string> <string name="installation_storage">Installazione non riuscita, errore dello spazio di archiviazione.</string>
<string name="modapk_missing">Impossibile trovare il file apk per il tema nero/scuro dall\'installer. Cancella i dati dell\'app del Manager, poi riprova.</string> <string name="modapk_missing">Impossibile trovare il file apk per il tema nero/scuro dall\'installer. Cancella i dati dell\'app Manager, quindi riprova.</string>
<string name="path_missing">Impossibile trovare il percorso di installazione di stock di YouTube dopo l\'installazione divisa.</string> <string name="path_missing">Impossibile individuare il percorso di installazione di YouTube stock dopo l\'installazione divisa.</string>
</resources> </resources>

View File

@ -17,7 +17,7 @@
<string name="select_at_least_one_app">アプリを少なくとも一つ選択してください!</string> <string name="select_at_least_one_app">アプリを少なくとも一つ選択してください!</string>
<string name="select_apps_music">Vanced, but for YouTube Music!\nrelatively less feature rich but fulfils your needs.</string> <string name="select_apps_music">Vanced, but for YouTube Music!\nrelatively less feature rich but fulfils your needs.</string>
<string name="select_apps_vanced">YouTube Vanced is the stock Android YouTube App, but better!</string> <string name="select_apps_vanced">YouTube Vanced is the stock Android YouTube App, but better!</string>
<string name="lets_get_started">Let\'s get started</string> <string name="lets_get_started">さあ、始めましょう</string>
<string name="willing_to_use_root">root 版を使用したいですか?下のボタンを押してください。そうでないなら続けるボタンを押してください</string> <string name="willing_to_use_root">root 版を使用したいですか?下のボタンを押してください。そうでないなら続けるボタンを押してください</string>
<!-- Home Page --> <!-- Home Page -->
<string name="about_app">%1$s について</string> <string name="about_app">%1$s について</string>
@ -61,7 +61,7 @@
<string name="update_not_found">アップデートはありません</string> <string name="update_not_found">アップデートはありません</string>
<string name="variant">種類</string> <string name="variant">種類</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="advanced">Advanced</string> <string name="advanced">上級者向け</string>
<string name="app_install_files_detected">%1$sのインストールに必要なファイルが見つかりました</string> <string name="app_install_files_detected">%1$sのインストールに必要なファイルが見つかりました</string>
<string name="app_install_files_detected_summary">%1$sのインストールに必要な全てのファイル準備が整いました。インストールしますか?</string> <string name="app_install_files_detected_summary">%1$sのインストールに必要な全てのファイル準備が整いました。インストールしますか?</string>
<string name="checking_updates">アップデートを確認中...</string> <string name="checking_updates">アップデートを確認中...</string>

View File

@ -46,7 +46,7 @@
<string name="clear_files">Limpar arquivos baixados</string> <string name="clear_files">Limpar arquivos baixados</string>
<string name="cleared_files">Arquivos limpos com sucesso</string> <string name="cleared_files">Arquivos limpos com sucesso</string>
<string name="firebase_title">Análises de Firebase</string> <string name="firebase_title">Análises de Firebase</string>
<string name="firebase_summary">Isso nos permite coletar informações sobre o desempenho do aplicativo e registros de falhas</string> <string name="firebase_summary">Isto nos permite coletar informações sobre o desempenho do aplicativo e registros de falhas</string>
<string name="language_title">Idioma</string> <string name="language_title">Idioma</string>
<string name="link_title">Usar abas personalizadas do Chrome</string> <string name="link_title">Usar abas personalizadas do Chrome</string>
<string name="link_custom_tabs">Os links serão abertos nas abas personalizadas do Chrome</string> <string name="link_custom_tabs">Os links serão abertos nas abas personalizadas do Chrome</string>
@ -78,7 +78,7 @@
<string name="redownload">Baixar novamente</string> <string name="redownload">Baixar novamente</string>
<string name="security_context">Certifique-se de fazer o download do aplicativo em vancedapp.com, no servidor Vanced Discord ou no Vanced GitHub</string> <string name="security_context">Certifique-se de fazer o download do aplicativo em vancedapp.com, no servidor Vanced Discord ou no Vanced GitHub</string>
<string name="success">Sucesso!</string> <string name="success">Sucesso!</string>
<string name="app_installation_preferences">Preferências de instalação de %1$s</string> <string name="app_installation_preferences">%1$s Preferências de Instalação</string>
<string name="vanced_installed">O Vanced foi instalado com sucesso. Deseja iniciá-lo agora?</string> <string name="vanced_installed">O Vanced foi instalado com sucesso. Deseja iniciá-lo agora?</string>
<string name="version">Versão</string> <string name="version">Versão</string>
<string name="music_installed">O Vanced Music foi instalado com sucesso! Abrir agora?</string> <string name="music_installed">O Vanced Music foi instalado com sucesso! Abrir agora?</string>

View File

@ -12,12 +12,12 @@
<string name="title_settings">Подешавања</string> <string name="title_settings">Подешавања</string>
<string name="update_manager">Освежи Менаџера</string> <string name="update_manager">Освежи Менаџера</string>
<!-- Welcome Page --> <!-- Welcome Page -->
<string name="are_you_rooted">Is Your Device Rooted?</string> <string name="are_you_rooted">Да ли је ваш уређај рутован?</string>
<string name="grant_root">Омогућите дозволу за рут</string> <string name="grant_root">Омогућите дозволу за рут</string>
<string name="select_at_least_one_app">Одабери барем једну апликацију!</string> <string name="select_at_least_one_app">Одабери барем једну апликацију!</string>
<string name="select_apps_music">Vanced, but for YouTube Music!\nrelatively less feature rich but fulfils your needs.</string> <string name="select_apps_music">Vanced, али за YouTube Music!\nрелативно са мање напредних карактеристикама, али ће задовољити ваше потребе.</string>
<string name="select_apps_vanced">YouTube Vanced is the stock Android YouTube App, but better!</string> <string name="select_apps_vanced">YouTube Vanced је фабрички Android YouTube апликација, али много боља!</string>
<string name="lets_get_started">Let\'s get started</string> <string name="lets_get_started">Хајде да почнемо</string>
<string name="willing_to_use_root">Имате ли намеру користити рутовану верзију? Само кликните на дугме доле, у супротном кликните за наставак</string> <string name="willing_to_use_root">Имате ли намеру користити рутовану верзију? Само кликните на дугме доле, у супротном кликните за наставак</string>
<!-- Home Page --> <!-- Home Page -->
<string name="about_app">О %s</string> <string name="about_app">О %s</string>
@ -61,7 +61,7 @@
<string name="update_not_found">Нема нове верзије</string> <string name="update_not_found">Нема нове верзије</string>
<string name="variant">Варијанта</string> <string name="variant">Варијанта</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="advanced">Advanced</string> <string name="advanced">Napredan</string>
<string name="app_install_files_detected">%1$s верзија је пронађена!</string> <string name="app_install_files_detected">%1$s верзија је пронађена!</string>
<string name="app_install_files_detected_summary">Менаџер је пронашао све датотеке за %1$s верзију инсталације. Да ли желите да инсталирате?</string> <string name="app_install_files_detected_summary">Менаџер је пронашао све датотеке за %1$s верзију инсталације. Да ли желите да инсталирате?</string>
<string name="checking_updates">Провера ажурирања…</string> <string name="checking_updates">Провера ажурирања…</string>
@ -76,9 +76,9 @@
<string name="miui_one">Да би апликација Vanced била исправно инсталирана морате да искључите оптимизацију за ову апликацију у MIUI подешавањима за програмере.( Ову напомену можете да занемарите у случају ако користите верзију 20.2.20 и новију xiaomi.eu ROM-а)</string> <string name="miui_one">Да би апликација Vanced била исправно инсталирана морате да искључите оптимизацију за ову апликацију у MIUI подешавањима за програмере.( Ову напомену можете да занемарите у случају ако користите верзију 20.2.20 и новију xiaomi.eu ROM-а)</string>
<string name="error">Грешка</string> <string name="error">Грешка</string>
<string name="redownload">Поново преузми</string> <string name="redownload">Поново преузми</string>
<string name="security_context">Make sure that you downloaded the app from vancedapp.com, the Vanced Discord server or the Vanced GitHub</string> <string name="security_context">Преузмите апликацију само са официјелног Vanced сајта, Vanced Discord сервера или Vanced GitHub-а</string>
<string name="success">Успешно!</string> <string name="success">Успешно!</string>
<string name="app_installation_preferences">%1$s Installation Preferences</string> <string name="app_installation_preferences">%1$s Инсталациона подешавања</string>
<string name="vanced_installed">Vanced је успешно инсталиран! Желите да га одмах отворите?</string> <string name="vanced_installed">Vanced је успешно инсталиран! Желите да га одмах отворите?</string>
<string name="version">Верзија</string> <string name="version">Верзија</string>
<string name="music_installed">Vanced Music је успешно инсталиран! Желите да га одмах отворите?</string> <string name="music_installed">Vanced Music је успешно инсталиран! Желите да га одмах отворите?</string>

View File

@ -12,7 +12,7 @@
<string name="title_settings">設定</string> <string name="title_settings">設定</string>
<string name="update_manager">更新 Manager</string> <string name="update_manager">更新 Manager</string>
<!-- Welcome Page --> <!-- Welcome Page -->
<string name="are_you_rooted">您的裝置擁有 Root 權限嗎?</string> <string name="are_you_rooted">您的裝置擁有 Root 權限嗎?</string>
<string name="grant_root">授予 Root 權限</string> <string name="grant_root">授予 Root 權限</string>
<string name="select_at_least_one_app">請至少選擇一個應用程式!</string> <string name="select_at_least_one_app">請至少選擇一個應用程式!</string>
<string name="select_apps_music">Vanced ,不過是 YouTube 音樂!\n功能相對較少但足以滿足您的需要。</string> <string name="select_apps_music">Vanced ,不過是 YouTube 音樂!\n功能相對較少但足以滿足您的需要。</string>

View File

@ -18,14 +18,14 @@
<string name="are_you_rooted">Is Your Device Rooted?</string> <string name="are_you_rooted">Is Your Device Rooted?</string>
<string name="grant_root">Grant Root Permission</string> <string name="grant_root">Grant Root Permission</string>
<string name="select_at_least_one_app">Select at least one app!</string> <string name="select_at_least_one_app">Select at least one app!</string>
<string name="select_apps_music">Vanced, but for YouTube Music!\nrelatively less feature rich but fulfils your needs.</string> <string name="select_apps_music">Vanced, but for YouTube Music!\nrelatively less feature-rich but fulfills your needs.</string>
<string name="select_apps_vanced">YouTube Vanced is the stock Android YouTube App, but better!</string> <string name="select_apps_vanced">YouTube Vanced is the stock Android YouTube App, but better!</string>
<string name="lets_get_started">Let\'s get started</string> <string name="lets_get_started">Let\'s get started</string>
<string name="willing_to_use_root">Willing to use root version? Just hit the button below, else tap to continue</string> <string name="willing_to_use_root">Willing to use the root version? Just hit the button below, else tap to continue</string>
<!-- Home Page --> <!-- Home Page -->
<string name="about_app">About %1$s</string> <string name="about_app">About %1$s</string>
<string name="app_changelog_tooltip">Tap on the card to see changelog.</string> <string name="app_changelog_tooltip">Tap on the card to see the changelog.</string>
<string name="changelog">Changelog</string> <string name="changelog">Changelog</string>
<string name="downloading_file">Downloading %1$s</string> <string name="downloading_file">Downloading %1$s</string>
<string name="install">Install</string> <string name="install">Install</string>
@ -37,7 +37,7 @@
<string name="unavailable">Unavailable</string> <string name="unavailable">Unavailable</string>
<string name="update">Update</string> <string name="update">Update</string>
<string name="useful_links">Useful Links</string> <string name="useful_links">Useful Links</string>
<string name="support_us">Support US!</string> <string name="support_us">Support us!</string>
<!-- Settings --> <!-- Settings -->
<string name="accent_color">Accent Color</string> <string name="accent_color">Accent Color</string>
@ -47,7 +47,7 @@
<string name="accent_red">Red</string> <string name="accent_red">Red</string>
<string name="accent_yellow">Yellow</string> <string name="accent_yellow">Yellow</string>
<string name="category_appearance">Appearance</string> <string name="category_appearance">Appearance</string>
<string name="category_behaviour">Behaviour</string> <string name="category_behaviour">Behavior</string>
<string name="clear_files">Clear downloaded files</string> <string name="clear_files">Clear downloaded files</string>
<string name="cleared_files">Successfully cleared files</string> <string name="cleared_files">Successfully cleared files</string>
<string name="firebase_title">Firebase Analytics</string> <string name="firebase_title">Firebase Analytics</string>
@ -69,7 +69,7 @@
<!-- Dialogs --> <!-- Dialogs -->
<string name="advanced">Advanced</string> <string name="advanced">Advanced</string>
<string name="app_install_files_detected">%1$s installation files detected!</string> <string name="app_install_files_detected">%1$s installation files detected!</string>
<string name="app_install_files_detected_summary">Manager detected that all necessary files for %1$s installation were found. Do you want to install?</string> <string name="app_install_files_detected_summary">Manager detected that all necessary files for %1$s installation were found. Do you want to install it?</string>
<string name="checking_updates">Checking for updates…</string> <string name="checking_updates">Checking for updates…</string>
<string name="chosen_lang">Language(s): %1$s</string> <string name="chosen_lang">Language(s): %1$s</string>
<string name="chosen_theme">Theme: %1$s</string> <string name="chosen_theme">Theme: %1$s</string>
@ -77,12 +77,12 @@
<string name="guide">Guide</string> <string name="guide">Guide</string>
<string name="hold_on">Stop!</string> <string name="hold_on">Stop!</string>
<string name="installing_app">Installing %1$s</string> <string name="installing_app">Installing %1$s</string>
<string name="magisk_vanced">You are using the Magisk/TWRP version of Vanced, which is discontinued and cannot be updated using this app. Please remove it by removing the magisk module/using TWRP Vanced uninstaller.</string> <string name="magisk_vanced">You are using the Magisk/TWRP version of Vanced, which is discontinued and cannot be updated using this app. Please remove it by removing the Magisk module/using TWRP Vanced uninstaller.</string>
<string name="miui_one_title">MIUI detected!</string> <string name="miui_one_title">MIUI detected!</string>
<string name="miui_one">In order to install Vanced, you MUST disable MIUI Optimisations in the developer settings. (You can ignore this warning if you are using 20.2.20 or later xiaomi.eu based ROM)</string> <string name="miui_one">To install Vanced, you MUST disable MIUI Optimisations in the developer settings. (You can ignore this warning if you are using 20.2.20 or later xiaomi.eu based ROM)</string>
<string name="error">Error</string> <string name="error">Error</string>
<string name="redownload">Redownload</string> <string name="redownload">Redownload</string>
<string name="security_context">Make sure that you downloaded the app from vancedapp.com, the Vanced Discord server or the Vanced GitHub</string> <string name="security_context">Make sure that you downloaded the app from vancedapp.com, the Vanced Discord server, or the Vanced GitHub</string>
<string name="success">Success!</string> <string name="success">Success!</string>
<string name="app_installation_preferences">%1$s Installation Preferences</string> <string name="app_installation_preferences">%1$s Installation Preferences</string>
<string name="vanced_installed">Vanced has successfully been installed! Open now?</string> <string name="vanced_installed">Vanced has successfully been installed! Open now?</string>
@ -103,15 +103,15 @@
<string name="vanced_team">Vanced Team</string> <string name="vanced_team">Vanced Team</string>
<!-- Error messages --> <!-- Error messages -->
<string name="chown_fail">Failed to `chown` apk to system owner, please try again.</string> <string name="chown_fail">Failed to `chown` APK to system owner, please try again.</string>
<string name="error_downloading">Error Downloading %1$s</string> <string name="error_downloading">Error Downloading %1$s</string>
<string name="failed_uninstall">Failed to uninstall package %1$s</string> <string name="failed_uninstall">Failed to uninstall package %1$s</string>
<string name="files_missing_va">Failed to locate the required files for installation. Re-download the installation files, then try again.</string> <string name="files_missing_va">Failed to locate the required files for installation. Re-download the installation files, then try again.</string>
<string name="ifile_missing">Failed to locate apk file for black/dark theme from storage, please try again.</string> <string name="ifile_missing">Failed to locate apk file for black/dark theme from storage, please try again.</string>
<string name="installation_aborted">Installation failed because user aborted the installation.</string> <string name="installation_aborted">Installation failed because the user aborted the installation.</string>
<string name="installation_blocked">Installation failed because user blocked the installation.</string> <string name="installation_blocked">Installation failed because the user blocked the installation.</string>
<string name="installation_downgrade">Installation failed because user tried to downgrade the package. Uninstall updates from stock YouTube app, then try again.</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 the app conflicts with an already installed app. Uninstall the current version of Vanced, 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 Vanced, 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_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_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> <string name="installation_invalid">Installation failed because the apk files are corrupted, please try again.</string>