Use sets for selected/unselected labels to eliminate duplicate IDs in selection

This commit is contained in:
Jackson Harper
2023-01-23 15:43:56 +08:00
parent 461087513b
commit d6acb69a1c
9 changed files with 48 additions and 34 deletions

View File

@ -255,10 +255,10 @@ public struct ShareExtensionView: View {
}
func onLabelTap(label: LinkedItemLabel, textChip _: TextChip) {
if let selectedIndex = labelsViewModel.selectedLabels.firstIndex(of: label) {
labelsViewModel.selectedLabels.remove(at: selectedIndex)
if labelsViewModel.selectedLabels.contains(label) {
labelsViewModel.selectedLabels.remove(label)
} else {
labelsViewModel.selectedLabels.append(label)
labelsViewModel.selectedLabels.insert(label)
}
if let linkedItem = viewModel.linkedItem {
@ -435,7 +435,7 @@ public struct ShareExtensionView: View {
labelsSection
.onTapGesture {
withAnimation {
previousLabels = self.labelsViewModel.selectedLabels
previousLabels = Array(self.labelsViewModel.selectedLabels)
viewState = .editingLabels
}
}

View File

@ -59,9 +59,9 @@ struct ApplyLabelsView: View {
Button(
action: {
if isSelected(label) {
viewModel.selectedLabels.removeAll(where: { $0.id == label.id })
viewModel.selectedLabels.remove(label)
} else {
viewModel.selectedLabels.append(label)
viewModel.selectedLabels.insert(label)
}
},
label: {
@ -138,10 +138,11 @@ struct ApplyLabelsView: View {
switch mode {
case let .item(feedItem):
viewModel.saveItemLabelChanges(itemID: feedItem.unwrappedID, dataService: dataService)
onSave?(Array(viewModel.selectedLabels))
case .highlight:
onSave?(viewModel.selectedLabels)
onSave?(Array(viewModel.selectedLabels))
case .list:
onSave?(viewModel.selectedLabels)
onSave?(Array(viewModel.selectedLabels))
}
presentationMode.wrappedValue.dismiss()
},

View File

@ -6,8 +6,8 @@ import Views
@MainActor final class LabelsViewModel: ObservableObject {
@Published var isLoading = false
@Published var selectedLabels = [LinkedItemLabel]()
@Published var unselectedLabels = [LinkedItemLabel]()
@Published var selectedLabels = Set<LinkedItemLabel>()
@Published var unselectedLabels = Set<LinkedItemLabel>()
@Published var labels = [LinkedItemLabel]()
@Published var showCreateLabelModal = false
@Published var labelSearchFilter = ""
@ -31,9 +31,9 @@ import Views
let selLabels = initiallySelectedLabels ?? item?.sortedLabels ?? []
for label in labels {
if selLabels.contains(label) {
selectedLabels.append(label)
selectedLabels.insert(label)
} else {
unselectedLabels.append(label)
unselectedLabels.insert(label)
}
}
@ -46,9 +46,9 @@ import Views
let selLabels = initiallySelectedLabels ?? item?.sortedLabels ?? []
for label in self.labels {
if selLabels.contains(label) {
self.selectedLabels.append(label)
self.selectedLabels.insert(label)
} else {
self.unselectedLabels.append(label)
self.unselectedLabels.insert(label)
}
}
}
@ -71,9 +71,9 @@ import Views
let selLabels = highlight.labels ?? []
for label in labels {
if selLabels.contains(label) {
selectedLabels.append(label)
selectedLabels.insert(label)
} else {
unselectedLabels.append(label)
unselectedLabels.insert(label)
}
}
}
@ -89,7 +89,7 @@ import Views
}
setLabels(fetchedLabels ?? [])
unselectedLabels = fetchedLabels ?? []
unselectedLabels = Set(fetchedLabels ?? [])
}
func fetchLabelsFromNetwork(dataService: DataService) async {
@ -101,7 +101,7 @@ import Views
}
setLabels(fetchedLabels)
unselectedLabels = fetchedLabels
unselectedLabels = Set(fetchedLabels)
}
func createLabel(dataService: DataService, name: String, color: Color, description: String?) {
@ -118,7 +118,7 @@ import Views
if let label = dataService.viewContext.object(with: labelObjectID) as? LinkedItemLabel {
labels.insert(label, at: 0)
selectedLabels.insert(label, at: 0)
selectedLabels.insert(label)
}
isLoading = false
@ -128,8 +128,6 @@ import Views
func deleteLabel(dataService: DataService, labelID: String, name: String) {
dataService.removeLabel(labelID: labelID, name: name)
labels.removeAll { $0.name == name }
selectedLabels.removeAll { $0.name == name }
unselectedLabels.removeAll { $0.name == name }
}
func saveItemLabelChanges(itemID: String, dataService: DataService) {
@ -139,14 +137,4 @@ import Views
func saveHighlightLabelChanges(highlightID: String, dataService: DataService) {
dataService.setLabelsForHighlight(highlightID: highlightID, labelIDs: selectedLabels.map(\.unwrappedID))
}
func addLabelToItem(_ label: LinkedItemLabel) {
selectedLabels.insert(label, at: 0)
unselectedLabels.removeAll { $0.name == label.name }
}
func removeLabelFromItem(_ label: LinkedItemLabel) {
unselectedLabels.insert(label, at: 0)
selectedLabels.removeAll { $0.name == label.name }
}
}

View File

@ -100,6 +100,7 @@ struct WebReader: PlatformViewRepresentable {
(webView as? OmnivoreWebView)?.updateTextContrast()
(webView as? OmnivoreWebView)?.updateMaxWidthPercentage()
(webView as? OmnivoreWebView)?.updateLineHeight()
(webView as? OmnivoreWebView)?.updateLabels(labelsJSON: item.labelsJSONString)
}
if showNavBarActionID != context.coordinator.previousShowNavBarActionID {

View File

@ -295,7 +295,11 @@ struct WebReaderContainerView: View {
Button(LocalText.cancelGeneric, role: .cancel, action: {})
}
.sheet(isPresented: $showLabelsModal) {
ApplyLabelsView(mode: .item(item), isSearchFocused: false, onSave: { _ in showLabelsModal = false })
ApplyLabelsView(mode: .item(item), isSearchFocused: false, onSave: { labels in
showLabelsModal = false
item.labels = NSSet(array: labels)
readerSettingsChangedTransactionID = UUID()
})
}
.sheet(isPresented: $showTitleEdit) {
LinkedItemMetadataEditView(item: item)

View File

@ -54,6 +54,7 @@ extension DataService {
send(mutation, to: path, headers: headers) { result in
let data = try? result.get()
let syncStatus: ServerSyncStatus = data == nil ? .needsUpdate : .isNSync
print("DATA: ", data)
context.perform {
guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: context) else { return }

View File

@ -105,6 +105,14 @@ public final class OmnivoreWebView: WKWebView {
}
}
public func updateLabels(labelsJSON: String) {
do {
try dispatchEvent(.updateLabels(labels: labelsJSON))
} catch {
showErrorInSnackbar("Error updating labels")
}
}
public func shareOriginalItem() {
do {
try dispatchEvent(.share)
@ -379,6 +387,7 @@ public enum WebViewDispatchEvent {
case copyHighlight
case dismissHighlight
case speakingSection(anchorIdx: String)
case updateLabels(labels: String)
var script: String {
get throws {
@ -421,6 +430,8 @@ public enum WebViewDispatchEvent {
return "dismissHighlight"
case .speakingSection:
return "speakingSection"
case .updateLabels:
return "updateLabels"
}
}
@ -441,6 +452,8 @@ public enum WebViewDispatchEvent {
return "event.isDark = '\(isDark)';"
case let .updateFontFamily(family: family):
return "event.fontFamily = '\(family)';"
case let .updateLabels(labels):
return "event.labels = \(labels);"
case let .saveAnnotation(annotation: annotation):
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(annotation) {

File diff suppressed because one or more lines are too long

View File

@ -50,8 +50,14 @@ const mutation = async (name, input) => {
}
const App = () => {
const [labels, setLabels] = React.useState(window.omnivoreArticle.labels)
applyStoredTheme(false)
document.addEventListener('updateLabels', (event) => {
console.log("updating labels: ", event.labels)
setLabels(event.labels)
})
return (
<>
<Box
@ -68,7 +74,7 @@ const App = () => {
>
<ArticleContainer
article={window.omnivoreArticle}
labels={window.omnivoreArticle.labels}
labels={labels}
isAppleAppEmbed={true}
highlightBarDisabled={!window.enableHighlightBar}
highlightsBaseURL="https://example.com"