DirectThreadFragment:direct_thread, a conversation.
Three entries, a sum on the input; all open a conversation that exists:
an existing thread, opened from a list row (kind: 'thread'): the inbox's
or the "New message" picker's thread row. The enter sends a group's join
requests, brings the thread to front, subscribes a one-to-one peer's
presence and, when the app does not hold the conversation locally
(MobileSessionState.directLoadedThreads), loads it; a stored
conversation shows the row.
a picked recipient (kind: 'recipient'), from the inbox's "New message"
picker: the participant lookup (direct_v2/threads/get_by_participants/)
runs while the picker is still in front — the app's order — and the
conversation it answers with (thread) is shown from that answer, with no
presence subscribed: in 1:1 the answer names a hidden earlier
thread with no messages, and the app shows that empty conversation and
subscribes nothing (owner decision, 2026-10-24: the picker always opens a
thread). An answer without a thread is not a conversation this model can
show: the typed DirectThreadNotFoundByParticipantsError, raised before the screen comes to front.
a created group (kind: 'created'), from the group picker's createGroup:
the input carries the ids the creation answered (thread_id,
thread_v2_id) and the picked people in pick order (target_user_ids).
The participant lookup that follows the creation is sent by the picker's
createGroupwhile the group picker is still in front, before this
entry (the creation, then the lookup 0.15 s later in 451, both on the
picker's chain); its answer for a just-created
group names no conversation, so nothing is read from it. This entry yields
the navigation, sends the Direct thread's quick-promotion batch
(QuickPromotionSurfaceQueryV3), then IGDirectGetThreadQuery
(min_uq_seq_id the inbox sequence plus one), and shows the thread from
that answer. No presence is subscribed.
Actions take no list element as an argument: a reaction is the message's own
react, the nickname editor is the participant's own openNicknameEditor,
and each item reads the thread its action sends from this screen's state
(its host's state), never from a copy in its entry. The handle's data is
under data (thread.data.thread); it declares no main identifier, because
the thread's ids live inside the thread member of its data.
The theme and nickname requests live on their own screens
(DirectCustomizeChat / DirectThreadThemePicker, DirectThreadNicknameChange).
DirectThreadFragment:direct_thread, a conversation.Three entries, a sum on the input; all open a conversation that exists:
kind: 'thread'): the inbox's or the "New message" picker's thread row. The enter sends a group's join requests, brings the thread to front, subscribes a one-to-one peer's presence and, when the app does not hold the conversation locally (MobileSessionState.directLoadedThreads), loads it; a stored conversation shows the row.kind: 'recipient'), from the inbox's "New message" picker: the participant lookup (direct_v2/threads/get_by_participants/) runs while the picker is still in front — the app's order — and the conversation it answers with (thread) is shown from that answer, with no presence subscribed: in 1:1 the answer names a hidden earlier thread with no messages, and the app shows that empty conversation and subscribes nothing (owner decision, 2026-10-24: the picker always opens a thread). An answer without athreadis not a conversation this model can show: the typedDirectThreadNotFoundByParticipantsError, raised before the screen comes to front.kind: 'created'), from the group picker'screateGroup: the input carries the ids the creation answered (thread_id,thread_v2_id) and the picked people in pick order (target_user_ids). The participant lookup that follows the creation is sent by the picker'screateGroupwhile the group picker is still in front, before this entry (the creation, then the lookup 0.15 s later in 451, both on the picker's chain); its answer for a just-created group names no conversation, so nothing is read from it. This entry yields the navigation, sends the Direct thread's quick-promotion batch (QuickPromotionSurfaceQueryV3), thenIGDirectGetThreadQuery(min_uq_seq_idthe inbox sequence plus one), and shows the thread from that answer. No presence is subscribed.Actions take no list element as an argument: a reaction is the message's own
react, the nickname editor is the participant's ownopenNicknameEditor, and each item reads the thread its action sends from this screen's state (its host's state), never from a copy in its entry. The handle's data is underdata(thread.data.thread); it declares no main identifier, because the thread's ids live inside thethreadmember of its data.The theme and nickname requests live on their own screens (
DirectCustomizeChat/DirectThreadThemePicker,DirectThreadNicknameChange).Guide: A conversation