nip29: livekit group live participants.

This commit is contained in:
fiatjaf
2026-03-11 16:06:30 -03:00
parent 681bd55e55
commit 3bd059d1f9
4 changed files with 223 additions and 158 deletions
+78 -20
View File
@@ -39,10 +39,11 @@ func ParseGroupAddress(raw string) (GroupAddress, error) {
type Group struct {
Address GroupAddress
Name string
Picture string
About string
Members map[nostr.PubKey][]*Role
Name string
Picture string
About string
Members map[nostr.PubKey][]*Role
LiveKitParticipants map[nostr.PubKey]string
// indicates that only members can read group messages
Private bool
@@ -57,7 +58,7 @@ type Group struct {
Hidden bool
// indicates that the group supports audio/video live chat
Livekit bool
LiveKit bool
// indicates which event kinds this group supports
SupportedKinds []nostr.Kind
@@ -65,10 +66,11 @@ type Group struct {
Roles []*Role
InviteCodes []string
LastMetadataUpdate nostr.Timestamp
LastAdminsUpdate nostr.Timestamp
LastMembersUpdate nostr.Timestamp
LastRolesUpdate nostr.Timestamp
LastMetadataUpdate nostr.Timestamp
LastAdminsUpdate nostr.Timestamp
LastMembersUpdate nostr.Timestamp
LastRolesUpdate nostr.Timestamp
LastLiveKitParticipantsUpdate nostr.Timestamp
}
func (group Group) String() string {
@@ -90,9 +92,9 @@ func (group Group) String() string {
maybeClosed = " closed"
}
maybeLivekit := ""
if group.Livekit {
maybeLivekit = " livekit"
maybeLiveKit := ""
if group.LiveKit {
maybeLiveKit = " livekit"
}
members := make([]string, len(group.Members))
@@ -120,7 +122,7 @@ func (group Group) String() string {
maybeRestricted,
maybeHidden,
maybeClosed,
maybeLivekit,
maybeLiveKit,
group.Picture,
group.About,
strings.Join(members, " "),
@@ -135,9 +137,10 @@ func NewGroup(gadstr string) (Group, error) {
}
return Group{
Address: gad,
Name: gad.ID,
Members: make(map[nostr.PubKey][]*Role),
Address: gad,
Name: gad.ID,
Members: make(map[nostr.PubKey][]*Role),
LiveKitParticipants: make(map[nostr.PubKey]string),
}, nil
}
@@ -147,8 +150,9 @@ func NewGroupFromMetadataEvent(relayURL string, evt *nostr.Event) (Group, error)
Relay: relayURL,
ID: evt.Tags.GetD(),
},
Name: evt.Tags.GetD(),
Members: make(map[nostr.PubKey][]*Role),
Name: evt.Tags.GetD(),
Members: make(map[nostr.PubKey][]*Role),
LiveKitParticipants: make(map[nostr.PubKey]string),
}
err := g.MergeInMetadataEvent(evt)
@@ -186,7 +190,7 @@ func (group Group) ToMetadataEvent() nostr.Event {
if group.Closed {
evt.Tags = append(evt.Tags, nostr.Tag{"closed"})
}
if group.Livekit {
if group.LiveKit {
evt.Tags = append(evt.Tags, nostr.Tag{"livekit"})
}
@@ -261,6 +265,27 @@ func (group Group) ToRolesEvent() nostr.Event {
return evt
}
func (group Group) ToLiveKitParticipantsEvent() nostr.Event {
evt := nostr.Event{
Kind: nostr.KindSimpleGroupLiveKitParticipants,
CreatedAt: group.LastLiveKitParticipantsUpdate,
Tags: make(nostr.Tags, 1, 1+len(group.LiveKitParticipants)),
}
evt.Tags[0] = nostr.Tag{"d", group.Address.ID}
for member, identity := range group.LiveKitParticipants {
tag := nostr.Tag{"participant", member.Hex()}
if identity != "" {
tag = append(tag, identity)
} else {
tag = append(tag, "")
}
evt.Tags = append(evt.Tags, tag)
}
return evt
}
func (group *Group) MergeInMetadataEvent(evt *nostr.Event) error {
if evt.Kind != nostr.KindSimpleGroupMetadata {
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupMetadata, evt.Kind)
@@ -284,7 +309,7 @@ func (group *Group) MergeInMetadataEvent(evt *nostr.Event) error {
case "hidden":
group.Hidden = true
case "livekit":
group.Livekit = true
group.LiveKit = true
case "supported_kinds":
kinds := make([]nostr.Kind, 0, len(tag)-1)
for _, raw := range tag[1:] {
@@ -408,3 +433,36 @@ func (group *Group) MergeInRolesEvent(evt *nostr.Event) error {
return nil
}
func (group *Group) MergeInLiveKitParticipantsEvent(evt *nostr.Event) error {
if evt.Kind != nostr.KindSimpleGroupLiveKitParticipants {
return fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupLiveKitParticipants, evt.Kind)
}
if evt.CreatedAt < group.LastLiveKitParticipantsUpdate {
return fmt.Errorf("event is older than our last update (%d vs %d)", evt.CreatedAt, group.LastLiveKitParticipantsUpdate)
}
group.LastLiveKitParticipantsUpdate = evt.CreatedAt
group.LiveKitParticipants = make(map[nostr.PubKey]string)
for _, tag := range evt.Tags {
if len(tag) < 2 {
continue
}
if tag[0] != "participant" {
continue
}
member, err := nostr.PubKeyFromHex(tag[1])
if err != nil {
continue
}
identity := ""
if len(tag) >= 3 {
identity = tag[2]
}
group.LiveKitParticipants[member] = identity
}
return nil
}
+9 -6
View File
@@ -124,10 +124,10 @@ var moderationActionFactories = map[nostr.Kind]func(nostr.Event) (Action, error)
edit.PrivateValue = &n
ok = true
case "livekit":
edit.LivekitValue = &y
edit.LiveKitValue = &y
ok = true
case "no-livekit":
edit.LivekitValue = &n
edit.LiveKitValue = &n
ok = true
}
}
@@ -244,7 +244,7 @@ type EditMetadata struct {
ClosedValue *bool
HiddenValue *bool
PrivateValue *bool
LivekitValue *bool
LiveKitValue *bool
When nostr.Timestamp
}
@@ -272,8 +272,8 @@ func (a EditMetadata) Apply(group *Group) {
if a.PrivateValue != nil {
group.Private = *a.PrivateValue
}
if a.LivekitValue != nil {
group.Livekit = *a.LivekitValue
if a.LiveKitValue != nil {
group.LiveKit = *a.LiveKitValue
}
}
@@ -287,6 +287,7 @@ func (a CreateGroup) Apply(group *Group) {
group.LastMetadataUpdate = a.When
group.LastAdminsUpdate = a.When
group.LastMembersUpdate = a.When
group.LastLiveKitParticipantsUpdate = a.When
}
type DeleteGroup struct {
@@ -296,6 +297,7 @@ type DeleteGroup struct {
func (_ DeleteGroup) Name() string { return "delete-group" }
func (a DeleteGroup) Apply(group *Group) {
group.Members = make(map[nostr.PubKey][]*Role)
group.LiveKitParticipants = make(map[nostr.PubKey]string)
group.Closed = true
group.Private = true
group.Restricted = true
@@ -303,10 +305,11 @@ func (a DeleteGroup) Apply(group *Group) {
group.Name = "[deleted]"
group.About = ""
group.Picture = ""
group.Livekit = false
group.LiveKit = false
group.LastMetadataUpdate = a.When
group.LastAdminsUpdate = a.When
group.LastMembersUpdate = a.When
group.LastLiveKitParticipantsUpdate = a.When
}
type CreateInvite struct {
+1
View File
@@ -28,6 +28,7 @@ var MetadataEventKinds = KindRange{
nostr.KindSimpleGroupAdmins,
nostr.KindSimpleGroupMembers,
nostr.KindSimpleGroupRoles,
nostr.KindSimpleGroupLiveKitParticipants,
}
func (kr KindRange) Includes(kind nostr.Kind) bool {