Merge pull request #257 from HaliksaR/view-binding-dialogs

View binding dialogs
This commit is contained in:
Tornike Khintibidze 2020-11-15 20:08:41 +04:00 committed by GitHub
commit 8c44377e7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 482 additions and 380 deletions

View File

@ -3,7 +3,7 @@ package com.vanced.manager.adapter
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.*
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.florent37.viewtooltip.ViewTooltip import com.github.florent37.viewtooltip.ViewTooltip
import com.vanced.manager.R import com.vanced.manager.R
@ -46,10 +46,10 @@ class AppListAdapter(
holder.appCard.setOnClickListener { holder.appCard.setOnClickListener {
tooltip.close() tooltip.close()
AppInfoDialog( AppInfoDialog.newInstance(
apps[position], appName = apps[position],
dataModels[position]?.appIcon, appIcon = dataModels[position]?.appIcon,
dataModels[position]?.changelog?.get() changelog = dataModels[position]?.changelog?.get()
).show(context.supportFragmentManager, "info") ).show(context.supportFragmentManager, "info")
} }
} }

View File

@ -1,5 +0,0 @@
package com.vanced.manager.core.base
import androidx.fragment.app.Fragment
open class BaseFragment : Fragment()

View File

@ -20,29 +20,29 @@ object MicrogDownloader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
) = launch { ) = launch {
val url = microg.get()?.string("url") val url = microg.get()?.string("url")
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk") downloadProgress.value?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk")
.build() .build()
.setOnStartOrResumeListener { .setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) })) downloadProgress.value?.downloadingFile?.value = context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) })
} }
.setOnProgressListener { progress -> .setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
} }
.start(object : OnDownloadListener { .start(object : OnDownloadListener {
override fun onDownloadComplete() { override fun onDownloadComplete() {
startMicrogInstall(context) startMicrogInstall(context)
} }
override fun onError(error: Error?) { override fun onError(error: Error?) {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "microG")) downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, "microG")
} }
}) })
} }
fun startMicrogInstall(context: Context) { fun startMicrogInstall(context: Context) {
downloadProgress.get()?.installing?.set(true) downloadProgress.value?.installing?.value = true
downloadProgress.get()?.reset() downloadProgress.value?.reset()
install("${context.getExternalFilesDir("microg")}/microg.apk", context) install("${context.getExternalFilesDir("microg")}/microg.apk", context)
} }
} }

View File

