Made chapters swipeable to change read/bookmark status

This commit is contained in:
Jay 2020-03-22 04:10:27 -04:00
parent 87e86f81cf
commit b331e12fde
23 changed files with 352 additions and 90 deletions

View File

@ -40,7 +40,7 @@ class Download(val source: HttpSource, val manga: Manga, val chapter: Chapter) {
}
companion object {
const val CHECKED = -1
const val NOT_DOWNLOADED = 0
const val QUEUE = 1
const val DOWNLOADING = 2

View File

@ -29,6 +29,10 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
R.drawable.filled_circle)?.mutate()
private val borderCircle = ContextCompat.getDrawable(context,
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 iconAnimation: ObjectAnimator? = null
@ -38,7 +42,17 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
download_icon.alpha = 1f
isAnimating = false
}
download_icon.setImageDrawable(if (state == Download.CHECKED)
checkDrawable else downloadDrawable)
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_border.visible()
download_progress.gone()

View File

@ -441,7 +441,7 @@ open class LibraryController(
val searchItem = menu.findItem(R.id.action_search)
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()
if (query.isNotEmpty()) {

View File

@ -59,10 +59,8 @@ import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.ui.setting.SettingsMainController
import eu.kanade.tachiyomi.util.system.getResourceColor
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.updatePadding
import eu.kanade.tachiyomi.util.view.visible
import java.util.Date
import java.util.concurrent.TimeUnit
import kotlin.math.abs
@ -197,19 +195,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
container.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
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)

View File

@ -19,7 +19,6 @@ import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
@ -31,12 +30,14 @@ import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.ColorUtils
import androidx.core.graphics.drawable.IconCompat
import androidx.palette.graphics.Palette
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
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.view.doOnApplyWindowInsets
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.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
@ -114,6 +116,7 @@ class MangaDetailsController : BaseController,
FlexibleAdapter.OnItemLongClickListener,
ActionMode.Callback,
ChaptersAdapter.MangaHeaderInterface,
FlexibleAdapter.OnItemMoveListener,
ChangeMangaCategoriesDialog.Listener {
constructor(
@ -159,6 +162,11 @@ class MangaDetailsController : BaseController,
private var editMangaDialog: EditMangaDialog? = null
var refreshTracker: Int? = null
/**
* Library search query.
*/
private var query = ""
/**
* Adapter containing a list of chapters.
*/
@ -190,6 +198,7 @@ class MangaDetailsController : BaseController,
adapter = ChaptersAdapter(this, view.context)
recycler.adapter = adapter
adapter?.isSwipeEnabled = true
recycler.layoutManager = LinearLayoutManager(view.context)
recycler.addItemDecoration(
DividerItemDecoration(
@ -369,6 +378,13 @@ class MangaDetailsController : BaseController,
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(
if (forThis) android.R.attr.textColorPrimary
else R.attr.actionBarTintColor
@ -418,6 +434,8 @@ class MangaDetailsController : BaseController,
adapter?.addSelection(position)
(recycler.findViewHolderForAdapterPosition(position) as? BaseFlexibleViewHolder)
?.toggleActivation()
(recycler.findViewHolderForAdapterPosition(position) as? ChapterMatHolder)
?.notifyStatus(Download.CHECKED, false, 0)
startingDLChapterPos = position
actionMode?.invalidate()
} else {
@ -446,24 +464,24 @@ class MangaDetailsController : BaseController,
val adapter = adapter ?: return
val item = (adapter.getItem(position) as? ChapterItem) ?: 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
popup.menuInflater.inflate(R.menu.chapters_mat_single, popup.menu)
// Hide bookmark if bookmark
popup.menu.findItem(R.id.action_bookmark).isVisible = !item.bookmark
popup.menu.findItem(R.id.action_remove_bookmark).isVisible = item.bookmark
popup.menu.findItem(R.id.action_bookmark).isVisible = false // !item.bookmark
popup.menu.findItem(R.id.action_remove_bookmark).isVisible = false // item.bookmark
// 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
}
// }
// 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
}
// }
// Set a listener so we are notified if a menu item is clicked
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) {
presenter.bookmarkChapters(chapters, bookmarked)
}
private fun markAsRead(chapters: List<ChapterItem>) {
presenter.markChaptersRead(chapters, true)
private fun markAsRead(chapters: List<ChapterItem>, refresh: Boolean = true) {
presenter.markChaptersRead(chapters, read = true)
if (presenter.preferences.removeAfterMarkedAsRead()) {
presenter.deleteChapters(chapters)
}
}
private fun markAsUnread(chapters: List<ChapterItem>) {
presenter.markChaptersRead(chapters, false)
private fun markAsUnread(chapters: List<ChapterItem>, refresh: Boolean = true) {
presenter.markChaptersRead(chapters, read = false)
}
private fun openChapter(chapter: Chapter) {
@ -535,6 +564,25 @@ class MangaDetailsController : BaseController,
?: Color.BLACK
menu.findItem(R.id.action_download).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 {
@ -1033,6 +1081,12 @@ class MangaDetailsController : BaseController,
override fun onDestroyActionMode(mode: ActionMode?) {
actionMode = null
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
adapter?.mode = SelectableAdapter.Mode.IDLE
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) {
// If there's an animation in progress, cancel it immediately and proceed with this one.
currentAnimator?.cancel()

View File

@ -22,6 +22,10 @@ class MangaHeaderItem(val manga: Manga, private val startExpanded: Boolean) :
return false
}
override fun isSwipeable(): Boolean {
return false
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaHeaderHolder {
return MangaHeaderHolder(view, adapter as ChaptersAdapter, startExpanded)
}

View File

@ -41,6 +41,10 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) :
return true
}
override fun isSwipeable(): Boolean {
return !isLocked
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): ChapterMatHolder {
return ChapterMatHolder(view, adapter as ChaptersAdapter)
}

View File

@ -1,8 +1,10 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.animation.Animator
import android.text.format.DateUtils
import android.view.View
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
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.util.view.gone
import eu.kanade.tachiyomi.util.view.visibleIf
import java.util.Date
import kotlinx.android.synthetic.main.chapters_mat_item.*
import kotlinx.android.synthetic.main.download_button.*
import java.util.Date
class ChapterMatHolder(
private val view: View,
@ -74,32 +76,93 @@ class ChapterMatHolder(
if (isLocked) download_button.gone()
// Set correct text color
chapter_title.setTextColor(if (chapter.read && !isLocked)
adapter.readColor else adapter.unreadColor)
chapter_title.setTextColor(
if (chapter.read && !isLocked) adapter.readColor else adapter.unreadColor
)
if (chapter.bookmark && !isLocked) chapter_title.setTextColor(adapter.bookmarkedColor)
val statuses = mutableListOf<String>()
if (chapter.date_upload > 0) {
statuses.add(DateUtils.getRelativeTimeSpanString(chapter.date_upload,
Date().time, DateUtils.HOUR_IN_MILLIS).toString())
statuses.add(
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) {
statuses.add(itemView.resources.getQuantityString(R.plurals.pages_left, chapter
.pages_left, chapter.pages_left))
statuses.add(
itemView.resources.getQuantityString(
R.plurals.pages_left, chapter.pages_left, chapter.pages_left
)
)
} else if (!chapter.read && chapter.last_page_read > 0 && !isLocked) {
statuses.add(itemView.context.getString(R.string.chapter_progress, chapter
.last_page_read + 1))
statuses.add(
itemView.context.getString(
R.string.chapter_progress, chapter.last_page_read + 1
)
)
}
if (!chapter.scanlator.isNullOrBlank()) {
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.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) {

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga.chapter
import android.content.Context
import android.view.View
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.ItemTouchHelper
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R
@ -37,7 +38,7 @@ class ChaptersAdapter(
fun setChapters(items: List<ChapterItem>?) {
this.items = items ?: emptyList()
super.updateDataSet(items)
performFilter()
}
fun indexOf(item: ChapterItem): Int {
@ -49,6 +50,24 @@ class ChaptersAdapter(
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 {
fun coverColor(): Int?
fun mangaPresenter(): MangaDetailsPresenter

View File

@ -36,6 +36,8 @@ class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
track_title.text = track.title
with(track_chapters) {
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(
R.string.chapter_x_of_y, track.last_chapter_read, track.total_chapters
)

View File

@ -36,7 +36,7 @@ class SettingsMainController : SettingsController() {
onClick { navigateTo(SettingsLibraryController()) }
}
preference {
iconRes = R.drawable.ic_chrome_reader_mode_black_24dp
iconRes = R.drawable.ic_read_24dp
iconTint = tintColor
titleRes = R.string.pref_category_reader
onClick { navigateTo(SettingsReaderController()) }

View File

@ -14,6 +14,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.WindowInsets
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageView
@ -310,6 +311,10 @@ fun Controller.setOnQueryTextChangeListener(
override fun onQueryTextSubmit(query: String?): Boolean {
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 true
@ -320,6 +325,7 @@ fun Controller.setOnQueryTextChangeListener(
fun Controller.scrollViewWith(
recycler: RecyclerView,
padBottom: Boolean = false,
customPadding: Boolean = false,
swipeRefreshLayout: SwipeRefreshLayout? = null,
afterInsets: ((WindowInsets) -> Unit)? = null
) {
@ -331,7 +337,7 @@ fun Controller.scrollViewWith(
array.recycle()
recycler.doOnApplyWindowInsets { view, insets, _ ->
val headerHeight = insets.systemWindowInsetTop + appBarHeight
view.updatePaddingRelative(
if (!customPadding) view.updatePaddingRelative(
top = headerHeight,
bottom = if (padBottom) insets.systemWindowInsetBottom else view.paddingBottom
)
@ -365,8 +371,10 @@ fun Controller.scrollViewWith(
android.R.integer.config_shortAnimTime
) ?: 0
val closerToTop = abs(activity!!.appbar.y) - halfWay > 0
val atTop =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() < 2
val atTop = (!customPadding &&
(recycler.layoutManager as LinearLayoutManager)
.findFirstVisibleItemPosition() < 2) ||
!recycler.canScrollVertically(-1)
activity!!.appbar.animate().y(
if (closerToTop && !atTop) (-activity!!.appbar.height.toFloat())
else 0f

View 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>

View 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>

View 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>

View 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>

View File

@ -1,48 +1,103 @@
<?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:tools="http://schemas.android.com/tools"
android:id="@+id/chapter_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?attr/selectable_list_drawable">
android:background="?android:attr/colorBackground">
<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"
<FrameLayout
android:id="@+id/right_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="@color/material_green_800"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
app:layout_constraintStart_toStartOf="parent"
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>

View File

@ -3,10 +3,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_edit"
android:icon="@drawable/ic_edit_white_24dp"
android:title="@string/action_edit"
app:showAsAction="ifRoom" />
android:id="@+id/action_search"
android:icon="@drawable/ic_search_white_24dp"
android:title="@string/action_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
<item
android:id="@+id/action_download"
@ -44,6 +45,12 @@
android:title="@string/action_mark_all_as_unread"
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
android:id="@+id/action_add_to_home_screen"
android:title="@string/action_add_to_home_screen"

View File

@ -41,6 +41,9 @@
</style>
<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>
</style>
</resources>

View File

@ -183,7 +183,7 @@
<item quantity="many">Po %1$s minutach</item>
<item quantity="other">Po %1$s minutach</item>
</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_summary">Odśwież okładki w bibliotece podczas odświeżania biblioteki (nadpisuje lokalne okładki)</string>

View File

@ -520,7 +520,7 @@
<string name="score">Оценка</string>
<string name="search_hint">Название, теги, источник</string>
<string name="library_search_hint">Название, теги, источник</string>
<string name="search_parameter">Параметр поиска (например: language:english)</string>
<string name="second_to_last">Предпоследняя</string>

View File

@ -244,7 +244,7 @@
<item quantity="one">After %1$s minute</item>
<item quantity="other">After %1$s minutes</item>
</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_summary">Refresh covers in library as well
when updating library (overwrites local covers)</string>
@ -531,6 +531,7 @@
<string name="remove_from_library">Remove from library</string>
<string name="select_start_chapter">Select starting chapter</string>
<string name="select_end_chapter">Select ending chapter</string>
<string name="chapter_search_hint">Search chapters</string>
<!-- Manga chapters fragment -->
<string name="start_reading">Start reading</string>