Implemented the DocumentView view for the Browse module.
This commit is contained in:
parent
745ba87fb5
commit
3c433bf72e
152
Modules/Sources/Browse/UI/Views/DocumentView.swift
Normal file
152
Modules/Sources/Browse/UI/Views/DocumentView.swift
Normal 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.
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user