Merge pull request #2069 from vitorpamplona/claude/nip-53-compliance-mh5pD
Add support for NIP-53 Meeting Spaces and Meeting Rooms
This commit is contained in:
@@ -163,6 +163,9 @@ import com.vitorpamplona.quartz.nip52Calendar.appt.time.CalendarTimeSlotEvent
|
|||||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||||
import com.vitorpamplona.quartz.nip52Calendar.rsvp.CalendarRSVPEvent
|
import com.vitorpamplona.quartz.nip52Calendar.rsvp.CalendarRSVPEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.presence.MeetingRoomPresenceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||||
@@ -2623,6 +2626,9 @@ object LocalCache : ILocalCache, ICacheProvider {
|
|||||||
is LabeledBookmarkListEvent -> consumeBaseReplaceable(event, relay, wasVerified)
|
is LabeledBookmarkListEvent -> consumeBaseReplaceable(event, relay, wasVerified)
|
||||||
is LiveActivitiesEvent -> consume(event, relay, wasVerified)
|
is LiveActivitiesEvent -> consume(event, relay, wasVerified)
|
||||||
is LiveActivitiesChatMessageEvent -> consume(event, relay, wasVerified)
|
is LiveActivitiesChatMessageEvent -> consume(event, relay, wasVerified)
|
||||||
|
is MeetingSpaceEvent -> consumeBaseReplaceable(event, relay, wasVerified)
|
||||||
|
is MeetingRoomEvent -> consumeBaseReplaceable(event, relay, wasVerified)
|
||||||
|
is MeetingRoomPresenceEvent -> consumeBaseReplaceable(event, relay, wasVerified)
|
||||||
is LnZapEvent -> consume(event, relay, wasVerified)
|
is LnZapEvent -> consume(event, relay, wasVerified)
|
||||||
is LnZapRequestEvent -> consume(event, relay, wasVerified)
|
is LnZapRequestEvent -> consume(event, relay, wasVerified)
|
||||||
is NIP90StatusEvent -> consumeRegularEvent(event, relay, wasVerified)
|
is NIP90StatusEvent -> consumeRegularEvent(event, relay, wasVerified)
|
||||||
|
|||||||
@@ -138,6 +138,8 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderLiveChessChallenge
|
|||||||
import com.vitorpamplona.amethyst.ui.note.types.RenderLiveChessGameEnd
|
import com.vitorpamplona.amethyst.ui.note.types.RenderLiveChessGameEnd
|
||||||
import com.vitorpamplona.amethyst.ui.note.types.RenderLnZap
|
import com.vitorpamplona.amethyst.ui.note.types.RenderLnZap
|
||||||
import com.vitorpamplona.amethyst.ui.note.types.RenderLongFormContent
|
import com.vitorpamplona.amethyst.ui.note.types.RenderLongFormContent
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.types.RenderMeetingRoomEvent
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.types.RenderMeetingSpaceEvent
|
||||||
import com.vitorpamplona.amethyst.ui.note.types.RenderMintRecommendation
|
import com.vitorpamplona.amethyst.ui.note.types.RenderMintRecommendation
|
||||||
import com.vitorpamplona.amethyst.ui.note.types.RenderNIP90ContentDiscoveryResponse
|
import com.vitorpamplona.amethyst.ui.note.types.RenderNIP90ContentDiscoveryResponse
|
||||||
import com.vitorpamplona.amethyst.ui.note.types.RenderNIP90Status
|
import com.vitorpamplona.amethyst.ui.note.types.RenderNIP90Status
|
||||||
@@ -251,6 +253,8 @@ import com.vitorpamplona.quartz.nip51Lists.relaySets.RelaySetEvent
|
|||||||
import com.vitorpamplona.quartz.nip52Calendar.appt.day.CalendarDateSlotEvent
|
import com.vitorpamplona.quartz.nip52Calendar.appt.day.CalendarDateSlotEvent
|
||||||
import com.vitorpamplona.quartz.nip52Calendar.appt.time.CalendarTimeSlotEvent
|
import com.vitorpamplona.quartz.nip52Calendar.appt.time.CalendarTimeSlotEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||||
@@ -987,6 +991,14 @@ private fun RenderNoteRow(
|
|||||||
RenderLiveActivityEvent(baseNote, accountViewModel, nav)
|
RenderLiveActivityEvent(baseNote, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is MeetingSpaceEvent -> {
|
||||||
|
RenderMeetingSpaceEvent(baseNote, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
|
is MeetingRoomEvent -> {
|
||||||
|
RenderMeetingRoomEvent(baseNote, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
is GitRepositoryEvent -> {
|
is GitRepositoryEvent -> {
|
||||||
RenderGitRepositoryEvent(baseNote, accountViewModel, nav)
|
RenderGitRepositoryEvent(baseNote, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,328 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.note.types
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.model.User
|
||||||
|
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||||
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
|
import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.nip53LiveActivities.LiveFlag
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.nip53LiveActivities.ScheduledFlag
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CrossfadeCheckIfVideoIsOnline
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.equalImmutableLists
|
||||||
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.SmallBorder
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ParticipantTag
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.StatusTag
|
||||||
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
import java.util.Locale
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag as MeetingSpaceStatusTag
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RenderMeetingSpaceEvent(
|
||||||
|
baseNote: Note,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: INav,
|
||||||
|
) {
|
||||||
|
Row(modifier = Modifier.padding(top = 5.dp)) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
RenderMeetingSpaceEventInner(baseNote = baseNote, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RenderMeetingSpaceEventInner(
|
||||||
|
baseNote: Note,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: INav,
|
||||||
|
) {
|
||||||
|
val noteEvent = baseNote.event as? MeetingSpaceEvent ?: return
|
||||||
|
|
||||||
|
val eventUpdates by observeNote(baseNote, accountViewModel)
|
||||||
|
|
||||||
|
val roomName = remember(eventUpdates) { noteEvent.room() }
|
||||||
|
val summary = remember(eventUpdates) { noteEvent.summary() }
|
||||||
|
val status = remember(eventUpdates) { noteEvent.status() }
|
||||||
|
val participants = remember(eventUpdates) { noteEvent.participants() }
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.padding(vertical = 5.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
roomName?.let {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = StdHorzSpacer)
|
||||||
|
|
||||||
|
CrossfadeIfEnabled(targetState = status, label = "MeetingSpaceStatus", accountViewModel = accountViewModel) {
|
||||||
|
when (it) {
|
||||||
|
MeetingSpaceStatusTag.STATUS.OPEN -> {
|
||||||
|
MeetingSpaceOpenFlag()
|
||||||
|
}
|
||||||
|
|
||||||
|
MeetingSpaceStatusTag.STATUS.PRIVATE -> {
|
||||||
|
MeetingSpacePrivateFlag()
|
||||||
|
}
|
||||||
|
|
||||||
|
MeetingSpaceStatusTag.STATUS.CLOSED -> {
|
||||||
|
MeetingSpaceClosedFlag()
|
||||||
|
}
|
||||||
|
|
||||||
|
null -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary?.let {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = MaterialTheme.colorScheme.placeholderText,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 5.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderParticipants(participants, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RenderMeetingRoomEvent(
|
||||||
|
baseNote: Note,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: INav,
|
||||||
|
) {
|
||||||
|
Row(modifier = Modifier.padding(top = 5.dp)) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
RenderMeetingRoomEventInner(baseNote = baseNote, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RenderMeetingRoomEventInner(
|
||||||
|
baseNote: Note,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: INav,
|
||||||
|
) {
|
||||||
|
val noteEvent = baseNote.event as? MeetingRoomEvent ?: return
|
||||||
|
|
||||||
|
val eventUpdates by observeNote(baseNote, accountViewModel)
|
||||||
|
|
||||||
|
val subject = remember(eventUpdates) { noteEvent.title() }
|
||||||
|
val media = remember(eventUpdates) { noteEvent.streaming() }
|
||||||
|
val status = remember(eventUpdates) { noteEvent.status() }
|
||||||
|
val starts = remember(eventUpdates) { noteEvent.starts() }
|
||||||
|
val participants = remember(eventUpdates) { noteEvent.participants() }
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.padding(vertical = 5.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
subject?.let {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = StdHorzSpacer)
|
||||||
|
|
||||||
|
CrossfadeIfEnabled(targetState = status, label = "MeetingRoomStatus", accountViewModel = accountViewModel) {
|
||||||
|
when (it) {
|
||||||
|
StatusTag.STATUS.LIVE -> {
|
||||||
|
media?.let {
|
||||||
|
CrossfadeCheckIfVideoIsOnline(it, accountViewModel) {
|
||||||
|
LiveFlag()
|
||||||
|
}
|
||||||
|
} ?: LiveFlag()
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusTag.STATUS.PLANNED -> {
|
||||||
|
ScheduledFlag(starts)
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusTag.STATUS.ENDED -> {}
|
||||||
|
|
||||||
|
null -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderParticipants(participants, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RenderParticipants(
|
||||||
|
participants: List<ParticipantTag>,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: INav,
|
||||||
|
) {
|
||||||
|
var participantUsers by remember {
|
||||||
|
mutableStateOf<ImmutableList<Pair<ParticipantTag, User>>>(
|
||||||
|
persistentListOf(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(key1 = participants) {
|
||||||
|
accountViewModel.loadParticipants(participants) { newParticipantUsers ->
|
||||||
|
if (!equalImmutableLists(newParticipantUsers, participantUsers)) {
|
||||||
|
participantUsers = newParticipantUsers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
participantUsers.forEach {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.padding(vertical = 5.dp)
|
||||||
|
.clickable { nav.nav(routeFor(it.second)) },
|
||||||
|
) {
|
||||||
|
ClickableUserPicture(it.second, 25.dp, accountViewModel)
|
||||||
|
Spacer(StdHorzSpacer)
|
||||||
|
UsernameDisplay(it.second, Modifier.weight(1f), accountViewModel = accountViewModel)
|
||||||
|
Spacer(StdHorzSpacer)
|
||||||
|
it.first.role?.let {
|
||||||
|
Text(
|
||||||
|
text =
|
||||||
|
it.replaceFirstChar {
|
||||||
|
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
|
||||||
|
},
|
||||||
|
color = MaterialTheme.colorScheme.placeholderText,
|
||||||
|
maxLines = 1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MeetingSpaceOpenFlag() {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.meeting_space_open_tag),
|
||||||
|
color = Color.White,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier =
|
||||||
|
remember {
|
||||||
|
Modifier
|
||||||
|
.clip(SmallBorder)
|
||||||
|
.background(Color(0xFF4CAF50))
|
||||||
|
.padding(horizontal = 5.dp)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MeetingSpacePrivateFlag() {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.meeting_space_private_tag),
|
||||||
|
color = Color.White,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier =
|
||||||
|
remember {
|
||||||
|
Modifier
|
||||||
|
.clip(SmallBorder)
|
||||||
|
.background(Color(0xFFFF9800))
|
||||||
|
.padding(horizontal = 5.dp)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MeetingSpaceClosedFlag() {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.meeting_space_closed_tag),
|
||||||
|
color = Color.White,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier =
|
||||||
|
remember {
|
||||||
|
Modifier
|
||||||
|
.clip(SmallBorder)
|
||||||
|
.background(Color.Black)
|
||||||
|
.padding(horizontal = 5.dp)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
+6
@@ -46,6 +46,8 @@ import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
|||||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||||
@@ -149,6 +151,8 @@ fun InnerChannelCardWithReactions(
|
|||||||
) {
|
) {
|
||||||
when (baseNote.event) {
|
when (baseNote.event) {
|
||||||
is LiveActivitiesEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
is LiveActivitiesEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
||||||
|
is MeetingSpaceEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
||||||
|
is MeetingRoomEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
||||||
is CommunityDefinitionEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
is CommunityDefinitionEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
||||||
is ChannelCreateEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
is ChannelCreateEvent -> InnerCardRow(baseNote, accountViewModel, nav)
|
||||||
is ClassifiedsEvent -> InnerCardBox(baseNote, accountViewModel, nav)
|
is ClassifiedsEvent -> InnerCardBox(baseNote, accountViewModel, nav)
|
||||||
@@ -202,6 +206,8 @@ private fun RenderNoteRow(
|
|||||||
) {
|
) {
|
||||||
when (baseNote.event) {
|
when (baseNote.event) {
|
||||||
is LiveActivitiesEvent -> RenderLiveActivityThumb(baseNote, accountViewModel, nav)
|
is LiveActivitiesEvent -> RenderLiveActivityThumb(baseNote, accountViewModel, nav)
|
||||||
|
is MeetingSpaceEvent -> RenderLiveActivityThumb(baseNote, accountViewModel, nav)
|
||||||
|
is MeetingRoomEvent -> RenderLiveActivityThumb(baseNote, accountViewModel, nav)
|
||||||
is CommunityDefinitionEvent -> RenderCommunitiesThumb(baseNote, accountViewModel, nav)
|
is CommunityDefinitionEvent -> RenderCommunitiesThumb(baseNote, accountViewModel, nav)
|
||||||
is ChannelCreateEvent -> RenderPublicChatChannelThumb(baseNote, accountViewModel, nav)
|
is ChannelCreateEvent -> RenderPublicChatChannelThumb(baseNote, accountViewModel, nav)
|
||||||
is AppDefinitionEvent -> RenderContentDVMThumb(baseNote, accountViewModel, nav)
|
is AppDefinitionEvent -> RenderContentDVMThumb(baseNote, accountViewModel, nav)
|
||||||
|
|||||||
+46
-15
@@ -35,6 +35,8 @@ import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.muted.MutedAuthors
|
|||||||
import com.vitorpamplona.amethyst.service.OnlineChecker
|
import com.vitorpamplona.amethyst.service.OnlineChecker
|
||||||
import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.FilterByListParams
|
import com.vitorpamplona.amethyst.ui.dal.FilterByListParams
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.StatusTag
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.StatusTag
|
||||||
|
|
||||||
@@ -75,7 +77,8 @@ open class DiscoverLiveFeedFilter(
|
|||||||
|
|
||||||
return collection.filterTo(HashSet()) {
|
return collection.filterTo(HashSet()) {
|
||||||
val noteEvent = it.event
|
val noteEvent = it.event
|
||||||
noteEvent is LiveActivitiesEvent && filterParams.match(noteEvent, it.relays)
|
(noteEvent is LiveActivitiesEvent || noteEvent is MeetingSpaceEvent || noteEvent is MeetingRoomEvent) &&
|
||||||
|
filterParams.match(noteEvent, it.relays)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,33 +109,61 @@ open class DiscoverLiveFeedFilter(
|
|||||||
return items
|
return items
|
||||||
.sortedWith(
|
.sortedWith(
|
||||||
compareBy(
|
compareBy(
|
||||||
{ convertStatusToOrder((it.event as? LiveActivitiesEvent)) },
|
{ convertStatusToOrder(it.event) },
|
||||||
{ participantCounts[it] },
|
{ participantCounts[it] },
|
||||||
{ allParticipants[it] },
|
{ allParticipants[it] },
|
||||||
{ (it.event as? LiveActivitiesEvent)?.starts() ?: it.createdAt() },
|
{
|
||||||
|
when (val e = it.event) {
|
||||||
|
is LiveActivitiesEvent -> e.starts() ?: it.createdAt()
|
||||||
|
is MeetingRoomEvent -> e.starts() ?: it.createdAt()
|
||||||
|
else -> it.createdAt()
|
||||||
|
}
|
||||||
|
},
|
||||||
{ it.idHex },
|
{ it.idHex },
|
||||||
),
|
),
|
||||||
).reversed()
|
).reversed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertStatusToOrder(event: LiveActivitiesEvent?): Int {
|
fun convertStatusToOrder(event: com.vitorpamplona.quartz.nip01Core.core.Event?): Int {
|
||||||
if (event == null) return 0
|
if (event == null) return 0
|
||||||
val url = event.streaming() ?: return 0
|
return when (event) {
|
||||||
return when (event.status()) {
|
is LiveActivitiesEvent -> {
|
||||||
StatusTag.STATUS.LIVE -> {
|
val url = event.streaming() ?: return 0
|
||||||
if (OnlineChecker.isCachedAndOffline(url)) {
|
when (event.status()) {
|
||||||
0
|
StatusTag.STATUS.LIVE -> {
|
||||||
} else {
|
if (OnlineChecker.isCachedAndOffline(url)) 0 else 2
|
||||||
2
|
}
|
||||||
|
|
||||||
|
StatusTag.STATUS.PLANNED -> {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusTag.STATUS.ENDED -> {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusTag.STATUS.PLANNED -> {
|
is MeetingRoomEvent -> {
|
||||||
1
|
when (event.status()) {
|
||||||
|
StatusTag.STATUS.LIVE -> 2
|
||||||
|
StatusTag.STATUS.PLANNED -> 1
|
||||||
|
StatusTag.STATUS.ENDED -> 0
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusTag.STATUS.ENDED -> {
|
is MeetingSpaceEvent -> {
|
||||||
0
|
when (event.status()) {
|
||||||
|
com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag.STATUS.OPEN -> 2
|
||||||
|
com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag.STATUS.PRIVATE -> 1
|
||||||
|
com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag.STATUS.CLOSED -> 0
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
|
|||||||
+64
-12
@@ -69,6 +69,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.equalImmutabl
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ParticipantTag
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ParticipantTag
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.StatusTag
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.StatusTag
|
||||||
@@ -98,19 +100,69 @@ fun RenderLiveActivityThumb(
|
|||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val card by observeNoteAndMap(baseNote, accountViewModel) {
|
val card by observeNoteAndMap(baseNote, accountViewModel) {
|
||||||
val noteEvent = it.event as? LiveActivitiesEvent
|
when (val noteEvent = it.event) {
|
||||||
|
is LiveActivitiesEvent -> {
|
||||||
|
LiveActivityCard(
|
||||||
|
id = noteEvent.address(),
|
||||||
|
name = noteEvent.dTag(),
|
||||||
|
cover = noteEvent.image()?.ifBlank { null },
|
||||||
|
media = noteEvent.streaming(),
|
||||||
|
subject = noteEvent.title()?.ifBlank { null },
|
||||||
|
content = noteEvent.summary(),
|
||||||
|
participants = noteEvent.participants().toImmutableList(),
|
||||||
|
status = noteEvent.status(),
|
||||||
|
starts = noteEvent.starts(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
LiveActivityCard(
|
is MeetingRoomEvent -> {
|
||||||
id = noteEvent?.address(),
|
LiveActivityCard(
|
||||||
name = noteEvent?.dTag() ?: "",
|
id = noteEvent.address(),
|
||||||
cover = noteEvent?.image()?.ifBlank { null },
|
name = noteEvent.dTag(),
|
||||||
media = noteEvent?.streaming(),
|
cover = noteEvent.image()?.ifBlank { null },
|
||||||
subject = noteEvent?.title()?.ifBlank { null },
|
media = noteEvent.streaming(),
|
||||||
content = noteEvent?.summary(),
|
subject = noteEvent.title()?.ifBlank { null },
|
||||||
participants = noteEvent?.participants()?.toImmutableList() ?: persistentListOf(),
|
content = noteEvent.summary(),
|
||||||
status = noteEvent?.status(),
|
participants = noteEvent.participants().toImmutableList(),
|
||||||
starts = noteEvent?.starts(),
|
status = noteEvent.status(),
|
||||||
)
|
starts = noteEvent.starts(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is MeetingSpaceEvent -> {
|
||||||
|
LiveActivityCard(
|
||||||
|
id = noteEvent.address(),
|
||||||
|
name = noteEvent.dTag(),
|
||||||
|
cover = noteEvent.image()?.ifBlank { null },
|
||||||
|
media = null,
|
||||||
|
subject = noteEvent.room()?.ifBlank { null },
|
||||||
|
content = noteEvent.summary(),
|
||||||
|
participants = noteEvent.participants().toImmutableList(),
|
||||||
|
status =
|
||||||
|
when (noteEvent.status()) {
|
||||||
|
com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag.STATUS.OPEN -> StatusTag.STATUS.LIVE
|
||||||
|
com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag.STATUS.PRIVATE -> StatusTag.STATUS.PLANNED
|
||||||
|
com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.StatusTag.STATUS.CLOSED -> StatusTag.STATUS.ENDED
|
||||||
|
else -> null
|
||||||
|
},
|
||||||
|
starts = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
LiveActivityCard(
|
||||||
|
id = null,
|
||||||
|
name = "",
|
||||||
|
cover = null,
|
||||||
|
media = null,
|
||||||
|
subject = null,
|
||||||
|
content = null,
|
||||||
|
participants = persistentListOf(),
|
||||||
|
status = null,
|
||||||
|
starts = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderLiveActivityThumb(
|
RenderLiveActivityThumb(
|
||||||
|
|||||||
+4
-2
@@ -27,6 +27,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
|||||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ fun filterLiveActivitiesAllCommunities(
|
|||||||
tags =
|
tags =
|
||||||
mapOf(
|
mapOf(
|
||||||
"a" to communityList,
|
"a" to communityList,
|
||||||
"k" to listOf(LiveActivitiesChatMessageEvent.KIND.toString(), LiveActivitiesEvent.KIND.toString()),
|
"k" to listOf(LiveActivitiesChatMessageEvent.KIND.toString(), LiveActivitiesEvent.KIND.toString(), MeetingSpaceEvent.KIND.toString(), MeetingRoomEvent.KIND.toString()),
|
||||||
),
|
),
|
||||||
limit = 300,
|
limit = 300,
|
||||||
since = since,
|
since = since,
|
||||||
@@ -59,7 +61,7 @@ fun filterLiveActivitiesAllCommunities(
|
|||||||
filter =
|
filter =
|
||||||
Filter(
|
Filter(
|
||||||
tags = mapOf("k" to listOf("5300"), "a" to communityList),
|
tags = mapOf("k" to listOf("5300"), "a" to communityList),
|
||||||
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND),
|
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
limit = 300,
|
limit = 300,
|
||||||
since = since,
|
since = since,
|
||||||
),
|
),
|
||||||
|
|||||||
+4
-2
@@ -28,6 +28,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
|||||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
|
|
||||||
fun filterLiveActivitiesAuthors(
|
fun filterLiveActivitiesAuthors(
|
||||||
@@ -42,7 +44,7 @@ fun filterLiveActivitiesAuthors(
|
|||||||
filter =
|
filter =
|
||||||
Filter(
|
Filter(
|
||||||
authors = authorList,
|
authors = authorList,
|
||||||
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND),
|
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
limit = 300,
|
limit = 300,
|
||||||
since = since,
|
since = since,
|
||||||
),
|
),
|
||||||
@@ -53,7 +55,7 @@ fun filterLiveActivitiesAuthors(
|
|||||||
filter =
|
filter =
|
||||||
Filter(
|
Filter(
|
||||||
tags = mapOf("p" to authorList),
|
tags = mapOf("p" to authorList),
|
||||||
kinds = listOf(LiveActivitiesEvent.KIND),
|
kinds = listOf(LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
limit = 100,
|
limit = 100,
|
||||||
since = since,
|
since = since,
|
||||||
),
|
),
|
||||||
|
|||||||
+4
-2
@@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
|||||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ fun filterLiveActivitiesByCommunity(
|
|||||||
tags =
|
tags =
|
||||||
mapOf(
|
mapOf(
|
||||||
"a" to listOf(community),
|
"a" to listOf(community),
|
||||||
"k" to listOf(LiveActivitiesChatMessageEvent.KIND.toString(), LiveActivitiesEvent.KIND.toString()),
|
"k" to listOf(LiveActivitiesChatMessageEvent.KIND.toString(), LiveActivitiesEvent.KIND.toString(), MeetingSpaceEvent.KIND.toString(), MeetingRoomEvent.KIND.toString()),
|
||||||
),
|
),
|
||||||
limit = 300,
|
limit = 300,
|
||||||
since = since,
|
since = since,
|
||||||
@@ -60,7 +62,7 @@ fun filterLiveActivitiesByCommunity(
|
|||||||
Filter(
|
Filter(
|
||||||
authors = authors,
|
authors = authors,
|
||||||
tags = mapOf("k" to listOf("5300"), "a" to listOf(community)),
|
tags = mapOf("k" to listOf("5300"), "a" to listOf(community)),
|
||||||
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND),
|
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
limit = 300,
|
limit = 300,
|
||||||
since = since,
|
since = since,
|
||||||
),
|
),
|
||||||
|
|||||||
+3
-1
@@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
|||||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
|
|
||||||
fun filterLiveActivitiesByGeohash(
|
fun filterLiveActivitiesByGeohash(
|
||||||
@@ -42,7 +44,7 @@ fun filterLiveActivitiesByGeohash(
|
|||||||
relay = relay,
|
relay = relay,
|
||||||
filter =
|
filter =
|
||||||
Filter(
|
Filter(
|
||||||
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND),
|
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
tags = mapOf("g" to geoHashes),
|
tags = mapOf("g" to geoHashes),
|
||||||
limit = 300,
|
limit = 300,
|
||||||
since = since,
|
since = since,
|
||||||
|
|||||||
+3
-1
@@ -27,6 +27,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
|||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtagAlts
|
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtagAlts
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
|
|
||||||
fun filterLiveActivitiesByHashtag(
|
fun filterLiveActivitiesByHashtag(
|
||||||
@@ -43,7 +45,7 @@ fun filterLiveActivitiesByHashtag(
|
|||||||
relay = relay,
|
relay = relay,
|
||||||
filter =
|
filter =
|
||||||
Filter(
|
Filter(
|
||||||
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND),
|
kinds = listOf(LiveActivitiesChatMessageEvent.KIND, LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
tags = mapOf("t" to hashtags),
|
tags = mapOf("t" to hashtags),
|
||||||
limit = 300,
|
limit = 300,
|
||||||
since = since,
|
since = since,
|
||||||
|
|||||||
+3
-1
@@ -25,6 +25,8 @@ import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
|||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
|
||||||
@@ -43,7 +45,7 @@ fun filterLiveActivitiesGlobal(
|
|||||||
relay = it.key,
|
relay = it.key,
|
||||||
filter =
|
filter =
|
||||||
Filter(
|
Filter(
|
||||||
kinds = listOf(LiveActivitiesEvent.KIND),
|
kinds = listOf(LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
limit = 30,
|
limit = 30,
|
||||||
since = since ?: TimeUtils.oneWeekAgo(),
|
since = since ?: TimeUtils.oneWeekAgo(),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -919,6 +919,9 @@
|
|||||||
|
|
||||||
<string name="live_stream_is_offline">Livestream is Offline</string>
|
<string name="live_stream_is_offline">Livestream is Offline</string>
|
||||||
<string name="live_stream_has_ended">Livestream Ended</string>
|
<string name="live_stream_has_ended">Livestream Ended</string>
|
||||||
|
<string name="meeting_space_open_tag">OPEN</string>
|
||||||
|
<string name="meeting_space_private_tag">PRIVATE</string>
|
||||||
|
<string name="meeting_space_closed_tag">CLOSED</string>
|
||||||
<string name="are_you_sure_you_want_to_log_out">Logging out deletes all your local information. Make sure to have your private keys backed up to avoid losing your account. Do you want to continue?</string>
|
<string name="are_you_sure_you_want_to_log_out">Logging out deletes all your local information. Make sure to have your private keys backed up to avoid losing your account. Do you want to continue?</string>
|
||||||
<string name="followed_tags">Followed Tags</string>
|
<string name="followed_tags">Followed Tags</string>
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
|||||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||||
|
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||||
@@ -56,7 +58,7 @@ object KindRegistry {
|
|||||||
"repost" to listOf(RepostEvent.KIND),
|
"repost" to listOf(RepostEvent.KIND),
|
||||||
"profile" to listOf(MetadataEvent.KIND),
|
"profile" to listOf(MetadataEvent.KIND),
|
||||||
"channel" to listOf(ChannelCreateEvent.KIND, ChannelMetadataEvent.KIND),
|
"channel" to listOf(ChannelCreateEvent.KIND, ChannelMetadataEvent.KIND),
|
||||||
"live" to listOf(LiveActivitiesEvent.KIND),
|
"live" to listOf(LiveActivitiesEvent.KIND, MeetingSpaceEvent.KIND, MeetingRoomEvent.KIND),
|
||||||
"community" to listOf(CommunityDefinitionEvent.KIND),
|
"community" to listOf(CommunityDefinitionEvent.KIND),
|
||||||
"wiki" to listOf(WikiNoteEvent.KIND),
|
"wiki" to listOf(WikiNoteEvent.KIND),
|
||||||
"classified" to listOf(ClassifiedsEvent.KIND),
|
"classified" to listOf(ClassifiedsEvent.KIND),
|
||||||
|
|||||||
+3
-2
@@ -37,6 +37,7 @@ enum class ROLE(
|
|||||||
HOST("host"),
|
HOST("host"),
|
||||||
MODERATOR("moderator"),
|
MODERATOR("moderator"),
|
||||||
SPEAKER("speaker"),
|
SPEAKER("speaker"),
|
||||||
|
PARTICIPANT("participant"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -58,7 +59,7 @@ data class ParticipantTag(
|
|||||||
ensure(tag.has(3)) { return false }
|
ensure(tag.has(3)) { return false }
|
||||||
ensure(tag[0] == TAG_NAME) { return false }
|
ensure(tag[0] == TAG_NAME) { return false }
|
||||||
ensure(tag[1].length == 64) { 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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ data class ParticipantTag(
|
|||||||
ensure(tag.has(3)) { return null }
|
ensure(tag.has(3)) { return null }
|
||||||
ensure(tag[0] == TAG_NAME) { return null }
|
ensure(tag[0] == TAG_NAME) { return null }
|
||||||
ensure(tag[1].length == 64) { 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])
|
val hint = RelayUrlNormalizer.normalizeOrNull(tag[2])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user