Skip to content

Commit a2001b7

Browse files
committed
working consume stream based on server
1 parent 5c7affe commit a2001b7

32 files changed

Lines changed: 685 additions & 562 deletions

BookPlayer.xcodeproj/project.pbxproj

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -705,12 +705,12 @@
705705
996D4CD22F98A45300FC3B57 /* IntegrationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0D0FA9BA32EDF5F367C757B /* IntegrationError.swift */; };
706706
996D4CD32F98A50C00FC3B57 /* IntegrationLibraryItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A823609A5B7EFC6D2D5D120 /* IntegrationLibraryItemProtocol.swift */; };
707707
996D4CD42F98A50C00FC3B57 /* IntegrationLibraryItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A823609A5B7EFC6D2D5D120 /* IntegrationLibraryItemProtocol.swift */; };
708-
997C8D182FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
709-
997C8D192FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
710-
997C8D1A2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
711-
997C8D1B2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
712-
997C8D1C2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
713-
997C8D1D2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
708+
997C8D262FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
709+
997C8D272FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
710+
997C8D282FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
711+
997C8D292FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
712+
997C8D2A2FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
713+
997C8D2B2FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */; };
714714
99B367FA2F4575C900C38F7F /* MediaAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99B367F92F4575C600C38F7F /* MediaAction.swift */; };
715715
99B367FC2F5108BF00C38F7F /* MediaActionRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99B367FB2F5108BF00C38F7F /* MediaActionRow.swift */; };
716716
99C919CC2F99609F00F66081 /* Get in Frameworks */ = {isa = PBXBuildFile; productRef = 99C919CB2F99609F00F66081 /* Get */; };
@@ -1710,7 +1710,7 @@
17101710
99329DDA2F3ED5E5003F8E73 /* DurationPickerSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DurationPickerSheet.swift; sourceTree = "<group>"; };
17111711
995787DD2F56674400BF0814 /* Audiobook Player 11.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Audiobook Player 11.xcdatamodel"; sourceTree = "<group>"; };
17121712
996D4CC42F98A25100FC3B57 /* MappingModel_v10_to_v11.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = MappingModel_v10_to_v11.xcmappingmodel; sourceTree = "<group>"; };
1713-
997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = MappingModel_v11_to_v12.xcmappingmodel; sourceTree = "<group>"; };
1713+
997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = MappingModel_v11_to_v12.xcmappingmodel; sourceTree = "<group>"; };
17141714
99B367F92F4575C600C38F7F /* MediaAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaAction.swift; sourceTree = "<group>"; };
17151715
99B367FB2F5108BF00C38F7F /* MediaActionRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaActionRow.swift; sourceTree = "<group>"; };
17161716
99C919C92F98AE4700F66081 /* Get */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Get; path = "/Users/pedro.aim/Library/Developer/Xcode/DerivedData/BookPlayer-aehtalmtnvnplqeabppyoncpqrlc/SourcePackages/checkouts/Get"; sourceTree = "<absolute>"; };
@@ -2470,7 +2470,7 @@
24702470
9FF383D02A40F97000BBAC11 /* MappingModel_v8_to_v9.xcmappingmodel */,
24712471
3F66408C2E172DF500356522 /* MappingModel_v9_to_v10.xcmappingmodel */,
24722472
996D4CC42F98A25100FC3B57 /* MappingModel_v10_to_v11.xcmappingmodel */,
2473-
997C8D172FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel */,
2473+
997C8D252FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel */,
24742474
);
24752475
path = Migrations;
24762476
sourceTree = "<group>";
@@ -4432,7 +4432,7 @@
44324432
6399D0702CEBA35D00A2E278 /* RemoteItemListView.swift in Sources */,
44334433
41C3396225E04103003ED2B0 /* MappingModel_v2_to_v3.xcmappingmodel in Sources */,
44344434
6350E4722CF4D0220077CDC1 /* PlayerControlsView.swift in Sources */,
4435-
997C8D1C2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
4435+
997C8D2B2FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
44364436
9FA334C727C28D650064E8EA /* PlaybackControlsView.swift in Sources */,
44374437
4140EA8522728A160009F794 /* BookPlayer.xcdatamodeld in Sources */,
44384438
63CD851D2CE2964900EDBEA8 /* SettingsView.swift in Sources */,
@@ -4445,7 +4445,7 @@
44454445
files = (
44464446
9FC1E46D2815A8CA00522FA8 /* LibraryAPI.swift in Sources */,
44474447
99F3C20B2F62285800AC91A2 /* ApiResponse.swift in Sources */,
4448-
997C8D182FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
4448+
997C8D2A2FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
44494449
4140EA6C2272898F0009F794 /* DataManager.swift in Sources */,
44504450
4140EA71227289A20009F794 /* UIColor+BookPlayer.swift in Sources */,
44514451
99C919D02F99A8C100F66081 /* IntegrationDetailsViewModelProtocol.swift in Sources */,
@@ -4624,7 +4624,7 @@
46244624
416A29DA256AB6A900605395 /* BookPlayer.xcdatamodeld in Sources */,
46254625
630826112AF6CA44002ACE0D /* SharedIconWidget.swift in Sources */,
46264626
637DAB0B2AEB3F6D006DC2D1 /* WidgetEntries.swift in Sources */,
4627-
997C8D1D2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
4627+
997C8D282FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
46284628
418CABB625EF28FC00D8C878 /* MappingModel_v3_to_v4.xcmappingmodel in Sources */,
46294629
63E893932CAFA89000946CD4 /* BPPlayerError.swift in Sources */,
46304630
41ADD6DA2570AC6300660C64 /* RecentBooksWidgetView.swift in Sources */,
@@ -4715,7 +4715,7 @@
47154715
63C1A8B02B0915EE00C4B418 /* WidgetUtils.swift in Sources */,
47164716
41B2A5ED21CCC6D100917584 /* AppNavigationController.swift in Sources */,
47174717
9F22DE40288D8BC800056FCD /* BaseLabel.swift in Sources */,
4718-
997C8D1B2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
4718+
997C8D262FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
47194719
63B407432C1B0CC1000A3B19 /* StorySkipControlsView.swift in Sources */,
47204720
99329DD02F3C282D003F8E73 /* AirplayPicker.swift in Sources */,
47214721
6338C7932E4AA4BA008016E5 /* LibraryNode.swift in Sources */,
@@ -5080,7 +5080,7 @@
50805080
41A1B125226F88C500EA0400 /* LibraryItem+CoreDataClass.swift in Sources */,
50815081
62CADBA52725BCB200A4A98F /* AVAudioAssetImageDataProvider.swift in Sources */,
50825082
9FC1E4592814E0B000522FA8 /* NetworkUtils.swift in Sources */,
5083-
997C8D1A2FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
5083+
997C8D272FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
50845084
9911FBB52F72486D00DC9A2B /* ExternalUpdateProgressOperation.swift in Sources */,
50855085
992D6E192FA98C8F0091849F /* AudiobookShelfLibraryLevelData.swift in Sources */,
50865086
99D995892F719E7E00BAF216 /* (null) in Sources */,
@@ -5186,7 +5186,7 @@
51865186
630826012AF29538002ACE0D /* SharedWidgetEntry.swift in Sources */,
51875187
6340D5692AF12D48003D0B09 /* SharedWidget.swift in Sources */,
51885188
63005A2D2AE7FD8000A4CA2C /* Intents.intentdefinition in Sources */,
5189-
997C8D192FDB812900609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
5189+
997C8D292FDBCAA000609C01 /* MappingModel_v11_to_v12.xcmappingmodel in Sources */,
51905190
630825FE2AF293DC002ACE0D /* SharedWidgetContainerView.swift in Sources */,
51915191
630825FC2AF2923B002ACE0D /* WidgetUtils.swift in Sources */,
51925192
630826122AF6CA45002ACE0D /* SharedIconWidget.swift in Sources */,

BookPlayer/AudiobookShelf/Library Screen/AudiobookShelfLibraryViewModel.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ final class AudiobookShelfLibraryViewModel: IntegrationLibraryViewModelProtocol,
280280
providerId: item.id,
281281
syncStatus: ExternalResource.SyncStatus.stream.rawValue,
282282
lastSyncedAt: nil,
283-
host: connectionService.connection?.url.absoluteString,
284-
hostSession: connectionService.connection?.userName,
283+
hostId: connectionService.connection?.serverId ?? connectionService.connection?.url.absoluteString,
285284
libraryItem: libraryItem
286285
)
287286

