Add edit handling too (not perfect, but useful later)

This commit is contained in:
Gigiaj 2025-06-15 23:05:06 -05:00
parent c8f490adfb
commit e820543951

View file

@ -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();
}
}
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 {
if (mx < -REPLY_THRESHOLD) {
scaleTarget = 1;
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 (
<div style={DraggableMessageStyles.container}>
<div style={DraggableMessageStyles.iconContainer}>
<animated.div
style={{
...DraggableMessageStyles.replyIconContainer,
...DraggableMessageStyles.icon,
opacity: replyOpacity,
transform: iconScale.to((s) => `scale(${s})`),
opacity: iconScale.to((s) => (s - 0.5) * 2),
}}
>
<Icon src={Icons.ReplyArrow} size="200" />
</animated.div>
<animated.div
{...bind()}
style={{
...DraggableMessageStyles.messageContent,
x,
...DraggableMessageStyles.icon,
opacity: editOpacity,
transform: iconScale.to((s) => `scale(${s})`),
}}
>
<Icon src={Icons.Pencil} size="200" />
</animated.div>
</div>
<animated.div {...bind()} style={{ ...DraggableMessageStyles.messageContent, x }}>
{children}
</animated.div>
</div>