Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/BhushanBadhe39/SkinFirts/llms.txt

Use this file to discover all available pages before exploring further.

The Chat tab in SkinFirts’s bottom navigation gives patients a dedicated messaging space to communicate directly with their dermatologist. The screen renders a full conversation thread, a text input bar, and quick-action buttons for placing voice or video calls — all within a single ChatScreen component.

Chat UI Layout

The conversation thread is built on a FlatList with the inverted prop set to true, so the most recent messages always appear at the bottom of the screen without any manual scroll management. Each list item is rendered as a ChatBubble component. Sender messages are right-aligned with a distinct background colour; receiver messages are left-aligned with a lighter shade.
// FlatList inside ChatScreen.jsx
<FlatList
  inverted={true}
  data={chatHistory}
  keyExtractor={(item, index) => item + index}
  renderItem={({ item, index }) => (
    <ChatBubble
      isSender={item.sender}
      text={item.msg}
      time={item.time}
      key={index}
    />
  )}
/>
The inverted prop on FlatList is the standard React Native pattern for chat UIs. It reverses the render order so new items visually appear at the bottom and automatic scroll-to-bottom behaviour is handled by the list itself — no scrollToEnd calls needed.

chatHistory State Shape

The chatHistory state is an array of 16 message objects managed by useState. Each object describes who sent the message, when it was sent, and the message body. The initial seed represents a back-and-forth conversation about building the app itself.
// Initial state in ChatScreen.jsx (all 16 messages)
const [chatHistory, setChatHistory] = useState([
  { sender: true,  time: '10:45', msg: 'See you later! 👋' },
  { sender: false, time: '10:44', msg: 'Sure, good luck with your app!' },
  { sender: true,  time: '10:43', msg: 'Thanks for the help.' },
  { sender: false, time: '10:42', msg: 'No problem. Happy coding!' },
  { sender: true,  time: '10:41', msg: 'The chat screen is almost done now.' },
  { sender: false, time: '10:40', msg: 'Great! Did you fix the FlatList issue?' },
  { sender: true,  time: '10:39', msg: 'Yeah, using inverted made it much easier.' },
  { sender: false, time: '10:38', msg: 'Nice! That is the recommended approach.' },
  { sender: true,  time: '10:37', msg: 'I also added chat bubbles.' },
  { sender: false, time: '10:36', msg: 'Looking good so far?' },
  { sender: true,  time: '10:35', msg: 'Yep, much cleaner now.' },
  { sender: false, time: '10:34', msg: 'What are you working on today?' },
  { sender: true,  time: '10:33', msg: 'A React Native doctor appointment app.' },
  { sender: false, time: '10:32', msg: 'Sounds interesting!' },
  { sender: true,  time: '10:31', msg: 'Hi!' },
  { sender: false, time: '10:30', msg: 'Hello 👋' },
]);
FieldTypeDescription
senderbooleantrue = current user (right side); false = doctor (left side)
timestringTimestamp displayed below the bubble (e.g. '10:45')
msgstringThe text content of the message

Send and Receive Flow

Two handler functions manage posting messages to the conversation thread. Both prepend a new message object to the front of the chatHistory array (which, combined with the inverted FlatList, makes it appear at the bottom of the screen).
// ChatScreen.jsx — message handlers
const handleSenderPost = () => {
  if (msg.trim()) {
    setChatHistory(prev => [
      {
        sender: true,
        time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
        msg: msg.trim(),
      },
      ...prev,
    ]);
    setMsg('');
  }
};

const handleReceiverPost = () => {
  if (msg.trim()) {
    setChatHistory(prev => [
      {
        sender: false,
        time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
        msg: msg.trim(),
      },
      ...prev,
    ]);
    setMsg('');
  }
};
  • handleSenderPost — called by the send button (send-outline icon). Posts the current input as a message from the patient (right-aligned bubble).
  • handleReceiverPost — called by the attach button (attach-outline icon). Posts the current input as a simulated incoming message from the doctor (left-aligned bubble).
Both handlers guard against empty input with msg.trim() and clear the text field after posting.

ChatBubble Component

The ChatBubble component is the single visual building block for every message in the thread. It accepts three props and renders the bubble with conditional alignment and background colour.
// ChatBubble.jsx — component signature
const ChatBubble = ({ isSender, text, time }) => { ... }

// Usage inside ChatScreen.jsx renderItem
<ChatBubble isSender={item.sender} text={item.msg} time={item.time} />
PropTypeDescription
isSenderbooleanAligns the bubble right (flex-end) when true, left (flex-start) when false
textstringMessage body displayed inside the bubble
timestringTimestamp rendered below the bubble in a smaller font
Styling details from ChatBubble.jsx:
  • Sender bubblecolors.shade background, borderBottomRightRadius: 0 for a speech-bubble tail effect.
  • Receiver bubblecolors.shadeLight background, borderBottomLeftRadius: 0 for the opposing tail.

Input Area

The bottom bar contains three elements laid out in a horizontal row:
ElementIconAction
Attach buttonattach-outlineCalls handleReceiverPost (simulates an incoming message)
Text inputBound to msg state via value / onChangeText; placeholder 'Write Here...'
Send buttonsend-outlineCalls handleSenderPost (posts the patient’s message)
A mic-outline icon sits inside the text input area on the trailing edge as a decorative element.

Screen Header

The header bar is rendered inside a primary-coloured View and contains two groups of controls: Left side:
  • Back button (chevron-back-outline) — navigates to 'Home'
  • Doctor name label — displays Dr. Bhushan Badhe
Right side:
  • RoundButtons with call-outline icon — for initiating a voice call
  • RoundButtons with videocam-outline icon — for initiating a video call
// Header controls in ChatScreen.jsx
<View style={styles.leftButtons}>
  <Pressable onPress={() => navigation.navigate('Home')} style={styles.backButton}>
    <Ionicons name='chevron-back-outline' size={scale(28)} color={colors.secondary} />
  </Pressable>
  <Text style={styles.title} numberOfLines={1}>Dr. Bhushan Badhe</Text>
</View>

<View style={styles.rightButtons}>
  <RoundButtons iconName='call-outline' size={scale(25)} />
  <RoundButtons iconName='videocam-outline' size={scale(25)} />
</View>
The chat is entirely client-side. There is no backend or WebSocket integration — all messages are stored in component state via useState and are lost when the screen unmounts or the app restarts. Persisting messages would require connecting to a real-time messaging service and storing history server-side or in AsyncStorage.

Build docs developers (and LLMs) love