Files
simplex-chat/apps/ios/product/views/chat.md
T
Evgeny @ SimpleX Chat aceb646f95 core, ui: typed empty lines are shown, and the flat chat layout reads as paragraphs (#8023)
* ui: markdown messages show the empty lines that were typed

* ui: snapshot references of messages with empty lines

* ui: terminal layout spacing by one paragraph unit, names at text size

* ui: terminal gap below reactions, same empty lines in both apps

* ui: flat layout references with the paragraph unit

* core, ui: text with empty lines as paragraphs, ios bubbles fit text

* core, ui: move text with empty lines as paragraphs to a follow-up

* ui: ios references with bubbles that fit their text

* ui: other senders' names in the flat layout in the secondary colour

* core, ui: text with empty lines as paragraphs

* core, ui: single-star text italic, reports drawn without core prefix
2026-11-04 13:27:22 +00:00

11 KiB
Raw Blame History

Chat View (Conversation)

Related spec: spec/client/chat-view.md | spec/client/compose.md

Purpose

Full conversation view for displaying and interacting with messages in a direct contact chat, group chat, or note-to-self. Supports text messaging with markdown, media attachments, voice messages, E2E encrypted calls, message reactions, replies, forwarding, and content search/filtering.

Route / Navigation

  • Entry point: Tap a chat row in ChatListView
  • Presented by: NavStackCompat destination from ChatListView, bound to chatModel.chatId
  • Back navigation: Dismiss sets chatModel.chatId = nil, returning to chat list
  • Sub-navigation: Info button navigates to ChatInfoView (contact) or GroupChatInfoView (group); member avatars navigate to GroupMemberInfoView

Page Sections

Navigation Bar

Custom toolbar overlaying the chat with themed material background:

Element Description
Back button Returns to chat list
Contact/Group avatar Small profile image
Chat name Display name; tappable to open info sheet
Encryption badge Shows PQ (post-quantum) or standard E2E status
Call buttons Audio and video call icons (direct chats only)
Search button Toggles in-chat message search
Info button Opens ChatInfoView or GroupChatInfoView

Message List

Rendered by EndlessScrollView<MergedItem> with lazy loading and pagination:

Feature Description
Scroll direction Bottom-to-top (newest messages at bottom)
Pagination Loads more items on scroll to top (loadingTopItems) and bottom (loadingBottomItems)
Merged items Adjacent messages from the same sender are visually merged via MergedItems
Floating buttons Scroll-to-bottom button with unread count; scroll-to-first-unread button
Date separators Sticky date headers between messages from different days
Wallpaper Themed background image with tint and opacity from theme.wallpaper
Content filter Filter messages by type: .images, .files, .links

Message Types

Each type has a dedicated view in Shared/Views/Chat/ChatItem/:

Type View Description
Text MsgContentView Rendered with markdown (bold, italic, code, links, mentions)
Image CIImageView Thumbnail with tap-to-fullscreen via FullScreenMediaView
Video CIVideoView Video thumbnail with play button; inline playback
Voice CIVoiceView / FramedCIVoiceView Waveform visualization with playback controls and duration
File CIFileView File icon, name, size; download/open actions
Link preview CILinkView URL preview card with title, description, image
Emoji-only EmojiItemView Large emoji rendering without message bubble
Call event CICallItemView Call status (missed, ended, duration)
Group event CIEventView Member joined/left, role changes, group updates
E2EE info CIChatFeatureView Encryption status and feature change notifications
Group invitation CIGroupInvitationView Inline group join invitation card
Deleted DeletedItemView / MarkedDeletedItemView Placeholder for deleted messages
Decryption error CIRcvDecryptionError Error with ratchet sync suggestion
Invalid JSON CIInvalidJSONView Developer fallback for malformed items
Integrity error IntegrityErrorItemView Message integrity/gap warnings

Message Interactions

Long-press context menu on any message:

Action Description
Reply Sets compose bar to reply mode with quoted message
Forward Opens forwardedChatItems sheet to pick destination chat
Copy Copies message text to clipboard
Edit Enters edit mode in compose bar (own messages, within edit window)
Delete Delete for self or delete for everyone (with confirmation)
React Opens emoji reaction picker
Select multiple Enters multi-select mode (selectedChatItems) with bulk delete/forward
Info Shows delivery status and timestamps

Emoji reactions bar displayed below messages with reaction counts.

Compose Bar (ComposeView)

Element Description
Text input NativeTextEditor with markdown support and auto-growing height
Attachment button Opens picker for images, videos, files, camera
Send button Sends composed message; changes to voice record button when empty
Voice record Hold-to-record with waveform preview; swipe-to-cancel
Reply quote Shows quoted message above input when replying
Edit indicator Shows "editing" label when editing a previous message
Link preview Auto-generated preview card for detected URLs (ComposeLinkView)
Image/Video preview Thumbnail strip for selected media (ComposeImageView)
File preview File name and size for attached file (ComposeFileView)
Voice preview Waveform of recorded voice message (ComposeVoiceView)
Live message Real-time typing broadcast (optional, with alert on first use)
Context actions ContextContactRequestActionsView for accepting/rejecting contact requests; ContextPendingMemberActionsView for pending group member actions
Commands menu CommandsMenuView for bot/menu commands in chats with menuCommands
Group mentions GroupMentionsView autocomplete popup when typing @ in groups
Profile picker ContextProfilePickerView for choosing incognito/main profile

Channel Messages

In channel conversations (groupInfo.useRelays == true), received messages (.channelRcv direction) display with:

  • The channel icon (antenna.radiowaves.left.and.right) instead of the standard group icon
  • The channel name as sender, with "channel" as the role label
  • The group profile image as the avatar (tapping opens group info, not member info)
  • Consecutive channel messages are grouped without repeating the avatar
  • Channel messages cannot be moderated per-member (no member identity)

Member Support Chat (Groups)

For groups with member support enabled:

  • MemberSupportView and MemberSupportChatToolbar shown as secondary chat within group
  • SecondaryChatView for scoped group chat views (reports, member support)
  • User knocking state: userMemberKnockingTitleBar() shown when user is pending admission

Terminal Layout

A chat with the terminal layout shows messages as full-width rows without bubbles, starting at one edge for sent and received messages, with the sender's name above each group of messages, again after a pause of 7.5 minutes, and the time at the end of the last line. Groups and channels show the sender's avatar beside its name; other chats have no avatar column. The wallpaper is drawn as its colour without the image.

A chat uses the user's choice for that chat, otherwise the layout set by the group owner or by the address the contact came from, otherwise the user's choice for the profile and then the app setting, otherwise classic. The choice for a chat is made in its theme screen; the choices for the app and the profile are made in Settings › Appearance.

Loading / Error States

State Behavior
Initial load Messages load from ItemsModel with merged items; allowLoadMoreItems throttles pagination
Loading more (top) loadingTopItems spinner at top of scroll view
Loading more (bottom) loadingBottomItems spinner at bottom
Connection in progress ConnectProgressManager shows connecting text below compose bar
Connecting text "connecting..." label shown below message list when chat not yet ready
Send disabled Compose bar shows disabledText reason when userCantSendReason is set
Empty chat No messages placeholder (implicit -- empty scroll view)
  • spec/client/chat-view.md -- Chat view feature specification
  • spec/client/compose.md -- Compose bar specification
  • Chat List -- Parent navigation
  • Contact Info -- Info sheet for direct chats
  • Group Info -- Info sheet for group chats
  • Call -- Audio/video calls initiated from toolbar

Source Files

  • Shared/Views/Chat/ChatView.swift -- Main chat view, message list, navigation, state management
  • Shared/Views/Chat/ChatItemView.swift -- Individual message item rendering dispatcher
  • Shared/Views/Chat/ComposeMessage/ComposeView.swift -- Compose bar container
  • Shared/Views/Chat/ComposeMessage/SendMessageView.swift -- Send button and voice record
  • Shared/Views/Chat/ComposeMessage/NativeTextEditor.swift -- Text input with markdown
  • Shared/Views/Chat/ComposeMessage/ComposeImageView.swift -- Image attachment preview
  • Shared/Views/Chat/ComposeMessage/ComposeFileView.swift -- File attachment preview
  • Shared/Views/Chat/ComposeMessage/ComposeVoiceView.swift -- Voice recording preview
  • Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift -- Link preview generation
  • Shared/Views/Chat/ComposeMessage/ContextItemView.swift -- Reply/edit context display
  • Shared/Views/Chat/ComposeMessage/ContextContactRequestActionsView.swift -- Contact request accept/reject
  • Shared/Views/Chat/ComposeMessage/ContextPendingMemberActionsView.swift -- Pending member actions
  • Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift -- Profile picker for incognito
  • Shared/Views/Chat/ChatItem/FramedItemView.swift -- Framed message bubble rendering
  • Shared/Views/Chat/ChatItem/MsgContentView.swift -- Text message content with markdown
  • Shared/Views/Chat/ChatItem/TerminalItemView.swift -- Terminal layout rows, sender rows and the time at the row end
  • Shared/Views/Chat/ChatItem/CIImageView.swift -- Image message view
  • Shared/Views/Chat/ChatItem/CIVideoView.swift -- Video message view
  • Shared/Views/Chat/ChatItem/CIVoiceView.swift -- Voice message view
  • Shared/Views/Chat/ChatItem/CIFileView.swift -- File message view
  • Shared/Views/Chat/ChatItem/CILinkView.swift -- Link preview view
  • Shared/Views/Chat/ChatItem/EmojiItemView.swift -- Large emoji view
  • Shared/Views/Chat/ChatItem/CICallItemView.swift -- Call event view
  • Shared/Views/Chat/ChatItem/CIEventView.swift -- Group/system event view
  • Shared/Views/Chat/ChatItem/CIChatFeatureView.swift -- Feature change notification
  • Shared/Views/Chat/ChatItem/CIMetaView.swift -- Timestamp and delivery status
  • Shared/Views/Chat/ChatItem/FullScreenMediaView.swift -- Fullscreen image/video viewer
  • Shared/Views/Chat/ChatItem/AnimatedImageView.swift -- Animated GIF rendering
  • Shared/Views/Chat/Group/GroupMentions.swift -- @mention autocomplete
  • Shared/Views/Chat/Group/MemberSupportView.swift -- Member support scoped chat
  • Shared/Views/Chat/Group/MemberSupportChatToolbar.swift -- Support chat toolbar
  • Shared/Views/Chat/Group/SecondaryChatView.swift -- Secondary scoped chat view