Phoenix.Presence wrapper for collaborative editing sessions.
Provides standardized user presence tracking with cursor positions,
typing indicators, and idle detection. Compatible with the
presence_avatars and connection_status PhiaUI components.
Setup
Configure the PubSub name in your config:
config :phia_ui, :collab_pubsub, MyApp.PubSubAdd PhiaUi.Collab.Supervisor to your supervision tree — it starts
the required Registry and DynamicSupervisor. This Presence module
must also be started in your supervision tree (it runs its own tracker):
children = [
PhiaUi.Collab.Supervisor,
PhiaUi.Collab.CollabPresence
]Topic Convention
Use "collab:room:<room_id>" as the presence topic to match the
channel topic convention used by PhiaUi.Editor.CollabChannel.
User Metadata
Each tracked user carries standardized metadata:
:name— display name (default"Anonymous"):color— hex color for cursor/avatar (default"#6366F1"):avatar_url— optional avatar image URL:cursor—%{x: number, y: number}or nil:typing— boolean typing indicator:idle_since— UTC datetime when user became idle, or nil:joined_at— UTC datetime when user was first tracked
Summary
Functions
Callback implementation for Phoenix.Presence.fetch/2.
Callback implementation for Phoenix.Presence.get_by_key/2.
Callback implementation for Phoenix.Presence.list/1.
Mark a user as idle.
Returns a formatted list of online users compatible with the presence_avatars component.
Callback implementation for Phoenix.Presence.track/3.
Callback implementation for Phoenix.Presence.track/4.
Track a user in a collaboration room.
Returns only users who are currently typing.
Callback implementation for Phoenix.Presence.untrack/2.
Callback implementation for Phoenix.Presence.untrack/3.
Callback implementation for Phoenix.Presence.update/3.
Callback implementation for Phoenix.Presence.update/4.
Update the cursor position for a tracked user.
Set or clear the typing indicator for a user.
Returns the count of distinct online users in the topic.
Types
@type user_meta() :: %{ name: String.t(), color: String.t(), avatar_url: String.t() | nil, cursor: map() | nil, typing: boolean(), idle_since: DateTime.t() | nil, joined_at: DateTime.t() }
Functions
Callback implementation for Phoenix.Presence.fetch/2.
Callback implementation for Phoenix.Presence.get_by_key/2.
Callback implementation for Phoenix.Presence.list/1.
Mark a user as idle.
Sets idle_since to the current UTC time and clears the typing flag.
Returns a formatted list of online users compatible with the presence_avatars component.
Each user map contains: :id, :name, :color, :avatar_url, :status, :cursor, :typing.
The :status field is "online" or "idle" based on the idle_since metadata.
Callback implementation for Phoenix.Presence.track/3.
Callback implementation for Phoenix.Presence.track/4.
Track a user in a collaboration room.
Normalizes the provided metadata into the standard presence schema. Missing fields receive sensible defaults.
Parameters
topic— the presence topic (e.g.,"collab:room:doc-123")user_id— unique user identifier (string)meta— user metadata map; recognized keys::name,:color,:avatar_url
Examples
iex> CollabPresence.track_user("collab:room:doc-1", "user-42", %{name: "Alice", color: "#EF4444"})
{:ok, _ref}
Returns only users who are currently typing.
Callback implementation for Phoenix.Presence.untrack/2.
Callback implementation for Phoenix.Presence.untrack/3.
Callback implementation for Phoenix.Presence.update/3.
Callback implementation for Phoenix.Presence.update/4.
Update the cursor position for a tracked user.
Also clears the idle state, since cursor movement implies activity.
Parameters
topic— the presence topicuser_id— the user whose cursor movedcursor— a map with position data (e.g.,%{x: 120, y: 340})
Set or clear the typing indicator for a user.
Parameters
topic— the presence topicuser_id— the user who started or stopped typingtyping?—truewhen typing,falsewhen stopped
@spec user_count(String.t()) :: non_neg_integer()
Returns the count of distinct online users in the topic.