Change to utilize image API

Change the url image format to webp
This commit is contained in:
PangMo5 2021-11-12 22:38:07 +09:00
parent 0f78534157
commit 5c24550228
5 changed files with 125 additions and 63 deletions

View File

@ -199,6 +199,9 @@
62C29EA326D1030F00C1D2E7 /* ConnectToServerCoodinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA226D1030F00C1D2E7 /* ConnectToServerCoodinator.swift */; };
62C29EA626D1036A00C1D2E7 /* HomeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA526D1036A00C1D2E7 /* HomeCoordinator.swift */; };
62C29EA826D103D500C1D2E7 /* LibraryListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA726D103D500C1D2E7 /* LibraryListCoordinator.swift */; };
62E1DCC3273CE19800C9AE76 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E1DCC2273CE19800C9AE76 /* URLExtensions.swift */; };
62E1DCC4273CE19800C9AE76 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E1DCC2273CE19800C9AE76 /* URLExtensions.swift */; };
62E1DCC5273CE19800C9AE76 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E1DCC2273CE19800C9AE76 /* URLExtensions.swift */; };
62E632DA267D2BC40063E547 /* LatestMediaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */; };
62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; };
62E632DD267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; };
@ -534,6 +537,7 @@
62C29EA226D1030F00C1D2E7 /* ConnectToServerCoodinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerCoodinator.swift; sourceTree = "<group>"; };
62C29EA526D1036A00C1D2E7 /* HomeCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCoordinator.swift; sourceTree = "<group>"; };
62C29EA726D103D500C1D2E7 /* LibraryListCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryListCoordinator.swift; sourceTree = "<group>"; };
62E1DCC2273CE19800C9AE76 /* URLExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = "<group>"; };
62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestMediaViewModel.swift; sourceTree = "<group>"; };
62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibrarySearchViewModel.swift; sourceTree = "<group>"; };
62E632DF267D30CA0063E547 /* LibraryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryViewModel.swift; sourceTree = "<group>"; };
@ -1059,6 +1063,7 @@
isa = PBXGroup;
children = (
5389277B263CC3DB0035E14B /* BlurHashDecode.swift */,
62E1DCC2273CE19800C9AE76 /* URLExtensions.swift */,
6267B3D526710B8900A7371D /* CollectionExtensions.swift */,
E173DA5126D04AAF00CC4EB7 /* ColorExtension.swift */,
6267B3D92671138200A7371D /* ImageExtensions.swift */,
@ -1818,6 +1823,7 @@
E1AD104E26D96CE3003E4A08 /* BaseItemDtoExtensions.swift in Sources */,
62E632DD267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */,
536D3D81267BDFC60004248C /* PortraitItemElement.swift in Sources */,
62E1DCC4273CE19800C9AE76 /* URLExtensions.swift in Sources */,
5310695B2684E7EE00CFFDBA /* AudioView.swift in Sources */,
5398514726B64E4100101B49 /* SearchBarView.swift in Sources */,
091B5A8D268315D400D78B61 /* ServerDiscovery.swift in Sources */,
@ -1977,6 +1983,7 @@
535870AD2669D8DD00D05A09 /* Typings.swift in Sources */,
E1AD105F26D9ADDD003E4A08 /* NameGUIDPairExtensions.swift in Sources */,
E13DD3D5271693CD009D4DAF /* SwiftfinStoreDefaults.swift in Sources */,
62E1DCC3273CE19800C9AE76 /* URLExtensions.swift in Sources */,
C4BE0769271FC164003F4AD1 /* TVLibrariesView.swift in Sources */,
E1267D3E271A1F46003C492E /* PreferenceUIHostingController.swift in Sources */,
6220D0BA26D6092100B8E046 /* FilterCoordinator.swift in Sources */,
@ -2025,6 +2032,7 @@
E13DD3D7271693CD009D4DAF /* SwiftfinStoreDefaults.swift in Sources */,
E131691926C583BC0074BFEE /* LogConstructor.swift in Sources */,
E13DD3CA27164B80009D4DAF /* SwiftfinStore.swift in Sources */,
62E1DCC5273CE19800C9AE76 /* URLExtensions.swift in Sources */,
62EC353226766849000E9F2D /* SessionManager.swift in Sources */,
536D3D79267BD5D00004248C /* ViewModel.swift in Sources */,
E1D4BF8C2719F39F00A11E64 /* AppAppearance.swift in Sources */,
@ -2365,7 +2373,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 66;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 4BHXT8RHFR;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
EXCLUDED_ARCHS = "";
@ -2402,7 +2410,7 @@
CURRENT_PROJECT_VERSION = 66;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 4BHXT8RHFR;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
EXCLUDED_ARCHS = "";
@ -2433,7 +2441,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 66;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 4BHXT8RHFR;
INFOPLIST_FILE = WidgetExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
@ -2460,7 +2468,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 66;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 4BHXT8RHFR;
INFOPLIST_FILE = WidgetExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (

View File

@ -92,7 +92,7 @@ struct ItemLandscapeMainView: View {
bh: viewModel.item.getBackdropImageBlurHash())
.opacity(0.3)
.edgesIgnoringSafeArea(.all)
.blur(radius: 4)
.blur(radius: 8)
// iPadOS is making the view go all the way to the edge.
// We have to accomodate this here

View File

@ -1,11 +1,11 @@
//
/*
* 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 2021 Aiden Vigue & Jellyfin Contributors
*/
/*
* 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 2021 Aiden Vigue & Jellyfin Contributors
*/
import Foundation
import JellyfinAPI
@ -14,35 +14,48 @@ import UIKit
// 001fC^ = dark grey plain blurhash
public extension BaseItemDto {
// MARK: Images
func getSeriesBackdropImageBlurHash() -> String {
let rawImgURL = getSeriesBackdropImage(maxWidth: 1).absoluteString
let imgTag = rawImgURL.components(separatedBy: "&tag=")[1]
let imgURL = getSeriesBackdropImage(maxWidth: 1)
guard let imgTag = imgURL.queryParameters?["tag"],
let hash = imageBlurHashes?.backdrop?[imgTag]
else {
return "001fC^"
}
return imageBlurHashes?.backdrop?[imgTag] ?? "001fC^"
return hash
}
func getSeriesPrimaryImageBlurHash() -> String {
let rawImgURL = getSeriesPrimaryImage(maxWidth: 1).absoluteString
let imgTag = rawImgURL.components(separatedBy: "&tag=")[1]
let imgURL = getSeriesPrimaryImage(maxWidth: 1)
guard let imgTag = imgURL.queryParameters?["tag"],
let hash = imageBlurHashes?.primary?[imgTag]
else {
return "001fC^"
}
return imageBlurHashes?.primary?[imgTag] ?? "001fC^"
return hash
}
func getPrimaryImageBlurHash() -> String {
let rawImgURL = getPrimaryImage(maxWidth: 1).absoluteString
let imgTag = rawImgURL.components(separatedBy: "&tag=")[1]
let imgURL = getPrimaryImage(maxWidth: 1)
guard let imgTag = imgURL.queryParameters?["tag"],
let hash = imageBlurHashes?.primary?[imgTag]
else {
return "001fC^"
}
return imageBlurHashes?.primary?[imgTag] ?? "001fC^"
return hash
}
func getBackdropImageBlurHash() -> String {
let rawImgURL = getBackdropImage(maxWidth: 1).absoluteString
let imgTag = rawImgURL.components(separatedBy: "&tag=")[1]
let imgURL = getBackdropImage(maxWidth: 1)
guard let imgTag = imgURL.queryParameters?["tag"] else {
return "001fC^"
}
if rawImgURL.contains("Backdrop") {
if imgURL.queryParameters?[ImageType.backdrop.rawValue] == nil {
return imageBlurHashes?.backdrop?[imgTag] ?? "001fC^"
} else {
return imageBlurHashes?.primary?[imgTag] ?? "001fC^"
@ -50,31 +63,34 @@ public extension BaseItemDto {
}
func getBackdropImage(maxWidth: Int) -> URL {
var imageType = ""
var imageTag = ""
var imageType = ImageType.backdrop
var imageTag: String?
var imageItemId = id ?? ""
if primaryImageAspectRatio ?? 0.0 < 1.0 {
imageType = "Backdrop"
if !(backdropImageTags?.isEmpty ?? true) {
imageTag = (backdropImageTags ?? [""])[0]
imageTag = backdropImageTags?.first
}
} else {
imageType = "Primary"
imageTag = imageTags?["Primary"] ?? ""
imageType = .primary
imageTag = imageTags?[ImageType.primary.rawValue] ?? ""
}
if imageTag == "" || imageItemId == "" {
imageType = "Backdrop"
if imageTag == nil || imageItemId.isEmpty {
if !(parentBackdropImageTags?.isEmpty ?? true) {
imageTag = (parentBackdropImageTags ?? [""])[0]
imageTag = parentBackdropImageTags?.first
imageItemId = parentBackdropItemId ?? ""
}
}
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
let urlString =
"\(SessionManager.main.currentLogin.server.uri)/Items/\(imageItemId)/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
let urlString = ImageAPI.getItemImageWithRequestBuilder(itemId: imageItemId,
imageType: imageType,
maxWidth: Int(x),
quality: 85,
tag: imageTag,
format: .webp).URLString
return URL(string: urlString)!
}
@ -86,39 +102,45 @@ public extension BaseItemDto {
}
func getSeriesBackdropImage(maxWidth: Int) -> URL {
let imageType = "Backdrop"
let imageTag = (parentBackdropImageTags ?? [""])[0]
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
let urlString =
"\(SessionManager.main.currentLogin.server.uri)/Items/\(parentBackdropItemId ?? "")/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
let urlString = ImageAPI.getItemImageWithRequestBuilder(itemId: parentBackdropItemId ?? "",
imageType: .backdrop,
maxWidth: Int(x),
quality: 85,
tag: parentBackdropImageTags?.first,
format: .webp).URLString
return URL(string: urlString)!
}
func getSeriesPrimaryImage(maxWidth: Int) -> URL {
let imageType = "Primary"
let imageTag = seriesPrimaryImageTag ?? ""
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
let urlString =
"\(SessionManager.main.currentLogin.server.uri)/Items/\(seriesId ?? "")/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
let urlString = ImageAPI.getItemImageWithRequestBuilder(itemId: seriesId ?? "",
imageType: .primary,
maxWidth: Int(x),
quality: 85,
tag: seriesPrimaryImageTag,
format: .webp).URLString
return URL(string: urlString)!
}
func getPrimaryImage(maxWidth: Int) -> URL {
let imageType = "Primary"
var imageTag = imageTags?["Primary"] ?? ""
let imageType = ImageType.primary
var imageTag = imageTags?[ImageType.primary.rawValue] ?? ""
var imageItemId = id ?? ""
if imageTag == "" || imageItemId == "" {
if imageTag.isEmpty || imageItemId.isEmpty {
imageTag = seriesPrimaryImageTag ?? ""
imageItemId = seriesId ?? ""
}
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
let urlString =
"\(SessionManager.main.currentLogin.server.uri)/Items/\(imageItemId)/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
// print(urlString)
let urlString = ImageAPI.getItemImageWithRequestBuilder(itemId: imageItemId,
imageType: imageType,
maxWidth: Int(x),
quality: 85,
tag: imageTag,
format: .webp).URLString
return URL(string: urlString)!
}
@ -174,14 +196,14 @@ public extension BaseItemDto {
}
var itemType: ItemType {
guard let originalType = self.type, let knownType = ItemType(rawValue: originalType) else { return .unknown }
guard let originalType = type, let knownType = ItemType(rawValue: originalType) else { return .unknown }
return knownType
}
// MARK: PortraitHeaderViewURL
func portraitHeaderViewURL(maxWidth: Int) -> URL {
switch self.itemType {
switch itemType {
case .movie, .season, .series:
return getPrimaryImage(maxWidth: maxWidth)
case .episode:

View File

@ -10,23 +10,29 @@ import JellyfinAPI
import UIKit
extension BaseItemPerson {
// MARK: Get Image
func getImage(baseURL: String, maxWidth: Int) -> URL {
let imageType = "Primary"
let imageTag = primaryImageTag ?? ""
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
let urlString = "\(baseURL)/Items/\(id ?? "")/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=85&tag=\(imageTag)"
let urlString = ImageAPI.getItemImageWithRequestBuilder(itemId: id ?? "",
imageType: .primary,
maxWidth: Int(x),
quality: 85,
tag: primaryImageTag,
format: .webp).URLString
return URL(string: urlString)!
}
func getBlurHash() -> String {
let rawImgURL = getImage(baseURL: "", maxWidth: 1).absoluteString
let imgTag = rawImgURL.components(separatedBy: "&tag=")[1]
let imgURL = getImage(baseURL: "", maxWidth: 1)
guard let imgTag = imgURL.queryParameters?["tag"],
let hash = imageBlurHashes?.primary?[imgTag]
else {
return "001fC^"
}
return imageBlurHashes?.primary?[imgTag] ?? "001fC^"
return hash
}
// MARK: First Role

View File

@ -0,0 +1,26 @@
//
/*
* 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 2021 Aiden Vigue & Jellyfin Contributors
*/
import Foundation
public extension URL {
/// Dictionary of the URL's query parameters
var queryParameters: [String: String]? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false),
let queryItems = components.queryItems else { return nil }
var items: [String: String] = [:]
for queryItem in queryItems {
items[queryItem.name] = queryItem.value
}
return items
}
}