Add ItemHeaderView

This commit is contained in:
Shav Kinderlehrer 2023-12-23 23:47:21 -05:00
parent 53bdc33ac7
commit 0798bb7141
4 changed files with 91 additions and 16 deletions

View File

@ -13,6 +13,7 @@
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 /* ItemMovieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9602B37637500E91913 /* ItemMovieView.swift */; };
3D13F9652B37EC7A00E91913 /* ItemHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9642B37EC7A00E91913 /* ItemHeaderView.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 /* LibraryIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F92B2CAE0000E58234 /* LibraryIconView.swift */; };
@ -73,6 +74,7 @@
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 /* ItemMovieView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMovieView.swift; sourceTree = "<group>"; };
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemHeaderView.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 /* LibraryIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryIconView.swift; sourceTree = "<group>"; };
@ -165,6 +167,7 @@
children = ( children = (
3D13F95E2B375DB800E91913 /* ItemView.swift */, 3D13F95E2B375DB800E91913 /* ItemView.swift */,
3D13F9602B37637500E91913 /* ItemMovieView.swift */, 3D13F9602B37637500E91913 /* ItemMovieView.swift */,
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */,
); );
path = Item; path = Item;
sourceTree = "<group>"; sourceTree = "<group>";
@ -413,6 +416,7 @@
3D9063CD2B279A310063DD2A /* ContentView.swift in Sources */, 3D9063CD2B279A310063DD2A /* ContentView.swift in Sources */,
3DF1ED3E2B282836000AD8EA /* JellyfinClientController.swift in Sources */, 3DF1ED3E2B282836000AD8EA /* JellyfinClientController.swift in Sources */,
3D1015D92B27F57400F5C29A /* AddServerView.swift in Sources */, 3D1015D92B27F57400F5C29A /* AddServerView.swift in Sources */,
3D13F9652B37EC7A00E91913 /* ItemHeaderView.swift in Sources */,
3D9063CB2B279A310063DD2A /* JelApp.swift in Sources */, 3D9063CB2B279A310063DD2A /* JelApp.swift in Sources */,
3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */, 3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */,
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */, 3D91FDC92B28C62800919017 /* SignInView.swift in Sources */,

View File

@ -0,0 +1,49 @@
//
// ItemHeaderView.swift
// Jel
//
// Created by zerocool on 12/23/23.
//
import SwiftUI
import JellyfinKit
struct ItemHeaderView: View {
@State var item: BaseItemDto
let overlayGradient = LinearGradient(gradient: Gradient(stops: [
.init(color: .clear, location: 0),
.init(color: .black, location: 0.3),
.init(color: .black, location: 0.7),
.init(color: .clear, location: 1)
]), startPoint: .bottom, endPoint: .top)
var body: some View {
ZStack(alignment: .bottom) {
LibraryIconView(library: item, imageType: "Backdrop", contentMode: .fill)
.hideCaption()
.setCornerRadius(0)
.mask(overlayGradient)
.padding(.top, 50)
.background {
LibraryIconView(library: item, imageType: "Backdrop", contentMode: .fill)
.hideCaption()
.setCornerRadius(0)
.blur(radius: 50)
}
HStack {
LibraryIconView(library: item, imageType: "Logo", width: 150)
.hideCaption()
.setCornerRadius(0)
.shadow(radius: 10)
Spacer()
}
.padding(.leading)
}
}
}
#Preview {
ItemHeaderView(item: BaseItemDto())
}

View File

@ -14,18 +14,23 @@ struct ItemMovieView: View {
@State var item: BaseItemDto @State var item: BaseItemDto
@State var loading: Bool = true @State var loading: Bool = true
var body: some View { var body: some View {
VStack { ScrollView {
Text(item.name ?? "Unknown") ItemHeaderView(item: item)
.font(.title)
Text(item.taglines?[0] ?? "Unknown") Text(item.taglines?[0] ?? "Unknown")
.font(.headline) .font(.headline)
.padding(.top, 20)
Text(item.overview ?? "Unknown") Text(item.overview ?? "Unknown")
.padding()
} }
.redacted(reason: loading ? .placeholder : [])
.ignoresSafeArea(edges: .top)
.toolbarRole(.editor)
.navigationTitle(item.name ?? "Unknown") .navigationTitle(item.name ?? "Unknown")
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.redacted(reason: loading ? .placeholder : [])
.onAppear { .onAppear {
Task { Task {
do { do {

View File

@ -20,6 +20,10 @@ struct LibraryIconView: View {
@State var blurHashImage: UIImage = UIImage() @State var blurHashImage: UIImage = UIImage()
@State var imageUrl: URL? @State var imageUrl: URL?
@State var contentMode: ContentMode = .fit
var shouldShowCaption: Bool = true
var imageCornerRadius: CGFloat = 5
var body: some View { var body: some View {
VStack { VStack {
LazyImage(url: imageUrl) {state in LazyImage(url: imageUrl) {state in
@ -33,12 +37,9 @@ struct LibraryIconView: View {
.resizable() .resizable()
} }
} }
.aspectRatio(contentMode: .fit) .aspectRatio(contentMode: contentMode)
.frame(width: width, height: height) .frame(width: width, height: height)
.clipShape(RoundedRectangle(cornerRadius: 5)) .clipShape(RoundedRectangle(cornerRadius: imageCornerRadius))
Text(library.name ?? "Unknown")
.font(.subheadline)
.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: 16, height: 16)) ?? UIImage()
@ -47,8 +48,24 @@ struct LibraryIconView: View {
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 {
Text(library.name ?? "Unknown")
.font(.subheadline)
} }
} }
}
func hideCaption(_ isHidden: Bool = true) -> Self {
var copy = self
copy.shouldShowCaption = !isHidden
return copy
}
func setCornerRadius(_ cornerRadius: CGFloat = 5) -> Self {
var copy = self
copy.imageCornerRadius = cornerRadius
return copy
}
} }
//#Preview { //#Preview {