Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 10 additions & 2 deletions BookPlayer/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger {
func setupMPSkipRemoteCommands() {
let center = MPRemoteCommandCenter.shared()
// Forward
center.skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)]
if PlayerManager.isForwardChapterSkip {
center.skipForwardCommand.isEnabled = false
} else {
center.skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)]
}
center.skipForwardCommand.addTarget { (_) -> MPRemoteCommandHandlerStatus in
guard let playerManager = AppServices.shared.coreServices?.playerManager else { return .commandFailed }

Expand Down Expand Up @@ -244,7 +248,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger {
}

// Rewind
center.skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)]
if PlayerManager.isRewindChapterSkip {
center.skipBackwardCommand.isEnabled = false
} else {
center.skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)]
}
center.skipBackwardCommand.addTarget { (_) -> MPRemoteCommandHandlerStatus in
guard let playerManager = AppServices.shared.coreServices?.playerManager else { return .commandFailed }

Expand Down
22 changes: 22 additions & 0 deletions BookPlayer/Generated/AutoMockable.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,28 @@ class PlayerManagerProtocolMock: PlayerManagerProtocol {
forwardCallsCount += 1
forwardClosure?()
}
//MARK: - skipToNextChapter

var skipToNextChapterCallsCount = 0
var skipToNextChapterCalled: Bool {
return skipToNextChapterCallsCount > 0
}
var skipToNextChapterClosure: (() -> Void)?
func skipToNextChapter() {
skipToNextChapterCallsCount += 1
skipToNextChapterClosure?()
}
//MARK: - skipToPreviousChapter

var skipToPreviousChapterCallsCount = 0
var skipToPreviousChapterCalled: Bool {
return skipToPreviousChapterCallsCount > 0
}
var skipToPreviousChapterClosure: (() -> Void)?
func skipToPreviousChapter() {
skipToPreviousChapterCallsCount += 1
skipToPreviousChapterClosure?()
}
//MARK: - skip

var skipCallsCount = 0
Expand Down
58 changes: 54 additions & 4 deletions BookPlayer/Player/PlayerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,13 @@ final class PlayerManager: NSObject, PlayerManagerProtocol, ObservableObject {
set {
UserDefaults.standard.set(newValue, forKey: Constants.UserDefaults.rewindInterval)

MPRemoteCommandCenter.shared().skipBackwardCommand.preferredIntervals = [newValue] as [NSNumber]
let center = MPRemoteCommandCenter.shared()
if newValue == Constants.SkipInterval.chapterSkipValue {
center.skipBackwardCommand.isEnabled = false
} else {
center.skipBackwardCommand.isEnabled = true
center.skipBackwardCommand.preferredIntervals = [newValue] as [NSNumber]
}
}
}

Expand All @@ -618,10 +624,24 @@ final class PlayerManager: NSObject, PlayerManagerProtocol, ObservableObject {
set {
UserDefaults.standard.set(newValue, forKey: Constants.UserDefaults.forwardInterval)

MPRemoteCommandCenter.shared().skipForwardCommand.preferredIntervals = [newValue] as [NSNumber]
let center = MPRemoteCommandCenter.shared()
if newValue == Constants.SkipInterval.chapterSkipValue {
center.skipForwardCommand.isEnabled = false
} else {
center.skipForwardCommand.isEnabled = true
center.skipForwardCommand.preferredIntervals = [newValue] as [NSNumber]
}
}
}

static var isRewindChapterSkip: Bool {
rewindInterval == Constants.SkipInterval.chapterSkipValue
}

static var isForwardChapterSkip: Bool {
forwardInterval == Constants.SkipInterval.chapterSkipValue
}

func setNowPlayingBookTitle(chapter: PlayableChapter) {
guard let currentItem = self.currentItem else { return }

Expand Down Expand Up @@ -735,11 +755,41 @@ extension PlayerManager {
}

func forward() {
skip(PlayerManager.forwardInterval)
if PlayerManager.isForwardChapterSkip {
skipToNextChapter()
} else {
skip(PlayerManager.forwardInterval)
}
}

func rewind() {
skip(-PlayerManager.rewindInterval)
if PlayerManager.isRewindChapterSkip {
skipToPreviousChapter()
} else {
skip(-PlayerManager.rewindInterval)
}
}

func skipToNextChapter() {
if let currentChapter = currentItem?.currentChapter,
let nextChapter = currentItem?.nextChapter(after: currentChapter)
{
jumpToChapter(nextChapter)
} else {
playNextItem(autoPlayed: false, shouldAutoplay: true)
}
NotificationCenter.default.post(name: .listeningProgressChanged, object: nil)
}

func skipToPreviousChapter() {
if let currentChapter = currentItem?.currentChapter,
let previousChapter = currentItem?.previousChapter(before: currentChapter)
{
jumpToChapter(previousChapter)
} else {
playPreviousItem()
}
NotificationCenter.default.post(name: .listeningProgressChanged, object: nil)
}

func skip(_ interval: TimeInterval) {
Expand Down
2 changes: 2 additions & 0 deletions BookPlayer/Player/PlayerManagerProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public protocol PlayerManagerProtocol: AnyObject {
func stop()
func rewind()
func forward()
func skipToNextChapter()
func skipToPreviousChapter()
func skip(_ interval: TimeInterval)
/// Bypass checks on chapter limits
func directSkip(_ interval: TimeInterval)
Expand Down
20 changes: 3 additions & 17 deletions BookPlayer/Player/ViewModels/PlayerViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -400,25 +400,11 @@ final class PlayerViewModel: ObservableObject {
}

func handleNextTap() {
if let currentChapter = self.playerManager.currentItem?.currentChapter,
let nextChapter = self.playerManager.currentItem?.nextChapter(after: currentChapter)
{
self.playerManager.jumpToChapter(nextChapter)
} else {
self.playerManager.playNextItem(autoPlayed: false, shouldAutoplay: true)
}
NotificationCenter.default.post(name: .listeningProgressChanged, object: nil)
self.playerManager.skipToNextChapter()
}

func handlePreviousTap() {
if let currentChapter = self.playerManager.currentItem?.currentChapter,
let previousChapter = self.playerManager.currentItem?.previousChapter(before: currentChapter)
{
self.playerManager.jumpToChapter(previousChapter)
} else {
self.playerManager.playPreviousItem()
}
NotificationCenter.default.post(name: .listeningProgressChanged, object: nil)
self.playerManager.skipToPreviousChapter()
}

func hasLoadedBook() -> Bool {
Expand Down
28 changes: 26 additions & 2 deletions BookPlayer/Player/Views/PlayControlsRowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,34 @@ struct PlayControlsRowView: View {
@EnvironmentObject private var theme: ThemeViewModel
@EnvironmentObject private var playerManager: PlayerManager

private var rewindImage: Image {
rewindInterval == Constants.SkipInterval.chapterSkipValue
? Image(systemName: "backward.end.fill")
: Image(.playerIconRewind)
}

private var rewindLabelText: String {
rewindInterval == Constants.SkipInterval.chapterSkipValue
? ""
: "-\(String(Int(rewindInterval.rounded())))"
}

private var forwardImage: Image {
forwardInterval == Constants.SkipInterval.chapterSkipValue
? Image(systemName: "forward.end.fill")
: Image(.playerIconForward)
}

private var forwardLabelText: String {
forwardInterval == Constants.SkipInterval.chapterSkipValue
? ""
: "+\(String(Int(forwardInterval.rounded())))"
}

var body: some View {
HStack(spacing: 0) {
Spacer()
PlayerJumpView(backgroundImage: Image(.playerIconRewind), text: "-\(String(Int(rewindInterval.rounded())))", tintColor: Color(theme.linkColor)) {
PlayerJumpView(backgroundImage: rewindImage, text: rewindLabelText, tintColor: Color(theme.linkColor)) {
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
playerManager.rewind()
}
Expand All @@ -33,7 +57,7 @@ struct PlayControlsRowView: View {
.accessibilityLabel(isPlaying ? "pause_title".localized : "play_title".localized)
Spacer()
Spacer()
PlayerJumpView(backgroundImage: Image(.playerIconForward), text: "+\(String(Int(forwardInterval.rounded())))", tintColor: Color(theme.linkColor)) {
PlayerJumpView(backgroundImage: forwardImage, text: forwardLabelText, tintColor: Color(theme.linkColor)) {
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
playerManager.forward()
}
Expand Down
6 changes: 6 additions & 0 deletions BookPlayer/Services/VoiceOverService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class VoiceOverService {
// MARK: - ArtworkControl

public static func rewindText() -> String {
if PlayerManager.isRewindChapterSkip {
return "chapters_previous_title".localized
}
return String(
describing: String.localizedStringWithFormat(
"voiceover_rewind_time".localized,
Expand All @@ -62,6 +65,9 @@ class VoiceOverService {
}

public static func fastForwardText() -> String {
if PlayerManager.isForwardChapterSkip {
return "chapters_next_title".localized
}
return String(
describing: String.localizedStringWithFormat(
"voiceover_forward_time".localized,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,23 @@ struct SkipIntervalsSectionView: View {
.tag(interval)
.foregroundStyle(theme.linkColor)
}
Text("chapters_previous_title")
.bpFont(.body)
.tag(Constants.SkipInterval.chapterSkipValue)
.foregroundStyle(theme.linkColor)
} label: {
Text("settings_skip_rewind_title")
.bpFont(.body)
}
.pickerStyle(.menu)
.onChange(of: rewindInterval) {
MPRemoteCommandCenter.shared().skipBackwardCommand.preferredIntervals = [rewindInterval] as [NSNumber]
let center = MPRemoteCommandCenter.shared()
if rewindInterval == Constants.SkipInterval.chapterSkipValue {
center.skipBackwardCommand.isEnabled = false
} else {
center.skipBackwardCommand.isEnabled = true
center.skipBackwardCommand.preferredIntervals = [rewindInterval] as [NSNumber]
}
}

Picker(selection: $forwardInterval) {
Expand All @@ -56,13 +66,23 @@ struct SkipIntervalsSectionView: View {
.tag(interval)
.foregroundStyle(theme.linkColor)
}
Text("chapters_next_title")
.bpFont(.body)
.tag(Constants.SkipInterval.chapterSkipValue)
.foregroundStyle(theme.linkColor)
} label: {
Text("settings_skip_forward_title")
.bpFont(.body)
}
.pickerStyle(.menu)
.onChange(of: forwardInterval) {
MPRemoteCommandCenter.shared().skipForwardCommand.preferredIntervals = [forwardInterval] as [NSNumber]
let center = MPRemoteCommandCenter.shared()
if forwardInterval == Constants.SkipInterval.chapterSkipValue {
center.skipForwardCommand.isEnabled = false
} else {
center.skipForwardCommand.isEnabled = true
center.skipForwardCommand.preferredIntervals = [forwardInterval] as [NSNumber]
}
}
} header: {
Text("settings_skip_title".localized.capitalized)
Expand Down
12 changes: 10 additions & 2 deletions BookPlayerWatch/ExtensionDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ class ExtensionDelegate: NSObject, WKApplicationDelegate, ObservableObject {
func setupMPSkipRemoteCommands() {
let center = MPRemoteCommandCenter.shared()
// Forward
center.skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)]
if PlayerManager.isForwardChapterSkip {
center.skipForwardCommand.isEnabled = false
} else {
center.skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)]
}
center.skipForwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in
guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed }

Expand Down Expand Up @@ -244,7 +248,11 @@ class ExtensionDelegate: NSObject, WKApplicationDelegate, ObservableObject {
}

// Rewind
center.skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)]
if PlayerManager.isRewindChapterSkip {
center.skipBackwardCommand.isEnabled = false
} else {
center.skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)]
}
center.skipBackwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in
guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ struct PlaybackFullControlsView: View {
HStack {
Text("settings_skip_rewind_title")
Spacer()
Text(TimeParser.formatDuration(rewindInterval))
Text(
rewindInterval == Constants.SkipInterval.chapterSkipValue
? "chapters_previous_title".localized
: TimeParser.formatDuration(rewindInterval)
)
Image(systemName: "chevron.forward")
}
}
Expand All @@ -137,7 +141,11 @@ struct PlaybackFullControlsView: View {
HStack {
Text("settings_skip_forward_title")
Spacer()
Text(TimeParser.formatDuration(forwardInterval))
Text(
forwardInterval == Constants.SkipInterval.chapterSkipValue
? "chapters_next_title".localized
: TimeParser.formatDuration(forwardInterval)
)
Image(systemName: "chevron.forward")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct SkipDurationListView: View {
ForEach(intervals, id: \.self) { interval in
Button {
switch skipDirection {
case .forward:
case .forward:
selectedForwardInterval = interval
case .back:
selectedRewindInterval = interval
Expand All @@ -65,6 +65,30 @@ struct SkipDurationListView: View {
}
}
}

Button {
switch skipDirection {
case .forward:
selectedForwardInterval = Constants.SkipInterval.chapterSkipValue
case .back:
selectedRewindInterval = Constants.SkipInterval.chapterSkipValue
}
dismiss()
} label: {
HStack {
Text(
skipDirection == .forward
? "chapters_next_title".localized
: "chapters_previous_title".localized
)
.font(.caption)
Spacer()
if selectedInterval == Constants.SkipInterval.chapterSkipValue {
Image(systemName: "checkmark")
.foregroundColor(.accentColor)
}
}
}
}
.onAppear {
proxy.scrollTo(selectedInterval, anchor: .center)
Expand Down
Loading
Loading