mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-24 15:01:52 +01:00
Made chapters swipeable to change read/bookmark status
This commit is contained in:
parent
87e86f81cf
commit
b331e12fde
@ -40,7 +40,7 @@ class Download(val source: HttpSource, val manga: Manga, val chapter: Chapter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val CHECKED = -1
|
||||||
const val NOT_DOWNLOADED = 0
|
const val NOT_DOWNLOADED = 0
|
||||||
const val QUEUE = 1
|
const val QUEUE = 1
|
||||||
const val DOWNLOADING = 2
|
const val DOWNLOADING = 2
|
||||||
|
@ -29,6 +29,10 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
R.drawable.filled_circle)?.mutate()
|
R.drawable.filled_circle)?.mutate()
|
||||||
private val borderCircle = ContextCompat.getDrawable(context,
|
private val borderCircle = ContextCompat.getDrawable(context,
|
||||||
R.drawable.border_circle)?.mutate()
|
R.drawable.border_circle)?.mutate()
|
||||||
|
private val downloadDrawable = ContextCompat.getDrawable(context,
|
||||||
|
R.drawable.ic_arrow_down_white_24dp)?.mutate()
|
||||||
|
private val checkDrawable = ContextCompat.getDrawable(context,
|
||||||
|
R.drawable.ic_check_white_24dp)?.mutate()
|
||||||
private var isAnimating = false
|
private var isAnimating = false
|
||||||
private var iconAnimation: ObjectAnimator? = null
|
private var iconAnimation: ObjectAnimator? = null
|
||||||
|
|
||||||
@ -38,7 +42,17 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
download_icon.alpha = 1f
|
download_icon.alpha = 1f
|
||||||
isAnimating = false
|
isAnimating = false
|
||||||
}
|
}
|
||||||
|
download_icon.setImageDrawable(if (state == Download.CHECKED)
|
||||||
|
checkDrawable else downloadDrawable)
|
||||||
when (state) {
|
when (state) {
|
||||||
|
Download.CHECKED -> {
|
||||||
|
download_progress.gone()
|
||||||
|
download_border.visible()
|
||||||
|
download_progress_indeterminate.gone()
|
||||||
|
download_border.setImageDrawable(filledCircle)
|
||||||
|
download_border.drawable.setTint(activeColor)
|
||||||
|
download_icon.drawable.setTint(Color.WHITE)
|
||||||
|
}
|
||||||
Download.NOT_DOWNLOADED -> {
|
Download.NOT_DOWNLOADED -> {
|
||||||
download_border.visible()
|
download_border.visible()
|
||||||
download_progress.gone()
|
download_progress.gone()
|
||||||
|
@ -441,7 +441,7 @@ open class LibraryController(
|
|||||||
|
|
||||||
val searchItem = menu.findItem(R.id.action_search)
|
val searchItem = menu.findItem(R.id.action_search)
|
||||||
val searchView = searchItem.actionView as SearchView
|
val searchView = searchItem.actionView as SearchView
|
||||||
searchView.queryHint = resources?.getString(R.string.search_hint)
|
searchView.queryHint = resources?.getString(R.string.library_search_hint)
|
||||||
|
|
||||||
searchItem.collapseActionView()
|
searchItem.collapseActionView()
|
||||||
if (query.isNotEmpty()) {
|
if (query.isNotEmpty()) {
|
||||||
|
@ -59,10 +59,8 @@ import eu.kanade.tachiyomi.ui.setting.SettingsController
|
|||||||
import eu.kanade.tachiyomi.ui.setting.SettingsMainController
|
import eu.kanade.tachiyomi.ui.setting.SettingsMainController
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
|
||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
import eu.kanade.tachiyomi.util.view.updatePadding
|
import eu.kanade.tachiyomi.util.view.updatePadding
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
@ -197,19 +195,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
container.systemUiVisibility =
|
container.systemUiVisibility =
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
updateRecentsIcon()
|
updateRecentsIcon()
|
||||||
content.viewTreeObserver.addOnGlobalLayoutListener {
|
|
||||||
val heightDiff: Int = content.rootView.height - content.height
|
|
||||||
if (heightDiff > 200 && window.attributes.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
|
|
||||||
// keyboard is open, hide layout
|
|
||||||
bottom_nav.gone()
|
|
||||||
} else if (bottom_nav.visibility == View.GONE && window.attributes.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
|
|
||||||
// keyboard is hidden, show layout
|
|
||||||
// use coroutine to delay so the bottom bar doesn't flash on top of the keyboard
|
|
||||||
launchUI {
|
|
||||||
bottom_nav.visible()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
supportActionBar?.setDisplayShowCustomEnabled(true)
|
supportActionBar?.setDisplayShowCustomEnabled(true)
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ import android.graphics.drawable.BitmapDrawable
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
@ -31,12 +30,14 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
import androidx.palette.graphics.Palette
|
import androidx.palette.graphics.Palette
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.transition.ChangeBounds
|
import androidx.transition.ChangeBounds
|
||||||
@ -95,6 +96,7 @@ import eu.kanade.tachiyomi.util.system.launchUI
|
|||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||||
import eu.kanade.tachiyomi.util.view.getText
|
import eu.kanade.tachiyomi.util.view.getText
|
||||||
|
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
||||||
import eu.kanade.tachiyomi.util.view.snack
|
import eu.kanade.tachiyomi.util.view.snack
|
||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
@ -114,6 +116,7 @@ class MangaDetailsController : BaseController,
|
|||||||
FlexibleAdapter.OnItemLongClickListener,
|
FlexibleAdapter.OnItemLongClickListener,
|
||||||
ActionMode.Callback,
|
ActionMode.Callback,
|
||||||
ChaptersAdapter.MangaHeaderInterface,
|
ChaptersAdapter.MangaHeaderInterface,
|
||||||
|
FlexibleAdapter.OnItemMoveListener,
|
||||||
ChangeMangaCategoriesDialog.Listener {
|
ChangeMangaCategoriesDialog.Listener {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -159,6 +162,11 @@ class MangaDetailsController : BaseController,
|
|||||||
private var editMangaDialog: EditMangaDialog? = null
|
private var editMangaDialog: EditMangaDialog? = null
|
||||||
var refreshTracker: Int? = null
|
var refreshTracker: Int? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Library search query.
|
||||||
|
*/
|
||||||
|
private var query = ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter containing a list of chapters.
|
* Adapter containing a list of chapters.
|
||||||
*/
|
*/
|
||||||
@ -190,6 +198,7 @@ class MangaDetailsController : BaseController,
|
|||||||
adapter = ChaptersAdapter(this, view.context)
|
adapter = ChaptersAdapter(this, view.context)
|
||||||
|
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
|
adapter?.isSwipeEnabled = true
|
||||||
recycler.layoutManager = LinearLayoutManager(view.context)
|
recycler.layoutManager = LinearLayoutManager(view.context)
|
||||||
recycler.addItemDecoration(
|
recycler.addItemDecoration(
|
||||||
DividerItemDecoration(
|
DividerItemDecoration(
|
||||||
@ -369,6 +378,13 @@ class MangaDetailsController : BaseController,
|
|||||||
presenter.preferences.theme()
|
presenter.preferences.theme()
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
if (forThis)
|
||||||
|
(activity as MainActivity).appbar.context.setTheme(R.style
|
||||||
|
.ThemeOverlay_AppCompat_DayNight_ActionBar)
|
||||||
|
else
|
||||||
|
(activity as MainActivity).appbar.context.setTheme(R.style
|
||||||
|
.Theme_ActionBar_Dark_DayNight)
|
||||||
|
|
||||||
val iconPrimary = view?.context?.getResourceColor(
|
val iconPrimary = view?.context?.getResourceColor(
|
||||||
if (forThis) android.R.attr.textColorPrimary
|
if (forThis) android.R.attr.textColorPrimary
|
||||||
else R.attr.actionBarTintColor
|
else R.attr.actionBarTintColor
|
||||||
@ -418,6 +434,8 @@ class MangaDetailsController : BaseController,
|
|||||||
adapter?.addSelection(position)
|
adapter?.addSelection(position)
|
||||||
(recycler.findViewHolderForAdapterPosition(position) as? BaseFlexibleViewHolder)
|
(recycler.findViewHolderForAdapterPosition(position) as? BaseFlexibleViewHolder)
|
||||||
?.toggleActivation()
|
?.toggleActivation()
|
||||||
|
(recycler.findViewHolderForAdapterPosition(position) as? ChapterMatHolder)
|
||||||
|
?.notifyStatus(Download.CHECKED, false, 0)
|
||||||
startingDLChapterPos = position
|
startingDLChapterPos = position
|
||||||
actionMode?.invalidate()
|
actionMode?.invalidate()
|
||||||
} else {
|
} else {
|
||||||
@ -446,24 +464,24 @@ class MangaDetailsController : BaseController,
|
|||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
val item = (adapter.getItem(position) as? ChapterItem) ?: return
|
val item = (adapter.getItem(position) as? ChapterItem) ?: return
|
||||||
val itemView = getHolder(item)?.itemView ?: return
|
val itemView = getHolder(item)?.itemView ?: return
|
||||||
val popup = PopupMenu(itemView.context, itemView, Gravity.END)
|
val popup = PopupMenu(itemView.context, itemView)
|
||||||
|
|
||||||
// Inflate our menu resource into the PopupMenu's Menu
|
// Inflate our menu resource into the PopupMenu's Menu
|
||||||
popup.menuInflater.inflate(R.menu.chapters_mat_single, popup.menu)
|
popup.menuInflater.inflate(R.menu.chapters_mat_single, popup.menu)
|
||||||
|
|
||||||
// Hide bookmark if bookmark
|
// Hide bookmark if bookmark
|
||||||
popup.menu.findItem(R.id.action_bookmark).isVisible = !item.bookmark
|
popup.menu.findItem(R.id.action_bookmark).isVisible = false // !item.bookmark
|
||||||
popup.menu.findItem(R.id.action_remove_bookmark).isVisible = item.bookmark
|
popup.menu.findItem(R.id.action_remove_bookmark).isVisible = false // item.bookmark
|
||||||
|
|
||||||
// Hide mark as unread when the chapter is unread
|
// Hide mark as unread when the chapter is unread
|
||||||
if (!item.read && item.last_page_read == 0) {
|
// if (!item.read && item.last_page_read == 0) {
|
||||||
popup.menu.findItem(R.id.action_mark_as_unread).isVisible = false
|
popup.menu.findItem(R.id.action_mark_as_unread).isVisible = false
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Hide mark as read when the chapter is read
|
// Hide mark as read when the chapter is read
|
||||||
if (item.read) {
|
// if (item.read) {
|
||||||
popup.menu.findItem(R.id.action_mark_as_read).isVisible = false
|
popup.menu.findItem(R.id.action_mark_as_read).isVisible = false
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Set a listener so we are notified if a menu item is clicked
|
// Set a listener so we are notified if a menu item is clicked
|
||||||
popup.setOnMenuItemClickListener { menuItem ->
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
@ -491,19 +509,30 @@ class MangaDetailsController : BaseController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun bookmarkChapter(position: Int) {
|
||||||
|
val item = adapter?.getItem(position) as? ChapterItem ?: return
|
||||||
|
bookmarkChapters(listOf(item), !item.bookmark)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toggleReadChapter(position: Int) {
|
||||||
|
val item = adapter?.getItem(position) as? ChapterItem ?: return
|
||||||
|
if (!item.read) markAsRead(listOf(item), false)
|
||||||
|
else markAsUnread(listOf(item), false)
|
||||||
|
}
|
||||||
|
|
||||||
private fun bookmarkChapters(chapters: List<ChapterItem>, bookmarked: Boolean) {
|
private fun bookmarkChapters(chapters: List<ChapterItem>, bookmarked: Boolean) {
|
||||||
presenter.bookmarkChapters(chapters, bookmarked)
|
presenter.bookmarkChapters(chapters, bookmarked)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markAsRead(chapters: List<ChapterItem>) {
|
private fun markAsRead(chapters: List<ChapterItem>, refresh: Boolean = true) {
|
||||||
presenter.markChaptersRead(chapters, true)
|
presenter.markChaptersRead(chapters, read = true)
|
||||||
if (presenter.preferences.removeAfterMarkedAsRead()) {
|
if (presenter.preferences.removeAfterMarkedAsRead()) {
|
||||||
presenter.deleteChapters(chapters)
|
presenter.deleteChapters(chapters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markAsUnread(chapters: List<ChapterItem>) {
|
private fun markAsUnread(chapters: List<ChapterItem>, refresh: Boolean = true) {
|
||||||
presenter.markChaptersRead(chapters, false)
|
presenter.markChaptersRead(chapters, read = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openChapter(chapter: Chapter) {
|
private fun openChapter(chapter: Chapter) {
|
||||||
@ -535,6 +564,25 @@ class MangaDetailsController : BaseController,
|
|||||||
?: Color.BLACK
|
?: Color.BLACK
|
||||||
menu.findItem(R.id.action_download).icon?.mutate()?.setTint(iconPrimary)
|
menu.findItem(R.id.action_download).icon?.mutate()?.setTint(iconPrimary)
|
||||||
editItem.icon?.mutate()?.setTint(iconPrimary)
|
editItem.icon?.mutate()?.setTint(iconPrimary)
|
||||||
|
|
||||||
|
val searchItem = menu.findItem(R.id.action_search)
|
||||||
|
val searchView = searchItem.actionView as SearchView
|
||||||
|
searchView.queryHint = resources?.getString(R.string.chapter_search_hint)
|
||||||
|
searchItem.icon?.mutate()?.setTint(iconPrimary)
|
||||||
|
searchItem.collapseActionView()
|
||||||
|
if (query.isNotEmpty()) {
|
||||||
|
searchItem.expandActionView()
|
||||||
|
searchView.setQuery(query, true)
|
||||||
|
searchView.clearFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnQueryTextChangeListener(searchView) {
|
||||||
|
query = it ?: ""
|
||||||
|
adapter?.setFilter(query)
|
||||||
|
adapter?.performFilter()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
@ -1033,6 +1081,12 @@ class MangaDetailsController : BaseController,
|
|||||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||||
actionMode = null
|
actionMode = null
|
||||||
setStatusBarAndToolbar()
|
setStatusBarAndToolbar()
|
||||||
|
if (startingDLChapterPos != null) {
|
||||||
|
val item = adapter?.getItem(startingDLChapterPos!!) as? ChapterItem
|
||||||
|
(recycler.findViewHolderForAdapterPosition(startingDLChapterPos!!) as? ChapterMatHolder)?.notifyStatus(
|
||||||
|
item?.status ?: Download.NOT_DOWNLOADED, false, 0
|
||||||
|
)
|
||||||
|
}
|
||||||
startingDLChapterPos = null
|
startingDLChapterPos = null
|
||||||
adapter?.mode = SelectableAdapter.Mode.IDLE
|
adapter?.mode = SelectableAdapter.Mode.IDLE
|
||||||
adapter?.clearSelection()
|
adapter?.clearSelection()
|
||||||
@ -1096,6 +1150,17 @@ class MangaDetailsController : BaseController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onActionStateChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
|
||||||
|
swipe_refresh.isEnabled = actionState != ItemTouchHelper.ACTION_STATE_SWIPE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override fun zoomImageFromThumb(thumbView: View) {
|
override fun zoomImageFromThumb(thumbView: View) {
|
||||||
// If there's an animation in progress, cancel it immediately and proceed with this one.
|
// If there's an animation in progress, cancel it immediately and proceed with this one.
|
||||||
currentAnimator?.cancel()
|
currentAnimator?.cancel()
|
||||||
|
@ -22,6 +22,10 @@ class MangaHeaderItem(val manga: Manga, private val startExpanded: Boolean) :
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isSwipeable(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHeaderHolder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHeaderHolder {
|
||||||
return MangaHeaderHolder(view, adapter as ChaptersAdapter, startExpanded)
|
return MangaHeaderHolder(view, adapter as ChaptersAdapter, startExpanded)
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,10 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) :
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isSwipeable(): Boolean {
|
||||||
|
return !isLocked
|
||||||
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): ChapterMatHolder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): ChapterMatHolder {
|
||||||
return ChapterMatHolder(view, adapter as ChaptersAdapter)
|
return ChapterMatHolder(view, adapter as ChaptersAdapter)
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.ui.manga.chapter
|
package eu.kanade.tachiyomi.ui.manga.chapter
|
||||||
|
|
||||||
|
import android.animation.Animator
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
@ -10,9 +12,9 @@ import eu.kanade.tachiyomi.source.LocalSource
|
|||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.visibleIf
|
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||||
import java.util.Date
|
|
||||||
import kotlinx.android.synthetic.main.chapters_mat_item.*
|
import kotlinx.android.synthetic.main.chapters_mat_item.*
|
||||||
import kotlinx.android.synthetic.main.download_button.*
|
import kotlinx.android.synthetic.main.download_button.*
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
class ChapterMatHolder(
|
class ChapterMatHolder(
|
||||||
private val view: View,
|
private val view: View,
|
||||||
@ -74,32 +76,93 @@ class ChapterMatHolder(
|
|||||||
if (isLocked) download_button.gone()
|
if (isLocked) download_button.gone()
|
||||||
|
|
||||||
// Set correct text color
|
// Set correct text color
|
||||||
chapter_title.setTextColor(if (chapter.read && !isLocked)
|
chapter_title.setTextColor(
|
||||||
adapter.readColor else adapter.unreadColor)
|
if (chapter.read && !isLocked) adapter.readColor else adapter.unreadColor
|
||||||
|
)
|
||||||
if (chapter.bookmark && !isLocked) chapter_title.setTextColor(adapter.bookmarkedColor)
|
if (chapter.bookmark && !isLocked) chapter_title.setTextColor(adapter.bookmarkedColor)
|
||||||
|
|
||||||
val statuses = mutableListOf<String>()
|
val statuses = mutableListOf<String>()
|
||||||
|
|
||||||
if (chapter.date_upload > 0) {
|
if (chapter.date_upload > 0) {
|
||||||
statuses.add(DateUtils.getRelativeTimeSpanString(chapter.date_upload,
|
statuses.add(
|
||||||
Date().time, DateUtils.HOUR_IN_MILLIS).toString())
|
DateUtils.getRelativeTimeSpanString(
|
||||||
|
chapter.date_upload, Date().time, DateUtils.HOUR_IN_MILLIS
|
||||||
|
).toString()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chapter.read && chapter.last_page_read > 0 && chapter.pages_left > 0 && !isLocked) {
|
if (!chapter.read && chapter.last_page_read > 0 && chapter.pages_left > 0 && !isLocked) {
|
||||||
statuses.add(itemView.resources.getQuantityString(R.plurals.pages_left, chapter
|
statuses.add(
|
||||||
.pages_left, chapter.pages_left))
|
itemView.resources.getQuantityString(
|
||||||
|
R.plurals.pages_left, chapter.pages_left, chapter.pages_left
|
||||||
|
)
|
||||||
|
)
|
||||||
} else if (!chapter.read && chapter.last_page_read > 0 && !isLocked) {
|
} else if (!chapter.read && chapter.last_page_read > 0 && !isLocked) {
|
||||||
statuses.add(itemView.context.getString(R.string.chapter_progress, chapter
|
statuses.add(
|
||||||
.last_page_read + 1))
|
itemView.context.getString(
|
||||||
|
R.string.chapter_progress, chapter.last_page_read + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chapter.scanlator.isNullOrBlank()) {
|
if (!chapter.scanlator.isNullOrBlank()) {
|
||||||
statuses.add(chapter.scanlator!!)
|
statuses.add(chapter.scanlator!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
read.context, if (item.read) R.drawable.eye_off
|
||||||
|
else R.drawable.eye
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bookmark.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
read.context, if (item.bookmark) R.drawable.star_off
|
||||||
|
else R.drawable.star
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
chapter_scanlator.setTextColor(if (chapter.read) adapter.readColor else adapter.unreadColor)
|
chapter_scanlator.setTextColor(if (chapter.read) adapter.readColor else adapter.unreadColor)
|
||||||
chapter_scanlator.text = statuses.joinToString(" • ")
|
chapter_scanlator.text = statuses.joinToString(" • ")
|
||||||
notifyStatus(item.status, item.isLocked, item.progress)
|
notifyStatus(
|
||||||
|
if (adapter.isSelected(adapterPosition)) Download.CHECKED else item.status,
|
||||||
|
item.isLocked,
|
||||||
|
item.progress
|
||||||
|
)
|
||||||
|
resetFrontView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFrontView(): View {
|
||||||
|
return front_view
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRearRightView(): View {
|
||||||
|
return right_view
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRearLeftView(): View {
|
||||||
|
return left_view
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetFrontView() {
|
||||||
|
if (front_view.translationX == 0f) return
|
||||||
|
itemView.post {
|
||||||
|
adapter.recyclerView.itemAnimator?.changeDuration = 0
|
||||||
|
val anim = front_view.animate().translationX(0f).setDuration(250)
|
||||||
|
anim.setListener(object : Animator.AnimatorListener {
|
||||||
|
override fun onAnimationEnd(animation: Animator?) {
|
||||||
|
adapter.itemTouchHelper.startSwipe(this@ChapterMatHolder)
|
||||||
|
adapter.notifyItemChanged(adapterPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAnimationCancel(animation: Animator?) {}
|
||||||
|
|
||||||
|
override fun onAnimationRepeat(animation: Animator?) {}
|
||||||
|
|
||||||
|
override fun onAnimationStart(animation: Animator?) {}
|
||||||
|
})
|
||||||
|
anim.start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyStatus(status: Int, locked: Boolean, progress: Int) = with(download_button) {
|
fun notifyStatus(status: Int, locked: Boolean, progress: Int) = with(download_button) {
|
||||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga.chapter
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -37,7 +38,7 @@ class ChaptersAdapter(
|
|||||||
|
|
||||||
fun setChapters(items: List<ChapterItem>?) {
|
fun setChapters(items: List<ChapterItem>?) {
|
||||||
this.items = items ?: emptyList()
|
this.items = items ?: emptyList()
|
||||||
super.updateDataSet(items)
|
performFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indexOf(item: ChapterItem): Int {
|
fun indexOf(item: ChapterItem): Int {
|
||||||
@ -49,6 +50,24 @@ class ChaptersAdapter(
|
|||||||
SecureActivityDelegate.promptLockIfNeeded(activity)
|
SecureActivityDelegate.promptLockIfNeeded(activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun performFilter() {
|
||||||
|
val s = getFilter(String::class.java)
|
||||||
|
if (s.isNullOrBlank()) {
|
||||||
|
updateDataSet(items)
|
||||||
|
} else {
|
||||||
|
updateDataSet(items.filter { it.name.contains(s, true) ||
|
||||||
|
it.scanlator?.contains(s, true) == true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemSwiped(position: Int, direction: Int) {
|
||||||
|
super.onItemSwiped(position, direction)
|
||||||
|
when (direction) {
|
||||||
|
ItemTouchHelper.RIGHT -> controller.bookmarkChapter(position)
|
||||||
|
ItemTouchHelper.LEFT -> controller.toggleReadChapter(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface MangaHeaderInterface {
|
interface MangaHeaderInterface {
|
||||||
fun coverColor(): Int?
|
fun coverColor(): Int?
|
||||||
fun mangaPresenter(): MangaDetailsPresenter
|
fun mangaPresenter(): MangaDetailsPresenter
|
||||||
|
@ -36,6 +36,8 @@ class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
|
|||||||
track_title.text = track.title
|
track_title.text = track.title
|
||||||
with(track_chapters) {
|
with(track_chapters) {
|
||||||
text = when {
|
text = when {
|
||||||
|
track.total_chapters > 0 && track.last_chapter_read == track.total_chapters ->
|
||||||
|
context.getString(R.string.all_chapters_read)
|
||||||
track.total_chapters > 0 -> context.getString(
|
track.total_chapters > 0 -> context.getString(
|
||||||
R.string.chapter_x_of_y, track.last_chapter_read, track.total_chapters
|
R.string.chapter_x_of_y, track.last_chapter_read, track.total_chapters
|
||||||
)
|
)
|
||||||
|
@ -36,7 +36,7 @@ class SettingsMainController : SettingsController() {
|
|||||||
onClick { navigateTo(SettingsLibraryController()) }
|
onClick { navigateTo(SettingsLibraryController()) }
|
||||||
}
|
}
|
||||||
preference {
|
preference {
|
||||||
iconRes = R.drawable.ic_chrome_reader_mode_black_24dp
|
iconRes = R.drawable.ic_read_24dp
|
||||||
iconTint = tintColor
|
iconTint = tintColor
|
||||||
titleRes = R.string.pref_category_reader
|
titleRes = R.string.pref_category_reader
|
||||||
onClick { navigateTo(SettingsReaderController()) }
|
onClick { navigateTo(SettingsReaderController()) }
|
||||||
|
@ -14,6 +14,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
@ -310,6 +311,10 @@ fun Controller.setOnQueryTextChangeListener(
|
|||||||
|
|
||||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||||
if (router.backstack.lastOrNull()?.controller() == this@setOnQueryTextChangeListener) {
|
if (router.backstack.lastOrNull()?.controller() == this@setOnQueryTextChangeListener) {
|
||||||
|
val imm =
|
||||||
|
activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
||||||
|
?: return f(query)
|
||||||
|
imm.hideSoftInputFromWindow(searchView.windowToken, 0)
|
||||||
return f(query)
|
return f(query)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -320,6 +325,7 @@ fun Controller.setOnQueryTextChangeListener(
|
|||||||
fun Controller.scrollViewWith(
|
fun Controller.scrollViewWith(
|
||||||
recycler: RecyclerView,
|
recycler: RecyclerView,
|
||||||
padBottom: Boolean = false,
|
padBottom: Boolean = false,
|
||||||
|
customPadding: Boolean = false,
|
||||||
swipeRefreshLayout: SwipeRefreshLayout? = null,
|
swipeRefreshLayout: SwipeRefreshLayout? = null,
|
||||||
afterInsets: ((WindowInsets) -> Unit)? = null
|
afterInsets: ((WindowInsets) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
@ -331,7 +337,7 @@ fun Controller.scrollViewWith(
|
|||||||
array.recycle()
|
array.recycle()
|
||||||
recycler.doOnApplyWindowInsets { view, insets, _ ->
|
recycler.doOnApplyWindowInsets { view, insets, _ ->
|
||||||
val headerHeight = insets.systemWindowInsetTop + appBarHeight
|
val headerHeight = insets.systemWindowInsetTop + appBarHeight
|
||||||
view.updatePaddingRelative(
|
if (!customPadding) view.updatePaddingRelative(
|
||||||
top = headerHeight,
|
top = headerHeight,
|
||||||
bottom = if (padBottom) insets.systemWindowInsetBottom else view.paddingBottom
|
bottom = if (padBottom) insets.systemWindowInsetBottom else view.paddingBottom
|
||||||
)
|
)
|
||||||
@ -365,8 +371,10 @@ fun Controller.scrollViewWith(
|
|||||||
android.R.integer.config_shortAnimTime
|
android.R.integer.config_shortAnimTime
|
||||||
) ?: 0
|
) ?: 0
|
||||||
val closerToTop = abs(activity!!.appbar.y) - halfWay > 0
|
val closerToTop = abs(activity!!.appbar.y) - halfWay > 0
|
||||||
val atTop =
|
val atTop = (!customPadding &&
|
||||||
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() < 2
|
(recycler.layoutManager as LinearLayoutManager)
|
||||||
|
.findFirstVisibleItemPosition() < 2) ||
|
||||||
|
!recycler.canScrollVertically(-1)
|
||||||
activity!!.appbar.animate().y(
|
activity!!.appbar.animate().y(
|
||||||
if (closerToTop && !atTop) (-activity!!.appbar.height.toFloat())
|
if (closerToTop && !atTop) (-activity!!.appbar.height.toFloat())
|
||||||
else 0f
|
else 0f
|
||||||
|
8
app/src/main/res/drawable/eye.xml
Normal file
8
app/src/main/res/drawable/eye.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/eye.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#000" android:pathData="M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z" />
|
||||||
|
</vector>
|
8
app/src/main/res/drawable/eye_off.xml
Normal file
8
app/src/main/res/drawable/eye_off.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/eye_off.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#000" android:pathData="M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z" />
|
||||||
|
</vector>
|
8
app/src/main/res/drawable/star.xml
Normal file
8
app/src/main/res/drawable/star.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/star.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#000" android:pathData="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z" />
|
||||||
|
</vector>
|
8
app/src/main/res/drawable/star_off.xml
Normal file
8
app/src/main/res/drawable/star_off.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/star_off.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#000" android:pathData="M2,5.27L3.28,4L20,20.72L18.73,22L17.05,20.31L12,17.27L5.82,21L7.45,13.97L2,9.24L5.66,8.93L2,5.27M12,2L14.81,8.62L22,9.24L16.54,13.97L16.77,14.95L9.56,7.74L12,2Z" />
|
||||||
|
</vector>
|
@ -1,48 +1,103 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout 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"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/chapter_layout"
|
android:id="@+id/chapter_layout"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?attr/selectable_list_drawable">
|
android:background="?android:attr/colorBackground">
|
||||||
|
|
||||||
<TextView
|
<FrameLayout
|
||||||
android:id="@+id/chapter_title"
|
android:id="@+id/right_view"
|
||||||
style="@style/TextAppearance.MaterialComponents.Body2"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:visibility="gone"
|
||||||
android:layout_marginStart="16dp"
|
android:background="@color/material_green_800"
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="2"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/chapter_scanlator"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/download_button"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:text="Chapter 123 - The Real One" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/chapter_scanlator"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Caption"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/download_button"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/chapter_title"
|
|
||||||
tools:text="3 days ago • On page 45 • Scanlator" />
|
|
||||||
|
|
||||||
<include
|
|
||||||
layout="@layout/download_button"
|
|
||||||
android:layout_width="50dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/read"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:tint="@color/md_white_1000"
|
||||||
|
android:layout_gravity="end|center"
|
||||||
|
android:layout_marginEnd="21dp"
|
||||||
|
android:src="@drawable/ic_read_24dp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/left_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:background="@color/colorAccent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/bookmark"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="start|center"
|
||||||
|
android:layout_marginStart="21dp"
|
||||||
|
android:tint="@color/md_white_1000"
|
||||||
|
android:src="@drawable/ic_bookmark_white_24dp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/front_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:background="?attr/selectable_list_drawable"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/chapter_title"
|
||||||
|
style="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/chapter_scanlator"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/download_button"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Chapter 123 - The Real One" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/chapter_scanlator"
|
||||||
|
style="@style/TextAppearance.MaterialComponents.Caption"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/download_button"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/chapter_title"
|
||||||
|
tools:text="3 days ago • On page 45 • Scanlator" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/download_button"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -3,10 +3,11 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_edit"
|
android:id="@+id/action_search"
|
||||||
android:icon="@drawable/ic_edit_white_24dp"
|
android:icon="@drawable/ic_search_white_24dp"
|
||||||
android:title="@string/action_edit"
|
android:title="@string/action_search"
|
||||||
app:showAsAction="ifRoom" />
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
|
app:showAsAction="collapseActionView|ifRoom" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_download"
|
android:id="@+id/action_download"
|
||||||
@ -44,6 +45,12 @@
|
|||||||
android:title="@string/action_mark_all_as_unread"
|
android:title="@string/action_mark_all_as_unread"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_edit"
|
||||||
|
android:icon="@drawable/ic_edit_white_24dp"
|
||||||
|
android:title="@string/action_edit"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_add_to_home_screen"
|
android:id="@+id/action_add_to_home_screen"
|
||||||
android:title="@string/action_add_to_home_screen"
|
android:title="@string/action_add_to_home_screen"
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.Splash" parent="Theme.Tachiyomi">
|
<style name="Theme.Splash" parent="Theme.Tachiyomi">
|
||||||
|
<item name="android:windowBackground">@drawable/splash_background</item>
|
||||||
|
<item name="android:statusBarColor">@color/splashBackground</item>
|
||||||
|
<item name="android:navigationBarColor">@color/splashBackground</item>
|
||||||
<item name="android:windowLightStatusBar">false</item>
|
<item name="android:windowLightStatusBar">false</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
@ -183,7 +183,7 @@
|
|||||||
<item quantity="many">Po %1$s minutach</item>
|
<item quantity="many">Po %1$s minutach</item>
|
||||||
<item quantity="other">Po %1$s minutach</item>
|
<item quantity="other">Po %1$s minutach</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="search_hint">Szukaj tytułu, tagów, źródła…</string>
|
<string name="library_search_hint">Szukaj tytułu, tagów, źródła…</string>
|
||||||
<string name="pref_refresh_covers_too">Automatycznie odśwież okładki</string>
|
<string name="pref_refresh_covers_too">Automatycznie odśwież okładki</string>
|
||||||
<string name="pref_refresh_covers_too_summary">Odśwież okładki w bibliotece podczas odświeżania biblioteki (nadpisuje lokalne okładki)</string>
|
<string name="pref_refresh_covers_too_summary">Odśwież okładki w bibliotece podczas odświeżania biblioteki (nadpisuje lokalne okładki)</string>
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@
|
|||||||
|
|
||||||
<string name="score">Оценка</string>
|
<string name="score">Оценка</string>
|
||||||
|
|
||||||
<string name="search_hint">Название, теги, источник</string>
|
<string name="library_search_hint">Название, теги, источник</string>
|
||||||
<string name="search_parameter">Параметр поиска (например: language:english)</string>
|
<string name="search_parameter">Параметр поиска (например: language:english)</string>
|
||||||
|
|
||||||
<string name="second_to_last">Предпоследняя</string>
|
<string name="second_to_last">Предпоследняя</string>
|
||||||
|
@ -244,7 +244,7 @@
|
|||||||
<item quantity="one">After %1$s minute</item>
|
<item quantity="one">After %1$s minute</item>
|
||||||
<item quantity="other">After %1$s minutes</item>
|
<item quantity="other">After %1$s minutes</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="search_hint">Search title, tags, source</string>
|
<string name="library_search_hint">Search title, tags, source</string>
|
||||||
<string name="pref_refresh_covers_too">Automatically refresh covers</string>
|
<string name="pref_refresh_covers_too">Automatically refresh covers</string>
|
||||||
<string name="pref_refresh_covers_too_summary">Refresh covers in library as well
|
<string name="pref_refresh_covers_too_summary">Refresh covers in library as well
|
||||||
when updating library (overwrites local covers)</string>
|
when updating library (overwrites local covers)</string>
|
||||||
@ -531,6 +531,7 @@
|
|||||||
<string name="remove_from_library">Remove from library</string>
|
<string name="remove_from_library">Remove from library</string>
|
||||||
<string name="select_start_chapter">Select starting chapter</string>
|
<string name="select_start_chapter">Select starting chapter</string>
|
||||||
<string name="select_end_chapter">Select ending chapter</string>
|
<string name="select_end_chapter">Select ending chapter</string>
|
||||||
|
<string name="chapter_search_hint">Search chapters</string>
|
||||||
|
|
||||||
<!-- Manga chapters fragment -->
|
<!-- Manga chapters fragment -->
|
||||||
<string name="start_reading">Start reading</string>
|
<string name="start_reading">Start reading</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user