@ -49,13 +49,13 @@ object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
launch { launch {
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk" val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
suspendCoroutine { suspendCoroutine {
downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build() .build()
.setOnStartOrResumeListener { .setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url))) downloadProgress.value?.downloadingFile?.value =context.getString(R.string.downloading_file, getFileNameFromUrl(url))
} }
.setOnProgressListener { progress -> .setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
} }
.start(object : OnDownloadListener { .start(object : OnDownloadListener {
override fun onDownloadComplete() { override fun onDownloadComplete() {
@ -90,7 +90,7 @@ object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
return return
} }
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "Music")) downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, "Music")
} }
}) })
} }
@ -99,8 +99,8 @@ object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
} }
fun startMusicInstall(context: Context) { fun startMusicInstall(context: Context) {
downloadProgress.get()?.installing?.set(true) downloadProgress.value?.installing?.value = true
downloadProgress.get()?.reset() downloadProgress.value?.reset()
if (variant == "root") if (variant == "root")
installMusicRoot(context) installMusicRoot(context)
else else

View File

@ -86,13 +86,13 @@ object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?") else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
} }
downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build() .build()
.setOnStartOrResumeListener { .setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url))) downloadProgress.value?.downloadingFile?.value = context.getString(R.string.downloading_file, getFileNameFromUrl(url))
} }
.setOnProgressListener { progress -> .setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
} }
.start(object : OnDownloadListener { .start(object : OnDownloadListener {
override fun onDownloadComplete() { override fun onDownloadComplete() {
@ -143,7 +143,7 @@ object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
} }
} else { } else {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, getFileNameFromUrl(url))) downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, getFileNameFromUrl(url))
} }
} }
}) })
@ -151,8 +151,8 @@ object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
} }
fun startVancedInstall(context: Context, variant: String? = this.variant) { fun startVancedInstall(context: Context, variant: String? = this.variant) {
downloadProgress.get()?.installing?.set(true) downloadProgress.value?.installing?.value = true
downloadProgress.get()?.reset() downloadProgress.value?.reset()
FirebaseAnalytics.getInstance(context).logEvent(FirebaseAnalytics.Event.SELECT_ITEM) { FirebaseAnalytics.getInstance(context).logEvent(FirebaseAnalytics.Event.SELECT_ITEM) {
variant?.let { param("vanced_variant", it) } variant?.let { param("vanced_variant", it) }
theme?.let { param("vanced_theme", it) } theme?.let { param("vanced_theme", it) }

View File

@ -1,24 +1,22 @@
package com.vanced.manager.model package com.vanced.manager.model
import androidx.databinding.ObservableBoolean import androidx.lifecycle.MutableLiveData
import androidx.databinding.ObservableField
import androidx.databinding.ObservableInt
open class ProgressModel { open class ProgressModel {
val downloadProgress = ObservableInt() val downloadProgress = MutableLiveData<Int>()
val downloadingFile = ObservableField<String>() val downloadingFile = MutableLiveData<String>()
val installing = ObservableBoolean() val installing = MutableLiveData<Boolean>()
var currentDownload: Int = 0 var currentDownload: Int = 0
fun reset() { fun reset() {
downloadProgress.set(0) downloadProgress.value = 0
downloadingFile.set("") downloadingFile.value = ""
} }
init { init {
installing.set(false) installing.value = false
reset() reset()
} }

View File

@ -0,0 +1,39 @@
package com.vanced.manager.ui.core
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
abstract class BindingDialogFragment<VB : ViewBinding> : AppCompatDialogFragment() {
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

@ -16,7 +16,7 @@ abstract class BindingFragment<VB : ViewBinding> : Fragment() {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
_binding = binding(inflater, container, savedInstanceState) _binding = binding(inflater, container, savedInstanceState)
otherSetups() otherSetups()
return binding.root return binding.root

View File

@ -10,8 +10,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader import com.downloader.PRDownloader
import com.vanced.manager.R import com.vanced.manager.R
@ -19,53 +18,87 @@ import com.vanced.manager.core.downloader.MicrogDownloader.downloadMicrog
import com.vanced.manager.core.downloader.MusicDownloader.downloadMusic import com.vanced.manager.core.downloader.MusicDownloader.downloadMusic
import com.vanced.manager.core.downloader.VancedDownloader.downloadVanced import com.vanced.manager.core.downloader.VancedDownloader.downloadVanced
import com.vanced.manager.databinding.DialogAppDownloadBinding import com.vanced.manager.databinding.DialogAppDownloadBinding
import com.vanced.manager.ui.core.BindingDialogFragment
import com.vanced.manager.utils.DownloadHelper.downloadProgress import com.vanced.manager.utils.DownloadHelper.downloadProgress
class AppDownloadDialog( class AppDownloadDialog : BindingDialogFragment<DialogAppDownloadBinding>() {
private val app: String,
private val installing: Boolean = false
) : DialogFragment() {
private lateinit var binding: DialogAppDownloadBinding companion object {
const val CLOSE_DIALOG = "close_dialog"
private const val TAG_APP = "TAG_APP"
private const val TAG_INSTALLING = "TAG_INSTALLING"
fun newInstance(
app: String,
installing: Boolean = false
): AppDownloadDialog = AppDownloadDialog().apply {
arguments = Bundle().apply {
putString(TAG_APP, app)
putBoolean(TAG_INSTALLING, installing)
}
}
}
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) } private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) }
private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
when (intent.action) { if (intent.action == CLOSE_DIALOG) {
CLOSE_DIALOG -> dismiss() dismiss()
} }
} }
} }
override fun onCreateView( override fun binding(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = DialogAppDownloadBinding.inflate(inflater, container, false)
if (dialog != null && dialog?.window != null) {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) override fun otherSetups() {
} dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
binding = DataBindingUtil.inflate(inflater, R.layout.dialog_app_download, container, false) bindData()
binding.progress = downloadProgress.get()
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { private fun bindData() {
super.onViewCreated(view, savedInstanceState) with(binding) {
isCancelable = false isCancelable = false
binding.appDownloadHeader.text = requireActivity().getString(R.string.installing_app, app) bindDownloadProgress()
binding.appDownloadCancel.setOnClickListener { val app = arguments?.getString(TAG_APP)
if (downloadProgress.get()?.installing?.get() == true) appDownloadHeader.text = app
return@setOnClickListener if (arguments?.getBoolean(TAG_INSTALLING) == false) {
when (app) {
PRDownloader.cancel(downloadProgress.get()!!.currentDownload) getString(R.string.vanced) -> downloadVanced(requireContext())
dismiss() getString(R.string.music) -> downloadMusic(requireContext())
getString(R.string.microg) -> downloadMicrog(requireContext())
}
}
} }
if (!installing) { }
when (app) {
requireActivity().getString(R.string.vanced) -> downloadVanced(requireActivity()) private fun DialogAppDownloadBinding.bindDownloadProgress() {
requireActivity().getString(R.string.music) -> downloadMusic(requireActivity()) with(downloadProgress) {
requireActivity().getString(R.string.microg) -> downloadMicrog(requireActivity()) observe(viewLifecycleOwner) { progressModel ->
progressModel.downloadProgress.observe(viewLifecycleOwner) {
appDownloadProgressbar.progress = it
}
progressModel.installing.observe(viewLifecycleOwner) { installing ->
appDownloadProgressbar.isVisible = !installing
appInstallProgressbar.isVisible = installing
appDownloadFile.isVisible = !installing
appDownloadCancel.isEnabled = !installing
appDownloadCancel.setOnClickListener {
if (installing) {
return@setOnClickListener
}
PRDownloader.cancel(downloadProgress.value?.currentDownload)
dismiss()
}
}
progressModel.downloadingFile.observe(viewLifecycleOwner) {
appDownloadFile.text = it
}
} }
} }
} }
@ -80,9 +113,4 @@ class AppDownloadDialog(
intentFilter.addAction(CLOSE_DIALOG) intentFilter.addAction(CLOSE_DIALOG)
localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter) localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter)
} }
companion object {
const val CLOSE_DIALOG = "close_dialog"
}
} }

