update inits

This commit is contained in:
Ethan Pippin 2022-03-18 21:38:33 -06:00
parent 42ea9ad1cf
commit 9e10395f80
33 changed files with 118 additions and 51 deletions

View File

@ -0,0 +1,61 @@
//
// 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 SwiftUI
import UIKit
struct BlurHashView: UIViewRepresentable {
let blurHash: String
func makeUIView(context: Context) -> UIBlurHashView {
return UIBlurHashView(blurHash)
}
func updateUIView(_ uiView: UIBlurHashView, context: Context) {}
}
class UIBlurHashView: UIView {
private let imageView: UIImageView
init(_ blurHash: String) {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
self.imageView = imageView
super.init(frame: .zero)
computeBlurHashImageAsync(blurHash: blurHash) { blurImage in
DispatchQueue.main.async {
self.imageView.image = blurImage
self.imageView.setNeedsDisplay()
}
}
addSubview(imageView)
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: topAnchor),
imageView.bottomAnchor.constraint(equalTo: bottomAnchor),
imageView.leftAnchor.constraint(equalTo: leftAnchor),
imageView.rightAnchor.constraint(equalTo: rightAnchor),
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func computeBlurHashImageAsync(blurHash: String, _ completion: @escaping (UIImage?) -> Void) {
DispatchQueue.global(qos: .utility).async {
let image = UIImage(blurHash: blurHash, size: .Circle(radius: 12))
completion(image)
}
}
}

View File

@ -29,7 +29,7 @@ struct LiveTVChannelItemElement: View {
.font(.footnote)
.frame(alignment: .trailing)
}.frame(alignment: .top)
ImageView(src: channel.getPrimaryImage(maxWidth: 125))
ImageView(channel.getPrimaryImage(maxWidth: 125))
.frame(width: 125, alignment: .center)
.offset(x: 0, y: -32)
Text(channel.name ?? "?")

View File

@ -21,8 +21,8 @@ struct EpisodeRowCard: View {
Button {
itemRouter.route(to: \.item, episode)
} label: {
ImageView(src: episode.getBackdropImage(maxWidth: 550),
bh: episode.getBackdropImageBlurHash())
ImageView(episode.getBackdropImage(maxWidth: 550),
blurHash: episode.getBackdropImageBlurHash())
.mask(Rectangle().frame(width: 550, height: 308))
.frame(width: 550, height: 308)
}

View File

@ -34,7 +34,7 @@ struct CinematicNextUpCardView: View {
item.getThumbImage(maxWidth: 350),
item.getBackdropImage(maxWidth: 350),
],
bh: item.getBackdropImageBlurHash())
blurHash: item.getBackdropImageBlurHash())
.frame(width: 350, height: 210)
}

View File

@ -35,7 +35,7 @@ struct CinematicResumeCardView: View {
item.getThumbImage(maxWidth: 350),
item.getBackdropImage(maxWidth: 350),
],
bh: item.getBackdropImageBlurHash())
blurHash: item.getBackdropImageBlurHash())
.frame(width: 350, height: 210)
}

View File

