diff --git a/src/app/features/room/message/DraggableMessage.tsx b/src/app/features/room/message/DraggableMessage.tsx index 4476d5c7..f172afe7 100644 --- a/src/app/features/room/message/DraggableMessage.tsx +++ b/src/app/features/room/message/DraggableMessage.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { useSpring, animated } from '@react-spring/web'; import { useDrag } from 'react-use-gesture'; import { Icon, Icons } from 'folds'; +import { MatrixClient, MatrixEvent } from 'matrix-js-sdk'; const DraggableMessageStyles = { container: { @@ -9,7 +10,7 @@ const DraggableMessageStyles = { overflow: 'hidden', width: '100%', }, - replyIconContainer: { + iconContainer: { position: 'absolute', top: 0, bottom: 0, @@ -17,7 +18,7 @@ const DraggableMessageStyles = { display: 'flex', alignItems: 'center', justifyContent: 'center', - width: '80px', + width: '150px', }, messageContent: { position: 'relative', @@ -25,46 +26,76 @@ const DraggableMessageStyles = { backgroundColor: 'var(--folds-color-Background-Main)', width: '100%', }, + icon: { + position: 'absolute', + }, }; -export function DraggableMessage({ children, onReply }) { +export function DraggableMessage({ + children, + onReply, + onEdit, + event, + mx, +}: { + children: React.ReactNode; + onReply: () => void; + onEdit: () => void; + event: MatrixEvent; + mx: MatrixClient; +}) { + const canEdit = mx.getUserId() === event.getSender(); const REPLY_THRESHOLD = 80; + const EDIT_THRESHOLD = canEdit ? 250 : Infinity; - const [{ x, iconScale }, api] = useSpring(() => ({ + const [{ x, replyOpacity, editOpacity, iconScale }, api] = useSpring(() => ({ x: 0, + replyOpacity: 0, + editOpacity: 0, iconScale: 0.5, config: { tension: 250, friction: 25 }, })); const bind = useDrag( - ({ down, movement: [mx], direction: [xDir], vxvy: [vx], cancel }) => { - if (!down && Math.abs(xDir) < 0.7) { - cancel(); - } - - const xTarget = down ? Math.min(0, mx) : 0; - let scaleTarget = down - ? 0.5 + Math.min(Math.abs(mx), REPLY_THRESHOLD) / (REPLY_THRESHOLD * 2) - : 0.5; - - if (mx < -REPLY_THRESHOLD) { - onReply(); - } - - /* + ({ down, movement: [x], vxvy: [vx] }) => { if (!down) { - if (mx < -REPLY_THRESHOLD && vx < -0.5) { + const finalDistance = Math.abs(x); + + if (finalDistance > EDIT_THRESHOLD) { + onEdit(); + } else if (finalDistance > REPLY_THRESHOLD) { onReply(); } - } else { - if (mx < -REPLY_THRESHOLD) { - scaleTarget = 1; - } } -*/ + + const xTarget = down ? Math.min(0, x) : 0; + const distance = Math.abs(xTarget); + + let newReplyOpacity = 0; + let newEditOpacity = 0; + let newScale = 1.0; + + if (canEdit && distance > REPLY_THRESHOLD) { + newReplyOpacity = 0; + newEditOpacity = 1; + if (down && distance > EDIT_THRESHOLD) { + newScale = 1.1; + } + } else { + newReplyOpacity = 1; + newEditOpacity = 0; + newScale = 0.5 + (distance / REPLY_THRESHOLD) * 0.5; + } + + if (distance < 5) { + newReplyOpacity = 0; + } + api.start({ x: xTarget, - iconScale: scaleTarget, + replyOpacity: newReplyOpacity, + editOpacity: newEditOpacity, + iconScale: newScale, }); }, { @@ -76,23 +107,29 @@ export function DraggableMessage({ children, onReply }) { return (
- `scale(${s})`), - opacity: iconScale.to((s) => (s - 0.5) * 2), - }} - > - - +
+ `scale(${s})`), + }} + > + + - + `scale(${s})`), + }} + > + + +
+ + {children}