mirror of
https://github.com/jellyfin/Swiftfin.git
synced 2024-11-23 14:10:01 +00:00
iOS/iPadOS - Library List View (#542)
This commit is contained in:
parent
d078d71393
commit
3b755adf87
25
Shared/Objects/LibraryViewType.swift
Normal file
25
Shared/Objects/LibraryViewType.swift
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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 (c) 2022 Jellyfin & Jellyfin Contributors
|
||||
//
|
||||
|
||||
import Defaults
|
||||
import Foundation
|
||||
|
||||
enum LibraryViewType: String, CaseIterable, Defaults.Serializable {
|
||||
case grid
|
||||
case list
|
||||
|
||||
// TODO: localize after organization
|
||||
var localizedName: String {
|
||||
switch self {
|
||||
case .grid:
|
||||
return "Grid"
|
||||
case .list:
|
||||
return "List"
|
||||
}
|
||||
}
|
||||
}
|
@ -37,11 +37,15 @@ extension Defaults.Keys {
|
||||
static let latestInLibraryPosterType = Key<PosterType>("latestInLibraryPosterType", default: .portrait, suite: .generalSuite)
|
||||
static let recommendedPosterType = Key<PosterType>("recommendedPosterType", default: .portrait, suite: .generalSuite)
|
||||
static let searchPosterType = Key<PosterType>("searchPosterType", default: .portrait, suite: .generalSuite)
|
||||
static let libraryPosterType = Key<PosterType>("libraryPosterType", default: .portrait, suite: .generalSuite)
|
||||
|
||||
enum Episodes {
|
||||
static let useSeriesLandscapeBackdrop = Key<Bool>("useSeriesBackdrop", default: true, suite: .generalSuite)
|
||||
}
|
||||
|
||||
enum Library {
|
||||
static let viewType = Key<LibraryViewType>("Customization.Library.viewType", default: .grid, suite: .generalSuite)
|
||||
static let gridPosterType = Key<PosterType>("Customization.Library.gridPosterType", default: .portrait, suite: .generalSuite)
|
||||
}
|
||||
}
|
||||
|
||||
// Video player / overlay settings
|
||||
|
@ -13,8 +13,8 @@ import UIKit
|
||||
|
||||
final class LibraryViewModel: ViewModel {
|
||||
|
||||
@Default(.Customization.libraryPosterType)
|
||||
var libraryPosterType
|
||||
@Default(.Customization.Library.gridPosterType)
|
||||
var libraryGridPosterType
|
||||
|
||||
@Published
|
||||
var items: [BaseItemDto] = []
|
||||
@ -35,8 +35,8 @@ final class LibraryViewModel: ViewModel {
|
||||
var studio: NameGuidPair?
|
||||
|
||||
private var pageItemSize: Int {
|
||||
let height = libraryPosterType == .portrait ? libraryPosterType.width * 1.5 : libraryPosterType.width / 1.77
|
||||
return UIScreen.itemsFillableOnScreen(width: libraryPosterType.width, height: height)
|
||||
let height = libraryGridPosterType == .portrait ? libraryGridPosterType.width * 1.5 : libraryGridPosterType.width / 1.77
|
||||
return UIScreen.itemsFillableOnScreen(width: libraryGridPosterType.width, height: height)
|
||||
}
|
||||
|
||||
var enabledFilterType: [FilterType] {
|
||||
|
@ -20,7 +20,7 @@ struct LibraryView: View {
|
||||
@State
|
||||
private var scrollViewOffset: CGPoint = .zero
|
||||
|
||||
@Default(.Customization.libraryPosterType)
|
||||
@Default(.Customization.Library.gridPosterType)
|
||||
var libraryPosterType
|
||||
|
||||
@ViewBuilder
|
||||
|
@ -83,7 +83,6 @@
|
||||
53ABFDEB2679753200886593 /* ConnectToServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53ABFDEA2679753200886593 /* ConnectToServerView.swift */; };
|
||||
53ABFDED26799D7700886593 /* ActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 53ABFDEC26799D7700886593 /* ActivityIndicator */; };
|
||||
53CD2A40268A49C2002ABD4E /* ItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CD2A3F268A49C2002ABD4E /* ItemView.swift */; };
|
||||
53DF641E263D9C0600A7CD1A /* LibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53DF641D263D9C0600A7CD1A /* LibraryView.swift */; };
|
||||
53EE24E6265060780068F029 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53EE24E5265060780068F029 /* SearchView.swift */; };
|
||||
5D1603FC278A3D5800D22B99 /* SubtitleSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D1603FB278A3D5700D22B99 /* SubtitleSize.swift */; };
|
||||
5D1603FD278A40DB00D22B99 /* SubtitleSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D1603FB278A3D5700D22B99 /* SubtitleSize.swift */; };
|
||||
@ -306,6 +305,11 @@
|
||||
E13DD3FA2717E961009D4DAF /* UserListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F82717E961009D4DAF /* UserListViewModel.swift */; };
|
||||
E13DD3FC2717EAE8009D4DAF /* UserListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3FB2717EAE8009D4DAF /* UserListView.swift */; };
|
||||
E13DD4022717EE79009D4DAF /* UserListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD4012717EE79009D4DAF /* UserListCoordinator.swift */; };
|
||||
E13F05EC28BC9000003499D2 /* LibraryViewType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13F05EB28BC9000003499D2 /* LibraryViewType.swift */; };
|
||||
E13F05ED28BC9000003499D2 /* LibraryViewType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13F05EB28BC9000003499D2 /* LibraryViewType.swift */; };
|
||||
E13F05F128BC9016003499D2 /* LibraryItemRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13F05EF28BC9016003499D2 /* LibraryItemRow.swift */; };
|
||||
E13F05F228BC9016003499D2 /* LibraryItemRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13F05EF28BC9016003499D2 /* LibraryItemRow.swift */; };
|
||||
E13F05F328BC9016003499D2 /* LibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13F05F028BC9016003499D2 /* LibraryView.swift */; };
|
||||
E1546777289AF46E00087E35 /* CollectionItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1546776289AF46E00087E35 /* CollectionItemView.swift */; };
|
||||
E154677A289AF48200087E35 /* CollectionItemContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1546779289AF48200087E35 /* CollectionItemContentView.swift */; };
|
||||
E168BD10289A4162001A6922 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E168BD08289A4162001A6922 /* HomeView.swift */; };
|
||||
@ -616,7 +620,6 @@
|
||||
53ABFDEA2679753200886593 /* ConnectToServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerView.swift; sourceTree = "<group>"; };
|
||||
53CD2A3F268A49C2002ABD4E /* ItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemView.swift; sourceTree = "<group>"; };
|
||||
53D5E3DC264B47EE00BADDC8 /* MobileVLCKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MobileVLCKit.xcframework; path = Carthage/Build/MobileVLCKit.xcframework; sourceTree = "<group>"; };
|
||||
53DF641D263D9C0600A7CD1A /* LibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryView.swift; sourceTree = "<group>"; };
|
||||
53E4E646263F6CF100F67C6B /* LibraryFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryFilterView.swift; sourceTree = "<group>"; };
|
||||
53EE24E5265060780068F029 /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = "<group>"; };
|
||||
5D1603FB278A3D5700D22B99 /* SubtitleSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubtitleSize.swift; sourceTree = "<group>"; };
|
||||
@ -769,6 +772,9 @@
|
||||
E13DD3F82717E961009D4DAF /* UserListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListViewModel.swift; sourceTree = "<group>"; };
|
||||
E13DD3FB2717EAE8009D4DAF /* UserListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListView.swift; sourceTree = "<group>"; };
|
||||
E13DD4012717EE79009D4DAF /* UserListCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListCoordinator.swift; sourceTree = "<group>"; };
|
||||
E13F05EB28BC9000003499D2 /* LibraryViewType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryViewType.swift; sourceTree = "<group>"; };
|
||||
E13F05EF28BC9016003499D2 /* LibraryItemRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryItemRow.swift; sourceTree = "<group>"; };
|
||||
E13F05F028BC9016003499D2 /* LibraryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryView.swift; sourceTree = "<group>"; };
|
||||
E1546776289AF46E00087E35 /* CollectionItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionItemView.swift; sourceTree = "<group>"; };
|
||||
E1546779289AF48200087E35 /* CollectionItemContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionItemContentView.swift; sourceTree = "<group>"; };
|
||||
E168BD08289A4162001A6922 /* HomeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
|
||||
@ -1151,6 +1157,7 @@
|
||||
E19169CD272514760085832A /* HTTPScheme.swift */,
|
||||
E1C925F328875037002A7A66 /* ItemViewType.swift */,
|
||||
E1E1644328BC60C600323B0A /* LibraryItem.swift */,
|
||||
E13F05EB28BC9000003499D2 /* LibraryViewType.swift */,
|
||||
E1AA331E2782639D00F6439C /* OverlayType.swift */,
|
||||
E1C925F62887504B002A7A66 /* PanDirectionGestureRecognizer.swift */,
|
||||
E193D4DA27193CCA00900D82 /* PillStackable.swift */,
|
||||
@ -1681,7 +1688,7 @@
|
||||
E1EBCB45278BD595009FE6E9 /* ItemOverviewView.swift */,
|
||||
E14F7D0A26DB3714007C3AE6 /* ItemView */,
|
||||
53E4E646263F6CF100F67C6B /* LibraryFilterView.swift */,
|
||||
53DF641D263D9C0600A7CD1A /* LibraryView.swift */,
|
||||
E13F05EE28BC9016003499D2 /* LibraryView */,
|
||||
C4E5598828124C10003DECA5 /* LiveTVChannelItemElement.swift */,
|
||||
C400DB6C27FE8E65007B65FE /* LiveTVChannelItemWideElement.swift */,
|
||||
C400DB6927FE894F007B65FE /* LiveTVChannelsView.swift */,
|
||||
@ -1700,6 +1707,15 @@
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E13F05EE28BC9016003499D2 /* LibraryView */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E1C55AB228BD051700A9AD88 /* Components */,
|
||||
E13F05F028BC9016003499D2 /* LibraryView.swift */,
|
||||
);
|
||||
path = LibraryView;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E14F7D0A26DB3714007C3AE6 /* ItemView */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2008,6 +2024,14 @@
|
||||
path = ContinueWatchingView;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E1C55AB228BD051700A9AD88 /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E13F05EF28BC9016003499D2 /* LibraryItemRow.swift */,
|
||||
);
|
||||
path = Components;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E1C812CF277AE4C700918266 /* VideoPlayerCoordinator */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2472,6 +2496,7 @@
|
||||
62E632DD267D2E130063E547 /* SearchViewModel.swift in Sources */,
|
||||
536D3D81267BDFC60004248C /* PortraitItemElement.swift in Sources */,
|
||||
5D1603FD278A40DB00D22B99 /* SubtitleSize.swift in Sources */,
|
||||
E13F05F228BC9016003499D2 /* LibraryItemRow.swift in Sources */,
|
||||
E103A6A7278AB6D700820EC7 /* CinematicResumeCardView.swift in Sources */,
|
||||
62E1DCC4273CE19800C9AE76 /* URLExtensions.swift in Sources */,
|
||||
E10EAA54277BBD17000269ED /* BaseItemDto+VideoPlayerViewModel.swift in Sources */,
|
||||
@ -2527,6 +2552,7 @@
|
||||
E193D5512719432400900D82 /* ServerDetailViewModel.swift in Sources */,
|
||||
C4E5081B2703F82A0045C9AB /* MediaView.swift in Sources */,
|
||||
E193D53B27193F9200900D82 /* SettingsCoordinator.swift in Sources */,
|
||||
E13F05ED28BC9000003499D2 /* LibraryViewType.swift in Sources */,
|
||||
E18E021C2887492B0022598C /* BlurView.swift in Sources */,
|
||||
E1E5D5442783BB5100692DFE /* ItemDetailsView.swift in Sources */,
|
||||
E10D87E327852FD000BD264C /* EpisodesRowManager.swift in Sources */,
|
||||
@ -2646,7 +2672,6 @@
|
||||
E107BB9327880A8F00354E07 /* CollectionItemViewModel.swift in Sources */,
|
||||
532175402671EE4F005491E6 /* LibraryFilterView.swift in Sources */,
|
||||
E1171A1928A2212600FA1AF5 /* QuickConnectView.swift in Sources */,
|
||||
53DF641E263D9C0600A7CD1A /* LibraryView.swift in Sources */,
|
||||
E11CEB8D28999B4A003E74C7 /* FontExtensions.swift in Sources */,
|
||||
E1C812CE277AE43100918266 /* VideoPlayerViewModel.swift in Sources */,
|
||||
E11895A9289383BC0042947B /* ScrollViewOffsetModifier.swift in Sources */,
|
||||
@ -2654,6 +2679,7 @@
|
||||
E18CE0B228A229E70092E7F1 /* UserDtoExtensions.swift in Sources */,
|
||||
E18E01F0288747230022598C /* AttributeHStack.swift in Sources */,
|
||||
6334175B287DDFB9000603CE /* QuickConnectSettingsView.swift in Sources */,
|
||||
E13F05F128BC9016003499D2 /* LibraryItemRow.swift in Sources */,
|
||||
E18E0205288749200022598C /* AppIcon.swift in Sources */,
|
||||
E168BD10289A4162001A6922 /* HomeView.swift in Sources */,
|
||||
E18E01AB288746AF0022598C /* PillHStack.swift in Sources */,
|
||||
@ -2753,7 +2779,9 @@
|
||||
09389CC726819B4600AE350E /* VideoPlayerModel.swift in Sources */,
|
||||
E1D4BF872719D27100A11E64 /* Bitrates.swift in Sources */,
|
||||
6220D0B726D5EE1100B8E046 /* SearchCoordinator.swift in Sources */,
|
||||
E13F05F328BC9016003499D2 /* LibraryView.swift in Sources */,
|
||||
E13DD3EF27178F87009D4DAF /* SwiftfinNotificationCenter.swift in Sources */,
|
||||
E13F05EC28BC9000003499D2 /* LibraryViewType.swift in Sources */,
|
||||
5377CBF5263B596A003A4E83 /* JellyfinPlayerApp.swift in Sources */,
|
||||
E13DD4022717EE79009D4DAF /* UserListCoordinator.swift in Sources */,
|
||||
E1FCD09626C47118007C8DCF /* ErrorMessage.swift in Sources */,
|
||||
|
58
Swiftfin/Views/LibraryView/Components/LibraryItemRow.swift
Normal file
58
Swiftfin/Views/LibraryView/Components/LibraryItemRow.swift
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// 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 (c) 2022 Jellyfin & Jellyfin Contributors
|
||||
//
|
||||
|
||||
import JellyfinAPI
|
||||
import SwiftUI
|
||||
|
||||
struct LibraryItemRow: View {
|
||||
|
||||
@EnvironmentObject
|
||||
private var router: LibraryCoordinator.Router
|
||||
|
||||
let item: BaseItemDto
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
router.route(to: \.item, item)
|
||||
} label: {
|
||||
HStack(alignment: .bottom) {
|
||||
PosterButton(item: item, type: .portrait)
|
||||
.scaleItem(0.6)
|
||||
.content { _ in }
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text(item.displayName)
|
||||
.foregroundColor(.primary)
|
||||
.fontWeight(.semibold)
|
||||
.lineLimit(2)
|
||||
.multilineTextAlignment(.leading)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
DotHStack {
|
||||
if let premiereYear = item.premiereDateYear {
|
||||
Text(premiereYear)
|
||||
}
|
||||
|
||||
if let runtime = item.getItemRuntime() {
|
||||
Text(runtime)
|
||||
}
|
||||
|
||||
if let officialRating = item.officialRating {
|
||||
Text(officialRating)
|
||||
}
|
||||
}
|
||||
.font(.caption)
|
||||
.foregroundColor(Color(UIColor.lightGray))
|
||||
}
|
||||
.padding(.vertical)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,12 +13,14 @@ import SwiftUI
|
||||
struct LibraryView: View {
|
||||
|
||||
@EnvironmentObject
|
||||
private var libraryRouter: LibraryCoordinator.Router
|
||||
private var router: LibraryCoordinator.Router
|
||||
@ObservedObject
|
||||
var viewModel: LibraryViewModel
|
||||
|
||||
@Default(.Customization.libraryPosterType)
|
||||
private var libraryPosterType
|
||||
@Default(.Customization.Library.gridPosterType)
|
||||
private var libraryGridPosterType
|
||||
@Default(.Customization.Library.viewType)
|
||||
private var libraryViewType
|
||||
|
||||
@ViewBuilder
|
||||
private var loadingView: some View {
|
||||
@ -31,21 +33,41 @@ struct LibraryView: View {
|
||||
}
|
||||
|
||||
private var gridLayout: NSCollectionLayoutSection.GridLayoutMode {
|
||||
if libraryPosterType == .landscape && UIDevice.isPhone {
|
||||
if libraryGridPosterType == .landscape && UIDevice.isPhone {
|
||||
return .fixedNumberOfColumns(2)
|
||||
} else {
|
||||
return .adaptive(withMinItemSize: libraryPosterType.width + (UIDevice.isIPad ? 10 : 0))
|
||||
return .adaptive(withMinItemSize: libraryGridPosterType.width + (UIDevice.isIPad ? 10 : 0))
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var libraryItemsView: some View {
|
||||
private var libraryListView: some View {
|
||||
CollectionView(items: viewModel.items) { _, item, _ in
|
||||
PosterButton(item: item, type: libraryPosterType)
|
||||
LibraryItemRow(item: item)
|
||||
.padding()
|
||||
}
|
||||
.layout { _, layoutEnvironment in
|
||||
.list(using: .init(appearance: .plain), layoutEnvironment: layoutEnvironment)
|
||||
}
|
||||
.willReachEdge(insets: .init(top: 0, leading: 0, bottom: 200, trailing: 0)) { edge in
|
||||
if !viewModel.isLoading && edge == .bottom {
|
||||
viewModel.requestNextPageAsync()
|
||||
}
|
||||
}
|
||||
.configure { configuration in
|
||||
configuration.showsVerticalScrollIndicator = false
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var libraryGridView: some View {
|
||||
CollectionView(items: viewModel.items) { _, item, _ in
|
||||
PosterButton(item: item, type: libraryGridPosterType)
|
||||
.onSelect { item in
|
||||
libraryRouter.route(to: \.item, item)
|
||||
router.route(to: \.item, item)
|
||||
}
|
||||
.scaleItem(libraryPosterType == .landscape && UIDevice.isPhone ? 0.8 : 1)
|
||||
.scaleItem(libraryGridPosterType == .landscape && UIDevice.isPhone ? 0.8 : 1)
|
||||
}
|
||||
.layout { _, layoutEnvironment in
|
||||
.grid(
|
||||
@ -71,15 +93,35 @@ struct LibraryView: View {
|
||||
} else if viewModel.items.isEmpty {
|
||||
noResultsView
|
||||
} else {
|
||||
libraryItemsView
|
||||
switch libraryViewType {
|
||||
case .grid:
|
||||
libraryGridView
|
||||
case .list:
|
||||
libraryListView
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
||||
Button {
|
||||
switch libraryViewType {
|
||||
case .grid:
|
||||
libraryViewType = .list
|
||||
case .list:
|
||||
libraryViewType = .grid
|
||||
}
|
||||
} label: {
|
||||
switch libraryViewType {
|
||||
case .grid:
|
||||
Image(systemName: "list.dash")
|
||||
case .list:
|
||||
Image(systemName: "square.grid.2x2")
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
libraryRouter
|
||||
router
|
||||
.route(to: \.filter, (
|
||||
filters: $viewModel.filters,
|
||||
enabledFilterType: viewModel.enabledFilterType,
|
@ -33,12 +33,15 @@ struct CustomizeViewsSettings: View {
|
||||
var recommendedPosterType
|
||||
@Default(.Customization.searchPosterType)
|
||||
var searchPosterType
|
||||
@Default(.Customization.libraryPosterType)
|
||||
var libraryPosterType
|
||||
|
||||
@Default(.Customization.Episodes.useSeriesLandscapeBackdrop)
|
||||
var useSeriesLandscapeBackdrop
|
||||
|
||||
@Default(.Customization.Library.gridPosterType)
|
||||
var libraryGridPosterType
|
||||
@Default(.Customization.Library.viewType)
|
||||
var libraryViewType
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
Section {
|
||||
@ -96,12 +99,6 @@ struct CustomizeViewsSettings: View {
|
||||
Text(type.localizedName).tag(type.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
Picker(L10n.library, selection: $libraryPosterType) {
|
||||
ForEach(PosterType.allCases, id: \.self) { type in
|
||||
Text(type.localizedName).tag(type.rawValue)
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
// TODO: localize after organization
|
||||
Text("Posters")
|
||||
@ -114,6 +111,23 @@ struct CustomizeViewsSettings: View {
|
||||
// TODO: localize after organization
|
||||
Text("Episode Landscape Poster")
|
||||
}
|
||||
|
||||
Section {
|
||||
Picker(L10n.library, selection: $libraryGridPosterType) {
|
||||
ForEach(PosterType.allCases, id: \.self) { type in
|
||||
Text(type.localizedName).tag(type.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
Picker(L10n.items, selection: $libraryViewType) {
|
||||
ForEach(LibraryViewType.allCases, id: \.self) { type in
|
||||
Text(type.localizedName).tag(type.rawValue)
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
// TODO: localize after organization
|
||||
Text("Library")
|
||||
}
|
||||
}
|
||||
.navigationTitle(L10n.customize)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user