feat: NIP-53 full compliance - render all live activity kinds

- Add case-insensitive role matching in ParticipantTag (accepts both
  "host" and "Host" from other clients per NIP-53 spec)
- Add PARTICIPANT role to ROLE enum per NIP-53 spec
- Add MeetingSpaceEvent (30312), MeetingRoomEvent (30313), and
  MeetingRoomPresenceEvent (10312) consumption in LocalCache
- Create rendering composables for MeetingSpaceEvent and MeetingRoomEvent
  with status flags (OPEN/PRIVATE/CLOSED for spaces, LIVE/PLANNED/ENDED
  for rooms) and participant display
- Add meeting kinds to all discovery feed relay filters (global, authors,
  hashtag, geohash, community)
- Add meeting kinds to ChannelCardCompose and LiveActivityCard thumb
  rendering
- Add meeting kinds to KindRegistry search aliases

https://claude.ai/code/session_01CJ6xfY9gRA1c5r4T1SrUuv
This commit is contained in:
Claude
2026-04-02 03:42:31 +00:00
parent 0f7bcdba38
commit a524890a36
15 changed files with 492 additions and 39 deletions
@@ -37,6 +37,7 @@ enum class ROLE(
HOST("host"),
MODERATOR("moderator"),
SPEAKER("speaker"),
PARTICIPANT("participant"),
}
@Immutable
@@ -58,7 +59,7 @@ data class ParticipantTag(
ensure(tag.has(3)) { return false }
ensure(tag[0] == TAG_NAME) { return false }
ensure(tag[1].length == 64) { return false }
ensure(tag[3] == ROLE.HOST.code) { return false }
ensure(tag[3].equals(ROLE.HOST.code, ignoreCase = true)) { return false }
return true
}
@@ -76,7 +77,7 @@ data class ParticipantTag(
ensure(tag.has(3)) { return null }
ensure(tag[0] == TAG_NAME) { return null }
ensure(tag[1].length == 64) { return null }
ensure(tag[3] == ROLE.HOST.code) { return null }
ensure(tag[3].equals(ROLE.HOST.code, ignoreCase = true)) { return null }
val hint = RelayUrlNormalizer.normalizeOrNull(tag[2])