Skip to content

Commit

Permalink
Small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmuslos committed Mar 13, 2024
1 parent 4f425cc commit ccf2909
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 103 deletions.
4 changes: 4 additions & 0 deletions ShelfPlayer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
3A38A1582AD4715100D533F3 /* PlayButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A38A1572AD4715100D533F3 /* PlayButton.swift */; };
3A48D2512AD0661500991139 /* LibrarySelectorModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A48D2502AD0661500991139 /* LibrarySelectorModifier.swift */; };
3A48D2542AD074DC00991139 /* PodcastEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A48D2532AD074DC00991139 /* PodcastEntryView.swift */; };
3A4E8A192B8E52A700A2586C /* CarPlay+Offline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4E8A182B8E52A700A2586C /* CarPlay+Offline.swift */; };
3A50AAA52ACC42B400BF5438 /* AudiobookEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A50AAA42ACC42B400BF5438 /* AudiobookEntryView.swift */; };
3A50AAB62ACC521B00BF5438 /* AudiobookLibraryView+ListenNow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A50AAB52ACC521B00BF5438 /* AudiobookLibraryView+ListenNow.swift */; };
3A50AAB82ACC522900BF5438 /* AudiobookEntryView+Library.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A50AAB72ACC522900BF5438 /* AudiobookEntryView+Library.swift */; };
Expand Down Expand Up @@ -155,6 +156,7 @@
3A38A1572AD4715100D533F3 /* PlayButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayButton.swift; sourceTree = "<group>"; };
3A48D2502AD0661500991139 /* LibrarySelectorModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibrarySelectorModifier.swift; sourceTree = "<group>"; };
3A48D2532AD074DC00991139 /* PodcastEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PodcastEntryView.swift; sourceTree = "<group>"; };
3A4E8A182B8E52A700A2586C /* CarPlay+Offline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarPlay+Offline.swift"; sourceTree = "<group>"; };
3A50AAA42ACC42B400BF5438 /* AudiobookEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudiobookEntryView.swift; sourceTree = "<group>"; };
3A50AAB52ACC521B00BF5438 /* AudiobookLibraryView+ListenNow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AudiobookLibraryView+ListenNow.swift"; sourceTree = "<group>"; };
3A50AAB72ACC522900BF5438 /* AudiobookEntryView+Library.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AudiobookEntryView+Library.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -462,6 +464,7 @@
isa = PBXGroup;
children = (
3A83B8722B8893E000A05957 /* CarPlayDelegate.swift */,
3A4E8A182B8E52A700A2586C /* CarPlay+Offline.swift */,
3AD6BE862B89066300EEA347 /* CarPlay+Playback.swift */,
3AD6BE842B89060F00EEA347 /* CarPlay+NowPlaying.swift */,
);
Expand Down Expand Up @@ -787,6 +790,7 @@
3A77B6FD2ACDE2FA00F22C7F /* AuthorUnavailableView.swift in Sources */,
3A0AE6BA2AB624E700ACCD68 /* LoginView.swift in Sources */,
3AEFA9532B8BB3CA00220CA3 /* String+Random.swift in Sources */,
3A4E8A192B8E52A700A2586C /* CarPlay+Offline.swift in Sources */,
3A9874292B59A7B500B2704F /* View+ReverseMask.swift in Sources */,
3A1EAB962ACC808A0064C80C /* ItemImage.swift in Sources */,
3A853FAF2AD03FA600FACAF6 /* AuthorView+Header.swift in Sources */,
Expand Down
95 changes: 95 additions & 0 deletions iOS/CarPlay/CarPlay+Offline.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//
// CarPlay+Offline.swift
// iOS
//
// Created by Rasmus Krämer on 27.02.24.
//

import CarPlay
import SPPlayback
import SPOffline
import SPOfflineExtended

