# Expo Chat: Day Separator Bars Design

**Date:** 2026-04-19
**Scope:** Add day indicators to the Expo chat screen as centered date labels with horizontal bars on each side, inserted between message groups when the calendar day changes.

## Context

The Expo chat screen at `xtablo-expo/app/(app)/channel/[cid].tsx` currently renders:
- grouped message bubbles
- connection banner
- typing indicator
- message input

It does **not** currently render any per-day separators in the message timeline. The result is that conversations spanning multiple days have no visible day boundary.

## Goal

Add day separators to the chat timeline with this visual treatment:
- centered date label
- thin horizontal line extending left and right
- one separator per day boundary

The separator should appear between message groups whenever the date changes.

## Non-Goals

- changing the backend or chat hooks
- changing message grouping behavior
- adding unread separators or timeline markers beyond day boundaries
- redesigning message bubbles or input UI

## Architecture

The current screen already derives `messageGroups` from raw messages. The separator feature should be implemented as a second derived layer on top of that.

### Derived Timeline Items

Instead of giving `FlatList` only message-group items, the screen will derive a timeline list with two item kinds:
- `message-group`
- `day-separator`

This keeps day-boundary logic isolated from the existing message group renderer.

### Display Model

Suggested item shape:

```ts
type TimelineItem =
  | { type: "day-separator"; key: string; label: string }
  | { type: "message-group"; key: string; group: MessageGroup };
```

`key` should remain stable and deterministic so the inverted `FlatList` behaves predictably.

## Components

Only `xtablo-expo/app/(app)/channel/[cid].tsx` needs behavior changes.

Additions:
- a day-label formatter
- a helper to insert separator items between message groups
- a `renderTimelineItem` function that dispatches between separator and message-group rendering
- styles for the separator row, centered label, and horizontal line segments

The rest of the screen remains unchanged:
- typing bar
- header
- pagination
- message input

## Data Flow

The screen should process data in this order:

1. read raw chat messages from `useChat(channelId)`
2. group them into `messageGroups` using the existing sender/time logic
3. walk those groups in chronological order
4. insert a `day-separator` item before the first group of each calendar day
5. reverse the final timeline item list as needed for the inverted `FlatList`
6. render based on item type

### Day Boundary Rule

A separator is inserted when:
- the current group is the first group in the list, or
- its calendar date differs from the previous group’s calendar date

Comparison should be based on the message group's first message timestamp.

### Label Formatting

Label behavior:
- `Aujourd’hui` for the current day
- `Hier` for the previous day
- otherwise a localized French date, such as `18 avril 2026`

## Visual Treatment

The separator should be visually neutral and lighter than primary CTAs:
- subtle line color based on the current theme
- subdued label text color
- centered horizontal layout with equal visual weight on both sides

The goal is a timeline marker, not a call-to-action.

## Error Handling And Verification

This is a UI-only derived-data change, so verification should focus on stability:

- `npx tsc --noEmit` in `xtablo-expo` still passes
- existing Expo lint behavior remains unchanged except for any new warnings introduced by this file
- existing Jest suite still passes
- manual behavior check confirms:
  - one separator per day
  - separators appear in the correct place with inverted list rendering
  - pagination still works
  - typing indicator and input remain unaffected

## Success Criteria

The feature is complete when:
- multi-day conversations show horizontal day separator bars
- the separator labels are correct in French
- no duplicate separators appear within the same day
- the chat screen’s current interaction behavior remains unchanged
