Improve widget fetcher

This commit is contained in:
Marcin Czachurski 2023-10-21 13:46:05 +02:00
parent 87951bc674
commit 06af34d4c8
4 changed files with 46 additions and 9 deletions

View File

@ -12,12 +12,14 @@ public extension PixelfedClientAuthenticated {
sinceId: EntityId? = nil,
minId: EntityId? = nil,
limit: Int? = nil,
includeReblogs: Bool? = nil) async throws -> [Status] {
includeReblogs: Bool? = nil,
timeoutInterval: Double? = nil) async throws -> [Status] {
let request = try Self.request(
for: baseURL,
target: Pixelfed.Timelines.home(maxId, sinceId, minId, limit, includeReblogs),
withBearerToken: token
withBearerToken: token,
timeoutInterval: timeoutInterval
)
return try await downloadJson([Status].self, request: request)

View File

@ -50,5 +50,5 @@ Things that should be implemented in version 2.0:
- [x] Move to new Observable macro (iOS 17)
- [x] Migrate to SwiftData (iOS 17)
- [ ] Use ViewModels
- [ ] Add tips (new TipKit framework in iOS 17)
- [x] Add tips (new TipKit framework in iOS 17)
- [ ] Enable swiftlint (https://github.com/realm/SwiftLint/issues/5053)

View File

@ -34,7 +34,7 @@ struct PhotoProvider: TimelineProvider {
}
func getWidgetEntriesForSnapshot() async -> PhotoWidgetEntry {
let entriesFromDatabase = await self.getWidgetEntriesFromServer(length: 1)
let entriesFromDatabase = await self.getWidgetEntriesFromDatabase(length: 1)
if let firstEntry = entriesFromDatabase.first {
return firstEntry
}
@ -48,6 +48,11 @@ struct PhotoProvider: TimelineProvider {
return entriesFromServer
}
let entriesFromDatabase = await self.getWidgetEntriesFromDatabase(length: 3)
if entriesFromDatabase.isEmpty == false {
return entriesFromDatabase
}
return [StatusFetcher.shared.placeholder()]
}
@ -58,4 +63,8 @@ struct PhotoProvider: TimelineProvider {
return []
}
}
func getWidgetEntriesFromDatabase(length: Int) async -> [PhotoWidgetEntry] {
return await StatusFetcher.shared.fetchWidgetEntriesFromDatabase(length: length)
}
}

View File

@ -31,7 +31,37 @@ public class StatusFetcher {
}
let client = PixelfedClient(baseURL: account.serverUrl).getAuthenticated(token: accessToken)
let statuses = try await client.getHomeTimeline(limit: 20, includeReblogs: defaultSettings.showReboostedStatuses)
let statuses = try await client.getHomeTimeline(limit: 20, includeReblogs: defaultSettings.showReboostedStatuses, timeoutInterval: 5.0)
let widgetEntries = await self.prepare(statuses: statuses, length: length)
return widgetEntries
}
@MainActor
func fetchWidgetEntriesFromDatabase(length: Int) async -> [PhotoWidgetEntry] {
let modelContext = SwiftDataHandler.shared.sharedModelContainer.mainContext
let defaultSettings = ApplicationSettingsHandler.shared.get(modelContext: modelContext)
guard let accountId = defaultSettings.currentAccount else {
return [self.placeholder()]
}
let accountData = AccountDataHandler.shared.getAccountData(accountId: accountId, modelContext: modelContext)
guard let timelineCache = accountData?.timelineCache,
let timelineCacheData = timelineCache.data(using: .utf8),
let statusesFromCache = try? JSONDecoder().decode([Status].self, from: timelineCacheData) else {
return [self.placeholder()]
}
let widgetEntries = await self.prepare(statuses: statusesFromCache, length: length)
return widgetEntries
}
func placeholder() -> PhotoWidgetEntry {
PhotoWidgetEntry(date: Date(), image: nil, avatar: nil, displayName: "Caroline Rick", statusId: "")
}
private func prepare(statuses: [Status], length: Int) async -> [PhotoWidgetEntry] {
var widgetEntries: [PhotoWidgetEntry] = []
for status in statuses {
@ -71,8 +101,4 @@ public class StatusFetcher {
return widgetEntries.shuffled()
}
func placeholder() -> PhotoWidgetEntry {
PhotoWidgetEntry(date: Date(), image: nil, avatar: nil, displayName: "Caroline Rick", statusId: "")
}
}