Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ public enum FeatureFlag: String, CaseIterable {
/// Enable Disable the use of suggested folders
case suggestedFolders

/// Parse toc value in chapters
case parseChaptersToc

public var enabled: Bool {
if let overriddenValue = FeatureFlagOverrideStore().overriddenValue(for: self) {
return overriddenValue
Expand Down Expand Up @@ -240,6 +243,8 @@ public enum FeatureFlag: String, CaseIterable {
true
case .suggestedFolders:
false
case .parseChaptersToc:
true
}
}

Expand Down
2 changes: 2 additions & 0 deletions podcasts/ChapterInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ class ChapterInfo: Equatable {
var isFirst = false
var isLast = false
var index = 0
var originalIndex = 0
var duration: TimeInterval = 0
var isHidden = false
var toc = true

/// Should only be used for sync purposes, if reading for playback
/// use `isPlayable()` instead
Expand Down
19 changes: 15 additions & 4 deletions podcasts/ChapterManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,21 @@ class ChapterManager {
private func handleChaptersLoaded(_ chapters: [ChapterInfo], for episode: BaseEpisode) {
self.chapters = chapters

episode.deselectedChapters?
.split(separator: ",")
.compactMap { Int($0) }
.forEach { self.chapters[safe: $0]?.shouldPlay = false }
if FeatureFlag.parseChaptersToc.enabled {
let map = chapters.reduce(into: [Int: ChapterInfo]()) {
$0[$1.originalIndex] = $1
}

episode.deselectedChapters?
.split(separator: ",")
.compactMap { Int($0) }
.forEach { map[$0]?.shouldPlay = false }
} else {
episode.deselectedChapters?
.split(separator: ",")
.compactMap { Int($0) }
.forEach { self.chapters[safe: $0]?.shouldPlay = false }
}

updateCurrentChapter(time: PlaybackManager.shared.currentTime())

Expand Down
4 changes: 4 additions & 0 deletions podcasts/Chapters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class Chapters: Equatable {
visibleChapter?.index ?? -1
}

var originalIndex: Int {
visibleChapter?.originalIndex ?? -1
}

var url: String? {
chapters.last(where: { $0.url != nil })?.url
}
Expand Down
4 changes: 3 additions & 1 deletion podcasts/PlayerChapterCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ class PlayerChapterCell: UITableViewCell {

setColors(dim: chapter?.isPlayable() == false)

if let currentEpisode = PlaybackManager.shared.currentEpisode(), let index = chapter?.index {
let chapterIndex = FeatureFlag.parseChaptersToc.enabled ? chapter?.originalIndex : chapter?.index

if let currentEpisode = PlaybackManager.shared.currentEpisode(), let index = chapterIndex {
if chapter?.shouldPlay == true {
currentEpisode.select(chapterIndex: index)
track(.deselectChaptersChapterSelected)
Expand Down
26 changes: 23 additions & 3 deletions podcasts/PodcastChapterParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class PodcastChapterParser {
let chapterInfo = ChapterInfo()
chapterInfo.title = chapter.title ?? ""
chapterInfo.index = index
if FeatureFlag.parseChaptersToc.enabled {
chapterInfo.originalIndex = index
}
chapterInfo.startTime = CMTime(seconds: chapter.startTime, preferredTimescale: 1000000)

// Calculate chapter duration based on the info we have
Expand All @@ -57,20 +60,34 @@ class PodcastChapterParser {
}

func parsePodcastIndexChapters(_ podcastIndexChapters: [PodcastIndexChapter], episodeDuration: TimeInterval) -> [ChapterInfo] {
podcastIndexChapters.enumerated().map { index, chapter in
var index = 0
let chapters = podcastIndexChapters.enumerated().map { originalIndex, chapter in
let chapterInfo = ChapterInfo()
chapterInfo.title = chapter.title ?? ""
chapterInfo.index = chapter.number ?? index
if FeatureFlag.parseChaptersToc.enabled {
chapterInfo.originalIndex = chapter.number ?? originalIndex
chapterInfo.toc = chapter.toc ?? true
if chapterInfo.toc {
chapterInfo.index = index
index += 1
}
} else {
chapterInfo.index = chapter.number ?? originalIndex
}
chapterInfo.startTime = CMTime(seconds: chapter.startTime, preferredTimescale: 1000000)
if let endTime = chapter.endTime {
chapterInfo.duration = endTime - chapter.startTime
} else if let nextChapterStartTime = podcastIndexChapters[safe: index + 1]?.startTime {
} else if let nextChapterStartTime = podcastIndexChapters[safe: originalIndex + 1]?.startTime {
chapterInfo.duration = nextChapterStartTime - chapter.startTime
} else {
chapterInfo.duration = episodeDuration - chapter.startTime
}
return chapterInfo
}
if FeatureFlag.parseChaptersToc.enabled {
return chapters.filter { $0.toc == true }
}
return chapters
}

private func parseChapters(url: URL, episodeDuration: TimeInterval, completion: @escaping (([ChapterInfo]) -> Void)) {
Expand Down Expand Up @@ -108,6 +125,9 @@ class PodcastChapterParser {
convertedChapter.isHidden = chapter.hidden
if !convertedChapter.isHidden {
convertedChapter.index = index
if FeatureFlag.parseChaptersToc.enabled {
convertedChapter.originalIndex = index
}
index += 1
}
if strongSelf.isValidUrl(chapter.url) {
Expand Down
1 change: 1 addition & 0 deletions podcasts/PodcastIndexChapterDataRetriever.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct PodcastIndexChapter: Decodable {
let number: Int?
let endTime: TimeInterval?
let startTime: TimeInterval
let toc: Bool?
}

/// Request information about an episode using the show notes endpoint
Expand Down