feat: add in-reader search and restructure documentation

- Add RDEPUBReaderSearchBarView with animated show/hide, keyword
  navigation, and match counting integrated into the reader controller
- Restructure docs: replace scattered design docs with consolidated
  BUSINESS_LOGIC.md and UML_CLASS_DIAGRAMS.md; update ARCHITECTURE.md
- Add SearchTests and FanrenParseTimeTest; enhance LargeBookOnDemandTests
- Add scripts/run_ui_regression.sh and summarize_ui_results.py for
  automated UI test execution and reporting

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-06-05 17:34:50 +08:00
co-authored by Claude Opus 4.7
parent d20196ee34
commit 0e7c0577e3
37 changed files with 4941 additions and 7621 deletions
@@ -10,8 +10,11 @@ public final class RDEPUBReaderTopToolView: RDEPUBReaderToolView {
var onBack: (() -> Void)?
///
var onToggleBookmark: (() -> Void)?
///
var onSearch: (() -> Void)?
private let backButton = RDEPUBReaderTintButton(type: .system)
private let searchButton = RDEPUBReaderTintButton(type: .system)
private let bookmarkButton = RDEPUBReaderTintButton(type: .system)
private let titleLabel: UILabel = {
let label = UILabel()
@@ -27,14 +30,17 @@ public final class RDEPUBReaderTopToolView: RDEPUBReaderToolView {
accessibilityIdentifier = "epub.reader.topToolbar"
self.backgroundColor = .white
addSubview(backButton)
addSubview(searchButton)
addSubview(bookmarkButton)
addSubview(titleLabel)
backButton.translatesAutoresizingMaskIntoConstraints = false
searchButton.translatesAutoresizingMaskIntoConstraints = false
bookmarkButton.translatesAutoresizingMaskIntoConstraints = false
titleLabel.translatesAutoresizingMaskIntoConstraints = false
backButton.addTarget(self, action: #selector(backAction), for: .touchUpInside)
searchButton.addTarget(self, action: #selector(searchAction), for: .touchUpInside)
bookmarkButton.addTarget(self, action: #selector(bookmarkAction), for: .touchUpInside)
NSLayoutConstraint.activate([
@@ -50,17 +56,26 @@ public final class RDEPUBReaderTopToolView: RDEPUBReaderToolView {
bookmarkButton.widthAnchor.constraint(equalToConstant: 44),
bookmarkButton.heightAnchor.constraint(equalToConstant: 44),
searchButton.trailingAnchor.constraint(equalTo: bookmarkButton.leadingAnchor, constant: -4),
searchButton.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 4),
searchButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -4),
searchButton.widthAnchor.constraint(equalToConstant: 44),
searchButton.heightAnchor.constraint(equalToConstant: 44),
titleLabel.leadingAnchor.constraint(equalTo: backButton.trailingAnchor, constant: 8),
titleLabel.trailingAnchor.constraint(equalTo: bookmarkButton.leadingAnchor, constant: -8),
titleLabel.trailingAnchor.constraint(equalTo: searchButton.leadingAnchor, constant: -8),
titleLabel.centerYAnchor.constraint(equalTo: backButton.centerYAnchor)
])
if #available(iOS 13.0, *) {
backButton.setImage(UIImage(systemName: "chevron.left")?.withRenderingMode(.alwaysTemplate), for: .normal)
searchButton.setImage(UIImage(systemName: "magnifyingglass")?.withRenderingMode(.alwaysTemplate), for: .normal)
} else {
backButton.setTitle("返回", for: .normal)
searchButton.setTitle("搜索", for: .normal)
}
backButton.accessibilityIdentifier = "epub.reader.back"
searchButton.accessibilityIdentifier = "epub.reader.search"
bookmarkButton.accessibilityIdentifier = "epub.reader.bookmark"
titleLabel.accessibilityIdentifier = "epub.reader.title"
updateBookmarkButtonAppearance()
@@ -76,12 +91,14 @@ public final class RDEPUBReaderTopToolView: RDEPUBReaderToolView {
override public func apply(theme: RDEPUBReaderTheme) {
super.apply(theme: theme)
titleLabel.textColor = .black
backButton.tintColor = .black
bookmarkButton.tintColor = .black
titleLabel.textColor = theme.toolControlTextColor
backButton.tintColor = theme.toolControlTextColor
searchButton.tintColor = theme.toolControlTextColor
bookmarkButton.tintColor = theme.toolControlTextColor
if #unavailable(iOS 13.0) {
backButton.setTitleColor(.black, for: .normal)
bookmarkButton.setTitleColor(.black, for: .normal)
backButton.setTitleColor(theme.toolControlTextColor, for: .normal)
searchButton.setTitleColor(theme.toolControlTextColor, for: .normal)
bookmarkButton.setTitleColor(theme.toolControlTextColor, for: .normal)
}
updateBookmarkButtonAppearance()
}
@@ -104,6 +121,10 @@ public final class RDEPUBReaderTopToolView: RDEPUBReaderToolView {
onBack?()
}
@objc private func searchAction() {
onSearch?()
}
@objc private func bookmarkAction() {
onToggleBookmark?()
}