diff --git a/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt index 0015f4d0..e6397500 100644 --- a/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt +++ b/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt @@ -3,7 +3,7 @@ package com.vanced.manager.adapter import android.view.LayoutInflater import android.view.ViewGroup import androidx.fragment.app.FragmentActivity -import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import androidx.preference.PreferenceManager.* import androidx.recyclerview.widget.RecyclerView import com.github.florent37.viewtooltip.ViewTooltip import com.vanced.manager.R @@ -46,10 +46,10 @@ class AppListAdapter( holder.appCard.setOnClickListener { tooltip.close() - AppInfoDialog( - apps[position], - dataModels[position]?.appIcon, - dataModels[position]?.changelog?.get() + AppInfoDialog.newInstance( + appName = apps[position], + appIcon = dataModels[position]?.appIcon, + changelog = dataModels[position]?.changelog?.get() ).show(context.supportFragmentManager, "info") } } diff --git a/app/src/main/java/com/vanced/manager/core/base/BaseFragment.kt b/app/src/main/java/com/vanced/manager/core/base/BaseFragment.kt deleted file mode 100644 index 2f759f37..00000000 --- a/app/src/main/java/com/vanced/manager/core/base/BaseFragment.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.vanced.manager.core.base - -import androidx.fragment.app.Fragment - -open class BaseFragment : Fragment() \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt b/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt index bf2872a4..06a17434 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt @@ -20,29 +20,29 @@ object MicrogDownloader : CoroutineScope by CoroutineScope(Dispatchers.IO) { ) = launch { 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() .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 -> - downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) + downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt() } - .start(object : OnDownloadListener { - override fun onDownloadComplete() { - startMicrogInstall(context) - } + .start(object : OnDownloadListener { + override fun onDownloadComplete() { + startMicrogInstall(context) + } - override fun onError(error: Error?) { - downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "microG")) - } - }) + override fun onError(error: Error?) { + downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, "microG") + } + }) } fun startMicrogInstall(context: Context) { - downloadProgress.get()?.installing?.set(true) - downloadProgress.get()?.reset() + downloadProgress.value?.installing?.value = true + downloadProgress.value?.reset() install("${context.getExternalFilesDir("microg")}/microg.apk", context) } } diff --git a/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt b/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt index ea8fb719..331e52d3 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt @@ -49,13 +49,13 @@ object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) { launch { val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk" suspendCoroutine { - downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) + downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) .build() .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 -> - downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) + downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt() } .start(object : OnDownloadListener { override fun onDownloadComplete() { @@ -90,7 +90,7 @@ object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) { 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) { - downloadProgress.get()?.installing?.set(true) - downloadProgress.get()?.reset() + downloadProgress.value?.installing?.value = true + downloadProgress.value?.reset() if (variant == "root") installMusicRoot(context) else diff --git a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt index 4d1a5a71..c6b92c71 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt @@ -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?") } - downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) + downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) .build() .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 -> - downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) + downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt() } .start(object : OnDownloadListener { override fun onDownloadComplete() { @@ -143,7 +143,7 @@ object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) { } } 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) { - downloadProgress.get()?.installing?.set(true) - downloadProgress.get()?.reset() + downloadProgress.value?.installing?.value = true + downloadProgress.value?.reset() FirebaseAnalytics.getInstance(context).logEvent(FirebaseAnalytics.Event.SELECT_ITEM) { variant?.let { param("vanced_variant", it) } theme?.let { param("vanced_theme", it) } diff --git a/app/src/main/java/com/vanced/manager/model/ProgressModel.kt b/app/src/main/java/com/vanced/manager/model/ProgressModel.kt index 23840c68..47c852a1 100644 --- a/app/src/main/java/com/vanced/manager/model/ProgressModel.kt +++ b/app/src/main/java/com/vanced/manager/model/ProgressModel.kt @@ -1,24 +1,22 @@ package com.vanced.manager.model -import androidx.databinding.ObservableBoolean -import androidx.databinding.ObservableField -import androidx.databinding.ObservableInt +import androidx.lifecycle.MutableLiveData open class ProgressModel { - - val downloadProgress = ObservableInt() - val downloadingFile = ObservableField() - val installing = ObservableBoolean() + + val downloadProgress = MutableLiveData() + val downloadingFile = MutableLiveData() + val installing = MutableLiveData() var currentDownload: Int = 0 fun reset() { - downloadProgress.set(0) - downloadingFile.set("") + downloadProgress.value = 0 + downloadingFile.value = "" } init { - installing.set(false) + installing.value = false reset() } diff --git a/app/src/main/java/com/vanced/manager/ui/core/BindingDialogFragment.kt b/app/src/main/java/com/vanced/manager/ui/core/BindingDialogFragment.kt new file mode 100644 index 00000000..8e75f2f8 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/core/BindingDialogFragment.kt @@ -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 : 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 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/BindingFragment.kt b/app/src/main/java/com/vanced/manager/ui/core/BindingFragment.kt index 73318bc9..62a0d0ed 100644 --- a/app/src/main/java/com/vanced/manager/ui/core/BindingFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/core/BindingFragment.kt @@ -16,7 +16,7 @@ abstract class BindingFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { _binding = binding(inflater, container, savedInstanceState) otherSetups() return binding.root diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt index 9815d7bb..481736a6 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt @@ -10,8 +10,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.DialogFragment +import androidx.core.view.isVisible import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.downloader.PRDownloader 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.VancedDownloader.downloadVanced import com.vanced.manager.databinding.DialogAppDownloadBinding +import com.vanced.manager.ui.core.BindingDialogFragment import com.vanced.manager.utils.DownloadHelper.downloadProgress -class AppDownloadDialog( - private val app: String, - private val installing: Boolean = false -) : DialogFragment() { +class AppDownloadDialog : BindingDialogFragment() { - 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 broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { - when (intent.action) { - CLOSE_DIALOG -> dismiss() + if (intent.action == CLOSE_DIALOG) { + dismiss() } } } - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + override fun binding( + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? - ): View? { - if (dialog != null && dialog?.window != null) { - dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) - } - binding = DataBindingUtil.inflate(inflater, R.layout.dialog_app_download, container, false) - binding.progress = downloadProgress.get() - return binding.root + ) = DialogAppDownloadBinding.inflate(inflater, container, false) + + override fun otherSetups() { + dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + bindData() } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - isCancelable = false - binding.appDownloadHeader.text = requireActivity().getString(R.string.installing_app, app) - binding.appDownloadCancel.setOnClickListener { - if (downloadProgress.get()?.installing?.get() == true) - return@setOnClickListener - - PRDownloader.cancel(downloadProgress.get()!!.currentDownload) - dismiss() + private fun bindData() { + with(binding) { + isCancelable = false + bindDownloadProgress() + val app = arguments?.getString(TAG_APP) + appDownloadHeader.text = app + if (arguments?.getBoolean(TAG_INSTALLING) == false) { + when (app) { + getString(R.string.vanced) -> downloadVanced(requireContext()) + getString(R.string.music) -> downloadMusic(requireContext()) + getString(R.string.microg) -> downloadMicrog(requireContext()) + } + } } - if (!installing) { - when (app) { - requireActivity().getString(R.string.vanced) -> downloadVanced(requireActivity()) - requireActivity().getString(R.string.music) -> downloadMusic(requireActivity()) - requireActivity().getString(R.string.microg) -> downloadMicrog(requireActivity()) + } + + private fun DialogAppDownloadBinding.bindDownloadProgress() { + with(downloadProgress) { + 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) localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter) } - - companion object { - const val CLOSE_DIALOG = "close_dialog" - } - } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt index 126d90ae..517e881e 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt @@ -5,34 +5,49 @@ import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.os.Bundle import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.DialogFragment +import androidx.core.graphics.drawable.toBitmap import com.vanced.manager.R import com.vanced.manager.databinding.DialogAppInfoBinding +import com.vanced.manager.ui.core.BindingDialogFragment -class AppInfoDialog( - private val appName: String?, - private val appIcon: Drawable?, - private val changelog: String? -) : DialogFragment() { +class AppInfoDialog : BindingDialogFragment() { - private lateinit var binding: DialogAppInfoBinding + companion object { - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - if (dialog != null && dialog?.window != null) { - dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + private const val TAG_APP_NAME = "TAG_APP_NAME" + private const val TAG_APP_ICON = "TAG_APP_ICON" + 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?) { - super.onViewCreated(view, savedInstanceState) - binding.aboutAppName.text = requireActivity().getString(R.string.about_app, appName) - binding.aboutAppImage.setImageDrawable(appIcon) - binding.aboutAppChangelog.text = changelog + override fun binding( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ) = 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)) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt index 7a52a35d..4ad8a805 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt @@ -5,8 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.databinding.DataBindingUtil -import androidx.lifecycle.lifecycleScope -import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import androidx.preference.PreferenceManager.* import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.vanced.manager.R 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.databinding.DialogInstallationFilesDetectedBinding import com.vanced.manager.utils.Extensions.show -import kotlinx.coroutines.launch class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() { @@ -39,18 +37,23 @@ class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDial dismiss() if (app == requireActivity().getString(R.string.vanced)) VancedPreferencesDialog().show(requireActivity()) - else - AppDownloadDialog(app).show(requireActivity()) + else { + AppDownloadDialog.newInstance(app).show(requireActivity()) + } } binding.installationDetectedInstall.setOnClickListener { dismiss() 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.microg) -> startMicrogInstall(requireActivity()) } - AppDownloadDialog(app, true).show(requireActivity()) + AppDownloadDialog.newInstance( + app = app, + installing = true + ).show(requireActivity()) } } diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt index cf90fe12..804389df 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt @@ -10,13 +10,19 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isVisible import androidx.databinding.DataBindingUtil import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.downloader.PRDownloader import com.vanced.manager.R +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.ui.core.BindingDialogFragment import com.vanced.manager.utils.DownloadHelper.downloadManager import com.vanced.manager.utils.DownloadHelper.downloadProgress import com.vanced.manager.utils.InternetTools.isUpdateAvailable @@ -24,9 +30,24 @@ import kotlinx.coroutines.launch class ManagerUpdateDialog( private val forceUpdate: Boolean -) : DialogFragment() { +) : BindingDialogFragment() { - 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()) } @@ -38,21 +59,15 @@ class ManagerUpdateDialog( } } - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + override fun binding( + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? - ): View? { - 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 - } + ) = DialogManagerUpdateBinding.inflate(inflater, container, false) - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun otherSetups() { + dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + bindData() lifecycleScope.launch { if (forceUpdate) { binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient) @@ -62,12 +77,30 @@ class ManagerUpdateDialog( } binding.managerUpdateCancel.setOnClickListener { - PRDownloader.cancel(downloadProgress.get()!!.currentDownload) + PRDownloader.cancel(downloadProgress.value?.currentDownload) 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() { super.onResume() registerReceiver() @@ -87,9 +120,4 @@ class ManagerUpdateDialog( intentFilter.addAction(CLOSE_DIALOG) localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter) } - - companion object { - const val CLOSE_DIALOG = "close_dialog" - } - } diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/MusicPreferencesDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/MusicPreferencesDialog.kt index d0bc3119..30d83f84 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/MusicPreferencesDialog.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/MusicPreferencesDialog.kt @@ -41,8 +41,9 @@ class MusicPreferencesDialog : BottomSheetDialogFragment() { } binding.musicInstall.setOnClickListener { dismiss() - AppDownloadDialog(requireActivity().getString(R.string.music)).show(requireActivity()) + AppDownloadDialog.newInstance( + app = getString(R.string.music) + ).show(requireActivity()) } } - } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/URLChangeDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/URLChangeDialog.kt index 05dfdbce..0d18d4d3 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/URLChangeDialog.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/URLChangeDialog.kt @@ -4,47 +4,58 @@ import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.EditText import android.widget.TextView import androidx.core.content.edit -import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope -import androidx.preference.PreferenceManager.getDefaultSharedPreferences -import com.google.android.material.button.MaterialButton -import com.vanced.manager.R +import androidx.preference.PreferenceManager.* +import com.vanced.manager.databinding.DialogCustomUrlBinding +import com.vanced.manager.ui.core.BindingDialogFragment import com.vanced.manager.utils.Extensions.fetchData import com.vanced.manager.utils.InternetTools.baseUrl import kotlinx.coroutines.launch -class URLChangeDialog : DialogFragment() { +class URLChangeDialog : BindingDialogFragment() { - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - if (dialog != null && dialog?.window != null) { - dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + companion object { + + fun newInstance(): URLChangeDialog = URLChangeDialog().apply { + arguments = Bundle() } - return inflater.inflate(R.layout.dialog_custom_url, container, false) } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - val urlField = view.findViewById(R.id.url_input) - val fieldTxt = if (arguments != null) arguments?.getString("url") else getDefaultSharedPreferences(requireActivity()).getString("install_url", baseUrl) - urlField.setText(fieldTxt, TextView.BufferType.EDITABLE) - view.findViewById(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("/") + override fun binding( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ) = DialogCustomUrlBinding.inflate(inflater, container, false) - 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(R.id.url_reset).setOnClickListener { saveUrl(baseUrl) } } private fun saveUrl(url: String) { diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt index 1e2d7dbe..3b0408ec 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt @@ -66,7 +66,9 @@ class VancedPreferencesDialog : BottomSheetDialogFragment() { binding.vancedInstall.setOnClickListener { dismiss() - AppDownloadDialog(requireActivity().getString(R.string.vanced)).show(requireActivity()) + AppDownloadDialog.newInstance( + app = getString(R.string.vanced) + ).show(requireActivity()) } } } diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/AboutFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/AboutFragment.kt index 84409ed2..515eef4a 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/AboutFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/fragments/AboutFragment.kt @@ -11,11 +11,11 @@ import androidx.core.content.edit import androidx.fragment.app.viewModels import androidx.preference.PreferenceManager import com.vanced.manager.R +import com.vanced.manager.core.ext.showDialog 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.dialogs.AppInfoDialog import com.vanced.manager.ui.viewmodels.AboutViewModel -import com.vanced.manager.utils.Extensions.show import com.vanced.manager.utils.InternetTools.manager class AboutFragment : BindingFragment() { @@ -37,7 +37,15 @@ class AboutFragment : BindingFragment() { @SuppressLint("ClickableViewAccessibility") private fun dataBind() { requireActivity().title = getString(R.string.title_about) - binding.aboutHeader.root.setOnClickListener { AppInfoDialog(getString(R.string.app_name), AppCompatResources.getDrawable(requireActivity(), R.mipmap.ic_launcher), manager.get()?.string("changelog")).show(requireActivity()) } + binding.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 -> val eventAction = event.action if (eventAction == MotionEvent.ACTION_UP) { diff --git a/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt b/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt index bea5621c..3d638c02 100644 --- a/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt @@ -100,7 +100,7 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() { when (app) { activity.getString(R.string.vanced) -> VancedPreferencesDialog().show(activity) activity.getString(R.string.music) -> MusicPreferencesDialog().show(activity) - else -> AppDownloadDialog(app).show(activity) + else -> AppDownloadDialog.newInstance(app).show(activity) } return @@ -109,18 +109,38 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() { when (app) { activity.getString(R.string.vanced) -> { when (variant) { - "nonroot" -> if (vancedInstallFilesExist(activity)) InstallationFilesDetectedDialog(app).show(activity) else VancedPreferencesDialog().show(activity) - "root" -> VancedPreferencesDialog().show(activity) + "nonroot" -> { + if (vancedInstallFilesExist(activity)) { + InstallationFilesDetectedDialog(app).show(activity) + } else { + VancedPreferencesDialog().show(activity) + } + } + "root" -> { + VancedPreferencesDialog().show(activity) + } } } activity.getString(R.string.music) -> { when (variant) { - "nonroot" -> if (musicApkExists(activity)) InstallationFilesDetectedDialog(app).show(activity) else MusicPreferencesDialog().show(activity) - "root" -> MusicPreferencesDialog().show(activity) + "nonroot" -> { + if (musicApkExists(activity)) { + InstallationFilesDetectedDialog(app).show(activity) + } else { + MusicPreferencesDialog().show(activity) + } + } + "root" -> { + MusicPreferencesDialog().show(activity) + } } } 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) + } } } diff --git a/app/src/main/java/com/vanced/manager/utils/AppUtils.kt b/app/src/main/java/com/vanced/manager/utils/AppUtils.kt index 1649a799..50013aae 100644 --- a/app/src/main/java/com/vanced/manager/utils/AppUtils.kt +++ b/app/src/main/java/com/vanced/manager/utils/AppUtils.kt @@ -32,7 +32,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) { } fun sendCloseDialog(context: Context): Job { - downloadProgress.get()?.installing?.set(false) + downloadProgress.value?.installing?.value = false return launch { delay(700) 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 { - downloadProgress.get()?.installing?.set(false) + downloadProgress.value?.installing?.value = false //Delay error broadcast until activity (and fragment) get back to the screen return launch { delay(700) @@ -51,7 +51,7 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) { } fun sendFailure(error: MutableList, context: Context): Job { - downloadProgress.get()?.installing?.set(false) + downloadProgress.value?.installing?.value = false return launch { delay(700) val intent = Intent(HomeFragment.INSTALL_FAILED) diff --git a/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt b/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt index e211373d..bb36d047 100644 --- a/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt +++ b/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt @@ -10,7 +10,7 @@ import android.widget.Toast import androidx.core.content.FileProvider import androidx.core.content.getSystemService import androidx.core.net.toUri -import androidx.databinding.ObservableField +import androidx.lifecycle.MutableLiveData import com.downloader.OnDownloadListener import com.downloader.PRDownloader import com.vanced.manager.R @@ -34,23 +34,23 @@ object DownloadHelper { return downloadManager.enqueue(request) } - val downloadProgress = ObservableField() + val downloadProgress = MutableLiveData() init { - downloadProgress.set(ProgressModel()) + downloadProgress.value = ProgressModel() } suspend fun downloadManager(context: Context) = withContext(Dispatchers.IO) { val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk" - downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk") + downloadProgress.value?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk") .build() .setOnProgressListener { progress -> val mProgress = progress.currentBytes * 100 / progress.totalBytes - downloadProgress.get()?.downloadProgress?.set(mProgress.toInt()) + downloadProgress.value?.downloadProgress?.value = mProgress.toInt() } .setOnCancelListener { - downloadProgress.get()?.downloadProgress?.set(0) + downloadProgress.value?.downloadProgress?.value = 0 } .start(object : OnDownloadListener { override fun onDownloadComplete() { diff --git a/app/src/main/res/layout/dialog_app_download.xml b/app/src/main/res/layout/dialog_app_download.xml index 83195223..8fba62e4 100644 --- a/app/src/main/res/layout/dialog_app_download.xml +++ b/app/src/main/res/layout/dialog_app_download.xml @@ -1,94 +1,72 @@ - + xmlns:tools="http://schemas.android.com/tools" + tools:context=".ui.dialogs.AppDownloadDialog" + style="@style/DialogCard"> - + - + - + - + - + + android:layout_height="wrap_content" + android:layout_below="@id/app_install_progressbar" + android:layout_marginTop="8dp"> - - - - - - + + - - - - - - - - - + android:text="@string/cancel" + app:layout_constraintEnd_toEndOf="parent" + style="@style/OutlinedButtonStyle"/> - - - - + + diff --git a/app/src/main/res/layout/dialog_app_info.xml b/app/src/main/res/layout/dialog_app_info.xml index d24c6620..2469d1e1 100644 --- a/app/src/main/res/layout/dialog_app_info.xml +++ b/app/src/main/res/layout/dialog_app_info.xml @@ -1,60 +1,55 @@ - + 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"> - + 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"/> - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_custom_url.xml b/app/src/main/res/layout/dialog_custom_url.xml index 1099adea..15d0340b 100644 --- a/app/src/main/res/layout/dialog_custom_url.xml +++ b/app/src/main/res/layout/dialog_custom_url.xml @@ -1,5 +1,6 @@ - @@ -48,9 +49,6 @@ style="@style/ButtonStyle" android:layout_alignParentEnd="true" android:text="@string/save" /> - - - \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_manager_update.xml b/app/src/main/res/layout/dialog_manager_update.xml index 6bfb0b2b..6159d9cc 100644 --- a/app/src/main/res/layout/dialog_manager_update.xml +++ b/app/src/main/res/layout/dialog_manager_update.xml @@ -1,73 +1,56 @@ - + - - - - - - - - - + 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"/> - + - - - - - - - - - - - + + + \ No newline at end of file