- MessageInput: paperclip button (team-only, controlled by teamUserIds
from ThreadDetail) uploads through the media service and hands the URL
to the WebSocket; Enter now inserts a newline — sending is button-only
since accidental Enter-sends were noisy for staff replies.
- MessageBubble: renders image messages inline (tap to open), shows the
coworker's username at the top of team-side bubbles so staff can tell
who typed what.
- MessageList / ThreadChatPage: any message from a store team member
(owner or active staff) renders on the "our" side of the bubble even
for a viewer who isn't the sender, using team_user_ids from
ThreadDetail. Delete option stays gated to the actual sender.
- ThreadsPage: inbox now shows smart-relative timestamps
(today HH:MM / دیروز HH:MM / N روز پیش / Persian date), plus a
reply-state icon per row (red bell = customer waiting, blue double-check
= you replied and they've seen it, nothing = you replied not yet seen).
Image-only last messages preview as "📷 تصویر".
- Push notifications: on mount we re-POST the current PushSubscription so
a browser-rotated sub or a backend row deleted after a 410 auto-heals.
- useWebSocket: SendMessagePayload and NewMessageEvent carry image_url so
the server relay can round-trip images.
- API types: MessageList.imageUrl, LastMessage.imageUrl,
ThreadList.lastMessageFromTeam/otherPartySeenLast, ThreadDetail.teamUserIds.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>