Implement auto aspect ratio for LibraryIconViews

This commit is contained in:
Shav Kinderlehrer 2023-12-27 08:25:35 -05:00
parent bd0b6ff491
commit 7aa602f19d
7 changed files with 92 additions and 45 deletions

View File

@ -12,7 +12,7 @@
3D13F95A2B375A9E00E91913 /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F9592B375A9E00E91913 /* Nuke */; }; 3D13F95A2B375A9E00E91913 /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F9592B375A9E00E91913 /* Nuke */; };
3D13F95C2B375A9E00E91913 /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F95B2B375A9E00E91913 /* NukeUI */; }; 3D13F95C2B375A9E00E91913 /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F95B2B375A9E00E91913 /* NukeUI */; };
3D13F95F2B375DB800E91913 /* ItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F95E2B375DB800E91913 /* ItemView.swift */; }; 3D13F95F2B375DB800E91913 /* ItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F95E2B375DB800E91913 /* ItemView.swift */; };
3D13F9612B37637500E91913 /* ItemMovieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9602B37637500E91913 /* ItemMovieView.swift */; }; 3D13F9612B37637500E91913 /* ItemMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9602B37637500E91913 /* ItemMediaView.swift */; };
3D13F9652B37EC7A00E91913 /* ItemHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */; }; 3D13F9652B37EC7A00E91913 /* ItemHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */; };
3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */; }; 3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */; };
3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */; }; 3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */; };
@ -37,6 +37,7 @@
3DAFA8E82B38AFED00D71AD1 /* ItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */; }; 3DAFA8E82B38AFED00D71AD1 /* ItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */; };
3DAFA8EA2B39039900D71AD1 /* JellyfinKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */; }; 3DAFA8EA2B39039900D71AD1 /* JellyfinKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */; };
3DAFA8EC2B394F9F00D71AD1 /* ViewConditionalMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */; }; 3DAFA8EC2B394F9F00D71AD1 /* ViewConditionalMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */; };
3DAFA8EF2B3B707B00D71AD1 /* ItemMovieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */; };
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */; }; 3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */; };
3DDD67932B293BC40026781E /* DashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67922B293BC40026781E /* DashboardView.swift */; }; 3DDD67932B293BC40026781E /* DashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67922B293BC40026781E /* DashboardView.swift */; };
3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67952B29E28B0026781E /* SettingsView.swift */; }; 3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67952B29E28B0026781E /* SettingsView.swift */; };
@ -78,7 +79,7 @@
3D1015D82B27F57400F5C29A /* AddServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddServerView.swift; sourceTree = "<group>"; }; 3D1015D82B27F57400F5C29A /* AddServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddServerView.swift; sourceTree = "<group>"; };
3D1015E32B28000E00F5C29A /* AuthStateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStateController.swift; sourceTree = "<group>"; }; 3D1015E32B28000E00F5C29A /* AuthStateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStateController.swift; sourceTree = "<group>"; };
3D13F95E2B375DB800E91913 /* ItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemView.swift; sourceTree = "<group>"; }; 3D13F95E2B375DB800E91913 /* ItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemView.swift; sourceTree = "<group>"; };
3D13F9602B37637500E91913 /* ItemMovieView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMovieView.swift; sourceTree = "<group>"; }; 3D13F9602B37637500E91913 /* ItemMediaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMediaView.swift; sourceTree = "<group>"; };
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemHeaderView.swift; sourceTree = "<group>"; }; 3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemHeaderView.swift; sourceTree = "<group>"; };
3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewOffsetKey.swift; sourceTree = "<group>"; }; 3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewOffsetKey.swift; sourceTree = "<group>"; };
3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyHeaderView.swift; sourceTree = "<group>"; }; 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyHeaderView.swift; sourceTree = "<group>"; };
@ -104,6 +105,7 @@
3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemInfoView.swift; sourceTree = "<group>"; }; 3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemInfoView.swift; sourceTree = "<group>"; };
3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinKitExtensions.swift; sourceTree = "<group>"; }; 3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinKitExtensions.swift; sourceTree = "<group>"; };
3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewConditionalMethod.swift; sourceTree = "<group>"; }; 3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewConditionalMethod.swift; sourceTree = "<group>"; };
3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMovieView.swift; sourceTree = "<group>"; };
3DC0E5802B2832B9001CCE96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 3DC0E5802B2832B9001CCE96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3DC6BA2C2B2A422300416B9F /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; }; 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
3DDD67922B293BC40026781E /* DashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardView.swift; sourceTree = "<group>"; }; 3DDD67922B293BC40026781E /* DashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardView.swift; sourceTree = "<group>"; };
@ -179,8 +181,9 @@
3D13F95D2B375DAC00E91913 /* Item */ = { 3D13F95D2B375DAC00E91913 /* Item */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3DAFA8ED2B3B707100D71AD1 /* Types */,
3D13F95E2B375DB800E91913 /* ItemView.swift */, 3D13F95E2B375DB800E91913 /* ItemView.swift */,
3D13F9602B37637500E91913 /* ItemMovieView.swift */, 3D13F9602B37637500E91913 /* ItemMediaView.swift */,
3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */, 3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */,
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */, 3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */,
); );
@ -276,6 +279,14 @@
path = SignIn; path = SignIn;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
3DAFA8ED2B3B707100D71AD1 /* Types */ = {
isa = PBXGroup;
children = (
3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */,
);
path = Types;
sourceTree = "<group>";
};
3DDD67902B293B780026781E /* Dashboard */ = { 3DDD67902B293B780026781E /* Dashboard */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -447,9 +458,10 @@
3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */, 3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */,
3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */, 3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */,
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */, 3D91FDC92B28C62800919017 /* SignInView.swift in Sources */,
3DAFA8EF2B3B707B00D71AD1 /* ItemMovieView.swift in Sources */,
3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */, 3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */,
3DDD67932B293BC40026781E /* DashboardView.swift in Sources */, 3DDD67932B293BC40026781E /* DashboardView.swift in Sources */,
3D13F9612B37637500E91913 /* ItemMovieView.swift in Sources */, 3D13F9612B37637500E91913 /* ItemMediaView.swift in Sources */,
3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */, 3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */,
3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */, 3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */,
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */, 3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */,

View File

@ -29,6 +29,7 @@ struct DashboardLibraryView: View {
LibraryDetailView(library: library) LibraryDetailView(library: library)
} label: { } label: {
LibraryIconView(library: library, height: 150) LibraryIconView(library: library, height: 150)
.setAspectRatio(library.primaryImageAspectRatio)
.padding() .padding()
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())

View File

@ -14,9 +14,9 @@ struct ItemInfoView: View {
var body: some View { var body: some View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
HStack { HStack {
Text(item.genres?.first ?? "---")
Text("")
Text((item.productionYear != nil) ? String(item.productionYear!) : "---") Text((item.productionYear != nil) ? String(item.productionYear!) : "---")
Text("")
Text(item.genres?.first ?? "---")
} }
Text(item.getRuntime() ?? "-:--") Text(item.getRuntime() ?? "-:--")
} }

View File

@ -1,5 +1,5 @@
// //
// ItemMovieView.swift // ItemMediaView.swift
// Jel // Jel
// //
// Created by zerocool on 12/23/23. // Created by zerocool on 12/23/23.
@ -8,7 +8,7 @@
import SwiftUI import SwiftUI
import JellyfinKit import JellyfinKit
struct ItemMovieView: View { struct ItemMediaView: View {
@EnvironmentObject var jellyfinClient: JellyfinClientController @EnvironmentObject var jellyfinClient: JellyfinClientController
@StateObject var authState: AuthStateController = AuthStateController.shared @StateObject var authState: AuthStateController = AuthStateController.shared

View File

@ -0,0 +1,22 @@
//
// ItemMovieView.swift
// Jel
//
// Created by zerocool on 12/26/23.
//
import SwiftUI
import JellyfinKit
struct ItemMovieView: View {
@State var item: BaseItemDto
var body: some View {
VStack {
ItemMediaView(item: item)
}
}
}
//#Preview {
// ItemMovieView()
//}

View File

@ -34,55 +34,50 @@ struct LibraryDetailView: View {
} }
ScrollView { ScrollView {
LazyVGrid(columns: columns) { LazyVGrid(columns: columns) {
if !searchText.isEmpty { // uses searchResultItems only if searchText is not empty
ForEach(searchResultItems ?? []) {item in ForEach(!searchText.isEmpty ? (searchResultItems ?? items) ?? [] : items ?? []) {item in
NavigationLink { NavigationLink {
ItemView(item: item) ItemView(item: item)
} label: { } label: {
LibraryIconView(library: item, imageType: "Primary", width: 170) LibraryIconView(library: item, imageType: "Primary", width: 170)
.padding() .setAspectRatio(item.primaryImageAspectRatio ?? 0.6)
} .padding()
.buttonStyle(PlainButtonStyle())
}
} else {
ForEach(items ?? []) {item in
NavigationLink {
ItemView(item: item)
} label: {
LibraryIconView(library: item, imageType: "Primary", width: 170)
.padding()
}
.buttonStyle(PlainButtonStyle())
} }
.buttonStyle(PlainButtonStyle())
} }
} }
} }
.if(!loading) {view in .if(!loading) {view in
view.searchable(text: $searchText) view.searchable(text: $searchText)
.onChange(of: searchText) { .onChange(of: searchText) {
Task { Task {
let parameters = Paths.GetParameters( let parameters = Paths.GetParameters(
userID: AuthStateController.shared.userId, userID: AuthStateController.shared.userId,
searchTerm: searchText.lowercased(), searchTerm: searchText.lowercased(),
parentID: library.id parentID: library.id
) )
searchResultHints = await jellyfinClient.search(parameters: parameters) searchResultHints = await jellyfinClient.search(parameters: parameters)
searchResultItems = items?.filter { item in searchResultItems = items?.filter { item in
for hint in searchResultHints?.searchHints ?? [] { for hint in searchResultHints?.searchHints ?? [] {
if hint.name == item.name { if hint.name == item.name {
return true return true
}
} }
return false
} }
return false
} }
} }
}
} }
.navigationTitle(library.name ?? "Unknown") .navigationTitle(library.name ?? "Unknown")
.onAppear { .onAppear {
Task { Task {
let params = Paths.GetItemsParameters(userID: authState.userId, parentID: library.id) let params = Paths.GetItemsParameters(
userID: authState.userId,
parentID: library.id,
fields: [.primaryImageAspectRatio]
)
let request = Paths.getItems(parameters: params) let request = Paths.getItems(parameters: params)
do { do {

View File

@ -32,21 +32,22 @@ struct LibraryIconView: View {
if let image = state.image { if let image = state.image {
image image
.resizable() .resizable()
.aspectRatio(contentMode: contentMode)
} else { } else {
if let content = placeHolder { if let content = placeHolder {
content content
} else { } else {
Image(uiImage: blurHashImage) Image(uiImage: blurHashImage)
.resizable() .resizable()
.aspectRatio(contentMode: .fill)
} }
} }
} }
.aspectRatio(contentMode: contentMode)
.frame(width: width, height: height) .frame(width: width, height: height)
.clipShape(RoundedRectangle(cornerRadius: imageCornerRadius)) .clipShape(RoundedRectangle(cornerRadius: imageCornerRadius))
.onAppear { .onAppear {
let blurhash = library.imageBlurHashes?.primary?[library.imageTags?[imageType] ?? ""] ?? "" let blurhash = library.imageBlurHashes?.primary?[library.imageTags?[imageType] ?? ""] ?? ""
blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 16, height: 16)) ?? UIImage() blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 32, height: 32)) ?? UIImage()
let imageId = library.id ?? "" let imageId = library.id ?? ""
let request = Paths.getItemImage(itemID: imageId, imageType: imageType) let request = Paths.getItemImage(itemID: imageId, imageType: imageType)
@ -70,6 +71,22 @@ struct LibraryIconView: View {
copy.imageCornerRadius = cornerRadius copy.imageCornerRadius = cornerRadius
return copy return copy
} }
func setAspectRatio(_ aspectRatio: Double?) -> Self {
var copy = self
if aspectRatio == nil {
return copy
}
if let newWidth = copy.width {
copy.height = newWidth / aspectRatio!
}
if let newHeight = copy.height {
copy.width = newHeight * aspectRatio!
}
return copy
}
} }
//#Preview { //#Preview {