Error state UI

This commit is contained in:
Thomas Ricouard 2023-01-07 18:01:06 +01:00
parent f9f6ffc71e
commit 039f786c16
7 changed files with 78 additions and 8 deletions

View file

@ -38,10 +38,18 @@ public struct ConversationsListView: View {
}
Divider()
}
} else if conversations.isEmpty && !viewModel.isLoadingFirstPage {
} else if conversations.isEmpty && !viewModel.isLoadingFirstPage && !viewModel.isError {
EmptyView(iconName: "tray",
title: "Inbox Zero",
message: "Looking for some social media love? You'll find all your direct messages and private mentions right here. Happy messaging! 📱❤️")
} else if viewModel.isError {
ErrorView(title: "An error occurred",
message: "Error while loading your messages",
buttonTitle: "Retry") {
Task {
await viewModel.fetchConversations()
}
}
}
}
.padding(.top, .layoutPadding)

View file

@ -8,6 +8,7 @@ class ConversationsListViewModel: ObservableObject {
@Published var isLoadingFirstPage: Bool = true
@Published var conversations: [Conversation] = []
@Published var isError: Bool = false
public init() { }
@ -20,6 +21,7 @@ class ConversationsListViewModel: ObservableObject {
conversations = try await client.get(endpoint: Conversations.conversations)
isLoadingFirstPage = false
} catch {
isError = true
isLoadingFirstPage = false
}
}

View file

@ -0,0 +1,40 @@
import SwiftUI
public struct ErrorView: View {
public let title: String
public let message: String
public let buttonTitle: String
public let onButtonPress: (() -> Void)
public init(title: String, message: String, buttonTitle: String, onButtonPress: @escaping (() -> Void)) {
self.title = title
self.message = message
self.buttonTitle = buttonTitle
self.onButtonPress = onButtonPress
}
public var body: some View {
VStack {
Image(systemName: "exclamationmark.triangle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxHeight: 50)
Text(title)
.font(.title)
.padding(.top, 16)
Text(message)
.font(.subheadline)
.multilineTextAlignment(.center)
.foregroundColor(.gray)
Button {
onButtonPress()
} label: {
Text(buttonTitle)
}
.buttonStyle(.bordered)
.padding(.top, 16)
}
.padding(.top, 100)
.padding(.layoutPadding)
}
}

View file

@ -102,8 +102,14 @@ public struct NotificationsListView: View {
loadingRow
}
case let .error(error):
Text(error.localizedDescription)
case .error:
ErrorView(title: "An error occured",
message: "An error occured while loading your notifications, please retry.",
buttonTitle: "Retry") {
Task {
await viewModel.fetchNotifications()
}
}
}
}

View file

@ -61,9 +61,14 @@ public struct StatusDetailView: View {
}
}
case let .error(error):
Text(error.localizedDescription)
.padding(.horizontal, .layoutPadding)
case .error:
ErrorView(title: "An error occured",
message: "An error occured while this post context, please try again.",
buttonTitle: "Retry") {
Task {
await viewModel.fetch()
}
}
}
}
.padding(.top, .layoutPadding)

View file

@ -24,8 +24,15 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
Divider()
.padding(.vertical, .dividerPadding)
}
case let .error(error):
Text(error.localizedDescription)
case .error:
ErrorView(title: "An error occured",
message: "An error occured while loading posts, please try again.",
buttonTitle: "Retry") {
Task {
await fetcher.fetchStatuses()
}
}
case let .display(statuses, nextPageState):
ForEach(statuses, id: \.viewId) { status in
StatusRowView(viewModel: .init(status: status, isCompact: false, isRemote: isRemote))

View file

@ -38,6 +38,8 @@ struct StatusRowContextMenu: View {
}
}
Divider()
if let url = viewModel.status.reblog?.url ?? viewModel.status.url {
ShareLink(item: url) {
Label("Share this post", systemImage: "square.and.arrow.up")