0
0
Fork 0
mirror of https://github.com/YTVanced/VancedManager synced 2024-11-27 13:33:00 +00:00

Variant tab rewrite, home screen and navigation optimisations

This commit is contained in:
Xinto 2020-09-21 11:53:42 +04:00
parent f44249f462
commit cf9fa512e7
19 changed files with 412 additions and 402 deletions

View file

@ -1,14 +1,89 @@
package com.vanced.manager.adapter package com.vanced.manager.adapter
import androidx.fragment.app.Fragment import android.content.ClipData
import androidx.fragment.app.FragmentActivity import android.content.ClipboardManager
import androidx.viewpager2.adapter.FragmentStateAdapter import android.content.Context
import com.vanced.manager.ui.fragments.MainFragment import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.tabs.TabLayoutMediator
import com.vanced.manager.R
import com.vanced.manager.databinding.ViewHomeBinding
import com.vanced.manager.ui.viewmodels.HomeViewModel
class VariantAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) { class VariantAdapter(private val viewModel: HomeViewModel, private val context: Context) : RecyclerView.Adapter<VariantAdapter.VariantAdapterHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VariantAdapterHolder {
val view = ViewHomeBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return VariantAdapterHolder(view, context)
}
override fun onBindViewHolder(holder: VariantAdapterHolder, position: Int) {
val variants = arrayOf("nonroot", "root")
holder.bind(variants[position], viewModel)
}
override fun getItemCount(): Int = 2 override fun getItemCount(): Int = 2
override fun createFragment(position: Int): Fragment = MainFragment() class VariantAdapterHolder(private val homeBinding: ViewHomeBinding, private val context: Context) : RecyclerView.ViewHolder(homeBinding.root) {
private var isExpanded: Boolean = false
fun bind(variant: String, viewModel: HomeViewModel) {
with (homeBinding) {
homeBinding.variant = variant
homeBinding.viewModel = viewModel
with(includeChangelogsLayout) {
changelogButton.setOnClickListener {
with (includeChangelogsLayout) {
viewpager.visibility = if (isExpanded) View.GONE else View.VISIBLE
tablayout.visibility = if (isExpanded) View.GONE else View.VISIBLE
changelogButton.animate().apply {
rotation(if (isExpanded) 0F else 180F)
interpolator = AccelerateDecelerateInterpolator()
}
isExpanded = !isExpanded
}
}
viewpager.adapter = ChangelogAdapter(variant, viewModel)
val nonrootTitles = arrayOf("Vanced", "Music", "microG", "Manager")
val rootTitles = arrayOf("Vanced", "Manager")
TabLayoutMediator(tablayout, viewpager) { tab, position ->
tab.text =
if (variant == "root") {
rootTitles[position]
} else {
nonrootTitles[position]
}
}.attach()
}
includeVancedLayout.vancedCard.setOnLongClickListener {
versionToast("Vanced", viewModel.vanced.get()?.installedVersionName?.get()!!)
true
}
includeMusicLayout.musicCard.setOnLongClickListener {
versionToast("Music", viewModel.music.get()?.installedVersionName?.get()!!)
true
}
includeMicrogLayout.microgCard.setOnLongClickListener {
versionToast("MicroG", viewModel.microg.get()?.installedVersionName?.get()!!)
true
}
}
}
private fun versionToast(name: String, app: String?) {
val clip = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clip.setPrimaryClip(ClipData.newPlainText(name, app))
Toast.makeText(context, context.getString(R.string.version_toast, name), Toast.LENGTH_LONG).show()
}
}
} }

View file

