Documentation
¶
Overview ¶
Package partyline implements the server-side synthetic cross-account chat feature (partyline.ts): a virtual, IRC-less "network" every local account gets, whose one channel fans messages/reactions out to every other local account instead of an IRC server.
What's deliberately NOT ported here: broadcastJitsi/jitsiJoin/jitsiLeave/ jitsiLeaveAll. Those need Chan.JitsiActive/JitsiHeartbeat fields that don't exist yet (internal/model/chan.go only tracks JitsiUsers/JitsiURL, enough for the IRC-TAGMSG-driven path in internal/irchandlers/jitsi.go) and are only reachable from the jitsi:join/jitsi:leave socket handlers, which aren't ported yet either (Stage 11 territory). sendPushNotification integration is deferred the same way internal/irchandlers defers it (see that package's Deps doc comment) - internal/webpush exists as of this stage, but wiring it into every call site is left for when Client ownership of sessions/subscriptions lands.
Index ¶
- Constants
- func Chan(network *model.Network) *model.Chan
- func NewNetwork(networkName, chanName, ownerNick string, nextID func() int) *model.Network
- func ReactMessage(sender Target, targets []Target, msgid, reaction string)
- func SendMessage(deps Deps, sender Target, targets []Target, text, replyTo string)
- func SyncPresence(targets []Target, attached func(Target) bool)
- type Deps
- type Target
Constants ¶
const NetworkUUID = "a11ce000-0000-4000-8000-000000000001"
NetworkUUID is PARTYLINE_NETWORK_UUID from partyline.ts: fixed rather than random, since the virtual network is rebuilt from scratch on every server restart (never persisted) but message storage keys logged history by (network.uuid, channel.name) - a random UUID here would orphan every previously logged message on each restart.
Variables ¶
This section is empty.
Functions ¶
func Chan ¶
Chan returns the account's partyline channel from a network built by NewNetwork, mirroring partyline.ts's getChan (`client.partylineNetwork ?.channels[1]` - index 1, since index 0 is always the lobby NewNetwork prepends).
func NewNetwork ¶
NewNetwork mirrors ensureChannel's construction of a fresh partyline Network + its one channel for one account (the caller is responsible for the "idempotent, already have one" half of ensureChannel - checking whether an account already has a partyline network is a Client-ownership concern this package doesn't have a seam for yet).
nextID mirrors client.idChan++, called twice in the same order Node's ensureChannel does: once for the (unused but still ID-bearing) lobby channel, then for the partyline channel itself.
func ReactMessage ¶
ReactMessage mirrors partyline.ts's reactMessage: toggles sender's reaction on msgid in every target's own copy of the message that shares it, fanning the new reaction state out via "msg:reaction".
func SendMessage ¶
SendMessage mirrors partyline.ts's sendMessage: fans a chat message out to every target's own copy of the partyline channel, reusing Chan.PushMessage per recipient so unread counters and history trimming all happen exactly like a normal channel message.
func SyncPresence ¶
SyncPresence mirrors partyline.ts's syncPresence: rebuilds every account's view of "who's online" (any account with at least one attached session) as synthetic Users in its own partyline channel. attached reports whether t currently has any browser session connected, mirroring `Object.keys(c.attachedClients).length > 0`.
Types ¶
type Deps ¶
Deps bundles the config-derived values SendMessage needs, mirroring the same Cfg/NextID seam internal/irchandlers.Deps and internal/incommands. Deps use for the identical purpose.
type Target ¶
type Target interface {
// Name is the account's username (sender.name in partyline.ts).
Name() string
// PartylineChan returns this account's own partyline channel (see
// Chan), or nil if it doesn't have one - callers skip nil targets the
// same way getChan's undefined return causes partyline.ts's `if
// (!targetChan) continue` to skip them.
PartylineChan() *model.Chan
// Emit sends one named event to every session this account currently
// has attached, mirroring Client.emit.
Emit(event string, payload any)
}
Target is the slice of one local account (Client, once it owns IRC/ partyline state) this package needs: enough to fan a message/reaction/ presence update out to that one account's own partyline channel and its own attached browser sessions, without this package needing a concrete Client type. Implementations must be safe to compare with == (SendMessage/ReactMessage use identity to detect "sender is also this recipient", mirroring Node's `target === sender`) - a pointer receiver satisfies this trivially.