diff --git a/apps/rebreak-native/app/(app)/chat.tsx b/apps/rebreak-native/app/(app)/chat.tsx
index 6e7c45a..85e4f5c 100644
--- a/apps/rebreak-native/app/(app)/chat.tsx
+++ b/apps/rebreak-native/app/(app)/chat.tsx
@@ -4,6 +4,7 @@ import {
Text,
FlatList,
TouchableOpacity,
+ TextInput,
ActivityIndicator,
Image,
RefreshControl,
@@ -15,8 +16,6 @@ import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { apiFetch } from '../../lib/api';
import { AppHeader } from '../../components/AppHeader';
-import { RoomCard, type Room } from '../../components/chat/RoomCard';
-import { CreateRoomSheet } from '../../components/chat/CreateRoomSheet';
import { useColors } from '../../lib/theme';
type DmConversation = {
@@ -60,7 +59,7 @@ function DmItem({ conv, onPress }: { conv: DmConversation; onPress: () => void }
{conv.partnerName}
-
+
{formatTime(conv.lastMessageAt, t('chat.just_now'))}
@@ -97,19 +96,7 @@ export default function ChatScreen() {
const router = useRouter();
const colors = useColors();
const styles = makeStyles(colors);
- const [tab, setTab] = useState<'groups' | 'direct'>('groups');
- const [createOpen, setCreateOpen] = useState(false);
-
- const {
- data: rooms = [],
- isLoading: loadingRooms,
- isRefetching: refetchingRooms,
- refetch: refetchRooms,
- } = useQuery({
- queryKey: ['chat-rooms'],
- queryFn: () => apiFetch('/api/chat/rooms'),
- staleTime: 30_000,
- });
+ const [search, setSearch] = useState('');
const {
data: convs = [],
@@ -120,17 +107,14 @@ export default function ChatScreen() {
queryKey: ['dm-conversations'],
queryFn: () => apiFetch('/api/chat/dm-conversations'),
staleTime: 30_000,
- enabled: tab === 'direct',
});
- const unreadDms = convs.reduce((s, c) => s + (c.unreadCount ?? 0), 0);
-
- const openRoom = useCallback(
- (roomId: string) => {
- router.push(`/room?roomId=${roomId}`);
- },
- [router],
- );
+ const filtered = search.trim()
+ ? convs.filter((c) =>
+ c.partnerName.toLowerCase().includes(search.toLowerCase()) ||
+ c.lastMessage.toLowerCase().includes(search.toLowerCase()),
+ )
+ : convs;
const openDm = useCallback(
(userId: string) => {
@@ -143,120 +127,53 @@ export default function ChatScreen() {
- {/* Header */}
+ {/* Search header */}
-
- {t('chat.title')}
- {tab === 'groups' && (
- setCreateOpen(true)}
- activeOpacity={0.7}
- style={styles.createBtn}
- >
-
+
+
+
+ {search.length > 0 && (
+ setSearch('')} activeOpacity={0.7} hitSlop={8}>
+
)}
-
- {/* Tabs */}
-
- setTab('groups')}
- activeOpacity={0.7}
- style={[styles.tab, tab === 'groups' && styles.tabActive]}
- >
-
-
- {t('chat.groups')}
-
-
- setTab('direct')}
- activeOpacity={0.7}
- style={[styles.tab, tab === 'direct' && styles.tabActive]}
- >
-
-
- {t('chat.direct')}
-
- {unreadDms > 0 && (
-
- {unreadDms}
-
- )}
-
-
- {tab === 'groups' ? (
- item.id}
- refreshControl={
-
- }
- ListEmptyComponent={
- loadingRooms ? (
-
-
-
- ) : (
-
-
- {t('chat.no_rooms')}
-
- )
- }
- renderItem={({ item }) => openRoom(item.id)} />}
- contentContainerStyle={{ paddingBottom: 100 }}
- />
- ) : (
- item.partnerId}
- refreshControl={
-
- }
- ListEmptyComponent={
- loadingDms ? (
-
-
-
- ) : (
-
-
- {t('chat.no_chats')}
-
- )
- }
- renderItem={({ item }) => openDm(item.partnerId)} />}
- contentContainerStyle={{ paddingBottom: 100 }}
- />
- )}
-
- setCreateOpen(false)}
- onCreated={(room) => {
- refetchRooms();
- openRoom(room.id);
- }}
+ item.partnerId}
+ refreshControl={
+
+ }
+ ListEmptyComponent={
+ loadingDms ? (
+
+
+
+ ) : (
+
+
+ {t('chat.no_chats')}
+
+ )
+ }
+ renderItem={({ item }) => openDm(item.partnerId)} />}
+ contentContainerStyle={{ paddingBottom: 100 }}
/>
);
@@ -267,76 +184,27 @@ function makeStyles(colors: ReturnType) {
container: { flex: 1, backgroundColor: colors.bg },
headerSection: {
paddingHorizontal: 16,
- paddingTop: 14,
+ paddingTop: 12,
paddingBottom: 10,
backgroundColor: colors.bg,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: colors.border,
},
- titleRow: {
+ searchRow: {
flexDirection: 'row',
alignItems: 'center',
- justifyContent: 'space-between',
- },
- title: {
- fontSize: 22,
- fontFamily: 'Nunito_800ExtraBold',
- color: colors.text,
- },
- createBtn: {
- width: 34,
- height: 34,
- borderRadius: 17,
- backgroundColor: '#007AFF',
- alignItems: 'center',
- justifyContent: 'center',
- },
- tabs: {
- flexDirection: 'row',
- marginTop: 12,
backgroundColor: colors.surfaceElevated,
borderRadius: 10,
- padding: 3,
+ paddingHorizontal: 10,
+ paddingVertical: 8,
},
- tab: {
+ searchIcon: { marginRight: 7 },
+ searchInput: {
flex: 1,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- paddingVertical: 7,
- borderRadius: 8,
- },
- tabActive: {
- backgroundColor: colors.surface,
- shadowColor: '#000',
- shadowOpacity: 0.05,
- shadowRadius: 2,
- shadowOffset: { width: 0, height: 1 },
- },
- tabText: {
- fontSize: 12,
- fontFamily: 'Nunito_600SemiBold',
- color: colors.textMuted,
- marginLeft: 5,
- },
- tabTextActive: {
- color: '#007AFF',
- fontFamily: 'Nunito_700Bold',
- },
- tabBadge: {
- minWidth: 16,
- height: 16,
- borderRadius: 8,
- backgroundColor: '#007AFF',
- paddingHorizontal: 4,
- alignItems: 'center',
- justifyContent: 'center',
- marginLeft: 5,
- },
- tabBadgeText: {
- fontSize: 9,
- fontFamily: 'Nunito_700Bold',
- color: '#fff',
+ fontSize: 14,
+ fontFamily: 'Nunito_500Medium',
+ color: colors.text,
+ paddingVertical: 0,
},
emptyBox: {
alignItems: 'center',
@@ -403,7 +271,7 @@ function makeStyles(colors: ReturnType) {
height: 20,
paddingHorizontal: 6,
borderRadius: 10,
- backgroundColor: '#007AFF',
+ backgroundColor: colors.brandOrange,
alignItems: 'center',
justifyContent: 'center',
marginLeft: 8,
@@ -413,5 +281,53 @@ function makeStyles(colors: ReturnType) {
fontFamily: 'Nunito_700Bold',
color: '#fff',
},
+ // Kept for v1.1 Groups comeback — tab styles no longer rendered
+ tabs: {
+ flexDirection: 'row',
+ marginTop: 12,
+ backgroundColor: colors.surfaceElevated,
+ borderRadius: 10,
+ padding: 3,
+ },
+ tab: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingVertical: 7,
+ borderRadius: 8,
+ },
+ tabActive: {
+ backgroundColor: colors.surface,
+ shadowColor: '#000',
+ shadowOpacity: 0.05,
+ shadowRadius: 2,
+ shadowOffset: { width: 0, height: 1 },
+ },
+ tabText: {
+ fontSize: 12,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.textMuted,
+ marginLeft: 5,
+ },
+ tabTextActive: {
+ color: colors.brandOrange,
+ fontFamily: 'Nunito_700Bold',
+ },
+ tabBadge: {
+ minWidth: 16,
+ height: 16,
+ borderRadius: 8,
+ backgroundColor: colors.brandOrange,
+ paddingHorizontal: 4,
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginLeft: 5,
+ },
+ tabBadgeText: {
+ fontSize: 9,
+ fontFamily: 'Nunito_700Bold',
+ color: '#fff',
+ },
});
}
diff --git a/apps/rebreak-native/locales/de.json b/apps/rebreak-native/locales/de.json
index 1222a0a..48bfe69 100644
--- a/apps/rebreak-native/locales/de.json
+++ b/apps/rebreak-native/locales/de.json
@@ -741,7 +741,8 @@
"approve": "Annehmen",
"reject": "Ablehnen",
"avatar_updated": "Gruppenbild aktualisiert",
- "send": "Senden"
+ "send": "Senden",
+ "search_placeholder": "Konversationen durchsuchen…"
},
"community": {
"compose_placeholder": "Was bewegt dich gerade?",
diff --git a/apps/rebreak-native/locales/en.json b/apps/rebreak-native/locales/en.json
index 361b1f8..9e5e395 100644
--- a/apps/rebreak-native/locales/en.json
+++ b/apps/rebreak-native/locales/en.json
@@ -741,7 +741,8 @@
"approve": "Approve",
"reject": "Reject",
"avatar_updated": "Group photo updated",
- "send": "Send"
+ "send": "Send",
+ "search_placeholder": "Search conversations…"
},
"community": {
"compose_placeholder": "What's on your mind?",
diff --git a/apps/rebreak-native/locales/fr.json b/apps/rebreak-native/locales/fr.json
index c92f74c..413ab14 100644
--- a/apps/rebreak-native/locales/fr.json
+++ b/apps/rebreak-native/locales/fr.json
@@ -741,7 +741,8 @@
"approve": "Accepter",
"reject": "Refuser",
"avatar_updated": "Photo du groupe mise à jour",
- "send": "Envoyer"
+ "send": "Envoyer",
+ "search_placeholder": "Rechercher des conversations…"
},
"community": {
"compose_placeholder": "Qu'est-ce qui vous préoccupe en ce moment ?",