Implemented the DocumentView view for the Browse module.

This commit is contained in:
Javier Cicchelli 2022-12-16 01:47:44 +01:00
parent 745ba87fb5
commit 3c433bf72e

View File

@ -0,0 +1,152 @@
//
// DocumentView.swift
// Browse
//
// Created by Javier Cicchelli on 16/12/2022.
// Copyright © 2022 Röck+Cöde. All rights reserved.
//
import DataModels
import KeychainStorage
import SwiftUI
struct DocumentView: View {
// MARK: Environments
@Environment(\.dismiss) private var dismiss
// MARK: Storages
@KeychainStorage(key: .KeychainStorage.account) private var account: Account?
// MARK: States
@State private var status: ViewStatus = .loading
@State private var loadedData: Data?
private let getData = GetDataUseCase()
// MARK: Properties
let document: Document
let login: ActionClosure
// MARK: Body
var body: some View {
content
.navigationTitle(document.name)
.navigationBarTitleDisplayMode(.inline)
.task {
await loadDataIfPossible()
}
}
}
// MARK: - UI
private extension DocumentView {
@ViewBuilder var content: some View {
switch status {
case .noCredentials:
MessageView(
type: .noCredentials,
action: login
)
case .notSupported:
MessageView(type: .notSupported) {
dismiss()
}
case .loading:
LoadingView()
case .loaded:
Image(uiImage: imageFromData)
.resizable()
.scaledToFit()
case .empty:
EmptyView()
case .error:
MessageView(type: .error) {
Task {
await loadDataIfPossible()
}
}
}
}
}
// MARK: - Helpers
private extension DocumentView {
// MARK: Computed
var imageFromData: UIImage {
guard
let loadedData,
let image = UIImage(data: loadedData)
else {
return .init()
}
return image
}
// MARK: Functions
func loadDataIfPossible() async {
guard document.contentType == .Constants.supportedContentType else {
status = .notSupported
return
}
guard let account else {
status = .noCredentials
return
}
do {
status = .loading
let data = try await getData(
id: document.id,
username: account.username,
password: account.password
)
if data.isEmpty {
status = .error
} else {
loadedData = data
status = .loaded
}
} catch {
status = .error
}
}
}
// MARK: - String+Constants
private extension String {
enum Constants {
static let supportedContentType = "image/jpeg"
}
}
// MARK: - Previews
struct DocumentView_Previews: PreviewProvider {
static var previews: some View {
DocumentView(document: .init(
id: "1234567890",
name: "Some document name goes in here...",
contentType: "some content type",
size: .random(in: 1 ... 100),
lastModifiedAt: .now
)) {
// login closure.
}
}
}