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 {
dataBinding true
viewBinding true
}
// To inline the bytecode built with JVM target 1.8 into
@ -120,7 +121,6 @@ dependencies {
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'com.google.android.material:material:1.3.0-alpha03'
// Other
// JSON parser
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.vanced.manager.BuildConfig.*
import com.vanced.manager.utils.InternetTools.loadJson
import kotlinx.coroutines.*
open class App: Application() {
private val prefs by lazy { getDefaultSharedPreferences(this) }
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
override fun onCreate() {
loadJson(this)
scope.launch { loadJson(this@App) }
super.onCreate()
PRDownloader.initialize(this)
@ -46,6 +48,4 @@ open class App: Application() {
super.onConfigurationChanged(newConfig)
Crowdin.onConfigurationChanged()
}
}

View File

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

View File

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

View File

@ -28,7 +28,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
object VancedDownloader {
object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
private lateinit var prefs: SharedPreferences
private lateinit var defPrefs: SharedPreferences
@ -36,7 +36,7 @@ object VancedDownloader {
private var installUrl: String? = null
private var variant: String? = null
private var theme: String? = null
private var lang: MutableList<String>? = null
private var lang = mutableListOf<String>()
private lateinit var themePath: String
@ -56,7 +56,9 @@ object VancedDownloader {
downloadPath = context.getExternalFilesDir("vanced/$variant")?.path
File(downloadPath.toString()).deleteRecursively()
installUrl = defPrefs.getInstallUrl()
lang = prefs.getString("lang", getDefaultVancedLanguages())?.split(", ")?.toMutableList()
prefs.getString("lang", getDefaultVancedLanguages())?.let {
lang = it.split(", ").toMutableList()
}
theme = prefs.getString("theme", "dark")
vancedVersion = defPrefs.getString("vanced_version", "latest")?.getLatestAppVersion(vancedVersions.get()?.value ?: listOf(""))
themePath = "$installUrl/apks/v$vancedVersion/$variant/Theme"
@ -73,7 +75,7 @@ object VancedDownloader {
context: Context,
type: String = "theme"
) {
CoroutineScope(Dispatchers.IO).launch {
launch {
val url =
when (type) {
"theme" -> "$themePath/$theme.apk"
@ -112,7 +114,7 @@ object VancedDownloader {
"lang" -> {
count++
succesfulLangCount++
if (count < lang?.size!!)
if (count < lang.size)
downloadSplits(context, "lang")
else
startVancedInstall(context)
@ -132,9 +134,9 @@ object VancedDownloader {
if (type == "lang") {
count++
when {
count < lang?.size!! -> downloadSplits(context, "lang")
count < lang.size -> downloadSplits(context, "lang")
succesfulLangCount == 0 -> {
lang?.add("en")
lang.add("en")
downloadSplits(context, "lang")
}
else -> startVancedInstall(context)
@ -160,8 +162,4 @@ object VancedDownloader {
else
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.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
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.databinding.DialogInstallationFilesDetectedBinding
import com.vanced.manager.utils.Extensions.show
import kotlinx.coroutines.launch
class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() {

View File

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

View File

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

View File

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

View File

@ -4,46 +4,41 @@ import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.preference.PreferenceManager
import com.vanced.manager.R
import com.vanced.manager.databinding.FragmentAboutBinding
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.utils.Extensions.show
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 var count = 0
private var startMillSec: Long = 0
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
requireActivity().title = getString(R.string.title_about)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_about, container, false)
binding.viewModel = viewModel
return binding.root
) = FragmentAboutBinding.inflate(inflater, container, false)
override fun otherSetups() {
dataBind()
}
@SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.aboutHeader.setOnClickListener { AppInfoDialog(getString(R.string.app_name), AppCompatResources.getDrawable(requireActivity(), R.mipmap.ic_launcher), manager.get()?.string("changelog")).show(requireActivity()) }
view.setOnTouchListener { _, event: MotionEvent ->
private fun dataBind() {
requireActivity().title = getString(R.string.title_about)
binding.aboutHeader.root.setOnClickListener { AppInfoDialog(getString(R.string.app_name), AppCompatResources.getDrawable(requireActivity(), R.mipmap.ic_launcher), manager.get()?.string("changelog")).show(requireActivity()) }
binding.root.setOnTouchListener { _, event: MotionEvent ->
val eventAction = event.action
if (eventAction == MotionEvent.ACTION_UP) {
val time = System.currentTimeMillis()
@ -68,5 +63,7 @@ class AboutFragment : Fragment() {
}
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.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.preference.PreferenceManager.*
import com.topjohnwu.superuser.Shell
import com.vanced.manager.R
import com.vanced.manager.databinding.FragmentGrantRootBinding
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 onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_grant_root, container, false)
return binding.root
) = FragmentGrantRootBinding.inflate(inflater, container, false)
override fun otherSetups() {
bindData()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.grantRootFinishFab.setOnClickListener(this)
binding.grantRootFab.setOnClickListener(this)
}
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 bindData() {
with(binding) {
grantRootFinishFab.setOnClickListener { navigateToFirstLaunch() }
grantRootFab.setOnClickListener { grantRoot() }
}
}
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.LinkAdapter
import com.vanced.manager.adapter.SponsorAdapter
import com.vanced.manager.databinding.FragmentGrantRootBinding
import com.vanced.manager.databinding.FragmentHomeBinding
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.dialogs.DialogContainer.installAlertBuilder
import com.vanced.manager.ui.viewmodels.HomeViewModel
import com.vanced.manager.ui.viewmodels.HomeViewModelFactory
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 {
HomeViewModelFactory(requireActivity())
}
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) }
private val prefs by lazy { PreferenceManager.getDefaultSharedPreferences(requireActivity()) }
private lateinit var tooltip: ViewTooltip
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
requireActivity().title = getString(R.string.title_home)
setHasOptionsMenu(true)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
return binding.root
) = FragmentHomeBinding.inflate(inflater, container, false)
override fun otherSetups() {
bindData()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
private fun bindData() {
requireActivity().title = getString(R.string.title_home)
setHasOptionsMenu(true)
with(binding) {
viewModel = this@HomeFragment.viewModel
homeRefresh.setOnRefreshListener { viewModel.fetchData() }
tooltip = ViewTooltip
.on(recyclerAppList)
.position(ViewTooltip.Position.TOP)
@ -91,9 +97,13 @@ open class HomeFragment : Fragment() {
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() {
super.onPause()
localBroadcastManager.unregisterReceiver(broadcastReceiver)
@ -122,15 +132,5 @@ open class HomeFragment : Fragment() {
intentFilter.addAction(REFRESH_HOME)
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.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.preference.PreferenceManager.*
import androidx.recyclerview.widget.LinearLayoutManager
import com.vanced.manager.R
import com.vanced.manager.adapter.SelectAppsAdapter
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(
inflater: LayoutInflater, container: ViewGroup?,
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_select_apps, container, false)
return binding.root
) = FragmentSelectAppsBinding.inflate(inflater, container, false)
override fun otherSetups() {
bindData()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val selectAdapter = SelectAppsAdapter(requireActivity())
val prefs = getDefaultSharedPreferences(requireActivity())
binding.selectAppsRecycler.apply {
private fun bindData() {
with(binding) {
initRecycler()
selectAppsFab.setOnClickListener { actionOnClickAppsFab() }
}
}
private fun FragmentSelectAppsBinding.initRecycler() {
selectAdapter = SelectAppsAdapter(requireActivity())
selectAppsRecycler.apply {
layoutManager = LinearLayoutManager(requireActivity())
setHasFixedSize(true)
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
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 androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.preference.PreferenceManager.*
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.perf.FirebasePerformance
import com.vanced.manager.R
import com.vanced.manager.adapter.GetNotifAdapter
import com.vanced.manager.core.ext.showDialogRefl
import com.vanced.manager.databinding.FragmentSettingsBinding
import com.vanced.manager.ui.core.BindingFragment
import com.vanced.manager.ui.dialogs.*
import com.vanced.manager.utils.LanguageHelper.getLanguageFormat
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()) }
override fun onCreateView(
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
) = FragmentSettingsBinding.inflate(inflater, container, false)
override fun otherSetups() {
setHasOptionsMenu(true)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_settings, container, false)
return binding.root
bindData()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
private fun bindData() {
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())
adapter = GetNotifAdapter(requireActivity())
}
}
binding.firebase.setOnCheckedListener { _, isChecked ->
private fun FragmentSettingsBinding.bindFirebase() {
firebase.setOnCheckedListener { _, isChecked ->
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(isChecked)
FirebasePerformance.getInstance().isPerformanceCollectionEnabled = isChecked
FirebaseAnalytics.getInstance(requireActivity()).setAnalyticsCollectionEnabled(isChecked)
}
}
binding.managerVariant.apply {
private fun FragmentSettingsBinding.bindManagerVariant() {
managerVariant.apply {
prefs.getString("vanced_variant", "nonroot")?.let { setSummary(it) }
setOnClickListener {
ManagerVariantDialog().show(requireActivity().supportFragmentManager, "")
}
setOnClickListener { showDialogRefl<ManagerVariantDialog>() }
}
binding.clearFiles.setOnClickListener {
}
private fun FragmentSettingsBinding.bindClearFiles() {
clearFiles.setOnClickListener {
with(requireActivity()) {
listOf("vanced/nonroot", "vanced/root", "music/nonroot", "music/root", "microg").forEach { dir ->
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()
}
}
}
private fun FragmentSettingsBinding.bindManagerTheme() {
val themePref = prefs.getString("manager_theme", "System Default")
binding.managerTheme.apply {
managerTheme.apply {
setSummary(
when (themePref) {
"Light" -> getString(R.string.theme_light)
"Dark" -> getString(R.string.theme_dark)
else -> getString(R.string.system_default)
}
when (themePref) {
LIGHT -> getString(R.string.theme_light)
DARK -> getString(R.string.theme_dark)
else -> getString(R.string.system_default)
}
)
setOnClickListener {
ManagerThemeDialog().show(requireActivity().supportFragmentManager, "")
}
setOnClickListener { showDialogRefl<ManagerThemeDialog>() }
}
}
private fun FragmentSettingsBinding.bindManagerAccentColor() {
val accentPref = prefs.getString("manager_accent", "Blue")
binding.managerAccentColor.apply {
managerAccentColor.apply {
setSummary(
when (accentPref) {
"Blue" -> getString(R.string.accent_blue)
"Red" -> getString(R.string.accent_red)
"Green" -> getString(R.string.accent_green)
"Yellow" -> getString(R.string.accent_yellow)
else -> getString(R.string.accent_purple)
}
when (accentPref) {
BLUE -> getString(R.string.accent_blue)
RED -> getString(R.string.accent_red)
GREEN -> getString(R.string.accent_green)
YELLOW -> getString(R.string.accent_yellow)
else -> getString(R.string.accent_purple)
}
)
setOnClickListener {
ManagerAccentColorDialog().show(requireActivity().supportFragmentManager, "")
}
setOnClickListener { showDialogRefl<ManagerAccentColorDialog>() }
}
}
private fun FragmentSettingsBinding.bindManagerLanguage() {
val langPref = prefs.getString("manager_lang", "System Default")
binding.managerLanguage.apply {
setSummary(getLanguageFormat(requireActivity(), langPref!!))
setOnClickListener {
ManagerLanguageDialog().show(requireActivity().supportFragmentManager, "")
}
}
binding.selectApps.setOnClickListener {
SelectAppsDialog().show(requireActivity().supportFragmentManager, "")
managerLanguage.apply {
setSummary(getLanguageFormat(requireActivity(), requireNotNull(langPref)))
setOnClickListener { showDialogRefl<ManagerLanguageDialog>() }
}
}
@ -113,5 +136,4 @@ class SettingsFragment : Fragment() {
}
super.onCreateOptionsMenu(menu, inflater)
}
}

View File

@ -2,31 +2,28 @@ package com.vanced.manager.ui.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.vanced.manager.R
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 onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
override fun binding(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_welcome, container, false)
return binding.root
) = FragmentWelcomeBinding.inflate(inflater, container, false)
override fun otherSetups() {
bindData()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.welcomeGetStarted.setOnClickListener {
findNavController().navigate(WelcomeFragmentDirections.welcomeToSelectApps())
}
private fun bindData() {
binding.welcomeGetStarted.setOnClickListener { navigateToWelcome() }
}
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.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin
import com.google.android.material.button.MaterialButton
@ -35,6 +36,7 @@ import com.vanced.manager.utils.PackageHelper.musicApkExists
import com.vanced.manager.utils.PackageHelper.uninstallApk
import com.vanced.manager.utils.PackageHelper.uninstallRootApk
import com.vanced.manager.utils.PackageHelper.vancedInstallFilesExist
import kotlinx.coroutines.launch
open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
@ -48,10 +50,12 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
val manager = ObservableField<DataModel>()
fun fetchData() {
activity.setRefreshing(true)
loadJson(activity)
Crowdin.forceUpdate(activity)
activity.setRefreshing(false)
viewModelScope.launch {
activity.setRefreshing(true)
loadJson(activity)
Crowdin.forceUpdate(activity)
activity.setRefreshing(false)
}
}
private val microgToast = Toast.makeText(activity, R.string.no_microg, Toast.LENGTH_LONG)
@ -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 {
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)))
activity.setRefreshing(false)
}
}

View File

@ -15,7 +15,7 @@ import java.io.File
import java.io.IOException
import java.security.MessageDigest
object AppUtils {
object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
const val vancedPkg = "com.vanced.android.youtube"
const val vancedRootPkg = "com.google.android.youtube"
@ -24,25 +24,25 @@ object AppUtils {
const val microgPkg = "com.mgoogle.android.gms"
const val managerPkg = APPLICATION_ID
fun sendRefresh(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
fun sendRefresh(context: Context): Job {
return launch {
delay(700)
LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(HomeFragment.REFRESH_HOME))
}
}
fun sendCloseDialog(context: Context) {
fun sendCloseDialog(context: Context): Job {
downloadProgress.get()?.installing?.set(false)
CoroutineScope(Dispatchers.IO).launch {
return launch {
delay(700)
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)
//Delay error broadcast until activity (and fragment) get back to the screen
CoroutineScope(Dispatchers.IO).launch {
return launch {
delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED)
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)
CoroutineScope(Dispatchers.IO).launch {
return launch {
delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED)
intent.putExtra("errorMsg", getErrorMessage(error.joinToString(), context))
@ -134,6 +134,4 @@ object AppUtils {
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.model.ProgressModel
import com.vanced.manager.utils.AppUtils.sendCloseDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
object DownloadHelper {
@ -41,8 +40,8 @@ object DownloadHelper {
downloadProgress.set(ProgressModel())
}
fun downloadManager(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
suspend fun downloadManager(context: Context) =
withContext(Dispatchers.IO) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk")
.build()
@ -82,6 +81,4 @@ object DownloadHelper {
})
}
}
}

View File

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

View File

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

View File

@ -12,15 +12,11 @@ object JsonHelper {
private var dataMap: HashMap<String, JsonObject> = HashMap()
suspend fun getJson(url: String): JsonObject? {
return try {
if(dataMap.containsKey(url)) {
dataMap[url]!!
} else {
dataMap[url] = getSuspendJson(url)
dataMap[url]!!
}
} catch (e: Exception) {
null
return if (dataMap.containsKey(url)) {
dataMap[url]
} else {
dataMap[url] = getSuspendJson(url)
dataMap[url]
}
}

View File

@ -6,28 +6,20 @@ import java.io.InputStreamReader
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? {
val line: String
var input: BufferedReader? = null
try {
val p = Runtime.getRuntime().exec("getprop $propname")
input = BufferedReader(InputStreamReader(p.inputStream), 1024)
line = input.readLine()
input.close()
return try {
val process = Runtime.getRuntime().exec("getprop $propname")
input = BufferedReader(InputStreamReader(process.inputStream), 1024)
input.readLine()
} catch (e: IOException) {
return null
null
} finally {
if (input != null) {
try {
input.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
input?.close()
}
return line
}
}

View File

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

View File

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

View File

@ -1,62 +1,58 @@
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface">
<TextView
android:id="@+id/grant_root_header"
android:text="@string/are_you_rooted"
app:layout_constraintTop_toTopOf="parent"
style="@style/WelcomeHeaderTitle"/>
<TextView
android:id="@+id/grant_root_header"
style="@style/WelcomeHeaderTitle"
android:text="@string/are_you_rooted"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/grant_root_description"
android:text="@string/willing_to_use_root"
android:textSize="13sp"
app:layout_constraintTop_toBottomOf="@id/grant_root_header"
style="@style/WelcomeHeaderSubtitle"/>
<TextView
android:id="@+id/grant_root_description"
style="@style/WelcomeHeaderSubtitle"
android:text="@string/willing_to_use_root"
android:textSize="13sp"
app:layout_constraintTop_toBottomOf="@id/grant_root_header" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/grant_root_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#1F1F1F"
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
android:id="@+id/grant_root_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#1F1F1F"
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" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/grant_root"
android:textColor="#ffffff"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/grant_root_fab"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/grant_root"
android:textColor="#ffffff"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/grant_root_fab" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
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>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/grant_root_finish_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="45dp"
android:layout_marginEnd="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>

View File

@ -1,75 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<data>
<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"
<androidx.core.widget.NestedScrollView
android:layout_width="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_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">
android:orientation="vertical">
<LinearLayout
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_app_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="3"
tools:listitem="@layout/view_app"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_app_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="3"
tools:listitem="@layout/view_app" />
<TextView
android:layout_marginHorizontal="24dp"
android:layout_marginTop="12dp"
android:text="@string/useful_links"
style="@style/CardTextHeader"/>
<TextView
style="@style/CardTextHeader"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="12dp"
android:text="@string/useful_links" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_sponsors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="2"
tools:listitem="@layout/view_sponsor"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_sponsors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:nestedScrollingEnabled="false"
tools:itemCount="2"
tools:listitem="@layout/view_sponsor" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_links"
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>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_links"
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>

View File

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

View File

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

View File

@ -1,37 +1,32 @@
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface">
android:layout_height="wrap_content"
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
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="@dimen/top_header_margin"
app:srcCompat="@drawable/ic_launch_text"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/welcome_get_started"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:letterSpacing="0.15"
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>
<com.google.android.material.button.MaterialButton
android:id="@+id/welcome_get_started"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:letterSpacing="0.15"
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>

View File

@ -1,73 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<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_height="wrap_content"
app:cardBackgroundColor="?colorLinkBG"
app:cardElevation="0dp"
app:contentPaddingBottom="8dp"
app:contentPaddingTop="2dp">
<data>
<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"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="?colorLinkBG"
app:cardElevation="0dp"
app:contentPaddingBottom="8dp"
app:contentPaddingTop="2dp">
android:layout_height="match_parent"
android:orientation="vertical">
<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_height="match_parent"
android:orientation="vertical">
android:layout_height="wrap_content"
app:alignItems="center"
app:flexDirection="row"
app:justifyContent="space_evenly">
<TextView
android:id="@+id/about_card_vancedTeam"
style="@style/CardTextHeader"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="@string/sources"
<com.google.android.material.button.MaterialButton
android:id="@+id/about_github_button"
style="@style/SocialButtonStyle"
app:icon="@drawable/ic_github"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/about_license_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:alignItems="center"
app:flexDirection="row"
app:justifyContent="space_evenly">
<com.google.android.material.button.MaterialButton
android:id="@+id/about_github_button"
style="@style/SocialButtonStyle"
android:onClick='@{()-> viewModel.openUrl("https://github.com/YTVanced/VancedInstaller")}'
app:icon="@drawable/ic_github"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/about_license_button"
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>
<com.google.android.material.button.MaterialButton
android:id="@+id/about_license_button"
style="@style/SocialButtonStyle"
android:fontFamily="@font/exo_semibold"
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>

View File

@ -15,9 +15,9 @@
<string name="are_you_rooted">Er Din Enhed Rooted?</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_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="lets_get_started">Let\'s get started</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 er standard YouTube App, men bedre!</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>
<!-- Home Page -->
<string name="about_app">Om %1$s</string>
@ -61,7 +61,7 @@
<string name="update_not_found">Ingen nye opdateringer</string>
<string name="variant">Variant</string>
<!-- 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_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>

View File

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

View File

@ -7,35 +7,35 @@
<string name="save">Salva</string>
<string name="select_apps">Seleziona le Tue App</string>
<!-- Main Activity -->
<string name="title_about">Autori</string>
<string name="title_about">Informazioni</string>
<string name="title_home">Manager</string>
<string name="title_settings">Impostazioni</string>
<string name="update_manager">Aggiorna Manager</string>
<!-- Welcome Page -->
<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_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="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 -->
<string name="about_app">A proposito di %1$s</string>
<string name="app_changelog_tooltip">Tocca sulla scheda per vedere il changelog.</string>
<string name="changelog">Changelog</string>
<string name="about_app">Informazioni su %1$s</string>
<string name="app_changelog_tooltip">Tocca la scheda per vedere le novità.</string>
<string name="changelog">Novità</string>
<string name="downloading_file">Download in corso di %1$s</string>
<string name="install">Installa</string>
<string name="button_reinstall">Reinstalla</string>
<string name="version_installed">Versione installata:</string>
<string name="latest">Ultima versione:</string>
<string name="version_installed">Installata:</string>
<string name="latest">Disponibile:</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="update">Aggiorna</string>
<string name="useful_links">Link utili</string>
<string name="useful_links">Link Utili</string>
<string name="support_us">Sostienici!</string>
<!-- 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_green">Verde</string>
<string name="accent_purple">Viola</string>
@ -45,26 +45,26 @@
<string name="category_behaviour">Comportamento</string>
<string name="clear_files">Cancella i file scaricati</string>
<string name="cleared_files">File cancellati con successo</string>
<string name="firebase_title">Analitica 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_title">Analisi Firebase</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="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_title">Utilizza le Schede Personalizzate di Chrome</string>
<string name="link_custom_tabs">I link verranno aperti nelle Schede Personalizzate di Chrome</string>
<string name="system_default">Predefinito di Sistema</string>
<string name="theme">Tema</string>
<string name="theme_dark">Tema scuro</string>
<string name="theme_light">Tema chiaro</string>
<string name="theme_dark">Tema Scuro</string>
<string name="theme_light">Tema Chiaro</string>
<string name="update_url">Aggiorna l\'URL del canale</string>
<string name="push_notifications">Notifiche push di %1$s</string>
<string name="push_notifications">Notifiche Push di %1$s</string>
<string name="push_notifications_summary">Ricevi notifiche push quando un aggiornamento per %1$s è disponibile</string>
<string name="update_center">Centro aggiornamenti</string>
<string name="update_center">Centro Aggiornamenti</string>
<string name="update_not_found">Nessun nuovo aggiornamento</string>
<string name="variant">Variante</string>
<!-- Dialogs -->
<string name="advanced">Avanzate</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="checking_updates">Verificando gli aggiornamenti…</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">Verifica aggiornamenti…</string>
<string name="chosen_lang">Lingue: %1$s</string>
<string name="chosen_theme">Tema: %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">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="redownload">Scarica di nuovo</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="success">Fatto!</string>
<string name="redownload">Scarica nuovamente</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">Riuscito!</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="version">Versione</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="welcome">Benvenuto</string>
<!-- Install Page -->
<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>
<!-- About Page -->
<string name="manager_dev">Sviluppatori di Manager</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 -->
<string name="chown_fail">Impossibile cambiare il proprietario dell\'apk in proprietario del sistema, sei pregato di riprovare.</string>
<string name="error_downloading">Errore nel download di %1$s</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="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="ifile_missing">Impossibile trovare il file apk per il tema nero/scuro dall\'archiviazione, sei pregato di riprovare.</string>
<string name="files_missing_va">Impossibile individuare i file richiesti per l\'installazione. Scaricali nuovamente e riprova.</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_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>
@ -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_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="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="path_missing">Impossibile trovare il percorso di installazione di stock di YouTube dopo l\'installazione divisa.</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 individuare il percorso di installazione di YouTube stock dopo l\'installazione divisa.</string>
</resources>

View File

@ -17,7 +17,7 @@
<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_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>
<!-- Home Page -->
<string name="about_app">%1$s について</string>
@ -61,7 +61,7 @@
<string name="update_not_found">アップデートはありません</string>
<string name="variant">種類</string>
<!-- 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_summary">%1$sのインストールに必要な全てのファイル準備が整いました。インストールしますか?</string>
<string name="checking_updates">アップデートを確認中...</string>

View File

@ -46,7 +46,7 @@
<string name="clear_files">Limpar arquivos baixados</string>
<string name="cleared_files">Arquivos limpos com sucesso</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="link_title">Usar 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="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="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="version">Versão</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="update_manager">Освежи Менаџера</string>
<!-- 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="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_vanced">YouTube Vanced is the stock Android YouTube App, but better!</string>
<string name="lets_get_started">Let\'s get started</string>
<string name="select_apps_music">Vanced, али за YouTube Music!\nрелативно са мање напредних карактеристикама, али ће задовољити ваше потребе.</string>
<string name="select_apps_vanced">YouTube Vanced је фабрички Android YouTube апликација, али много боља!</string>
<string name="lets_get_started">Хајде да почнемо</string>
<string name="willing_to_use_root">Имате ли намеру користити рутовану верзију? Само кликните на дугме доле, у супротном кликните за наставак</string>
<!-- Home Page -->
<string name="about_app">О %s</string>
@ -61,7 +61,7 @@
<string name="update_not_found">Нема нове верзије</string>
<string name="variant">Варијанта</string>
<!-- 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_summary">Менаџер је пронашао све датотеке за %1$s верзију инсталације. Да ли желите да инсталирате?</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="error">Грешка</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="app_installation_preferences">%1$s Installation Preferences</string>
<string name="app_installation_preferences">%1$s Инсталациона подешавања</string>
<string name="vanced_installed">Vanced је успешно инсталиран! Желите да га одмах отворите?</string>
<string name="version">Верзија</string>
<string name="music_installed">Vanced Music је успешно инсталиран! Желите да га одмах отворите?</string>

View File

@ -12,7 +12,7 @@
<string name="title_settings">設定</string>
<string name="update_manager">更新 Manager</string>
<!-- Welcome Page -->
<string name="are_you_rooted">您的裝置擁有 Root 權限嗎?</string>
<string name="are_you_rooted">您的裝置擁有 Root 權限嗎?</string>
<string name="grant_root">授予 Root 權限</string>
<string name="select_at_least_one_app">請至少選擇一個應用程式!</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="grant_root">Grant Root Permission</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="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 -->
<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="downloading_file">Downloading %1$s</string>
<string name="install">Install</string>
@ -37,7 +37,7 @@
<string name="unavailable">Unavailable</string>
<string name="update">Update</string>
<string name="useful_links">Useful Links</string>
<string name="support_us">Support US!</string>
<string name="support_us">Support us!</string>
<!-- Settings -->
<string name="accent_color">Accent Color</string>
@ -47,7 +47,7 @@
<string name="accent_red">Red</string>
<string name="accent_yellow">Yellow</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="cleared_files">Successfully cleared files</string>
<string name="firebase_title">Firebase Analytics</string>
@ -69,7 +69,7 @@
<!-- Dialogs -->
<string name="advanced">Advanced</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="chosen_lang">Language(s): %1$s</string>
<string name="chosen_theme">Theme: %1$s</string>
@ -77,12 +77,12 @@
<string name="guide">Guide</string>
<string name="hold_on">Stop!</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">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="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="app_installation_preferences">%1$s Installation Preferences</string>
<string name="vanced_installed">Vanced has successfully been installed! Open now?</string>
@ -103,15 +103,15 @@
<string name="vanced_team">Vanced Team</string>
<!-- 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="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="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_blocked">Installation failed because 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_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_aborted">Installation failed because the user aborted the installation.</string>
<string name="installation_blocked">Installation failed because the user blocked the installation.</string>
<string name="installation_downgrade">Installation failed because the user tried to downgrade the package. Uninstall updates from the stock YouTube app, then try again.</string>
<string name="installation_conflict">Installation failed because of the app conflicts with an already installed app. Uninstall the current version of 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_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>