Skip to content

Commit

Permalink
Fix Csv generating bug on application (#59)
Browse files Browse the repository at this point in the history
* chore: Add format script

* style: Apply format

* chore: Add .editroconfig

* test: Add test for Csv parse

* test: Add ImageMaker tests

* refactor

* chore: Fix Csv2ImgCmd schema

* test: Add pdf maker tests

* test

* test: Skip some tests

* fix: Fix state management issue on application side.
  • Loading branch information
fummicc1 authored Sep 23, 2024
1 parent 3eb4c7b commit c04d726
Show file tree
Hide file tree
Showing 25 changed files with 385 additions and 142 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[*.swift]
indent_style = space
indent_size = 4
tab_width = 4
end_of_line = crlf
insert_final_newline = false
max_line_length = 120
trim_trailing_whitespace = true
2 changes: 1 addition & 1 deletion .github/workflows/command.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ jobs:
run: |
set -o pipefail && \
xcodebuild -scheme Csv2ImgCmd \
clean build test \
clean build \
-destination 'platform=OS X,arch=arm64' \
| xcbeautify
2 changes: 1 addition & 1 deletion .swiftpm/xcode/xcshareddata/xcschemes/Csv2ImgCmd.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
skipped = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Csv2ImgTests"
Expand Down
8 changes: 8 additions & 0 deletions Csv2ImageApp/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[*.swift]
indent_style = space
indent_size = 4
tab_width = 4
end_of_line = crlf
insert_final_newline = false
max_line_length = 120
trim_trailing_whitespace = true
2 changes: 2 additions & 0 deletions Csv2ImageApp/Csv2ImageApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
D35DB0D3285FA754009C252D /* CsvViewer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CsvViewer.swift; sourceTree = "<group>"; };
D35DB0D5285FADA5009C252D /* HistoryModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryModel.swift; sourceTree = "<group>"; };
D3736B27286393D8004C20C8 /* Csv2Img */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Csv2Img; path = ..; sourceTree = "<group>"; };
D39EA3632CA139E300F20514 /* .editorconfig */ = {isa = PBXFileReference; lastKnownFileType = text; path = .editorconfig; sourceTree = "<group>"; };
D3A4EB14284F11A3002E3499 /* Csv2ImageApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Csv2ImageApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
D3A4EB17284F11A3002E3499 /* Csv2ImageAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Csv2ImageAppApp.swift; sourceTree = "<group>"; };
D3A4EB19284F11A3002E3499 /* SelectCsvView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectCsvView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -148,6 +149,7 @@
D3A4EB0B284F11A3002E3499 = {
isa = PBXGroup;
children = (
D39EA3632CA139E300F20514 /* .editorconfig */,
D3736B26286393D8004C20C8 /* Packages */,
D3A4EB16284F11A3002E3499 /* Csv2ImageApp */,
D3A4EB28284F11A4002E3499 /* Csv2ImageAppTests */,
Expand Down
2 changes: 1 addition & 1 deletion Csv2ImageApp/Csv2ImageApp/States/GenerateOutputState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Csv2Img
import Foundation
import PDFKit

