Enable highlight on selection behavior on iOS

This commit is contained in:
Jackson Harper 2023-02-02 18:03:14 +08:00
parent 4f2d05d3be
commit 92d5851aa9
6 changed files with 54 additions and 15 deletions

File diff suppressed because one or more lines are too long

View file

@ -99,6 +99,7 @@ const App = () => {
margin={window.margin}
maxWidthPercentage={window.maxWidthPercentage}
lineHeight={window.lineHeight}
highlightOnRelease={true}
highContrastFont={window.prefersHighContrastFont ?? true}
articleMutations={{
createHighlightMutation: (input) =>

View file

@ -30,6 +30,7 @@ type ArticleContainerProps = {
maxWidthPercentage?: number
highContrastFont?: boolean
showHighlightsModal: boolean
highlightOnRelease?: boolean
setShowHighlightsModal: React.Dispatch<React.SetStateAction<boolean>>
}
@ -380,6 +381,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
highlightBarDisabled={props.highlightBarDisabled}
showHighlightsModal={props.showHighlightsModal}
setShowHighlightsModal={props.setShowHighlightsModal}
highlightOnRelease={props.highlightOnRelease}
articleMutations={props.articleMutations}
/>
{showReportIssuesModal ? (

View file

@ -36,6 +36,7 @@ type HighlightsLayerProps = {
isAppleAppEmbed: boolean
highlightBarDisabled: boolean
showHighlightsModal: boolean
highlightOnRelease?: boolean
scrollToHighlight: MutableRefObject<string | null>
setShowHighlightsModal: React.Dispatch<React.SetStateAction<boolean>>
articleMutations: ArticleMutations
@ -262,7 +263,6 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
}
},
[
handleNativeShare,
highlights,
openNoteModal,
props.articleId,
@ -386,14 +386,14 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
)
if (focusedHighlight) {
if (canShareNative) {
handleNativeShare(focusedHighlight.shortId)
} else {
setHighlightModalAction({
highlight: focusedHighlight,
highlightModalAction: 'share',
})
}
// if (canShareNative) {
// handleNativeShare(focusedHighlight.shortId)
// } else {
// setHighlightModalAction({
// highlight: focusedHighlight,
// highlightModalAction: 'share',
// })
// }
} else {
await createHighlightCallback('share')
}
@ -416,7 +416,6 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
[
createHighlightCallback,
focusedHighlight,
handleNativeShare,
openNoteModal,
props.highlightBarDisabled,
props.isAppleAppEmbed,
@ -425,6 +424,12 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
]
)
useEffect(() => {
if (props.highlightOnRelease && selectionData?.wasDragEvent) {
handleAction('create')
}
}, [selectionData])
const dispatchHighlightError = (action: string, error: unknown) => {
if (props.isAppleAppEmbed) {
window?.webkit?.messageHandlers.highlightAction?.postMessage({

View file

@ -1,6 +1,5 @@
export type SelectionAttributes = {
selection: Selection
mouseEvent: React.MouseEvent
range: Range
focusPosition: {
x: number
@ -8,6 +7,7 @@ export type SelectionAttributes = {
isReverseSelected: boolean
}
overlapHighlights: string[]
wasDragEvent: boolean
}
export const highlightIdAttribute = 'omnivore-highlight-id'

View file

@ -9,16 +9,39 @@ import type { SelectionAttributes } from './highlightHelpers'
export function useSelection(
highlightLocations: HighlightLocation[]
): [SelectionAttributes | null, (x: SelectionAttributes | null) => void] {
const [touchStartPos, setTouchStartPos] = useState<
{ x: number; y: number } | undefined
>(undefined)
const [selectionAttributes, setSelectionAttributes] =
useState<SelectionAttributes | null>(null)
const handleTouchStart = useCallback(
(event: TouchEvent) => {
setTouchStartPos({
x: event.touches[0].pageX,
y: event.touches[0].pageY,
})
},
[touchStartPos, setTouchStartPos]
)
const handleFinishTouch = useCallback(
async (mouseEvent) => {
var wasDragEvent = false
const tapAttributes = {
tapX: mouseEvent.screenX,
tapY: mouseEvent.screenY,
}
if (touchStartPos) {
if (
Math.abs(touchStartPos.x - mouseEvent.pageX) > 10 ||
Math.abs(touchStartPos.y - mouseEvent.pageY) > 10
) {
wasDragEvent = true
}
}
window?.AndroidWebKitMessenger?.handleIdentifiableMessage(
'userTap',
JSON.stringify(tapAttributes)
@ -117,7 +140,7 @@ export function useSelection(
return setSelectionAttributes({
selection,
mouseEvent,
wasDragEvent,
range: mergedRange ?? range,
focusPosition: {
x: rangeRect[isReverseSelected ? 'left' : 'right'],
@ -127,7 +150,7 @@ export function useSelection(
overlapHighlights: overlapHighlights.map(({ id }) => id),
})
},
[highlightLocations]
[highlightLocations, touchStartPos, setTouchStartPos]
)
const copyTextSelection = useCallback(async () => {
@ -141,17 +164,25 @@ export function useSelection(
useEffect(() => {
document.addEventListener('mouseup', handleFinishTouch)
document.addEventListener('touchstart', handleTouchStart)
document.addEventListener('touchend', handleFinishTouch)
document.addEventListener('contextmenu', handleFinishTouch)
document.addEventListener('copyTextSelection', copyTextSelection)
return () => {
document.removeEventListener('mouseup', handleFinishTouch)
document.removeEventListener('touchstart', handleTouchStart)
document.removeEventListener('touchend', handleFinishTouch)
document.removeEventListener('contextmenu', handleFinishTouch)
document.removeEventListener('copyTextSelection', copyTextSelection)
}
}, [highlightLocations, handleFinishTouch, copyTextSelection])
}, [
highlightLocations,
handleFinishTouch,
copyTextSelection,
touchStartPos,
setTouchStartPos,
])
return [selectionAttributes, setSelectionAttributes]
}