diff --git a/web/src/ui/modal/Modal.tsx b/web/src/ui/modal/Modal.tsx
index 83a1176..1fc3ab6 100644
--- a/web/src/ui/modal/Modal.tsx
+++ b/web/src/ui/modal/Modal.tsx
@@ -13,7 +13,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import React, { JSX, useCallback, useLayoutEffect, useReducer, useRef } from "react"
+import React, { JSX, useCallback, useEffect, useLayoutEffect, useReducer, useRef } from "react"
import { ModalCloseContext, ModalContext, ModalState } from "./contexts.ts"
const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
@@ -40,7 +40,7 @@ const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
evt.stopPropagation()
}
const openModal = useCallback((newState: ModalState) => {
- if (!history.state?.modal) {
+ if (!history.state?.modal && newState.captureInput !== false) {
history.pushState({ ...(history.state ?? {}), modal: true }, "")
}
setState(newState)
@@ -50,6 +50,9 @@ const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
if (wrapperRef.current && (!document.activeElement || !wrapperRef.current.contains(document.activeElement))) {
wrapperRef.current.focus()
}
+ }, [state])
+ useEffect(() => {
+ window.closeModal = onClickWrapper
const listener = (evt: PopStateEvent) => {
if (!evt.state?.modal) {
setState(null)
@@ -57,7 +60,7 @@ const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
}
window.addEventListener("popstate", listener)
return () => window.removeEventListener("popstate", listener)
- }, [state])
+ }, [])
let modal: JSX.Element | null = null
if (state) {
let content = {state.content}
@@ -68,15 +71,19 @@ const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
}
- modal =
- {content}
-
+ if (state.captureInput !== false) {
+ modal =
+ {content}
+
+ } else {
+ modal = content
+ }
}
return
{children}
diff --git a/web/src/ui/modal/contexts.ts b/web/src/ui/modal/contexts.ts
index e7fa7c7..dad5963 100644
--- a/web/src/ui/modal/contexts.ts
+++ b/web/src/ui/modal/contexts.ts
@@ -32,6 +32,7 @@ export interface ModalState {
boxClass?: string
innerBoxClass?: string
onClose?: () => void
+ captureInput?: boolean
}
type openModal = (state: ModalState) => void
diff --git a/web/src/ui/timeline/TimelineEvent.tsx b/web/src/ui/timeline/TimelineEvent.tsx
index 760428e..38b15d7 100644
--- a/web/src/ui/timeline/TimelineEvent.tsx
+++ b/web/src/ui/timeline/TimelineEvent.tsx
@@ -107,9 +107,21 @@ const TimelineEvent = ({ evt, prevEvt, disableMenu, smallReplies }: TimelineEven
return
}
mouseEvt.preventDefault()
- openModal({
- content: ,
- })
+ if (window.hackyOpenEventContextMenu === evt.event_id) {
+ window.closeModal()
+ window.hackyOpenEventContextMenu = undefined
+ } else {
+ openModal({
+ content: ,
+ captureInput: false,
+ onClose: () => {
+ if (window.hackyOpenEventContextMenu === evt.event_id) {
+ window.hackyOpenEventContextMenu = undefined
+ }
+ },
+ })
+ window.hackyOpenEventContextMenu = evt.event_id
+ }
}
const memberEvt = useRoomMember(client, roomCtx.store, evt.sender)
const memberEvtContent = memberEvt?.content as MemberEventContent | undefined
diff --git a/web/src/ui/timeline/menu/index.css b/web/src/ui/timeline/menu/index.css
index 2750816..535273b 100644
--- a/web/src/ui/timeline/menu/index.css
+++ b/web/src/ui/timeline/menu/index.css
@@ -28,6 +28,7 @@ div.event-fixed-menu {
box-sizing: border-box;
justify-content: right;
flex-direction: row-reverse;
+ overflow-x: auto;
> button {
width: 3rem;
diff --git a/web/src/vite-env.d.ts b/web/src/vite-env.d.ts
index ceffa1a..9cef2d8 100644
--- a/web/src/vite-env.d.ts
+++ b/web/src/vite-env.d.ts
@@ -14,5 +14,7 @@ declare global {
mainScreenContext: MainScreenContextFields
openLightbox: (params: { src: string, alt: string }) => void
gcSettings: GCSettings
+ hackyOpenEventContextMenu?: string
+ closeModal: () => void
}
}