@ -4,15 +4,15 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build import android.os.Build
import android.widget.Toast import android.widget.Toast
import androidx.preference.PreferenceManager
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.downloader.Error import com.downloader.Error
import com.downloader.OnDownloadListener import com.downloader.OnDownloadListener
import com.downloader.PRDownloader import com.downloader.PRDownloader
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.logEvent
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.core.App import com.vanced.manager.core.App
import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.vancedProgress import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.vancedProgress
import com.vanced.manager.utils.AppUtils.installing
import com.vanced.manager.utils.AppUtils.mutableInstall import com.vanced.manager.utils.AppUtils.mutableInstall
import com.vanced.manager.utils.InternetTools import com.vanced.manager.utils.InternetTools
import com.vanced.manager.utils.InternetTools.baseUrl import com.vanced.manager.utils.InternetTools.baseUrl
@ -199,6 +199,10 @@ object VancedDownloader {
private fun prepareInstall(variant: String, context: Context) { private fun prepareInstall(variant: String, context: Context) {
vancedProgress.get()?.showDownloadBar?.set(false) vancedProgress.get()?.showDownloadBar?.set(false)
vancedProgress.get()?.showInstallCircle?.set(true) vancedProgress.get()?.showInstallCircle?.set(true)
FirebaseAnalytics.getInstance(context).logEvent(FirebaseAnalytics.Event.SELECT_ITEM) {
param("Vanced Variant", variant)
theme?.let { param("Vanced Theme", it) }
}
if (variant == "root") if (variant == "root")
installVancedRoot(context) installVancedRoot(context)
else else

View file

@ -16,14 +16,14 @@ import kotlinx.coroutines.launch
open class DataModel( open class DataModel(
private val jsonObject: JsonObject?, private val jsonObject: JsonObject?,
variant: String = "nonroot",
app: String, app: String,
private val context: Context private val context: Context
) { ) {
private val appPkg = private val appPkg =
when (app) { when (app) {
"vanced" -> if (variant == "root") "com.google.android.youtube" else "com.vanced.android.youtube" "vanced" -> "com.vanced.android.youtube"
"vancedRoot" -> "com.google.android.youtube"
"microg" -> "com.mgoogle.android.gms" "microg" -> "com.mgoogle.android.gms"
else -> "com.vanced.android.apps.youtube.music" else -> "com.vanced.android.apps.youtube.music"
} }

View file

@ -5,20 +5,22 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.MenuItem import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.navigation.NavDestination
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin import com.crowdin.platform.Crowdin
import com.crowdin.platform.LoadingStateListener import com.crowdin.platform.LoadingStateListener
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessaging
import com.topjohnwu.superuser.Shell
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.adapter.VariantAdapter
import com.vanced.manager.databinding.ActivityMainBinding import com.vanced.manager.databinding.ActivityMainBinding
import com.vanced.manager.ui.dialogs.DialogContainer import com.vanced.manager.ui.dialogs.DialogContainer
import com.vanced.manager.ui.fragments.HomeFragmentDirections
import com.vanced.manager.ui.fragments.SettingsFragmentDirections
import com.vanced.manager.ui.fragments.UpdateCheckFragment import com.vanced.manager.ui.fragments.UpdateCheckFragment
import com.vanced.manager.utils.AppUtils.installing import com.vanced.manager.utils.AppUtils.installing
import com.vanced.manager.utils.InternetTools import com.vanced.manager.utils.InternetTools
@ -31,6 +33,7 @@ import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding lateinit var binding: ActivityMainBinding
private val navHost by lazy { findNavController(R.id.nav_host) }
private val loadingObserver = object : LoadingStateListener { private val loadingObserver = object : LoadingStateListener {
val tag = "VMLocalisation" val tag = "VMLocalisation"
@ -44,33 +47,6 @@ class MainActivity : AppCompatActivity() {
} }
private val tabListener = object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
if (tab.position == 1 && !Shell.rootAccess()) {
Toast.makeText(this@MainActivity, getString(R.string.root_not_granted), Toast.LENGTH_SHORT).show()
return
}
getDefaultSharedPreferences(this@MainActivity).edit().putString("vanced_variant",
when (tab.position) {
1 -> "root"
else -> "nonroot"
}
).apply()
}
override fun onTabUnselected(tab: TabLayout.Tab) {
return
}
override fun onTabReselected(tab: TabLayout.Tab) {
return
}
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setFinalTheme(this) setFinalTheme(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -79,35 +55,34 @@ class MainActivity : AppCompatActivity() {
with(binding) { with(binding) {
lifecycleOwner = this@MainActivity lifecycleOwner = this@MainActivity
setSupportActionBar(homeToolbar) setSupportActionBar(homeToolbar)
mainViewpager.adapter = VariantAdapter(this@MainActivity) homeToolbar.setupWithNavController(this@MainActivity.navHost, AppBarConfiguration(this@MainActivity.navHost.graph))
TabLayoutMediator(mainTablayout, mainViewpager) { tab, position -> }
tab.text = if (position == 1) "root" else "nonroot" navHost.addOnDestinationChangedListener { _, currFrag: NavDestination, _ ->
}.attach() setDisplayHomeAsUpEnabled(currFrag.id != R.id.home_fragment)
mainTablayout.getTabAt(
if (getDefaultSharedPreferences(this@MainActivity).getString("vanced_variant", "nonroot") == "root")
1
else
0
)?.select()
} }
initDialogs() initDialogs()
} }
override fun onBackPressed() {
if (!navHost.popBackStack())
finish()
}
private fun setDisplayHomeAsUpEnabled(isNeeded: Boolean) {
binding.homeToolbar.navigationIcon = if (isNeeded) ContextCompat.getDrawable(this, R.drawable.ic_keyboard_backspace_black_24dp) else null
}
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
Crowdin.unregisterDataLoadingObserver(loadingObserver) Crowdin.unregisterDataLoadingObserver(loadingObserver)
binding.mainTablayout.removeOnTabSelectedListener(tabListener)
} }
override fun onResume() { override fun onResume() {
setFinalTheme(this) setFinalTheme(this)
super.onResume() super.onResume()
Crowdin.registerDataLoadingObserver(loadingObserver) Crowdin.registerDataLoadingObserver(loadingObserver)
binding.mainTablayout.addOnTabSelectedListener(tabListener)
} }
override fun recreate() { override fun recreate() {
@ -116,18 +91,25 @@ class MainActivity : AppCompatActivity() {
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (installing.value!!)
return false
when (item.itemId) { when (item.itemId) {
android.R.id.home -> { android.R.id.home -> {
return false onBackPressedDispatcher.onBackPressed()
return true
} }
R.id.toolbar_about -> { R.id.toolbar_about -> {
return false navHost.navigate(HomeFragmentDirections.toAboutFragment())
return true
} }
R.id.toolbar_settings -> { R.id.toolbar_settings -> {
return false navHost.navigate(HomeFragmentDirections.toSettingsFragment())
return true
} }
R.id.dev_settings -> { R.id.dev_settings -> {
return false navHost.navigate(SettingsFragmentDirections.toDevSettingsFragment())
return true
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }

View file

@ -0,0 +1,33 @@
package com.vanced.manager.ui.core
import android.content.Context
import android.util.AttributeSet
import android.widget.LinearLayout
open class SlidingWidthLinearLayout: LinearLayout {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(
context,
attrs
)
var xFraction: Float
get() {
val width = width
return if (width != 0)
x / getWidth()
else
x
}
set(xFraction) {
val width = width
val newWidth =
if (width > 0)
xFraction * width
else
(1).toFloat()
x = newWidth
}
}

View file

@ -24,8 +24,6 @@ class DevSettingsFragment: PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.dev_settings, rootKey) setPreferencesFromResource(R.xml.dev_settings, rootKey)
val ftSwitch: Preference? = findPreference("firststart_switch") val ftSwitch: Preference? = findPreference("firststart_switch")
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext()) val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
@ -56,7 +54,7 @@ class DevSettingsFragment: PreferenceFragmentCompat() {
"32bit" "32bit"
} }
findPreference<Preference>("device_os")?.summary = "${Build.VERSION.CODENAME} (API ${Build.VERSION.SDK_INT})" findPreference<Preference>("device_os")?.summary = "${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})"
val forceUpdate: Preference? = findPreference("force_update") val forceUpdate: Preference? = findPreference("force_update")
forceUpdate?.setOnPreferenceClickListener { forceUpdate?.setOnPreferenceClickListener {

View file

@ -1,43 +1,62 @@
package com.vanced.manager.ui.fragments package com.vanced.manager.ui.fragments
import android.content.* import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
import android.view.animation.AccelerateDecelerateInterpolator import android.view.animation.AnimationUtils
import android.widget.Toast import android.widget.Toast
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import com.topjohnwu.superuser.Shell
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.adapter.ChangelogAdapter import com.vanced.manager.adapter.VariantAdapter
import com.vanced.manager.databinding.FragmentHomeBinding import com.vanced.manager.databinding.FragmentHomeBinding
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.utils.AppUtils
open class HomeFragment : Fragment(), View.OnClickListener { open class HomeFragment : Fragment() {
private lateinit var binding: FragmentHomeBinding private lateinit var binding: FragmentHomeBinding
private lateinit var variant: String private val viewModel: HomeViewModel by viewModels()
private var isExpanded: Boolean = false
private val viewModel: HomeViewModel by viewModels {
HomeViewModelFactory(requireActivity().application, variant)
}
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) } private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) }
private val tabListener = object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
if (tab.position == 1 && !Shell.rootAccess()) {
Toast.makeText(requireActivity(), getString(R.string.root_not_granted), Toast.LENGTH_SHORT).show()
}
val variant = if (tab.position == 1) "root" else "nonroot"
getDefaultSharedPreferences(requireActivity()).edit().putString("vanced_variant", variant).apply()
}
override fun onTabUnselected(tab: TabLayout.Tab) {
return
}
override fun onTabReselected(tab: TabLayout.Tab) {
return
}
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
requireActivity().title = getString(R.string.title_home) requireActivity().title = getString(R.string.title_home)
setHasOptionsMenu(true) setHasOptionsMenu(true)
variant = if (requireActivity().findViewById<TabLayout>(R.id.main_tablayout).selectedTabPosition == 1) "root" else "nonroot"
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false) binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
binding.viewModel = viewModel
return binding.root return binding.root
} }
@ -51,73 +70,30 @@ open class HomeFragment : Fragment(), View.OnClickListener {
}) })
with(binding) { with(binding) {
includeChangelogsLayout.changelogButton.setOnClickListener(this@HomeFragment) mainViewpager.adapter = VariantAdapter(viewModel, requireActivity())
TabLayoutMediator(mainTablayout, mainViewpager) { tab, position ->
includeVancedLayout.vancedCard.setOnLongClickListener { val variants = arrayOf("nonroot", "root")
versionToast("Vanced", viewModel?.vanced?.get()?.installedVersionName?.get()!!) tab.text = variants[position]
true
}
includeMusicLayout.musicCard.setOnLongClickListener {
versionToast("Music", viewModel?.music?.get()?.installedVersionName?.get()!!)
true
}
includeMicrogLayout.microgCard.setOnLongClickListener {
versionToast("MicroG", viewModel?.microg?.get()?.installedVersionName?.get()!!)
true
}
}
with(binding.includeChangelogsLayout) {
viewpager.adapter = ChangelogAdapter(variant, this@HomeFragment.viewModel)
val nonrootTitles = arrayOf("Vanced", "Music", "microG", "Manager")
val rootTitles = arrayOf("Vanced", "Manager")
TabLayoutMediator(tablayout, viewpager) { tab, position ->
tab.text =
if (variant == "root") {
rootTitles[position]
} else {
nonrootTitles[position]
}
}.attach() }.attach()
mainTablayout.getTabAt(if (getDefaultSharedPreferences(requireActivity()).getString("vanced_variant", "nonroot") == "root") 1 else 0)?.select()
} }
} AppUtils.installing.observe(viewLifecycleOwner, { value ->
if (value) hideTab() else showTab()
})
override fun onClick(v: View?) {
when (v?.id) {
R.id.changelog_button -> cardExpandCollapse()
}
}
private fun versionToast(name: String, app: String?) {
val clip = requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clip.setPrimaryClip(ClipData.newPlainText(name, app))
Toast.makeText(activity, getString(R.string.version_toast, name), Toast.LENGTH_LONG).show()
}
private fun cardExpandCollapse() {
with(binding.includeChangelogsLayout) {
viewpager.visibility = if (isExpanded) View.GONE else View.VISIBLE
tablayout.visibility = if (isExpanded) View.GONE else View.VISIBLE
changelogButton.animate().apply {
rotation(if (isExpanded) 0F else 180F)
interpolator = AccelerateDecelerateInterpolator()
}
isExpanded = !isExpanded
}
} }
override fun onPause() { override fun onPause() {
localBroadcastManager.unregisterReceiver(broadcastReceiver)
super.onPause() super.onPause()
localBroadcastManager.unregisterReceiver(broadcastReceiver)
binding.mainTablayout.removeOnTabSelectedListener(tabListener)
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
registerReceivers() registerReceivers()
binding.mainTablayout.addOnTabSelectedListener(tabListener)
} }
private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
@ -129,6 +105,28 @@ open class HomeFragment : Fragment(), View.OnClickListener {
} }
} }
private fun hideTab() {
val tabHide = AnimationUtils.loadAnimation(requireActivity(), R.anim.tablayout_exit)
with(binding) {
if (mainTablayout.visibility != View.GONE) {
mainTablayout.startAnimation(tabHide)
mainTablayout.visibility = View.GONE
}
mainViewpager.isUserInputEnabled = false
}
}
private fun showTab() {
val tabShow = AnimationUtils.loadAnimation(requireActivity(), R.anim.tablayout_enter)
with(binding) {
if (mainTablayout.visibility != View.VISIBLE) {
mainTablayout.visibility = View.VISIBLE
mainTablayout.startAnimation(tabShow)
}
mainViewpager.isUserInputEnabled = true
}
}
private fun registerReceivers() { private fun registerReceivers() {
val intentFilter = IntentFilter() val intentFilter = IntentFilter()
intentFilter.addAction(INSTALL_FAILED) intentFilter.addAction(INSTALL_FAILED)

View file

@ -1,123 +0,0 @@
package com.vanced.manager.ui.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.activity.OnBackPressedCallback
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.fragment.NavHostFragment
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.tabs.TabLayout
import com.vanced.manager.R
import com.vanced.manager.databinding.FragmentMainBinding
import com.vanced.manager.ui.MainActivity
import com.vanced.manager.utils.AppUtils.installing
import kotlin.system.exitProcess
class MainFragment : Fragment() {
private lateinit var binding: FragmentMainBinding
private lateinit var navHost: NavController
private lateinit var act: MainActivity
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setHasOptionsMenu(true)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val navHostFragment = childFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment
navHost = navHostFragment.navController
act = requireActivity() as MainActivity
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if(!navHost.popBackStack()) {
exitProcess(0)
}
}
}
act.onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
val tabLayout = act.binding.mainTablayout
installing.observe(viewLifecycleOwner, { value ->
if (value)
hideTab(tabLayout)
else
showTab(tabLayout)
})
navHost.addOnDestinationChangedListener { _, currFrag: NavDestination, _ ->
setDisplayHomeAsUpEnabled(currFrag.id != R.id.home_fragment)
if (currFrag.id != R.id.home_fragment)
hideTab(tabLayout)
else
showTab(tabLayout)
}
}
private fun hideTab(tabLayout: TabLayout) {
val tabHide = AnimationUtils.loadAnimation(act, R.anim.tablayout_exit)
if (tabLayout.visibility != View.GONE) {
tabLayout.startAnimation(tabHide)
tabLayout.visibility = View.GONE
}
act.binding.mainViewpager.isUserInputEnabled = false
}
private fun showTab(tabLayout: TabLayout) {
val tabShow = AnimationUtils.loadAnimation(act, R.anim.tablayout_enter)
if (tabLayout.visibility != View.VISIBLE) {
tabLayout.visibility = View.VISIBLE
tabLayout.startAnimation(tabShow)
}
act.binding.mainViewpager.isUserInputEnabled = true
}
private fun setDisplayHomeAsUpEnabled(isNeeded: Boolean) {
act.binding.homeToolbar.navigationIcon = if (isNeeded) ContextCompat.getDrawable(act, R.drawable.ic_keyboard_backspace_black_24dp) else null
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (installing.value!!)
return false
when (item.itemId) {
android.R.id.home -> {
requireActivity().onBackPressedDispatcher.onBackPressed()
return true
}
R.id.toolbar_about -> {
navHost.navigate(HomeFragmentDirections.toAboutFragment())
return true
}
R.id.toolbar_settings -> {
navHost.navigate(HomeFragmentDirections.toSettingsFragment())
return true
}
R.id.dev_settings -> {
navHost.navigate(SettingsFragmentDirections.toDevSettingsFragment())
return true
}
else -> super.onOptionsItemSelected(item)
}
return false
}
}