View File

@ -5,34 +5,49 @@ import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil import androidx.core.graphics.drawable.toBitmap
import androidx.fragment.app.DialogFragment
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.databinding.DialogAppInfoBinding import com.vanced.manager.databinding.DialogAppInfoBinding
import com.vanced.manager.ui.core.BindingDialogFragment
class AppInfoDialog( class AppInfoDialog : BindingDialogFragment<DialogAppInfoBinding>() {
private val appName: String?,
private val appIcon: Drawable?,
private val changelog: String?
) : DialogFragment() {
private lateinit var binding: DialogAppInfoBinding companion object {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { private const val TAG_APP_NAME = "TAG_APP_NAME"
if (dialog != null && dialog?.window != null) { private const val TAG_APP_ICON = "TAG_APP_ICON"
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) private const val TAG_CHANGELOG = "TAG_CHANGELOG"
fun newInstance(
appName: String?,
appIcon: Drawable?,
changelog: String?
): AppInfoDialog = AppInfoDialog().apply {
arguments = Bundle().apply {
putString(TAG_APP_NAME, appName)
putString(TAG_CHANGELOG, changelog)
putParcelable(TAG_APP_ICON, appIcon?.toBitmap())
}
} }
binding = DataBindingUtil.inflate(inflater, R.layout.dialog_app_info, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun binding(
super.onViewCreated(view, savedInstanceState) inflater: LayoutInflater,
binding.aboutAppName.text = requireActivity().getString(R.string.about_app, appName) container: ViewGroup?,
binding.aboutAppImage.setImageDrawable(appIcon) savedInstanceState: Bundle?
binding.aboutAppChangelog.text = changelog ) = DialogAppInfoBinding.inflate(inflater, container, false)
override fun otherSetups() {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
bindData()
} }
private fun bindData() {
with(binding) {
aboutAppName.text = getString(R.string.about_app, arguments?.getString(TAG_APP_NAME))
aboutAppChangelog.text = arguments?.getString(TAG_CHANGELOG)
aboutAppImage.setImageBitmap(arguments?.getParcelable(TAG_APP_ICON))
}
}
} }

View File

@ -5,8 +5,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.core.downloader.MicrogDownloader.startMicrogInstall import com.vanced.manager.core.downloader.MicrogDownloader.startMicrogInstall
@ -14,7 +13,6 @@ import com.vanced.manager.core.downloader.MusicDownloader.startMusicInstall
import com.vanced.manager.core.downloader.VancedDownloader.startVancedInstall import com.vanced.manager.core.downloader.VancedDownloader.startVancedInstall
import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding
import com.vanced.manager.utils.Extensions.show import com.vanced.manager.utils.Extensions.show
import kotlinx.coroutines.launch
class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() { class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() {
@ -39,18 +37,23 @@ class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDial
dismiss() dismiss()
if (app == requireActivity().getString(R.string.vanced)) if (app == requireActivity().getString(R.string.vanced))
VancedPreferencesDialog().show(requireActivity()) VancedPreferencesDialog().show(requireActivity())
else else {
AppDownloadDialog(app).show(requireActivity()) AppDownloadDialog.newInstance(app).show(requireActivity())
}
} }
binding.installationDetectedInstall.setOnClickListener { binding.installationDetectedInstall.setOnClickListener {
dismiss() dismiss()
when (app) { when (app) {
requireActivity().getString(R.string.vanced) -> startVancedInstall(requireActivity(), getDefaultSharedPreferences(requireActivity()).getString("vanced_variant", "nonroot")) requireActivity().getString(R.string.vanced) -> startVancedInstall(requireActivity(),
getDefaultSharedPreferences(requireActivity()).getString("vanced_variant", "nonroot"))
requireActivity().getString(R.string.music) -> startMusicInstall(requireActivity()) requireActivity().getString(R.string.music) -> startMusicInstall(requireActivity())
requireActivity().getString(R.string.microg) -> startMicrogInstall(requireActivity()) requireActivity().getString(R.string.microg) -> startMicrogInstall(requireActivity())
} }
AppDownloadDialog(app, true).show(requireActivity()) AppDownloadDialog.newInstance(
app = app,
installing = true
).show(requireActivity())
} }
} }

