Migrate LocalTimeline to SwiftData

This commit is contained in:
Thomas Ricouard 2023-09-22 12:49:25 +02:00
parent cb1b5b69df
commit 527d982dce
8 changed files with 46 additions and 26 deletions

View file

@ -124,6 +124,7 @@ extension View {
func withModelContainer() -> some View { func withModelContainer() -> some View {
modelContainer(for: [ modelContainer(for: [
Draft.self, Draft.self,
LocalTimeline.self,
]) ])
} }
} }

View file

@ -8,10 +8,12 @@ import Network
import Nuke import Nuke
import SwiftUI import SwiftUI
import Timeline import Timeline
import SwiftData
@MainActor @MainActor
struct SettingsTabs: View { struct SettingsTabs: View {
@Environment(\.dismiss) private var dismiss @Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var context
@Environment(PushNotificationsService.self) private var pushNotifications @Environment(PushNotificationsService.self) private var pushNotifications
@Environment(UserPreferences.self) private var preferences @Environment(UserPreferences.self) private var preferences
@ -28,6 +30,8 @@ struct SettingsTabs: View {
@Binding var popToRootTab: Tab @Binding var popToRootTab: Tab
@Query(sort: \LocalTimeline.creationDate, order: .reverse) var localTimelines: [LocalTimeline]
var body: some View { var body: some View {
NavigationStack(path: $routerPath.path) { NavigationStack(path: $routerPath.path) {
Form { Form {
@ -303,16 +307,13 @@ struct SettingsTabs: View {
private var remoteLocalTimelinesView: some View { private var remoteLocalTimelinesView: some View {
Form { Form {
ForEach(preferences.remoteLocalTimelines, id: \.self) { server in ForEach(localTimelines) { timeline in
Text(server) Text(timeline.instance)
}.onDelete { indexes in }.onDelete { indexes in
if let index = indexes.first { if let index = indexes.first {
_ = preferences.remoteLocalTimelines.remove(at: index) context.delete(localTimelines[index])
} }
} }
.onMove(perform: { indices, newOffset in
moveTimelineItems(from: indices, to: newOffset)
})
.listRowBackground(theme.primaryBackgroundColor) .listRowBackground(theme.primaryBackgroundColor)
Button { Button {
routerPath.presentedSheet = .addRemoteLocalTimeline routerPath.presentedSheet = .addRemoteLocalTimeline
@ -329,10 +330,6 @@ struct SettingsTabs: View {
} }
} }
private func moveTimelineItems(from source: IndexSet, to destination: Int) {
preferences.remoteLocalTimelines.move(fromOffsets: source, toOffset: destination)
}
private var cacheSection: some View { private var cacheSection: some View {
Section("settings.section.cache") { Section("settings.section.cache") {
if cachedRemoved { if cachedRemoved {

View file

@ -10,6 +10,7 @@ import SwiftUI
@MainActor @MainActor
struct AddRemoteTimelineView: View { struct AddRemoteTimelineView: View {
@Environment(\.dismiss) private var dismiss @Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var context
@Environment(UserPreferences.self) private var preferences @Environment(UserPreferences.self) private var preferences
@Environment(Theme.self) private var theme @Environment(Theme.self) private var theme
@ -39,7 +40,7 @@ struct AddRemoteTimelineView: View {
} }
Button { Button {
guard instance != nil else { return } guard instance != nil else { return }
preferences.remoteLocalTimelines.append(instanceName) context.insert(LocalTimeline(instance: instanceName))
dismiss() dismiss()
} label: { } label: {
Text("timeline.add.action.add") Text("timeline.add.action.add")

View file

@ -6,9 +6,12 @@ import Models
import Network import Network
import SwiftUI import SwiftUI
import Timeline import Timeline
import SwiftData
@MainActor @MainActor
struct TimelineTab: View { struct TimelineTab: View {
@Environment(\.modelContext) private var context
@Environment(AppAccountsManager.self) private var appAccount @Environment(AppAccountsManager.self) private var appAccount
@Environment(Theme.self) private var theme @Environment(Theme.self) private var theme
@Environment(CurrentAccount.self) private var currentAccount @Environment(CurrentAccount.self) private var currentAccount
@ -18,17 +21,20 @@ struct TimelineTab: View {
@Binding var popToRootTab: Tab @Binding var popToRootTab: Tab
@State private var didAppear: Bool = false @State private var didAppear: Bool = false
@State private var timeline: TimelineFilter @State private var timeline: TimelineFilter = .home
@State private var scrollToTopSignal: Int = 0 @State private var scrollToTopSignal: Int = 0
@AppStorage("last_timeline_filter") public var lastTimelineFilter: TimelineFilter = .home @Query(sort: \LocalTimeline.creationDate, order: .reverse) var localTimelines: [LocalTimeline]
@AppStorage("remote_local_timeline") var legacyLocalTimelines: [String] = []
@AppStorage("last_timeline_filter") var lastTimelineFilter: TimelineFilter = .home
private let canFilterTimeline: Bool private let canFilterTimeline: Bool
init(popToRootTab: Binding<Tab>, timeline: TimelineFilter? = nil) { init(popToRootTab: Binding<Tab>, timeline: TimelineFilter? = nil) {
canFilterTimeline = timeline == nil canFilterTimeline = timeline == nil
self.timeline = timeline ?? .home
_popToRootTab = popToRootTab _popToRootTab = popToRootTab
self.timeline = timeline ?? .home
} }
var body: some View { var body: some View {
@ -43,6 +49,7 @@ struct TimelineTab: View {
.id(client.id) .id(client.id)
} }
.onAppear { .onAppear {
migrateUserPreferencesTimeline()
routerPath.client = client routerPath.client = client
if !didAppear, canFilterTimeline { if !didAppear, canFilterTimeline {
didAppear = true didAppear = true
@ -129,12 +136,12 @@ struct TimelineTab: View {
} }
Menu("timeline.filter.local") { Menu("timeline.filter.local") {
ForEach(preferences.remoteLocalTimelines, id: \.self) { server in ForEach(localTimelines) { remoteLocal in
Button { Button {
timeline = .remoteLocal(server: server, filter: .local) timeline = .remoteLocal(server: remoteLocal.instance, filter: .local)
} label: { } label: {
VStack { VStack {
Label(server, systemImage: "dot.radiowaves.right") Label(remoteLocal.instance, systemImage: "dot.radiowaves.right")
} }
} }
} }
@ -235,4 +242,11 @@ struct TimelineTab: View {
timeline = .federated timeline = .federated
} }
} }
func migrateUserPreferencesTimeline() {
for instance in legacyLocalTimelines {
context.insert(LocalTimeline(instance: instance))
}
legacyLocalTimelines = []
}
} }

View file

@ -7,7 +7,6 @@ import SwiftUI
@MainActor @MainActor
@Observable public class UserPreferences { @Observable public class UserPreferences {
class Storage { class Storage {
@AppStorage("remote_local_timeline") public var remoteLocalTimelines: [String] = []
@AppStorage("tag_groups") public var tagGroups: [TagGroup] = [] @AppStorage("tag_groups") public var tagGroups: [TagGroup] = []
@AppStorage("preferred_browser") public var preferredBrowser: PreferredBrowser = .inAppSafari @AppStorage("preferred_browser") public var preferredBrowser: PreferredBrowser = .inAppSafari
@AppStorage("show_translate_button_inline") public var showTranslateButton: Bool = true @AppStorage("show_translate_button_inline") public var showTranslateButton: Bool = true
@ -63,11 +62,6 @@ import SwiftUI
private var client: Client? private var client: Client?
public var remoteLocalTimelines: [String] {
didSet {
storage.remoteLocalTimelines = remoteLocalTimelines
}
}
public var tagGroups: [TagGroup] { public var tagGroups: [TagGroup] {
didSet { didSet {
storage.tagGroups = tagGroups storage.tagGroups = tagGroups
@ -371,7 +365,6 @@ import SwiftUI
} }
private init() { private init() {
remoteLocalTimelines = storage.remoteLocalTimelines
tagGroups = storage.tagGroups tagGroups = storage.tagGroups
preferredBrowser = storage.preferredBrowser preferredBrowser = storage.preferredBrowser
showTranslateButton = storage.showTranslateButton showTranslateButton = storage.showTranslateButton

View file

@ -2,7 +2,7 @@ import SwiftData
import SwiftUI import SwiftUI
import Foundation import Foundation
@Model public class Draft: Identifiable { @Model public class Draft {
@Attribute(.unique) public var id: UUID @Attribute(.unique) public var id: UUID
public var content: String public var content: String
public var creationDate: Date public var creationDate: Date

View file

@ -0,0 +1,13 @@
import SwiftData
import SwiftUI
import Foundation
@Model public class LocalTimeline {
public var instance: String
public var creationDate: Date
public init(instance: String) {
self.instance = instance
self.creationDate = Date()
}
}

View file

@ -1,6 +1,7 @@
import SwiftUI import SwiftUI
import SwiftData import SwiftData
import DesignSystem import DesignSystem
import Models
struct DraftsListView: View { struct DraftsListView: View {
@AppStorage("draft_posts") public var legacyDraftPosts: [String] = [] @AppStorage("draft_posts") public var legacyDraftPosts: [String] = []