jellyflood/Shared/Extensions/Nuke/ImagePipeline.swift

70 lines
2.4 KiB
Swift

//
// 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) 2025 Jellyfin & Jellyfin Contributors
//
import Foundation
import Nuke
extension ImagePipeline {
enum Swiftfin {}
static func cacheKey(for url: URL) -> String? {
guard var components = url.components else { return nil }
var maxWidthValue: String?
if let maxWidth = components.queryItems?.first(where: { $0.name == "maxWidth" }) {
maxWidthValue = maxWidth.value
components.queryItems = components.queryItems?.filter { $0.name != "maxWidth" }
}
guard let newURL = components.url, let urlSHA = newURL.pathAndQuery?.sha1 else { return nil }
if let maxWidthValue {
return urlSHA + "-\(maxWidthValue)"
} else {
return urlSHA
}
}
func removeItem(for url: URL) {
let request = ImageRequest(url: url)
cache.removeCachedImage(for: request)
cache.removeCachedData(for: request)
guard let dataCacheKey = Self.cacheKey(for: url) else { return }
configuration.dataCache?.removeData(for: dataCacheKey)
}
}
extension ImagePipeline.Swiftfin {
/// The default `ImagePipeline` to use for images that are typically posters
/// or server user images that should be presentable with an active connection.
static let posters: ImagePipeline = ImagePipeline(delegate: SwiftfinImagePipelineDelegate()) {
$0.dataCache = DataCache.Swiftfin.posters
}
/// The `ImagePipeline` used for images that should have longer lifetimes and usable
/// without a connection, likes local user profile images and server splashscreens.
static let local: ImagePipeline = ImagePipeline(delegate: SwiftfinImagePipelineDelegate()) {
$0.dataCache = DataCache.Swiftfin.local
}
/// An `ImagePipeline` for images to prevent more important images from losing their cache.
static let other: ImagePipeline = ImagePipeline(configuration: .withURLCache)
}
final class SwiftfinImagePipelineDelegate: ImagePipelineDelegate {
func cacheKey(for request: ImageRequest, pipeline: ImagePipeline) -> String? {
guard let url = request.url else { return nil }
return ImagePipeline.cacheKey(for: url)
}
}