104 lines
2.5 KiB
TypeScript
104 lines
2.5 KiB
TypeScript
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 (
|
|
<Modal
|
|
visible={visible}
|
|
transparent
|
|
animationType="fade"
|
|
onRequestClose={onClose}
|
|
>
|
|
<Pressable style={styles.backdrop} onPress={onClose}>
|
|
<Pressable style={styles.sheet} onPress={() => undefined}>
|
|
<ReactionStrip
|
|
onReact={(e) => {
|
|
onReact(e);
|
|
onClose();
|
|
}}
|
|
/>
|
|
<Action label="Antworten" onPress={() => { onReply(); onClose(); }} />
|
|
{mine && (
|
|
<Action
|
|
label="Löschen"
|
|
danger
|
|
onPress={() => { onDelete(); onClose(); }}
|
|
/>
|
|
)}
|
|
<Action label="Abbrechen" muted onPress={onClose} />
|
|
</Pressable>
|
|
</Pressable>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
function Action({
|
|
label,
|
|
danger,
|
|
muted,
|
|
onPress,
|
|
}: {
|
|
label: string;
|
|
danger?: boolean;
|
|
muted?: boolean;
|
|
onPress: () => void;
|
|
}) {
|
|
return (
|
|
<Pressable
|
|
onPress={onPress}
|
|
style={({ pressed }) => [styles.action, pressed && styles.actionPressed]}
|
|
>
|
|
<Text style={[styles.actionText, danger && styles.actionDanger, muted && styles.actionMuted]}>
|
|
{label}
|
|
</Text>
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
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 },
|
|
});
|