Implemented the RepositoriesView view and its respective view model in the app target.
This commit is contained in:
parent
2f8e3a094d
commit
cd8adb6f66
@ -42,6 +42,57 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.button.add-repository.text" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Add repository"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.column.active.text" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Active"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.column.folder.text" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Folder"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.column.name.text" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Name"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.item.active.text" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : " "
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.tab-bar.repositories.text" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
|
37
Piper/Sources/Logic/ViewModels/RepositoriesViewModel.swift
Normal file
37
Piper/Sources/Logic/ViewModels/RepositoriesViewModel.swift
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// RepositoriesViewModel.swift
|
||||
// Piper ~ App
|
||||
//
|
||||
// Created by Javier Cicchelli on 21/10/2024.
|
||||
// Copyright © 2024 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import SwiftData
|
||||
|
||||
@Observable
|
||||
final class RepositoriesViewModel {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
var fileImporterOpened: Bool = false
|
||||
var rowsSelected: Set<Repository.ID> = []
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
func addRepository(
|
||||
_ result: Result<URL, any Error>,
|
||||
into context: ModelContext
|
||||
) {
|
||||
do {
|
||||
let url = try result.get()
|
||||
let repository = Repository(url)
|
||||
|
||||
context.insert(repository)
|
||||
} catch {
|
||||
// TODO: Handle this error gracefully.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
117
Piper/Sources/UI/Views/RepositoriesView.swift
Normal file
117
Piper/Sources/UI/Views/RepositoriesView.swift
Normal file
@ -0,0 +1,117 @@
|
||||
//
|
||||
// RepositoriesView.swift
|
||||
// Piper ~ App
|
||||
//
|
||||
// Created by Javier Cicchelli on 14/10/2024.
|
||||
// Copyright © 2024 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
struct RepositoriesView: View {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
|
||||
@Query(sort: \Repository.addedAt)
|
||||
private var repositories: [Repository]
|
||||
|
||||
@State private var viewModel: RepositoriesViewModel = .init()
|
||||
|
||||
// MARK: Body
|
||||
|
||||
var body: some View {
|
||||
HStack(
|
||||
alignment: .top,
|
||||
spacing: Layout.spacingHorizontal
|
||||
) {
|
||||
Table(
|
||||
repositories,
|
||||
selection: $viewModel.rowsSelected
|
||||
) {
|
||||
TableColumn("settings.column.active.text") { repository in
|
||||
HStack {
|
||||
Toggle("settings.item.active.text", isOn: .init {
|
||||
repository.active
|
||||
} set: {
|
||||
repository.active = $0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
TableColumn("settings.column.name.text") { repository in
|
||||
Text(repository.name)
|
||||
.fontWeight(.semibold)
|
||||
.foregroundStyle(.primary)
|
||||
}
|
||||
|
||||
TableColumn("settings.column.folder.text") { repository in
|
||||
Text(repository.folder)
|
||||
.fontWeight(.regular)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
VStack {
|
||||
Button("settings.button.add-repository.text") {
|
||||
viewModel.fileImporterOpened = true
|
||||
}
|
||||
.fileImporter(
|
||||
isPresented: $viewModel.fileImporterOpened,
|
||||
allowedContentTypes: [.pdf]
|
||||
) {
|
||||
viewModel.addRepository($0, into: modelContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
private extension RepositoriesView {
|
||||
enum Layout {
|
||||
static let spacingHorizontal = CGFloat(16)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
@available(macOS 15.0, *)
|
||||
#Preview(
|
||||
"Repositories view when no repositories found (macOS 15)",
|
||||
traits: .emptyData
|
||||
) {
|
||||
RepositoriesView()
|
||||
.scenePadding()
|
||||
}
|
||||
|
||||
@available(macOS, obsoleted: 15)
|
||||
#Preview("Repositories view when no repositories found (macOS 14)") {
|
||||
MenuBarView()
|
||||
.modelContainer(.preview)
|
||||
.scenePadding()
|
||||
}
|
||||
|
||||
@available(macOS 15.0, *)
|
||||
#Preview(
|
||||
"Repositories view when repositories found (macOS 15)",
|
||||
traits: .sampleData
|
||||
) {
|
||||
RepositoriesView()
|
||||
.scenePadding()
|
||||
}
|
||||
|
||||
@available(macOS, obsoleted: 15)
|
||||
#Preview("Repositories view when repositories found (macOS 14)") {
|
||||
let container = ModelContainer.preview
|
||||
|
||||
Repository.samples(in: container)
|
||||
|
||||
return RepositoriesView()
|
||||
.modelContainer(container)
|
||||
.scenePadding()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user