BookPlayer/AudiobookShelf/Library Screen/Details/AudiobookShelfAudiobookDetailsViewModel.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ class AudiobookShelfAudiobookDetailsViewModel: IntegrationDetailsViewModelProtoc
109109
providerId: item.id,
110110
syncStatus: ExternalResource.SyncStatus.stream.rawValue,
111111
lastSyncedAt: nil,
112-
host: connectionService.connection?.url.absoluteString,
113-
hostSession: connectionService.connection?.userName,
112+
hostId: connectionService.connection?.serverId ?? connectionService.connection?.url.absoluteString,
114113
libraryItem: libraryItem
115114
)
116115

BookPlayer/Base.lproj/Localizable.strings

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,11 @@ We're working hard on providing a seamless experience, if possible, please conta
427427
"hours" = "Hours";
428428
"minutes" = "Minutes";
429429

430+
"provider_title" = "Provider";
431+
"provider_id_title" = "Item ID";
432+
"host_title" = "Host";
433+
"external_resources_title" = "External Resources";
434+
430435
// Passkey Authentication
431436
"passkey_unnamed_device" = "Unnamed Device";
432437
"passkey_delete_title" = "Delete Passkey";

BookPlayer/Jellyfin/Library Screen/Details/JellyfinAudiobookDetailsViewModel.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ class JellyfinAudiobookDetailsViewModel: IntegrationDetailsViewModelProtocol {
122122
providerId: item.id,
123123
syncStatus: ExternalResource.SyncStatus.stream.rawValue,
124124
lastSyncedAt: nil,
125-
host: connectionService.connection?.url.absoluteString,
126-
hostSession: connectionService.connection?.userName,
125+
hostId: connectionService.connection?.serverId ?? connectionService.connection?.url.absoluteString,
127126
libraryItem: libraryItem
128127
)
129128

