From a0726b07a197ca3bab5bcc2b787656546d9e9334 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 20 Oct 2026 08:53:16 -0700 Subject: [PATCH] iOS 1.0.2: shuffle the whole library from Songs Shuffle used only the pages loaded so far (the A and B songs). It now asks Plex for 1000 random tracks from the whole library. Co-Authored-By: Claude Opus 5.5 --- ios/Stemify/Plex/PlexClient.swift | 5 +++++ ios/Stemify/UI/Screens/LibraryScreens.swift | 10 +++++++++- ios/project.yml | 4 ++-- ios/scripts/build-ipa.sh | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ios/Stemify/Plex/PlexClient.swift b/ios/Stemify/Plex/PlexClient.swift index 5a174be..9675541 100644 --- a/ios/Stemify/Plex/PlexClient.swift +++ b/ios/Stemify/Plex/PlexClient.swift @@ -132,6 +132,11 @@ final class PlexClient: @unchecked Sendable { return (c.metadata.map { $0.toTrack() }, c.totalSize ?? c.size) } + /// Random tracks from the whole library, for shuffling it without loading every page. + func randomTracks(_ count: Int) async throws -> [Track] { + try await get("/library/sections/\(section)/all", [("type", 10), ("sort", "random")], start: 0, size: count).metadata.map { $0.toTrack() } + } + func album(_ key: String) async throws -> Album? { try await get("/library/metadata/\(key)").metadata.first?.toAlbum() } diff --git a/ios/Stemify/UI/Screens/LibraryScreens.swift b/ios/Stemify/UI/Screens/LibraryScreens.swift index 37bffb7..9a991e6 100644 --- a/ios/Stemify/UI/Screens/LibraryScreens.swift +++ b/ios/Stemify/UI/Screens/LibraryScreens.swift @@ -235,6 +235,14 @@ struct SongsScreen: View { @State private var error: String? private var g: AppGraph { .shared } + /// Shuffles the whole library, not just the pages loaded so far. + private func shuffleAll() { + Task { + do { g.playback.playTracks(try await g.plex.randomTracks(1000), shuffle: true) } + catch { g.playback.report("Couldn't load songs: \(error.localizedDescription)") } + } + } + var body: some View { Page(title: "Songs") { if !tracks.isEmpty { @@ -242,7 +250,7 @@ struct SongsScreen: View { Text(songs(total)).font(.subheadline).foregroundStyle(p.label2).padding(.leading, MARGIN).padding(.bottom, 12) } PlayShuffle(play: { g.playback.playTracks(Array(tracks.prefix(1000))) }, - shuffle: { g.playback.playTracks(Array(tracks.prefix(1000)), shuffle: true) }) + shuffle: shuffleAll) .padding(.bottom, 12) } ForEach(Array(tracks.enumerated()), id: \.element.id) { i, t in diff --git a/ios/project.yml b/ios/project.yml index b851bd5..caff9ed 100644 --- a/ios/project.yml +++ b/ios/project.yml @@ -6,8 +6,8 @@ options: settings: base: SWIFT_VERSION: "5.0" - MARKETING_VERSION: "1.0.1" - CURRENT_PROJECT_VERSION: "2" + MARKETING_VERSION: "1.0.2" + CURRENT_PROJECT_VERSION: "3" targets: Stemify: type: application diff --git a/ios/scripts/build-ipa.sh b/ios/scripts/build-ipa.sh index 8dedc03..695c00e 100755 --- a/ios/scripts/build-ipa.sh +++ b/ios/scripts/build-ipa.sh @@ -14,7 +14,7 @@ xcrun -sdk iphoneos swiftc -target arm64-apple-ios17.0 -sdk "$SDK" -O -wmo -swif # Info.plist: xcodegen's generated one with the build settings filled in. xcodegen generate -q sed -e 's/$(DEVELOPMENT_LANGUAGE)/en/; s/$(EXECUTABLE_NAME)/Stemify/; s/$(PRODUCT_BUNDLE_IDENTIFIER)/com.stemify.mobile/' \ - -e 's/$(PRODUCT_NAME)/Stemify/; s/$(MARKETING_VERSION)/1.0.1/; s/$(CURRENT_PROJECT_VERSION)/2/' \ + -e 's/$(PRODUCT_NAME)/Stemify/; s/$(MARKETING_VERSION)/1.0.2/; s/$(CURRENT_PROJECT_VERSION)/3/' \ -e 's/$(PRODUCT_MODULE_NAME)/Stemify/' Stemify/Info.plist > $APP/Info.plist P=$APP/Info.plist plutil -insert MinimumOSVersion -string 17.0 $P