Migrate Swift Language Mode From V5 To V6
This commit is contained in:
parent
7c0a0d481f
commit
45cbfb418b
18 changed files with 103 additions and 103 deletions
|
|
@ -85,5 +85,5 @@ let package = Package(
|
|||
plugins: [.plugin(name: "GenerateLocalized", package: "localized")]
|
||||
),
|
||||
],
|
||||
swiftLanguageModes: [.v5]
|
||||
swiftLanguageModes: [.v6]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/14/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
import LuminateDI
|
||||
|
|
@ -15,16 +15,21 @@ import LuminateUI
|
|||
@main
|
||||
struct Luminate: App {
|
||||
|
||||
let app = AdwaitaApp(id: "dev.bscubed.Luminate")
|
||||
@State private var client: JellyfinClient?
|
||||
@State private var userId = ""
|
||||
@State private var isLaunchLoading = true
|
||||
nonisolated(unsafe) let app = AdwaitaApp(id: "dev.bscubed.Luminate")
|
||||
@State private nonisolated(unsafe) var client: JellyfinClient?
|
||||
@State private nonisolated(unsafe) var userId = ""
|
||||
@State private nonisolated(unsafe) var isLaunchLoading = true
|
||||
|
||||
init() {
|
||||
Task { @MainActor in
|
||||
ObservationRegistrar.onChange = { StateManager.updateViews() }
|
||||
if let store = try? SQLiteStore(dbURL: SQLiteStore.defaultDatabaseURL()) {
|
||||
}
|
||||
let dbURL = SQLiteStore.defaultDatabaseURL()
|
||||
Task { [dbURL] in
|
||||
if let store = try? await SQLiteStore(dbURL: dbURL) {
|
||||
DIContainer.shared.register(\.persistence, value: store)
|
||||
}
|
||||
}
|
||||
DIContainer.shared.register(\.imageService, value: ImageService())
|
||||
DIContainer.shared.register(\.pageAnimationTracker, value: PageAnimationTracker())
|
||||
}
|
||||
|
|
@ -63,11 +68,11 @@ struct Luminate: App {
|
|||
}
|
||||
|
||||
private func loadSavedSession() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
do {
|
||||
defer { isLaunchLoading = false }
|
||||
|
||||
let store = try SQLiteStore(dbURL: SQLiteStore.defaultDatabaseURL())
|
||||
let store = try await SQLiteStore(dbURL: SQLiteStore.defaultDatabaseURL())
|
||||
let auth = try await store.loadAuth()
|
||||
guard let serverURL = URL(string: auth.serverURL) else { return }
|
||||
|
||||
|
|
@ -92,7 +97,7 @@ struct ContentView: View {
|
|||
|
||||
var client: JellyfinClient
|
||||
var userId: String
|
||||
@State var stack: NavigationStack<Page> = .init()
|
||||
@State nonisolated(unsafe) var stack: NavigationStack<Page> = .init()
|
||||
@Injected(\.pageAnimationTracker) var pageAnimationTracker
|
||||
|
||||
var view: Body {
|
||||
|
|
|
|||
|
|
@ -5,26 +5,26 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import LuminateCore
|
||||
import LuminateDI
|
||||
import LuminateUI
|
||||
|
||||
public struct HomeView: View {
|
||||
|
||||
nonisolated public init(navigation: Binding<NavigationStack<Page>>) {
|
||||
public init(navigation: Binding<NavigationStack<Page>>) {
|
||||
_navigation = navigation
|
||||
}
|
||||
|
||||
@Injected(\.client) var client
|
||||
@Injected(\.userId) var userId
|
||||
@Binding var navigation: NavigationStack<Page>
|
||||
@State private var resumeItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private var nextUpItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private var latestItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private var libraries: [Components.Schemas.BaseItemDto] = []
|
||||
@State private var isLoading = true
|
||||
@State private var isLoadingData = false
|
||||
@Binding nonisolated(unsafe) var navigation: NavigationStack<Page>
|
||||
@State private nonisolated(unsafe) var resumeItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var nextUpItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var latestItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var libraries: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var isLoading = true
|
||||
@State private nonisolated(unsafe) var isLoadingData = false
|
||||
|
||||
public var view: Body {
|
||||
ScrollView {
|
||||
|
|
@ -96,7 +96,7 @@ public struct HomeView: View {
|
|||
}
|
||||
|
||||
private func loadHomeData() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
async let resume = client.getItems(
|
||||
userId: userId,
|
||||
filters: [.isResumable],
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import LuminateUI
|
|||
|
||||
public struct LibraryPage: View {
|
||||
|
||||
nonisolated public init(
|
||||
public init(
|
||||
title: String, items: [Components.Schemas.BaseItemDto],
|
||||
navigation: Binding<NavigationStack<Page>>
|
||||
) {
|
||||
|
|
@ -22,7 +22,7 @@ public struct LibraryPage: View {
|
|||
|
||||
private var items: [Components.Schemas.BaseItemDto]
|
||||
private var title: String
|
||||
@Binding var navigation: NavigationStack<Page>
|
||||
@Binding nonisolated(unsafe) var navigation: NavigationStack<Page>
|
||||
|
||||
public var view: Body {
|
||||
ScrollView {
|
||||
|
|
|
|||
|
|
@ -5,21 +5,21 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
import LuminateDI
|
||||
|
||||
public struct ServerSetupView: View {
|
||||
|
||||
@State private var serverURL = ""
|
||||
@State private var username = ""
|
||||
@State private var password = ""
|
||||
@State private var isLoading = false
|
||||
@State private var error: String?
|
||||
public var onLogin: (JellyfinClient, String) -> Void
|
||||
@State private nonisolated(unsafe) var serverURL = ""
|
||||
@State private nonisolated(unsafe) var username = ""
|
||||
@State private nonisolated(unsafe) var password = ""
|
||||
@State private nonisolated(unsafe) var isLoading = false
|
||||
@State private nonisolated(unsafe) var error: String?
|
||||
public var onLogin: @Sendable (JellyfinClient, String) -> Void
|
||||
|
||||
public init(onLogin: @escaping (JellyfinClient, String) -> Void) {
|
||||
public init(onLogin: @escaping @Sendable (JellyfinClient, String) -> Void) {
|
||||
self.onLogin = onLogin
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ public struct ServerSetupView: View {
|
|||
}
|
||||
isLoading = true
|
||||
error = nil
|
||||
Task {
|
||||
Task { [self] in
|
||||
do {
|
||||
let client = JellyfinClient(serverURL: url)
|
||||
let result = try await client.authenticate(username: username, password: password)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import Foundation
|
|||
/// ```swift
|
||||
/// ObservationRegistrar.onChange = { StateManager.updateViews() }
|
||||
/// ```
|
||||
@MainActor
|
||||
public class ObservationRegistrar {
|
||||
|
||||
/// Global callback invoked when any tracked property changes.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public actor SQLiteStore: PersistenceService {
|
|||
|
||||
private let db: Connection
|
||||
|
||||
public init(dbURL: URL) throws {
|
||||
public init(dbURL: URL) async throws {
|
||||
let directory = dbURL.deletingLastPathComponent()
|
||||
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
||||
db = try Connection(dbURL.path)
|
||||
|
|
@ -23,7 +23,7 @@ public actor SQLiteStore: PersistenceService {
|
|||
try migrate()
|
||||
}
|
||||
|
||||
private func migrate() throws {
|
||||
private nonisolated func migrate() throws {
|
||||
let version = db.userVersion
|
||||
switch version {
|
||||
case 0:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public struct Injected<T> {
|
|||
}
|
||||
}
|
||||
|
||||
private final class ObserverRef {
|
||||
private final class ObserverRef: @unchecked Sendable {
|
||||
let id: UUID
|
||||
init(id: UUID) { self.id = id }
|
||||
deinit { DIContainer.shared.removeObserver(id) }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
|
||||
|
|
@ -17,11 +17,11 @@ public struct PlayerView: View {
|
|||
public var mediaSourceId: String
|
||||
public var playSessionId: String
|
||||
public var streamURL: URL
|
||||
@State private var isPlaying = true
|
||||
@State private var position: Double = 0
|
||||
@State private var duration: Double = 0
|
||||
@State private var showControls = true
|
||||
public var onClose: () -> Void
|
||||
@State private nonisolated(unsafe) var isPlaying = true
|
||||
@State private nonisolated(unsafe) var position: Double = 0
|
||||
@State private nonisolated(unsafe) var duration: Double = 0
|
||||
@State private nonisolated(unsafe) var showControls = true
|
||||
public var onClose: @Sendable () -> Void
|
||||
|
||||
public init(
|
||||
item: Components.Schemas.BaseItemDto,
|
||||
|
|
@ -30,7 +30,7 @@ public struct PlayerView: View {
|
|||
mediaSourceId: String,
|
||||
playSessionId: String,
|
||||
streamURL: URL,
|
||||
onClose: @escaping () -> Void
|
||||
onClose: @escaping @Sendable () -> Void
|
||||
) {
|
||||
self.item = item
|
||||
self.client = client
|
||||
|
|
@ -70,7 +70,7 @@ public struct PlayerView: View {
|
|||
}
|
||||
|
||||
private func startPlayback() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
try? await client.reportPlaybackStart(
|
||||
info: .init(
|
||||
itemId: item.id,
|
||||
|
|
@ -82,7 +82,7 @@ public struct PlayerView: View {
|
|||
}
|
||||
|
||||
private func stopPlayback() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
try? await client.reportPlaybackStopped(
|
||||
info: .init(
|
||||
itemId: item.id,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ struct EpisodeList: View {
|
|||
var seasonId: String
|
||||
var client: JellyfinClient
|
||||
var userId: String
|
||||
@State private var episodes: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var episodes: [Components.Schemas.BaseItemDto] = []
|
||||
|
||||
var view: Body {
|
||||
VStack {
|
||||
|
|
@ -32,13 +32,13 @@ struct EpisodeList: View {
|
|||
}
|
||||
|
||||
private func loadEpisodes() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
let result = try? await client.getEpisodes(
|
||||
seriesId: seriesId,
|
||||
userId: userId,
|
||||
seasonId: seasonId
|
||||
)
|
||||
await MainActor.run { episodes = result?.items ?? [] }
|
||||
episodes = result?.items ?? []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ struct EpisodeRow: View {
|
|||
|
||||
var episode: Components.Schemas.BaseItemDto
|
||||
var client: JellyfinClient
|
||||
@State private var imageData: Data?
|
||||
@State private nonisolated(unsafe) var imageData: Data?
|
||||
|
||||
var view: Body {
|
||||
HStack {
|
||||
|
|
@ -89,7 +89,7 @@ struct EpisodeRow: View {
|
|||
guard let tag = episode.primaryImageTag, let itemId = episode.id else {
|
||||
return
|
||||
}
|
||||
Task {
|
||||
Task { [self] in
|
||||
guard
|
||||
let url = await client.imageURL(
|
||||
itemId: itemId,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
import LuminateDI
|
||||
|
|
@ -15,7 +15,7 @@ struct HomePosterCell: View {
|
|||
var item: Components.Schemas.BaseItemDto
|
||||
@Injected(\.client) var client
|
||||
@Injected(\.pageAnimationTracker) var pageAnimationTracker
|
||||
@State private var imageData: Data?
|
||||
@State private nonisolated(unsafe) var imageData: Data?
|
||||
|
||||
var view: Body {
|
||||
VStack {
|
||||
|
|
@ -67,7 +67,7 @@ struct HomePosterCell: View {
|
|||
guard let tag = item.primaryImageTag,
|
||||
let itemId = item.seriesId ?? item.id
|
||||
else { return }
|
||||
Task {
|
||||
Task { [self] in
|
||||
guard
|
||||
let url = await client.imageURL(
|
||||
itemId: itemId,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import LuminateCore
|
||||
|
||||
public struct ItemGrid: View {
|
||||
|
|
@ -15,8 +15,8 @@ public struct ItemGrid: View {
|
|||
var parentId: String?
|
||||
var includeItemTypes: [Components.Schemas.BaseItemKind]?
|
||||
var title: String?
|
||||
@State private var items: [Components.Schemas.BaseItemDto] = []
|
||||
@State private var isLoading = false
|
||||
@State private nonisolated(unsafe) var items: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var isLoading = false
|
||||
private let pageSize: Int32 = 50
|
||||
|
||||
public init(
|
||||
|
|
@ -58,7 +58,7 @@ public struct ItemGrid: View {
|
|||
|
||||
private func loadItems() {
|
||||
isLoading = true
|
||||
Task {
|
||||
Task { [self] in
|
||||
do {
|
||||
let result = try await client.getItems(
|
||||
userId: userId,
|
||||
|
|
@ -71,12 +71,10 @@ public struct ItemGrid: View {
|
|||
limit: pageSize,
|
||||
recursive: true
|
||||
)
|
||||
await MainActor.run {
|
||||
items = result.items ?? []
|
||||
isLoading = false
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run { isLoading = false }
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import LuminateCore
|
|||
public struct LibraryGrid: View {
|
||||
|
||||
public var libraries: [Components.Schemas.BaseItemDto]
|
||||
@Binding public var navigation: NavigationStack<Page>
|
||||
@Binding public nonisolated(unsafe) var navigation: NavigationStack<Page>
|
||||
public var title: String?
|
||||
|
||||
public init(
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ public struct MediaRow: View {
|
|||
|
||||
public var title: String
|
||||
public var items: [Components.Schemas.BaseItemDto]
|
||||
@Binding public var navigation: NavigationStack<Page>
|
||||
public var onSeeAll: (() -> Void)?
|
||||
@Binding public nonisolated(unsafe) var navigation: NavigationStack<Page>
|
||||
public var onSeeAll: (@Sendable () -> Void)?
|
||||
|
||||
public init(
|
||||
title: String,
|
||||
items: [Components.Schemas.BaseItemDto],
|
||||
navigation: Binding<NavigationStack<Page>>,
|
||||
onSeeAll: (() -> Void)? = nil
|
||||
onSeeAll: (@Sendable () -> Void)? = nil
|
||||
) {
|
||||
self.title = title
|
||||
self.items = items
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
|
||||
|
|
@ -14,10 +14,10 @@ struct MovieDetailView: View {
|
|||
var item: Components.Schemas.BaseItemDto
|
||||
var client: JellyfinClient
|
||||
var userId: String
|
||||
@State private var isFavorite: Bool
|
||||
@State private var isPlayed: Bool
|
||||
@State private var similarItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private var backdropData: Data?
|
||||
@State private nonisolated(unsafe) var isFavorite: Bool
|
||||
@State private nonisolated(unsafe) var isPlayed: Bool
|
||||
@State private nonisolated(unsafe) var similarItems: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var backdropData: Data?
|
||||
|
||||
init(item: Components.Schemas.BaseItemDto, client: JellyfinClient, userId: String) {
|
||||
self.item = item
|
||||
|
|
@ -115,7 +115,7 @@ struct MovieDetailView: View {
|
|||
|
||||
private func loadBackdrop() {
|
||||
guard let tag = item.backdropImageTag, let itemId = item.id else { return }
|
||||
Task {
|
||||
Task { [self] in
|
||||
guard
|
||||
let url = await client.imageURL(
|
||||
itemId: itemId, imageType: .backdrop, tag: tag, maxWidth: 1920
|
||||
|
|
@ -127,7 +127,7 @@ struct MovieDetailView: View {
|
|||
}
|
||||
|
||||
private func loadSimilar() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
let result = try? await client.getItems(
|
||||
userId: userId,
|
||||
includeItemTypes: [.movie],
|
||||
|
|
@ -136,29 +136,29 @@ struct MovieDetailView: View {
|
|||
limit: 10,
|
||||
recursive: true
|
||||
)
|
||||
await MainActor.run { similarItems = result?.items ?? [] }
|
||||
similarItems = result?.items ?? []
|
||||
}
|
||||
}
|
||||
|
||||
private func toggleFavorite() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
if isFavorite {
|
||||
try? await client.unmarkFavoriteItem(itemId: item.id ?? "", userId: userId)
|
||||
} else {
|
||||
try? await client.markFavoriteItem(itemId: item.id ?? "", userId: userId)
|
||||
}
|
||||
await MainActor.run { isFavorite.toggle() }
|
||||
isFavorite.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
private func togglePlayed() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
if isPlayed {
|
||||
try? await client.markUnplayedItem(itemId: item.id ?? "", userId: userId)
|
||||
} else {
|
||||
try? await client.markPlayedItem(itemId: item.id ?? "", userId: userId)
|
||||
}
|
||||
await MainActor.run { isPlayed.toggle() }
|
||||
isPlayed.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
import LuminateDI
|
||||
|
|
@ -15,7 +15,7 @@ struct PosterCell: View {
|
|||
var item: Components.Schemas.BaseItemDto
|
||||
var client: JellyfinClient
|
||||
@Injected(\.pageAnimationTracker) var pageAnimationTracker
|
||||
@State private var imageData: Data?
|
||||
@State private nonisolated(unsafe) var imageData: Data?
|
||||
|
||||
var view: Body {
|
||||
VStack {
|
||||
|
|
@ -46,7 +46,7 @@ struct PosterCell: View {
|
|||
guard let tag = item.primaryImageTag,
|
||||
let itemId = item.id
|
||||
else { return }
|
||||
Task {
|
||||
Task { [self] in
|
||||
let url = await client.imageURL(
|
||||
itemId: itemId,
|
||||
imageType: .primary,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
import LuminateDI
|
||||
|
|
@ -14,9 +14,9 @@ struct SearchView: View {
|
|||
|
||||
var client: JellyfinClient
|
||||
var userId: String
|
||||
@State private var searchText = ""
|
||||
@State private var results: [Components.Schemas.SearchHint] = []
|
||||
@State private var isSearching = false
|
||||
@State private nonisolated(unsafe) var searchText = ""
|
||||
@State private nonisolated(unsafe) var results: [Components.Schemas.SearchHint] = []
|
||||
@State private nonisolated(unsafe) var isSearching = false
|
||||
|
||||
var view: Body {
|
||||
VStack {
|
||||
|
|
@ -45,18 +45,16 @@ struct SearchView: View {
|
|||
return
|
||||
}
|
||||
isSearching = true
|
||||
Task {
|
||||
Task { [self] in
|
||||
let result = try? await client.getSearchHints(
|
||||
searchTerm: searchText,
|
||||
userId: userId,
|
||||
limit: 50
|
||||
)
|
||||
await MainActor.run {
|
||||
results = result?.searchHints ?? []
|
||||
isSearching = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Components.Schemas.SearchHint: Identifiable {
|
||||
|
|
@ -68,7 +66,7 @@ struct SearchResultRow: View {
|
|||
var hint: Components.Schemas.SearchHint
|
||||
var client: JellyfinClient
|
||||
@Injected(\.pageAnimationTracker) var pageAnimationTracker
|
||||
@State private var imageData: Data?
|
||||
@State private nonisolated(unsafe) var imageData: Data?
|
||||
|
||||
var view: Body {
|
||||
HStack {
|
||||
|
|
@ -118,7 +116,7 @@ struct SearchResultRow: View {
|
|||
guard let tag = hint.primaryImageTag,
|
||||
let itemId = hint.id ?? hint.itemId
|
||||
else { return }
|
||||
Task {
|
||||
Task { [self] in
|
||||
guard
|
||||
let url = await client.imageURL(
|
||||
itemId: itemId, imageType: .primary, tag: tag, maxWidth: 160
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Brendan Szymanski on 6/5/26.
|
||||
//
|
||||
|
||||
import Adwaita
|
||||
@preconcurrency import Adwaita
|
||||
import Foundation
|
||||
import LuminateCore
|
||||
|
||||
|
|
@ -14,9 +14,9 @@ struct TVShowView: View {
|
|||
var item: Components.Schemas.BaseItemDto
|
||||
var client: JellyfinClient
|
||||
var userId: String
|
||||
@State private var seasons: [Components.Schemas.BaseItemDto] = []
|
||||
@State private var selectedSeasonId: String?
|
||||
@State private var backdropData: Data?
|
||||
@State private nonisolated(unsafe) var seasons: [Components.Schemas.BaseItemDto] = []
|
||||
@State private nonisolated(unsafe) var selectedSeasonId: String?
|
||||
@State private nonisolated(unsafe) var backdropData: Data?
|
||||
|
||||
var view: Body {
|
||||
ScrollView {
|
||||
|
|
@ -86,7 +86,7 @@ struct TVShowView: View {
|
|||
|
||||
private func loadBackdrop() {
|
||||
guard let tag = item.backdropImageTag, let itemId = item.id else { return }
|
||||
Task {
|
||||
Task { [self] in
|
||||
guard
|
||||
let url = await client.imageURL(
|
||||
itemId: itemId, imageType: .backdrop, tag: tag, maxWidth: 1920
|
||||
|
|
@ -98,12 +98,10 @@ struct TVShowView: View {
|
|||
}
|
||||
|
||||
private func loadSeasons() {
|
||||
Task {
|
||||
Task { [self] in
|
||||
let result = try? await client.getSeasons(seriesId: item.id ?? "", userId: userId)
|
||||
await MainActor.run {
|
||||
seasons = result?.items ?? []
|
||||
selectedSeasonId = seasons.first?.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue