Allow setting highlight labels by clicking a highlight

This commit is contained in:
Jackson Harper 2022-11-29 11:58:32 +08:00
parent 9665cfdb76
commit 53c9881fe0
6 changed files with 49 additions and 11 deletions

View file

@ -73,6 +73,9 @@ struct WebReaderContainerView: View {
case "annotate":
annotation = messageBody["annotation"] ?? ""
showHighlightAnnotationModal = true
case "setHighlightLabels":
annotation = messageBody["highlightID"] ?? ""
showHighlightLabelsModal = true
default:
break
}
@ -272,9 +275,6 @@ struct WebReaderContainerView: View {
.sheet(isPresented: $showLabelsModal) {
ApplyLabelsView(mode: .item(item), onSave: { _ in showLabelsModal = false })
}
.sheet(isPresented: $showHighlightLabelsModal) {
ApplyLabelsView(mode: .item(item), onSave: { _ in showLabelsModal = false })
}
.sheet(isPresented: $showTitleEdit) {
LinkedItemMetadataEditView(item: item)
}
@ -345,6 +345,15 @@ struct WebReaderContainerView: View {
}
)
}
.sheet(isPresented: $showHighlightLabelsModal) {
if let highlight = Highlight.lookup(byID: self.annotation, inContext: self.dataService.viewContext) {
ApplyLabelsView(mode: .highlight(highlight)) { selectedLabels in
viewModel.setLabelsForHighlight(highlightID: highlight.unwrappedID,
labelIDs: selectedLabels.map(\.unwrappedID),
dataService: dataService)
}
}
}
} else if let errorMessage = viewModel.errorMessage {
Text(errorMessage).padding()
} else {

View file

@ -169,4 +169,11 @@ struct SafariWebLink: Identifiable {
replyHandler(nil, "Unknown actionID: \(actionID)")
}
}
func setLabelsForHighlight(highlightID: String,
labelIDs: [String],
dataService: DataService)
{
dataService.setLabelsForHighlight(highlightID: highlightID, labelIDs: labelIDs)
}
}

View file

@ -295,7 +295,14 @@ public final class OmnivoreWebView: WKWebView {
hideMenu()
}
@objc public func setLabels(_: Any?) {}
@objc public func setLabels(_: Any?) {
do {
try dispatchEvent(.setHighlightLabels)
} catch {
showErrorInSnackbar("Error setting labels for highlight")
}
hideMenu()
}
override public func buildMenu(with builder: UIMenuBuilder) {
if #available(iOS 16.0, *) {
@ -368,6 +375,7 @@ public enum WebViewDispatchEvent {
case highlight
case share
case remove
case setHighlightLabels
case copyHighlight
case dismissHighlight
case speakingSection(anchorIdx: String)
@ -405,6 +413,8 @@ public enum WebViewDispatchEvent {
return "share"
case .remove:
return "remove"
case .setHighlightLabels:
return "setHighlightLabels"
case .copyHighlight:
return "copyHighlight"
case .dismissHighlight:
@ -441,7 +451,7 @@ public enum WebViewDispatchEvent {
}
case let .speakingSection(anchorIdx: anchorIdx):
return "event.anchorIdx = '\(anchorIdx)';"
case .annotate, .highlight, .share, .remove, .copyHighlight, .dismissHighlight:
case .annotate, .highlight, .setHighlightLabels, .share, .remove, .copyHighlight, .dismissHighlight:
return ""
}
}

File diff suppressed because one or more lines are too long

View file

@ -22,6 +22,7 @@ export type HighlightAction =
| 'share'
| 'post'
| 'unshare'
| 'setHighlightLabels'
type HighlightBarProps = {
anchorCoordinates: PageCoordinates
@ -133,10 +134,7 @@ function BarContent(props: HighlightBarProps): JSX.Element {
css={{ color: '$readerFont', height: '100%', m: 0, p: 0 }}
>
<HStack css={{ height: '100%', alignItems: 'center' }}>
<Trash
size={24}
color={theme.colors.omnivoreRed.toString()}
/>
<Trash size={24} color={theme.colors.omnivoreRed.toString()} />
<StyledText
style="body"
css={{
@ -157,7 +155,7 @@ function BarContent(props: HighlightBarProps): JSX.Element {
style="plainIcon"
title="Add Note to Highlight"
onClick={() => props.handleButtonClick('comment')}
css={{ color: '$readerFont', height: '100%', m: 0, p: 0}}
css={{ color: '$readerFont', height: '100%', m: 0, p: 0 }}
>
<HStack css={{ height: '100%', alignItems: 'center' }}>
<Note size={24} color={theme.colors.readerFont.toString()} />

View file

@ -381,6 +381,14 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
case 'unshare':
console.log('unshare')
break // TODO: implement -- need to show confirmation dialog
case 'setHighlightLabels':
if (props.isAppleAppEmbed) {
window?.webkit?.messageHandlers.highlightAction?.postMessage({
actionID: 'setHighlightLabels',
highlightID: focusedHighlight?.id,
})
}
break
}
},
[
@ -416,6 +424,10 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
setFocusedHighlight(undefined)
}
const setHighlightLabels = () => {
handleAction('setHighlightLabels')
}
const copy = async () => {
if (focusedHighlight) {
await navigator.clipboard.writeText(focusedHighlight.quote)
@ -468,6 +480,7 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
document.addEventListener('dismissHighlight', dismissHighlight)
document.addEventListener('saveAnnotation', saveAnnotation)
document.addEventListener('speakingSection', speakingSection)
document.addEventListener('setHighlightLabels', setHighlightLabels)
return () => {
document.removeEventListener('annotate', annotate)
@ -478,6 +491,7 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
document.removeEventListener('dismissHighlight', dismissHighlight)
document.removeEventListener('saveAnnotation', saveAnnotation)
document.removeEventListener('speakingSection', speakingSection)
document.removeEventListener('setHighlightLabels', setHighlightLabels)
}
})