mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Merge pull request #192 from writefreely/ios15-beta-testing
Fix three-column navigation and various iOS 15 glitches
This commit is contained in:
commit
6ba6e39e68
@ -35,7 +35,7 @@ struct ContentView: View {
|
||||
.help("Create a new local draft.")
|
||||
}
|
||||
#else
|
||||
CollectionListView()
|
||||
CollectionListView(selectedCollection: model.selectedCollection)
|
||||
#endif
|
||||
|
||||
#if os(macOS)
|
||||
@ -49,36 +49,13 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
#else
|
||||
PostListView()
|
||||
PostListView(selectedCollection: model.selectedCollection, showAllPosts: model.showAllPosts)
|
||||
#endif
|
||||
|
||||
Text("Select a post, or create a new local draft.")
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.environmentObject(model)
|
||||
|
||||
#if os(iOS)
|
||||
EmptyView()
|
||||
.sheet(
|
||||
isPresented: $model.isPresentingSettingsView,
|
||||
onDismiss: { model.isPresentingSettingsView = false },
|
||||
content: {
|
||||
SettingsView()
|
||||
.environmentObject(model)
|
||||
}
|
||||
)
|
||||
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
|
||||
Alert(
|
||||
title: Text("Connection Error"),
|
||||
message: Text("""
|
||||
There is no internet connection at the moment. Please reconnect or try again later.
|
||||
"""),
|
||||
dismissButton: .default(Text("OK"), action: {
|
||||
model.isPresentingNetworkErrorAlert = false
|
||||
})
|
||||
)
|
||||
})
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
40
Shared/PostCollection/CollectionListModel.swift
Normal file
40
Shared/PostCollection/CollectionListModel.swift
Normal file
@ -0,0 +1,40 @@
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
|
||||
class CollectionListModel: NSObject, ObservableObject {
|
||||
@Published var list: [WFACollection] = []
|
||||
private let collectionsController: NSFetchedResultsController<WFACollection>
|
||||
|
||||
init(managedObjectContext: NSManagedObjectContext) {
|
||||
collectionsController = NSFetchedResultsController(fetchRequest: WFACollection.collectionsFetchRequest,
|
||||
managedObjectContext: managedObjectContext,
|
||||
sectionNameKeyPath: nil,
|
||||
cacheName: nil)
|
||||
|
||||
super.init()
|
||||
|
||||
collectionsController.delegate = self
|
||||
|
||||
do {
|
||||
try collectionsController.performFetch()
|
||||
list = collectionsController.fetchedObjects ?? []
|
||||
} catch {
|
||||
print("Failed to fetch collections!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension CollectionListModel: NSFetchedResultsControllerDelegate {
|
||||
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
|
||||
guard let collections = controller.fetchedObjects as? [WFACollection] else { return }
|
||||
self.list = collections
|
||||
}
|
||||
}
|
||||
|
||||
extension WFACollection {
|
||||
static var collectionsFetchRequest: NSFetchRequest<WFACollection> {
|
||||
let request: NSFetchRequest<WFACollection> = WFACollection.createFetchRequest()
|
||||
request.sortDescriptors = [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)]
|
||||
return request
|
||||
}
|
||||
}
|
@ -2,71 +2,24 @@ import SwiftUI
|
||||
|
||||
struct CollectionListView: View {
|
||||
@EnvironmentObject var model: WriteFreelyModel
|
||||
|
||||
@FetchRequest(
|
||||
entity: WFACollection.entity(),
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)]
|
||||
) var collections: FetchedResults<WFACollection>
|
||||
@ObservedObject var collections = CollectionListModel(managedObjectContext: LocalStorageManager.persistentContainer.viewContext)
|
||||
@State var selectedCollection: WFACollection?
|
||||
|
||||
var body: some View {
|
||||
List(selection: $model.selectedCollection) {
|
||||
List(selection: $selectedCollection) {
|
||||
if model.account.isLoggedIn {
|
||||
NavigationLink(
|
||||
destination: PostListView(),
|
||||
isActive: Binding<Bool>(
|
||||
get: { () -> Bool in
|
||||
model.selectedCollection == nil && model.showAllPosts
|
||||
}, set: { newValue in
|
||||
if newValue {
|
||||
self.model.showAllPosts = true
|
||||
self.model.selectedCollection = nil
|
||||
} else {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
),
|
||||
label: {
|
||||
Text("All Posts")
|
||||
})
|
||||
NavigationLink(
|
||||
destination: PostListView(),
|
||||
isActive: Binding<Bool>(
|
||||
get: { () -> Bool in
|
||||
model.selectedCollection == nil && !model.showAllPosts
|
||||
}, set: { newValue in
|
||||
if newValue {
|
||||
self.model.showAllPosts = false
|
||||
self.model.selectedCollection = nil
|
||||
} else {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
),
|
||||
label: {
|
||||
Text(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")
|
||||
})
|
||||
NavigationLink("All Posts", destination: PostListView(selectedCollection: nil, showAllPosts: true))
|
||||
NavigationLink("Drafts", destination: PostListView(selectedCollection: nil, showAllPosts: false))
|
||||
Section(header: Text("Your Blogs")) {
|
||||
ForEach(collections, id: \.self) { collection in
|
||||
NavigationLink(
|
||||
destination: PostListView(),
|
||||
isActive: Binding<Bool>(
|
||||
get: { () -> Bool in
|
||||
model.selectedCollection == collection && !model.showAllPosts
|
||||
}, set: { newValue in
|
||||
if newValue {
|
||||
self.model.showAllPosts = false
|
||||
self.model.selectedCollection = collection
|
||||
} else {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
),
|
||||
label: { Text(collection.title) }
|
||||
)
|
||||
ForEach(collections.list, id: \.self) { collection in
|
||||
NavigationLink(destination: PostListView(selectedCollection: collection, showAllPosts: false),
|
||||
tag: collection,
|
||||
selection: $selectedCollection,
|
||||
label: { Text("\(collection.title)") })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NavigationLink(destination: PostListView()) {
|
||||
NavigationLink(destination: PostListView(selectedCollection: nil, showAllPosts: false)) {
|
||||
Text("Drafts")
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ struct PostListFilteredView: View {
|
||||
Alert(
|
||||
title: Text("Delete Post?"),
|
||||
message: Text("This action cannot be undone."),
|
||||
primaryButton: .cancel() {
|
||||
primaryButton: .cancel {
|
||||
model.postToDelete = nil
|
||||
},
|
||||
secondaryButton: .destructive(Text("Delete"), action: {
|
||||
|
@ -7,6 +7,9 @@ struct PostListView: View {
|
||||
|
||||
@State private var postCount: Int = 0
|
||||
|
||||
var selectedCollection: WFACollection?
|
||||
var showAllPosts: Bool
|
||||
|
||||
#if os(iOS)
|
||||
private var frameHeight: CGFloat {
|
||||
var height: CGFloat = 50
|
||||
@ -20,12 +23,12 @@ struct PostListView: View {
|
||||
#if os(iOS)
|
||||
ZStack(alignment: .bottom) {
|
||||
PostListFilteredView(
|
||||
collection: model.selectedCollection,
|
||||
showAllPosts: model.showAllPosts,
|
||||
collection: selectedCollection,
|
||||
showAllPosts: showAllPosts,
|
||||
postCount: $postCount
|
||||
)
|
||||
.navigationTitle(
|
||||
model.showAllPosts ? "All Posts" : model.selectedCollection?.title ?? (
|
||||
showAllPosts ? "All Posts" : selectedCollection?.title ?? (
|
||||
model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
|
||||
)
|
||||
)
|
||||
@ -70,9 +73,28 @@ struct PostListView: View {
|
||||
})
|
||||
.accessibilityLabel(Text("Settings"))
|
||||
.accessibilityHint(Text("Open the Settings sheet"))
|
||||
.sheet(
|
||||
isPresented: $model.isPresentingSettingsView,
|
||||
onDismiss: { model.isPresentingSettingsView = false },
|
||||
content: {
|
||||
SettingsView()
|
||||
.environmentObject(model)
|
||||
}
|
||||
)
|
||||
Spacer()
|
||||
Text(postCount == 1 ? "\(postCount) post" : "\(postCount) posts")
|
||||
.foregroundColor(.secondary)
|
||||
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
|
||||
Alert(
|
||||
title: Text("Connection Error"),
|
||||
message: Text("""
|
||||
There is no internet connection at the moment. Please reconnect or try again later.
|
||||
"""),
|
||||
dismissButton: .default(Text("OK"), action: {
|
||||
model.isPresentingNetworkErrorAlert = false
|
||||
})
|
||||
)
|
||||
})
|
||||
Spacer()
|
||||
if model.isProcessingRequest {
|
||||
ProgressView()
|
||||
@ -103,10 +125,14 @@ struct PostListView: View {
|
||||
.overlay(Divider(), alignment: .top)
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
.onAppear {
|
||||
model.selectedCollection = selectedCollection
|
||||
model.showAllPosts = showAllPosts
|
||||
}
|
||||
#else
|
||||
PostListFilteredView(
|
||||
collection: model.selectedCollection,
|
||||
showAllPosts: model.showAllPosts,
|
||||
collection: selectedCollection,
|
||||
showAllPosts: showAllPosts,
|
||||
postCount: $postCount
|
||||
)
|
||||
.toolbar {
|
||||
@ -129,7 +155,7 @@ struct PostListView: View {
|
||||
}
|
||||
}
|
||||
.navigationTitle(
|
||||
model.showAllPosts ? "All Posts" : model.selectedCollection?.title ?? (
|
||||
showAllPosts ? "All Posts" : selectedCollection?.title ?? (
|
||||
model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
|
||||
)
|
||||
)
|
||||
@ -142,7 +168,7 @@ struct PostListView_Previews: PreviewProvider {
|
||||
let context = LocalStorageManager.persistentContainer.viewContext
|
||||
let model = WriteFreelyModel()
|
||||
|
||||
return PostListView()
|
||||
return PostListView(showAllPosts: true)
|
||||
.environment(\.managedObjectContext, context)
|
||||
.environmentObject(model)
|
||||
}
|
||||
|
@ -38,20 +38,22 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
DispatchQueue.main.async {
|
||||
self.model.selectedCollection = nil
|
||||
self.model.showAllPosts = true
|
||||
showLastDraftOrCreateNewLocalPost()
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
self.model.selectedCollection = model.editor.fetchSelectedCollectionFromAppStorage()
|
||||
self.model.showAllPosts = false
|
||||
showLastDraftOrCreateNewLocalPost()
|
||||
}
|
||||
}
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
if model.editor.lastDraftURL != nil {
|
||||
self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
|
||||
} else {
|
||||
createNewLocalPost()
|
||||
}
|
||||
}
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
// if model.editor.lastDraftURL != nil {
|
||||
// self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
|
||||
// } else {
|
||||
// createNewLocalPost()
|
||||
// }
|
||||
// }
|
||||
})
|
||||
.environmentObject(model)
|
||||
.environment(\.managedObjectContext, LocalStorageManager.persistentContainer.viewContext)
|
||||
@ -128,6 +130,14 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
#endif
|
||||
}
|
||||
|
||||
private func showLastDraftOrCreateNewLocalPost() {
|
||||
if model.editor.lastDraftURL != nil {
|
||||
self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
|
||||
} else {
|
||||
createNewLocalPost()
|
||||
}
|
||||
}
|
||||
|
||||
private func createNewLocalPost() {
|
||||
withAnimation {
|
||||
// Un-set the currently selected post
|
||||
|
@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
170A7EC126F5186A00F1CBD4 /* CollectionListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */; };
|
||||
170A7EC226F5186A00F1CBD4 /* CollectionListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */; };
|
||||
170DFA34251BBC44001D82A0 /* PostEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170DFA33251BBC44001D82A0 /* PostEditorModel.swift */; };
|
||||
170DFA35251BBC44001D82A0 /* PostEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170DFA33251BBC44001D82A0 /* PostEditorModel.swift */; };
|
||||
17120DA124E19839002B9F6C /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388D24DDEC7400DEFF9A /* AccountView.swift */; };
|
||||
@ -126,6 +128,7 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1709ADDF251B9A110053AF79 /* EditorLaunchingPolicy.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = EditorLaunchingPolicy.md; sourceTree = "<group>"; };
|
||||
170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionListModel.swift; sourceTree = "<group>"; };
|
||||
170DFA33251BBC44001D82A0 /* PostEditorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorModel.swift; sourceTree = "<group>"; };
|
||||
17120DA424E19CBF002B9F6C /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||
17120DA824E1B2F5002B9F6C /* AccountLogoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLogoutView.swift; sourceTree = "<group>"; };
|
||||
@ -496,6 +499,7 @@
|
||||
17DF32D224C8B78D00BCE2E3 /* PostCollection */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
170A7EC026F5186A00F1CBD4 /* CollectionListModel.swift */,
|
||||
171BFDF924D4AF8300888236 /* CollectionListView.swift */,
|
||||
);
|
||||
path = PostCollection;
|
||||
@ -755,6 +759,7 @@
|
||||
17B996DA2502D23E0017B536 /* WFAPost+CoreDataProperties.swift in Sources */,
|
||||
1756AE7724CB2EDD00FD7257 /* PostEditorView.swift in Sources */,
|
||||
17DF32D524C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */,
|
||||
170A7EC126F5186A00F1CBD4 /* CollectionListModel.swift in Sources */,
|
||||
17D435E824E3128F0036B539 /* PreferencesModel.swift in Sources */,
|
||||
1756AE7A24CB65DF00FD7257 /* PostListView.swift in Sources */,
|
||||
17B996D82502D23E0017B536 /* WFAPost+CoreDataClass.swift in Sources */,
|
||||
@ -791,6 +796,7 @@
|
||||
17C42E662509237800072984 /* PostListFilteredView.swift in Sources */,
|
||||
17120DAD24E1B99F002B9F6C /* AccountLoginView.swift in Sources */,
|
||||
17466626256C0D0600629997 /* MacEditorTextView.swift in Sources */,
|
||||
170A7EC226F5186A00F1CBD4 /* CollectionListModel.swift in Sources */,
|
||||
17E5DF8A2543610700DCDC9B /* PostTextEditingView.swift in Sources */,
|
||||
17C42E71250AAFD500072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
|
||||
1756AE7B24CB65DF00FD7257 /* PostListView.swift in Sources */,
|
||||
|
Loading…
Reference in New Issue
Block a user