extension CarPlayDelegate {
internal func buildOfflineListTemplate() async throws -> CPListTemplate {
let template = CPListTemplate(title: String(localized: "carPlay.offline.title"), sections: try getOfflineSections(), assistantCellConfiguration: .init(position: .top, visibility: .always, assistantAction: .playMedia))

Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { _ in
Task { @MainActor in
template.updateSections(Self.updateSections(template.sections))
}
}
NotificationCenter.default.addObserver(forName: Self.updateContentNotifications, object: nil, queue: nil) { _ in
Task { @MainActor in
template.updateSections(Self.updateSections(template.sections))
}
}

return template
}

private func getOfflineSections() throws -> [CPListSection] {
let podcasts = try OfflineManager.shared.getPodcasts()
let audiobooks = try OfflineManager.shared.getAudiobooks()

var sections: [CPListSection] = [
.init(items: audiobooks.map { @MainActor in
var image: UIImage?
var detailText = ""

if let imageUrl = $0.image?.url, let data = try? Data(contentsOf: imageUrl) {
image = UIImage(data: data)
}

if let author = $0.author {
detailText += author
}
if let narrator = $0.narrator {
if !detailText.isEmpty {
detailText += ""
}

detailText += narrator
}

let item = CPListItem(text: $0.name, detailText: detailText.isEmpty ? nil : detailText, image: image, accessoryImage: nil, accessoryType: .none)

item.isExplicitContent = $0.explicit

item.playingIndicatorLocation = .trailing
item.isPlaying = AudioPlayer.shared.item == $0

item.userInfo = $0
item.handler = Self.startPlayback

item.playbackProgress = OfflineManager.shared.requireProgressEntity(item: $0).progress

return item
}, header: String(localized: "carPlay.offline.sections.audiobooks"), headerSubtitle: nil, headerImage: UIImage(systemName: "bookmark.fill"), headerButton: nil, sectionIndexTitle: nil),
]

sections.append(contentsOf: podcasts.map {
CPListSection(items: $0.value.map { @MainActor in
let item = CPListItem(text: $0.name, detailText: $0.descriptionText)

item.userInfo = $0
item.handler = Self.startPlayback

item.playingIndicatorLocation = .trailing
item.isPlaying = AudioPlayer.shared.item == $0

item.playbackProgress = OfflineManager.shared.requireProgressEntity(item: $0).progress

return item
}, header: $0.key.name, headerSubtitle: $0.key.author, headerImage: {
if let imageUrl = $0.image?.url, let data = try? Data(contentsOf: imageUrl) {
return UIImage(data: data)
}

return nil
}($0.key), headerButton: nil, sectionIndexTitle: nil)
})

return sections
}
}
21 changes: 12 additions & 9 deletions iOS/CarPlay/CarPlay+Playback.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@ internal extension CarPlayDelegate {
static func updateSections(_ sections: [CPListSection]) -> [CPListSection] {
sections.map {
CPListSection(items: $0.items.map {
let item = $0 as! CPListItem
let playableItem = $0.userInfo as! PlayableItem

if AudioPlayer.shared.item == playableItem {
item.isPlaying = true
item.playbackProgress = OfflineManager.shared.requireProgressEntity(item: playableItem).progress
} else {
item.isPlaying = false
if let item = $0 as? CPListItem {
let playableItem = $0.userInfo as! PlayableItem

if AudioPlayer.shared.item == playableItem {
item.isPlaying = true
item.playbackProgress = OfflineManager.shared.requireProgressEntity(item: playableItem).progress
} else {
item.isPlaying = false
}

return item
}

return item
return $0
}, header: $0.header!, headerSubtitle: $0.headerSubtitle, headerImage: $0.headerImage, headerButton: $0.headerButton, sectionIndexTitle: $0.sectionIndexTitle)
}
}
Expand Down
88 changes: 0 additions & 88 deletions iOS/CarPlay/CarPlayDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@
//

import CarPlay
import Defaults
import SPBase
import SPPlayback
import SPOffline
import SPOfflineExtended

class CarPlayDelegate: UIResponder, CPTemplateApplicationSceneDelegate {
// we need to keep a strong reference to this object
Expand Down Expand Up @@ -43,87 +39,3 @@ class CarPlayDelegate: UIResponder, CPTemplateApplicationSceneDelegate {
nowPlayingObserver = nil
}
}

extension CarPlayDelegate {
private func buildOfflineListTemplate() async throws -> CPListTemplate {
let template = CPListTemplate(title: String(localized: "carPlay.offline.title"), sections: try getOfflineSections(), assistantCellConfiguration: .init(position: .top, visibility: .always, assistantAction: .playMedia))

Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { _ in
Task { @MainActor in
template.updateSections(Self.updateSections(template.sections))
}
}
NotificationCenter.default.addObserver(forName: Self.updateContentNotifications, object: nil, queue: nil) { _ in
Task { @MainActor in
template.updateSections(Self.updateSections(template.sections))
}
}

return template
}

private func getOfflineSections() throws -> [CPListSection] {
let podcasts = try OfflineManager.shared.getPodcasts()
let audiobooks = try OfflineManager.shared.getAudiobooks()

var sections: [CPListSection] = [
.init(items: audiobooks.map { @MainActor in
var image: UIImage?
var detailText = ""

if let imageUrl = $0.image?.url, let data = try? Data(contentsOf: imageUrl) {
image = UIImage(data: data)
}

if let author = $0.author {
detailText += author
}
if let narrator = $0.narrator {
if !detailText.isEmpty {
detailText += ""
}

detailText += narrator
}

let item = CPListItem(text: $0.name, detailText: detailText.isEmpty ? nil : detailText, image: image, accessoryImage: nil, accessoryType: .none)

item.isExplicitContent = $0.explicit

item.playingIndicatorLocation = .trailing
item.isPlaying = AudioPlayer.shared.item == $0

item.userInfo = $0
item.handler = Self.startPlayback

item.playbackProgress = OfflineManager.shared.requireProgressEntity(item: $0).progress

return item
}, header: String(localized: "carPlay.offline.sections.audiobooks"), headerSubtitle: nil, headerImage: UIImage(systemName: "bookmark.fill"), headerButton: nil, sectionIndexTitle: nil),
]

sections.append(contentsOf: podcasts.map {
CPListSection(items: $0.value.map { @MainActor in
let item = CPListItem(text: $0.name, detailText: $0.descriptionText)

item.userInfo = $0
item.handler = Self.startPlayback

item.playingIndicatorLocation = .trailing
item.isPlaying = AudioPlayer.shared.item == $0

item.playbackProgress = OfflineManager.shared.requireProgressEntity(item: $0).progress

return item
}, header: $0.key.name, headerSubtitle: $0.key.author, headerImage: {
if let imageUrl = $0.image?.url, let data = try? Data(contentsOf: imageUrl) {
return UIImage(data: data)
}

return nil
}($0.key), headerButton: nil, sectionIndexTitle: nil)
})

return sections
}
}
1 change: 0 additions & 1 deletion iOS/Offline/OfflineView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ struct OfflineView: View {
}

extension OfflineView {
@Sendable
func loadItems() async throws {
(audiobooks, podcasts) = try await (OfflineManager.shared.getAudiobooks(), OfflineManager.shared.getPodcasts())
}
Expand Down
12 changes: 7 additions & 5 deletions iOS/Reusable/Buttons/DownloadButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ struct DownloadButton: View {
Label("download.remove", systemImage: "xmark")
}
case .working:
HStack {
ProgressView()

if downloadingLabel {
if downloadingLabel {
HStack {
ProgressView()
Text("downloading")
}
} else {
ProgressView()
}
}
}
Expand Down Expand Up @@ -89,5 +91,5 @@ extension DownloadButton {
}

#Preview {
DownloadButton(item: Audiobook.fixture, downloadingLabel: true)
DownloadButton(item: Audiobook.fixture, downloadingLabel: false)
}

0 comments on commit ccf2909

Please sign in to comment.