Messenger/packages/mobile/src/features/messaging/ui/FileBubble.tsx
Заид Омар Медхат | Zaid Omar Medhat f653b083aa f
2026-07-13 12:32:00 +05:00

51 lines
1.9 KiB
TypeScript

import type { ReactElement } from 'react';
import { Linking, Pressable, StyleSheet, Text, View } from 'react-native';
import type { MediaRef } from '@altricade/core';
import { Icon } from '@/components';
import { useTheme } from '@/theme';
import { spacing, radius, fontSize } from '@/theme';
import { useMediaUrl, formatBytes } from '../media';
interface Props {
conversationId: string;
messageId: string;
media: MediaRef;
outgoing: boolean;
}
// Generic file attachment — tapping opens the presigned url in the OS handler.
export const FileBubble = ({ conversationId, messageId, media, outgoing }: Props): ReactElement => {
const { colors } = useTheme();
const url = useMediaUrl(conversationId, messageId, true);
const nameTone = outgoing ? colors.onAccent : colors.text;
const subTone = outgoing ? colors.onAccentMuted : colors.textFaint;
return (
<Pressable
disabled={url === null}
onPress={() => {
if (url !== null) {
void Linking.openURL(url);
}
}}
style={styles.row}
>
<View style={[styles.icon, { backgroundColor: outgoing ? colors.onAccentMuted : colors.accentSoft }]}>
<Icon name="file" size={20} color={outgoing ? colors.onAccent : colors.accent} />
</View>
<View style={styles.meta}>
<Text style={[styles.name, { color: nameTone }]} numberOfLines={1}>
{media.name}
</Text>
<Text style={[styles.size, { color: subTone }]}>{formatBytes(media.size)}</Text>
</View>
</Pressable>
);
};
const styles = StyleSheet.create({
row: { flexDirection: 'row', alignItems: 'center', gap: spacing.md, minWidth: 180 },
icon: { width: 42, height: 42, borderRadius: radius.md, alignItems: 'center', justifyContent: 'center' },
meta: { flex: 1, gap: 2 },
name: { fontSize: fontSize.base, fontWeight: '600' },
size: { fontSize: fontSize.xs },
});