Skip to content

Commit

Permalink
fix: Show the tags as a list on iPadOS (#717)
Browse files Browse the repository at this point in the history
This change switches all iOS targeted implementations over to using a
list style instead of a table view style for the tags view.
  • Loading branch information
jbmorley authored Jul 2, 2023
1 parent 381ce4f commit 1f42400
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 42 deletions.
21 changes: 16 additions & 5 deletions core/Sources/BookmarksCore/Model/TagsContentViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,23 @@ class TagsContentViewModel: ObservableObject, Runnable {
cancellables.removeAll()
}

@MainActor func delete(tags scope: SelectionScope<String>) {

let tags: Set<String>
@MainActor private func tags(_ scope: SelectionScope<String>) -> Set<String> {
switch scope {
case .items(let items):
tags = items
return items
case .selection:
// Counter-intuitively, we need to generate the intersection of our tags and the current visible filtered
// tags as SwiftUI doesn't update the selection set as the items in the list change when filtering. It might
// be cleaner to update the selection ourselves as the list is filtered, but doing it here we avoid thinking
// too hard about race conditions and only do work when we need the selection updated.
let visibleTags = Set(filteredTags.map { $0.name })
tags = selection
return selection
.filter { visibleTags.contains($0) }
}
}

@MainActor func delete(tags scope: SelectionScope<String>) {
let tags = tags(scope)
let title: String
if tags.count < 5 {
let summary = tags
Expand All @@ -101,4 +102,14 @@ class TagsContentViewModel: ObservableObject, Runnable {
}
}

@MainActor func open(tags scope: SelectionScope<String>) {
let tags = tags(scope)
guard tags.count == 1,
let tag = tags.first,
let actionURL = URL(forOpeningTag: tag) else {
return
}
Application.open(actionURL)
}

}
2 changes: 1 addition & 1 deletion core/Sources/BookmarksCore/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public struct ContentView: View {
.sheet(item: $sceneState.sheet) { sheet in
switch sheet {
case .tags:
PhoneTagsView()
PhoneTagsView(applicationModel: applicationModel)
case .settings:
PhoneSettingsView(settings: applicationModel.settings)
case .edit(let id):
Expand Down
45 changes: 40 additions & 5 deletions core/Sources/BookmarksCore/Views/PhoneTagsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,50 @@ import SwiftUI

public struct PhoneTagsView: View {

@Environment(\.dismiss) var dismiss

@EnvironmentObject var applicationModel: ApplicationModel
@EnvironmentObject var settings: Settings

@StateObject var model: TagsContentViewModel

public init(applicationModel: ApplicationModel) {
_model = StateObject(wrappedValue: TagsContentViewModel(applicationModel: applicationModel))
}

public var body: some View {
NavigationView {
TagsContentView(applicationModel: applicationModel)
.navigationBarTitle("Tags", displayMode: .inline)
.dismissable(.close)
List(selection: $model.selection) {
ForEach(model.filteredTags) { tag in
HStack {
Image(systemName: "circle.fill")
.foregroundColor(tag.name.color())
Text(tag.name)
Spacer()
Text(tag.count.formatted())
Toggle(isOn: $settings.favoriteTags.contains(tag.name))
.foregroundColor(.accentColor)
.toggleStyle(.favorite)
}
}
}
.contextMenu(forSelectionType: String.ID.self) { selection in
Button(role: .destructive) {
model.delete(tags: .items(selection))
} label: {
Label("Delete", systemImage: "trash")
}
} primaryAction: { selection in
model.open(tags: .items(selection))
}
.onDeleteCommand {
model.delete(tags: .selection)
}
.listStyle(.plain)
.searchable(text: $model.filter)
.navigationBarTitle("Tags", displayMode: .inline)
.dismissable(.close)
.presents($model.confirmation)
.presents($model.error)
.runs(model)
}
}

Expand Down
35 changes: 4 additions & 31 deletions core/Sources/BookmarksCore/Views/TagsContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@ public struct TagsContentView: View {
static let indicatorSize = 16.0
}

#if os(iOS)
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
private var isCompact: Bool { horizontalSizeClass == .compact }
#else
private let isCompact = false
#endif

@Environment(\.openURL) var openURL

@EnvironmentObject var applicationModel: ApplicationModel
@EnvironmentObject var settings: Settings

@StateObject var model: TagsContentViewModel
Expand All @@ -49,21 +39,10 @@ public struct TagsContentView: View {
public var body: some View {
Table(of: Database.Tag.self, selection: $model.selection) {
TableColumn("") { tag in
if isCompact {
HStack {
Image(systemName: "circle.fill")
.foregroundColor(tag.name.color())
Text(tag.name)
Spacer()
Text(tag.count.formatted())
Toggle(isOn: $settings.favoriteTags.contains(tag.name))
}
} else {
Image(systemName: "circle.fill")
.foregroundColor(tag.name.color())
}
Image(systemName: "circle.fill")
.foregroundColor(tag.name.color())
}
.width(isCompact ? .none : LayoutMetrics.indicatorSize)
.width(LayoutMetrics.indicatorSize)
TableColumn("Tag") { tag in
Text(tag.name)
}
Expand All @@ -85,13 +64,7 @@ public struct TagsContentView: View {
Label("Delete", systemImage: "trash")
}
} primaryAction: { selection in
guard selection.count == 1,
let tag = selection.first,
let actionURL = URL(forOpeningTag: tag) else {
return
}
print(actionURL.absoluteString)
openURL(actionURL)
model.open(tags: .items(selection))
}
.onDeleteCommand {
model.delete(tags: .selection)
Expand Down

0 comments on commit 1f42400

Please sign in to comment.