View File

@ -10,13 +10,19 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader import com.downloader.PRDownloader
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.core.downloader.MicrogDownloader
import com.vanced.manager.core.downloader.MusicDownloader
import com.vanced.manager.core.downloader.VancedDownloader
import com.vanced.manager.databinding.DialogAppDownloadBinding
import com.vanced.manager.databinding.DialogManagerUpdateBinding import com.vanced.manager.databinding.DialogManagerUpdateBinding
import com.vanced.manager.ui.core.BindingDialogFragment
import com.vanced.manager.utils.DownloadHelper.downloadManager import com.vanced.manager.utils.DownloadHelper.downloadManager
import com.vanced.manager.utils.DownloadHelper.downloadProgress import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.isUpdateAvailable import com.vanced.manager.utils.InternetTools.isUpdateAvailable
@ -24,9 +30,24 @@ import kotlinx.coroutines.launch
class ManagerUpdateDialog( class ManagerUpdateDialog(
private val forceUpdate: Boolean private val forceUpdate: Boolean
) : DialogFragment() { ) : BindingDialogFragment<DialogManagerUpdateBinding>() {
private lateinit var binding: DialogManagerUpdateBinding companion object {
const val CLOSE_DIALOG = "close_dialog"
private const val TAG_APP = "TAG_APP"
private const val TAG_INSTALLING = "TAG_INSTALLING"
fun newInstance(
app: String,
installing: Boolean = false
): AppDownloadDialog = AppDownloadDialog().apply {
arguments = Bundle().apply {
putString(TAG_APP, app)
putBoolean(TAG_INSTALLING, installing)
}
}
}
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) } private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) }
@ -38,21 +59,15 @@ class ManagerUpdateDialog(
} }
} }
override fun onCreateView( override fun binding(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ) = DialogManagerUpdateBinding.inflate(inflater, container, false)
if (dialog != null && dialog?.window != null) {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
isCancelable = false
binding = DataBindingUtil.inflate(inflater, R.layout.dialog_manager_update, container, false)
binding.progress = downloadProgress.get()
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun otherSetups() {
super.onViewCreated(view, savedInstanceState) dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
bindData()
lifecycleScope.launch { lifecycleScope.launch {
if (forceUpdate) { if (forceUpdate) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient) binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
@ -62,12 +77,30 @@ class ManagerUpdateDialog(
} }
binding.managerUpdateCancel.setOnClickListener { binding.managerUpdateCancel.setOnClickListener {
PRDownloader.cancel(downloadProgress.get()!!.currentDownload) PRDownloader.cancel(downloadProgress.value?.currentDownload)
dismiss() dismiss()
} }
} }
} }
private fun bindData() {
with(binding) {
isCancelable = false
bindDownloadProgress()
}
}
private fun DialogManagerUpdateBinding.bindDownloadProgress() {
with(downloadProgress) {
observe(viewLifecycleOwner) { progressModel ->
progressModel.downloadProgress.observe(viewLifecycleOwner) {
managerUpdateProgressbar.progress = it
managerUpdateProgressbar.isVisible = it != 0
}
}
}
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
registerReceiver() registerReceiver()
@ -87,9 +120,4 @@ class ManagerUpdateDialog(
intentFilter.addAction(CLOSE_DIALOG) intentFilter.addAction(CLOSE_DIALOG)
localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter) localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter)
} }
companion object {
const val CLOSE_DIALOG = "close_dialog"
}
} }