BookPlayer/Jellyfin/Library Screen/JellyfinLibraryViewModel.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,7 @@ final class JellyfinLibraryViewModel: IntegrationLibraryViewModelProtocol, BPLog
414414
providerId: item.id,
415415
syncStatus: ExternalResource.SyncStatus.stream.rawValue,
416416
lastSyncedAt: nil,
417-
host: connectionService.connection?.url.absoluteString,
418-
hostSession: connectionService.connection?.userName,
417+
hostId: connectionService.connection?.serverId ?? connectionService.connection?.url.absoluteString,
419418
libraryItem: libraryItem
420419
)
421420

@@ -633,8 +632,7 @@ final class JellyfinAuthorBooksViewModel: IntegrationLibraryViewModelProtocol, B
633632
providerId: item.id,
634633
syncStatus: ExternalResource.SyncStatus.stream.rawValue,
635634
lastSyncedAt: nil,
636-
host: connectionService.connection?.url.absoluteString,
637-
hostSession: connectionService.connection?.userName,
635+
hostId: connectionService.connection?.serverId ?? connectionService.connection?.url.absoluteString,
638636
libraryItem: libraryItem
639637
)
640638

@@ -866,8 +864,7 @@ final class JellyfinNarratorBooksViewModel: IntegrationLibraryViewModelProtocol,
866864
providerId: item.id,
867865
syncStatus: ExternalResource.SyncStatus.stream.rawValue,
868866
lastSyncedAt: nil,
869-
host: connectionService.connection?.url.absoluteString,
870-
hostSession: connectionService.connection?.userName,
867+
hostId: connectionService.connection?.serverId ?? connectionService.connection?.url.absoluteString,
871868
libraryItem: libraryItem
872869
)
873870

