pull/2498/head
Horis 2 years ago
parent 28048d8aa2
commit 8f71d9af26
  1. 1
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  2. 6
      app/src/main/java/io/legado/app/help/config/AppConfig.kt
  3. 5
      app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt
  4. 6
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BaseBooksAdapter.kt
  5. 11
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterList.kt
  6. 21
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt
  7. 39
      app/src/main/java/io/legado/app/utils/TimeUtils.kt
  8. 13
      app/src/main/res/layout/dialog_bookshelf_config.xml
  9. 17
      app/src/main/res/layout/item_bookshelf_list.xml
  10. 1
      app/src/main/res/values-es-rES/strings.xml
  11. 1
      app/src/main/res/values-ja-rJP/strings.xml
  12. 1
      app/src/main/res/values-pt-rBR/strings.xml
  13. 1
      app/src/main/res/values-zh-rHK/strings.xml
  14. 1
      app/src/main/res/values-zh-rTW/strings.xml
  15. 1
      app/src/main/res/values-zh/strings.xml
  16. 1
      app/src/main/res/values/strings.xml

@ -120,6 +120,7 @@ object PreferKey {
const val noAnimScrollPage = "noAnimScrollPage" const val noAnimScrollPage = "noAnimScrollPage"
const val webDavDeviceName = "webDavDeviceName" const val webDavDeviceName = "webDavDeviceName"
const val wakeLock = "wakeLock" const val wakeLock = "wakeLock"
const val showLastUpdateTime = "showLastUpdateTime"
const val cPrimary = "colorPrimary" const val cPrimary = "colorPrimary"
const val cAccent = "colorAccent" const val cAccent = "colorAccent"

@ -82,6 +82,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
appCtx.putPrefBoolean(PreferKey.showUnread, value) appCtx.putPrefBoolean(PreferKey.showUnread, value)
} }
var showLastUpdateTime: Boolean
get() = appCtx.getPrefBoolean(PreferKey.showLastUpdateTime, false)
set(value) {
appCtx.putPrefBoolean(PreferKey.showLastUpdateTime, value)
}
var readBrightness: Int var readBrightness: Int
get() = if (isNightTheme) { get() = if (isNightTheme) {
appCtx.getPrefInt(PreferKey.nightBrightness, 100) appCtx.getPrefInt(PreferKey.nightBrightness, 100)

@ -136,6 +136,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
.apply { .apply {
spGroupStyle.setSelection(AppConfig.bookGroupStyle) spGroupStyle.setSelection(AppConfig.bookGroupStyle)
swShowUnread.isChecked = AppConfig.showUnread swShowUnread.isChecked = AppConfig.showUnread
swShowLastUpdateTime.isChecked = AppConfig.showLastUpdateTime
rgLayout.checkByIndex(bookshelfLayout) rgLayout.checkByIndex(bookshelfLayout)
rgSort.checkByIndex(bookshelfSort) rgSort.checkByIndex(bookshelfSort)
} }
@ -150,6 +151,10 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
AppConfig.showUnread = swShowUnread.isChecked AppConfig.showUnread = swShowUnread.isChecked
postEvent(EventBus.BOOKSHELF_REFRESH, "") postEvent(EventBus.BOOKSHELF_REFRESH, "")
} }
if (AppConfig.showLastUpdateTime != swShowLastUpdateTime.isChecked) {
AppConfig.showLastUpdateTime = swShowLastUpdateTime.isChecked
postEvent(EventBus.BOOKSHELF_REFRESH, "")
}
var changed = false var changed = false
if (bookshelfLayout != rgLayout.getCheckedIndex()) { if (bookshelfLayout != rgLayout.getCheckedIndex()) {
putPrefInt(PreferKey.bookshelfLayout, rgLayout.getCheckedIndex()) putPrefInt(PreferKey.bookshelfLayout, rgLayout.getCheckedIndex())

@ -66,13 +66,17 @@ abstract class BaseBooksAdapter<VB : ViewBinding>(context: Context) :
for (i in 0 until itemCount) { for (i in 0 until itemCount) {
getItem(i)?.let { getItem(i)?.let {
if (it.bookUrl == bookUrl) { if (it.bookUrl == bookUrl) {
notifyItemChanged(i, bundleOf(Pair("refresh", null))) notifyItemChanged(i, bundleOf(Pair("refresh", null), Pair("lastUpdateTime", null)))
return return
} }
} }
} }
} }
fun upLastUpdateTime() {
notifyItemRangeChanged(0, itemCount, bundleOf(Pair("lastUpdateTime", null)))
}
interface CallBack { interface CallBack {
fun open(book: Book) fun open(book: Book)
fun openBookInfo(book: Book) fun openBookInfo(book: Book)

@ -9,6 +9,7 @@ import io.legado.app.databinding.ItemBookshelfListBinding
import io.legado.app.help.book.isLocal import io.legado.app.help.book.isLocal
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import io.legado.app.utils.toTimeAgo
import splitties.views.onLongClick import splitties.views.onLongClick
class BooksAdapterList(context: Context, private val callBack: CallBack) : class BooksAdapterList(context: Context, private val callBack: CallBack) :
@ -32,6 +33,7 @@ class BooksAdapterList(context: Context, private val callBack: CallBack) :
tvLast.text = item.latestChapterTitle tvLast.text = item.latestChapterTitle
ivCover.load(item.getDisplayCover(), item.name, item.author, false, item.origin) ivCover.load(item.getDisplayCover(), item.name, item.author, false, item.origin)
upRefresh(binding, item) upRefresh(binding, item)
upLastUpdateTime(binding, item)
} else { } else {
tvRead.text = item.durChapterTitle tvRead.text = item.durChapterTitle
tvLast.text = item.latestChapterTitle tvLast.text = item.latestChapterTitle
@ -41,6 +43,7 @@ class BooksAdapterList(context: Context, private val callBack: CallBack) :
"author" -> tvAuthor.text = item.author "author" -> tvAuthor.text = item.author
"cover" -> ivCover.load(item.getDisplayCover(), item.name, item.author, false, item.origin) "cover" -> ivCover.load(item.getDisplayCover(), item.name, item.author, false, item.origin)
"refresh" -> upRefresh(binding, item) "refresh" -> upRefresh(binding, item)
"lastUpdateTime" -> upLastUpdateTime(binding, item)
} }
} }
} }
@ -61,6 +64,14 @@ class BooksAdapterList(context: Context, private val callBack: CallBack) :
} }
} }
private fun upLastUpdateTime(binding: ItemBookshelfListBinding, item: Book) {
if (AppConfig.showLastUpdateTime && !item.isLocal) {
binding.tvLastUpdateTime.text = item.latestChapterTime.toTimeAgo()
} else {
binding.tvLastUpdateTime.text = ""
}
}
override fun registerListener(holder: ItemViewHolder, binding: ItemBookshelfListBinding) { override fun registerListener(holder: ItemViewHolder, binding: ItemBookshelfListBinding) {
holder.itemView.apply { holder.itemView.apply {
setOnClickListener { setOnClickListener {

@ -27,14 +27,11 @@ import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.main.MainViewModel import io.legado.app.ui.main.MainViewModel
import io.legado.app.utils.* import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.*
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlin.math.max import kotlin.math.max
/** /**
@ -66,6 +63,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
private var savedInstanceState: Bundle? = null private var savedInstanceState: Bundle? = null
private var position = 0 private var position = 0
private var groupId = -1L private var groupId = -1L
private var upLastUpdateTimeJob : Job? = null
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
this.savedInstanceState = savedInstanceState this.savedInstanceState = savedInstanceState
@ -107,6 +105,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
} }
} }
}) })
startLastUpdateTimeJob()
} }
private fun upRecyclerData() { private fun upRecyclerData() {
@ -153,6 +152,19 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
} }
} }
private fun startLastUpdateTimeJob() {
upLastUpdateTimeJob?.cancel()
if (!AppConfig.showLastUpdateTime) {
return
}
upLastUpdateTimeJob = launch {
while (isActive) {
booksAdapter.upLastUpdateTime()
delay(30 * 1000)
}
}
}
fun getBooks(): List<Book> { fun getBooks(): List<Book> {
return booksAdapter.getItems() return booksAdapter.getItems()
} }
@ -222,6 +234,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
} }
observeEvent<String>(EventBus.BOOKSHELF_REFRESH) { observeEvent<String>(EventBus.BOOKSHELF_REFRESH) {
booksAdapter.notifyDataSetChanged() booksAdapter.notifyDataSetChanged()
startLastUpdateTimeJob()
} }
} }
} }

@ -0,0 +1,39 @@
package io.legado.app.utils
import kotlin.math.abs
fun Long.toTimeAgo(): String {
val curTime = System.currentTimeMillis()
val time = this
val seconds = abs(System.currentTimeMillis() - time) / 1000f
val end = if (time < curTime) "" else ""
val start = when {
seconds < 60 -> "${seconds.toInt()}"
seconds < 3600 -> {
val minutes = seconds / 60f
"${minutes.toInt()}分钟"
}
seconds < 86400 -> {
val hours = seconds / 3600f
"${hours.toInt()}小时"
}
seconds < 604800 -> {
val days = seconds / 86400f
"${days.toInt()}"
}
seconds < 2_628_000 -> {
val weeks = seconds / 604800f
"${weeks.toInt()}"
}
seconds < 31_536_000 -> {
val months = seconds / 2_628_000f
"${months.toInt()}"
}
else -> {
val years = seconds / 31_536_000f
"${years.toInt()}"
}
}
return start + end
}

@ -40,13 +40,22 @@
app:layout_constraintTop_toBottomOf="@+id/ll_group_style" app:layout_constraintTop_toBottomOf="@+id/ll_group_style"
tools:ignore="TouchTargetSizeCheck" /> tools:ignore="TouchTargetSizeCheck" />
<io.legado.app.lib.theme.view.ThemeSwitch
android:id="@+id/sw_show_last_update_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:text="@string/show_last_update_time"
app:layout_constraintTop_toBottomOf="@+id/sw_show_unread"
tools:ignore="TouchTargetSizeCheck" />
<LinearLayout <LinearLayout
android:id="@+id/ll_layout" android:id="@+id/ll_layout"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintRight_toLeftOf="@+id/ll_sort" app:layout_constraintRight_toLeftOf="@+id/ll_sort"
app:layout_constraintTop_toBottomOf="@+id/sw_show_unread" app:layout_constraintTop_toBottomOf="@+id/sw_show_last_update_time"
app:layout_constraintLeft_toLeftOf="parent"> app:layout_constraintLeft_toLeftOf="parent">
<io.legado.app.ui.widget.text.AccentTextView <io.legado.app.ui.widget.text.AccentTextView
@ -101,7 +110,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintLeft_toRightOf="@+id/ll_layout" app:layout_constraintLeft_toRightOf="@+id/ll_layout"
app:layout_constraintTop_toBottomOf="@id/sw_show_unread" app:layout_constraintTop_toBottomOf="@id/sw_show_last_update_time"
app:layout_constraintRight_toRightOf="parent"> app:layout_constraintRight_toRightOf="parent">
<io.legado.app.ui.widget.text.AccentTextView <io.legado.app.ui.widget.text.AccentTextView

@ -98,6 +98,23 @@
android:textSize="13sp" android:textSize="13sp"
app:layout_constraintBottom_toTopOf="@+id/tv_read" app:layout_constraintBottom_toTopOf="@+id/tv_read"
app:layout_constraintLeft_toRightOf="@+id/iv_author" app:layout_constraintLeft_toRightOf="@+id/iv_author"
app:layout_constraintRight_toLeftOf="@id/tv_last_update_time"
app:layout_constraintTop_toBottomOf="@+id/tv_name"
tools:ignore="RtlSymmetry,TextContrastCheck" />
<TextView
android:id="@+id/tv_last_update_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:maxLines="1"
android:paddingEnd="6dp"
android:text=""
android:textColor="@color/tv_text_summary"
android:textSize="13sp"
app:layout_constraintBottom_toTopOf="@+id/tv_read"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="@+id/tv_author"
app:layout_constraintRight_toRightOf="@id/fl_has_new" app:layout_constraintRight_toRightOf="@id/fl_has_new"
app:layout_constraintTop_toBottomOf="@+id/tv_name" app:layout_constraintTop_toBottomOf="@+id/tv_name"
tools:ignore="RtlSymmetry,TextContrastCheck" /> tools:ignore="RtlSymmetry,TextContrastCheck" />

@ -1052,4 +1052,5 @@
<string name="paste_rule">粘贴规则</string> <string name="paste_rule">粘贴规则</string>
<string name="groups_or_source">多分组/书源</string> <string name="groups_or_source">多分组/书源</string>
<string name="replace_state_change">替换(启用/禁用)</string> <string name="replace_state_change">替换(启用/禁用)</string>
<string name="show_last_update_time">显示上次更新时间</string>
</resources> </resources>

@ -1055,4 +1055,5 @@
<string name="paste_rule">粘贴规则</string> <string name="paste_rule">粘贴规则</string>
<string name="groups_or_source">多分组/书源</string> <string name="groups_or_source">多分组/书源</string>
<string name="replace_state_change">替换(启用/禁用)</string> <string name="replace_state_change">替换(启用/禁用)</string>
<string name="show_last_update_time">显示上次更新时间</string>
</resources> </resources>

@ -1055,4 +1055,5 @@
<string name="paste_rule">粘贴规则</string> <string name="paste_rule">粘贴规则</string>
<string name="groups_or_source">多分组/书源</string> <string name="groups_or_source">多分组/书源</string>
<string name="replace_state_change">替换(启用/禁用)</string> <string name="replace_state_change">替换(启用/禁用)</string>
<string name="show_last_update_time">显示上次更新时间</string>
</resources> </resources>

@ -1052,4 +1052,5 @@
<string name="paste_rule">粘贴规则</string> <string name="paste_rule">粘贴规则</string>
<string name="groups_or_source">多分组/书源</string> <string name="groups_or_source">多分组/书源</string>
<string name="replace_state_change">替换(启用/禁用)</string> <string name="replace_state_change">替换(启用/禁用)</string>
<string name="show_last_update_time">显示上次更新时间</string>
</resources> </resources>

@ -1054,4 +1054,5 @@
<string name="paste_rule">粘贴规则</string> <string name="paste_rule">粘贴规则</string>
<string name="groups_or_source">多分组/书源</string> <string name="groups_or_source">多分组/书源</string>
<string name="replace_state_change">替换(启用/禁用)</string> <string name="replace_state_change">替换(启用/禁用)</string>
<string name="show_last_update_time">显示上次更新时间</string>
</resources> </resources>

@ -1054,4 +1054,5 @@
<string name="paste_rule">粘贴规则</string> <string name="paste_rule">粘贴规则</string>
<string name="groups_or_source">多分组/书源</string> <string name="groups_or_source">多分组/书源</string>
<string name="replace_state_change">替换(启用/禁用)</string> <string name="replace_state_change">替换(启用/禁用)</string>
<string name="show_last_update_time">显示上次更新时间</string>
</resources> </resources>

@ -1055,4 +1055,5 @@
<string name="paste_rule">粘贴规则</string> <string name="paste_rule">粘贴规则</string>
<string name="groups_or_source">多分组/书源</string> <string name="groups_or_source">多分组/书源</string>
<string name="replace_state_change">替换(启用/禁用)</string> <string name="replace_state_change">替换(启用/禁用)</string>
<string name="show_last_update_time">显示上次更新时间</string>
</resources> </resources>

Loading…
Cancel
Save