Skip to content
This repository was archived by the owner on Jan 20, 2021. It is now read-only.

Commit 4987b95

Browse files
Julian KahnertJulian Kahnert
authored andcommitted
fix macOS tag tab view
1 parent b92ca3c commit 4987b95

File tree

15 files changed

+247
-142
lines changed

15 files changed

+247
-142
lines changed

ArchiveCore/Sources/ArchiveBackend/ArchiveStore.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,15 @@ public final class ArchiveStore: ObservableObject, ArchiveStoreAPI, Log {
175175
for change in changes {
176176

177177
var document: Document?
178-
var contentParsingOptions: ParsingOptions?
178+
var shouldParseDate: Bool?
179179

180180
switch change {
181181
case .added(let details):
182182
let taggingStatus = getTaggingStatus(of: details.url)
183183
document = Document(from: details, with: taggingStatus)
184184

185185
// parse document content only for untagged documents
186-
contentParsingOptions = taggingStatus == .untagged ? .all : []
186+
shouldParseDate = taggingStatus == .untagged
187187

188188
case .removed(let url):
189189
contents[provider.baseUrl]?.removeAll { $0.path == url }
@@ -204,19 +204,19 @@ public final class ArchiveStore: ObservableObject, ArchiveStoreAPI, Log {
204204

205205
contents[provider.baseUrl]?.removeAll { $0.path == details.url }
206206

207-
contentParsingOptions = []
207+
shouldParseDate = false
208208
}
209209

210210
if let document = document {
211211
contents[provider.baseUrl, default: []].append(document)
212212
contents[provider.baseUrl]?.sort()
213213

214214
// trigger update of the document properties
215-
if let contentParsingOptions = contentParsingOptions {
215+
if let shouldParseDate = shouldParseDate {
216216
DispatchQueue.global(qos: .userInitiated).async {
217217
// save documents after the last has been written
218218
documentProcessingGroup.enter()
219-
document.updateProperties(with: document.downloadStatus, contentParsingOptions: contentParsingOptions)
219+
document.updateProperties(with: document.downloadStatus, shouldParseDate: shouldParseDate)
220220
documentProcessingGroup.leave()
221221
}
222222
}

ArchiveCore/Sources/ArchiveBackend/Models/Document.swift

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public final class Document: ObservableObject, Identifiable, Codable, Log {
145145
return "\(dateStr)--\(specification)__\(tagStr).pdf"
146146
}
147147

148-
func updateProperties(with downloadStatus: FileChange.DownloadStatus, contentParsingOptions: ParsingOptions) {
148+
func updateProperties(with downloadStatus: FileChange.DownloadStatus, shouldParseDate: Bool) {
149149
if Thread.isMainThread {
150150
log.errorAndAssert("updateProperties() must not be called from the main thread.")
151151
}
@@ -174,8 +174,8 @@ public final class Document: ObservableObject, Identifiable, Codable, Log {
174174
}
175175

176176
guard downloadStatus == .local,
177-
!contentParsingOptions.isEmpty else { return }
178-
self.parseContent(contentParsingOptions)
177+
shouldParseDate else { return }
178+
self.parseContent()
179179
}
180180

181181
/// Get the new foldername and filename after applying the PDF Archiver naming scheme.
@@ -209,14 +209,11 @@ public final class Document: ObservableObject, Identifiable, Codable, Log {
209209
/// ATTENTION: This method needs security access!
210210
///
211211
/// - Parameter tagManager: TagManager that will be used when adding new tags.
212-
private func parseContent(_ options: ParsingOptions) {
212+
private func parseContent() {
213213
if Thread.isMainThread {
214214
log.errorAndAssert("parseContent() must not be called from the main thread.")
215215
}
216216

217-
// skip the calculations if the OptionSet is empty
218-
guard !options.isEmpty else { return }
219-
220217
// get the pdf content of first 3 pages
221218
guard let pdfDocument = PDFDocument(url: path) else { return }
222219
var text = ""
@@ -231,22 +228,11 @@ public final class Document: ObservableObject, Identifiable, Codable, Log {
231228
guard !text.isEmpty else { return }
232229

233230
// parse the date
234-
if options.contains(.date),
235-
let parsed = DateParser.parse(text) {
231+
if let parsed = DateParser.parse(text) {
236232
DispatchQueue.main.sync {
237233
self.date = parsed.date
238234
}
239235
}
240-
241-
// parse the tags
242-
if options.contains(.tags) {
243-
244-
// get new tags
245-
let newTags = TagParser.parse(text)
246-
DispatchQueue.main.sync {
247-
self.tags.formUnion(newTags)
248-
}
249-
}
250236
}
251237

252238
// MARK: - Codable Implementation

ArchiveCore/Sources/ArchiveBackend/Models/ParsingOptions.swift

Lines changed: 0 additions & 21 deletions
This file was deleted.

ArchiveCore/Sources/ArchiveBackend/PDFRendering/PDFProcessing.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,8 @@ public final class PDFProcessing: Operation, Log {
134134
let parsedDate = DateParser.parse(content)?.date ?? Date()
135135

136136
// parse the tags
137-
var newTags = TagParser.parse(content)
138-
if newTags.isEmpty {
139-
newTags.insert(Constants.documentTagPlaceholder)
140-
} else {
141-
142-
// only use tags that are already in the archive
143-
newTags = Set(newTags.intersection(archiveTags).prefix(5))
144-
}
145-
146-
return Document.createFilename(date: parsedDate, specification: specification, tags: newTags)
137+
let tags = Set([Constants.documentTagPlaceholder])
138+
return Document.createFilename(date: parsedDate, specification: specification, tags: tags)
147139
}
148140

149141
private func createPdf(of documentId: UUID) throws -> URL {

ArchiveCore/Sources/ArchiveSharedConstants/Color.swift

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,28 @@
99
import SwiftUI
1010

1111
public extension Color {
12+
static var paDelete = Color("Delete")
13+
static var paDarkGray = Color("DarkGray")
14+
static var paLightGray = Color("LightGray")
15+
static var paWhite = Color("White")
16+
static var paDarkRed = Color("DarkRed")
17+
static var paLightRed = Color("LightRed")
1218

13-
static var paDelete: Color { return Color("Delete") }
14-
static var paDarkGray: Color { return Color("DarkGray") }
15-
static var paLightGray: Color { return Color("LightGray") }
16-
static var paWhite: Color { return Color("White") }
17-
static var paDarkRed: Color { return Color("DarkRed") }
18-
static var paLightRed: Color { return Color("LightRed") }
19-
20-
static var paPDFBackground: Color { return Color("PDFBackground") }
21-
static var paBackground: Color { return Color("Background") }
22-
static var paSecondaryBackground: Color { return Color("SecondaryBackground") }
23-
static var paKeyboardBackground: Color { return Color("KeyboardBackground") }
24-
static var paPlaceholderGray: Color { return Color("PlaceholderGray") }
19+
static var paPDFBackground = Color("PDFBackground")
20+
static var paBackground = Color("Background")
21+
#if os(macOS)
22+
static var paSecondaryBackground = Color(NSColor.alternatingContentBackgroundColors.last!)
23+
#else
24+
static var paSecondaryBackground = Color("SecondaryBackground")
25+
#endif
26+
static var paKeyboardBackground = Color("KeyboardBackground")
27+
static var paPlaceholderGray = Color("PlaceholderGray")
2528
}
2629

2730
#if os(macOS)
2831
public extension Color {
29-
static var systemBackground: Color { return Color(.windowBackgroundColor) }
30-
static var secondarySystemBackground: Color { return Color(.controlBackgroundColor) }
31-
static var systemGray6: Color { return Color(.darkGray) }
32+
static var systemBackground = Color(.windowBackgroundColor)
33+
static var secondarySystemBackground = Color(.controlBackgroundColor)
34+
static var systemGray6 = Color(.darkGray)
3235
}
3336
#endif
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//
2+
// WrappingHStack.swift
3+
//
4+
//
5+
// Created by Julian Kahnert on 26.12.20.
6+
//
7+
// Source: https://stackoverflow.com/a/62103264/10026834
8+
9+
import SwiftUI
10+
11+
public struct WrappingHStack<Item: Identifiable & Hashable, Content: View>: View {
12+
var items: [Item]
13+
14+
@State private var totalHeight
15+
= CGFloat.zero // << variant for ScrollView/List
16+
// = CGFloat.infinity // << variant for VStack
17+
18+
private let content: (Item) -> Content
19+
public init(items: [Item], @ViewBuilder content: @escaping (Item) -> Content) {
20+
self.items = items
21+
self.content = content
22+
}
23+
24+
public var body: some View {
25+
VStack {
26+
GeometryReader { geometry in
27+
self.generateContent(in: geometry)
28+
}
29+
}
30+
.frame(height: totalHeight)// << variant for ScrollView/List
31+
//.frame(maxHeight: totalHeight) // << variant for VStack
32+
}
33+
34+
private func generateContent(in proxy: GeometryProxy) -> some View {
35+
var width = CGFloat.zero
36+
var height = CGFloat.zero
37+
38+
return ZStack(alignment: .topLeading) {
39+
ForEach(items, id: \.self) { item in
40+
content(item)
41+
.padding([.horizontal, .vertical], 4)
42+
.alignmentGuide(.leading) { dimensions in
43+
if abs(width - dimensions.width) > proxy.size.width {
44+
width = 0
45+
height -= dimensions.height
46+
}
47+
let result = width
48+
if let lastItem = self.items.last,
49+
item == lastItem {
50+
width = 0 //last item
51+
} else {
52+
width -= dimensions.width
53+
}
54+
return result
55+
}
56+
.alignmentGuide(.top) { _ in
57+
let result = height
58+
if let lastItem = self.items.last,
59+
item == lastItem {
60+
height = 0 // last item
61+
}
62+
return result
63+
}
64+
}
65+
}.background(viewHeightReader($totalHeight))
66+
}
67+
68+
private func item(for text: String) -> some View {
69+
Text(text)
70+
.padding(.all, 5)
71+
.font(.body)
72+
.background(Color.blue)
73+
.foregroundColor(Color.white)
74+
.cornerRadius(5)
75+
}
76+
77+
private func viewHeightReader(_ binding: Binding<CGFloat>) -> some View {
78+
return GeometryReader { geometry -> Color in
79+
let rect = geometry.frame(in: .local)
80+
DispatchQueue.main.async {
81+
binding.wrappedValue = rect.size.height
82+
}
83+
return .clear
84+
}
85+
}
86+
}
87+
88+
#if DEBUG
89+
struct WrappingHStack_Previews: PreviewProvider {
90+
static var previews: some View {
91+
WrappingHStack(items: ["Nintendo", "XBox", "PlayStation", "PlayStation 2", "PlayStation 3", "PlayStation 4"]) { text in
92+
TagView(tagName: text, isEditable: true, tapHandler: { print($0) })
93+
// Label(text, systemImage: "tag")
94+
// .padding(.all, 5)
95+
.font(.body)
96+
.fixedSize()
97+
.background(Color.blue)
98+
.foregroundColor(Color.white)
99+
.cornerRadius(5)
100+
}
101+
}
102+
}
103+
#endif

ArchiveCore/Sources/ArchiveViews/TagTab/DocumentInformationForm.swift

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,19 @@ struct DocumentInformationForm: View {
3131

3232
private func documentTagTapped(_ tag: String) {
3333
tags.removeAll { $0 == tag }
34-
insertAndSort($suggestedTags, tag: tag)
34+
// $suggestedTags.insertAndSort(tag)
3535
}
3636

3737
private func saveCurrentTag() {
3838
let tag = tagInput
3939
tagInput = ""
40-
insertAndSort($tags, tag: tag)
40+
$tags.insertAndSort(tag)
4141
}
4242

4343
private func suggestedTagTapped(_ tag: String) {
4444
suggestedTags.removeAll { $0 == tag }
45-
insertAndSort($tags, tag: tag)
46-
}
47-
48-
private func insertAndSort(_ tags: Binding<[String]>, tag: String) {
49-
var uniqueTags = Set(tags.wrappedValue)
50-
uniqueTags.insert(tag)
51-
tags.wrappedValue = uniqueTags.sorted()
45+
tagInput = ""
46+
$tags.insertAndSort(tag)
5247
}
5348

5449
private var documentTagsView: some View {
@@ -100,3 +95,12 @@ struct DocumentInformationForm_Previews: PreviewProvider {
10095
.previewLayout(.sizeThatFits)
10196
}
10297
}
98+
99+
// TODO: move this to a helper file
100+
extension Binding where Value == [String] {
101+
func insertAndSort(_ item: String) {
102+
var uniqueItems = Set(wrappedValue)
103+
uniqueItems.insert(item)
104+
wrappedValue = uniqueItems.sorted()
105+
}
106+
}

0 commit comments

Comments
 (0)