View File

@ -41,8 +41,9 @@ class MusicPreferencesDialog : BottomSheetDialogFragment() {
} }
binding.musicInstall.setOnClickListener { binding.musicInstall.setOnClickListener {
dismiss() dismiss()
AppDownloadDialog(requireActivity().getString(R.string.music)).show(requireActivity()) AppDownloadDialog.newInstance(
app = getString(R.string.music)
).show(requireActivity())
} }
} }
} }

View File

@ -4,47 +4,58 @@ import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import androidx.core.content.edit import androidx.core.content.edit
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences import androidx.preference.PreferenceManager.*
import com.google.android.material.button.MaterialButton import com.vanced.manager.databinding.DialogCustomUrlBinding
import com.vanced.manager.R import com.vanced.manager.ui.core.BindingDialogFragment
import com.vanced.manager.utils.Extensions.fetchData import com.vanced.manager.utils.Extensions.fetchData
import com.vanced.manager.utils.InternetTools.baseUrl import com.vanced.manager.utils.InternetTools.baseUrl
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class URLChangeDialog : DialogFragment() { class URLChangeDialog : BindingDialogFragment<DialogCustomUrlBinding>() {
override fun onCreateView( companion object {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? fun newInstance(): URLChangeDialog = URLChangeDialog().apply {
): View? { arguments = Bundle()
if (dialog != null && dialog?.window != null) {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
} }
return inflater.inflate(R.layout.dialog_custom_url, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun binding(
super.onViewCreated(view, savedInstanceState) inflater: LayoutInflater,
val urlField = view.findViewById<EditText>(R.id.url_input) container: ViewGroup?,
val fieldTxt = if (arguments != null) arguments?.getString("url") else getDefaultSharedPreferences(requireActivity()).getString("install_url", baseUrl) savedInstanceState: Bundle?
urlField.setText(fieldTxt, TextView.BufferType.EDITABLE) ) = DialogCustomUrlBinding.inflate(inflater, container, false)
view.findViewById<MaterialButton>(R.id.url_save).setOnClickListener {
val finalUrl =
if (urlField.text.startsWith("https://") || urlField.text.startsWith("http://"))
urlField.text.removeSuffix("/").toString()
else
"https://${urlField.text}".removeSuffix("/")
saveUrl(finalUrl) override fun otherSetups() {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
bindData()
}
private fun bindData() {
with(binding) {
urlInput.setText(
if (arguments != null) {
arguments?.getString("url")
} else {
getDefaultSharedPreferences(requireActivity()).getString("install_url", baseUrl)
},
TextView.BufferType.EDITABLE
)
urlSave.setOnClickListener {
val finalUrl = if (urlInput.text?.startsWith("https://") == true || urlInput.text?.startsWith("http://") == true) {
urlInput.text?.removeSuffix("/").toString()
} else {
"https://${urlInput.text}".removeSuffix("/")
}
saveUrl(finalUrl)
}
urlReset.setOnClickListener { saveUrl(baseUrl) }
} }
view.findViewById<MaterialButton>(R.id.url_reset).setOnClickListener { saveUrl(baseUrl) }
} }
private fun saveUrl(url: String) { private fun saveUrl(url: String) {

View File

@ -66,7 +66,9 @@ class VancedPreferencesDialog : BottomSheetDialogFragment() {
binding.vancedInstall.setOnClickListener { binding.vancedInstall.setOnClickListener {
dismiss() dismiss()
AppDownloadDialog(requireActivity().getString(R.string.vanced)).show(requireActivity()) AppDownloadDialog.newInstance(
app = getString(R.string.vanced)
).show(requireActivity())
} }
} }
} }

View File

@ -11,11 +11,11 @@ import androidx.core.content.edit
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.vanced.manager.R import com.vanced.manager.R
import com.vanced.manager.core.ext.showDialog
import com.vanced.manager.databinding.FragmentAboutBinding 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.core.BindingFragment
import com.vanced.manager.ui.dialogs.AppInfoDialog
import com.vanced.manager.ui.viewmodels.AboutViewModel import com.vanced.manager.ui.viewmodels.AboutViewModel
import com.vanced.manager.utils.Extensions.show
import com.vanced.manager.utils.InternetTools.manager import com.vanced.manager.utils.InternetTools.manager
class AboutFragment : BindingFragment<FragmentAboutBinding>() { class AboutFragment : BindingFragment<FragmentAboutBinding>() {
@ -37,7 +37,15 @@ class AboutFragment : BindingFragment<FragmentAboutBinding>() {
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
private fun dataBind() { private fun dataBind() {
requireActivity().title = getString(R.string.title_about) 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.aboutHeader.root.setOnClickListener {
showDialog(
AppInfoDialog.newInstance(
appName = getString(R.string.app_name),
appIcon = AppCompatResources.getDrawable(requireActivity(), R.mipmap.ic_launcher),
changelog = manager.get()?.string("changelog")
)
)
}
binding.root.setOnTouchListener { _, event: MotionEvent -> binding.root.setOnTouchListener { _, event: MotionEvent ->
val eventAction = event.action val eventAction = event.action
if (eventAction == MotionEvent.ACTION_UP) { if (eventAction == MotionEvent.ACTION_UP) {

View File

@ -100,7 +100,7 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
when (app) { when (app) {
activity.getString(R.string.vanced) -> VancedPreferencesDialog().show(activity) activity.getString(R.string.vanced) -> VancedPreferencesDialog().show(activity)
activity.getString(R.string.music) -> MusicPreferencesDialog().show(activity) activity.getString(R.string.music) -> MusicPreferencesDialog().show(activity)
else -> AppDownloadDialog(app).show(activity) else -> AppDownloadDialog.newInstance(app).show(activity)
} }
return return
@ -109,18 +109,38 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
when (app) { when (app) {
activity.getString(R.string.vanced) -> { activity.getString(R.string.vanced) -> {
when (variant) { when (variant) {
"nonroot" -> if (vancedInstallFilesExist(activity)) InstallationFilesDetectedDialog(app).show(activity) else VancedPreferencesDialog().show(activity) "nonroot" -> {
"root" -> VancedPreferencesDialog().show(activity) if (vancedInstallFilesExist(activity)) {
InstallationFilesDetectedDialog(app).show(activity)
} else {
VancedPreferencesDialog().show(activity)
}
}
"root" -> {
VancedPreferencesDialog().show(activity)
}
} }
} }
activity.getString(R.string.music) -> { activity.getString(R.string.music) -> {
when (variant) { when (variant) {
"nonroot" -> if (musicApkExists(activity)) InstallationFilesDetectedDialog(app).show(activity) else MusicPreferencesDialog().show(activity) "nonroot" -> {
"root" -> MusicPreferencesDialog().show(activity) if (musicApkExists(activity)) {
InstallationFilesDetectedDialog(app).show(activity)
} else {
MusicPreferencesDialog().show(activity)
}
}
"root" -> {
MusicPreferencesDialog().show(activity)
}
} }
} }
activity.getString(R.string.microg) -> { activity.getString(R.string.microg) -> {
if (apkExist(activity, "microg.apk")) InstallationFilesDetectedDialog(app).show(activity) else AppDownloadDialog(app).show(activity) if (apkExist(activity, "microg.apk")) {
InstallationFilesDetectedDialog(app).show(activity)
} else {
AppDownloadDialog.newInstance(app).show(activity)
}
} }
} }

View File

@ -32,7 +32,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
} }
fun sendCloseDialog(context: Context): Job { fun sendCloseDialog(context: Context): Job {
downloadProgress.get()?.installing?.set(false) downloadProgress.value?.installing?.value = false
return launch { return launch {
delay(700) delay(700)
LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(AppDownloadDialog.CLOSE_DIALOG)) LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(AppDownloadDialog.CLOSE_DIALOG))
@ -40,7 +40,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
} }
fun sendFailure(status: Int, context: Context): Job { fun sendFailure(status: Int, context: Context): Job {
downloadProgress.get()?.installing?.set(false) downloadProgress.value?.installing?.value = false
//Delay error broadcast until activity (and fragment) get back to the screen //Delay error broadcast until activity (and fragment) get back to the screen
return launch { return launch {
delay(700) delay(700)
@ -51,7 +51,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
} }
fun sendFailure(error: MutableList<String>, context: Context): Job { fun sendFailure(error: MutableList<String>, context: Context): Job {
downloadProgress.get()?.installing?.set(false) downloadProgress.value?.installing?.value = false
return launch { return launch {
delay(700) delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED) val intent = Intent(HomeFragment.INSTALL_FAILED)

View File

@ -10,7 +10,7 @@ import android.widget.Toast
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.databinding.ObservableField import androidx.lifecycle.MutableLiveData
import com.downloader.OnDownloadListener import com.downloader.OnDownloadListener
import com.downloader.PRDownloader import com.downloader.PRDownloader
import com.vanced.manager.R import com.vanced.manager.R
@ -34,23 +34,23 @@ object DownloadHelper {
return downloadManager.enqueue(request) return downloadManager.enqueue(request)
} }
val downloadProgress = ObservableField<ProgressModel>() val downloadProgress = MutableLiveData<ProgressModel>()
init { init {
downloadProgress.set(ProgressModel()) downloadProgress.value = ProgressModel()
} }
suspend fun downloadManager(context: Context) = suspend fun downloadManager(context: Context) =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk" val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk") downloadProgress.value?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk")
.build() .build()
.setOnProgressListener { progress -> .setOnProgressListener { progress ->
val mProgress = progress.currentBytes * 100 / progress.totalBytes val mProgress = progress.currentBytes * 100 / progress.totalBytes
downloadProgress.get()?.downloadProgress?.set(mProgress.toInt()) downloadProgress.value?.downloadProgress?.value = mProgress.toInt()
} }
.setOnCancelListener { .setOnCancelListener {
downloadProgress.get()?.downloadProgress?.set(0) downloadProgress.value?.downloadProgress?.value = 0
} }
.start(object : OnDownloadListener { .start(object : OnDownloadListener {
override fun onDownloadComplete() { override fun onDownloadComplete() {

View File

@ -1,94 +1,72 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.dialogs.AppDownloadDialog"
style="@style/DialogCard">
<data> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<import type="android.view.View" /> <TextView
android:id="@+id/app_download_header"
tools:text="Installing Vanced"
style="@style/DialogCardTitle"/>
<variable <TextView
name="progress" android:id="@+id/app_download_patient"
type="com.vanced.manager.model.ProgressModel" /> android:layout_below="@id/app_download_header"
android:text="@string/please_be_patient"
style="@style/DialogCardSubtitle"/>
</data> <com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/app_download_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/app_download_patient"
android:layout_marginTop="24dp"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
tools:progress="10"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"/>
<com.google.android.material.card.MaterialCardView <com.google.android.material.progressindicator.ProgressIndicator
style="@style/DialogCard" android:id="@+id/app_install_progressbar"
tools:context=".ui.dialogs.AppDownloadDialog"> android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_below="@id/app_download_progressbar"
android:layout_marginTop="24dp"
android:indeterminate="true"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"/>
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:layout_below="@id/app_install_progressbar"
android:layout_marginTop="8dp">
<TextView <TextView
android:id="@+id/app_download_header" android:id="@+id/app_download_file"
style="@style/DialogCardTitle" android:layout_width="wrap_content"
tools:text="Installing Vanced" />
<TextView
android:id="@+id/app_download_patient"
style="@style/DialogCardSubtitle"
android:layout_below="@id/app_download_header"
android:text="@string/please_be_patient" />
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/app_download_progressbar"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/app_download_patient"
android:layout_marginTop="24dp"
android:progress="@{progress.downloadProgress}"
android:visibility="@{progress.installing ? View.GONE : View.VISIBLE}"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
tools:progress="10" />
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/app_install_progressbar"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/app_download_progressbar"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/app_download_cancel"
android:textSize="15sp"
tools:text="Downloading base.apk..."/>
<com.google.android.material.button.MaterialButton
android:id="@+id/app_download_cancel"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_marginTop="24dp" android:text="@string/cancel"
android:indeterminate="true" app:layout_constraintEnd_toEndOf="parent"
android:visibility="@{progress.installing ? View.VISIBLE : View.GONE}" style="@style/OutlinedButtonStyle"/>
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/app_install_progressbar"
android:layout_marginTop="8dp">
<TextView
android:id="@+id/app_download_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/app_download_cancel"
android:text="@{progress.downloadingFile}"
android:textSize="15sp"
android:visibility="@{progress.installing ? View.GONE : View.VISIBLE}"
tools:text="Downloading base.apk..." />
<com.google.android.material.button.MaterialButton
android:id="@+id/app_download_cancel"
style="@style/OutlinedButtonStyle"
android:layout_alignParentEnd="true"
android:enabled="@{!progress.installing}"
android:text="@string/cancel"
app:layout_constraintEnd_toEndOf="parent" />
</RelativeLayout>
</RelativeLayout> </RelativeLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
</layout>

View File

@ -1,60 +1,55 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorLinkBG"
app:cardCornerRadius="8dp"
app:cardElevation="0dp"
app:contentPaddingBottom="8dp"
app:contentPaddingLeft="16dp"
app:contentPaddingRight="16dp">
<com.google.android.material.card.MaterialCardView <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent">
android:background="?colorLinkBG"
app:cardCornerRadius="8dp"
app:cardElevation="0dp"
app:contentPaddingBottom="8dp"
app:contentPaddingLeft="16dp"
app:contentPaddingRight="16dp">
<androidx.constraintlayout.widget.ConstraintLayout <TextView
android:id="@+id/about_app_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="About YouTube Vanced"
style="@style/DialogCardTitle"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/about_app_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/about_app_name"
tools:src="@drawable/ic_vanced"/>
<TextView
android:id="@+id/about_app_changelog_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/changelog"
app:layout_constraintTop_toBottomOf="@id/about_app_image"
style="@style/CardTextHeader"/>
<TextView <TextView
android:id="@+id/about_app_name" android:id="@+id/about_app_changelog"
style="@style/DialogCardTitle" android:layout_width="match_parent"
app:layout_constraintEnd_toEndOf="parent" android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent" android:layout_marginHorizontal="4dp"
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp"
tools:text="About YouTube Vanced" /> app:layout_constraintTop_toBottomOf="@id/about_app_changelog_header"
tools:text="@tools:sample/lorem/random"/>
<androidx.appcompat.widget.AppCompatImageView </androidx.constraintlayout.widget.ConstraintLayout>
android:id="@+id/about_app_image" </com.google.android.material.card.MaterialCardView>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/about_app_name"
tools:src="@drawable/ic_vanced" />
<TextView
android:id="@+id/about_app_changelog_header"
style="@style/CardTextHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/changelog"
app:layout_constraintTop_toBottomOf="@id/about_app_image" />
<TextView
android:id="@+id/about_app_changelog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/about_app_changelog_header"
tools:text="@tools:sample/lorem/random" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</layout>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" <com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
style="@style/DialogCard"> style="@style/DialogCard">
@ -48,9 +49,6 @@
style="@style/ButtonStyle" style="@style/ButtonStyle"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:text="@string/save" /> android:text="@string/save" />
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>

View File

@ -1,73 +1,56 @@
<?xml version="1.0" encoding="utf-8"?> <?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"
app:contentPaddingLeft="16dp"
app:contentPaddingRight="16dp"
tools:context=".ui.dialogs.ManagerUpdateDialog"
style="@style/MaterialCard">
<data> <RelativeLayout
<import type="android.view.View" />
<variable
name="progress"
type="com.vanced.manager.model.ProgressModel" />
</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"
style="@style/MaterialCard"
android:layout_width="match_parent" android:layout_width="match_parent"
app:contentPaddingLeft="16dp" android:layout_height="match_parent">
app:contentPaddingRight="16dp"
tools:context=".ui.dialogs.ManagerUpdateDialog">
<RelativeLayout <TextView
android:id="@+id/manager_update_header"
android:text="@string/update_center"
style="@style/DialogCardTitle"/>
<TextView
android:id="@+id/manager_update_patient"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_below="@id/manager_update_header"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="@string/checking_updates"
android:textSize="16sp"/>
<TextView <com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/manager_update_header" android:id="@+id/manager_update_progressbar"
style="@style/DialogCardTitle" android:layout_width="match_parent"
android:text="@string/update_center" /> android:layout_height="wrap_content"
android:layout_below="@id/manager_update_patient"
android:layout_marginTop="32dp"
android:paddingBottom="8dp"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
tools:progress="10"
tools:visibility="visible"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"/>
<TextView <com.google.android.material.button.MaterialButton
android:id="@+id/manager_update_patient" android:id="@+id/manager_update_cancel"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/manager_update_header" android:layout_alignParentEnd="true"
android:layout_alignParentStart="true" android:layout_below="@id/manager_update_progressbar"
android:layout_alignParentEnd="true" android:text="@string/cancel"
android:layout_marginTop="8dp" app:strokeWidth="2dp"
android:gravity="center" style="@style/Widget.MaterialComponents.Button.OutlinedButton"/>
android:text="@string/checking_updates" </RelativeLayout>
android:textSize="16sp" /> </com.google.android.material.card.MaterialCardView>
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/manager_update_progressbar"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/manager_update_patient"
android:layout_marginTop="32dp"
android:paddingBottom="8dp"
android:progress="@{progress.downloadProgress}"
android:visibility="@{progress.downloadProgress == 0 ? View.GONE : View.VISIBLE}"
app:indicatorColor="?colorPrimary"
app:indicatorCornerRadius="15dp"
tools:progress="10"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
android:id="@+id/manager_update_cancel"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/manager_update_progressbar"
android:layout_alignParentEnd="true"
android:text="@string/cancel"
app:strokeWidth="2dp" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
</layout>