MishkaCmsCore.Runtime.PageBuilder.Presence (Mishka CMS Core v0.0.1)

Copy Markdown View Source

Who else is in this editing session — real Phoenix.Presence on the session's own PubSub topic.

The prototype drew three hardcoded avatars (JD, AB, CD). That is worse than showing none: it tells an author their colleagues are watching when nobody is, and it hides the one case that actually matters — two people editing the same page, where the editor is last-write-wins at the op level.

Tracking costs nothing here because the topic already exists: both LiveViews of a session are subscribed to it for document updates, so presence rides along.

Summary

Functions

A display name for a review byline: the local part of the address, "Someone" with no user.

Everyone currently in the session, one entry per person however many tabs they have open.

Callback implementation for Phoenix.Presence.fetch/2.

Two letters for an avatar chip, from the local part of an email: "ada.love@x.com" gives "AL".

Announces a user as editing token. Safe to call with no user — an anonymous mount tracks nothing.

Callback implementation for Phoenix.Presence.list/1.

Everyone except user — the avatars worth showing, since your own presence is not news.

Callback implementation for Phoenix.Presence.track/3.

Callback implementation for Phoenix.Presence.untrack/2.

Functions

child_spec(opts)

display_name(arg1)

@spec display_name(map() | nil) :: String.t()

A display name for a review byline: the local part of the address, "Someone" with no user.

Accounts carry no separate name field, so the address is what there is. The domain is dropped because a comment thread reads better as "ada.love" than as a full address.

editors(token)

@spec editors(String.t()) :: [map()]

Everyone currently in the session, one entry per person however many tabs they have open.

fetch(topic, presences)

Callback implementation for Phoenix.Presence.fetch/2.

fetchers_pids()

get_by_key(topic, key)

Callback implementation for Phoenix.Presence.get_by_key/2.

initials(arg1)

@spec initials(map()) :: String.t()

Two letters for an avatar chip, from the local part of an email: "ada.love@x.com" gives "AL".

An address is an Ash.CiString, not a binary, so it is stringified rather than guarded on — guarding on is_binary/1 silently produced "?" for every real user.

join(token, user)

@spec join(String.t(), map() | nil) :: {:ok, binary()} | {:error, term()} | :ignore

Announces a user as editing token. Safe to call with no user — an anonymous mount tracks nothing.

The entry carries the user's id, initials and whether it is a master, never its email.

list(topic)

Callback implementation for Phoenix.Presence.list/1.

others(token, user)

@spec others(String.t(), map() | nil) :: [map()]

Everyone except user — the avatars worth showing, since your own presence is not news.

A master's avatar reads the first letter of MishkaCmsCore.Accounts.Helper.label(:master), "M", unless user is a master too.

track(socket, key, meta)

Callback implementation for Phoenix.Presence.track/3.

track(pid, topic, key, meta)

Callback implementation for Phoenix.Presence.track/4.

untrack(socket, key)

Callback implementation for Phoenix.Presence.untrack/2.

untrack(pid, topic, key)

Callback implementation for Phoenix.Presence.untrack/3.

update(socket, key, meta)

Callback implementation for Phoenix.Presence.update/3.

update(pid, topic, key, meta)

Callback implementation for Phoenix.Presence.update/4.