big update: added reactions, groups, media share
CI / Go (build + vet + test) (push) Canceled after 0s
CI / Web (build + lint) (push) Canceled after 0s

This commit is contained in:
vantablackTea
2026-09-27 21:59:48 +03:00
parent ae24bdd0e0
commit 9d03ea4c51
41 changed files with 2548 additions and 172 deletions
+61
View File
@@ -84,6 +84,67 @@ func (h *Hub) PublishRead(conversationID, userID, messageID int64) {
h.sendToConversation(conversationID, envelope{Type: EventRead, Data: mustMarshal(evt)}, userID)
}
// Subscribe adds a user to a conversation's subscriber set so they receive its
// events without reconnecting (used when a member is added to a group).
func (h *Hub) Subscribe(userID, conversationID int64) {
h.mu.Lock()
defer h.mu.Unlock()
if h.subs[conversationID] == nil {
h.subs[conversationID] = make(map[int64]struct{})
}
h.subs[conversationID][userID] = struct{}{}
}
// Unsubscribe removes a user from a conversation's subscriber set.
func (h *Hub) Unsubscribe(userID, conversationID int64) {
h.mu.Lock()
defer h.mu.Unlock()
users := h.subs[conversationID]
delete(users, userID)
if len(users) == 0 {
delete(h.subs, conversationID)
}
}
// SendToUser delivers an event to every connection of a single user.
func (h *Hub) SendToUser(userID int64, evtType string, data any) {
payload, err := json.Marshal(envelope{Type: evtType, Data: mustMarshal(data)})
if err != nil {
slog.Error("ws: marshal direct event", "error", err)
return
}
h.mu.Lock()
defer h.mu.Unlock()
for c := range h.conns[userID] {
c.enqueueRaw(payload)
}
}
// PublishMemberChanged tells a conversation's members that someone joined or left.
func (h *Hub) PublishMemberChanged(conversationID, userID int64, added bool) {
evtType := EventMemberAdded
if !added {
evtType = EventMemberRemoved
}
evt := MemberChanged{ConversationID: conversationID, UserID: userID}
h.sendToConversation(conversationID, envelope{Type: evtType, Data: mustMarshal(evt)}, 0)
}
// PublishReactionChanged tells a conversation's members that a reaction changed.
func (h *Hub) PublishReactionChanged(conversationID, messageID, userID int64, emoji string, added bool) {
evtType := EventReactionAdded
if !added {
evtType = EventReactionRemoved
}
evt := ReactionChanged{
ConversationID: conversationID,
MessageID: messageID,
UserID: userID,
Emoji: emoji,
}
h.sendToConversation(conversationID, envelope{Type: evtType, Data: mustMarshal(evt)}, 0)
}
func (h *Hub) register(c *client, conversationIDs []int64) {
h.mu.Lock()
defer h.mu.Unlock()