Add ItemHeaderView
This commit is contained in:
parent
53bdc33ac7
commit
0798bb7141
@ -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 */,
|
||||||
|
49
Jel/Views/Library/Item/ItemHeaderView.swift
Normal file
49
Jel/Views/Library/Item/ItemHeaderView.swift
Normal 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())
|
||||||
|
}
|
@ -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 {
|
||||||
|
@ -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,22 +37,35 @@ 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))
|
||||||
|
.onAppear {
|
||||||
|
let blurhash = library.imageBlurHashes?.primary?[library.imageTags?[imageType] ?? ""] ?? ""
|
||||||
|
blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 16, height: 16)) ?? UIImage()
|
||||||
|
|
||||||
|
let imageId = library.id ?? ""
|
||||||
|
let request = Paths.getItemImage(itemID: imageId, imageType: imageType)
|
||||||
|
imageUrl = jellyfinClient.getUrl()?.appending(path: request.url?.absoluteString ?? "")
|
||||||
|
}
|
||||||
|
|
||||||
Text(library.name ?? "Unknown")
|
if shouldShowCaption {
|
||||||
.font(.subheadline)
|
Text(library.name ?? "Unknown")
|
||||||
.onAppear {
|
.font(.subheadline)
|
||||||
let blurhash = library.imageBlurHashes?.primary?[library.imageTags?[imageType] ?? ""] ?? ""
|
}
|
||||||
blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 16, height: 16)) ?? UIImage()
|
|
||||||
|
|
||||||
let imageId = library.id ?? ""
|
|
||||||
let request = Paths.getItemImage(itemID: imageId, imageType: imageType)
|
|
||||||
imageUrl = jellyfinClient.getUrl()?.appending(path: request.url?.absoluteString ?? "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user