Impressia/VernissageWidget/ImageFetcher.swift

107 lines
3.4 KiB
Swift
Raw Normal View History

2023-03-11 18:30:33 +01:00
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
2023-03-28 10:35:38 +02:00
// Licensed under the Apache License 2.0.
2023-03-11 18:30:33 +01:00
//
import Foundation
import SwiftUI
import PixelfedKit
public class ImageFetcher {
public static let shared = ImageFetcher()
private init() { }
2023-03-11 18:53:58 +01:00
private let maxImageSize = 1000.0
2023-03-13 13:53:36 +01:00
func fetchWidgetEntries(length: Int = 8) async throws -> [WidgetEntry] {
2023-03-15 14:27:59 +01:00
let defaultSettings = ApplicationSettingsHandler.shared.get()
2023-03-11 18:30:33 +01:00
guard let accountId = defaultSettings.currentAccount else {
return [self.placeholder()]
}
2023-03-11 18:30:33 +01:00
guard let account = AccountDataHandler.shared.getAccountData(accountId: accountId) else {
return [self.placeholder()]
}
2023-03-11 18:30:33 +01:00
guard let accessToken = account.accessToken else {
return [self.placeholder()]
}
2023-03-11 18:30:33 +01:00
let client = PixelfedClient(baseURL: account.serverUrl).getAuthenticated(token: accessToken)
2023-03-13 13:53:36 +01:00
let statuses = try await client.getHomeTimeline(limit: 20)
2023-03-11 18:30:33 +01:00
var widgetEntries: [WidgetEntry] = []
2023-03-11 18:30:33 +01:00
for status in statuses {
// When we have images for next hour we can skip.
if widgetEntries.count == length {
break
}
2023-03-11 18:30:33 +01:00
// We have to skip sensitive (we cannot show them on iPhone home screen).
if status.sensitive {
continue
}
2023-03-11 18:30:33 +01:00
guard let imageAttachment = status.mediaAttachments.first(where: { $0.type == .image }) else {
continue
}
2023-03-11 18:30:33 +01:00
let uiImage = await self.getImage(url: imageAttachment.url)
let uiAvatar = await self.getImage(url: status.account.avatar)
guard let uiImage, let uiAvatar else {
continue
}
2023-03-13 13:53:36 +01:00
let displayDate = Calendar.current.date(byAdding: .minute, value: widgetEntries.count * 15, to: Date())
2023-03-11 18:30:33 +01:00
widgetEntries.append(WidgetEntry(date: displayDate ?? Date(),
image: uiImage,
avatar: uiAvatar,
displayName: status.account.displayNameWithoutEmojis,
statusId: status.id))
}
2023-03-11 18:30:33 +01:00
if widgetEntries.isEmpty {
widgetEntries.append(self.placeholder())
}
2023-03-11 18:30:33 +01:00
return widgetEntries
}
2023-03-11 18:30:33 +01:00
func placeholder() -> WidgetEntry {
WidgetEntry(date: Date(), image: nil, avatar: nil, displayName: "Caroline Rick", statusId: "")
2023-03-11 18:30:33 +01:00
}
2023-03-11 18:30:33 +01:00
private func getImage(url: URL?) async -> UIImage? {
guard let url else {
return nil
}
2023-03-11 18:30:33 +01:00
do {
let (data, response) = try await URLSession.shared.data(from: url)
2023-03-11 18:53:58 +01:00
guard (response as? HTTPURLResponse)?.status?.responseType == .success else {
return nil
2023-03-11 18:30:33 +01:00
}
2023-03-11 18:53:58 +01:00
guard let uiImage = UIImage(data: data) else {
return nil
}
2023-03-11 18:53:58 +01:00
if uiImage.size.width < self.maxImageSize && uiImage.size.height < self.maxImageSize {
return uiImage
}
2023-03-11 18:53:58 +01:00
if uiImage.size.width > uiImage.size.height {
return uiImage.resized(toWidth: self.maxImageSize)
} else {
return uiImage.resized(toHeight: self.maxImageSize)
}
2023-03-11 18:30:33 +01:00
} catch {
return nil
}
}
}