diff --git a/src/app/components/message/layout/Bubble.css.ts b/src/app/components/message/layout/Bubble.css.ts index c5c2d0a3..01b60b6d 100644 --- a/src/app/components/message/layout/Bubble.css.ts +++ b/src/app/components/message/layout/Bubble.css.ts @@ -85,13 +85,6 @@ export const MediaPlain = style({ maxWidth: '100%', }); -// Editing: the body is the composer card itself (wrapped in ChatComposer by the -// caller) — full width, no bubble background of our own. -export const EditContent = style({ - width: '100%', - minWidth: 0, -}); - // Tap-rail open (or context menu / emoji board open) → the message reads as // «selected», the same affordance long-press gives. A soft brand ring rather // than a fill so it works over both the bubble and bare peer text / media. diff --git a/src/app/components/message/layout/Bubble.tsx b/src/app/components/message/layout/Bubble.tsx index 43f3c681..2866c280 100644 --- a/src/app/components/message/layout/Bubble.tsx +++ b/src/app/components/message/layout/Bubble.tsx @@ -19,9 +19,6 @@ export type BubbleLayoutProps = { // media AND for the tail of a same-minute series (grouped messages). A single // text message keeps its timestamp on the side. timeBelow?: boolean; - // While editing, the body IS a composer card — drop the bubble chrome so it - // reads as one box, and skip the timestamp. - editing?: boolean; // Reactions chip-row, floats under the message on the page background. reactions?: ReactNode; threadSummary?: ReactNode; @@ -45,7 +42,6 @@ export const BubbleLayout = as<'div', BubbleLayoutProps>( selected, mediaMode, timeBelow, - editing, reactions, threadSummary, readStatus, @@ -63,10 +59,7 @@ export const BubbleLayout = as<'div', BubbleLayoutProps>( ); let body: ReactNode; - if (editing) { - // The child is already a composer card; render it full width, no chrome. - body =
{children}
; - } else if (mediaMode || timeBelow) { + if (mediaMode || timeBelow) { // Media, and the tail of a same-minute series: timestamp BELOW the content, // aligned to the message side by the Row (own → right, peer → left). body = ( diff --git a/src/app/components/upload-board/UploadBoard.css.ts b/src/app/components/upload-board/UploadBoard.css.ts deleted file mode 100644 index 80c1b264..00000000 --- a/src/app/components/upload-board/UploadBoard.css.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { style } from '@vanilla-extract/css'; -import { DefaultReset, color, config, toRem } from 'folds'; - -export const UploadBoardBase = style([ - DefaultReset, - { - position: 'relative', - pointerEvents: 'none', - }, -]); - -export const UploadBoardContainer = style([ - DefaultReset, - { - position: 'absolute', - bottom: config.space.S200, - left: 0, - right: 0, - zIndex: config.zIndex.Max, - }, -]); - -export const UploadBoard = style({ - maxWidth: toRem(400), - width: '100%', - maxHeight: toRem(450), - height: '100%', - backgroundColor: color.Surface.Container, - color: color.Surface.OnContainer, - borderRadius: config.radii.R400, - boxShadow: config.shadow.E200, - border: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`, - overflow: 'hidden', - pointerEvents: 'all', -}); - -export const UploadBoardHeaderContent = style({ - height: '100%', - padding: `0 ${config.space.S200}`, -}); - -export const UploadBoardContent = style({ - padding: config.space.S200, - paddingBottom: 0, - paddingRight: 0, -}); diff --git a/src/app/components/upload-board/UploadBoard.tsx b/src/app/components/upload-board/UploadBoard.tsx deleted file mode 100644 index 42f3899f..00000000 --- a/src/app/components/upload-board/UploadBoard.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import React, { MutableRefObject, ReactNode, useImperativeHandle, useRef } from 'react'; -import { Badge, Box, Chip, Header, Icon, Icons, Spinner, Text, as, percent } from 'folds'; -import classNames from 'classnames'; -import { useAtomValue } from 'jotai'; - -import * as css from './UploadBoard.css'; -import { TUploadFamilyObserverAtom, Upload, UploadStatus, UploadSuccess } from '../../state/upload'; - -type UploadBoardProps = { - header: ReactNode; -}; -export const UploadBoard = as<'div', UploadBoardProps>(({ header, children, ...props }, ref) => ( - - - - - {children} - - - {header} - - - - -)); - -export type UploadBoardImperativeHandlers = { handleSend: () => Promise }; - -type UploadBoardHeaderProps = { - open: boolean; - onToggle: () => void; - uploadFamilyObserverAtom: TUploadFamilyObserverAtom; - onCancel: (uploads: Upload[]) => void; - onSend: (uploads: UploadSuccess[]) => Promise; - imperativeHandlerRef: MutableRefObject; -}; - -export function UploadBoardHeader({ - open, - onToggle, - uploadFamilyObserverAtom, - onCancel, - onSend, - imperativeHandlerRef, -}: UploadBoardHeaderProps) { - const sendingRef = useRef(false); - const uploads = useAtomValue(uploadFamilyObserverAtom); - - const isSuccess = uploads.every((upload) => upload.status === UploadStatus.Success); - const isError = uploads.some((upload) => upload.status === UploadStatus.Error); - const progress = uploads.reduce( - (acc, upload) => { - acc.total += upload.file.size; - if (upload.status === UploadStatus.Loading) { - acc.loaded += upload.progress.loaded; - } - if (upload.status === UploadStatus.Success) { - acc.loaded += upload.file.size; - } - return acc; - }, - { loaded: 0, total: 0 } - ); - - const handleSend = async () => { - if (sendingRef.current) return; - sendingRef.current = true; - await onSend( - uploads.filter((upload) => upload.status === UploadStatus.Success) as UploadSuccess[] - ); - sendingRef.current = false; - }; - - useImperativeHandle(imperativeHandlerRef, () => ({ - handleSend, - })); - const handleCancel = () => onCancel(uploads); - - return ( -
- - - Files - - - {isSuccess && ( - } - > - Send - - )} - {isError && !open && ( - - Upload Failed - - )} - {!isSuccess && !isError && !open && ( - <> - - {Math.round(percent(0, progress.total, progress.loaded))}% - - - - )} - {!isSuccess && open && ( - } - > - {uploads.length === 1 ? 'Remove' : 'Remove All'} - - )} - -
- ); -} - -export const UploadBoardContent = as<'div'>(({ className, children, ...props }, ref) => ( - - {children} - -)); diff --git a/src/app/components/upload-board/index.ts b/src/app/components/upload-board/index.ts deleted file mode 100644 index 24ae780c..00000000 --- a/src/app/components/upload-board/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './UploadBoard'; diff --git a/src/app/components/upload-card/UploadCardRenderer.tsx b/src/app/components/upload-card/UploadCardRenderer.tsx deleted file mode 100644 index f5bc68e0..00000000 --- a/src/app/components/upload-card/UploadCardRenderer.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import React, { ReactNode, useEffect } from 'react'; -import { Box, Chip, Icon, IconButton, Icons, Text, color, config, toRem } from 'folds'; -import { UploadCard, UploadCardError, UploadCardProgress } from './UploadCard'; -import { UploadStatus, UploadSuccess, useBindUploadAtom } from '../../state/upload'; -import { useMatrixClient } from '../../hooks/useMatrixClient'; -import { TUploadContent } from '../../utils/matrix'; -import { bytesToSize, getFileTypeIcon } from '../../utils/common'; -import { - roomUploadAtomFamily, - TUploadItem, - TUploadMetadata, -} from '../../state/room/roomInputDrafts'; -import { useObjectURL } from '../../hooks/useObjectURL'; -import { useMediaConfig } from '../../hooks/useMediaConfig'; - -type PreviewImageProps = { - fileItem: TUploadItem; -}; -function PreviewImage({ fileItem }: PreviewImageProps) { - const { originalFile, metadata } = fileItem; - const fileUrl = useObjectURL(originalFile); - - return ( - {originalFile.name} - ); -} - -type PreviewVideoProps = { - fileItem: TUploadItem; -}; -function PreviewVideo({ fileItem }: PreviewVideoProps) { - const { originalFile, metadata } = fileItem; - const fileUrl = useObjectURL(originalFile); - - return ( - // eslint-disable-next-line jsx-a11y/media-has-caption -