# `PhoenixKit.Modules.Entities.PresenceHelpers`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L1)

Helper functions for collaborative editing with Phoenix.Presence.

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

# `count_editors`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L160)

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

# `editing_topic`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L191)

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`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L57)

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.uuid) 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`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L130)

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`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L95)

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

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

## Examples

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

# `get_spectators`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L150)

Gets all spectators (everyone except the first person).

Returns a list of metadata for spectators only.

## Examples

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

# `subscribe_to_editing`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L175)

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`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.65/lib/modules/entities/presence_helpers.ex#L26)

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}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
