Use backdrop blurhash + rename LibraryIconView

This commit is contained in:
Shav Kinderlehrer 2024-01-07 16:41:45 -05:00
parent a271314f15
commit 4d40b0c083
8 changed files with 33 additions and 28 deletions

View File

@ -18,7 +18,7 @@
3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */; }; 3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */; };
3D16FC3C2B2CDFB500E6D8B3 /* DashboardLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */; }; 3D16FC3C2B2CDFB500E6D8B3 /* DashboardLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */; };
3D41D1F52B2C962500E58234 /* AppearancePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F42B2C962500E58234 /* AppearancePicker.swift */; }; 3D41D1F52B2C962500E58234 /* AppearancePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F42B2C962500E58234 /* AppearancePicker.swift */; };
3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F92B2CAE0000E58234 /* LibraryIconView.swift */; }; 3D41D1FA2B2CAE0000E58234 /* ItemIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F92B2CAE0000E58234 /* ItemIconView.swift */; };
3D4C15722B3CAA670035373E /* DashboardSectionTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D4C15712B3CAA670035373E /* DashboardSectionTitleView.swift */; }; 3D4C15722B3CAA670035373E /* DashboardSectionTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D4C15712B3CAA670035373E /* DashboardSectionTitleView.swift */; };
3D7709392B29139700199889 /* Pulse in Frameworks */ = {isa = PBXBuildFile; productRef = 3D7709382B29139700199889 /* Pulse */; }; 3D7709392B29139700199889 /* Pulse in Frameworks */ = {isa = PBXBuildFile; productRef = 3D7709382B29139700199889 /* Pulse */; };
3D77093B2B29139700199889 /* PulseUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D77093A2B29139700199889 /* PulseUI */; }; 3D77093B2B29139700199889 /* PulseUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D77093A2B29139700199889 /* PulseUI */; };
@ -86,7 +86,7 @@
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>"; };
3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardLibraryView.swift; sourceTree = "<group>"; }; 3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardLibraryView.swift; sourceTree = "<group>"; };
3D41D1F42B2C962500E58234 /* AppearancePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearancePicker.swift; sourceTree = "<group>"; }; 3D41D1F42B2C962500E58234 /* AppearancePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearancePicker.swift; sourceTree = "<group>"; };
3D41D1F92B2CAE0000E58234 /* LibraryIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryIconView.swift; sourceTree = "<group>"; }; 3D41D1F92B2CAE0000E58234 /* ItemIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemIconView.swift; sourceTree = "<group>"; };
3D4C15712B3CAA670035373E /* DashboardSectionTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardSectionTitleView.swift; sourceTree = "<group>"; }; 3D4C15712B3CAA670035373E /* DashboardSectionTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardSectionTitleView.swift; sourceTree = "<group>"; };
3D8AB2A42B36440D005BD7D0 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; }; 3D8AB2A42B36440D005BD7D0 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
3D8AB2A72B366353005BD7D0 /* LibraryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryDetailView.swift; sourceTree = "<group>"; }; 3D8AB2A72B366353005BD7D0 /* LibraryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryDetailView.swift; sourceTree = "<group>"; };
@ -204,7 +204,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3D13F95D2B375DAC00E91913 /* Item */, 3D13F95D2B375DAC00E91913 /* Item */,
3D41D1F92B2CAE0000E58234 /* LibraryIconView.swift */, 3D41D1F92B2CAE0000E58234 /* ItemIconView.swift */,
3D8AB2A72B366353005BD7D0 /* LibraryDetailView.swift */, 3D8AB2A72B366353005BD7D0 /* LibraryDetailView.swift */,
); );
path = Library; path = Library;
@ -465,7 +465,7 @@
3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */, 3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */,
3DDD67932B293BC40026781E /* DashboardView.swift in Sources */, 3DDD67932B293BC40026781E /* DashboardView.swift in Sources */,
3D13F9612B37637500E91913 /* ItemMediaView.swift in Sources */, 3D13F9612B37637500E91913 /* ItemMediaView.swift in Sources */,
3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */, 3D41D1FA2B2CAE0000E58234 /* ItemIconView.swift in Sources */,
3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */, 3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */,
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */, 3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */,
3DAFA8E82B38AFED00D71AD1 /* ItemInfoView.swift in Sources */, 3DAFA8E82B38AFED00D71AD1 /* ItemInfoView.swift in Sources */,

View File

@ -28,12 +28,12 @@ struct DashboardLibraryView: View {
NavigationLink { NavigationLink {
LibraryDetailView(library: library) LibraryDetailView(library: library)
} label: { } label: {
LibraryIconView(library: library, height: 150) ItemIconView(item: library, height: 150)
.setAspectRatio(library.primaryImageAspectRatio) .setAspectRatio(library.primaryImageAspectRatio)
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
} }
} }.padding(.horizontal)
} }
} }
.onAppear { .onAppear {

View File

@ -21,7 +21,6 @@ struct DashboardSectionTitleView: View {
.bold() .bold()
Spacer() Spacer()
} }
.padding(.top)
} }
} }