struct GenerateOutputState: Hashable, Equatable {
struct GenerateOutputState: Hashable, Equatable, Sendable {
let url: URL
let fileType: FileURLType

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ actor CsvGlobalActor {
@Observable
class GenerateOutputModel: ObservableObject {

private(set) var state: GenerateOutputState {
var state: GenerateOutputState {
didSet {
if oldValue.exportType == state.exportType && oldValue.encoding == state.encoding
&& oldValue.size == state.size && oldValue.orientation == state.orientation
Expand All @@ -36,19 +36,7 @@ class GenerateOutputModel: ObservableObject {
}
private(set) var savedURL: URL?

private var cachedCsv: Csv? {
didSet {
guard let cachedCsv else {
return
}
Task { @MainActor in
let encoding = await cachedCsv.encoding
state.encoding = encoding
let exportType = await cachedCsv.exportType
state.exportType = exportType
}
}
}
private var cachedCsv: Csv?

private var csvTask: Task<Void, Never>?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,47 +27,61 @@ import SwiftUI
NavigationView {
Form {
Section(header: Text("Export Settings")) {
Picker("Export Type", selection: Binding(
get: { model.state.exportType },
set: { model.update(keyPath: \.exportType, value: $0) }
)) {
Picker(
"Export Type",
selection: Binding(
get: { model.state.exportType },
set: { model.update(keyPath: \.exportType, value: $0) }
)
) {
Text("PDF").tag(Csv.ExportType.pdf)
Text("PNG").tag(Csv.ExportType.png)
}
.pickerStyle(SegmentedPickerStyle())

Picker("Encoding", selection: Binding(
get: { model.state.encoding },
set: { model.update(keyPath: \.encoding, value: $0) }
)) {
Picker(
"Encoding",
selection: Binding(
get: { model.state.encoding },
set: { model.update(keyPath: \.encoding, value: $0) }
)
) {
ForEach(availableEncodingType, id: \.self) { encoding in
Text(encoding.description).tag(encoding)
}
}

Picker("PDF Size", selection: Binding(
get: { model.state.size },
set: { model.update(keyPath: \.size, value: $0) }
)) {
ForEach(PdfSize.allCases, id: \.self) { size in
Text(size.rawValue).tag(size)

if model.state.exportType == .pdf {

Picker(
"PDF Size",
selection: Binding(
get: { model.state.size },
set: { model.update(keyPath: \.size, value: $0) }
)
) {
ForEach(PdfSize.allCases, id: \.self) { size in
Text(size.rawValue).tag(size)
}
}
}

Picker("PDF Orientation", selection: Binding(
get: { model.state.orientation },
set: { model.update(keyPath: \.orientation, value: $0) }
)) {
ForEach(PdfSize.Orientation.allCases, id: \.self) { orientation in
Text(orientation.rawValue).tag(orientation)

Picker(
"PDF Orientation",
selection: Binding(
get: { model.state.orientation },
set: { model.update(keyPath: \.orientation, value: $0) }
)
) {
ForEach(PdfSize.Orientation.allCases, id: \.self) { orientation in
Text(orientation.rawValue).tag(orientation)
}
}
}
}

Section(header: Text("Preview")) {
GeneratePreviewView(
model: model,
size: .constant(CGSize(width: UIScreen.main.bounds.width - 32, height: 300))
model: model
)
.frame(height: 300)
.background(Asset.lightAccentColor.swiftUIColor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import SwiftUI
#if os(macOS)
struct GenerateOutputView_macOS: View {

@StateObject var model: GenerateOutputModel
@Bindable var model: GenerateOutputModel
@Binding var backToPreviousPage: Bool
@State private var succeedSavingOutput: Bool = false

private let availableEncodingType: [String.Encoding] = [
.utf8,
Expand All @@ -30,37 +31,43 @@ import SwiftUI
HSplitView {
List {
Section("Settings") {
Picker("Encoding", selection: $model.encoding) {
Picker("Export Type", selection: $model.state.exportType) {
ForEach(Csv.ExportType.allCases, id: \.self) { exportType in
Text(exportType.fileExtension).tag(exportType)
}
}
Picker("Encoding", selection: $model.state.encoding) {
ForEach(availableEncodingType, id: \.self) { encoding in
Text(encoding.description).tag(encoding)
}
}
// Add more settings here as needed
if model.state.exportType == .pdf {
Picker("PDF Size", selection: $model.state.size) {
ForEach(PdfSize.allCases, id: \.self) { pdfSize in
Text(pdfSize.rawValue).tag(pdfSize)
}
}
Picker("PDF Orientation", selection: $model.state.orientation) {
ForEach(PdfSize.Orientation.allCases, id: \.self) { orientation in
Text(orientation.rawValue).tag(orientation)
}
}
}
}
}
.listStyle(SidebarListStyle())
.frame(minWidth: 200, idealWidth: 250, maxWidth: 300)

VStack {
GeneratePreviewView(
model: model,
size: .constant(
.init(
width: 480,
height: 360
)
GeometryReader(content: { proxy in
GeneratePreviewView(
model: model
)
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
})

HStack {
Button("Generate") {
// Add generation logic here
}
.keyboardShortcut(.defaultAction)

Button("Save As...") {
// Add save logic here
succeedSavingOutput = model.save()
}
}
.padding()
Expand All @@ -76,6 +83,22 @@ import SwiftUI
}
}
.frame(minWidth: 800, minHeight: 600)
.alert(isPresented: $succeedSavingOutput) {
Alert(
title: Text("Complete Saving!"),
message: nil,
primaryButton: .default(Text("Back")) {
withAnimation {
backToPreviousPage = true
}
},
secondaryButton: .default(Text("Open")) {
if let savedURL = model.savedURL, NSWorkspace.shared.open(savedURL) {
NSWorkspace.shared.open(savedURL)
}
}
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import SwiftUI

struct GeneratePreviewView: View {

@StateObject var model: GenerateOutputModel
@Binding var size: CGSize
@Bindable var model: GenerateOutputModel

#if os(iOS)
var body: some View {
Expand All @@ -30,8 +29,15 @@ struct GeneratePreviewView: View {
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width, height: geometry.size.height)
}
} else if let document = model.state.pdfDocument, model.state.exportType == .pdf {
PdfDocumentView(document: document, size: $size)
} else if model.state.pdfDocument != nil, model.state.exportType == .pdf
{
PdfDocumentView(
document: $model.state.pdfDocument,
size: CGSize(
width: geometry.size.width,
height: geometry.size.height
)
)
}
}
}
Expand All @@ -52,8 +58,15 @@ struct GeneratePreviewView: View {
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width, height: geometry.size.height)
}
} else if let document = model.state.pdfDocument, model.state.exportType == .pdf {
PdfDocumentView(document: document, size: $size)
} else if model.state.pdfDocument != nil, model.state.exportType == .pdf
{
PdfDocumentView(
document: $model.state.pdfDocument,
size: CGSize(
width: geometry.size.width,
height: geometry.size.height
)
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import SwiftUI

struct PdfDocumentView: ViewRepresentable {

let document: PDFDocument
@Binding var size: CGSize
@Binding var document: PDFDocument?
let size: CGSize

private let view: PDFView = .init()

Expand All @@ -25,6 +25,9 @@ struct PdfDocumentView: ViewRepresentable {
}

func updateNSView(_ nsView: PDFView, context: Context) {
nsView.document = document
nsView.setFrameSize(size)
nsView.displayMode = .twoUpContinuous
}
#elseif os(iOS)
typealias UIViewType = PDFView
Expand All @@ -37,12 +40,21 @@ struct PdfDocumentView: ViewRepresentable {
return view
}
func updateUIView(_ uiView: PDFView, context: Context) {
uiView.document = document
uiView.frame.size = size
uiView.displayMode = .singlePage
uiView.usePageViewController(true, withViewOptions: nil)
}
#endif
}

struct PdfDocumentView_Previews: PreviewProvider {
static var previews: some View {
PdfDocumentView(document: .init(), size: .constant(CGSize(width: 100, height: 100)))
PdfDocumentView(
document: .constant(
.init()
),
size: CGSize(width: 100, height: 100)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import SwiftUI
}
}
}

Section(footer: Text("Saved data is stored in Folder App.").font(.footnote)) {
Button(action: {
model.openFolderApp()
Expand Down
Loading

0 comments on commit c04d726

Please sign in to comment.