mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Updates to Downloads UI
Add background to draggable items - tachiyomiorg/tachiyomi@73e5e9ecd9 Grouped chapter download list by source - tachiyomiorg/tachiyomi@9106fc5b94 Add "Move all chapters from series to top" option to download context menu - tachiyomiorg/tachiyomi@3aa4e6eb93 add sort by chapter number in download queue - tachiyomiorg/tachiyomi@a083e1f71a Fixes to fab pause/resume Closes #1205 Co-Authored-By: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Co-Authored-By: Franco Olivera <franco.olivera@fing.edu.uy> Co-Authored-By: Riztard Lanthorn <16263232+Riztard@users.noreply.github.com>
This commit is contained in:
parent
7363603732
commit
6174bced03
18 changed files with 309 additions and 65 deletions
|
@ -69,7 +69,9 @@ class DownloadManager(val context: Context) {
|
|||
* @return true if it's started, false otherwise (empty queue).
|
||||
*/
|
||||
fun startDownloads(): Boolean {
|
||||
return downloader.start()
|
||||
val hasStarted = downloader.start()
|
||||
DownloadService.callListeners(hasStarted)
|
||||
return hasStarted
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,6 +114,7 @@ class DownloadManager(val context: Context) {
|
|||
if (isPaused()) {
|
||||
if (DownloadService.isRunning(context)) {
|
||||
downloader.start()
|
||||
DownloadService.callListeners(true)
|
||||
} else {
|
||||
DownloadService.start(context)
|
||||
}
|
||||
|
@ -135,6 +138,7 @@ class DownloadManager(val context: Context) {
|
|||
downloader.queue.addAll(downloads)
|
||||
if (!wasPaused) {
|
||||
downloader.start()
|
||||
DownloadService.callListeners(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,6 +247,7 @@ class DownloadManager(val context: Context) {
|
|||
downloader.queue.remove(chapters)
|
||||
if (!wasPaused && downloader.queue.isNotEmpty()) {
|
||||
downloader.start()
|
||||
DownloadService.callListeners(true)
|
||||
} else if (downloader.queue.isEmpty() && DownloadService.isRunning(context)) {
|
||||
DownloadService.stop(context)
|
||||
} else if (downloader.queue.isEmpty()) {
|
||||
|
|
|
@ -55,7 +55,7 @@ class DownloadService : Service() {
|
|||
fun callListeners(downloading: Boolean? = null) {
|
||||
val downloadManager: DownloadManager by injectLazy()
|
||||
listeners.forEach {
|
||||
it.downloadStatusChanged(downloading ?: downloadManager.hasQueue())
|
||||
it.downloadStatusChanged(downloading ?: !downloadManager.isPaused())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ class DownloadService : Service() {
|
|||
subscriptions.unsubscribe()
|
||||
connectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
downloadManager.stopDownloads()
|
||||
callListeners(downloadManager.hasQueue())
|
||||
callListeners(false)
|
||||
wakeLock.releaseIfNeeded()
|
||||
if (LibraryUpdateService.runExtensionUpdatesAfter) {
|
||||
ExtensionUpdateJob.runJobAgain(this, NetworkType.CONNECTED)
|
||||
|
|
|
@ -2,13 +2,14 @@ package eu.kanade.tachiyomi.ui.download
|
|||
|
||||
import android.view.MenuItem
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
|
||||
/**
|
||||
* Adapter storing a list of downloads.
|
||||
*
|
||||
* @param context the context of the fragment containing this adapter.
|
||||
*/
|
||||
class DownloadAdapter(controller: DownloadItemListener) : FlexibleAdapter<DownloadItem>(
|
||||
class DownloadAdapter(controller: DownloadItemListener) : FlexibleAdapter<AbstractFlexibleItem<*>>(
|
||||
null,
|
||||
controller,
|
||||
true
|
||||
|
@ -28,12 +29,21 @@ class DownloadAdapter(controller: DownloadItemListener) : FlexibleAdapter<Downlo
|
|||
fun onMenuItemClick(position: Int, menuItem: MenuItem)
|
||||
}
|
||||
|
||||
override fun shouldMove(fromPosition: Int, toPosition: Int): Boolean {
|
||||
// Don't let sub-items changing group
|
||||
return getHeaderOf(getItem(fromPosition)) == getHeaderOf(getItem(toPosition))
|
||||
}
|
||||
|
||||
override fun onItemSwiped(position: Int, direction: Int) {
|
||||
super.onItemSwiped(position, direction)
|
||||
downloadItemListener.onItemRemoved(position)
|
||||
}
|
||||
|
||||
override fun onCreateBubbleText(position: Int): String {
|
||||
return getItem(position)?.download?.manga?.title ?: ""
|
||||
return when (val item = getItem(position)) {
|
||||
is DownloadHeaderItem -> item.name
|
||||
is DownloadItem -> item.download.manga.title
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class DownloadBottomPresenter(val sheet: DownloadBottomSheet) {
|
|||
* Download manager.
|
||||
*/
|
||||
val downloadManager: DownloadManager by injectLazy()
|
||||
var items = listOf<DownloadItem>()
|
||||
var items = listOf<DownloadHeaderItem>()
|
||||
|
||||
private var scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
|
||||
|
@ -31,13 +31,27 @@ class DownloadBottomPresenter(val sheet: DownloadBottomSheet) {
|
|||
|
||||
fun getItems() {
|
||||
scope.launch {
|
||||
val items = downloadQueue.map(::DownloadItem)
|
||||
val hasChanged = if (this@DownloadBottomPresenter.items.size != items.size) true
|
||||
val items = downloadQueue
|
||||
.groupBy { it.source }
|
||||
.map { entry ->
|
||||
DownloadHeaderItem(entry.key.id, entry.key.name, entry.value.size).apply {
|
||||
addSubItems(0, entry.value.map { DownloadItem(it, this) })
|
||||
}
|
||||
}
|
||||
val hasChanged = if (this@DownloadBottomPresenter.items.size != items.size ||
|
||||
this@DownloadBottomPresenter.items.sumOf { it.subItemsCount } != items.sumOf { it.subItemsCount }
|
||||
) true
|
||||
else {
|
||||
val oldItemsIds = this@DownloadBottomPresenter.items.mapNotNull {
|
||||
it.download.chapter.id
|
||||
}.toLongArray()
|
||||
val newItemsIds = items.mapNotNull { it.download.chapter.id }.toLongArray()
|
||||
val oldItemsIds = this@DownloadBottomPresenter.items.map { header ->
|
||||
header.subItems.mapNotNull { it.download.chapter.id }
|
||||
}
|
||||
.flatten()
|
||||
.toLongArray()
|
||||
val newItemsIds = items.map { header ->
|
||||
header.subItems.mapNotNull { it.download.chapter.id }
|
||||
}
|
||||
.flatten()
|
||||
.toLongArray()
|
||||
!oldItemsIds.contentEquals(newItemsIds)
|
||||
}
|
||||
this@DownloadBottomPresenter.items = items
|
||||
|
|
|
@ -93,7 +93,7 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||
}
|
||||
updateFab()
|
||||
}
|
||||
update()
|
||||
update(!presenter.downloadManager.isPaused())
|
||||
setInformationView()
|
||||
if (!controller.hasQueue()) {
|
||||
sheetBehavior?.isHideable = true
|
||||
|
@ -101,9 +101,9 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun update() {
|
||||
fun update(isRunning: Boolean) {
|
||||
presenter.getItems()
|
||||
onQueueStatusChange(!presenter.downloadManager.isPaused())
|
||||
onQueueStatusChange(isRunning)
|
||||
binding.downloadFab.isInvisible = presenter.downloadQueue.isEmpty()
|
||||
prepareMenu()
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||
*
|
||||
* @param downloads the downloads from the queue.
|
||||
*/
|
||||
fun onNextDownloads(downloads: List<DownloadItem>) {
|
||||
fun onNextDownloads(downloads: List<DownloadHeaderItem>) {
|
||||
prepareMenu()
|
||||
setInformationView()
|
||||
adapter?.updateDataSet(downloads)
|
||||
|
@ -214,20 +214,30 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||
presenter.clearQueue()
|
||||
}
|
||||
R.id.newest, R.id.oldest -> {
|
||||
val adapter = adapter ?: return false
|
||||
val items = adapter.currentItems.sortedBy { it.download.chapter.date_upload }
|
||||
.toMutableList()
|
||||
if (item.itemId == R.id.newest) {
|
||||
items.reverse()
|
||||
}
|
||||
adapter.updateDataSet(items)
|
||||
val downloads = items.mapNotNull { it.download }
|
||||
presenter.reorder(downloads)
|
||||
reorderQueue({ it.download.chapter.date_upload }, item.itemId == R.id.newest)
|
||||
}
|
||||
R.id.asc, R.id.desc -> {
|
||||
reorderQueue({ it.download.chapter.chapter_number }, item.itemId == R.id.desc)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun <R : Comparable<R>> reorderQueue(selector: (DownloadItem) -> R, reverse: Boolean = false) {
|
||||
val adapter = adapter ?: return
|
||||
val newDownloads = mutableListOf<Download>()
|
||||
adapter.headerItems.forEach { headerItem ->
|
||||
headerItem as DownloadHeaderItem
|
||||
headerItem.subItems = headerItem.subItems.sortedBy(selector).toMutableList().apply {
|
||||
if (reverse) {
|
||||
reverse()
|
||||
}
|
||||
}
|
||||
newDownloads.addAll(headerItem.subItems.map { it.download })
|
||||
}
|
||||
presenter.reorder(newDownloads)
|
||||
}
|
||||
|
||||
fun dismiss() {
|
||||
if (sheetBehavior?.isHideable == true) {
|
||||
sheetBehavior?.hide()
|
||||
|
@ -256,17 +266,25 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||
*/
|
||||
override fun onItemReleased(position: Int) {
|
||||
val adapter = adapter ?: return
|
||||
val downloads = (0 until adapter.itemCount).mapNotNull { adapter.getItem(it)?.download }
|
||||
val downloads = adapter.headerItems.flatMap { header ->
|
||||
adapter.getSectionItems(header).map { item ->
|
||||
(item as DownloadItem).download
|
||||
}
|
||||
}
|
||||
presenter.reorder(downloads)
|
||||
}
|
||||
|
||||
override fun onItemRemoved(position: Int) {
|
||||
val download = adapter?.getItem(position)?.download ?: return
|
||||
val download = (adapter?.getItem(position) as? DownloadItem)?.download ?: return
|
||||
presenter.cancelDownload(download)
|
||||
|
||||
adapter?.removeItem(position)
|
||||
val adapter = adapter ?: return
|
||||
val downloads = (0 until adapter.itemCount).mapNotNull { adapter.getItem(it)?.download }
|
||||
val downloads = adapter.headerItems.flatMap { header ->
|
||||
adapter.getSectionItems(header).map { item ->
|
||||
(item as DownloadItem).download
|
||||
}
|
||||
}
|
||||
presenter.reorder(downloads)
|
||||
controller.updateChapterDownload(download, false)
|
||||
}
|
||||
|
@ -278,27 +296,42 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||
* @param menuItem The menu Item pressed
|
||||
*/
|
||||
override fun onMenuItemClick(position: Int, menuItem: MenuItem) {
|
||||
when (menuItem.itemId) {
|
||||
R.id.move_to_top, R.id.move_to_bottom -> {
|
||||
val items = adapter?.currentItems?.toMutableList() ?: return
|
||||
val item = items[position]
|
||||
items.remove(item)
|
||||
if (menuItem.itemId == R.id.move_to_top) {
|
||||
items.add(0, item)
|
||||
} else {
|
||||
items.add(item)
|
||||
val item = adapter?.getItem(position) ?: return
|
||||
if (item is DownloadItem) {
|
||||
when (menuItem.itemId) {
|
||||
R.id.move_to_top, R.id.move_to_bottom -> {
|
||||
val headerItems = adapter?.headerItems ?: return
|
||||
val newDownloads = mutableListOf<Download>()
|
||||
headerItems.forEach { headerItem ->
|
||||
headerItem as DownloadHeaderItem
|
||||
if (headerItem == item.header) {
|
||||
headerItem.removeSubItem(item)
|
||||
if (menuItem.itemId == R.id.move_to_top) {
|
||||
headerItem.addSubItem(0, item)
|
||||
} else {
|
||||
headerItem.addSubItem(item)
|
||||
}
|
||||
}
|
||||
newDownloads.addAll(headerItem.subItems.map { it.download })
|
||||
}
|
||||
presenter.reorder(newDownloads)
|
||||
}
|
||||
adapter?.updateDataSet(items)
|
||||
val downloads = items.mapNotNull { it.download }
|
||||
presenter.reorder(downloads)
|
||||
}
|
||||
R.id.cancel_series -> {
|
||||
val download = adapter?.getItem(position)?.download ?: return
|
||||
val allDownloadsForSeries = adapter?.currentItems
|
||||
?.filter { download.manga.id == it.download.manga.id }
|
||||
?.map(DownloadItem::download)
|
||||
if (!allDownloadsForSeries.isNullOrEmpty()) {
|
||||
presenter.cancelDownloads(allDownloadsForSeries)
|
||||
R.id.move_to_top_series -> {
|
||||
val (selectedSeries, otherSeries) = adapter?.currentItems
|
||||
?.filterIsInstance<DownloadItem>()
|
||||
?.map(DownloadItem::download)
|
||||
?.partition { item.download.manga.id == it.manga.id }
|
||||
?: Pair(listOf<Download>(), listOf<Download>())
|
||||
presenter.reorder(selectedSeries + otherSeries)
|
||||
}
|
||||
R.id.cancel_series -> {
|
||||
val allDownloadsForSeries = adapter?.currentItems
|
||||
?.filterIsInstance<DownloadItem>()
|
||||
?.filter { item.download.manga.id == it.download.manga.id }
|
||||
?.map(DownloadItem::download)
|
||||
if (!allDownloadsForSeries.isNullOrEmpty()) {
|
||||
presenter.cancelDownloads(allDownloadsForSeries)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package eu.kanade.tachiyomi.ui.download
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.viewholders.ExpandableViewHolder
|
||||
import eu.kanade.tachiyomi.databinding.DownloadHeaderBinding
|
||||
|
||||
class DownloadHeaderHolder(view: View, adapter: FlexibleAdapter<*>) : ExpandableViewHolder(view, adapter) {
|
||||
|
||||
private val binding = DownloadHeaderBinding.bind(view)
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun bind(item: DownloadHeaderItem) {
|
||||
setDragHandleView(binding.reorder)
|
||||
binding.title.text = "${item.name} (${item.size})"
|
||||
}
|
||||
|
||||
override fun onActionStateChanged(position: Int, actionState: Int) {
|
||||
super.onActionStateChanged(position, actionState)
|
||||
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
|
||||
binding.container.isDragged = true
|
||||
mAdapter.collapseAll()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemReleased(position: Int) {
|
||||
super.onItemReleased(position)
|
||||
binding.container.isDragged = false
|
||||
mAdapter as DownloadAdapter
|
||||
mAdapter.expandAll()
|
||||
mAdapter.downloadItemListener.onItemReleased(position)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package eu.kanade.tachiyomi.ui.download
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
data class DownloadHeaderItem(
|
||||
val id: Long,
|
||||
val name: String,
|
||||
val size: Int,
|
||||
) : AbstractExpandableHeaderItem<DownloadHeaderHolder, DownloadItem>() {
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return R.layout.download_header
|
||||
}
|
||||
|
||||
override fun createViewHolder(
|
||||
view: View,
|
||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
|
||||
): DownloadHeaderHolder {
|
||||
return DownloadHeaderHolder(view, adapter)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(
|
||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
|
||||
holder: DownloadHeaderHolder,
|
||||
position: Int,
|
||||
payloads: List<Any?>?,
|
||||
) {
|
||||
holder.bind(this)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other is DownloadHeaderItem) {
|
||||
return id == other.id && name == other.name
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
init {
|
||||
isHidden = false
|
||||
isExpanded = true
|
||||
isSelectable = false
|
||||
isSwipeable = false
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.download
|
|||
import android.view.View
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.databinding.DownloadItemBinding
|
||||
|
@ -77,9 +78,18 @@ class DownloadHolder(private val view: View, val adapter: DownloadAdapter) :
|
|||
binding.downloadProgressText.text = "${download.downloadedImages}/${pages.size}"
|
||||
}
|
||||
|
||||
override fun onActionStateChanged(position: Int, actionState: Int) {
|
||||
super.onActionStateChanged(position, actionState)
|
||||
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
|
||||
binding.root.isDragged = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemReleased(position: Int) {
|
||||
super.onItemReleased(position)
|
||||
adapter.downloadItemListener.onItemReleased(position)
|
||||
binding.root.isDragged = false
|
||||
binding.root.cardElevation = 0f
|
||||
}
|
||||
|
||||
private fun showPopupMenu(view: View) {
|
||||
|
|
|
@ -3,12 +3,15 @@ package eu.kanade.tachiyomi.ui.download
|
|||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
|
||||
class DownloadItem(val download: Download) : AbstractFlexibleItem<DownloadHolder>() {
|
||||
class DownloadItem(
|
||||
val download: Download,
|
||||
header: DownloadHeaderItem,
|
||||
) : AbstractSectionableItem<DownloadHolder, DownloadHeaderItem>(header) {
|
||||
|
||||
/**
|
||||
* Whether this item is currently selected.
|
||||
|
|
|
@ -474,7 +474,7 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
refresh()
|
||||
}
|
||||
setBottomPadding()
|
||||
binding.downloadBottomSheet.dlBottomSheet.update()
|
||||
binding.downloadBottomSheet.dlBottomSheet.update(!presenter.downloadManager.isPaused())
|
||||
|
||||
if (BuildConfig.DEBUG && query.isBlank() && isControllerVisible) {
|
||||
val searchItem =
|
||||
|
@ -560,7 +560,7 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
fun updateChapterDownload(download: Download, updateDLSheet: Boolean = true) {
|
||||
if (view == null) return
|
||||
if (updateDLSheet) {
|
||||
binding.downloadBottomSheet.dlBottomSheet.update()
|
||||
binding.downloadBottomSheet.dlBottomSheet.update(!presenter.downloadManager.isPaused())
|
||||
binding.downloadBottomSheet.dlBottomSheet.onUpdateProgress(download)
|
||||
binding.downloadBottomSheet.dlBottomSheet.onUpdateDownloadedPages(download)
|
||||
}
|
||||
|
@ -569,8 +569,8 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
holder.notifyStatus(download.status, download.progress, download.chapter.read, true)
|
||||
}
|
||||
|
||||
fun updateDownloadStatus() {
|
||||
binding.downloadBottomSheet.dlBottomSheet.update()
|
||||
fun updateDownloadStatus(isRunning: Boolean) {
|
||||
binding.downloadBottomSheet.dlBottomSheet.update(isRunning)
|
||||
}
|
||||
|
||||
private fun refreshItem(chapterId: Long) {
|
||||
|
|
|
@ -378,7 +378,7 @@ class RecentsPresenter(
|
|||
setDownloadedChapters(recentItems)
|
||||
withContext(Dispatchers.Main) {
|
||||
controller?.showLists(recentItems, true)
|
||||
controller?.updateDownloadStatus()
|
||||
controller?.updateDownloadStatus(!downloadManager.isPaused())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ class RecentsPresenter(
|
|||
override fun downloadStatusChanged(downloading: Boolean) {
|
||||
presenterScope.launch {
|
||||
withContext(Dispatchers.Main) {
|
||||
controller?.updateDownloadStatus()
|
||||
controller?.updateDownloadStatus(downloading)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
7
app/src/main/res/color/draggable_card_foreground.xml
Normal file
7
app/src/main/res/color/draggable_card_foreground.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item android:alpha="0.08" android:color="?attr/colorSecondary" app:state_dragged="true" />
|
||||
<item android:alpha="0.08" android:color="?attr/colorSecondary" android:state_activated="true" />
|
||||
<item android:color="@android:color/transparent" />
|
||||
</selector>
|
39
app/src/main/res/layout/download_header.xml
Normal file
39
app/src/main/res/layout/download_header.xml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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:id="@+id/container"
|
||||
style="@style/Widget.Tachiyomi.CardView.Draggable"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:textAppearance="?textAppearanceLabelLarge"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:text="Title" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/reorder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:scaleType="center"
|
||||
app:srcCompat="@drawable/ic_drag_handle_24dp"
|
||||
app:tint="?android:attr/textColorHint"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -1,8 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/Widget.Tachiyomi.CardView.Draggable"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<FrameLayout
|
||||
|
@ -129,4 +128,4 @@
|
|||
app:srcCompat="@drawable/ic_more_vert_24dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu 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">
|
||||
|
||||
<item
|
||||
android:id="@+id/reorder"
|
||||
|
@ -9,11 +9,31 @@
|
|||
app:showAsAction="never">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/newest"
|
||||
android:title="@string/newest"/>
|
||||
android:id="@+id/action_sort_date"
|
||||
android:title="@string/by_update_date"
|
||||
app:showAsAction="never">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/newest"
|
||||
android:title="@string/newest" />
|
||||
<item
|
||||
android:id="@+id/oldest"
|
||||
android:title="@string/oldest" />
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/oldest"
|
||||
android:title="@string/oldest"/>
|
||||
android:id="@+id/action_sort_chapter"
|
||||
android:title="@string/by_chapter_number"
|
||||
app:showAsAction="never">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/asc"
|
||||
android:title="@string/ascending" />
|
||||
<item
|
||||
android:id="@+id/desc"
|
||||
android:title="@string/descending" />
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
<item android:id="@+id/move_to_bottom"
|
||||
android:title="@string/move_to_bottom" />
|
||||
|
||||
<item android:id="@+id/move_to_top_series"
|
||||
android:title="@string/move_series_to_top" />
|
||||
|
||||
<item android:id="@+id/cancel_series"
|
||||
android:title="@string/cancel_all_for_series" />
|
||||
</menu>
|
|
@ -873,6 +873,7 @@
|
|||
<string name="download_queue">Download queue</string>
|
||||
<string name="downloading_">Downloading: %1$s</string>
|
||||
<string name="cancel_all">Cancel all</string>
|
||||
<string name="move_series_to_top">Move series to top</string>
|
||||
<string name="cancel_all_for_series">Cancel all for this series</string>
|
||||
<string name="downloaded">Downloaded</string>
|
||||
<string name="not_downloaded">Not downloaded</string>
|
||||
|
@ -951,6 +952,7 @@
|
|||
<string name="alphabetically">Alphabetically</string>
|
||||
<string name="always">Always</string>
|
||||
<string name="always_ask">Always ask</string>
|
||||
<string name="ascending">Ascending</string>
|
||||
<string name="automatic">Automatic</string>
|
||||
<string name="back">Back</string>
|
||||
<string name="beta">BETA</string>
|
||||
|
@ -966,6 +968,7 @@
|
|||
<string name="cover_of_image">Cover of manga</string>
|
||||
<string name="create">Create</string>
|
||||
<string name="date">Date</string>
|
||||
<string name="descending">Descending</string>
|
||||
<string name="default_value">Default</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="deleted_">Deleted: %1$s</string>
|
||||
|
|
|
@ -87,6 +87,15 @@
|
|||
<item name="cardElevation">4dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Tachiyomi.CardView.Draggable" parent="Widget.Material3.CardView.Elevated">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="cardCornerRadius">0dp</item>
|
||||
<item name="cardBackgroundColor">?background</item>
|
||||
<item name="cardForegroundColor">@color/draggable_card_foreground</item>
|
||||
<item name="cardElevation">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Widget.GridView">
|
||||
<item name="android:smoothScrollbar">true</item>
|
||||
<item name="android:numColumns">auto_fit</item>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue