From 4023a1881e1e56a9be5fec81561a12994e94b343 Mon Sep 17 00:00:00 2001 From: Rahul Kumar Patel Date: Sat, 20 Mar 2021 02:28:29 +0530 Subject: [PATCH] Improve updates fragment actions --- .../main/java/com/aurora/extensions/View.kt | 4 ++ .../com/aurora/store/data/event/BusEvent.kt | 5 ++ .../store/data/installer/InstallerService.kt | 7 ++ .../custom/layouts/button/UpdateButton.kt | 7 +- .../view/epoxy/views/app/AppUpdateView.kt | 46 +++++++++---- .../store/view/ui/updates/UpdatesFragment.kt | 69 ++++++++++++++----- .../store/viewmodel/all/UpdatesViewModel.kt | 30 ++++++-- app/src/main/res/layout/view_app_update.xml | 22 +++--- .../main/res/layout/view_update_button.xml | 16 ++++- 9 files changed, 151 insertions(+), 55 deletions(-) diff --git a/app/src/main/java/com/aurora/extensions/View.kt b/app/src/main/java/com/aurora/extensions/View.kt index 6b7857932..e011558fa 100644 --- a/app/src/main/java/com/aurora/extensions/View.kt +++ b/app/src/main/java/com/aurora/extensions/View.kt @@ -37,6 +37,10 @@ fun View.hide() { visibility = View.GONE } +fun View.invisible() { + visibility = View.INVISIBLE +} + fun View.showKeyboard() { val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager this.requestFocus() diff --git a/app/src/main/java/com/aurora/store/data/event/BusEvent.kt b/app/src/main/java/com/aurora/store/data/event/BusEvent.kt index dd266875e..664cff69e 100644 --- a/app/src/main/java/com/aurora/store/data/event/BusEvent.kt +++ b/app/src/main/java/com/aurora/store/data/event/BusEvent.kt @@ -48,6 +48,11 @@ sealed class InstallerEvent { var extra: String? = "" ) : InstallerEvent() + data class Cancelled( + var packageName: String? = "", + var extra: String? = "" + ) : InstallerEvent() + data class Failed( var packageName: String? = "", var error: String? = "", diff --git a/app/src/main/java/com/aurora/store/data/installer/InstallerService.kt b/app/src/main/java/com/aurora/store/data/installer/InstallerService.kt index dfcc52ce7..959103da9 100644 --- a/app/src/main/java/com/aurora/store/data/installer/InstallerService.kt +++ b/app/src/main/java/com/aurora/store/data/installer/InstallerService.kt @@ -67,6 +67,13 @@ class InstallerService : Service() { PackageInstaller.STATUS_SUCCESS -> { EventBus.getDefault().post(InstallerEvent.Success(packageName, "Success")) } + PackageInstaller.STATUS_FAILURE_ABORTED -> { + val errorString = AppInstaller.getErrorString(this, status) + val event = + InstallerEvent.Cancelled(packageName, errorString) + Log.e("$packageName : $errorString") + EventBus.getDefault().post(event) + } else -> { val errorString = AppInstaller.getErrorString(this, status) diff --git a/app/src/main/java/com/aurora/store/view/custom/layouts/button/UpdateButton.kt b/app/src/main/java/com/aurora/store/view/custom/layouts/button/UpdateButton.kt index 7be935a33..fbedd481d 100644 --- a/app/src/main/java/com/aurora/store/view/custom/layouts/button/UpdateButton.kt +++ b/app/src/main/java/com/aurora/store/view/custom/layouts/button/UpdateButton.kt @@ -77,9 +77,10 @@ class UpdateButton : RelativeLayout { fun updateState(state: State) { val displayChild = when (state) { - State.IDLE, State.COMPLETE, State.CANCELED -> 0 + State.IDLE, State.CANCELED -> 0 State.QUEUED -> 1 State.PROGRESS -> 2 + State.COMPLETE -> 3 } if (B.viewFlipper.displayedChild != displayChild) { @@ -96,4 +97,8 @@ class UpdateButton : RelativeLayout { fun addNegativeOnClickListener(onClickListener: OnClickListener?) { B.btnNegative.setOnClickListener(onClickListener) } + + fun addInstallOnClickListener(onClickListener: OnClickListener?) { + B.btnInstall.setOnClickListener(onClickListener) + } } \ No newline at end of file diff --git a/app/src/main/java/com/aurora/store/view/epoxy/views/app/AppUpdateView.kt b/app/src/main/java/com/aurora/store/view/epoxy/views/app/AppUpdateView.kt index 704087964..cf2b0c813 100644 --- a/app/src/main/java/com/aurora/store/view/epoxy/views/app/AppUpdateView.kt +++ b/app/src/main/java/com/aurora/store/view/epoxy/views/app/AppUpdateView.kt @@ -27,7 +27,7 @@ import com.airbnb.epoxy.CallbackProp import com.airbnb.epoxy.ModelProp import com.airbnb.epoxy.ModelView import com.airbnb.epoxy.OnViewRecycled -import com.aurora.extensions.hide +import com.aurora.extensions.invisible import com.aurora.extensions.load import com.aurora.extensions.px import com.aurora.extensions.show @@ -105,22 +105,32 @@ class AppUpdateView : RelativeLayout { /*Inflate Download details*/ updateFile.group?.let { - if (updateFile.state == State.PROGRESS) { - val progress = it.groupDownloadProgress - if (progress > 0) { - if (progress == 100) { - B.txtProgressPercent.hide() - } else { - B.txtProgressPercent.show() - B.txtProgressPercent.text = ("${progress}%") + when (updateFile.state) { + State.QUEUED -> { + B.progressDownload.progress = 0 + B.progressDownload.show() + B.btnAction.updateState(State.QUEUED) + } + State.IDLE, State.CANCELED -> { + B.progressDownload.progress = 0 + B.progressDownload.invisible() + B.btnAction.updateState(State.IDLE) + } + State.PROGRESS -> { + val progress = it.groupDownloadProgress + if (progress > 0) { + if (progress == 100) { + B.progressDownload.invisible() + } else { + B.progressDownload.progress = progress + B.progressDownload.show() + } } } - } else if (updateFile.state == State.IDLE || updateFile.state == State.CANCELED) { - B.btnAction.updateState(State.IDLE) - B.txtProgressPercent.text = ("0%") - B.txtProgressPercent.hide() - } else if (updateFile.state == State.QUEUED) { - B.btnAction.updateState(State.QUEUED) + State.COMPLETE -> { + B.progressDownload.invisible() + B.btnAction.updateState(State.COMPLETE) + } } } } @@ -148,6 +158,11 @@ class AppUpdateView : RelativeLayout { B.btnAction.addNegativeOnClickListener(onClickListener) } + @CallbackProp + fun installAction(onClickListener: OnClickListener?) { + B.btnAction.addInstallOnClickListener(onClickListener) + } + @CallbackProp fun longClick(onClickListener: OnLongClickListener?) { B.layoutContent.setOnLongClickListener(onClickListener) @@ -156,5 +171,6 @@ class AppUpdateView : RelativeLayout { @OnViewRecycled fun clear() { B.headerIndicator.removeCallbacks { } + B.progressDownload.invisible() } } \ No newline at end of file diff --git a/app/src/main/java/com/aurora/store/view/ui/updates/UpdatesFragment.kt b/app/src/main/java/com/aurora/store/view/ui/updates/UpdatesFragment.kt index 520455b7b..2232c8260 100644 --- a/app/src/main/java/com/aurora/store/view/ui/updates/UpdatesFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/updates/UpdatesFragment.kt @@ -52,6 +52,7 @@ import com.tonyodev.fetch2.FetchGroup import nl.komponents.kovenant.task import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi +import org.apache.commons.io.FileUtils class UpdatesFragment : BaseFragment() { @@ -103,17 +104,17 @@ class UpdatesFragment : BaseFragment() { override fun onCompleted(groupId: Int, download: Download, fetchGroup: FetchGroup) { if (fetchGroup.groupDownloadProgress == 100) { - VM.updateDownload(groupId, fetchGroup) + VM.updateDownload(groupId, fetchGroup, isComplete = true) install(download.tag!!, fetchGroup.downloads) } } override fun onCancelled(groupId: Int, download: Download, fetchGroup: FetchGroup) { - VM.updateDownload(groupId, fetchGroup,true) + VM.updateDownload(groupId, fetchGroup, isCancelled = true) } override fun onDeleted(groupId: Int, download: Download, fetchGroup: FetchGroup) { - VM.updateDownload(groupId, fetchGroup,true) + VM.updateDownload(groupId, fetchGroup, isCancelled = true) } } @@ -127,11 +128,11 @@ class UpdatesFragment : BaseFragment() { } } - override fun onPause() { + override fun onDestroy() { if (::fetch.isInitialized && ::fetchListener.isInitialized) { fetch.removeListener(fetchListener) } - super.onPause() + super.onDestroy() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -173,8 +174,20 @@ class UpdatesFragment : BaseFragment() { UpdateHeaderViewModel_() .id("header_all") .title("${updateFileMap.size} updates available") - .action(getString(R.string.action_update_all)) - .click { _ -> updateAll() } + .action( + if (VM.updateAllEnqueued) + getString(R.string.action_cancel) + else + getString(R.string.action_update_all) + ) + .click { _ -> + if (VM.updateAllEnqueued) + cancelAll() + else + updateAll() + + requestModelBuild() + } ) updateFileMap.values.forEach { updateFile -> @@ -189,6 +202,12 @@ class UpdatesFragment : BaseFragment() { } .positiveAction { _ -> updateSingle(updateFile.app) } .negativeAction { _ -> cancelSingle(updateFile.app) } + .installAction { _ -> + install( + updateFile.app.packageName, + updateFile.group?.downloads + ) + } .state(updateFile.state) ) } @@ -229,19 +248,35 @@ class UpdatesFragment : BaseFragment() { private fun updateAll() { updateFileMap.values.forEach { updateSingle(it.app) } + VM.updateAllEnqueued = true + } + + private fun cancelAll() { + VM.updateAllEnqueued = false + updateFileMap.values.forEach { fetch.cancelGroup(it.app.id) } } @Synchronized - private fun install(packageName: String, files: List) { - task { - AppInstaller(requireContext()) - .getPreferredInstaller() - .install( - packageName, - files - .filter { it.file.endsWith(".apk") } - .map { it.file }.toList() - ) + private fun install(packageName: String, files: List?) { + files?.let { downloads -> + var filesExist = true + + downloads.forEach { download -> + filesExist = filesExist && FileUtils.getFile(download.file).exists() + } + + if (filesExist) { + task { + AppInstaller(requireContext()) + .getPreferredInstaller() + .install( + packageName, + files + .filter { it.file.endsWith(".apk") } + .map { it.file }.toList() + ) + } + } } } diff --git a/app/src/main/java/com/aurora/store/viewmodel/all/UpdatesViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/all/UpdatesViewModel.kt index 14c22caea..90bf41fd0 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/all/UpdatesViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/all/UpdatesViewModel.kt @@ -39,6 +39,7 @@ class UpdatesViewModel(application: Application) : BaseAppsViewModel(application var updateFileMap: MutableMap = mutableMapOf() var liveUpdateData: MutableLiveData> = MutableLiveData() + var updateAllEnqueued: Boolean = false init { EventBus.getDefault().register(this) @@ -99,6 +100,9 @@ class UpdatesViewModel(application: Application) : BaseAppsViewModel(application when (event) { is InstallerEvent.Success -> { + } + is InstallerEvent.Cancelled -> { + } is InstallerEvent.Failed -> { val packageName = event.packageName @@ -114,13 +118,25 @@ class UpdatesViewModel(application: Application) : BaseAppsViewModel(application liveUpdateData.postValue(updateFileMap) } - fun updateDownload(id: Int, group: FetchGroup?, isCancelled: Boolean = false) { - if (isCancelled) { - updateFileMap[id]?.state = State.IDLE - updateFileMap[id]?.group = null - } else { - updateFileMap[id]?.state = State.PROGRESS - updateFileMap[id]?.group = group + fun updateDownload( + id: Int, + group: FetchGroup?, + isCancelled: Boolean = false, + isComplete: Boolean = false + ) { + when { + isCancelled -> { + updateFileMap[id]?.state = State.IDLE + updateFileMap[id]?.group = null + } + isComplete -> { + updateFileMap[id]?.state = State.COMPLETE + updateFileMap[id]?.group = group + } + else -> { + updateFileMap[id]?.state = State.PROGRESS + updateFileMap[id]?.group = group + } } liveUpdateData.postValue(updateFileMap) diff --git a/app/src/main/res/layout/view_app_update.xml b/app/src/main/res/layout/view_app_update.xml index 81b708a25..cb3f4ec89 100644 --- a/app/src/main/res/layout/view_app_update.xml +++ b/app/src/main/res/layout/view_app_update.xml @@ -21,6 +21,7 @@ - + android:progressDrawable="@drawable/progressbar_bg" + android:visibility="invisible" + tools:progress="40" /> + android:textAppearance="@style/TextAppearance.Aurora.Line1" /> + + + + +