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
54 changes: 36 additions & 18 deletions BookPlayer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,9 @@
63B760F72C32734000AA98C7 /* SecondOnboardingResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B760F62C32734000AA98C7 /* SecondOnboardingResponse.swift */; };
63B760F92C32738E00AA98C7 /* StoryAccountSubscriptionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B760F82C32738E00AA98C7 /* StoryAccountSubscriptionService.swift */; };
63B760FC2C33B77F00AA98C7 /* SupportProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B760FB2C33B77F00AA98C7 /* SupportProfileView.swift */; };
63B9149E2EE47951000918D8 /* AppEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B9149C2EE47951000918D8 /* AppEnvironment.swift */; };
63B9149F2EE47951000918D8 /* AppEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B9149C2EE47951000918D8 /* AppEnvironment.swift */; };
63B914A12EE49079000918D8 /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B914A02EE49079000918D8 /* NetworkMonitor.swift */; };
63B9EFA82E9A4230002361A0 /* PlayerControlsBoostVolumeSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B9EFA72E9A4230002361A0 /* PlayerControlsBoostVolumeSectionView.swift */; };
63B9EFAA2E9A4644002361A0 /* PlayerControlsSpeedSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B9EFA92E9A4644002361A0 /* PlayerControlsSpeedSectionView.swift */; };
63C1A8B02B0915EE00C4B418 /* WidgetUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 418445C2258AE11E0072DD13 /* WidgetUtils.swift */; };
Expand Down Expand Up @@ -1456,6 +1459,8 @@
63B760F62C32734000AA98C7 /* SecondOnboardingResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondOnboardingResponse.swift; sourceTree = "<group>"; };
63B760F82C32738E00AA98C7 /* StoryAccountSubscriptionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryAccountSubscriptionService.swift; sourceTree = "<group>"; };
63B760FB2C33B77F00AA98C7 /* SupportProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportProfileView.swift; sourceTree = "<group>"; };
63B9149C2EE47951000918D8 /* AppEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppEnvironment.swift; sourceTree = "<group>"; };
63B914A02EE49079000918D8 /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = "<group>"; };
63B9EFA72E9A4230002361A0 /* PlayerControlsBoostVolumeSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerControlsBoostVolumeSectionView.swift; sourceTree = "<group>"; };
63B9EFA92E9A4644002361A0 /* PlayerControlsSpeedSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerControlsSpeedSectionView.swift; sourceTree = "<group>"; };
63C48C792E3DAC9D005FBB96 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2135,6 +2140,7 @@
638352C92E67F327009EE79E /* SwiftData */,
6279361B272CDA8A0097837D /* Artwork */,
41A1B106226E9DCA00EA0400 /* Extensions */,
63B9149D2EE47951000918D8 /* Utils */,
41A8941F2652A5DE0032E972 /* Configuration.swift */,
D367F7671FA2A6F000FEDB37 /* Constants.swift */,
4140EA1E22723CFC0009F794 /* CommandParser.swift */,
Expand Down Expand Up @@ -2812,6 +2818,14 @@
path = RemoteItemList;
sourceTree = "<group>";
};
63B9149D2EE47951000918D8 /* Utils */ = {
isa = PBXGroup;
children = (
63B9149C2EE47951000918D8 /* AppEnvironment.swift */,
);
path = Utils;
sourceTree = "<group>";
};
63C6C2E42B50299D00FFE0D8 /* Autolock */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3278,6 +3292,7 @@
8ADD46212CF29A02002E9C50 /* TextFieldFocused.swift */,
63C48C832E3E66D1005FBB96 /* PurchasesManager.swift */,
63344BFF2EA708F800B90DF7 /* BackupDatabaseOperation.swift */,
63B914A02EE49079000918D8 /* NetworkMonitor.swift */,
);
path = Utils;
sourceTree = "<group>";
Expand Down Expand Up @@ -4113,6 +4128,7 @@
41EB07162752F17B00EFEE13 /* PlayableItem.swift in Sources */,
4140EA84227289E60009F794 /* BookPlayer.xcdatamodeld in Sources */,
412AB70A2701421600969618 /* ManualOrderMigrationUtils.swift in Sources */,
63B9149E2EE47951000918D8 /* AppEnvironment.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -4199,6 +4215,7 @@
63C48C842E3E66D1005FBB96 /* PurchasesManager.swift in Sources */,
8ADD46222CF29A02002E9C50 /* TextFieldFocused.swift in Sources */,
63C48C7E2E3DB24A005FBB96 /* LoginDisclaimerSectionView.swift in Sources */,
63B914A12EE49079000918D8 /* NetworkMonitor.swift in Sources */,
9F22DE39288CBE6A00056FCD /* FormButton.swift in Sources */,
63B4A3BE2E9187B800784A22 /* ItemListView+ConfirmationDialogs.swift in Sources */,
4151A6A826E48C3400E49DBE /* Storyboarded.swift in Sources */,
Expand Down Expand Up @@ -4529,6 +4546,7 @@
9F2DC9E52A014BB5006CDF1F /* PricingModel.swift in Sources */,
41A1B126226F88C500EA0400 /* LibraryItem+CoreDataProperties.swift in Sources */,
6327E0C62ADB9913004780DC /* DownloadState.swift in Sources */,
63B9149F2EE47951000918D8 /* AppEnvironment.swift in Sources */,
63C6C3192B5E102200FFE0D8 /* SyncTask.swift in Sources */,
3FF5BA662E10EA6F00B82BCC /* HardcoverBook+CoreDataProperties.swift in Sources */,
62CADBAB2725C23A00A4A98F /* ArtworkService.swift in Sources */,
Expand Down Expand Up @@ -4876,7 +4894,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerIntents";
Expand Down Expand Up @@ -4910,7 +4928,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerIntents";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -4942,7 +4960,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerIntents";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -4979,7 +4997,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp";
Expand Down Expand Up @@ -5021,7 +5039,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -5060,7 +5078,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -5229,7 +5247,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerWidgetUI";
Expand Down Expand Up @@ -5267,7 +5285,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerWidgetUI";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -5303,7 +5321,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerWidgetUI";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -5457,7 +5475,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = BookPlayer;
PROVISIONING_PROFILE_SPECIFIER = "$(BP_PROVISIONING_MAIN)";
Expand Down Expand Up @@ -5496,7 +5514,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = BookPlayer;
PROVISIONING_PROFILE_SPECIFIER = "$(BP_PROVISIONING_MAIN)";
Expand Down Expand Up @@ -5718,7 +5736,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp.widgets";
Expand Down Expand Up @@ -5756,7 +5774,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp.widgets";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -5792,7 +5810,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp.widgets";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -5831,7 +5849,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerShareExtension";
Expand Down Expand Up @@ -5871,7 +5889,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerShareExtension";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -5909,7 +5927,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerShareExtension";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -6002,7 +6020,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.15.1;
MARKETING_VERSION = 5.15.2;
PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = BookPlayer;
PROVISIONING_PROFILE_SPECIFIER = "$(BP_PROVISIONING_MAIN)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct AudiobookShelfLibraryView<Model: AudiobookShelfLibraryViewModelProtocol>:
}
Section {
Picker(selection: $viewModel.sortBy, label: Text("Sort by".localized)) {
Text("Recently Added".localized).tag(AudiobookShelfLayout.SortBy.recent)
Label("sort_most_recent_button", systemImage: "clock").tag(AudiobookShelfLayout.SortBy.recent)
Label("Title".localized, systemImage: "textformat.abc").tag(AudiobookShelfLayout.SortBy.title)
}
}
Expand Down
1 change: 1 addition & 0 deletions BookPlayer/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,4 @@ We're working hard on providing a seamless experience, if possible, please conta
"database_restore_failed_message" = "The database is corrupted and the backup restoration failed. The library will need to be reset and rebuilt from your audio files.";
"database_no_backup_message" = "The database is corrupted and no backup is available. The library will need to be reset and rebuilt from your audio files.";
"settings_smartrewind_max_interval_title" = "Smart Rewind Limit";
"settings_support_discord_title" = "Join our Discord server";
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ struct JellyfinLibraryView<Model: JellyfinLibraryViewModelProtocol>: View {
Section {
Picker(selection: $viewModel.sortBy, label: Text("Sort by".localized)) {
Text("Default".localized).tag(JellyfinLayout.SortBy.smart)
Label("sort_most_recent_button", systemImage: "clock").tag(JellyfinLayout.SortBy.recent)
Label("Name".localized, systemImage: "textformat.abc").tag(JellyfinLayout.SortBy.name)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ enum JellyfinLayout {
}

enum SortBy: String {
case name, smart
case recent, name, smart
}
}

Expand Down
8 changes: 7 additions & 1 deletion BookPlayer/Jellyfin/Network/JellyfinConnectionService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,24 @@ class JellyfinConnectionService: BPLogger {
sortBy: JellyfinLayout.SortBy
) async throws -> (items: [JellyfinLibraryItem], nextStartIndex: Int, maxCountItems: Int) {
let orderBy: [JellyfinAPI.ItemSortBy]
let sortOrder: [JellyfinAPI.SortOrder]
switch sortBy {
case .recent:
orderBy = [.dateCreated]
sortOrder = [.descending]
case .name:
orderBy = [.name]
sortOrder = [.ascending]
case .smart:
orderBy = [.isFolder, .sortName]
sortOrder = [.ascending]
}

let parameters = Paths.GetItemsParameters(
startIndex: startIndex,
limit: limit,
isRecursive: false,
sortOrder: [.ascending],
sortOrder: sortOrder,
parentID: folderID,
fields: [.sortName],
includeItemTypes: [.audioBook, .folder],
Expand Down
4 changes: 2 additions & 2 deletions BookPlayer/Library/ItemDetails/ItemDetailsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ final class ItemDetailsViewModel: ObservableObject {
@Published var originalFileName: String
/// Title of the item
@Published var title: String
/// Author of the item (only applies for books)
/// Author of the item (applies for books and volumes)
@Published var author: String
/// Artwork image
@Published var selectedImage: UIImage?
Expand All @@ -53,7 +53,7 @@ final class ItemDetailsViewModel: ObservableObject {
/// Determines if there's an update for the artwork
var artworkIsUpdated: Bool = false
/// Flag to show the author field
var showAuthor: Bool { item.type == .book }
var showAuthor: Bool { item.type != .folder }

@Published var hardcoverSectionViewModel: ItemDetailsHardcoverSectionView.Model?

Expand Down
1 change: 0 additions & 1 deletion BookPlayer/Library/ItemList/ItemListView+Alerts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ extension ItemListView {

@ViewBuilder
func queuedTasksAlert() -> some View {
Text("sync_tasks_inprogress_alert_title")
Button("sync_tasks_view_title") {
activeSheet = .queuedTasks
}
Expand Down
3 changes: 2 additions & 1 deletion BookPlayer/Profile/Profile/QueuedSyncTasksView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct QueuedSyncTasksView: View {
@State private var queuedJobs = [SyncTaskReference]()
@State private var jobsCount = 0
@State private var showInfoAlert = false
@State private var networkMonitor = NetworkMonitor()

@Environment(\.syncService) private var syncService
@EnvironmentObject private var theme: ThemeViewModel
Expand All @@ -30,7 +31,7 @@ struct QueuedSyncTasksView: View {
)
}
} header: {
if !allowsCellularData {
if !allowsCellularData && !networkMonitor.isConnectedViaWiFi {
HStack {
Spacer()
Image(systemName: "wifi")
Expand Down
22 changes: 22 additions & 0 deletions BookPlayer/SecondOnboarding/Support/Tips/TipJarViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ public final class TipJarViewModel: ObservableObject {

@MainActor
func donate(_ tip: TipOption) async {
guard AppEnvironment.isPurchaseEnabled else {
onTransition?(
.showAlert(
BPAlertContent.errorAlert(
message: PurchaseError.testFlightPurchasesDisabled.errorDescription!
)
)
)
return
}

onTransition?(.showLoader(true))
do {
let product = await Purchases.shared.products([tip.rawValue]).first!
Expand All @@ -66,6 +77,17 @@ public final class TipJarViewModel: ObservableObject {

@MainActor
func restorePurchases() async {
guard AppEnvironment.isPurchaseEnabled else {
onTransition?(
.showAlert(
BPAlertContent.errorAlert(
message: PurchaseError.testFlightPurchasesDisabled.errorDescription!
)
)
)
return
}

onTransition?(.showLoader(true))
do {
let customerInfo = try await Purchases.shared.restorePurchases()
Expand Down
11 changes: 10 additions & 1 deletion BookPlayer/Settings/Sections/DebugFileTransferable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ struct DebugFileTransferable: Transferable {

var remoteIdentifiers: [String]?
var syncJobsInformation: String?
var syncError: String?

if syncService.isActive {
remoteIdentifiers = try await syncService.fetchSyncedIdentifiers()
do {
remoteIdentifiers = try await syncService.fetchSyncedIdentifiers()
} catch {
syncError = "Error fetching remote identifiers: \(error.localizedDescription)"
}
syncJobsInformation = await file.getSyncOperationsInformation()
}

Expand All @@ -43,6 +48,10 @@ struct DebugFileTransferable: Transferable {
libraryRepresentation += syncJobsInformation
}

if let syncError {
libraryRepresentation += "\n\n⚠️ Sync Error:\n\(syncError)\n"
}

return libraryRepresentation.data(using: .utf8)!
}
.suggestedFileName { _ in
Expand Down
Loading