DownloadFragment: Refactor to work with new downloads logic
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
package com.aurora.store.data.room.download
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.aurora.gplayapi.data.models.App
|
||||
import com.aurora.store.data.model.DownloadStatus
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@Entity(tableName = "download")
|
||||
data class Download(
|
||||
@PrimaryKey val packageName: String,
|
||||
@@ -21,7 +24,7 @@ data class Download(
|
||||
var timeRemaining: Long,
|
||||
var totalFiles: Int,
|
||||
var downloadedFiles: Int
|
||||
) {
|
||||
) : Parcelable {
|
||||
val isFinished get() = status in DownloadStatus.finished
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -21,6 +21,8 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.io.path.ExperimentalPathApi
|
||||
import kotlin.io.path.deleteRecursively
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
class DownloadWorkerUtil @Inject constructor(
|
||||
@@ -42,6 +44,8 @@ class DownloadWorkerUtil @Inject constructor(
|
||||
val downloadsList = downloadDao.downloads()
|
||||
.stateIn(GlobalScope, SharingStarted.WhileSubscribed(), emptyList())
|
||||
|
||||
private val TAG = DownloadWorkerUtil::class.java.simpleName
|
||||
|
||||
fun init() {
|
||||
// Run cleanup for last finished download and drop it database
|
||||
GlobalScope.launch {
|
||||
@@ -68,13 +72,35 @@ class DownloadWorkerUtil @Inject constructor(
|
||||
downloadDao.insert(Download.fromApp(app))
|
||||
}
|
||||
|
||||
fun cancelDownload(packageName: String) {
|
||||
suspend fun cancelDownload(packageName: String) {
|
||||
Log.i(TAG, "Cancelling download for $packageName")
|
||||
WorkManager.getInstance(context).cancelAllWorkByTag("$PACKAGE_NAME:$packageName")
|
||||
downloadsList.value
|
||||
.find { it.packageName == packageName && it.status == DownloadStatus.QUEUED }
|
||||
?.let { downloadDao.update(it.copy(status = DownloadStatus.CANCELLED)) }
|
||||
}
|
||||
|
||||
fun cancelAll(context: Context, downloads: Boolean = true, updates: Boolean = true) {
|
||||
val workManager = WorkManager.getInstance(context)
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
suspend fun clearDownload(packageName: String, versionCode: Int) {
|
||||
Log.i(TAG, "Clearing downloads for $packageName ($versionCode)")
|
||||
downloadDao.delete(packageName)
|
||||
PathUtil.getAppDownloadDir(context, packageName, versionCode)
|
||||
.deleteRecursively()
|
||||
}
|
||||
|
||||
suspend fun clearFinishedDownloads() {
|
||||
downloadsList.value.filter { it.isFinished }.forEach {
|
||||
clearDownload(it.packageName, it.versionCode)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun cancelAll(downloads: Boolean = true, updates: Boolean = true) {
|
||||
// Cancel all enqueued downloads first to avoid triggering re-download
|
||||
downloadsList.value.filter { it.status == DownloadStatus.QUEUED }.forEach {
|
||||
downloadDao.update(it.copy(status = DownloadStatus.CANCELLED))
|
||||
}
|
||||
|
||||
val workManager = WorkManager.getInstance(context)
|
||||
if (downloads) workManager.cancelAllWorkByTag(DOWNLOAD_APP)
|
||||
if (updates) workManager.cancelAllWorkByTag(DOWNLOAD_UPDATE)
|
||||
}
|
||||
|
||||
@@ -27,17 +27,14 @@ import coil.transform.RoundedCornersTransformation
|
||||
import com.airbnb.epoxy.CallbackProp
|
||||
import com.airbnb.epoxy.ModelProp
|
||||
import com.airbnb.epoxy.ModelView
|
||||
import com.aurora.Constants
|
||||
import com.aurora.gplayapi.data.models.App
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.model.DownloadFile
|
||||
import com.aurora.store.data.model.DownloadStatus
|
||||
import com.aurora.store.data.room.download.Download
|
||||
import com.aurora.store.databinding.ViewDownloadBinding
|
||||
import com.aurora.store.util.CommonUtil.getDownloadSpeedString
|
||||
import com.aurora.store.util.CommonUtil.getETAString
|
||||
import com.aurora.store.util.CommonUtil.humanReadableByteValue
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.tonyodev.fetch2.Status
|
||||
import java.lang.reflect.Modifier
|
||||
import java.util.Locale
|
||||
|
||||
@@ -49,10 +46,6 @@ class DownloadView : RelativeLayout {
|
||||
|
||||
private lateinit var B: ViewDownloadBinding
|
||||
|
||||
private val gson: Gson = GsonBuilder()
|
||||
.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT)
|
||||
.create()
|
||||
|
||||
constructor(context: Context?) : super(context) {
|
||||
init(context)
|
||||
}
|
||||
@@ -75,18 +68,12 @@ class DownloadView : RelativeLayout {
|
||||
}
|
||||
|
||||
@ModelProp
|
||||
fun download(downloadFile: DownloadFile) {
|
||||
val download = downloadFile.download
|
||||
val extras = download.extras.getString(Constants.STRING_EXTRA, "{}")
|
||||
val app = gson.fromJson(extras, App::class.java)
|
||||
|
||||
app?.let {
|
||||
B.imgDownload.load(app.iconArtwork.url) {
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(RoundedCornersTransformation(32F))
|
||||
}
|
||||
B.txtTitle.text = app.displayName
|
||||
fun download(download: Download) {
|
||||
B.imgDownload.load(download.iconURL) {
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(RoundedCornersTransformation(32F))
|
||||
}
|
||||
B.txtTitle.text = download.displayName
|
||||
|
||||
B.txtStatus.text = download.status.name
|
||||
.lowercase(Locale.getDefault())
|
||||
@@ -98,33 +85,24 @@ class DownloadView : RelativeLayout {
|
||||
}
|
||||
}
|
||||
|
||||
B.txtSize.text = StringBuilder()
|
||||
.append(humanReadableByteValue(download.downloaded, true))
|
||||
.append("/")
|
||||
.append(humanReadableByteValue(download.total, true))
|
||||
|
||||
val file = download.file
|
||||
B.txtFile.text = file.substring(file.lastIndexOf("/") + 1)
|
||||
|
||||
var progress = download.progress
|
||||
if (progress == -1) {
|
||||
progress = 0
|
||||
B.progressDownload.apply {
|
||||
progress = download.progress
|
||||
isIndeterminate = download.progress <= 0 && !download.isFinished
|
||||
}
|
||||
B.txtProgress.text = ("${download.progress}%")
|
||||
|
||||
B.progressDownload.progress = progress
|
||||
B.txtProgress.text = ("$progress%")
|
||||
|
||||
B.txtEta.text = getETAString(context, download.etaInMilliSeconds)
|
||||
B.txtEta.text = getETAString(context, download.timeRemaining)
|
||||
B.txtSpeed.text = getDownloadSpeedString(
|
||||
context,
|
||||
download.downloadedBytesPerSecond
|
||||
download.speed
|
||||
)
|
||||
|
||||
when (download.status) {
|
||||
Status.DOWNLOADING, Status.QUEUED, Status.ADDED -> {
|
||||
DownloadStatus.DOWNLOADING, DownloadStatus.QUEUED -> {
|
||||
B.txtSpeed.visibility = VISIBLE
|
||||
B.txtEta.visibility = VISIBLE
|
||||
}
|
||||
|
||||
else -> {
|
||||
B.txtSpeed.visibility = INVISIBLE
|
||||
B.txtEta.visibility = INVISIBLE
|
||||
|
||||
@@ -22,24 +22,21 @@ package com.aurora.store.view.ui.downloads
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.aurora.store.MobileNavigationDirections
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.downloader.DownloadManager
|
||||
import com.aurora.store.data.model.DownloadFile
|
||||
import com.aurora.store.data.room.download.Download
|
||||
import com.aurora.store.databinding.FragmentDownloadBinding
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.DownloadWorkerUtil
|
||||
import com.aurora.store.view.epoxy.views.DownloadViewModel_
|
||||
import com.aurora.store.view.epoxy.views.app.NoAppViewModel_
|
||||
import com.aurora.store.view.ui.commons.BaseFragment
|
||||
import com.tonyodev.fetch2.AbstractFetchListener
|
||||
import com.tonyodev.fetch2.BuildConfig
|
||||
import com.tonyodev.fetch2.Download
|
||||
import com.tonyodev.fetch2.Error
|
||||
import com.tonyodev.fetch2.Fetch
|
||||
import com.tonyodev.fetch2.FetchListener
|
||||
import com.tonyodev.fetch2.Status
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DownloadFragment : BaseFragment(R.layout.fragment_download) {
|
||||
@@ -48,53 +45,8 @@ class DownloadFragment : BaseFragment(R.layout.fragment_download) {
|
||||
private val binding: FragmentDownloadBinding
|
||||
get() = _binding!!
|
||||
|
||||
private lateinit var fetch: Fetch
|
||||
|
||||
private var fetchListener: FetchListener = object : AbstractFetchListener() {
|
||||
override fun onAdded(download: Download) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onQueued(download: Download, waitingOnNetwork: Boolean) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onCompleted(download: Download) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onError(download: Download, error: Error, throwable: Throwable?) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onProgress(
|
||||
download: Download,
|
||||
etaInMilliSeconds: Long,
|
||||
downloadedBytesPerSecond: Long
|
||||
) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onPaused(download: Download) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onResumed(download: Download) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onCancelled(download: Download) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onRemoved(download: Download) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
|
||||
override fun onDeleted(download: Download) {
|
||||
updateDownloadsList()
|
||||
}
|
||||
}
|
||||
@Inject
|
||||
lateinit var downloadWorkerUtil: DownloadWorkerUtil
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
@@ -110,73 +62,32 @@ class DownloadFragment : BaseFragment(R.layout.fragment_download) {
|
||||
setNavigationOnClickListener { findNavController().navigateUp() }
|
||||
setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.action_pause_all -> {
|
||||
fetch.pauseAll()
|
||||
}
|
||||
|
||||
R.id.action_resume_all -> {
|
||||
fetch.resumeAll()
|
||||
}
|
||||
|
||||
R.id.action_cancel_all -> {
|
||||
fetch.cancelAll()
|
||||
viewLifecycleOwner.lifecycleScope.launch(NonCancellable) {
|
||||
downloadWorkerUtil.cancelAll()
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_clear_completed -> {
|
||||
fetch.removeAllWithStatus(Status.COMPLETED)
|
||||
Preferences.getPrefs(view.context).edit()
|
||||
.remove(Preferences.PREFERENCE_UNIQUE_GROUP_IDS).apply()
|
||||
}
|
||||
|
||||
R.id.action_force_clear_all -> {
|
||||
fetch.deleteAll()
|
||||
Preferences.getPrefs(view.context).edit()
|
||||
.remove(Preferences.PREFERENCE_UNIQUE_GROUP_IDS).apply()
|
||||
viewLifecycleOwner.lifecycleScope.launch(NonCancellable) {
|
||||
downloadWorkerUtil.clearFinishedDownloads()
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fetch = DownloadManager.with(view.context).fetch
|
||||
updateDownloadsList()
|
||||
|
||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||
updateDownloadsList()
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
downloadWorkerUtil.downloadsList.collectLatest { updateController(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (::fetch.isInitialized)
|
||||
fetch.addListener(fetchListener)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
if (::fetch.isInitialized)
|
||||
fetch.removeListener(fetchListener)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (::fetch.isInitialized) fetch.removeListener(fetchListener)
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun updateDownloadsList() {
|
||||
if (::fetch.isInitialized)
|
||||
fetch.getDownloads { downloads ->
|
||||
updateController(
|
||||
downloads
|
||||
.filter { it.id != BuildConfig.APPLICATION_ID.hashCode() }
|
||||
.sortedWith { o1, o2 -> o2.created.compareTo(o1.created) }
|
||||
.map { DownloadFile(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateController(downloads: List<DownloadFile>) {
|
||||
private fun updateController(downloads: List<Download>) {
|
||||
binding.recycler.withModels {
|
||||
if (downloads.isEmpty()) {
|
||||
add(
|
||||
@@ -188,12 +99,12 @@ class DownloadFragment : BaseFragment(R.layout.fragment_download) {
|
||||
downloads.forEach {
|
||||
add(
|
||||
DownloadViewModel_()
|
||||
.id(it.download.id, it.download.progress, it.download.status.value)
|
||||
.id(it.packageName)
|
||||
.download(it)
|
||||
.click { _ -> openDetailsActivity(it) }
|
||||
.click { _ -> openDetailsFragment(it.packageName) }
|
||||
.longClick { _ ->
|
||||
openDownloadMenuSheet(it)
|
||||
false
|
||||
true
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -202,15 +113,9 @@ class DownloadFragment : BaseFragment(R.layout.fragment_download) {
|
||||
binding.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
private fun openDetailsActivity(downloadFile: DownloadFile) {
|
||||
private fun openDownloadMenuSheet(download: Download) {
|
||||
findNavController().navigate(
|
||||
MobileNavigationDirections.actionGlobalAppDetailsFragment(downloadFile.download.tag!!)
|
||||
)
|
||||
}
|
||||
|
||||
private fun openDownloadMenuSheet(downloadFile: DownloadFile) {
|
||||
findNavController().navigate(
|
||||
DownloadFragmentDirections.actionDownloadFragmentToDownloadMenuSheet(downloadFile)
|
||||
DownloadFragmentDirections.actionDownloadFragmentToDownloadMenuSheet(download)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,79 +23,72 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.findViewTreeLifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import com.aurora.extensions.copyToClipBoard
|
||||
import com.aurora.extensions.toast
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.downloader.DownloadManager
|
||||
import com.aurora.store.data.model.DownloadStatus
|
||||
import com.aurora.store.databinding.SheetDownloadMenuBinding
|
||||
import com.aurora.store.util.DownloadWorkerUtil
|
||||
import com.tonyodev.fetch2.Fetch
|
||||
import com.tonyodev.fetch2.Status
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DownloadMenuSheet : BaseBottomSheet() {
|
||||
|
||||
private lateinit var B: SheetDownloadMenuBinding
|
||||
private lateinit var fetch: Fetch
|
||||
private var _binding: SheetDownloadMenuBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val args: DownloadMenuSheetArgs by navArgs()
|
||||
private var status by Delegates.notNull<Int>()
|
||||
private val playStoreURL = "https://play.google.com/store/apps/details?id="
|
||||
|
||||
@Inject
|
||||
lateinit var downloadWorkerUtil: DownloadWorkerUtil
|
||||
|
||||
override fun onCreateContentView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
B = SheetDownloadMenuBinding.inflate(layoutInflater)
|
||||
return B.root
|
||||
_binding = SheetDownloadMenuBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onContentViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
fetch = DownloadManager
|
||||
.with(requireContext())
|
||||
.getFetchInstance()
|
||||
|
||||
status = args.downloadFile.download.status.value
|
||||
attachNavigation()
|
||||
}
|
||||
|
||||
private fun attachNavigation() {
|
||||
with(B.navigationView) {
|
||||
if (status == Status.PAUSED.value || status == Status.COMPLETED.value || status == Status.CANCELLED.value) {
|
||||
menu.findItem(R.id.action_pause).isVisible = false
|
||||
}
|
||||
|
||||
if (status == Status.DOWNLOADING.value || status == Status.COMPLETED.value || status == Status.QUEUED.value) {
|
||||
menu.findItem(R.id.action_resume).isVisible = false
|
||||
}
|
||||
|
||||
if (status == Status.COMPLETED.value || status == Status.CANCELLED.value) {
|
||||
menu.findItem(R.id.action_cancel).isVisible = false
|
||||
}
|
||||
with(binding.navigationView) {
|
||||
menu.findItem(R.id.action_cancel).isVisible = !args.download.isFinished
|
||||
menu.findItem(R.id.action_clear).isVisible = args.download.isFinished
|
||||
|
||||
setNavigationItemSelectedListener { item ->
|
||||
when (item.itemId) {
|
||||
R.id.action_copy -> {
|
||||
requireContext().copyToClipBoard(args.downloadFile.download.url)
|
||||
requireContext().copyToClipBoard(
|
||||
"${playStoreURL}${args.download.packageName}"
|
||||
)
|
||||
requireContext().toast(requireContext().getString(R.string.toast_clipboard_copied))
|
||||
}
|
||||
R.id.action_pause -> {
|
||||
fetch.pause(args.downloadFile.download.id)
|
||||
}
|
||||
R.id.action_resume -> if (status == Status.FAILED.value || status == Status.CANCELLED.value) {
|
||||
fetch.retry(args.downloadFile.download.id)
|
||||
} else {
|
||||
fetch.resume(args.downloadFile.download.id)
|
||||
}
|
||||
R.id.action_cancel -> {
|
||||
fetch.cancel(args.downloadFile.download.id)
|
||||
findViewTreeLifecycleOwner()?.lifecycleScope?.launch(NonCancellable) {
|
||||
downloadWorkerUtil.cancelDownload(args.download.packageName)
|
||||
}
|
||||
}
|
||||
R.id.action_clear -> {
|
||||
fetch.delete(args.downloadFile.download.id)
|
||||
findViewTreeLifecycleOwner()?.lifecycleScope?.launch(NonCancellable) {
|
||||
downloadWorkerUtil.clearDownload(
|
||||
args.download.packageName,
|
||||
args.download.versionCode
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
dismissAllowingStateLoss()
|
||||
@@ -103,4 +96,9 @@ class DownloadMenuSheet : BaseBottomSheet() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,43 +51,15 @@
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="App Name" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/txt_status"
|
||||
style="@style/AuroraTextStyle.Line2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="Status" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/txt_size"
|
||||
style="@style/AuroraTextStyle.Line2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewEnd"
|
||||
tools:text="33 MB" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/txt_file"
|
||||
style="@style/AuroraTextStyle.Line3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="17dp"
|
||||
android:id="@+id/txt_status"
|
||||
style="@style/AuroraTextStyle.Line2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
tools:text="File path" />
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="Status" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_download"
|
||||
|
||||
@@ -18,19 +18,10 @@
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/action_pause_all"
|
||||
android:title="@string/download_pause_all" />
|
||||
<item
|
||||
android:id="@+id/action_resume_all"
|
||||
android:title="@string/download_resume_all" />
|
||||
<item
|
||||
android:id="@+id/action_cancel_all"
|
||||
android:title="@string/download_cancel_all" />
|
||||
<item
|
||||
android:id="@+id/action_clear_completed"
|
||||
android:title="@string/download_clear_completed" />
|
||||
<item
|
||||
android:id="@+id/action_force_clear_all"
|
||||
android:title="@string/download_force_clear_all" />
|
||||
</menu>
|
||||
</menu>
|
||||
|
||||
@@ -21,16 +21,10 @@
|
||||
<item
|
||||
android:id="@+id/action_copy"
|
||||
android:title="@string/action_copy_link" />
|
||||
<item
|
||||
android:id="@+id/action_pause"
|
||||
android:title="@string/action_pause" />
|
||||
<item
|
||||
android:id="@+id/action_resume"
|
||||
android:title="@string/action_resume" />
|
||||
<item
|
||||
android:id="@+id/action_cancel"
|
||||
android:title="@string/action_cancel" />
|
||||
<item
|
||||
android:id="@+id/action_clear"
|
||||
android:title="@string/action_clear" />
|
||||
</menu>
|
||||
</menu>
|
||||
|
||||
@@ -432,8 +432,8 @@
|
||||
android:label="DownloadMenuSheet"
|
||||
tools:layout="@layout/sheet_download_menu">
|
||||
<argument
|
||||
android:name="downloadFile"
|
||||
app:argType="com.aurora.store.data.model.DownloadFile" />
|
||||
android:name="download"
|
||||
app:argType="com.aurora.store.data.room.download.Download" />
|
||||
</dialog>
|
||||
<dialog
|
||||
android:id="@+id/deviceMiuiSheet"
|
||||
|
||||
Reference in New Issue
Block a user