nip29: supported_kinds and transition edit-metadata to be a PUT, not a PATCH.

This commit is contained in:
fiatjaf
2026-03-12 11:00:01 -03:00
parent 3bd059d1f9
commit bb4093d834
2 changed files with 80 additions and 25 deletions
+8 -15
View File
@@ -43,7 +43,7 @@ type Group struct {
Picture string Picture string
About string About string
Members map[nostr.PubKey][]*Role Members map[nostr.PubKey][]*Role
LiveKitParticipants map[nostr.PubKey]string LiveKitParticipants []nostr.PubKey
// indicates that only members can read group messages // indicates that only members can read group messages
Private bool Private bool
@@ -140,7 +140,7 @@ func NewGroup(gadstr string) (Group, error) {
Address: gad, Address: gad,
Name: gad.ID, Name: gad.ID,
Members: make(map[nostr.PubKey][]*Role), Members: make(map[nostr.PubKey][]*Role),
LiveKitParticipants: make(map[nostr.PubKey]string), LiveKitParticipants: make([]nostr.PubKey, 0),
}, nil }, nil
} }
@@ -152,7 +152,7 @@ func NewGroupFromMetadataEvent(relayURL string, evt *nostr.Event) (Group, error)
}, },
Name: evt.Tags.GetD(), Name: evt.Tags.GetD(),
Members: make(map[nostr.PubKey][]*Role), Members: make(map[nostr.PubKey][]*Role),
LiveKitParticipants: make(map[nostr.PubKey]string), LiveKitParticipants: make([]nostr.PubKey, 0),
} }
err := g.MergeInMetadataEvent(evt) err := g.MergeInMetadataEvent(evt)
@@ -273,13 +273,8 @@ func (group Group) ToLiveKitParticipantsEvent() nostr.Event {
} }
evt.Tags[0] = nostr.Tag{"d", group.Address.ID} evt.Tags[0] = nostr.Tag{"d", group.Address.ID}
for member, identity := range group.LiveKitParticipants { for _, member := range group.LiveKitParticipants {
tag := nostr.Tag{"participant", member.Hex()} tag := nostr.Tag{"participant", member.Hex()}
if identity != "" {
tag = append(tag, identity)
} else {
tag = append(tag, "")
}
evt.Tags = append(evt.Tags, tag) evt.Tags = append(evt.Tags, tag)
} }
@@ -443,7 +438,7 @@ func (group *Group) MergeInLiveKitParticipantsEvent(evt *nostr.Event) error {
} }
group.LastLiveKitParticipantsUpdate = evt.CreatedAt group.LastLiveKitParticipantsUpdate = evt.CreatedAt
group.LiveKitParticipants = make(map[nostr.PubKey]string) group.LiveKitParticipants = make([]nostr.PubKey, 0, len(evt.Tags))
for _, tag := range evt.Tags { for _, tag := range evt.Tags {
if len(tag) < 2 { if len(tag) < 2 {
continue continue
@@ -456,12 +451,10 @@ func (group *Group) MergeInLiveKitParticipantsEvent(evt *nostr.Event) error {
if err != nil { if err != nil {
continue continue
} }
if slices.Contains(group.LiveKitParticipants, member) {
identity := "" continue
if len(tag) >= 3 {
identity = tag[2]
} }
group.LiveKitParticipants[member] = identity group.LiveKitParticipants = append(group.LiveKitParticipants, member)
} }
return nil return nil
+72 -10
View File
@@ -3,6 +3,7 @@ package nip29
import ( import (
"fmt" "fmt"
"slices" "slices"
"strconv"
"fiatjaf.com/nostr" "fiatjaf.com/nostr"
) )
@@ -81,54 +82,96 @@ var moderationActionFactories = map[nostr.Kind]func(nostr.Event) (Action, error)
y := true y := true
n := false n := false
hasName := false
// DEPRECATED: remove all the fields not tagged with Replace = true eventually
// edit-metadata to become a PUT rather than a PATCH
for _, tag := range evt.Tags { for _, tag := range evt.Tags {
if len(tag) >= 1 { if len(tag) >= 1 {
switch tag[0] { switch tag[0] {
case "name": case "name":
if len(tag) >= 2 { if len(tag) >= 2 {
edit.NameValue = &tag[1] edit.NameValue = &tag[1]
if ok {
edit.Replace = true
}
ok = true ok = true
hasName = true
} }
case "picture": case "picture":
if len(tag) >= 2 { if len(tag) >= 2 {
edit.PictureValue = &tag[1] edit.PictureValue = &tag[1]
if hasName {
edit.Replace = true
}
ok = true ok = true
} }
case "about": case "about":
if len(tag) >= 2 { if len(tag) >= 2 {
edit.AboutValue = &tag[1] edit.AboutValue = &tag[1]
if hasName {
edit.Replace = true
}
ok = true ok = true
} }
case "supported_kinds":
kinds := make([]nostr.Kind, 0, len(tag)-1)
for _, kstr := range tag[1:] {
if kind, err := strconv.ParseUint(kstr, 10, 16); err != nil {
return nil, fmt.Errorf("invalid kind: %w", err)
} else {
kinds = append(kinds, nostr.Kind(kind))
}
}
edit.SupportedKindsValue = &kinds
edit.Replace = true
case "closed": case "closed":
edit.ClosedValue = &y edit.ClosedValue = &y
if hasName {
edit.Replace = true
}
ok = true ok = true
case "open": case "open":
edit.ClosedValue = &n edit.ClosedValue = &n
ok = true ok = true
case "restricted": case "restricted":
edit.RestrictedValue = &y edit.RestrictedValue = &y
if hasName {
edit.Replace = true
}
ok = true ok = true
case "unrestricted": case "unrestricted":
edit.RestrictedValue = &n edit.RestrictedValue = &n
ok = true ok = true
case "hidden": case "hidden":
edit.HiddenValue = &y edit.HiddenValue = &y
if hasName {
edit.Replace = true
}
ok = true ok = true
case "visible": case "visible":
edit.HiddenValue = &n edit.HiddenValue = &n
ok = true ok = true
case "private": case "private":
edit.PrivateValue = &y edit.PrivateValue = &y
if hasName {
edit.Replace = true
}
ok = true ok = true
case "public": case "public":
edit.PrivateValue = &n edit.PrivateValue = &n
ok = true ok = true
case "livekit": case "livekit":
edit.LiveKitValue = &y edit.LiveKitValue = &y
edit.Replace = true
ok = true ok = true
case "no-livekit": case "no-livekit":
edit.LiveKitValue = &n edit.LiveKitValue = &n
ok = true ok = true
case "no-text":
edit.SupportedKindsValue = nil
ok = true
} }
} }
} }
@@ -237,20 +280,36 @@ func (a RemoveUser) Apply(group *Group) {
} }
type EditMetadata struct { type EditMetadata struct {
NameValue *string NameValue *string
PictureValue *string PictureValue *string
AboutValue *string AboutValue *string
RestrictedValue *bool RestrictedValue *bool
ClosedValue *bool ClosedValue *bool
HiddenValue *bool HiddenValue *bool
PrivateValue *bool PrivateValue *bool
LiveKitValue *bool LiveKitValue *bool
When nostr.Timestamp SupportedKindsValue *[]nostr.Kind
Replace bool
When nostr.Timestamp
} }
func (_ EditMetadata) Name() string { return "edit-metadata" } func (_ EditMetadata) Name() string { return "edit-metadata" }
func (a EditMetadata) Apply(group *Group) { func (a EditMetadata) Apply(group *Group) {
group.LastMetadataUpdate = a.When group.LastMetadataUpdate = a.When
if a.Replace {
group.Name = ""
group.Picture = ""
group.About = ""
group.Restricted = false
group.Closed = false
group.Hidden = false
group.Private = false
group.LiveKit = false
group.SupportedKinds = nil
}
if a.NameValue != nil { if a.NameValue != nil {
group.Name = *a.NameValue group.Name = *a.NameValue
} }
@@ -275,6 +334,9 @@ func (a EditMetadata) Apply(group *Group) {
if a.LiveKitValue != nil { if a.LiveKitValue != nil {
group.LiveKit = *a.LiveKitValue group.LiveKit = *a.LiveKitValue
} }
if a.SupportedKindsValue != nil {
group.SupportedKinds = *a.SupportedKindsValue
}
} }
type CreateGroup struct { type CreateGroup struct {
@@ -297,7 +359,7 @@ type DeleteGroup struct {
func (_ DeleteGroup) Name() string { return "delete-group" } func (_ DeleteGroup) Name() string { return "delete-group" }
func (a DeleteGroup) Apply(group *Group) { func (a DeleteGroup) Apply(group *Group) {
group.Members = make(map[nostr.PubKey][]*Role) group.Members = make(map[nostr.PubKey][]*Role)
group.LiveKitParticipants = make(map[nostr.PubKey]string) group.LiveKitParticipants = make([]nostr.PubKey, 0)
group.Closed = true group.Closed = true
group.Private = true group.Private = true
group.Restricted = true group.Restricted = true