View File

@ -20,17 +20,9 @@ struct DashboardView: View {
} }
} header: { } header: {
DashboardSectionTitleView("Libraries") DashboardSectionTitleView("Libraries")
} .padding([.top, .leading])
Section {
NavigationStack {
DashboardLibraryView()
}
} header: {
DashboardSectionTitleView("Next up")
} }
} }
.padding()
} }
.navigationTitle("Home") .navigationTitle("Home")
.toolbar { .toolbar {

View File

@ -21,18 +21,18 @@ struct ItemHeaderView: View {
var body: some View { var body: some View {
ZStack(alignment: .bottom) { ZStack(alignment: .bottom) {
StickyHeaderView(minHeight: 300) { StickyHeaderView(minHeight: 300) {
LibraryIconView(library: item, imageType: "Backdrop", contentMode: .fill) ItemIconView(item: item, imageType: "Backdrop", contentMode: .fill)
.setCornerRadius(0) .setCornerRadius(0)
.mask(overlayGradient) .mask(overlayGradient)
.background { .background {
LibraryIconView(library: item, imageType: "Backdrop", contentMode: .fill) ItemIconView(item: item, imageType: "Backdrop", contentMode: .fill)
.setCornerRadius(0) .setCornerRadius(0)
.blur(radius: 50) .blur(radius: 50)
} }
} }
HStack { HStack {
LibraryIconView(library: item, imageType: "Logo", width: 200, height: 100, placeHolder: AnyView(Text(item.name ?? "Unknown").font(.title).bold().truncationMode(.middle))) ItemIconView(item: item, imageType: "Logo", width: 200, height: 100, placeHolder: AnyView(Text(item.name ?? "Unknown").font(.title).bold().truncationMode(.middle)))
.setCornerRadius(0) .setCornerRadius(0)
.shadow(radius: 10) .shadow(radius: 10)
.frame(alignment: .leading) .frame(alignment: .leading)

View File

@ -21,9 +21,11 @@ struct ItemInfoView: View {
Text(item.genres?.first ?? "---") Text(item.genres?.first ?? "---")
.shadow(color: .black, radius: 1) .shadow(color: .black, radius: 1)
} }
if item.type == .movie {
Text(item.getRuntime() ?? "-:--") Text(item.getRuntime() ?? "-:--")
.shadow(color: .black, radius: 1) .shadow(color: .black, radius: 1)
} }
}
.font(.caption) .font(.caption)
} }
} }

View File

@ -1,5 +1,5 @@
// //
// LibraryIconView.swift // ItemIconView.swift
// Jel // Jel
// //
// Created by zerocool on 12/15/23. // Created by zerocool on 12/15/23.
@ -9,10 +9,10 @@ import SwiftUI
import JellyfinKit import JellyfinKit
import NukeUI import NukeUI
struct LibraryIconView: View { struct ItemIconView: View {
@EnvironmentObject var jellyfinClient: JellyfinClientController @EnvironmentObject var jellyfinClient: JellyfinClientController
var library: BaseItemDto var item: BaseItemDto
var imageType: String = "Primary" var imageType: String = "Primary"
var width: CGFloat? var width: CGFloat?
@ -46,20 +46,32 @@ struct LibraryIconView: View {
.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 = getBlurHash(imageType: imageType)
blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 32, height: 32)) ?? UIImage() blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 32, height: 32)) ?? UIImage()
let imageId = library.id ?? "" let imageId = item.id ?? ""
let request = Paths.getItemImage(itemID: imageId, imageType: imageType) let request = Paths.getItemImage(itemID: imageId, imageType: imageType)
imageUrl = jellyfinClient.getUrl()?.appending(path: request.url?.absoluteString ?? "") imageUrl = jellyfinClient.getUrl()?.appending(path: request.url?.absoluteString ?? "")
} }
if shouldShowCaption { if shouldShowCaption {
Text(library.name ?? "Unknown") Text(item.name ?? "Unknown")
.font(.subheadline) .font(.subheadline)
} }
} }
} }
private func getBlurHash(imageType: String) -> String {
switch imageType {
case "Primary":
return item.imageBlurHashes?.primary?[item.imageTags?[imageType] ?? ""] ?? ""
case "Backdrop":
return item.imageBlurHashes?.backdrop?[item.backdropImageTags?[0] ?? ""] ?? ""
default:
return ""
}
}
func showCaption(_ showCaption: Bool = true) -> Self { func showCaption(_ showCaption: Bool = true) -> Self {
var copy = self var copy = self
copy.shouldShowCaption = showCaption copy.shouldShowCaption = showCaption

View File

@ -39,7 +39,7 @@ struct LibraryDetailView: View {
NavigationLink { NavigationLink {
ItemView(item: item) ItemView(item: item)
} label: { } label: {
LibraryIconView(library: item, imageType: "Primary", width: 150) ItemIconView(item: item, imageType: "Primary", width: 150)
.showCaption() .showCaption()
.setAspectRatio(item.primaryImageAspectRatio ?? 0.6) .setAspectRatio(item.primaryImageAspectRatio ?? 0.6)
.padding() .padding()