Live video on the AT Protocol
1import { TouchableOpacity } from "react-native";
2import { ScrollView, Text, View } from "tamagui";
3
4export interface MentionSuggestion {
5 did: string;
6 handle: string;
7 color?: {
8 red: number;
9 green: number;
10 blue: number;
11 };
12}
13
14interface MentionSuggestionsProps {
15 suggestions: MentionSuggestion[];
16 onSelect: (suggestion: MentionSuggestion) => void;
17 highlightedIndex: number;
18 setHighlightedIndex: (i: number) => void;
19}
20
21export default function MentionSuggestions({
22 suggestions,
23 onSelect,
24 highlightedIndex,
25 setHighlightedIndex,
26}: MentionSuggestionsProps) {
27 if (suggestions.length === 0) return null;
28
29 const getRgbColor = (color?: MentionSuggestion["color"]) =>
30 color ? `rgb(${color.red}, ${color.green}, ${color.blue})` : "$accentColor";
31
32 return (
33 <View
34 position="absolute"
35 left={0}
36 right={0}
37 bottom="100%"
38 marginBottom={44}
39 backgroundColor="$background"
40 borderRadius={4}
41 maxHeight={200}
42 minWidth={200}
43 zIndex={100000}
44 shadowColor="$shadowColor"
45 shadowOffset={{ width: 0, height: 2 }}
46 shadowOpacity={0.25}
47 shadowRadius={4}
48 style={{
49 pointerEvents: "auto",
50 }}
51 >
52 <Text
53 fontSize={12}
54 color="$color"
55 padding="$2"
56 opacity={0.7}
57 style={{ borderBottomWidth: 1, borderBottomColor: "$borderColor" }}
58 >
59 ↑/↓ to navigate, Tab/Enter to select, Esc to close
60 </Text>
61 <ScrollView>
62 {suggestions.map((suggestion, i) => (
63 <View
64 key={suggestion.did}
65 onMouseEnter={() => setHighlightedIndex(i)}
66 >
67 <TouchableOpacity onPress={() => onSelect(suggestion)} style={{}}>
68 <View
69 padding="$2"
70 backgroundColor={
71 i === highlightedIndex ? "$accentBackground" : "transparent"
72 }
73 style={{
74 borderBottomWidth: 1,
75 borderBottomColor: "$borderColor",
76 }}
77 >
78 <Text fontSize={14} color={getRgbColor(suggestion.color)}>
79 @{suggestion.handle}
80 </Text>
81 </View>
82 </TouchableOpacity>
83 </View>
84 ))}
85 </ScrollView>
86 </View>
87 );
88}