增加一个新的紧凑列表布局
This commit is contained in:
@@ -36,6 +36,7 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
|
||||
val isGrid = bookshelfLayout == 1
|
||||
val isGridCompact = bookshelfLayout == 2
|
||||
val isGridCover = bookshelfLayout == 3
|
||||
val isListCompact = bookshelfLayout == 4
|
||||
|
||||
val columnCount = requireContext().bookshelfLayoutGrid.takeIf { it > 0 } ?: 1
|
||||
|
||||
@@ -76,13 +77,17 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
|
||||
swShowBookshelfFastScroller.isChecked = AppConfig.showBookshelfFastScroller
|
||||
|
||||
chipList.isChecked = isList
|
||||
chipListCompact.isChecked = isListCompact
|
||||
chipGrid.isChecked = isGrid
|
||||
chipGridCompact.isChecked = isGridCompact
|
||||
chipGridCover.isChecked = isGridCover
|
||||
sliderText.isVisible = isGrid || isGridCompact || isGridCover
|
||||
sliderGridCount.isVisible = isGrid || isGridCompact || isGridCover
|
||||
|
||||
val showSlider = isGrid || isGridCompact || isGridCover
|
||||
sliderText.isVisible = showSlider
|
||||
sliderGridCount.isVisible = showSlider
|
||||
sliderGridCount.value = columnCount.toFloat()
|
||||
|
||||
|
||||
when (AppConfig.bookshelfSortOrder) {
|
||||
0 -> binding.chipGroupOrder.check(binding.chipAsc.id)
|
||||
1 -> binding.chipGroupOrder.check(binding.chipDesc.id)
|
||||
@@ -90,10 +95,11 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
|
||||
|
||||
chipGroupLayout.setOnCheckedStateChangeListener { _, checkedIds ->
|
||||
val checkedId = checkedIds.firstOrNull()
|
||||
val showSlider =
|
||||
checkedId == R.id.chip_grid || checkedId == R.id.chip_grid_compact || checkedId == R.id.chip_grid_cover
|
||||
sliderText.isVisible = showSlider
|
||||
val showSlider = checkedId == R.id.chip_grid ||
|
||||
checkedId == R.id.chip_grid_compact ||
|
||||
checkedId == R.id.chip_grid_cover
|
||||
TransitionManager.beginDelayedTransition(root)
|
||||
sliderText.isVisible = showSlider
|
||||
sliderGridCount.isVisible = showSlider
|
||||
}
|
||||
|
||||
@@ -136,6 +142,7 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
|
||||
chipGrid.isChecked -> 1
|
||||
chipGridCompact.isChecked -> 2
|
||||
chipGridCover.isChecked -> 3
|
||||
chipListCompact.isChecked -> 4
|
||||
else -> 0
|
||||
}
|
||||
|
||||
@@ -149,7 +156,7 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
|
||||
AppConfig.bookshelfLayoutGridPortrait = selectedColumn
|
||||
}
|
||||
|
||||
if (newLayout == 0) {
|
||||
if (newLayout == 0 || newLayout == 4) {
|
||||
activityViewModel.booksGridRecycledViewPool.clear()
|
||||
} else {
|
||||
activityViewModel.booksListRecycledViewPool.clear()
|
||||
|
||||
@@ -39,6 +39,7 @@ import io.legato.kazusa.ui.main.bookshelf.books.styleDefalut.BooksAdapterGrid
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleDefalut.BooksAdapterGridCompact
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleDefalut.BooksAdapterGridCover
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleDefalut.BooksAdapterList
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleDefalut.BooksAdapterListCompact
|
||||
import io.legato.kazusa.utils.bookshelfLayoutGrid
|
||||
import io.legato.kazusa.utils.bookshelfLayoutMode
|
||||
import io.legato.kazusa.utils.cnCompare
|
||||
@@ -92,9 +93,13 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
|
||||
BooksAdapterGridCompact(requireContext(), this)
|
||||
}
|
||||
|
||||
else -> {
|
||||
3 -> {
|
||||
BooksAdapterGridCover(requireContext(), this)
|
||||
}
|
||||
|
||||
else -> {
|
||||
BooksAdapterListCompact(requireContext(), this, this, viewLifecycleOwner.lifecycle)
|
||||
}
|
||||
}
|
||||
}
|
||||
private var booksFlowJob: Job? = null
|
||||
@@ -127,7 +132,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
|
||||
binding.refreshLayout.isRefreshing = false
|
||||
activityViewModel.upToc(booksAdapter.getItems())
|
||||
}
|
||||
if (bookshelfLayoutMode == 0) {
|
||||
if (bookshelfLayoutMode == 0 ||bookshelfLayoutMode == 4) {
|
||||
binding.rvBookshelf.layoutManager = LinearLayoutManager(context)
|
||||
binding.rvBookshelf.setRecycledViewPool(activityViewModel.booksListRecycledViewPool)
|
||||
} else {
|
||||
@@ -232,7 +237,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
|
||||
|
||||
private fun startLastUpdateTimeJob() {
|
||||
upLastUpdateTimeJob?.cancel()
|
||||
if (!AppConfig.showLastUpdateTime || bookshelfLayoutMode != 0) {
|
||||
if (!AppConfig.showLastUpdateTime || bookshelfLayoutMode != 0 ||bookshelfLayoutMode != 4) {
|
||||
return
|
||||
}
|
||||
upLastUpdateTimeJob = lifecycleScope.launch {
|
||||
|
||||
@@ -36,6 +36,7 @@ import io.legato.kazusa.ui.main.bookshelf.books.styleFold.BooksAdapterGrid
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleFold.BooksAdapterGridCompact
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleFold.BooksAdapterGridCover
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleFold.BooksAdapterList
|
||||
import io.legato.kazusa.ui.main.bookshelf.books.styleFold.BooksAdapterListCompact
|
||||
import io.legato.kazusa.utils.bookshelfLayoutGrid
|
||||
import io.legato.kazusa.utils.bookshelfLayoutMode
|
||||
import io.legato.kazusa.utils.cnCompare
|
||||
@@ -85,9 +86,13 @@ class BookshelfFragment2() : BaseBookshelfFragment(R.layout.fragment_bookshelf2)
|
||||
BooksAdapterGridCompact(requireContext(), this)
|
||||
}
|
||||
|
||||
else -> {
|
||||
3 -> {
|
||||
BooksAdapterGridCover(requireContext(), this)
|
||||
}
|
||||
|
||||
else -> {
|
||||
BooksAdapterListCompact(requireContext(), this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +116,7 @@ class BookshelfFragment2() : BaseBookshelfFragment(R.layout.fragment_bookshelf2)
|
||||
binding.refreshLayout.isRefreshing = false
|
||||
activityViewModel.upToc(books)
|
||||
}
|
||||
if (bookshelfLayoutMode == 0) {
|
||||
if (bookshelfLayoutMode == 0 || bookshelfLayoutMode == 4) {
|
||||
binding.rvBookshelf.layoutManager = LinearLayoutManager(context)
|
||||
} else {
|
||||
binding.rvBookshelf.layoutManager = GridLayoutManager(context, bookshelfLayoutGrid)
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package io.legato.kazusa.ui.main.bookshelf.books.styleDefalut
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.adapter.ItemViewHolder
|
||||
import io.legato.kazusa.data.entities.Book
|
||||
import io.legato.kazusa.databinding.ItemBookshelfListCompactBinding
|
||||
import io.legato.kazusa.help.book.isLocal
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
import io.legato.kazusa.utils.toTimeAgo
|
||||
import splitties.views.onLongClick
|
||||
|
||||
class BooksAdapterListCompact(
|
||||
context: Context,
|
||||
private val fragment: Fragment,
|
||||
private val callBack: CallBack,
|
||||
private val lifecycle: Lifecycle
|
||||
) : BaseBooksAdapter<ItemBookshelfListCompactBinding>(context) {
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemBookshelfListCompactBinding {
|
||||
return ItemBookshelfListCompactBinding.inflate(inflater, parent, false)
|
||||
}
|
||||
|
||||
override fun convert(
|
||||
holder: ItemViewHolder,
|
||||
binding: ItemBookshelfListCompactBinding,
|
||||
item: Book,
|
||||
payloads: MutableList<Any>
|
||||
) = binding.run {
|
||||
binding.cdCover.transitionName = "book_${item.bookUrl}"
|
||||
if (payloads.isEmpty()) {
|
||||
tvName.text = item.name
|
||||
tvAuthor.text =
|
||||
context.getString(
|
||||
R.string.author_read,
|
||||
item.author,
|
||||
(item.totalChapterNum - item.durChapterIndex).coerceAtLeast(0)
|
||||
)
|
||||
tvLast.text = item.latestChapterTitle
|
||||
ivCover.load(item.getDisplayCover(), item.name, item.author, false, item.origin)
|
||||
upRefresh(binding, item)
|
||||
upLastUpdateTime(binding, item)
|
||||
} else {
|
||||
for (i in payloads.indices) {
|
||||
val bundle = payloads[i] as Bundle
|
||||
bundle.keySet().forEach {
|
||||
when (it) {
|
||||
"name" -> tvName.text = item.name
|
||||
"author" -> tvAuthor.text = item.author
|
||||
"last" -> tvLast.text = item.latestChapterTitle
|
||||
"cover" -> ivCover.load(
|
||||
item.getDisplayCover(),
|
||||
item.name,
|
||||
item.author,
|
||||
false,
|
||||
item.origin,
|
||||
fragment,
|
||||
lifecycle
|
||||
)
|
||||
|
||||
"refresh" -> upRefresh(binding, item)
|
||||
"lastUpdateTime" -> upLastUpdateTime(binding, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun upRefresh(binding: ItemBookshelfListCompactBinding, item: Book) {
|
||||
if (!item.isLocal && callBack.isUpdate(item.bookUrl)) {
|
||||
binding.tvUnread.isVisible = false
|
||||
binding.rlLoading.isVisible = true
|
||||
} else {
|
||||
binding.rlLoading.isVisible = false
|
||||
if (AppConfig.showUnread) {
|
||||
//binding.tvUnread.setHighlight(item.lastCheckCount > 0)
|
||||
binding.tvUnread.isVisible = true
|
||||
binding.tvUnread.text = item.getUnreadChapterNum().toString()
|
||||
} else {
|
||||
binding.tvUnread.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun upLastUpdateTime(binding: ItemBookshelfListCompactBinding, item: Book) {
|
||||
if (AppConfig.showLastUpdateTime && !item.isLocal) {
|
||||
val time = item.latestChapterTime.toTimeAgo()
|
||||
if (binding.tvLastUpdateTime.text != time) {
|
||||
binding.tvLastUpdateTime.text = time
|
||||
}
|
||||
} else {
|
||||
binding.tvLastUpdateTime.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemBookshelfListCompactBinding) {
|
||||
holder.itemView.apply {
|
||||
binding.cvContent.setOnClickListener {
|
||||
getItem(holder.layoutPosition)?.let {
|
||||
callBack.open(it, binding.cdCover)
|
||||
}
|
||||
}
|
||||
|
||||
binding.cvContent.onLongClick {
|
||||
getItem(holder.layoutPosition)?.let {
|
||||
callBack.openBookInfo(it, binding.cdCover)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -65,9 +65,9 @@ class BooksAdapterList(context: Context, callBack: CallBack) :
|
||||
tvLast.text = item.latestChapterTitle
|
||||
ivCover.load(item.getDisplayCover(), item.name, item.author, false, item.origin)
|
||||
cdUnread.visible()
|
||||
ivAuthor.visible()
|
||||
ivLast.visible()
|
||||
ivRead.visible()
|
||||
// ivAuthor.visible()
|
||||
// ivLast.visible()
|
||||
// ivRead.visible()
|
||||
upRefresh(this, item)
|
||||
upLastUpdateTime(binding, item)
|
||||
}
|
||||
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
package io.legato.kazusa.ui.main.bookshelf.books.styleFold
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.data.entities.Book
|
||||
import io.legato.kazusa.data.entities.BookGroup
|
||||
import io.legato.kazusa.databinding.ItemBookshelfListCompactBinding
|
||||
import io.legato.kazusa.databinding.ItemBookshelfListCompactGroupBinding
|
||||
import io.legato.kazusa.help.book.isLocal
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
import io.legato.kazusa.utils.gone
|
||||
import io.legato.kazusa.utils.toTimeAgo
|
||||
import io.legato.kazusa.utils.visible
|
||||
import splitties.views.onLongClick
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
class BooksAdapterListCompact(context: Context, callBack: CallBack) :
|
||||
BaseBooksAdapter<RecyclerView.ViewHolder>(context, callBack) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return when (viewType) {
|
||||
1 -> GroupViewHolder(ItemBookshelfListCompactGroupBinding.inflate(inflater, parent, false))
|
||||
else -> BookViewHolder(ItemBookshelfListCompactBinding.inflate(inflater, parent, false))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(
|
||||
holder: RecyclerView.ViewHolder,
|
||||
position: Int,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
when (holder) {
|
||||
is BookViewHolder -> (getItem(position) as? Book)?.let {
|
||||
holder.registerListener(it)
|
||||
holder.onBind(it, payloads)
|
||||
}
|
||||
|
||||
is GroupViewHolder -> (getItem(position) as? BookGroup)?.let {
|
||||
holder.registerListener(it)
|
||||
holder.onBind(it, payloads)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBooksForGroup(group: BookGroup): List<Book> {
|
||||
return if (group.groupId == -1L) {
|
||||
allBooks.take(4)
|
||||
} else {
|
||||
allBooks.filter { (it.group and group.groupId) != 0L }.take(4)
|
||||
}
|
||||
}
|
||||
|
||||
inner class BookViewHolder(val binding: ItemBookshelfListCompactBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun onBind(item: Book) = binding.run {
|
||||
tvName.text = item.name
|
||||
tvAuthor.text = item.author
|
||||
tvLast.text = item.latestChapterTitle
|
||||
ivCover.load(item.getDisplayCover(), item.name, item.author, false, item.origin)
|
||||
cdUnread.visible()
|
||||
// ivAuthor.visible()
|
||||
// ivLast.visible()
|
||||
// ivRead.visible()
|
||||
upRefresh(this, item)
|
||||
upLastUpdateTime(binding, item)
|
||||
}
|
||||
|
||||
fun onBind(item: Book, payloads: MutableList<Any>) = binding.run {
|
||||
if (payloads.isEmpty()) {
|
||||
onBind(item)
|
||||
} else {
|
||||
for (i in payloads.indices) {
|
||||
val bundle = payloads[i] as Bundle
|
||||
bundle.keySet().forEach {
|
||||
when (it) {
|
||||
"name" -> tvName.text = item.name
|
||||
"author" -> tvAuthor.text = item.author
|
||||
"last" -> tvLast.text = item.latestChapterTitle
|
||||
"cover" -> ivCover.load(
|
||||
item.getDisplayCover(),
|
||||
item.name,
|
||||
item.author,
|
||||
false,
|
||||
item.origin
|
||||
)
|
||||
|
||||
"refresh" -> upRefresh(this, item)
|
||||
"lastUpdateTime" -> upLastUpdateTime(binding, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun upLastUpdateTime(binding: ItemBookshelfListCompactBinding, item: Book) {
|
||||
if (AppConfig.showLastUpdateTime && !item.isLocal) {
|
||||
val time = item.latestChapterTime.toTimeAgo()
|
||||
if (binding.tvLastUpdateTime.text != time) {
|
||||
binding.tvLastUpdateTime.text = time
|
||||
}
|
||||
} else {
|
||||
binding.tvLastUpdateTime.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
fun registerListener(item: Any) {
|
||||
binding.cvContent.setOnClickListener {
|
||||
callBack.onItemClick(item, binding.cdCover)
|
||||
}
|
||||
binding.cvContent.onLongClick {
|
||||
callBack.onItemLongClick(item, binding.cdCover)
|
||||
}
|
||||
}
|
||||
|
||||
private fun upRefresh(binding: ItemBookshelfListCompactBinding, item: Book) {
|
||||
if (!item.isLocal && callBack.isUpdate(item.bookUrl)) {
|
||||
binding.tvUnread.isVisible = false
|
||||
binding.rlLoading.isVisible = true
|
||||
} else {
|
||||
binding.rlLoading.isVisible = false
|
||||
if (AppConfig.showUnread) {
|
||||
//binding.tvUnread.setHighlight(item.lastCheckCount > 0)
|
||||
binding.tvUnread.isVisible = true
|
||||
binding.tvUnread.text = item.getUnreadChapterNum().toString()
|
||||
} else {
|
||||
binding.tvUnread.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inner class GroupViewHolder(val binding: ItemBookshelfListCompactGroupBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun onBind(item: BookGroup) = binding.run {
|
||||
tvName.text = item.groupName
|
||||
loadGroupCover(item)
|
||||
cdUnread.gone()
|
||||
}
|
||||
|
||||
|
||||
fun onBind(item: BookGroup, payloads: MutableList<Any>) = binding.run {
|
||||
if (payloads.isEmpty()) {
|
||||
onBind(item)
|
||||
} else {
|
||||
for (i in payloads.indices) {
|
||||
val bundle = payloads[i] as Bundle
|
||||
bundle.keySet().forEach {
|
||||
when (it) {
|
||||
"groupName" -> tvName.text = item.groupName
|
||||
"cover" -> loadGroupCover(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun registerListener(item: Any) {
|
||||
binding.cvContent.setOnClickListener {
|
||||
callBack.onItemClick(item, binding.ivCover)
|
||||
}
|
||||
binding.cvContent.onLongClick {
|
||||
callBack.onItemLongClick(item, binding.ivCover)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadGroupCover(item: BookGroup) = binding.run {
|
||||
|
||||
binding.ivCover.setImageDrawable(
|
||||
ContextCompat.getDrawable(binding.root.context, R.drawable.bg_surface_variant)
|
||||
)
|
||||
binding.ivCover1.setImageDrawable(null)
|
||||
binding.ivCover2.setImageDrawable(null)
|
||||
if (!item.cover.isNullOrEmpty()) {
|
||||
ivCover.load(item.cover)
|
||||
} else {
|
||||
|
||||
val books = getBooksForGroup(item)
|
||||
|
||||
if (books.size > 0) binding.ivCover1.load(books[0].getDisplayCover())
|
||||
if (books.size > 1) binding.ivCover2.load(books[1].getDisplayCover())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -111,6 +111,13 @@
|
||||
android:checkable="true"
|
||||
android:text="@string/list" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_list_compact"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkable="true"
|
||||
android:text="@string/compact_list" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_grid"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="4dp"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -85,122 +84,100 @@
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:text="@string/book_name"
|
||||
style="@style/ChapterNameText"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
app:layout_constraintStart_toEndOf="@+id/cd_cover"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/cd_cover" />
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/cd_cover"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_author"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:contentDescription="@string/author"
|
||||
android:scrollbars="none"
|
||||
android:src="@drawable/ic_author"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_name"/>
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/book_name"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
app:layout_constraintStart_toEndOf="@+id/cd_cover"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/cd_cover" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_author"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:maxLines="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/author"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="RtlSymmetry,TextContrastCheck"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_author"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iv_author"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_author" />
|
||||
<TextView
|
||||
android:id="@+id/tv_author"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:maxLines="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/author"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="RtlSymmetry,TextContrastCheck"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_author"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iv_author"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_author" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_last_update_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:maxLines="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/text"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tv_author"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_author" />
|
||||
<TextView
|
||||
android:id="@+id/tv_read"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/read_dur_progress"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
app:layout_constraintBottom_toTopOf="@id/iv_read"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_read"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_read"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_read"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:contentDescription="@string/read_dur_progress"
|
||||
android:scrollbars="none"
|
||||
android:src="@drawable/ic_history"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_author" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_read"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_weight="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/read_dur_progress"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
app:layout_constraintBottom_toTopOf="@id/iv_read"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_read"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_read"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
<TextView
|
||||
android:id="@+id/tv_last_update_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:maxLines="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/text"
|
||||
android:textSize="13sp"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
app:layout_constraintBottom_toTopOf="@id/iv_last"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_last"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_last" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_last"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:contentDescription="@string/lasted_show"
|
||||
android:scrollbars="none"
|
||||
android:src="@drawable/ic_book_last"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_read" />
|
||||
<TextView
|
||||
android:id="@+id/tv_last"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/lasted_show"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
app:layout_constraintBottom_toTopOf="@id/iv_last"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_last_update_time"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_last"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_last"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_weight="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/lasted_show"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
app:layout_constraintBottom_toTopOf="@id/iv_last"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_last"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_last"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
<?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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cv_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cd_cover"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="6dp"
|
||||
app:strokeWidth="0dp"
|
||||
android:layout_margin="8dp"
|
||||
android:transitionName="img_cover"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_cover"
|
||||
android:layout_width="55dp"
|
||||
android:layout_height="77dp">
|
||||
|
||||
<io.legato.kazusa.ui.widget.image.CoverImageView
|
||||
android:id="@+id/iv_cover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/image_cover_default"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:ignore="ImageContrastCheck" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/rl_loading"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="4dp"
|
||||
android:layout_marginHorizontal="6dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="invisible"
|
||||
android:layout_gravity="top"
|
||||
app:layout_constraintTop_toTopOf="@id/iv_cover"
|
||||
app:layout_constraintStart_toStartOf="@id/iv_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/iv_cover" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cd_unread"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:visibility="visible"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:strokeWidth="0dp"
|
||||
app:cardBackgroundColor="?attr/colorSecondaryVariant"
|
||||
app:layout_constraintTop_toTopOf="@id/iv_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/iv_cover">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_unread"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/colorSurface"
|
||||
android:textSize="9sp"
|
||||
android:padding="3dp"
|
||||
android:textStyle="bold"
|
||||
android:includeFontPadding="false"
|
||||
tools:text="5"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/cd_cover"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/book_name"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
app:layout_constraintStart_toEndOf="@+id/cd_cover"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/cd_cover" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_author"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:maxLines="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/author_read"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="RtlSymmetry,TextContrastCheck"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_author"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iv_author"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_author" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_last_update_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:maxLines="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/text"
|
||||
android:textSize="13sp"
|
||||
android:textColor="?attr/colorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@id/iv_last"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_last"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_last" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_last"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:text="@string/lasted_show"
|
||||
android:textSize="13sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
app:layout_constraintBottom_toTopOf="@id/iv_last"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_last_update_time"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_last"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@@ -0,0 +1,120 @@
|
||||
<?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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cv_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_cover"
|
||||
android:layout_width="55dp"
|
||||
android:layout_height="77dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginVertical="8dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
<!-- 书封面 -->
|
||||
<io.legato.kazusa.ui.widget.image.CoverImageView
|
||||
android:id="@+id/iv_cover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="?attr/colorSurfaceVariant"
|
||||
android:transitionName="img_cover"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:ignore="ImageContrastCheck" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/rl_loading"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="4dp"
|
||||
android:layout_marginHorizontal="6dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="invisible"
|
||||
android:layout_gravity="top"
|
||||
app:layout_constraintTop_toTopOf="@id/iv_cover"
|
||||
app:layout_constraintStart_toStartOf="@id/iv_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/iv_cover" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cd_unread"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:visibility="visible"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:strokeWidth="0dp"
|
||||
app:cardBackgroundColor="?attr/colorSecondaryVariant"
|
||||
app:layout_constraintTop_toTopOf="@id/iv_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/iv_cover">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_unread"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/colorSurface"
|
||||
android:textSize="10sp"
|
||||
android:padding="4dp"
|
||||
android:textStyle="bold"
|
||||
android:includeFontPadding="false"
|
||||
tools:text="5"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<io.legato.kazusa.ui.widget.image.CoverImageView
|
||||
android:id="@+id/iv_cover1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<io.legato.kazusa.ui.widget.image.CoverImageView
|
||||
android:id="@+id/iv_cover2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:text="@string/book_name"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
app:layout_constraintStart_toEndOf="@+id/cl_cover"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/cl_cover"
|
||||
app:layout_constraintBottom_toBottomOf="@id/cl_cover"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@@ -4,7 +4,6 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="4dp"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -136,7 +135,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:text="@string/book_name"
|
||||
android:textSize="18sp"
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:paddingEnd="@dimen/fastscroll_scrollbar_padding_end"
|
||||
android:paddingStart="@dimen/fastscroll_scrollbar_padding_start"
|
||||
tools:ignore="ContentDescription"
|
||||
android:src="@drawable/fastscroll_handle" />
|
||||
|
||||
|
||||
@@ -1284,4 +1284,6 @@
|
||||
<string name="use_animation">使用共享元素动画</string>
|
||||
<string name="reduce_stutter">减少进入阅读界面时的卡顿,但加载书籍时间会延长。</string>
|
||||
<string name="delay_book_load">延缓书籍加载</string>
|
||||
<string name="compact_list">紧凑列表</string>
|
||||
<string name="author_read">%s • %d章未读</string>
|
||||
</resources>
|
||||
|
||||
@@ -1285,4 +1285,6 @@
|
||||
<string name="use_animation">Use Shared Element Animation</string>
|
||||
<string name="reduce_stutter">Reduces stutter when entering the reading interface, but increases book loading time.</string>
|
||||
<string name="delay_book_load">Delay Book Loading</string>
|
||||
<string name="compact_list">Compact List</string>
|
||||
<string name="author_read">%s • %dNot read</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user