@ -46,9 +46,9 @@ struct LandscapeItemElement: View {
var body: some View {
VStack {
ImageView(src: item.type == "Episode" && !(inSeasonView ?? false) ? item.getSeriesBackdropImage(maxWidth: 445) : item
ImageView(item.type == "Episode" && !(inSeasonView ?? false) ? item.getSeriesBackdropImage(maxWidth: 445) : item
.getBackdropImage(maxWidth: 445),
bh: item.type == "Episode" ? item.getSeriesBackdropImageBlurHash() : item.getBackdropImageBlurHash())
blurHash: item.type == "Episode" ? item.getSeriesBackdropImageBlurHash() : item.getBackdropImageBlurHash())
.frame(width: 445, height: 250)
.cornerRadius(10)
.ignoresSafeArea()

View File

@ -21,8 +21,8 @@ struct PortraitItemElement: View {
var body: some View {
VStack {
ImageView(src: item.type == "Episode" ? item.getSeriesPrimaryImage(maxWidth: 200) : item.getPrimaryImage(maxWidth: 200),
bh: item.type == "Episode" ? item.getSeriesPrimaryImageBlurHash() : item.getPrimaryImageBlurHash())
ImageView(item.type == "Episode" ? item.getSeriesPrimaryImage(maxWidth: 200) : item.getPrimaryImage(maxWidth: 200),
blurHash: item.type == "Episode" ? item.getSeriesPrimaryImageBlurHash() : item.getPrimaryImageBlurHash())
.frame(width: 200, height: 300)
.cornerRadius(10)
.shadow(radius: focused ? 10.0 : 0)

View File

@ -45,7 +45,7 @@ struct PortraitItemsRowView: View {
Button {
selectedAction(item)
} label: {
ImageView(src: item.portraitHeaderViewURL(maxWidth: 257))
ImageView(item.portraitHeaderViewURL(maxWidth: 257))
.frame(width: 257, height: 380)
}
.frame(height: 380)

View File

@ -20,7 +20,7 @@ struct PublicUserButton: View {
var body: some View {
VStack {
if publicUser.primaryImageTag != nil {
ImageView(src: URL(string: "\(SessionManager.main.currentLogin.server.currentURI)/Users/\(publicUser.id ?? "")/Images/Primary?width=500&quality=80&tag=\(publicUser.primaryImageTag!)")!)
ImageView(URL(string: "\(SessionManager.main.currentLogin.server.currentURI)/Users/\(publicUser.id ?? "")/Images/Primary?width=500&quality=80&tag=\(publicUser.primaryImageTag!)")!)
.frame(width: 250, height: 250)
.cornerRadius(125.0)
} else {

View File

@ -23,10 +23,10 @@ struct ContinueWatchingCard: View {
ZStack(alignment: .bottom) {
if item.itemType == .episode {
ImageView(src: item.getSeriesBackdropImage(maxWidth: 500))
ImageView(item.getSeriesBackdropImage(maxWidth: 500))
.frame(width: 500, height: 281.25)
} else {
ImageView(src: item.getBackdropImage(maxWidth: 500))
ImageView(item.getBackdropImage(maxWidth: 500))
.frame(width: 500, height: 281.25)
}

View File

@ -24,8 +24,8 @@ struct CinematicCollectionItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920),
bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920),
blurHash: viewModel.item.getBackdropImageBlurHash())
.ignoresSafeArea()
ScrollView {

View File

@ -32,8 +32,8 @@ struct CinematicEpisodeItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920),
bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920),
blurHash: viewModel.item.getBackdropImageBlurHash())
.frame(height: UIScreen.main.bounds.height - 10)
.ignoresSafeArea()

View File

@ -17,7 +17,7 @@ struct CinematicItemAboutView: View {
var body: some View {
HStack(alignment: .top, spacing: 10) {
ImageView(src: viewModel.item.portraitHeaderViewURL(maxWidth: 257))
ImageView(viewModel.item.portraitHeaderViewURL(maxWidth: 257))
.portraitPoster(width: 257)
ZStack(alignment: .topLeading) {

View File

@ -24,8 +24,8 @@ struct CinematicMovieItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920),
bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920),
blurHash: viewModel.item.getBackdropImageBlurHash())
.ignoresSafeArea()
ScrollView {

View File

@ -23,7 +23,7 @@ struct CinematicSeasonItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920), bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920), blurHash: viewModel.item.getBackdropImageBlurHash())
.ignoresSafeArea()
ScrollView {

View File

@ -23,7 +23,7 @@ struct CinematicSeriesItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920), bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920), blurHash: viewModel.item.getBackdropImageBlurHash())
.ignoresSafeArea()
ScrollView {

View File

@ -45,7 +45,7 @@ struct EpisodeItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920), bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920), blurHash: viewModel.item.getBackdropImageBlurHash())
.opacity(0.4)
.ignoresSafeArea()
LazyVStack(alignment: .leading) {

View File

@ -50,7 +50,7 @@ struct MovieItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920), bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920), blurHash: viewModel.item.getBackdropImageBlurHash())
.opacity(0.4)
.ignoresSafeArea()
ScrollView {

View File

@ -25,7 +25,7 @@ struct SeasonItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getSeriesBackdropImage(maxWidth: 1920), bh: viewModel.item.getSeriesBackdropImageBlurHash())
ImageView(viewModel.item.getSeriesBackdropImage(maxWidth: 1920), blurHash: viewModel.item.getSeriesBackdropImageBlurHash())
.opacity(0.4)
.ignoresSafeArea()
ScrollView {

View File

@ -53,7 +53,7 @@ struct SeriesItemView: View {
var body: some View {
ZStack {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 1920), bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 1920), blurHash: viewModel.item.getBackdropImageBlurHash())
.opacity(0.4)
.ignoresSafeArea()
ScrollView {

View File

@ -34,7 +34,7 @@ struct LatestMediaView: View {
Button {
homeRouter.route(to: \.modalItem, item)
} label: {
ImageView(src: item.portraitHeaderViewURL(maxWidth: 257))
ImageView(item.portraitHeaderViewURL(maxWidth: 257))
.frame(width: 257, height: 380)
}
.frame(height: 380)

View File

@ -21,10 +21,10 @@ struct NextUpCard: View {
homeRouter.route(to: \.modalItem, item)
} label: {
if item.itemType == .episode {
ImageView(src: item.getSeriesBackdropImage(maxWidth: 500))
ImageView(item.getSeriesBackdropImage(maxWidth: 500))
.frame(width: 500, height: 281.25)
} else {
ImageView(src: item.getBackdropImage(maxWidth: 500))
ImageView(item.getBackdropImage(maxWidth: 500))
.frame(width: 500, height: 281.25)
}
}

View File

@ -329,7 +329,7 @@ struct SmallMediaStreamSelectionView: View {
Button {
viewModel.playerOverlayDelegate?.didSelectChapter(viewModel.chapters[chapterIndex])
} label: {
ImageView(src: chapterImages[chapterIndex])
ImageView(chapterImages[chapterIndex])
.cornerRadius(10)
.frame(width: 350, height: 210)
}

View File

@ -292,6 +292,8 @@
E103A6A5278A82E500820EC7 /* HomeCinematicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E103A6A4278A82E500820EC7 /* HomeCinematicView.swift */; };
E103A6A7278AB6D700820EC7 /* CinematicResumeCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E103A6A6278AB6D700820EC7 /* CinematicResumeCardView.swift */; };
E103A6A9278AB6FF00820EC7 /* CinematicNextUpCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E103A6A8278AB6FF00820EC7 /* CinematicNextUpCardView.swift */; };
E1047E2027E584AF00CB0D4A /* BlurHashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1047E1F27E584AF00CB0D4A /* BlurHashView.swift */; };
E1047E2127E584AF00CB0D4A /* BlurHashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1047E1F27E584AF00CB0D4A /* BlurHashView.swift */; };
E107BB9327880A8F00354E07 /* CollectionItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E107BB9227880A8F00354E07 /* CollectionItemViewModel.swift */; };
E107BB9427880A8F00354E07 /* CollectionItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E107BB9227880A8F00354E07 /* CollectionItemViewModel.swift */; };
E107BB972788104100354E07 /* CinematicCollectionItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E107BB952788104100354E07 /* CinematicCollectionItemView.swift */; };
@ -760,6 +762,7 @@
E103A6A4278A82E500820EC7 /* HomeCinematicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCinematicView.swift; sourceTree = "<group>"; };
E103A6A6278AB6D700820EC7 /* CinematicResumeCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CinematicResumeCardView.swift; sourceTree = "<group>"; };
E103A6A8278AB6FF00820EC7 /* CinematicNextUpCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CinematicNextUpCardView.swift; sourceTree = "<group>"; };
E1047E1F27E584AF00CB0D4A /* BlurHashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashView.swift; sourceTree = "<group>"; };
E107BB9227880A8F00354E07 /* CollectionItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionItemViewModel.swift; sourceTree = "<group>"; };
E107BB952788104100354E07 /* CinematicCollectionItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CinematicCollectionItemView.swift; sourceTree = "<group>"; };
E10C0940278B8DAB009DBF93 /* PortraitItemSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortraitItemSize.swift; sourceTree = "<group>"; };
@ -1748,6 +1751,7 @@
E1AD105326D96F5A003E4A08 /* Views */ = {
isa = PBXGroup;
children = (
E1047E1F27E584AF00CB0D4A /* BlurHashView.swift */,
531AC8BE26750DE20091C7EB /* ImageView.swift */,
621338B22660A07800A81A2A /* LazyView.swift */,
C4E52304272CE68800654268 /* LiveTVChannelItemElement.swift */,
@ -2243,6 +2247,7 @@
C4BE078C272844AF003F4AD1 /* LiveTVChannelsView.swift in Sources */,
E1D4BF852719D25A00A11E64 /* TrackLanguage.swift in Sources */,
53272532268BF09D0035FBF1 /* MediaViewActionButton.swift in Sources */,
E1047E2127E584AF00CB0D4A /* BlurHashView.swift in Sources */,
531690F0267ABF72005D8AB9 /* NextUpView.swift in Sources */,
E193D53427193F7F00900D82 /* HomeCoordinator.swift in Sources */,
E193D5502719430400900D82 /* ServerDetailView.swift in Sources */,
@ -2390,6 +2395,7 @@
E1EBCB42278BD174009FE6E9 /* TruncatedTextView.swift in Sources */,
62133890265F83A900A81A2A /* LibraryListView.swift in Sources */,
62C29EA326D1030F00C1D2E7 /* ConnectToServerCoodinator.swift in Sources */,
E1047E2027E584AF00CB0D4A /* BlurHashView.swift in Sources */,
62E632DA267D2BC40063E547 /* LatestMediaViewModel.swift in Sources */,
E1AD105C26D9ABDD003E4A08 /* PillHStackView.swift in Sources */,
625CB56F2678C23300530A6E /* HomeView.swift in Sources */,

View File

@ -50,8 +50,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/kaishin/Gifu",
"state" : {
"revision" : "51f2eab32903e336f590c013267cfa4d7f8b06c4",
"version" : "3.3.1"
"revision" : "0ffe24744cc3d82ab9edece53670d0352c6d5507",
"version" : "3.3.0"
}
},
{
@ -66,7 +66,7 @@
{
"identity" : "nuke",
"kind" : "remoteSourceControl",
"location" : "https://github.com/kean/Nuke",
"location" : "https://github.com/kean/Nuke.git",
"state" : {
"revision" : "78fa963b8491fc520791d8c2a509f1b8593d8aae",
"version" : "10.7.1"
@ -140,8 +140,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/siteline/SwiftUI-Introspect",
"state" : {
"revision" : "f2616860a41f9d9932da412a8978fec79c06fe24",
"version" : "0.1.4"
"revision" : "2e09be8af614401bc9f87d40093ec19ce56ccaf2",
"version" : "0.1.3"
}
},
{

View File

@ -23,8 +23,8 @@ struct EpisodeRowCard: View {
HStack(alignment: .top) {
VStack(alignment: .leading) {
ImageView(src: episode.getBackdropImage(maxWidth: 200),
bh: episode.getBackdropImageBlurHash())
ImageView(episode.getBackdropImage(maxWidth: 200),
blurHash: episode.getBackdropImageBlurHash())
.mask(Rectangle().frame(width: 200, height: 112).cornerRadius(10))
.frame(width: 200, height: 112)
.overlay {

View File

@ -43,8 +43,8 @@ struct PortraitImageHStackView<TopBarView: View, ItemType: PortraitImageStackabl
selectedAction(item)
} label: {
VStack(alignment: horizontalAlignment) {
ImageView(src: item.imageURLConstructor(maxWidth: Int(maxWidth)),
bh: item.blurHash,
ImageView(item.imageURLConstructor(maxWidth: Int(maxWidth)),
blurHash: item.blurHash,
failureInitials: item.failureInitials)
.portraitPoster(width: maxWidth)
.shadow(radius: 4, y: 2)

View File

@ -35,8 +35,8 @@ struct PortraitItemButton<ItemType: PortraitImageStackable>: View {
selectedAction(item)
} label: {
VStack(alignment: horizontalAlignment) {
ImageView(src: item.imageURLConstructor(maxWidth: Int(maxWidth)),
bh: item.blurHash,
ImageView(item.imageURLConstructor(maxWidth: Int(maxWidth)),
blurHash: item.blurHash,
failureInitials: item.failureInitials)
.portraitPoster(width: maxWidth)
.shadow(radius: 4, y: 2)

View File

@ -24,8 +24,8 @@ struct ItemLandscapeMainView: View {
// MARK: Sidebar Image
VStack {
ImageView(src: viewModel.item.portraitHeaderViewURL(maxWidth: 130),
bh: viewModel.item.getPrimaryImageBlurHash())
ImageView(viewModel.item.portraitHeaderViewURL(maxWidth: 130),
blurHash: viewModel.item.getPrimaryImageBlurHash())
.frame(width: 130, height: 195)
.cornerRadius(10)
.accessibilityIgnoresInvertColors()
@ -95,8 +95,8 @@ struct ItemLandscapeMainView: View {
ZStack {
// MARK: Backdrop
ImageView(src: viewModel.item.getBackdropImage(maxWidth: 200),
bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: 200),
blurHash: viewModel.item.getBackdropImageBlurHash())
.opacity(0.3)
.edgesIgnoringSafeArea(.all)
.blur(radius: 8)

View File

@ -24,8 +24,8 @@ struct PortraitHeaderOverlayView: View {
// MARK: Portrait Image
ImageView(src: viewModel.item.portraitHeaderViewURL(maxWidth: 130),
bh: viewModel.item.getPrimaryImageBlurHash())
ImageView(viewModel.item.portraitHeaderViewURL(maxWidth: 130),
blurHash: viewModel.item.getPrimaryImageBlurHash())
.portraitPoster(width: 130)
.accessibilityIgnoresInvertColors()

View File

@ -19,8 +19,8 @@ struct ItemPortraitMainView: View {
// MARK: portraitHeaderView
var portraitHeaderView: some View {
ImageView(src: viewModel.item.getBackdropImage(maxWidth: Int(UIScreen.main.bounds.width)),
bh: viewModel.item.getBackdropImageBlurHash())
ImageView(viewModel.item.getBackdropImage(maxWidth: Int(UIScreen.main.bounds.width)),
blurHash: viewModel.item.getBackdropImageBlurHash())
.opacity(0.4)
.blur(radius: 2.0)
.accessibilityIgnoresInvertColors()

View File

@ -54,7 +54,7 @@ struct LibraryListView: View {
title: library.name ?? ""))
} label: {
ZStack {
ImageView(src: library.getPrimaryImage(maxWidth: 500), bh: library.getPrimaryImageBlurHash())
ImageView(library.getPrimaryImage(maxWidth: 500), blurHash: library.getPrimaryImageBlurHash())
.opacity(0.4)
.accessibilityIgnoresInvertColors()
HStack {

View File

@ -48,7 +48,7 @@ struct VLCPlayerChapterOverlayView: View {
Button {
viewModel.playerOverlayDelegate?.didSelectChapter(viewModel.chapters[chapterIndex])
} label: {
ImageView(src: chapterImages[chapterIndex])
ImageView(chapterImages[chapterIndex])
.cornerRadius(10)
.frame(width: 150, height: 100)
.overlay {