add SeriesItemViewModel
This commit is contained in:
parent
3d22456968
commit
f8a70051ac
|
@ -129,6 +129,8 @@
|
||||||
62E632E7267D3F5B0063E547 /* EpisodeItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632E5267D3F5B0063E547 /* EpisodeItemViewModel.swift */; };
|
62E632E7267D3F5B0063E547 /* EpisodeItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632E5267D3F5B0063E547 /* EpisodeItemViewModel.swift */; };
|
||||||
62E632E9267D3FF50063E547 /* SeasonItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */; };
|
62E632E9267D3FF50063E547 /* SeasonItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */; };
|
||||||
62E632EA267D3FF50063E547 /* SeasonItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */; };
|
62E632EA267D3FF50063E547 /* SeasonItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */; };
|
||||||
|
62E632EC267D410B0063E547 /* SeriesItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632EB267D410B0063E547 /* SeriesItemViewModel.swift */; };
|
||||||
|
62E632ED267D410B0063E547 /* SeriesItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632EB267D410B0063E547 /* SeriesItemViewModel.swift */; };
|
||||||
62EC3527267665D8000E9F2D /* MobileVLCKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53D5E3DC264B47EE00BADDC8 /* MobileVLCKit.xcframework */; };
|
62EC3527267665D8000E9F2D /* MobileVLCKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53D5E3DC264B47EE00BADDC8 /* MobileVLCKit.xcframework */; };
|
||||||
62EC3528267665D8000E9F2D /* MobileVLCKit.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 53D5E3DC264B47EE00BADDC8 /* MobileVLCKit.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
62EC3528267665D8000E9F2D /* MobileVLCKit.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 53D5E3DC264B47EE00BADDC8 /* MobileVLCKit.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
62EC352C26766675000E9F2D /* ServerEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352B26766675000E9F2D /* ServerEnvironment.swift */; };
|
62EC352C26766675000E9F2D /* ServerEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352B26766675000E9F2D /* ServerEnvironment.swift */; };
|
||||||
|
@ -283,6 +285,7 @@
|
||||||
62E632E2267D3BA60063E547 /* MovieItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieItemViewModel.swift; sourceTree = "<group>"; };
|
62E632E2267D3BA60063E547 /* MovieItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieItemViewModel.swift; sourceTree = "<group>"; };
|
||||||
62E632E5267D3F5B0063E547 /* EpisodeItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EpisodeItemViewModel.swift; sourceTree = "<group>"; };
|
62E632E5267D3F5B0063E547 /* EpisodeItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EpisodeItemViewModel.swift; sourceTree = "<group>"; };
|
||||||
62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonItemViewModel.swift; sourceTree = "<group>"; };
|
62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonItemViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
62E632EB267D410B0063E547 /* SeriesItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeriesItemViewModel.swift; sourceTree = "<group>"; };
|
||||||
62EC352B26766675000E9F2D /* ServerEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerEnvironment.swift; sourceTree = "<group>"; };
|
62EC352B26766675000E9F2D /* ServerEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerEnvironment.swift; sourceTree = "<group>"; };
|
||||||
62EC352E267666A5000E9F2D /* SessionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManager.swift; sourceTree = "<group>"; };
|
62EC352E267666A5000E9F2D /* SessionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManager.swift; sourceTree = "<group>"; };
|
||||||
62EC353326766B03000E9F2D /* DeviceRotationViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRotationViewModifier.swift; sourceTree = "<group>"; };
|
62EC353326766B03000E9F2D /* DeviceRotationViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRotationViewModifier.swift; sourceTree = "<group>"; };
|
||||||
|
@ -350,6 +353,7 @@
|
||||||
62E632E2267D3BA60063E547 /* MovieItemViewModel.swift */,
|
62E632E2267D3BA60063E547 /* MovieItemViewModel.swift */,
|
||||||
62E632E5267D3F5B0063E547 /* EpisodeItemViewModel.swift */,
|
62E632E5267D3F5B0063E547 /* EpisodeItemViewModel.swift */,
|
||||||
62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */,
|
62E632E8267D3FF50063E547 /* SeasonItemViewModel.swift */,
|
||||||
|
62E632EB267D410B0063E547 /* SeriesItemViewModel.swift */,
|
||||||
);
|
);
|
||||||
path = ViewModels;
|
path = ViewModels;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -725,6 +729,7 @@
|
||||||
531690F7267ACC00005D8AB9 /* LandscapeItemElement.swift in Sources */,
|
531690F7267ACC00005D8AB9 /* LandscapeItemElement.swift in Sources */,
|
||||||
62E632E1267D30CA0063E547 /* LibraryViewModel.swift in Sources */,
|
62E632E1267D30CA0063E547 /* LibraryViewModel.swift in Sources */,
|
||||||
535870A82669D8AE00D05A09 /* StringExtensions.swift in Sources */,
|
535870A82669D8AE00D05A09 /* StringExtensions.swift in Sources */,
|
||||||
|
62E632ED267D410B0063E547 /* SeriesItemViewModel.swift in Sources */,
|
||||||
53ABFDE6267974EF00886593 /* SettingsViewModel.swift in Sources */,
|
53ABFDE6267974EF00886593 /* SettingsViewModel.swift in Sources */,
|
||||||
6267B3D826710B9800A7371D /* CollectionExtensions.swift in Sources */,
|
6267B3D826710B9800A7371D /* CollectionExtensions.swift in Sources */,
|
||||||
62E632E7267D3F5B0063E547 /* EpisodeItemViewModel.swift in Sources */,
|
62E632E7267D3F5B0063E547 /* EpisodeItemViewModel.swift in Sources */,
|
||||||
|
@ -760,6 +765,7 @@
|
||||||
5364F455266CA0DC0026ECBA /* APIExtensions.swift in Sources */,
|
5364F455266CA0DC0026ECBA /* APIExtensions.swift in Sources */,
|
||||||
621338932660107500A81A2A /* StringExtensions.swift in Sources */,
|
621338932660107500A81A2A /* StringExtensions.swift in Sources */,
|
||||||
53FF7F2A263CF3F500585C35 /* LatestMediaView.swift in Sources */,
|
53FF7F2A263CF3F500585C35 /* LatestMediaView.swift in Sources */,
|
||||||
|
62E632EC267D410B0063E547 /* SeriesItemViewModel.swift in Sources */,
|
||||||
625CB5732678C32A00530A6E /* HomeViewModel.swift in Sources */,
|
625CB5732678C32A00530A6E /* HomeViewModel.swift in Sources */,
|
||||||
62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */,
|
62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */,
|
||||||
5377CBFE263B596B003A4E83 /* PersistenceController.swift in Sources */,
|
5377CBFE263B596B003A4E83 /* PersistenceController.swift in Sources */,
|
||||||
|
|
|
@ -43,7 +43,7 @@ struct ItemView: View {
|
||||||
} else if item.type == "Season" {
|
} else if item.type == "Season" {
|
||||||
SeasonItemView(viewModel: .init(item: item))
|
SeasonItemView(viewModel: .init(item: item))
|
||||||
} else if item.type == "Series" {
|
} else if item.type == "Series" {
|
||||||
SeriesItemView(item: item)
|
SeriesItemView(viewModel: .init(item: item))
|
||||||
} else if item.type == "Episode" {
|
} else if item.type == "Episode" {
|
||||||
EpisodeItemView(viewModel: .init(item: item))
|
EpisodeItemView(viewModel: .init(item: item))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,54 +11,23 @@ import Combine
|
||||||
|
|
||||||
struct SeriesItemView: View {
|
struct SeriesItemView: View {
|
||||||
@StateObject
|
@StateObject
|
||||||
var tempViewModel = ViewModel()
|
var viewModel: SeriesItemViewModel
|
||||||
|
|
||||||
var item: BaseItemDto
|
@State
|
||||||
|
private var tracks: [GridItem] = Array(repeating: .init(.flexible()), count: Int(UIScreen.main.bounds.size.width) / 125)
|
||||||
|
|
||||||
@State private var seasons: [BaseItemDto] = []
|
|
||||||
@State private var isLoading: Bool = true
|
|
||||||
@State private var viewDidLoad: Bool = false
|
|
||||||
|
|
||||||
func onAppear() {
|
|
||||||
recalcTracks()
|
|
||||||
if viewDidLoad {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isLoading = true
|
|
||||||
|
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
|
||||||
TvShowsAPI.getSeasons(seriesId: item.id ?? "", fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people])
|
|
||||||
.sink(receiveCompletion: { completion in
|
|
||||||
print(completion)
|
|
||||||
}, receiveValue: { response in
|
|
||||||
isLoading = false
|
|
||||||
viewDidLoad = true
|
|
||||||
seasons = response.items ?? []
|
|
||||||
})
|
|
||||||
.store(in: &tempViewModel.cancellables)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Grid tracks
|
|
||||||
func recalcTracks() {
|
func recalcTracks() {
|
||||||
let trkCnt: Int = Int(floor(UIScreen.main.bounds.size.width / 125))
|
tracks = Array(repeating: .init(.flexible()), count: Int(UIScreen.main.bounds.size.width) / 125)
|
||||||
tracks = []
|
|
||||||
for _ in (0..<trkCnt) {
|
|
||||||
tracks.append(GridItem.init(.flexible()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@State private var tracks: [GridItem] = []
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if isLoading {
|
if viewModel.isLoading {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
.onAppear(perform: onAppear)
|
|
||||||
} else {
|
} else {
|
||||||
ScrollView(.vertical) {
|
ScrollView(.vertical) {
|
||||||
Spacer().frame(height: 16)
|
Spacer().frame(height: 16)
|
||||||
LazyVGrid(columns: tracks) {
|
LazyVGrid(columns: tracks) {
|
||||||
ForEach(seasons, id: \.id) { season in
|
ForEach(viewModel.seasons, id: \.id) { season in
|
||||||
NavigationLink(destination: ItemView(item: season)) {
|
NavigationLink(destination: ItemView(item: season)) {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
ImageView(src: season.getPrimaryImage(maxWidth: 100), bh: season.getPrimaryImageBlurHash())
|
ImageView(src: season.getPrimaryImage(maxWidth: 100), bh: season.getPrimaryImageBlurHash())
|
||||||
|
@ -85,7 +54,7 @@ struct SeriesItemView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.overrideViewPreference(.unspecified)
|
.overrideViewPreference(.unspecified)
|
||||||
.navigationTitle(item.name ?? "")
|
.navigationTitle(viewModel.item.name ?? "")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
* SwiftFin is subject to the terms of the Mozilla Public
|
||||||
|
* License, v2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* Copyright 2021 Aiden Vigue & Jellyfin Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
import JellyfinAPI
|
||||||
|
|
||||||
|
final class SeriesItemViewModel: ViewModel {
|
||||||
|
@Published
|
||||||
|
var item: BaseItemDto
|
||||||
|
|
||||||
|
@Published
|
||||||
|
var seasons = [BaseItemDto]()
|
||||||
|
|
||||||
|
init(item: BaseItemDto) {
|
||||||
|
self.item = item
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
func refresh() {
|
||||||
|
TvShowsAPI.getSeasons(seriesId: item.id ?? "", fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people])
|
||||||
|
.trackActivity(loading)
|
||||||
|
.sink(receiveCompletion: { [weak self] completion in
|
||||||
|
self?.HandleAPIRequestCompletion(completion: completion)
|
||||||
|
}, receiveValue: { [weak self] response in
|
||||||
|
self?.seasons = response.items ?? []
|
||||||
|
})
|
||||||
|
.store(in: &cancellables)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue