diff --git a/examples/vite/src/AppSettings/ActionsMenu/ActionsMenu.tsx b/examples/vite/src/AppSettings/ActionsMenu/ActionsMenu.tsx index 50682e18e7..e20ea0a3f3 100644 --- a/examples/vite/src/AppSettings/ActionsMenu/ActionsMenu.tsx +++ b/examples/vite/src/AppSettings/ActionsMenu/ActionsMenu.tsx @@ -18,6 +18,10 @@ import { AttachmentPromptDialog, attachmentPromptDialogId, } from './AttachmentPromptDialog'; +import { + WebSocketEventPromptDialog, + webSocketEventPromptDialogId, +} from './WebSocketEventPromptDialog'; const actionsMenuDialogId = 'app-actions-menu'; @@ -91,6 +95,20 @@ function TriggerAttachmentAction({ onTrigger }: { onTrigger: () => void }) { ); } +function TriggerWebSocketEventAction({ onTrigger }: { onTrigger: () => void }) { + const { closeMenu } = useContextMenuContext(); + + return ( + { + closeMenu(); + onTrigger(); + }} + /> + ); +} + const ActionsMenuInner = ({ iconOnly }: { iconOnly: boolean }) => { const [menuButtonElement, setMenuButtonElement] = useState( null, @@ -104,6 +122,9 @@ const ActionsMenuInner = ({ iconOnly }: { iconOnly: boolean }) => { const { dialog: attachmentDialog } = useDialogOnNearestManager({ id: attachmentPromptDialogId, }); + const { dialog: webSocketEventDialog } = useDialogOnNearestManager({ + id: webSocketEventPromptDialogId, + }); const menuIsOpen = useDialogIsOpen(actionsMenuDialogId, dialogManager?.id); return ( @@ -127,9 +148,11 @@ const ActionsMenuInner = ({ iconOnly }: { iconOnly: boolean }) => { > + + ); }; diff --git a/examples/vite/src/AppSettings/ActionsMenu/AttachmentPromptDialog.tsx b/examples/vite/src/AppSettings/ActionsMenu/AttachmentPromptDialog.tsx index c095c4a4bd..e213d620e1 100644 --- a/examples/vite/src/AppSettings/ActionsMenu/AttachmentPromptDialog.tsx +++ b/examples/vite/src/AppSettings/ActionsMenu/AttachmentPromptDialog.tsx @@ -1,18 +1,16 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; -import type { PointerEvent as ReactPointerEvent } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import type { LocalAttachment } from 'stream-chat'; import { - DialogAnchor, Prompt, useChatContext, useDialogIsOpen, useDialogOnNearestManager, } from 'stream-chat-react'; +import { DraggableDialog } from './DraggableDialog'; export const attachmentPromptDialogId = 'app-attachment-prompt-dialog'; type AttachmentEditorTab = 'unsupported-file' | 'unsupported-object'; -const VIEWPORT_MARGIN = 8; const defaultUnsupportedAttachment = { asset_url: 'https://example.com/unsupported.bin', file_size: 128000, @@ -43,11 +41,6 @@ const initialUnsupportedObjectValue = JSON.stringify( 2, ); -const clamp = (value: number, min: number, max: number) => { - if (max < min) return min; - return Math.min(Math.max(value, min), max); -}; - export const AttachmentPromptDialog = ({ referenceElement, }: { @@ -61,8 +54,6 @@ export const AttachmentPromptDialog = ({ initialUnsupportedObjectValue, ); const [errorMessage, setErrorMessage] = useState(null); - const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 }); - const shellRef = useRef(null); const { channel } = useChatContext(); const { dialog, dialogManager } = useDialogOnNearestManager({ id: attachmentPromptDialogId, @@ -75,41 +66,6 @@ export const AttachmentPromptDialog = ({ setUnsupportedFileInput(initialUnsupportedFileValue); setUnsupportedObjectInput(initialUnsupportedObjectValue); setErrorMessage(null); - setDragOffset({ x: 0, y: 0 }); - }, [dialogIsOpen]); - - useEffect(() => { - if (!dialogIsOpen) return; - - const clampToViewport = () => { - const shell = shellRef.current; - if (!shell) return; - - const rect = shell.getBoundingClientRect(); - const nextLeft = clamp( - rect.left, - VIEWPORT_MARGIN, - window.innerWidth - rect.width - VIEWPORT_MARGIN, - ); - const nextTop = clamp( - rect.top, - VIEWPORT_MARGIN, - window.innerHeight - rect.height - VIEWPORT_MARGIN, - ); - - if (nextLeft === rect.left && nextTop === rect.top) return; - - setDragOffset((current) => ({ - x: current.x + (nextLeft - rect.left), - y: current.y + (nextTop - rect.top), - })); - }; - - window.addEventListener('resize', clampToViewport); - - return () => { - window.removeEventListener('resize', clampToViewport); - }; }, [dialogIsOpen]); const closeDialog = useCallback(() => { @@ -145,159 +101,99 @@ export const AttachmentPromptDialog = ({ [channel, closeDialog, unsupportedFileInput, unsupportedObjectInput], ); - const handleHeaderPointerDown = useCallback( - (event: ReactPointerEvent) => { - if (event.button !== 0) return; - if (!(event.target instanceof HTMLElement)) return; - if (event.target.closest('button')) return; - - const shell = shellRef.current; - if (!shell) return; - - event.preventDefault(); - - const startClientX = event.clientX; - const startClientY = event.clientY; - const startOffset = dragOffset; - const startRect = shell.getBoundingClientRect(); - - const handlePointerMove = (moveEvent: PointerEvent) => { - const nextLeft = clamp( - startRect.left + (moveEvent.clientX - startClientX), - VIEWPORT_MARGIN, - window.innerWidth - startRect.width - VIEWPORT_MARGIN, - ); - const nextTop = clamp( - startRect.top + (moveEvent.clientY - startClientY), - VIEWPORT_MARGIN, - window.innerHeight - startRect.height - VIEWPORT_MARGIN, - ); - - setDragOffset({ - x: startOffset.x + (nextLeft - startRect.left), - y: startOffset.y + (nextTop - startRect.top), - }); - }; - - const handlePointerUp = () => { - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); - }; - - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); - }, - [dragOffset], - ); - - const shellStyle = { - transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)`, - }; - return ( - -
- + +
+

+ Attach Unsupported Attachment +

- + +
- -
-

- Attach Unsupported Attachment -

-
+ Attachment JSON +