Implemented the MessageView component for the Browse module.

This commit is contained in:
Javier Cicchelli 2022-12-15 01:51:21 +01:00
parent 3d21e0f78a
commit 3e70186959
2 changed files with 148 additions and 2 deletions

View File

@ -6,11 +6,23 @@
Copyright © 2022 Röck+Cöde. All rights reserved.
*/
// Loading
// LoadingView
"loading.loading_data.text" = "Loading data\nfrom the API...";
// Browse
// MessageView
"message.type_no_credentials.text.first" = "No user credentials have been found in your device";
"message.type_no_credentials.text.second" = "Please login again with your credentials to load this data.";
"message.type_no_credentials.button.text" = "Log in";
"message.type_empty.text.first" = "No data has been found for this folder";
"message.type_empty.text.second" = "Please populate this folder by uploading some file from your device.";
"message.type_empty.button.text" = "Upload a file";
"message.type_error.text.first" = "An error occurred while loading this data";
"message.type_error.text.second" = "Please try loading this data again at a later time.";
"message.type_error.button.text" = "Try again";
// BrowseView
"browse.toolbar_item.menu.add_actions.text" = "Add file and/or folder";
"browse.toolbar_item.button.add_folder.text" = "Create a new folder";

View File

@ -0,0 +1,134 @@
//
// MessageView.swift
// Browse
//
// Created by Javier Cicchelli on 15/12/2022.
// Copyright © 2022 Röck+Cöde. All rights reserved.
//
import DataModels
import SwiftUI
struct MessageView: View {
// MARK: Properties
let type: MessageType
let action: ActionClosure
// MARK: Body
var body: some View {
VStack(spacing: 72) {
Image.warning
.resizable()
.scaledToFit()
.frame(width: 120, height: 120)
VStack(spacing: 48) {
Text(
type.firstText,
bundle: .module
)
.font(.title)
.fontWeight(.semibold)
Text(
type.secondText,
bundle: .module
)
.font(.title2)
.fontWeight(.regular)
}
.multilineTextAlignment(.center)
Button(action: action) {
Text(
type.button,
bundle: .module
)
.font(.body)
.foregroundColor(.primary)
.frame(maxWidth: .infinity)
}
.tint(.red)
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle(radius: 8))
.controlSize(.large)
}
.padding(.horizontal, 48)
.ignoresSafeArea()
}
}
// MARK: - Enumerations
extension MessageView {
enum MessageType {
case noCredentials
case empty
case error
}
}
private extension MessageView.MessageType {
var firstText: LocalizedStringKey {
switch self {
case .noCredentials:
return "message.type_no_credentials.text.first"
case .empty:
return "message.type_empty.text.first"
case .error:
return "message.type_error.text.first"
}
}
var secondText: LocalizedStringKey {
switch self {
case .noCredentials:
return "message.type_no_credentials.text.second"
case .empty:
return "message.type_empty.text.second"
case .error:
return "message.type_error.text.second"
}
}
var button: LocalizedStringKey {
switch self {
case .noCredentials:
return "message.type_no_credentials.button.text"
case .empty:
return "message.type_empty.button.text"
case .error:
return "message.type_error.button.text"
}
}
}
// MARK: - Image+Constants
private extension Image {
static let warning = Image(systemName: "exclamationmark.circle.fill")
}
// MARK: - Previews
struct MessageView_Previews: PreviewProvider {
static var previews: some View {
MessageView(type: .noCredentials) {
// action closure.
}
.previewDisplayName("View of type no credentials")
MessageView(type: .empty) {
// action closure.
}
.previewDisplayName("View of type empty")
MessageView(type: .error) {
// action closure.
}
.previewDisplayName("View of type error")
}
}