View file

@ -5,7 +5,10 @@ import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.widget.Toast import android.widget.Toast
import androidx.preference.* import androidx.preference.*
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.perf.FirebasePerformance
import com.vanced.manager.R import com.vanced.manager.R
import java.io.File import java.io.File
@ -46,6 +49,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
} }
} }
findPreference<SwitchPreference>("firebase_analytics")?.setOnPreferenceChangeListener { _, newValue ->
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(newValue as Boolean)
FirebasePerformance.getInstance().isPerformanceCollectionEnabled = newValue
FirebaseAnalytics.getInstance(requireActivity()).setAnalyticsCollectionEnabled(newValue)
true
}
val themePref = preferenceScreen.sharedPreferences.getString("theme_mode", "Follow System") val themePref = preferenceScreen.sharedPreferences.getString("theme_mode", "Follow System")
findPreference<ListPreference>("theme_mode")?.apply { findPreference<ListPreference>("theme_mode")?.apply {
summary = when (themePref) { summary = when (themePref) {

View file

@ -24,10 +24,8 @@ import com.vanced.manager.ui.events.Event
import com.vanced.manager.utils.AppUtils.installing import com.vanced.manager.utils.AppUtils.installing
import com.vanced.manager.utils.InternetTools import com.vanced.manager.utils.InternetTools
import com.vanced.manager.utils.PackageHelper.uninstallApk import com.vanced.manager.utils.PackageHelper.uninstallApk
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
open class HomeViewModel(application: Application, val variant: String): AndroidViewModel(application) { open class HomeViewModel(application: Application): AndroidViewModel(application) {
val app = application val app = application
private val managerApp = application as App private val managerApp = application as App
@ -35,6 +33,7 @@ open class HomeViewModel(application: Application, val variant: String): Android
//val variant = getDefaultSharedPreferences(application).getString("vanced_variant", "nonroot") //val variant = getDefaultSharedPreferences(application).getString("vanced_variant", "nonroot")
val vanced = ObservableField<DataModel>() val vanced = ObservableField<DataModel>()
val vancedRoot = ObservableField<DataModel>()
val microg = ObservableField<DataModel>() val microg = ObservableField<DataModel>()
val music = ObservableField<DataModel>() val music = ObservableField<DataModel>()
val manager = ObservableField<DataModel>() val manager = ObservableField<DataModel>()
@ -48,6 +47,7 @@ open class HomeViewModel(application: Application, val variant: String): Android
fetching.set(true) fetching.set(true)
managerApp.loadJsonAsync() managerApp.loadJsonAsync()
vanced.get()?.fetch() vanced.get()?.fetch()
vancedRoot.get()?.fetch()
music.get()?.fetch() music.get()?.fetch()
microg.get()?.fetch() microg.get()?.fetch()
manager.get()?.fetch() manager.get()?.fetch()
@ -58,12 +58,6 @@ open class HomeViewModel(application: Application, val variant: String): Android
//private val microgSnackbar = Snackbar.make(, R.string.no_microg, Snackbar.LENGTH_LONG).setAction(R.string.install) { downloadMicrog(getApplication()) } //private val microgSnackbar = Snackbar.make(, R.string.no_microg, Snackbar.LENGTH_LONG).setAction(R.string.install) { downloadMicrog(getApplication()) }
private val microgToast = Toast.makeText(app, R.string.no_microg, Toast.LENGTH_LONG) private val microgToast = Toast.makeText(app, R.string.no_microg, Toast.LENGTH_LONG)
private val vancedPkgName =
if (variant == "root")
"com.google.android.youtube"
else
"com.vanced.android.youtube"
fun openMicrogSettings() { fun openMicrogSettings() {
try { try {
val intent = Intent() val intent = Intent()
@ -93,7 +87,7 @@ open class HomeViewModel(application: Application, val variant: String): Android
InternetTools.openUrl(url, color, getApplication()) InternetTools.openUrl(url, color, getApplication())
} }
fun installVanced() { fun installVanced(variant: String) {
if (!installing.value!!) { if (!installing.value!!) {
if (!fetching.get()) { if (!fetching.get()) {
if (variant == "nonroot" && !microg.get()?.isAppInstalled?.get()!!) { if (variant == "nonroot" && !microg.get()?.isAppInstalled?.get()!!) {
@ -130,7 +124,7 @@ open class HomeViewModel(application: Application, val variant: String): Android
Toast.makeText(getApplication(), R.string.installation_wait, Toast.LENGTH_SHORT).show() Toast.makeText(getApplication(), R.string.installation_wait, Toast.LENGTH_SHORT).show()
} }
fun uninstallVanced() = uninstallApk(vancedPkgName, app) fun uninstallVanced(variant: String) = uninstallApk(if (variant == "root") "com.google.android.youtube" else "com.vanced.android.youtube", app)
fun uninstallMusic() = uninstallApk("com.vanced.android.apps.youtube.music", app) fun uninstallMusic() = uninstallApk("com.vanced.android.apps.youtube.music", app)
fun uninstallMicrog() = uninstallApk("com.mgoogle.android.gms", app) fun uninstallMicrog() = uninstallApk("com.mgoogle.android.gms", app)
@ -142,10 +136,11 @@ open class HomeViewModel(application: Application, val variant: String): Android
init { init {
fetching.set(true) fetching.set(true)
vanced.set(DataModel(managerApp.vanced, variant, "vanced", app)) vanced.set(DataModel(managerApp.vanced, "vanced", app))
music.set(DataModel(managerApp.music, app = "music", context = app)) vancedRoot.set(DataModel(managerApp.vanced, "vancedRoot", app))
microg.set(DataModel(managerApp.microg, app = "microg", context = app)) music.set(DataModel(managerApp.music, "music", app))
manager.set(DataModel(managerApp.manager, app = "manager", context = app)) microg.set(DataModel(managerApp.microg, "microg", app))
manager.set(DataModel(managerApp.manager, "manager", app))
vancedProgress.set(ProgressModel()) vancedProgress.set(ProgressModel())
musicProgress.set(ProgressModel()) musicProgress.set(ProgressModel())
microgProgress.set(ProgressModel()) microgProgress.set(ProgressModel())

View file

@ -1,14 +0,0 @@
package com.vanced.manager.ui.viewmodels
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class HomeViewModelFactory(private val application: Application, private val variant: String = "nonroot") :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return HomeViewModel(application, variant) as T
}
}

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorPrimaryVariant">
<path
android:fillColor="@android:color/white"
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"/>
</vector>

View file

@ -25,29 +25,15 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <fragment
android:id="@+id/variant_tab_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_below="@id/home_appbar" android:layout_below="@id/home_appbar"
android:orientation="vertical"> android:layout_alignParentBottom="true"
app:defaultNavHost="true"
<com.google.android.material.tabs.TabLayout app:navGraph="@navigation/mobile_navigation" />
android:id="@+id/main_tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorSurface"
app:tabIndicatorColor="?colorPrimary"
app:tabSelectedTextColor="?colorPrimary"
app:tabTextColor="?colorPrimary" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout> </RelativeLayout>

View file

@ -1,90 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout <layout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<data> <com.vanced.manager.ui.core.SlidingWidthLinearLayout
android:id="@+id/variant_tab_container"
<import type="android.view.View" />
<variable
name="viewModel"
type="com.vanced.manager.ui.viewmodels.HomeViewModel" />
</data>
<com.vanced.manager.ui.core.SlidingSwipeRefreshLayout
android:id="@+id/home_refresh"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
bind:refreshing="@{viewModel.fetching}"
bind:onRefreshListener="@{()-> viewModel.fetchData()}">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include <com.google.android.material.tabs.TabLayout
android:id="@+id/include_vanced_layout" android:id="@+id/main_tablayout"
layout="@layout/include_vanced"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp" android:background="?colorSurface"
android:layout_marginTop="@dimen/stdp" app:tabIndicatorColor="?colorPrimary"
android:layout_marginEnd="@dimen/stdp" app:tabSelectedTextColor="?colorPrimary"
bind:viewModel="@{viewModel}" /> app:tabTextColor="?colorPrimary" />
<include <androidx.viewpager2.widget.ViewPager2
android:id="@+id/include_music_layout" android:id="@+id/main_viewpager"
layout="@layout/include_music"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginStart="@dimen/stdp" android:layout_weight="1" />
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp"
android:visibility="@{viewModel.variant.equals(`nonroot`) ? View.VISIBLE : View.GONE}"
bind:viewModel="@{viewModel}" />
<include </com.vanced.manager.ui.core.SlidingWidthLinearLayout>
android:id="@+id/include_microg_layout"
layout="@layout/include_microg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp"
android:visibility="@{viewModel.variant.equals(`nonroot`) ? View.VISIBLE : View.GONE}"
bind:viewModel="@{viewModel}" />
<include
android:id="@+id/include_changelogs_layout"
layout="@layout/include_changelogs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp" />
<include
layout="@layout/include_useful_links"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp"
bind:viewModel="@{viewModel}" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</com.vanced.manager.ui.core.SlidingSwipeRefreshLayout>
</layout> </layout>

View file

@ -3,18 +3,27 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout <LinearLayout
android:id="@+id/variant_tab_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView <com.google.android.material.tabs.TabLayout
android:id="@+id/main_tablayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:id="@+id/nav_host" android:background="?colorSurface"
android:name="androidx.navigation.fragment.NavHostFragment" app:tabIndicatorColor="?colorPrimary"
app:defaultNavHost="true" app:tabSelectedTextColor="?colorPrimary"
app:navGraph="@navigation/mobile_navigation" /> app:tabTextColor="?colorPrimary" />
</FrameLayout> <androidx.viewpager2.widget.ViewPager2
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</layout> </layout>

View file

@ -12,6 +12,10 @@
name="viewModel" name="viewModel"
type="com.vanced.manager.ui.viewmodels.HomeViewModel" /> type="com.vanced.manager.ui.viewmodels.HomeViewModel" />
<variable
name="vancedVariant"
type="String" />
</data> </data>
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
@ -47,11 +51,11 @@
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/vanced_installbtn" android:id="@+id/vanced_installbtn"
style="@style/ButtonStyle" style="@style/ButtonStyle"
android:text="@{viewModel.vanced.buttonTxt}" android:text="@{vancedVariant.equals(`root`) ? viewModel.vancedRoot.buttonTxt : viewModel.vanced.buttonTxt}"
android:textColor="@color/White" android:textColor="@color/White"
android:backgroundTint="?colorPrimary" android:backgroundTint="?colorPrimary"
android:onClick="@{()-> viewModel.installVanced()}" android:onClick="@{()-> viewModel.installVanced(vancedVariant)}"
app:icon="@{viewModel.vanced.buttonIcon}" app:icon="@{vancedVariant.equals(`root`) ? viewModel.vancedRoot.buttonIcon : viewModel.vanced.buttonIcon}"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -65,8 +69,8 @@
<ImageView <ImageView
android:id="@+id/vanced_uninstallbtn" android:id="@+id/vanced_uninstallbtn"
style="@style/ClickableImageWidget.Red" style="@style/ClickableImageWidget.Red"
android:onClick="@{()-> viewModel.uninstallVanced()}" android:onClick="@{()-> viewModel.uninstallVanced(vancedVariant)}"
android:visibility="@{viewModel.vanced.appInstalled ? View.VISIBLE : View.GONE}" android:visibility="@{vancedVariant.equals(`root`) ? (viewModel.vancedRoot.appInstalled ? View.VISIBLE : View.GONE) : (viewModel.vanced.appInstalled ? View.VISIBLE : View.GONE)}"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/vanced_title_buttons_barrier" app:layout_constraintTop_toBottomOf="@id/vanced_title_buttons_barrier"
@ -105,7 +109,7 @@
<TextView <TextView
android:id="@+id/vanced_installed_version" android:id="@+id/vanced_installed_version"
style="@style/AppVer.Bold" style="@style/AppVer.Bold"
android:text="@{viewModel.vanced.installedVersionName}" /> android:text="@{vancedVariant.equals(`root`) ? viewModel.vancedRoot.installedVersionName : viewModel.vanced.installedVersionName}" />
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,95 @@
<?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">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="com.vanced.manager.ui.viewmodels.HomeViewModel" />
<variable
name="variant"
type="String" />
</data>
<com.vanced.manager.ui.core.SlidingSwipeRefreshLayout
android:id="@+id/home_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
bind:refreshing="@{viewModel.fetching}"
bind:onRefreshListener="@{()-> viewModel.fetchData()}">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/include_vanced_layout"
layout="@layout/include_vanced"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp"
bind:viewModel="@{viewModel}"
bind:vancedVariant="@{variant}"/>
<include
android:id="@+id/include_music_layout"
layout="@layout/include_music"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp"
android:visibility="@{variant.equals(`nonroot`) ? View.VISIBLE : View.GONE}"
bind:viewModel="@{viewModel}" />
<include
android:id="@+id/include_microg_layout"
layout="@layout/include_microg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp"
android:visibility="@{variant.equals(`nonroot`) ? View.VISIBLE : View.GONE}"
bind:viewModel="@{viewModel}" />
<include
android:id="@+id/include_changelogs_layout"
layout="@layout/include_changelogs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp" />
<include
layout="@layout/include_useful_links"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/stdp"
android:layout_marginTop="@dimen/stdp"
android:layout_marginEnd="@dimen/stdp"
bind:viewModel="@{viewModel}" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</com.vanced.manager.ui.core.SlidingSwipeRefreshLayout>
</layout>

View file

@ -43,6 +43,8 @@
<string name="chosen_theme">Theme: %1$s</string> <string name="chosen_theme">Theme: %1$s</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_summary">This lets us collect information about app performance and crash logs</string>
<string name="link_title">Use Chrome Custom Tabs</string> <string name="link_title">Use Chrome Custom Tabs</string>
<string name="link_custom_tabs">Links will open in Chrome Custom Tabs</string> <string name="link_custom_tabs">Links will open in Chrome Custom Tabs</string>
<string name="link_external_browser">Links will open in an External Browser</string> <string name="link_external_browser">Links will open in an External Browser</string>

View file

@ -30,6 +30,13 @@
android:defaultValue="true" android:defaultValue="true"
android:icon="@drawable/ic_notifications_black_24dp"/> android:icon="@drawable/ic_notifications_black_24dp"/>
<SwitchPreference
android:key="firebase_analytics"
android:defaultValue="true"
android:title="@string/firebase_title"
android:summary="@string/firebase_summary"
android:icon="@drawable/ic_baseline_bug_report_24" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory