Skip to content

Commit 3c1e04e

Browse files
committed
Use view model for CollectionListView
1 parent 28856eb commit 3c1e04e

File tree

7 files changed

+107
-138
lines changed

7 files changed

+107
-138
lines changed

Shared/Navigation/ContentView.swift

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,7 @@ struct ContentView: View {
3535
.help("Create a new local draft.")
3636
}
3737
#else
38-
if #available(iOS 15.0, *) {
39-
CollectionListView()
40-
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
41-
Alert(
42-
title: Text("Connection Error"),
43-
message: Text("""
44-
There is no internet connection at the moment. Please reconnect or try again later.
45-
"""),
46-
dismissButton: .default(Text("OK"), action: {
47-
model.isPresentingNetworkErrorAlert = false
48-
})
49-
)
50-
})
51-
} else {
52-
CollectionListView()
53-
}
38+
CollectionListView(selectedCollection: model.selectedCollection)
5439
#endif
5540

5641
#if os(macOS)
@@ -64,50 +49,13 @@ struct ContentView: View {
6449
}
6550
}
6651
#else
67-
if #available(iOS 15.0, *) {
68-
PostListView()
69-
.sheet(
70-
isPresented: $model.isPresentingSettingsView,
71-
onDismiss: { model.isPresentingSettingsView = false },
72-
content: {
73-
SettingsView()
74-
.environmentObject(model)
75-
}
76-
)
77-
} else {
78-
PostListView()
79-
}
52+
PostListView(selectedCollection: nil, showAllPosts: false)
8053
#endif
8154

8255
Text("Select a post, or create a new local draft.")
8356
.foregroundColor(.secondary)
8457
}
8558
.environmentObject(model)
86-
// For iOS 14
87-
if #available(iOS 15.0, *) {
88-
// Do nothing.
89-
} else {
90-
EmptyView()
91-
.sheet(
92-
isPresented: $model.isPresentingSettingsView,
93-
onDismiss: { model.isPresentingSettingsView = false },
94-
content: {
95-
SettingsView()
96-
.environmentObject(model)
97-
}
98-
)
99-
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
100-
Alert(
101-
title: Text("Connection Error"),
102-
message: Text("""
103-
There is no internet connection at the moment. Please reconnect or try again later.
104-
"""),
105-
dismissButton: .default(Text("OK"), action: {
106-
model.isPresentingNetworkErrorAlert = false
107-
})
108-
)
109-
})
110-
}
11159
}
11260
}
11361

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import SwiftUI
2+
import CoreData
3+
4+
class CollectionListModel: NSObject, ObservableObject {
5+
@Published var list: [WFACollection] = []
6+
private let collectionsController: NSFetchedResultsController<WFACollection>
7+
8+
init(managedObjectContext: NSManagedObjectContext) {
9+
collectionsController = NSFetchedResultsController(fetchRequest: WFACollection.collectionsFetchRequest,
10+
managedObjectContext: managedObjectContext,
11+
sectionNameKeyPath: nil,
12+
cacheName: nil)
13+
14+
super.init()
15+
16+
collectionsController.delegate = self
17+
18+
do {
19+
try collectionsController.performFetch()
20+
list = collectionsController.fetchedObjects ?? []
21+
} catch {
22+
print("Failed to fetch collections!")
23+
}
24+
}
25+
}
26+
27+
extension CollectionListModel: NSFetchedResultsControllerDelegate {
28+
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
29+
guard let collections = controller.fetchedObjects as? [WFACollection] else { return }
30+
self.list = collections
31+
}
32+
}
33+
34+
extension WFACollection {
35+
static var collectionsFetchRequest: NSFetchRequest<WFACollection> {
36+
let request: NSFetchRequest<WFACollection> = WFACollection.createFetchRequest()
37+
request.sortDescriptors = [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)]
38+
return request
39+
}
40+
}

Shared/PostCollection/CollectionListView.swift

Lines changed: 11 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,24 @@ import SwiftUI
22

33
struct CollectionListView: View {
44
@EnvironmentObject var model: WriteFreelyModel
5-
6-
@FetchRequest(
7-
entity: WFACollection.entity(),
8-
sortDescriptors: [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)]
9-
) var collections: FetchedResults<WFACollection>
5+
@ObservedObject var collections = CollectionListModel(managedObjectContext: LocalStorageManager.persistentContainer.viewContext)
6+
@State var selectedCollection: WFACollection?
107

118
var body: some View {
12-
List(selection: $model.selectedCollection) {
9+
List(selection: $selectedCollection) {
1310
if model.account.isLoggedIn {
14-
NavigationLink(
15-
destination: PostListView(),
16-
isActive: Binding<Bool>(
17-
get: { () -> Bool in
18-
model.selectedCollection == nil && model.showAllPosts
19-
}, set: { newValue in
20-
if newValue {
21-
self.model.showAllPosts = true
22-
self.model.selectedCollection = nil
23-
} else {
24-
// No-op
25-
}
26-
}
27-
),
28-
label: {
29-
Text("All Posts")
30-
})
31-
NavigationLink(
32-
destination: PostListView(),
33-
isActive: Binding<Bool>(
34-
get: { () -> Bool in
35-
model.selectedCollection == nil && !model.showAllPosts
36-
}, set: { newValue in
37-
if newValue {
38-
self.model.showAllPosts = false
39-
self.model.selectedCollection = nil
40-
} else {
41-
// No-op
42-
}
43-
}
44-
),
45-
label: {
46-
Text(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")
47-
})
11+
NavigationLink("All Posts", destination: PostListView(selectedCollection: nil, showAllPosts: true))
12+
NavigationLink("Drafts", destination: PostListView(selectedCollection: nil, showAllPosts: false))
4813
Section(header: Text("Your Blogs")) {
49-
ForEach(collections, id: \.self) { collection in
50-
NavigationLink(
51-
destination: PostListView(),
52-
isActive: Binding<Bool>(
53-
get: { () -> Bool in
54-
model.selectedCollection == collection && !model.showAllPosts
55-
}, set: { newValue in
56-
if newValue {
57-
self.model.showAllPosts = false
58-
self.model.selectedCollection = collection
59-
} else {
60-
// No-op
61-
}
62-
}
63-
),
64-
label: { Text(collection.title) }
65-
)
14+
ForEach(collections.list, id: \.self) { collection in
15+
NavigationLink(destination: PostListView(selectedCollection: collection, showAllPosts: false),
16+
tag: collection,
17+
selection: $selectedCollection,
18+
label: { Text("\(collection.title)") })
6619
}
6720
}
6821
} else {
69-
NavigationLink(destination: PostListView()) {
22+
NavigationLink(destination: PostListView(selectedCollection: nil, showAllPosts: false)) {
7023
Text("Drafts")
7124
}
7225
}

Shared/PostList/PostListFilteredView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ struct PostListFilteredView: View {
9797
Alert(
9898
title: Text("Delete Post?"),
9999
message: Text("This action cannot be undone."),
100-
primaryButton: .cancel() {
100+
primaryButton: .cancel {
101101
model.postToDelete = nil
102102
},
103103
secondaryButton: .destructive(Text("Delete"), action: {

Shared/PostList/PostListView.swift

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ struct PostListView: View {
77

88
@State private var postCount: Int = 0
99

10+
var selectedCollection: WFACollection?
11+
var showAllPosts: Bool
12+
1013
#if os(iOS)
1114
private var frameHeight: CGFloat {
1215
var height: CGFloat = 50
@@ -20,12 +23,12 @@ struct PostListView: View {
2023
#if os(iOS)
2124
ZStack(alignment: .bottom) {
2225
PostListFilteredView(
23-
collection: model.selectedCollection,
24-
showAllPosts: model.showAllPosts,
26+
collection: selectedCollection,
27+
showAllPosts: showAllPosts,
2528
postCount: $postCount
2629
)
2730
.navigationTitle(
28-
model.showAllPosts ? "All Posts" : model.selectedCollection?.title ?? (
31+
showAllPosts ? "All Posts" : selectedCollection?.title ?? (
2932
model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
3033
)
3134
)
@@ -70,9 +73,28 @@ struct PostListView: View {
7073
})
7174
.accessibilityLabel(Text("Settings"))
7275
.accessibilityHint(Text("Open the Settings sheet"))
76+
.sheet(
77+
isPresented: $model.isPresentingSettingsView,
78+
onDismiss: { model.isPresentingSettingsView = false },
79+
content: {
80+
SettingsView()
81+
.environmentObject(model)
82+
}
83+
)
7384
Spacer()
7485
Text(postCount == 1 ? "\(postCount) post" : "\(postCount) posts")
7586
.foregroundColor(.secondary)
87+
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
88+
Alert(
89+
title: Text("Connection Error"),
90+
message: Text("""
91+
There is no internet connection at the moment. Please reconnect or try again later.
92+
"""),
93+
dismissButton: .default(Text("OK"), action: {
94+
model.isPresentingNetworkErrorAlert = false
95+
})
96+
)
97+
})
7698
Spacer()
7799
if model.isProcessingRequest {
78100
ProgressView()
@@ -105,8 +127,8 @@ struct PostListView: View {
105127
.ignoresSafeArea()
106128
#else
107129
PostListFilteredView(
108-
collection: model.selectedCollection,
109-
showAllPosts: model.showAllPosts,
130+
collection: selectedCollection,
131+
showAllPosts: showAllPosts,
110132
postCount: $postCount
111133
)
112134
.toolbar {
@@ -129,7 +151,7 @@ struct PostListView: View {
129151
}
130152
}
131153
.navigationTitle(
132-
model.showAllPosts ? "All Posts" : model.selectedCollection?.title ?? (
154+
showAllPosts ? "All Posts" : selectedCollection?.title ?? (
133155
model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
134156
)
135157
)
@@ -142,7 +164,7 @@ struct PostListView_Previews: PreviewProvider {
142164
let context = LocalStorageManager.persistentContainer.viewContext
143165
let model = WriteFreelyModel()
144166

145-
return PostListView()
167+
return PostListView(showAllPosts: true)
146168
.environment(\.managedObjectContext, context)
147169
.environmentObject(model)
148170
}

Shared/WriteFreely_MultiPlatformApp.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,24 @@ struct WriteFreely_MultiPlatformApp: App {
3434
WindowGroup {
3535
ContentView()
3636
.onAppear(perform: {
37-
if model.editor.showAllPostsFlag {
38-
DispatchQueue.main.async {
39-
self.model.selectedCollection = nil
40-
self.model.showAllPosts = true
41-
}
42-
} else {
43-
DispatchQueue.main.async {
44-
self.model.selectedCollection = model.editor.fetchSelectedCollectionFromAppStorage()
45-
self.model.showAllPosts = false
46-
}
47-
}
48-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
49-
if model.editor.lastDraftURL != nil {
50-
self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
51-
} else {
52-
createNewLocalPost()
53-
}
54-
}
37+
// if model.editor.showAllPostsFlag {
38+
// DispatchQueue.main.async {
39+
// self.model.selectedCollection = nil
40+
// self.model.showAllPosts = true
41+
// }
42+
// } else {
43+
// DispatchQueue.main.async {
44+
// self.model.selectedCollection = model.editor.fetchSelectedCollectionFromAppStorage()
45+
// self.model.showAllPosts = false
46+
// }
47+
// }
48+
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
49+
// if model.editor.lastDraftURL != nil {
50+
// self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
51+
// } else {
52+
// createNewLocalPost()
53+
// }
54+
// }
5555
})
5656
.environmentObject(model)
5757
.environment(\.managedObjectContext, LocalStorageManager.persistentContainer.viewContext)

WriteFreely-MultiPlatform.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
170A7EC126F5186A00F1CBD4 /* CollectionListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */; };
11+
170A7EC226F5186A00F1CBD4 /* CollectionListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */; };
1012
170DFA34251BBC44001D82A0 /* PostEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170DFA33251BBC44001D82A0 /* PostEditorModel.swift */; };
1113
170DFA35251BBC44001D82A0 /* PostEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170DFA33251BBC44001D82A0 /* PostEditorModel.swift */; };
1214
17120DA124E19839002B9F6C /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388D24DDEC7400DEFF9A /* AccountView.swift */; };
@@ -126,6 +128,7 @@
126128

127129
/* Begin PBXFileReference section */
128130
1709ADDF251B9A110053AF79 /* EditorLaunchingPolicy.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = EditorLaunchingPolicy.md; sourceTree = "<group>"; };
131+
170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionListModel.swift; sourceTree = "<group>"; };
129132
170DFA33251BBC44001D82A0 /* PostEditorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorModel.swift; sourceTree = "<group>"; };
130133
17120DA424E19CBF002B9F6C /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
131134
17120DA824E1B2F5002B9F6C /* AccountLogoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLogoutView.swift; sourceTree = "<group>"; };
@@ -496,6 +499,7 @@
496499
17DF32D224C8B78D00BCE2E3 /* PostCollection */ = {
497500
isa = PBXGroup;
498501
children = (
502+
170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */,
499503
171BFDF924D4AF8300888236 /* CollectionListView.swift */,
500504
);
501505
path = PostCollection;
@@ -755,6 +759,7 @@
755759
17B996DA2502D23E0017B536 /* WFAPost+CoreDataProperties.swift in Sources */,
756760
1756AE7724CB2EDD00FD7257 /* PostEditorView.swift in Sources */,
757761
17DF32D524C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */,
762+
170A7EC126F5186A00F1CBD4 /* CollectionListModel.swift in Sources */,
758763
17D435E824E3128F0036B539 /* PreferencesModel.swift in Sources */,
759764
1756AE7A24CB65DF00FD7257 /* PostListView.swift in Sources */,
760765
17B996D82502D23E0017B536 /* WFAPost+CoreDataClass.swift in Sources */,
@@ -791,6 +796,7 @@
791796
17C42E662509237800072984 /* PostListFilteredView.swift in Sources */,
792797
17120DAD24E1B99F002B9F6C /* AccountLoginView.swift in Sources */,
793798
17466626256C0D0600629997 /* MacEditorTextView.swift in Sources */,
799+
170A7EC226F5186A00F1CBD4 /* CollectionListModel.swift in Sources */,
794800
17E5DF8A2543610700DCDC9B /* PostTextEditingView.swift in Sources */,
795801
17C42E71250AAFD500072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
796802
1756AE7B24CB65DF00FD7257 /* PostListView.swift in Sources */,

0 commit comments

Comments
 (0)