mirror of
https://github.com/yattee/yattee.git
synced 2026-02-20 01:39:46 +00:00
Yattee v2 rewrite
This commit is contained in:
79
Yattee/Utilities/AvatarURLBuilder.swift
Normal file
79
Yattee/Utilities/AvatarURLBuilder.swift
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// AvatarURLBuilder.swift
|
||||
// Yattee
|
||||
//
|
||||
// Utility for constructing channel avatar URLs with Yattee Server fallback.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Nuke
|
||||
|
||||
/// Utility for constructing channel avatar URLs with Yattee Server fallback
|
||||
enum AvatarURLBuilder {
|
||||
|
||||
/// Available avatar sizes on Yattee Server
|
||||
private static let availableSizes = [32, 48, 76, 100, 176, 512]
|
||||
|
||||
/// Constructs the effective avatar URL for a channel
|
||||
/// - Parameters:
|
||||
/// - channelID: The channel ID
|
||||
/// - directURL: Direct avatar URL if available (from API response)
|
||||
/// - serverURL: Yattee Server base URL
|
||||
/// - size: Desired size in points (will be doubled for retina and rounded to nearest available)
|
||||
/// - Returns: URL to use for avatar, or nil if unavailable
|
||||
static func avatarURL(
|
||||
channelID: String,
|
||||
directURL: URL?,
|
||||
serverURL: URL?,
|
||||
size: Int
|
||||
) -> URL? {
|
||||
// Check if this is a YouTube channel (UC prefix or @handle)
|
||||
let isYouTubeChannel = channelID.hasPrefix("UC") || channelID.hasPrefix("@")
|
||||
|
||||
// Priority 1: For YouTube channels, prefer Yattee Server (more reliable, avoids stale URLs from iCloud sync)
|
||||
if isYouTubeChannel, let serverURL = serverURL {
|
||||
return buildServerAvatarURL(serverURL: serverURL, channelID: channelID, size: size)
|
||||
}
|
||||
|
||||
// Priority 2: Use direct URL for non-YouTube channels or when server unavailable
|
||||
if let directURL = directURL {
|
||||
return directURL
|
||||
}
|
||||
|
||||
// Priority 3: Try server as last resort (for YouTube without direct URL)
|
||||
if let serverURL = serverURL {
|
||||
return buildServerAvatarURL(serverURL: serverURL, channelID: channelID, size: size)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Builds the Yattee Server avatar URL for a channel
|
||||
private static func buildServerAvatarURL(serverURL: URL, channelID: String, size: Int) -> URL {
|
||||
// Calculate retina size and round to nearest available
|
||||
let retinaSize = size * 2
|
||||
let roundedSize = availableSizes
|
||||
.min { abs($0 - retinaSize) < abs($1 - retinaSize) } ?? 176
|
||||
|
||||
return serverURL
|
||||
.appendingPathComponent("api/v1/channels")
|
||||
.appendingPathComponent(channelID)
|
||||
.appendingPathComponent("avatar")
|
||||
.appendingPathComponent("\(roundedSize).jpg")
|
||||
}
|
||||
|
||||
/// Creates an ImageRequest with auth header for Yattee Server avatar URLs
|
||||
/// - Parameters:
|
||||
/// - url: The avatar URL
|
||||
/// - authHeader: Optional Basic Auth header for Yattee Server
|
||||
/// - Returns: ImageRequest configured with auth if needed, or nil if URL is nil
|
||||
static func imageRequest(url: URL?, authHeader: String?) -> ImageRequest? {
|
||||
guard let url else { return nil }
|
||||
var request = URLRequest(url: url)
|
||||
// Only add auth header for Yattee Server avatar URLs
|
||||
if let authHeader, url.path.contains("/api/v1/channels/") && url.path.contains("/avatar/") {
|
||||
request.setValue(authHeader, forHTTPHeaderField: "Authorization")
|
||||
}
|
||||
return ImageRequest(urlRequest: request)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user