Pass tap events from web reader into native instead of setting up gestures in native

This allows us to handle tap events based on state better, most
importantly it means we wont raise the bottom buttons if the
there is a tap to dismiss an active menu.
This commit is contained in:
Jackson Harper
2023-02-08 18:52:12 +08:00
parent 35a2e91fb8
commit 3062e16e63
8 changed files with 57 additions and 26 deletions

View File

@ -8,6 +8,7 @@ struct WebReader: PlatformViewRepresentable {
let item: LinkedItem
let articleContent: ArticleContent
let openLinkAction: (URL) -> Void
let tapHandler: () -> Void
let webViewActionHandler: (WKScriptMessage, WKScriptMessageReplyHandler?) -> Void
let navBarVisibilityRatioUpdater: (Double) -> Void
@ -46,6 +47,7 @@ struct WebReader: PlatformViewRepresentable {
let webView = WebViewManager.shared()
let contentController = WKUserContentController()
webView.tapHandler = tapHandler
webView.navigationDelegate = context.coordinator
webView.configuration.userContentController = contentController
webView.configuration.userContentController.removeAllScriptMessageHandlers()

View File

@ -73,6 +73,14 @@ struct WebReaderContainerView: View {
}
}
private func tapHandler() {
withAnimation(.easeIn(duration: 0.08)) {
navBarVisibilityRatio = navBarVisibilityRatio == 1 ? 0 : 1
showBottomBar = navBarVisibilityRatio == 1
showNavBarActionID = UUID()
}
}
private func handleHighlightAction(message: WKScriptMessage) {
guard let messageBody = message.body as? [String: String] else { return }
guard let actionID = messageBody["actionID"] else { return }
@ -89,6 +97,12 @@ struct WebReaderContainerView: View {
case "setHighlightLabels":
annotation = messageBody["highlightID"] ?? ""
showHighlightLabelsModal = true
case "pageTapped":
withAnimation {
navBarVisibilityRatio = navBarVisibilityRatio == 1 ? 0 : 1
showBottomBar = navBarVisibilityRatio == 1
showNavBarActionID = UUID()
}
default:
break
}
@ -354,6 +368,7 @@ struct WebReaderContainerView: View {
}
#endif
},
tapHandler: tapHandler,
webViewActionHandler: webViewActionHandler,
navBarVisibilityRatioUpdater: {
navBarVisibilityRatio = $0
@ -366,13 +381,6 @@ struct WebReaderContainerView: View {
showBottomBar: $showBottomBar,
showHighlightAnnotationModal: $showHighlightAnnotationModal
)
.onTapGesture {
withAnimation {
navBarVisibilityRatio = navBarVisibilityRatio == 1 ? 0 : 1
showBottomBar = navBarVisibilityRatio == 1
showNavBarActionID = UUID()
}
}
.confirmationDialog(linkToOpen?.absoluteString ?? "", isPresented: $displayLinkSheet) {
Button(action: {
if let linkToOpen = linkToOpen {

View File

@ -16,10 +16,12 @@ enum ContextMenu {
public final class OmnivoreWebView: WKWebView {
#if os(iOS)
private var menuDisplayed = false
private var panGestureRecognizer: UIPanGestureRecognizer?
private var tapGestureRecognizer: UITapGestureRecognizer?
#endif
public var tapHandler: (() -> Void)?
private var currentMenu: ContextMenu = .defaultMenu
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
@ -196,6 +198,17 @@ public final class OmnivoreWebView: WKWebView {
{ // swiftlint:disable:this opening_brace
showHighlightMenu(CGRect(x: rectX, y: rectY, width: rectWidth, height: rectHeight))
}
case "pageTapped":
print("currentMenu: ", currentMenu, "menuDisplayed", menuDisplayed)
if menuDisplayed {
hideMenuAndDismissHighlight()
break
}
if let tapHandler = self.tapHandler {
tapHandler()
}
default:
break
}
@ -338,14 +351,11 @@ public final class OmnivoreWebView: WKWebView {
private func hideMenu() {
UIMenuController.shared.hideMenu()
if let tapGestureRecognizer = tapGestureRecognizer {
removeGestureRecognizer(tapGestureRecognizer)
self.tapGestureRecognizer = nil
}
if let panGestureRecognizer = panGestureRecognizer {
removeGestureRecognizer(panGestureRecognizer)
self.panGestureRecognizer = nil
}
menuDisplayed = false
setDefaultMenu()
}
@ -357,21 +367,13 @@ public final class OmnivoreWebView: WKWebView {
private func showHighlightMenu(_ rect: CGRect) {
setHighlightMenu()
// When the highlight menu is displayed we set up gesture recognizers so it
// can be dismissed if the user interacts with another part of the view.
// This isn't needed for the default menu as the system will handle that.
if tapGestureRecognizer == nil {
let tap = UITapGestureRecognizer(target: self, action: #selector(gestureHandled))
tap.delegate = self
addGestureRecognizer(tap)
tapGestureRecognizer = tap
}
if panGestureRecognizer == nil {
let pan = UIPanGestureRecognizer(target: self, action: #selector(gestureHandled))
pan.delegate = self
addGestureRecognizer(pan)
panGestureRecognizer = pan
}
menuDisplayed = true
UIMenuController.shared.showMenu(from: self, rect: rect)
}

File diff suppressed because one or more lines are too long

View File

@ -49,7 +49,8 @@ public struct TextChip: View {
return .white
}
return luminance > 0.3 ? .black : .white
print(" Luminance: ", luminance, "for color", color.hex)
return luminance > 0.35 ? .black : .white
}
var backgroundColor: Color {

View File

@ -17,12 +17,24 @@ export function LabelChip(props: LabelChipProps): JSX.Element {
const g = (bigint >> 8) & 255
const b = bigint & 255
console.log(' -- ', r, g, b, 'for', hex)
return [r, g, b]
}
const parsed = parseToRgba(props.color)
console.log(' -- parsed: ', parsed, 'for', props.color)
function f(x: number) {
const channel = x / 255
return channel <= 0.03928
? channel / 12.92
: Math.pow((channel + 0.055) / 1.055, 2.4)
}
console.log(' -- parts: ', f(parsed[0]), f(parsed[1]), f(parsed[2]))
const luminance = getLuminance(props.color)
const backgroundColor = hexToRgb(props.color)
const textColor = luminance > 0.3 ? '#000000' : '#ffffff'
console.log('luminance', luminance, 'for color: ', props.color)
const textColor = luminance > 0.5 ? '#000000' : '#ffffff'
return (
<Button

View File

@ -278,6 +278,8 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
const { target, pageX, pageY } = event
if (!target || (target as Node)?.nodeType !== Node.ELEMENT_NODE) {
console.log(' -- returning early from page tap')
return
}
@ -333,6 +335,10 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
highlightModalAction: 'addComment',
})
} else {
console.log('sending page tapped')
window?.webkit?.messageHandlers.viewerAction?.postMessage({
actionID: 'pageTapped',
})
setFocusedHighlight(undefined)
}
},

View File

@ -131,7 +131,7 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } =
grayProgressBackground: '#FFFFFF',
// Semantic Colors
highlightBackground: '250, 227, 146',
highlightBackground: '255, 255, 0',
recommendedHighlightBackground: '#E5FFE5',
highlight: '#FFD234',
highlightText: '#3D3D3D',
@ -203,7 +203,7 @@ const darkThemeSpec = {
grayProgressBackground: '#616161',
// Semantic Colors
highlightBackground: '134, 119, 64',
highlightBackground: '134, 109, 21',
recommendedHighlightBackground: '#1F4315',
highlight: '#FFD234',
highlightText: 'white',