handle keyboard event in iframe

This commit is contained in:
2025-05-21 16:25:25 +01:00
parent bc8856d60f
commit af56fa636f

View File

@@ -1,5 +1,5 @@
import type { Bookmark } from "@markone/core/bookmark" import type { Bookmark } from "@markone/core/bookmark"
import { createFileRoute, useCanGoBack, useNavigate, useRouter } from "@tanstack/react-router" import { createFileRoute, useNavigate } from "@tanstack/react-router"
import clsx from "clsx" import clsx from "clsx"
import { atom, useAtom } from "jotai" import { atom, useAtom } from "jotai"
import { useCallback, useEffect, useRef } from "react" import { useCallback, useEffect, useRef } from "react"
@@ -118,20 +118,38 @@ function BookmarkListContainer() {
function BookmarkPreview() { function BookmarkPreview() {
const { bookmarkId } = Route.useParams() const { bookmarkId } = Route.useParams()
const { const { data: previewHtml, status: previewQueryStatus } = useAuthenticatedQuery(
data: previewHtml, ["bookmarks", `${bookmarkId}.html`],
status: previewQueryStatus, () =>
error, fetchApi(`/bookmarks/${bookmarkId}`, {
} = useAuthenticatedQuery(["bookmarks", `${bookmarkId}.html`], () => headers: {
fetchApi(`/bookmarks/${bookmarkId}`, { Accept: "text/html",
headers: { },
Accept: "text/html", }).then((res) => res.text()),
},
}).then((res) => res.text()),
) )
const { data: bookmark, status: bookmarkQueryStatus } = useBookmark(bookmarkId) const { data: bookmark, status: bookmarkQueryStatus } = useBookmark(bookmarkId)
const [_titleBarHeight] = useAtom(titleBarHeight) const [_titleBarHeight] = useAtom(titleBarHeight)
const [_actionBarHeight] = useAtom(actionBarHeight) const [_actionBarHeight] = useAtom(actionBarHeight)
const navigate = useNavigate()
function attachKeyListenerToIFrame(event: React.SyntheticEvent<HTMLIFrameElement, Event>) {
if (event.currentTarget.contentDocument) {
event.currentTarget.contentDocument.addEventListener("keydown", (keyEvent) => {
switch (keyEvent.key) {
case "c":
navigate({ to: "/bookmarks", replace: true })
break
case "o":
if (bookmark) {
window.open(bookmark.url, "_blank")?.focus()
}
break
default:
break
}
})
}
}
if (previewQueryStatus === "error") { if (previewQueryStatus === "error") {
return ( return (
@@ -148,6 +166,7 @@ function BookmarkPreview() {
className="w-full h-full" className="w-full h-full"
style={{ paddingTop: _titleBarHeight, paddingBottom: _actionBarHeight }} style={{ paddingTop: _titleBarHeight, paddingBottom: _actionBarHeight }}
srcDoc={previewHtml} srcDoc={previewHtml}
onLoad={attachKeyListenerToIFrame}
/> />
) )
} }
@@ -218,7 +237,9 @@ function BookmarkPreviewActionBar() {
} }
function openLink() { function openLink() {
linkRef.current?.click() if (bookmark) {
window.open(bookmark.url, "_blank")?.focus()
}
} }
if (status !== "success") { if (status !== "success") {