PhoenixKit.Modules.Publishing.PresenceHelpers (phoenix_kit v1.7.38)

Copy Markdown View Source

Helper functions for collaborative post 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 form.

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 form, sorted by join time (FIFO).

Gets all spectators (everyone except the first person).

Subscribes the current process to presence events for a form.

Tracks the current LiveView process in a Presence topic.

Unsubscribes from presence events and editor form events for a form.

Untracks the current LiveView process from a Presence topic.

Functions

count_editors(form_key)

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

editing_topic(form_key)

Generates the Presence topic name for a form.

Examples

editing_topic("docs:my-post/en.phk")
# => "publishing_edit:docs:my-post/en.phk"

get_editing_role(form_key, 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("blog:my-post", 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(form_key)

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

get_sorted_presences(form_key)

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

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

get_spectators(form_key)

Gets all spectators (everyone except the first person).

Returns a list of metadata for spectators only.

subscribe_to_editing(form_key)

Subscribes the current process to presence events for a form.

After subscribing, the process will receive:

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

track_editing_session(form_key, socket, user)

Tracks the current LiveView process in a Presence topic.

Parameters

  • form_key: The unique key for the post being edited
  • socket: The LiveView socket
  • user: The current user struct

Examples

track_editing_session("blog:my-post/en.phk", socket, user)
# => {:ok, ref}

unsubscribe_from_editing(form_key)

Unsubscribes from presence events and editor form events for a form.

Call this when switching languages or versions to clean up subscriptions.

untrack_editing_session(form_key, socket)

Untracks the current LiveView process from a Presence topic.

Call this when switching languages or versions to release the lock on the previous form before tracking the new one.

Parameters

  • form_key: The unique key for the post that was being edited
  • socket: The LiveView socket

Examples

untrack_editing_session("blog:my-post:en", socket)
# => :ok