perf: add-new-feed UI

This commit is contained in:
Duong Thai 2024-03-12 17:51:36 +07:00
parent c9d8d85ef5
commit 52655c6d11
4 changed files with 39 additions and 7 deletions

View file

@ -13,6 +13,7 @@ import RSS
import Env
import Network
import AppAccount
import CoreData
@MainActor
public struct RSSTab: View {
@ -39,6 +40,10 @@ public struct RSSTab: View {
.navigationBarTitleDisplayMode(.inline)
.listStyle(PlainListStyle())
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
.onReceive(NotificationCenter.default.publisher(for: .NSManagedObjectContextDidSave)) { notification in
let userInfo = notification.userInfo ?? [:]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: userInfo, into: [moContext])
}
.toolbar {
if client.isAuth {
ToolbarItem(placement: .navigationBarLeading) {

View file

@ -12,6 +12,8 @@ public class RSSDataController {
private static let modelName = "RSSModel"
public let container: NSPersistentContainer
public var viewContext: NSManagedObjectContext { container.viewContext }
public let backgroundContext: NSManagedObjectContext
public static let shared = RSSDataController()
private init() {
@ -34,5 +36,7 @@ public class RSSDataController {
}
}
self.container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyStoreTrump
self.backgroundContext = container.newBackgroundContext()
self.backgroundContext.mergePolicy = NSMergePolicy.mergeByPropertyStoreTrump
}
}

View file

@ -189,6 +189,30 @@ public enum RSSTools {
rssFeed.items = NSSet(array: rssItems)
return rssFeed
}
@MainActor
public static func load(feedURL: URL) async -> RSSFeed? {
let sendableFeed = await Task.detached {
await RSSTools.getFeedData(from: feedURL)
}.value
guard let sendableFeed else { return nil }
let backgroundContext = RSSDataController.shared.backgroundContext
let sendableItems = await Task.detached {
await sendableFeed.getSendableItemData()
}.value
return await backgroundContext.perform {
let rssFeed = RSSFeed(context: backgroundContext, sendableData: sendableFeed)
let rssItems = sendableItems.compactMap {
RSSItem(context: backgroundContext, sendableData: $0)
}
rssFeed.items = NSSet(array: rssItems)
return rssFeed
}
}
}
private struct Icon {

View file

@ -9,7 +9,6 @@ import SwiftUI
import CoreData
public struct RSSAddNewFeed: View {
@Environment(\.managedObjectContext) private var moContext
@Environment(\.dismiss) private var dismiss
@State private var state: MachineState = .emptyInput
@ -35,7 +34,7 @@ public struct RSSAddNewFeed: View {
ToolbarItem(placement: .topBarLeading) {
Button {
dismiss()
moContext.rollback()
feed?.managedObjectContext?.rollback()
} label: {
Image(systemName: "xmark")
}
@ -44,7 +43,7 @@ public struct RSSAddNewFeed: View {
ToolbarItem(placement: .topBarTrailing) {
Button("rss.addNewFeed.action.add") {
dismiss()
try? moContext.save()
try? feed?.managedObjectContext?.save()
}
}
}
@ -55,10 +54,10 @@ public struct RSSAddNewFeed: View {
switch state {
case .downloading(let url):
downloadingTask?.cancel()
moContext.rollback()
feed?.managedObjectContext?.rollback()
downloadingTask = Task {
let rssFeed = await RSSTools.load(feedURL: url, into: moContext)
let rssFeed = await RSSTools.load(feedURL: url)
if Task.isCancelled { return }
if let rssFeed { self.state = .downloaded(feed: rssFeed, url: url) }
else { self.state = .noData(url: url) }
@ -67,10 +66,10 @@ public struct RSSAddNewFeed: View {
self.feed = feed
default:
downloadingTask?.cancel()
moContext.rollback()
feed?.managedObjectContext?.rollback()
}
}
.onDisappear { moContext.rollback() }
.onDisappear { feed?.managedObjectContext?.rollback() }
}
}