feat: unify reader chrome state management
- Add RDEPUBReaderUIState struct for centralized UI state model - Refactor RDEPUBReaderChromeCoordinator with makeUIState() and applyUIState() - Remove direct UI updates from RDEPUBReaderAnnotationCoordinator - Consolidate updateBookmarkChrome() into updateReaderChrome() - Update RDEPUBReaderContext, Runtime, and LocationCoordinator - Add reader problem fix development checklist documentation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
d15187b730
commit
ed390da147
+3
-12
@@ -38,9 +38,7 @@ final class RDEPUBReaderAnnotationCoordinator {
|
||||
controller.readerView.isShowToolView == false {
|
||||
controller.readerView.tapCenter()
|
||||
}
|
||||
controller.bottomToolView.setAddHighlightEnabled(
|
||||
controller.configuration.allowsHighlights && controller.currentSelection != nil
|
||||
)
|
||||
controller.updateReaderChrome()
|
||||
controller.delegate?.epubReader(controller, didChangeSelection: controller.currentSelection)
|
||||
}
|
||||
|
||||
@@ -321,13 +319,6 @@ final class RDEPUBReaderAnnotationCoordinator {
|
||||
return controller.restoreReadingLocation(bookmark.location, animated: animated)
|
||||
}
|
||||
|
||||
/// 同步顶部书签按钮和底部书签列表按钮的 UI 状态。
|
||||
func updateBookmarkChrome() {
|
||||
guard let controller else { return }
|
||||
controller.topToolView.setBookmarkSelected(currentBookmark() != nil)
|
||||
controller.bottomToolView.setBookmarksEnabled(!controller.activeBookmarks.isEmpty)
|
||||
}
|
||||
|
||||
/// 弹出书签管理器,支持查看、跳转和删除书签。
|
||||
func presentBookmarksManager() {
|
||||
guard let controller else { return }
|
||||
@@ -468,10 +459,10 @@ final class RDEPUBReaderAnnotationCoordinator {
|
||||
guard let currentBookIdentifier = controller.currentBookIdentifier else { return }
|
||||
controller.persistence?.saveBookmarks(controller.activeBookmarks, for: currentBookIdentifier)
|
||||
controller.delegate?.epubReader(controller, didUpdateBookmarks: controller.activeBookmarks)
|
||||
updateBookmarkChrome()
|
||||
controller.updateReaderChrome()
|
||||
}
|
||||
|
||||
private func currentBookmark() -> RDEPUBBookmark? {
|
||||
func currentBookmark() -> RDEPUBBookmark? {
|
||||
guard let controller else { return nil }
|
||||
guard let location = scopedBookmarkLocation(controller.currentVisibleLocation()) else {
|
||||
return nil
|
||||
|
||||
@@ -57,6 +57,29 @@ final class RDEPUBReaderChromeCoordinator {
|
||||
|
||||
/// 同步更新顶部和底部工具栏的主题、标题、按钮可用性等状态。
|
||||
func updateReaderChrome() {
|
||||
guard let controller else { return }
|
||||
let uiState = makeUIState()
|
||||
applyUIState(uiState)
|
||||
updateSearchBar()
|
||||
}
|
||||
|
||||
/// 构建当前 UI 状态快照
|
||||
func makeUIState() -> RDEPUBReaderUIState {
|
||||
guard let controller else { return .empty }
|
||||
return RDEPUBReaderUIState(
|
||||
canToggleBookmark: controller.currentBookIdentifier != nil,
|
||||
hasBookmarkAtCurrentLocation: hasBookmarkAtCurrentLocation(),
|
||||
canShowBookmarks: !controller.activeBookmarks.isEmpty,
|
||||
canAddHighlight: controller.configuration.allowsHighlights && controller.currentSelection != nil,
|
||||
canShowHighlights: controller.configuration.allowsHighlights && !controller.activeHighlights.isEmpty,
|
||||
showsTableOfContents: controller.configuration.showsTableOfContents,
|
||||
allowsHighlights: controller.configuration.allowsHighlights,
|
||||
showsSettingsPanel: controller.configuration.showsSettingsPanel
|
||||
)
|
||||
}
|
||||
|
||||
/// 将 UI 状态应用到顶部和底部工具栏
|
||||
func applyUIState(_ state: RDEPUBReaderUIState) {
|
||||
guard let controller else { return }
|
||||
controller.topToolView.apply(theme: controller.configuration.theme)
|
||||
controller.topToolView.setTitle(
|
||||
@@ -64,22 +87,23 @@ final class RDEPUBReaderChromeCoordinator {
|
||||
?? controller.parser?.metadata.title
|
||||
?? controller.epubURL.deletingPathExtension().lastPathComponent
|
||||
)
|
||||
controller.topToolView.setBookmarkEnabled(controller.currentBookIdentifier != nil)
|
||||
controller.topToolView.setBookmarkEnabled(state.canToggleBookmark)
|
||||
controller.topToolView.setBookmarkSelected(state.hasBookmarkAtCurrentLocation)
|
||||
controller.bottomToolView.apply(theme: controller.configuration.theme)
|
||||
controller.bottomToolView.updateVisibility(
|
||||
showsTableOfContents: controller.configuration.showsTableOfContents,
|
||||
allowsHighlights: controller.configuration.allowsHighlights,
|
||||
showsSettingsPanel: controller.configuration.showsSettingsPanel
|
||||
showsTableOfContents: state.showsTableOfContents,
|
||||
allowsHighlights: state.allowsHighlights,
|
||||
showsSettingsPanel: state.showsSettingsPanel
|
||||
)
|
||||
controller.bottomToolView.setBookmarksEnabled(!controller.activeBookmarks.isEmpty)
|
||||
controller.bottomToolView.setAddHighlightEnabled(
|
||||
controller.configuration.allowsHighlights && controller.currentSelection != nil
|
||||
)
|
||||
controller.bottomToolView.setHighlightsEnabled(
|
||||
controller.configuration.allowsHighlights && !controller.activeHighlights.isEmpty
|
||||
)
|
||||
controller.updateBookmarkChrome()
|
||||
updateSearchBar()
|
||||
controller.bottomToolView.setBookmarksEnabled(state.canShowBookmarks)
|
||||
controller.bottomToolView.setAddHighlightEnabled(state.canAddHighlight)
|
||||
controller.bottomToolView.setHighlightsEnabled(state.canShowHighlights)
|
||||
}
|
||||
|
||||
/// 判断当前位置是否有书签
|
||||
private func hasBookmarkAtCurrentLocation() -> Bool {
|
||||
guard let controller else { return false }
|
||||
return context.runtime?.annotationCoordinator.currentBookmark() != nil
|
||||
}
|
||||
|
||||
/// 弹出阅读设置面板(字号、字体、行距、分栏、主题、亮度等)。
|
||||
|
||||
@@ -369,9 +369,4 @@ final class RDEPUBReaderContext {
|
||||
func applyReaderViewConfiguration() {
|
||||
controller?.applyReaderViewConfiguration()
|
||||
}
|
||||
|
||||
/// 同步书签按钮的 UI 状态。
|
||||
func updateBookmarkChrome() {
|
||||
controller?.updateBookmarkChrome()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,6 @@ final class RDEPUBReaderLocationCoordinator {
|
||||
controller.persistence?.saveLocation(location, for: currentBookIdentifier)
|
||||
controller.delegate?.epubReader(controller, didUpdateLocation: location)
|
||||
controller.delegate?.epubReader(controller, didUpdateCurrentTableOfContentsItem: controller.currentTableOfContentsItem)
|
||||
controller.updateBookmarkChrome()
|
||||
controller.updateReaderChrome()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,10 +193,6 @@ final class RDEPUBReaderRuntime {
|
||||
annotationCoordinator.go(toBookmarkID: id, animated: animated)
|
||||
}
|
||||
|
||||
func updateBookmarkChrome() {
|
||||
annotationCoordinator.updateBookmarkChrome()
|
||||
}
|
||||
|
||||
func presentBookmarksManager() {
|
||||
annotationCoordinator.presentBookmarksManager()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import Foundation
|
||||
|
||||
/// 阅读器 UI 状态模型:统一管理顶部/底部工具栏按钮的可用性和显示状态。
|
||||
///
|
||||
/// 解决问题:之前书签、高亮等按钮的状态分散在 ChromeCoordinator 和 AnnotationCoordinator 中,
|
||||
/// 导致状态更新入口不一致,容易出现不同步的情况。
|
||||
struct RDEPUBReaderUIState {
|
||||
/// 顶部书签按钮是否可用(当前有书籍标识时可用)
|
||||
let canToggleBookmark: Bool
|
||||
/// 顶部书签按钮是否选中(当前位置已加书签时选中)
|
||||
let hasBookmarkAtCurrentLocation: Bool
|
||||
/// 底部书签列表按钮是否可用(有书签数据时可用)
|
||||
let canShowBookmarks: Bool
|
||||
/// 底部新建标注按钮是否可用(有选中文本时可用)
|
||||
let canAddHighlight: Bool
|
||||
/// 底部高亮列表按钮是否可用(有高亮数据时可用)
|
||||
let canShowHighlights: Bool
|
||||
/// 是否显示目录按钮
|
||||
let showsTableOfContents: Bool
|
||||
/// 是否显示高亮相关按钮(新建标注和高亮列表)
|
||||
let allowsHighlights: Bool
|
||||
/// 是否显示设置按钮
|
||||
let showsSettingsPanel: Bool
|
||||
}
|
||||
|
||||
extension RDEPUBReaderUIState {
|
||||
/// 默认的空状态
|
||||
static let empty = RDEPUBReaderUIState(
|
||||
canToggleBookmark: false,
|
||||
hasBookmarkAtCurrentLocation: false,
|
||||
canShowBookmarks: false,
|
||||
canAddHighlight: false,
|
||||
canShowHighlights: false,
|
||||
showsTableOfContents: true,
|
||||
allowsHighlights: true,
|
||||
showsSettingsPanel: true
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user