From 3b62fbc24315fb49d68ab8731ca073693a9b69f5 Mon Sep 17 00:00:00 2001 From: byGalax Date: Thu, 14 May 2026 00:20:08 +0200 Subject: [PATCH] =?UTF-8?q?feat(mobile):=20MessageActionsSheet=20bottom=20?= =?UTF-8?q?modal=20=E2=80=94=20react/reply/delete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile/components/MessageActionsSheet.tsx | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 apps/mobile/components/MessageActionsSheet.tsx diff --git a/apps/mobile/components/MessageActionsSheet.tsx b/apps/mobile/components/MessageActionsSheet.tsx new file mode 100644 index 0000000..0de024f --- /dev/null +++ b/apps/mobile/components/MessageActionsSheet.tsx @@ -0,0 +1,103 @@ +import { Modal, Pressable, StyleSheet, Text } from 'react-native'; + +import { ReactionStrip } from './ReactionStrip'; +import { colors } from '../theme/colors'; + +interface Props { + visible: boolean; + mine: boolean; + onClose: () => void; + onReact: (emoji: string) => void; + onReply: () => void; + onDelete: () => void; +} + +// Bottom-sheet-style modal opened on long-press of a message bubble. +// Contains the reaction quick-strip plus the action rows. The "Löschen" +// row is hidden for messages not authored by the current user — the +// server-side trigger would refuse anyway, but trimming UI keeps the +// surface honest. +export function MessageActionsSheet({ + visible, + mine, + onClose, + onReact, + onReply, + onDelete, +}: Props) { + return ( + + + undefined}> + { + onReact(e); + onClose(); + }} + /> + { onReply(); onClose(); }} /> + {mine && ( + { onDelete(); onClose(); }} + /> + )} + + + + + ); +} + +function Action({ + label, + danger, + muted, + onPress, +}: { + label: string; + danger?: boolean; + muted?: boolean; + onPress: () => void; +}) { + return ( + [styles.action, pressed && styles.actionPressed]} + > + + {label} + + + ); +} + +const styles = StyleSheet.create({ + backdrop: { + flex: 1, + justifyContent: 'flex-end', + backgroundColor: 'rgba(0,0,0,0.5)', + }, + sheet: { + backgroundColor: colors.surface, + borderTopLeftRadius: 16, + borderTopRightRadius: 16, + paddingBottom: 24, + }, + action: { + paddingVertical: 14, + paddingHorizontal: 20, + borderBottomColor: colors.border, + borderBottomWidth: 1, + }, + actionPressed: { backgroundColor: colors.bg }, + actionText: { color: colors.text, fontSize: 15, fontWeight: '500' }, + actionDanger: { color: colors.danger }, + actionMuted: { color: colors.textMuted }, +});