Files
dchain/client-app/components/SearchBar.tsx
vsecoder 516940fa8e fix(client): contact-request endpoint path + search screen polish
1. Contact requests silently 404'd
   fetchContactRequests hit /api/relay/contacts, but the server mounts
   the whole /relay/* group at root (no /api prefix). Result: every
   poll returned 404, the catch swallowed it, and the notifications
   tab stayed empty even after the user sent themselves a CONTACT_
   REQUEST on-chain. Fixed the client path to /relay/contacts — same
   pattern as sendEnvelope / fetchInbox in the v1.0.x relay cleanup.

2. Search screen was half-finished
   SearchBar used a dual-state hack (idle-centered Text overlaid with
   an invisible TextInput) that broke focus + alignment on Android and
   sometimes ate taps. Rewrote as a plain single-row pill: icon +
   TextInput + optional clear button. Fewer moving parts, predictable
   focus, proper placeholder styling.

   new-contact.tsx cleaned up:
   - Title "New chat" → "Поиск" (matches the NavBar tab label and the
     rest of the Russian UI).
   - All labels localised: "Accept/Decline", "Intro", "Anti-spam fee",
     fee-tier names, error messages, final CTA.
   - Proper empty-state hint when query is empty (icon + headline +
     explanation of @username / hex / DC prefix) instead of just a
     floating helper text.
   - Search button hidden until user types something — the empty-
     state stands alone, no dead grey button under it.
   - onClear handler on SearchBar resets the resolved profile too.

   requests.tsx localised: title, empty-state, Accept/Decline button
   copy, confirmation Alert text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 23:19:03 +03:00

70 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* SearchBar — single-TextInput pill. Icon + input в одном ряду, без
* idle/focused двойного состояния (раньше был хак с невидимым
* TextInput поверх отцентрированного Text — ломал focus и выравнивание
* на Android).
*/
import React from 'react';
import { View, TextInput, Pressable } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
export interface SearchBarProps {
value: string;
onChangeText: (v: string) => void;
placeholder?: string;
autoFocus?: boolean;
onSubmitEditing?: () => void;
onClear?: () => void;
}
export function SearchBar({
value, onChangeText, placeholder = 'Поиск', autoFocus, onSubmitEditing, onClear,
}: SearchBarProps) {
return (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#111111',
borderWidth: 1,
borderColor: '#1f1f1f',
borderRadius: 999,
paddingHorizontal: 14,
gap: 8,
}}
>
<Ionicons name="search" size={16} color="#6a6a6a" />
<TextInput
value={value}
onChangeText={onChangeText}
placeholder={placeholder}
placeholderTextColor="#5a5a5a"
autoCapitalize="none"
autoCorrect={false}
autoFocus={autoFocus}
onSubmitEditing={onSubmitEditing}
returnKeyType="search"
style={{
flex: 1,
color: '#ffffff',
fontSize: 14,
paddingVertical: 10,
padding: 0,
includeFontPadding: false,
}}
/>
{value.length > 0 && (
<Pressable
onPress={() => {
onChangeText('');
onClear?.();
}}
hitSlop={8}
>
<Ionicons name="close-circle" size={16} color="#6a6a6a" />
</Pressable>
)}
</View>
);
}