From a73e3db0fc46c8c64ff30f10c2330739ec15f043 Mon Sep 17 00:00:00 2001 From: HapeLee <1321903405@qq.com> Date: Fri, 24 Oct 2025 01:52:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E8=BF=BD=E8=AF=BB=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E4=B8=8E=E5=8A=9F=E8=83=BD=20#131?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legato/kazusa/data/entities/Book.kt | 11 +- .../legato/kazusa/help/book/BookExtensions.kt | 14 +- .../ui/book/read/BaseReadBookActivity.kt | 71 ++++--- .../res/layout/dialog_simulated_reading.xml | 177 +++++------------- 4 files changed, 114 insertions(+), 159 deletions(-) diff --git a/app/src/main/java/io/legato/kazusa/data/entities/Book.kt b/app/src/main/java/io/legato/kazusa/data/entities/Book.kt index f3bc03b50..f7902aeb8 100644 --- a/app/src/main/java/io/legato/kazusa/data/entities/Book.kt +++ b/app/src/main/java/io/legato/kazusa/data/entities/Book.kt @@ -265,14 +265,19 @@ data class Book( // startDate 的 setter 和 getter fun setStartDate(startDate: LocalDate?) { - config.startDate = startDate + config.startDate = startDate?.toString() } fun getStartDate(): LocalDate? { if (!config.readSimulating || config.startDate == null) { return LocalDate.now() } - return config.startDate + return try { + LocalDate.parse(config.startDate) + } catch (e: Exception) { + println("解析日期失败: ${config.startDate}, 错误: ${e.message}") + LocalDate.now() + } } // startChapter 的 setter 和 getter @@ -400,7 +405,7 @@ data class Book( var ttsEngine: String? = null, var splitLongChapter: Boolean = true, var readSimulating: Boolean = false, - var startDate: LocalDate? = null, + var startDate: String? = null, var startChapter: Int? = null, // 用户设置的起始章节 var dailyChapters: Int = 3, // 用户设置的每日更新章节数 diff --git a/app/src/main/java/io/legato/kazusa/help/book/BookExtensions.kt b/app/src/main/java/io/legato/kazusa/help/book/BookExtensions.kt index c650a6658..f43094538 100644 --- a/app/src/main/java/io/legato/kazusa/help/book/BookExtensions.kt +++ b/app/src/main/java/io/legato/kazusa/help/book/BookExtensions.kt @@ -28,7 +28,7 @@ import io.legato.kazusa.utils.toastOnUi import splitties.init.appCtx import java.io.File import java.time.LocalDate -import java.time.Period.between +import java.time.temporal.ChronoUnit import java.util.concurrent.ConcurrentHashMap import kotlin.math.max import kotlin.math.min @@ -353,7 +353,17 @@ fun Book.getExportFileName( fun Book.simulatedTotalChapterNum(): Int { return if (readSimulating()) { val currentDate = LocalDate.now() - val daysPassed = between(config.startDate, currentDate).days + 1 + val daysPassed = if (config.startDate != null) { + try { + val startDate = LocalDate.parse(config.startDate) + ChronoUnit.DAYS.between(startDate, currentDate).toInt() + 1 + } catch (e: Exception) { + println("解析起始日期失败: ${config.startDate}, 错误: ${e.message}") + 1 // 解析失败时返回默认值1 + } + } else { + 1 // 没有设置起始日期时返回默认值1 + } // 计算当前应该解锁到哪一章 val chaptersToUnlock = max(0, (config.startChapter ?: 0) + (daysPassed * config.dailyChapters)) diff --git a/app/src/main/java/io/legato/kazusa/ui/book/read/BaseReadBookActivity.kt b/app/src/main/java/io/legato/kazusa/ui/book/read/BaseReadBookActivity.kt index 1ba1e1cf5..736a3d2d6 100644 --- a/app/src/main/java/io/legato/kazusa/ui/book/read/BaseReadBookActivity.kt +++ b/app/src/main/java/io/legato/kazusa/ui/book/read/BaseReadBookActivity.kt @@ -1,7 +1,6 @@ package io.legato.kazusa.ui.book.read import android.annotation.SuppressLint -import android.app.DatePickerDialog import android.content.pm.ActivityInfo import android.os.Build import android.os.Bundle @@ -10,10 +9,12 @@ import android.view.View import android.view.WindowInsets import android.view.WindowManager import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowInsetsCompat import androidx.core.view.doOnDetach import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams +import com.google.android.material.datepicker.MaterialDatePicker import io.legato.kazusa.R import io.legato.kazusa.base.VMBaseActivity import io.legato.kazusa.constant.AppConst.charsets @@ -27,7 +28,6 @@ import io.legato.kazusa.help.config.LocalConfig import io.legato.kazusa.help.config.ReadBookConfig import io.legato.kazusa.lib.dialogs.alert import io.legato.kazusa.lib.dialogs.selector -//import io.legado.app.lib.theme.bottomBackground import io.legato.kazusa.model.CacheBook import io.legato.kazusa.model.ReadBook import io.legato.kazusa.ui.book.read.config.BgTextConfigDialog @@ -47,7 +47,9 @@ import io.legato.kazusa.utils.setOnApplyWindowInsetsListenerCompat import io.legato.kazusa.utils.showDialogFragment import io.legato.kazusa.utils.themeColor import io.legato.kazusa.utils.viewbindingdelegate.viewBinding +import java.time.Instant import java.time.LocalDate +import java.time.ZoneId import java.time.format.DateTimeFormatter /** @@ -288,46 +290,57 @@ abstract class BaseReadBookActivity : fun showSimulatedReading() { val book = ReadBook.book ?: return val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + val alertBinding = DialogSimulatedReadingBinding.inflate(layoutInflater).apply { srEnabled.isChecked = book.getReadSimulating() editStart.setText(book.getStartChapter().toString()) editNum.setText(book.getDailyChapters().toString()) - startDate.setText(book.getStartDate()?.format(dateFormatter)) - startDate.isFocusable = false // 设置为false,不允许获得焦点 - startDate.isCursorVisible = false // 不显示光标 + + // 安全地设置初始日期 + val safeDate = book.getStartDate() ?: LocalDate.now() + startDate.setText(safeDate.format(dateFormatter)) + + // 让 EditText 不可直接编辑,只能通过选择器 + startDate.isFocusable = false + startDate.isCursorVisible = false + startDate.setOnClickListener { - // 获取当前日期 - val localStartDate = LocalDate.parse(startDate.text) - // 创建 DatePickerDialog - val datePickerDialog = DatePickerDialog( - root.context, - { _, yy, mm, dayOfMonth -> - // 使用Java 8的日期和时间API来格式化日期 - val date = LocalDate.of(yy, mm + 1, dayOfMonth) // Java 8的LocalDate,月份从1开始 - val formattedDate = date.format(dateFormatter) - startDate.setText(formattedDate) - }, localStartDate.year, - localStartDate.monthValue - 1, - localStartDate.dayOfMonth - ) - datePickerDialog.show() + val currentDate = try { + LocalDate.parse(startDate.text.toString(), dateFormatter) + } catch (e: Exception) { + LocalDate.now() + } + val initialSelection = currentDate + .atStartOfDay(ZoneId.systemDefault()) + .toInstant() + .toEpochMilli() + val picker = MaterialDatePicker.Builder.datePicker() + .setTitleText("选择开始日期") + .setSelection(initialSelection) + .build() + picker.addOnPositiveButtonClickListener { selection -> + val date = Instant.ofEpochMilli(selection) + .atZone(ZoneId.systemDefault()) + .toLocalDate() + startDate.setText(date.format(dateFormatter)) + } + picker.show((root.context as AppCompatActivity).supportFragmentManager, "md3_date_picker") } } alert(titleResource = R.string.simulated_reading) { customView { alertBinding.root } okButton { alertBinding.run { - val start = editStart.text!!.toString().let { - if (it.isEmpty()) 0 else it.toInt() - } - val num = editNum.text!!.toString().let { - if (it.isEmpty()) book.totalChapterNum else it.toInt() - } + val start = editStart.text.toString().toIntOrNull() ?: 0 + val num = editNum.text.toString().toIntOrNull() ?: book.totalChapterNum val enabled = srEnabled.isChecked - val date = startDate.text!!.toString().let { - if (it.isEmpty()) LocalDate.now() - else LocalDate.parse(it, dateFormatter) + + val date = try { + LocalDate.parse(startDate.text.toString(), dateFormatter) + } catch (e: Exception) { + LocalDate.now() } + book.setStartDate(date) book.setDailyChapters(num) book.setStartChapter(start) diff --git a/app/src/main/res/layout/dialog_simulated_reading.xml b/app/src/main/res/layout/dialog_simulated_reading.xml index 289be39b6..5e1cbd7a3 100644 --- a/app/src/main/res/layout/dialog_simulated_reading.xml +++ b/app/src/main/res/layout/dialog_simulated_reading.xml @@ -1,159 +1,86 @@ - + style="@style/Widget.Material3.TextInputLayout.FilledBox.Dense"> + + - - - - - - - - - - - - - - - + android:layout_height="match_parent" + android:id="@+id/sr_enabled" /> - - - - - - - - - - - + - - - + android:maxLength="5" /> + + + + + + + +