diff --git a/CubeTime/Helper/Helper.swift b/CubeTime/Helper/Helper.swift index e7fba61..4f0688f 100644 --- a/CubeTime/Helper/Helper.swift +++ b/CubeTime/Helper/Helper.swift @@ -64,6 +64,13 @@ extension Array where Element: Equatable { } } +extension Collection { + /// Returns the element at the specified index if it is within bounds, otherwise nil. + subscript (safe index: Index) -> Element? { + return indices.contains(index) ? self[index] : nil + } +} + extension RandomAccessCollection where Element: Comparable { func insertionIndex(of value: Element) -> Index { var slice : SubSequence = self[...] diff --git a/CubeTime/StopwatchManager/StopwatchManager+Stats.swift b/CubeTime/StopwatchManager/StopwatchManager+Stats.swift index 777af80..ae5efa3 100644 --- a/CubeTime/StopwatchManager/StopwatchManager+Stats.swift +++ b/CubeTime/StopwatchManager/StopwatchManager+Stats.swift @@ -145,8 +145,19 @@ extension StopwatchManager { if timeListFilter.isEmpty { timeListSolvesFiltered = timeListSolves } else { + + timeListSolvesFiltered = timeListSolves.filter{ - formatSolveTime(secs: $0.time).hasPrefix(timeListFilter) || + let time = if let multiphaseSolve = $0 as? MultiphaseSolve, + let phase = timeListShownPhase, + let phases = multiphaseSolve.phases, + let time = ([0] + phases).chunked().map({ $0[1] - $0[0] })[safe: Int(phase)] { + time + } else { + $0.time + } + + return formatSolveTime(secs: time).hasPrefix(timeListFilter) || ($0.comment ?? "").lowercased().contains(timeListFilter.lowercased()) } } diff --git a/CubeTime/StopwatchManager/StopwatchManager.swift b/CubeTime/StopwatchManager/StopwatchManager.swift index c5805e2..d77d0e7 100644 --- a/CubeTime/StopwatchManager/StopwatchManager.swift +++ b/CubeTime/StopwatchManager/StopwatchManager.swift @@ -249,6 +249,12 @@ class StopwatchManager: ObservableObject { } } + @Published var timeListShownPhase: Int16? = nil { + didSet { + changedTimeListSort() + } + } + var timeListReloadSolve: ((Solve) -> ())? var timeListSelectAll: (() -> ())? diff --git a/CubeTime/TimeList/TimeListView.swift b/CubeTime/TimeList/TimeListView.swift index 9b999ca..ec41203 100644 --- a/CubeTime/TimeList/TimeListView.swift +++ b/CubeTime/TimeList/TimeListView.swift @@ -25,6 +25,16 @@ struct SortByMenu: View { var body: some View { Menu { + if let phaseCount = (stopwatchManager.currentSession as? MultiphaseSession)?.phaseCount { + Menu("Phase") { + Picker("", selection: $stopwatchManager.timeListShownPhase) { + Text("All phases").tag(Optional.none) + ForEach(0...some(idx)) + } + } + } + } #warning("TODO: headers not working") Section("Sort by") { Picker("", selection: $stopwatchManager.timeListSortBy) { diff --git a/CubeTime/TimeList/TimeListViewInner.swift b/CubeTime/TimeList/TimeListViewInner.swift index 3d7c95b..c1f4032 100644 --- a/CubeTime/TimeList/TimeListViewInner.swift +++ b/CubeTime/TimeList/TimeListViewInner.swift @@ -125,6 +125,8 @@ final class TimeListViewController: UICollectionViewController, UICollectionView typealias Snapshot = NSDiffableDataSourceSnapshot private let timeResuseIdentifier = "TimeCard" + + #warning("TODO: subscribe to changes of dynamic type?") private lazy var cardHeight: CGFloat = { if traitCollection.preferredContentSizeCategory > UIContentSizeCategory.extraLarge { return 60 @@ -165,7 +167,8 @@ final class TimeListViewController: UICollectionViewController, UICollectionView let stopwatchManager: StopwatchManager let onClickSolve: (Solve) -> () - var subscriber: AnyCancellable? + var subscribers: Set = [] + var shownPhase: Int16? = nil lazy var dataSource = makeDataSource() @@ -178,10 +181,18 @@ final class TimeListViewController: UICollectionViewController, UICollectionView super.init(collectionViewLayout: layout) - subscriber = stopwatchManager.$timeListSolvesFiltered + stopwatchManager.$timeListSolvesFiltered .sink(receiveValue: { [weak self] i in self?.applySnapshot(i) }) + .store(in: &subscribers) + + stopwatchManager.$timeListShownPhase + .sink(receiveValue: { [weak self] newValue in + self?.shownPhase = newValue + self?.collectionView.reloadData() + }) + .store(in: &subscribers) } required init?(coder: NSCoder) { @@ -198,7 +209,15 @@ final class TimeListViewController: UICollectionViewController, UICollectionView let solveCellRegistration = UICollectionView.CellRegistration { [weak self] cell, _, item in guard let self else { return } - cell.label.text = item.timeText + if let multiphaseSolve = item as? MultiphaseSolve, + let phase = shownPhase, + let phases = multiphaseSolve.phases, + let time = ([0] + phases).chunked().map({ $0[1] - $0[0] })[safe: Int(phase)] { +// let time = phases[safe: Int(phase)] { + cell.label.text = formatSolveTime(secs: time) + } else { + cell.label.text = item.timeText + } cell.label.frame = CGRect(origin: .zero, size: cell.frame.size) cell.item = item