mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Merge pull request #100 from writeas/show-progressview-during-network-requests
Show ProgressView during network requests
This commit is contained in:
commit
a2efef2f72
@ -11,7 +11,8 @@ class WriteFreelyModel: ObservableObject {
|
||||
@Published var posts = PostListModel()
|
||||
@Published var editor = PostEditorModel()
|
||||
@Published var isLoggingIn: Bool = false
|
||||
@Published var hasNetworkConnection: Bool = false
|
||||
@Published var isProcessingRequest: Bool = false
|
||||
@Published var hasNetworkConnection: Bool = true
|
||||
@Published var selectedPost: WFAPost? {
|
||||
didSet {
|
||||
if let post = selectedPost {
|
||||
@ -27,6 +28,7 @@ class WriteFreelyModel: ObservableObject {
|
||||
}
|
||||
@Published var isPresentingDeleteAlert: Bool = false
|
||||
@Published var isPresentingLoginErrorAlert: Bool = false
|
||||
@Published var isPresentingNetworkErrorAlert: Bool = false
|
||||
@Published var postToDelete: WFAPost?
|
||||
#if os(iOS)
|
||||
@Published var isPresentingSettingsView: Bool = false
|
||||
@ -82,6 +84,10 @@ class WriteFreelyModel: ObservableObject {
|
||||
|
||||
extension WriteFreelyModel {
|
||||
func login(to server: URL, as username: String, password: String) {
|
||||
if !hasNetworkConnection {
|
||||
isPresentingNetworkErrorAlert = true
|
||||
return
|
||||
}
|
||||
let secureProtocolPrefix = "https://"
|
||||
let insecureProtocolPrefix = "http://"
|
||||
var serverString = server.absoluteString
|
||||
@ -104,6 +110,10 @@ extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func logout() {
|
||||
if !hasNetworkConnection {
|
||||
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
||||
return
|
||||
}
|
||||
guard let loggedInClient = client else {
|
||||
do {
|
||||
try purgeTokenFromKeychain(username: account.username, server: account.server)
|
||||
@ -117,17 +127,41 @@ extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func fetchUserCollections() {
|
||||
if !hasNetworkConnection {
|
||||
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
||||
return
|
||||
}
|
||||
guard let loggedInClient = client else { return }
|
||||
// We're starting the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = true
|
||||
}
|
||||
loggedInClient.getUserCollections(completion: fetchUserCollectionsHandler)
|
||||
}
|
||||
|
||||
func fetchUserPosts() {
|
||||
if !hasNetworkConnection {
|
||||
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
||||
return
|
||||
}
|
||||
guard let loggedInClient = client else { return }
|
||||
// We're starting the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = true
|
||||
}
|
||||
loggedInClient.getPosts(completion: fetchUserPostsHandler)
|
||||
}
|
||||
|
||||
func publish(post: WFAPost) {
|
||||
if !hasNetworkConnection {
|
||||
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
||||
return
|
||||
}
|
||||
guard let loggedInClient = client else { return }
|
||||
// We're starting the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = true
|
||||
}
|
||||
|
||||
if post.language == nil {
|
||||
if let languageCode = Locale.current.languageCode {
|
||||
@ -166,10 +200,16 @@ extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func updateFromServer(post: WFAPost) {
|
||||
if !hasNetworkConnection {
|
||||
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
||||
return
|
||||
}
|
||||
guard let loggedInClient = client else { return }
|
||||
guard let postId = post.postId else { return }
|
||||
// We're starting the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.selectedPost = post
|
||||
self.isProcessingRequest = true
|
||||
}
|
||||
if let postCollectionAlias = post.collectionAlias,
|
||||
let postSlug = post.slug {
|
||||
@ -180,8 +220,16 @@ extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func move(post: WFAPost, from oldCollection: WFACollection?, to newCollection: WFACollection?) {
|
||||
if !hasNetworkConnection {
|
||||
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
||||
return
|
||||
}
|
||||
guard let loggedInClient = client,
|
||||
let postId = post.postId else { return }
|
||||
// We're starting the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = true
|
||||
}
|
||||
|
||||
post.collectionAlias = newCollection?.alias
|
||||
loggedInClient.movePost(postId: postId, to: newCollection?.alias, completion: movePostHandler)
|
||||
@ -271,6 +319,10 @@ private extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func fetchUserCollectionsHandler(result: Result<[WFCollection], Error>) {
|
||||
// We're done with the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = false
|
||||
}
|
||||
do {
|
||||
let fetchedCollections = try result.get()
|
||||
for fetchedCollection in fetchedCollections {
|
||||
@ -294,6 +346,10 @@ private extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func fetchUserPostsHandler(result: Result<[WFPost], Error>) {
|
||||
// We're done with the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = false
|
||||
}
|
||||
do {
|
||||
var postsToDelete = posts.userPosts.filter { $0.status != PostStatus.local.rawValue }
|
||||
let fetchedPosts = try result.get()
|
||||
@ -336,6 +392,10 @@ private extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func publishHandler(result: Result<WFPost, Error>) {
|
||||
// We're done with the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = false
|
||||
}
|
||||
// ⚠️ NOTE:
|
||||
// The API does not return a collection alias, so we take care not to overwrite the
|
||||
// cached post's collection alias with the 'nil' value from the fetched post.
|
||||
@ -366,6 +426,10 @@ private extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func updateFromServerHandler(result: Result<WFPost, Error>) {
|
||||
// We're done with the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = false
|
||||
}
|
||||
// ⚠️ NOTE:
|
||||
// The API does not return a collection alias, so we take care not to overwrite the
|
||||
// cached post's collection alias with the 'nil' value from the fetched post.
|
||||
@ -393,6 +457,10 @@ private extension WriteFreelyModel {
|
||||
}
|
||||
|
||||
func movePostHandler(result: Result<Bool, Error>) {
|
||||
// We're done with the network request.
|
||||
DispatchQueue.main.async {
|
||||
self.isProcessingRequest = false
|
||||
}
|
||||
do {
|
||||
let succeeded = try result.get()
|
||||
if succeeded {
|
||||
|
@ -55,6 +55,15 @@ struct ContentView: View {
|
||||
}
|
||||
)
|
||||
}
|
||||
.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
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
#if os(iOS)
|
||||
EmptyView()
|
||||
|
@ -35,12 +35,16 @@ struct PostListView: View {
|
||||
Text(pluralizedPostCount(for: showPosts(for: selectedCollection)))
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
Button(action: {
|
||||
reloadFromServer()
|
||||
}, label: {
|
||||
Image(systemName: "arrow.clockwise")
|
||||
})
|
||||
.disabled(!model.account.isLoggedIn || !model.hasNetworkConnection)
|
||||
if model.isProcessingRequest {
|
||||
ProgressView()
|
||||
} else {
|
||||
Button(action: {
|
||||
reloadFromServer()
|
||||
}, label: {
|
||||
Image(systemName: "arrow.clockwise")
|
||||
})
|
||||
.disabled(!model.account.isLoggedIn)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.frame(width: geometry.size.width)
|
||||
@ -66,7 +70,7 @@ struct PostListView: View {
|
||||
}, label: {
|
||||
Image(systemName: "arrow.clockwise")
|
||||
})
|
||||
.disabled(!model.account.isLoggedIn || !model.hasNetworkConnection)
|
||||
.disabled(!model.account.isLoggedIn)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -153,7 +153,10 @@ struct PostEditorView: View {
|
||||
PostEditorStatusToolbarView(post: post)
|
||||
}
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
Menu(content: {
|
||||
if model.isProcessingRequest {
|
||||
ProgressView()
|
||||
} else {
|
||||
Menu(content: {
|
||||
if post.status == PostStatus.local.rawValue {
|
||||
Menu(content: {
|
||||
Label("Publish to…", systemImage: "paperplane")
|
||||
@ -192,12 +195,7 @@ struct PostEditorView: View {
|
||||
}, label: {
|
||||
Label("Publish", systemImage: "paperplane")
|
||||
})
|
||||
.disabled(
|
||||
post.status ==
|
||||
PostStatus.published.rawValue ||
|
||||
!model.hasNetworkConnection ||
|
||||
post.body.count == 0
|
||||
)
|
||||
.disabled(post.status == PostStatus.published.rawValue || post.body.count == 0)
|
||||
}
|
||||
Button(action: {
|
||||
sharePost()
|
||||
@ -226,6 +224,7 @@ struct PostEditorView: View {
|
||||
}, label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: post.hasNewerRemoteCopy, perform: { _ in
|
||||
|
@ -143,9 +143,7 @@ struct PostEditorView: View {
|
||||
}, label: {
|
||||
Image(systemName: "paperplane")
|
||||
})
|
||||
.disabled(
|
||||
post.status == PostStatus.published.rawValue || !model.hasNetworkConnection || post.body.count == 0
|
||||
)
|
||||
.disabled(post.status == PostStatus.published.rawValue || || post.body.count == 0)
|
||||
}
|
||||
}
|
||||
.onChange(of: post.hasNewerRemoteCopy, perform: { _ in
|
||||
|
Loading…
Reference in New Issue
Block a user