PhoenixKit.Entities.PresenceHelpers (phoenix_kit v1.6.15)

View Source

Helper functions for collaborative editing with Phoenix.Presence.

Provides utilities for tracking editing sessions, determining owner/spectator roles, and syncing state between users.

Summary

Functions

Counts total number of people editing (owner + spectators).

Generates the Presence topic name for a resource.

Determines if the current socket is the owner (first in the presence list).

Gets the lock owner's metadata, or nil if no one is editing.

Gets all presences for a resource, sorted by join time (FIFO).

Gets all spectators (everyone except the first person).

Subscribes the current process to presence events for a resource.

Tracks the current LiveView process in a Presence topic.

Functions

count_editors(type, id)

Counts total number of people editing (owner + spectators).

editing_topic(atom, id)

Generates the Presence topic name for a resource.

Examples

editing_topic(:entity, 5)
# => "entity_edit:5"

editing_topic(:data, 10)
# => "data_edit:10"

get_editing_role(type, id, socket_id, current_user_id)

Determines if the current socket is the owner (first in the presence list).

Returns {:owner, presences} if this socket is the owner (or same user in different tab), or {:spectator, owner_meta, presences} if a different user is the owner.

Examples

case get_editing_role(:entity, 5, socket.id, current_user.id) do
  {:owner, all_presences} ->
    # I can edit!

  {:spectator, owner_metadata, all_presences} ->
    # I'm read-only, sync with owner's state
end

get_lock_owner(type, id)

Gets the lock owner's metadata, or nil if no one is editing.

Examples

case get_lock_owner(:entity, 5) do
  nil -> # No one editing
  meta -> # meta.user, meta.joined_at, etc.
end

get_sorted_presences(type, id)

Gets all presences for a resource, sorted by join time (FIFO).

Returns a list of tuples: [{socket_id, metadata}, ...]

Examples

get_sorted_presences(:entity, 5)
# => [
#   {"phx-abc123", %{user_id: 5, joined_at: 123456, ...}},
#   {"phx-def456", %{user_id: 7, joined_at: 123458, ...}}
# ]

get_spectators(type, id)

Gets all spectators (everyone except the first person).

Returns a list of metadata for spectators only.

Examples

get_spectators(:entity, 5)
# => [
#   %{user_id: 7, user_email: "user@example.com", joined_at: 123458, ...},
#   %{user_id: 9, user_email: "other@example.com", joined_at: 123460, ...}
# ]

subscribe_to_editing(type, id)

Subscribes the current process to presence events for a resource.

After subscribing, the process will receive:

  • %Phoenix.Socket.Broadcast{event: "presence_diff", ...} when users join/leave

Examples

subscribe_to_editing(:entity, 5)
# Now will receive presence_diff messages

track_editing_session(type, id, socket, user)

Tracks the current LiveView process in a Presence topic.

Parameters

  • type: The resource type (:entity or :data)
  • id: The resource ID
  • socket: The LiveView socket
  • user: The current user struct

Examples

track_editing_session(:entity, 5, socket, user)
# => {:ok, ref}