Improve updates fragment actions

This commit is contained in:
Rahul Kumar Patel
2021-03-20 02:28:29 +05:30
parent 48c5651250
commit 4023a1881e
9 changed files with 151 additions and 55 deletions

View File

@@ -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()

View File

@@ -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? = "",

View File

@@ -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)

View File

@@ -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)
}
}

View File

@@ -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()
}
}

View File

@@ -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<Download>) {
task {
AppInstaller(requireContext())
.getPreferredInstaller()
.install(
packageName,
files
.filter { it.file.endsWith(".apk") }
.map { it.file }.toList()
)
private fun install(packageName: String, files: List<Download>?) {
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()
)
}
}
}
}

View File

@@ -39,6 +39,7 @@ class UpdatesViewModel(application: Application) : BaseAppsViewModel(application
var updateFileMap: MutableMap<Int, UpdateFile> = mutableMapOf()
var liveUpdateData: MutableLiveData<MutableMap<Int, UpdateFile>> = 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)