BookPlayer/Library/ItemDetails/ItemDetailsView.swift

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ struct ItemDetailsView: View {
5353
progress: viewModel.progress,
5454
lastPlayedDate: viewModel.lastPlayedDate
5555
)
56+
57+
if let externalResources = viewModel.item.externalResources {
58+
ItemDetailsExternalResourceSectionView(externalResources: externalResources)
59+
}
5660
}
5761
.onChange(of: viewModel.selectedImage) {
5862
viewModel.artworkIsUpdated = true
@@ -128,3 +132,73 @@ struct ItemDetailsView: View {
128132
.applyListStyle(with: theme, background: theme.systemGroupedBackgroundColor)
129133
}
130134
}
135+
136+
struct ItemDetailsExternalResourceSectionView: View {
137+
let externalResources: [SimpleExternalResource]
138+
139+
@EnvironmentObject private var theme: ThemeViewModel
140+
141+
var body: some View {
142+
if !externalResources.isEmpty {
143+
ThemedSection {
144+
ForEach(externalResources) { resource in
145+
VStack(alignment: .leading, spacing: Spacing.S1) {
146+
HStack {
147+
Text("provider_title".localized)
148+
.bold()
149+
Spacer()
150+
Text(resource.providerName.capitalized)
151+
.lineLimit(1)
152+
}
153+
154+
HStack {
155+
Text("provider_id_title".localized)
156+
.bold()
157+
Spacer()
158+
Text(resource.providerId)
159+
.lineLimit(1)
160+
}
161+
162+
if let hostId = resource.hostId, !hostId.isEmpty {
163+
HStack {
164+
Text("host_title".localized)
165+
.bold()
166+
Spacer()
167+
Text(resolveHost(resource))
168+
.lineLimit(1)
169+
.truncationMode(.tail)
170+
}
171+
}
172+
}
173+
.bpFont(.body)
174+
.padding(.vertical, Spacing.S1)
175+
}
176+
} header: {
177+
Text("external_resources_title".localized)
178+
}
179+
}
180+
}
181+
182+
private func resolveHost(_ resource: SimpleExternalResource) -> String {
183+
let keychainService = KeychainService()
184+
let hostId = resource.hostId ?? ""
185+
186+
switch ExternalResource.ProviderName(rawValue: resource.providerName) {
187+
case .jellyfin:
188+
let connections: [JellyfinConnectionData] = (try? keychainService.get(.jellyfinConnection)) ?? []
189+
if let connection = connections.first(where: { $0.serverId == hostId || $0.url.absoluteString == hostId }) {
190+
return connection.url.absoluteString
191+
}
192+
case .audiobookshelf:
193+
let connections: [AudiobookShelfConnectionData] = (try? keychainService.get(.audiobookshelfConnection)) ?? []
194+
if let connection = connections.first(where: { $0.serverId == hostId || $0.url.absoluteString == hostId }) {
195+
return connection.url.absoluteString
196+
}
197+
default:
198+
break
199+
}
200+
201+
return hostId
202+
}
203+
}
204+

BookPlayer/Library/ItemList/LibraryRootView.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ struct LibraryRootView: View {
135135
self.handleOperationCompletion(.external(files: externalResources), suggestedFolderName: nil)
136136
}
137137
}
138+
.onReceive(NotificationCenter.default.publisher(for: .showMediaServers)) { _ in
139+
listState.activeIntegrationSheet = .mediaServers
140+
}
138141
}
139142
.tint(theme.linkColor)
140143
.environmentObject(theme)

BookPlayer/MediaServerIntegration/Library Screen/Details/IntegrationAudiobookDetailsView.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,7 @@ struct IntegrationAudiobookDetailsView<
7979
}
8080

8181
HStack(spacing: 12) {
82-
if allowStream {
83-
SynchronizeButton
84-
} else if showSubscribeButton {
82+
if allowStream || showSubscribeButton {
8583
SmallDownloadButton
8684
SynchronizeButton
8785
} else {
@@ -135,7 +133,7 @@ struct IntegrationAudiobookDetailsView<
135133
.applyListStyle(with: theme, background: theme.systemBackgroundColor)
136134
.tint(theme.linkColor)
137135
.errorAlert(error: $viewModel.error)
138-
.onAppear {
136+
.task(id: viewModel.item.id) {
139137
viewModel.fetchData()
140138
}
141139
.onDisappear {

0 commit comments

Comments
 (0)