1
0
Fork 0
forked from Mirrors/gomuks

web/widget: implement handling close event

This commit is contained in:
Tulir Asokan 2025-03-08 15:57:53 +02:00
parent b3b255e71c
commit fbad48129b
4 changed files with 17 additions and 12 deletions

View file

@ -16,7 +16,7 @@
import type { IWidget } from "matrix-widget-api" import type { IWidget } from "matrix-widget-api"
import { JSX, use } from "react" import { JSX, use } from "react"
import type { UserID } from "@/api/types" import type { UserID } from "@/api/types"
import MainScreenContext from "../MainScreenContext.ts" import MainScreenContext, { MainScreenContextFields } from "../MainScreenContext.ts"
import ErrorBoundary from "../util/ErrorBoundary.tsx" import ErrorBoundary from "../util/ErrorBoundary.tsx"
import ElementCall from "../widget/ElementCall.tsx" import ElementCall from "../widget/ElementCall.tsx"
import LazyWidget from "../widget/LazyWidget.tsx" import LazyWidget from "../widget/LazyWidget.tsx"
@ -63,7 +63,7 @@ function getTitle(props: RightPanelProps): string {
} }
} }
function renderRightPanelContent(props: RightPanelProps): JSX.Element | null { function renderRightPanelContent(props: RightPanelProps, mainScreen: MainScreenContextFields): JSX.Element | null {
switch (props.type) { switch (props.type) {
case "pinned-messages": case "pinned-messages":
return <PinnedMessages /> return <PinnedMessages />
@ -72,9 +72,9 @@ function renderRightPanelContent(props: RightPanelProps): JSX.Element | null {
case "widgets": case "widgets":
return <WidgetList /> return <WidgetList />
case "element-call": case "element-call":
return <ElementCall /> return <ElementCall onClose={mainScreen.closeRightPanel} />
case "widget": case "widget":
return <LazyWidget info={props.info} /> return <LazyWidget info={props.info} onClose={mainScreen.closeRightPanel} />
case "user": case "user":
return <UserInfo userID={props.userID} /> return <UserInfo userID={props.userID} />
} }
@ -104,7 +104,7 @@ const RightPanel = (props: RightPanelProps) => {
</div> </div>
<div className={`right-panel-content ${props.type}`}> <div className={`right-panel-content ${props.type}`}>
<ErrorBoundary thing="right panel content"> <ErrorBoundary thing="right panel content">
{renderRightPanelContent(props)} {renderRightPanelContent(props, mainScreen)}
</ErrorBoundary> </ErrorBoundary>
</div> </div>
</div> </div>

View file

@ -33,7 +33,7 @@ const elementCallParams = new URLSearchParams({
appPrompt: "false", appPrompt: "false",
}).toString().replaceAll("%24", "$") }).toString().replaceAll("%24", "$")
const ElementCall = () => { const ElementCall = ({ onClose }: { onClose?: () => void }) => {
const room = use(RoomContext)?.store ?? null const room = use(RoomContext)?.store ?? null
const client = use(ClientContext)! const client = use(ClientContext)!
const baseURL = usePreference(client.store, room, "element_call_base_url") const baseURL = usePreference(client.store, room, "element_call_base_url")
@ -51,7 +51,7 @@ const ElementCall = () => {
if (!room || !client) { if (!room || !client) {
return null return null
} }
return <LazyWidget info={widgetInfo} /> return <LazyWidget info={widgetInfo} onClose={onClose} />
} }
export default ElementCall export default ElementCall

View file

@ -28,9 +28,10 @@ const widgetLoader = <div className="widget-container widget-loading">
export interface LazyWidgetProps { export interface LazyWidgetProps {
info: IWidget info: IWidget
onClose?: () => void
} }
const LazyWidget = ({ info }: LazyWidgetProps) => { const LazyWidget = ({ info, onClose }: LazyWidgetProps) => {
const room = use(RoomContext)?.store const room = use(RoomContext)?.store
const client = use(ClientContext) const client = use(ClientContext)
if (!room || !client) { if (!room || !client) {
@ -38,7 +39,7 @@ const LazyWidget = ({ info }: LazyWidgetProps) => {
} }
return ( return (
<Suspense fallback={widgetLoader}> <Suspense fallback={widgetLoader}>
<Widget info={info} room={room} client={client} /> <Widget info={info} room={room} client={client} onClose={onClose} />
</Suspense> </Suspense>
) )
} }

View file

@ -27,6 +27,7 @@ export interface WidgetProps {
info: IWidget info: IWidget
room: RoomStateStore room: RoomStateStore
client: Client client: Client
onClose?: () => void
} }
// TODO remove this after widgets start using a parameter for it // TODO remove this after widgets start using a parameter for it
@ -68,7 +69,7 @@ class WidgetListenerImpl implements WidgetListener {
} }
} }
const ReactWidget = ({ room, info, client }: WidgetProps) => { const ReactWidget = ({ room, info, client, onClose }: WidgetProps) => {
const wrappedWidget = new WrappedWidget(info) const wrappedWidget = new WrappedWidget(info)
const driver = new GomuksWidgetDriver(client, room) const driver = new GomuksWidgetDriver(client, room)
const widgetURL = addLegacyParams(wrappedWidget.getCompleteUrl({ const widgetURL = addLegacyParams(wrappedWidget.getCompleteUrl({
@ -92,13 +93,16 @@ const ReactWidget = ({ room, info, client }: WidgetProps) => {
evt.preventDefault() evt.preventDefault()
clientAPI.transport.reply(evt.detail, {}) clientAPI.transport.reply(evt.detail, {})
} }
const closeWidget = (evt: CustomEvent) => {
noopReply(evt)
onClose?.()
}
clientAPI.on("action:io.element.join", noopReply) clientAPI.on("action:io.element.join", noopReply)
clientAPI.on("action:im.vector.hangup", noopReply) clientAPI.on("action:im.vector.hangup", noopReply)
clientAPI.on("action:io.element.device_mute", noopReply) clientAPI.on("action:io.element.device_mute", noopReply)
clientAPI.on("action:io.element.tile_layout", noopReply) clientAPI.on("action:io.element.tile_layout", noopReply)
clientAPI.on("action:io.element.spotlight_layout", noopReply) clientAPI.on("action:io.element.spotlight_layout", noopReply)
// TODO handle this one? clientAPI.on("action:io.element.close", closeWidget)
clientAPI.on("action:io.element.close", noopReply)
clientAPI.on("action:set_always_on_screen", noopReply) clientAPI.on("action:set_always_on_screen", noopReply)
const removeListener = client.addWidgetListener(new WidgetListenerImpl(clientAPI)) const removeListener = client.addWidgetListener(new WidgetListenerImpl(clientAPI))