Skip to content

Commit 1c89282

Browse files
authored
Add the scroll progressions in the EPUB viewport (#620)
1 parent c6cf719 commit 1c89282

File tree

3 files changed

+47
-30
lines changed

3 files changed

+47
-30
lines changed

Sources/Navigator/EPUB/EPUBNavigatorViewController.swift

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ open class EPUBNavigatorViewController: InputObservableViewController,
136136
/// Indices of the visible reading order resources.
137137
public var readingOrderIndices: ClosedRange<[Link].Index>
138138

139+
/// Range of visible scroll progressions for each visible reading order
140+
/// resource.
141+
public var progressions: [[Link].Index: ClosedRange<Double>]
142+
139143
/// Range of visible positions.
140144
public var positions: ClosedRange<Int>?
141145
}
@@ -623,44 +627,57 @@ open class EPUBNavigatorViewController: InputObservableViewController,
623627
return (nil, nil)
624628
}
625629

626-
let index = spreadView.focusedResource ?? spreadView.spread.leading
627-
let link = readingOrder[index]
628-
let href = link.url()
629-
let progressionRange = spreadView.progression(in: index)
630-
let firstProgression = min(max(progressionRange.lowerBound, 0.0), 1.0)
631-
let lastProgression = min(max(progressionRange.upperBound, 0.0), 1.0)
632-
633-
let location: Locator?
634630
var viewport = Viewport(
635631
readingOrderIndices: spreadView.spread.readingOrderIndices,
632+
progressions: spreadView.spread.readingOrderIndices.reduce([:]) { progressions, index in
633+
var progressions = progressions
634+
progressions[index] = spreadView.progression(in: index)
635+
return progressions
636+
},
636637
positions: nil
637638
)
638639

640+
let firstIndex = spreadView.spread.readingOrderIndices.lowerBound
641+
let lastIndex = spreadView.spread.readingOrderIndices.upperBound
642+
let progressionOfFirstResource = spreadView.progression(in: firstIndex)
643+
let progressionOfLastResource = spreadView.progression(in: lastIndex)
644+
let firstProgressionInFirstResource = min(max(progressionOfFirstResource.lowerBound, 0.0), 1.0)
645+
let lastProgressionInLastResource = min(max(progressionOfLastResource.upperBound, 0.0), 1.0)
646+
647+
let link = readingOrder[firstIndex]
648+
let location: Locator?
649+
639650
if
640651
// The positions are not always available, for example a Readium
641652
// WebPub doesn't have any unless a Publication Positions Web
642653
// Service is provided
643-
let index = readingOrder.firstIndexWithHREF(href),
644-
let positionList = positionsByReadingOrder.getOrNil(index),
645-
positionList.count > 0,
646-
let positionOffset = positionList[0].locations.position
654+
let positionsOfFirstResource = positionsByReadingOrder.getOrNil(firstIndex),
655+
let positionsOfLastResource = positionsByReadingOrder.getOrNil(lastIndex),
656+
!positionsOfFirstResource.isEmpty,
657+
!positionsOfLastResource.isEmpty
647658
{
648-
// Gets the current locator from the positionList, and fill its missing data.
649-
let firstPositionIndex = Int(ceil(firstProgression * Double(positionList.count - 1)))
650-
let lastPositionIndex = (lastProgression == 1.0)
651-
? positionList.count - 1
652-
: max(firstPositionIndex, Int(ceil(lastProgression * Double(positionList.count - 1))) - 1)
653-
654-
location = await positionList[firstPositionIndex].copy(
655-
title: tableOfContentsTitleByHref[equivalent: href],
656-
locations: { $0.progression = firstProgression }
659+
// Gets the current locator from the positions, and fill its missing
660+
// data.
661+
let firstPositionIndex = Int(ceil(firstProgressionInFirstResource * Double(positionsOfFirstResource.count - 1)))
662+
let lastPositionIndex = (lastProgressionInLastResource == 1.0)
663+
? positionsOfLastResource.count - 1
664+
: max(firstPositionIndex, Int(ceil(lastProgressionInLastResource * Double(positionsOfLastResource.count - 1))) - 1)
665+
666+
location = await positionsOfFirstResource[firstPositionIndex].copy(
667+
title: tableOfContentsTitleByHref[equivalent: link.url()],
668+
locations: { $0.progression = firstProgressionInFirstResource }
657669
)
658670

659-
viewport.positions = (positionOffset + firstPositionIndex) ... (positionOffset + lastPositionIndex)
671+
if
672+
let firstPosition = location?.locations.position,
673+
let lastPosition = positionsOfLastResource[lastPositionIndex].locations.position
674+
{
675+
viewport.positions = firstPosition ... lastPosition
676+
}
660677

661678
} else {
662679
location = await publication.locate(link)?.copy(
663-
locations: { $0.progression = firstProgression }
680+
locations: { $0.progression = firstProgressionInFirstResource }
664681
)
665682
}
666683

Sources/Navigator/EPUB/EPUBReflowableSpreadView.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,12 @@ final class EPUBReflowableSpreadView: EPUBSpreadView {
131131

132132
// MARK: - Location and progression
133133

134-
override func progression(in index: ReadingOrder.Index) -> Range<Double> {
134+
override func progression(in index: ReadingOrder.Index) -> ClosedRange<Double> {
135135
guard
136136
spread.leading == index,
137137
let progression = progression
138138
else {
139-
return 0 ..< 0
139+
return 0 ... 0
140140
}
141141
return progression
142142
}
@@ -319,9 +319,9 @@ final class EPUBReflowableSpreadView: EPUBSpreadView {
319319
// MARK: - Progression
320320

321321
// Current progression range in the page.
322-
private var progression: Range<Double>?
322+
private var progression: ClosedRange<Double>?
323323
// To check if a progression change was cancelled or not.
324-
private var previousProgression: Range<Double>?
324+
private var previousProgression: ClosedRange<Double>?
325325

326326
// Called by the javascript code to notify that scrolling ended.
327327
private func progressionDidChange(_ body: Any) {
@@ -340,7 +340,7 @@ final class EPUBReflowableSpreadView: EPUBSpreadView {
340340
if previousProgression == nil {
341341
previousProgression = progression
342342
}
343-
progression = firstProgression ..< lastProgression
343+
progression = firstProgression ... lastProgression
344344

345345
setNeedsNotifyPagesDidChange()
346346
}

Sources/Navigator/EPUB/EPUBSpreadView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,9 @@ class EPUBSpreadView: UIView, Loggable, PageView {
342342
// MARK: - Location and progression.
343343

344344
/// Current progression in the resource with given href.
345-
func progression(in index: ReadingOrder.Index) -> Range<Double> {
345+
func progression(in index: ReadingOrder.Index) -> ClosedRange<Double> {
346346
// To be overridden in subclasses if the resource supports a progression.
347-
0 ..< 0
347+
0 ... 1
348348
}
349349

350350
func go(to location: PageLocation) async {

0 commit comments

Comments
 (0)