Adds support for Stemstr
This commit is contained in:
@@ -1051,6 +1051,23 @@ object LocalCache {
|
|||||||
refreshObservers(note)
|
refreshObservers(note)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun consume(event: AudioHeaderEvent, relay: Relay?) {
|
||||||
|
val note = getOrCreateNote(event.id)
|
||||||
|
val author = getOrCreateUser(event.pubKey)
|
||||||
|
|
||||||
|
if (relay != null) {
|
||||||
|
author.addRelayBeingUsed(relay, event.createdAt)
|
||||||
|
note.addRelay(relay)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already processed this event.
|
||||||
|
if (note.event != null) return
|
||||||
|
|
||||||
|
note.loadEvent(event, author, emptyList())
|
||||||
|
|
||||||
|
refreshObservers(note)
|
||||||
|
}
|
||||||
|
|
||||||
fun consume(event: FileHeaderEvent, relay: Relay?) {
|
fun consume(event: FileHeaderEvent, relay: Relay?) {
|
||||||
val note = getOrCreateNote(event.id)
|
val note = getOrCreateNote(event.id)
|
||||||
val author = getOrCreateUser(event.pubKey)
|
val author = getOrCreateUser(event.pubKey)
|
||||||
@@ -1284,7 +1301,7 @@ object LocalCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return notes.values.filter {
|
return notes.values.filter {
|
||||||
(it.event !is GenericRepostEvent && it.event !is RepostEvent && it.event !is CommunityPostApprovalEvent && it.event !is ReactionEvent) &&
|
(it.event !is GenericRepostEvent && it.event !is RepostEvent && it.event !is CommunityPostApprovalEvent && it.event !is ReactionEvent && it.event !is GiftWrapEvent) &&
|
||||||
(
|
(
|
||||||
it.event?.content()?.contains(text, true) ?: false ||
|
it.event?.content()?.contains(text, true) ?: false ||
|
||||||
it.event?.matchTag1With(text) ?: false ||
|
it.event?.matchTag1With(text) ?: false ||
|
||||||
@@ -1292,7 +1309,7 @@ object LocalCache {
|
|||||||
it.idNote().startsWith(text, true)
|
it.idNote().startsWith(text, true)
|
||||||
)
|
)
|
||||||
} + addressables.values.filter {
|
} + addressables.values.filter {
|
||||||
(it.event !is GenericRepostEvent && it.event !is RepostEvent && it.event !is CommunityPostApprovalEvent && it.event !is ReactionEvent) &&
|
(it.event !is GenericRepostEvent && it.event !is RepostEvent && it.event !is CommunityPostApprovalEvent && it.event !is ReactionEvent && it.event !is GiftWrapEvent) &&
|
||||||
(
|
(
|
||||||
it.event?.content()?.contains(text, true) ?: false ||
|
it.event?.content()?.contains(text, true) ?: false ||
|
||||||
it.event?.matchTag1With(text) ?: false ||
|
it.event?.matchTag1With(text) ?: false ||
|
||||||
@@ -1524,6 +1541,7 @@ object LocalCache {
|
|||||||
is AdvertisedRelayListEvent -> consume(event)
|
is AdvertisedRelayListEvent -> consume(event)
|
||||||
is AppDefinitionEvent -> consume(event)
|
is AppDefinitionEvent -> consume(event)
|
||||||
is AppRecommendationEvent -> consume(event)
|
is AppRecommendationEvent -> consume(event)
|
||||||
|
is AudioHeaderEvent -> consume(event, relay)
|
||||||
is AudioTrackEvent -> consume(event)
|
is AudioTrackEvent -> consume(event)
|
||||||
is BadgeAwardEvent -> consume(event)
|
is BadgeAwardEvent -> consume(event)
|
||||||
is BadgeDefinitionEvent -> consume(event)
|
is BadgeDefinitionEvent -> consume(event)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.service
|
|||||||
import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES
|
import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES
|
||||||
import com.vitorpamplona.amethyst.service.relays.JsonFilter
|
import com.vitorpamplona.amethyst.service.relays.JsonFilter
|
||||||
import com.vitorpamplona.amethyst.service.relays.TypedFilter
|
import com.vitorpamplona.amethyst.service.relays.TypedFilter
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
||||||
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
||||||
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
||||||
@@ -26,7 +27,7 @@ object NostrGeohashDataSource : NostrDataSource("SingleGeoHashFeed") {
|
|||||||
hashToLoad
|
hashToLoad
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
kinds = listOf(TextNoteEvent.kind, ChannelMessageEvent.kind, LongTextNoteEvent.kind, PollNoteEvent.kind, LiveActivitiesChatMessageEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioTrackEvent.kind),
|
kinds = listOf(TextNoteEvent.kind, ChannelMessageEvent.kind, LongTextNoteEvent.kind, PollNoteEvent.kind, LiveActivitiesChatMessageEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioTrackEvent.kind, AudioHeaderEvent.kind),
|
||||||
limit = 200
|
limit = 200
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.service
|
|||||||
import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES
|
import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES
|
||||||
import com.vitorpamplona.amethyst.service.relays.JsonFilter
|
import com.vitorpamplona.amethyst.service.relays.JsonFilter
|
||||||
import com.vitorpamplona.amethyst.service.relays.TypedFilter
|
import com.vitorpamplona.amethyst.service.relays.TypedFilter
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
||||||
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
||||||
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
||||||
@@ -29,7 +30,7 @@ object NostrHashtagDataSource : NostrDataSource("SingleHashtagFeed") {
|
|||||||
hashToLoad.capitalize()
|
hashToLoad.capitalize()
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
kinds = listOf(TextNoteEvent.kind, ChannelMessageEvent.kind, LongTextNoteEvent.kind, PollNoteEvent.kind, LiveActivitiesChatMessageEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioTrackEvent.kind),
|
kinds = listOf(TextNoteEvent.kind, ChannelMessageEvent.kind, LongTextNoteEvent.kind, PollNoteEvent.kind, LiveActivitiesChatMessageEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioTrackEvent.kind, AudioHeaderEvent.kind),
|
||||||
limit = 200
|
limit = 200
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.vitorpamplona.amethyst.service.relays.EOSEAccount
|
|||||||
import com.vitorpamplona.amethyst.service.relays.FeedType
|
import com.vitorpamplona.amethyst.service.relays.FeedType
|
||||||
import com.vitorpamplona.amethyst.service.relays.JsonFilter
|
import com.vitorpamplona.amethyst.service.relays.JsonFilter
|
||||||
import com.vitorpamplona.amethyst.service.relays.TypedFilter
|
import com.vitorpamplona.amethyst.service.relays.TypedFilter
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
||||||
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
||||||
import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent
|
import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent
|
||||||
@@ -73,6 +74,7 @@ object NostrHomeDataSource : NostrDataSource("HomeFeed") {
|
|||||||
PollNoteEvent.kind,
|
PollNoteEvent.kind,
|
||||||
HighlightEvent.kind,
|
HighlightEvent.kind,
|
||||||
AudioTrackEvent.kind,
|
AudioTrackEvent.kind,
|
||||||
|
AudioHeaderEvent.kind,
|
||||||
PinListEvent.kind,
|
PinListEvent.kind,
|
||||||
LiveActivitiesChatMessageEvent.kind,
|
LiveActivitiesChatMessageEvent.kind,
|
||||||
LiveActivitiesEvent.kind
|
LiveActivitiesEvent.kind
|
||||||
@@ -92,7 +94,7 @@ object NostrHomeDataSource : NostrDataSource("HomeFeed") {
|
|||||||
return TypedFilter(
|
return TypedFilter(
|
||||||
types = setOf(FeedType.FOLLOWS),
|
types = setOf(FeedType.FOLLOWS),
|
||||||
filter = JsonFilter(
|
filter = JsonFilter(
|
||||||
kinds = listOf(TextNoteEvent.kind, LongTextNoteEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioTrackEvent.kind, PinListEvent.kind),
|
kinds = listOf(TextNoteEvent.kind, LongTextNoteEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioHeaderEvent.kind, AudioTrackEvent.kind, PinListEvent.kind),
|
||||||
tags = mapOf(
|
tags = mapOf(
|
||||||
"t" to hashToLoad.map {
|
"t" to hashToLoad.map {
|
||||||
listOf(it, it.lowercase(), it.uppercase(), it.capitalize())
|
listOf(it, it.lowercase(), it.uppercase(), it.capitalize())
|
||||||
@@ -112,7 +114,7 @@ object NostrHomeDataSource : NostrDataSource("HomeFeed") {
|
|||||||
return TypedFilter(
|
return TypedFilter(
|
||||||
types = setOf(FeedType.FOLLOWS),
|
types = setOf(FeedType.FOLLOWS),
|
||||||
filter = JsonFilter(
|
filter = JsonFilter(
|
||||||
kinds = listOf(TextNoteEvent.kind, LongTextNoteEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioTrackEvent.kind, PinListEvent.kind),
|
kinds = listOf(TextNoteEvent.kind, LongTextNoteEvent.kind, ClassifiedsEvent.kind, HighlightEvent.kind, AudioHeaderEvent.kind, AudioTrackEvent.kind, PinListEvent.kind),
|
||||||
tags = mapOf(
|
tags = mapOf(
|
||||||
"g" to hashToLoad.map {
|
"g" to hashToLoad.map {
|
||||||
listOf(it, it.lowercase(), it.uppercase(), it.capitalize())
|
listOf(it, it.lowercase(), it.uppercase(), it.capitalize())
|
||||||
@@ -137,6 +139,7 @@ object NostrHomeDataSource : NostrDataSource("HomeFeed") {
|
|||||||
LongTextNoteEvent.kind,
|
LongTextNoteEvent.kind,
|
||||||
ClassifiedsEvent.kind,
|
ClassifiedsEvent.kind,
|
||||||
HighlightEvent.kind,
|
HighlightEvent.kind,
|
||||||
|
AudioHeaderEvent.kind,
|
||||||
AudioTrackEvent.kind,
|
AudioTrackEvent.kind,
|
||||||
PinListEvent.kind,
|
PinListEvent.kind,
|
||||||
CommunityPostApprovalEvent.kind
|
CommunityPostApprovalEvent.kind
|
||||||
|
|||||||
+3
-2
@@ -56,8 +56,9 @@ object NostrSearchEventOrUserDataSource : NostrDataSource("SearchEventFeed") {
|
|||||||
filter = JsonFilter(
|
filter = JsonFilter(
|
||||||
kinds = listOf(
|
kinds = listOf(
|
||||||
TextNoteEvent.kind, LongTextNoteEvent.kind, BadgeDefinitionEvent.kind,
|
TextNoteEvent.kind, LongTextNoteEvent.kind, BadgeDefinitionEvent.kind,
|
||||||
PeopleListEvent.kind, BookmarkListEvent.kind, AudioTrackEvent.kind, PinListEvent.kind,
|
PeopleListEvent.kind, BookmarkListEvent.kind, AudioHeaderEvent.kind,
|
||||||
PollNoteEvent.kind, ChannelCreateEvent.kind
|
AudioTrackEvent.kind, PinListEvent.kind, PollNoteEvent.kind,
|
||||||
|
ChannelCreateEvent.kind
|
||||||
),
|
),
|
||||||
search = mySearchString,
|
search = mySearchString,
|
||||||
limit = 100
|
limit = 100
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ object NostrUserProfileDataSource : NostrDataSource("UserProfileFeed") {
|
|||||||
RepostEvent.kind,
|
RepostEvent.kind,
|
||||||
LongTextNoteEvent.kind,
|
LongTextNoteEvent.kind,
|
||||||
AudioTrackEvent.kind,
|
AudioTrackEvent.kind,
|
||||||
|
AudioHeaderEvent.kind,
|
||||||
PinListEvent.kind,
|
PinListEvent.kind,
|
||||||
PollNoteEvent.kind,
|
PollNoteEvent.kind,
|
||||||
HighlightEvent.kind
|
HighlightEvent.kind
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.ui.dal
|
|||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
||||||
import com.vitorpamplona.quartz.events.LongTextNoteEvent
|
import com.vitorpamplona.quartz.events.LongTextNoteEvent
|
||||||
import com.vitorpamplona.quartz.events.PrivateDmEvent
|
import com.vitorpamplona.quartz.events.PrivateDmEvent
|
||||||
@@ -32,7 +33,8 @@ class GeoHashFeedFilter(val tag: String, val account: Account) : AdditiveFeedFil
|
|||||||
it.event is TextNoteEvent ||
|
it.event is TextNoteEvent ||
|
||||||
it.event is LongTextNoteEvent ||
|
it.event is LongTextNoteEvent ||
|
||||||
it.event is ChannelMessageEvent ||
|
it.event is ChannelMessageEvent ||
|
||||||
it.event is PrivateDmEvent
|
it.event is PrivateDmEvent ||
|
||||||
|
it.event is AudioHeaderEvent
|
||||||
) &&
|
) &&
|
||||||
it.event?.isTaggedGeoHash(myTag) == true
|
it.event?.isTaggedGeoHash(myTag) == true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.ui.dal
|
|||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
import com.vitorpamplona.quartz.events.ChannelMessageEvent
|
||||||
import com.vitorpamplona.quartz.events.LongTextNoteEvent
|
import com.vitorpamplona.quartz.events.LongTextNoteEvent
|
||||||
import com.vitorpamplona.quartz.events.PrivateDmEvent
|
import com.vitorpamplona.quartz.events.PrivateDmEvent
|
||||||
@@ -32,7 +33,8 @@ class HashtagFeedFilter(val tag: String, val account: Account) : AdditiveFeedFil
|
|||||||
it.event is TextNoteEvent ||
|
it.event is TextNoteEvent ||
|
||||||
it.event is LongTextNoteEvent ||
|
it.event is LongTextNoteEvent ||
|
||||||
it.event is ChannelMessageEvent ||
|
it.event is ChannelMessageEvent ||
|
||||||
it.event is PrivateDmEvent
|
it.event is PrivateDmEvent ||
|
||||||
|
it.event is AudioHeaderEvent
|
||||||
) &&
|
) &&
|
||||||
it.event?.isTaggedHash(myTag) == true
|
it.event?.isTaggedHash(myTag) == true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.vitorpamplona.amethyst.model.Account
|
|||||||
import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS
|
import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
||||||
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
||||||
import com.vitorpamplona.quartz.events.GenericRepostEvent
|
import com.vitorpamplona.quartz.events.GenericRepostEvent
|
||||||
@@ -53,7 +54,7 @@ class HomeNewThreadFeedFilter(val account: Account) : AdditiveFeedFilter<Note>()
|
|||||||
.filter { it ->
|
.filter { it ->
|
||||||
val noteEvent = it.event
|
val noteEvent = it.event
|
||||||
val isGlobalRelay = it.relays.any { gRelays.contains(it) }
|
val isGlobalRelay = it.relays.any { gRelays.contains(it) }
|
||||||
(noteEvent is TextNoteEvent || noteEvent is ClassifiedsEvent || noteEvent is RepostEvent || noteEvent is GenericRepostEvent || noteEvent is LongTextNoteEvent || noteEvent is PollNoteEvent || noteEvent is HighlightEvent || noteEvent is AudioTrackEvent) &&
|
(noteEvent is TextNoteEvent || noteEvent is ClassifiedsEvent || noteEvent is RepostEvent || noteEvent is GenericRepostEvent || noteEvent is LongTextNoteEvent || noteEvent is PollNoteEvent || noteEvent is HighlightEvent || noteEvent is AudioTrackEvent || noteEvent is AudioHeaderEvent) &&
|
||||||
(!ignoreAddressables || noteEvent.kind() < 10000) &&
|
(!ignoreAddressables || noteEvent.kind() < 10000) &&
|
||||||
((isGlobal && isGlobalRelay) || it.author?.pubkeyHex in followingKeySet || noteEvent.isTaggedHashes(followingTagSet) || noteEvent.isTaggedGeoHashes(followingGeoSet) || noteEvent.isTaggedAddressableNotes(followingCommunities)) &&
|
((isGlobal && isGlobalRelay) || it.author?.pubkeyHex in followingKeySet || noteEvent.isTaggedHashes(followingTagSet) || noteEvent.isTaggedGeoHashes(followingGeoSet) || noteEvent.isTaggedAddressableNotes(followingCommunities)) &&
|
||||||
// && account.isAcceptable(it) // This filter follows only. No need to check if acceptable
|
// && account.isAcceptable(it) // This filter follows only. No need to check if acceptable
|
||||||
|
|||||||
+3
-1
@@ -4,6 +4,7 @@ import com.vitorpamplona.amethyst.model.Account
|
|||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
||||||
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
||||||
import com.vitorpamplona.quartz.events.GenericRepostEvent
|
import com.vitorpamplona.quartz.events.GenericRepostEvent
|
||||||
@@ -41,7 +42,8 @@ class UserProfileNewThreadFeedFilter(val user: User, val account: Account) : Add
|
|||||||
it.event is LongTextNoteEvent ||
|
it.event is LongTextNoteEvent ||
|
||||||
it.event is PollNoteEvent ||
|
it.event is PollNoteEvent ||
|
||||||
it.event is HighlightEvent ||
|
it.event is HighlightEvent ||
|
||||||
it.event is AudioTrackEvent
|
it.event is AudioTrackEvent ||
|
||||||
|
it.event is AudioHeaderEvent
|
||||||
) &&
|
) &&
|
||||||
it.isNewThread() &&
|
it.isNewThread() &&
|
||||||
account.isAcceptable(it) == true
|
account.isAcceptable(it) == true
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ import com.vitorpamplona.amethyst.ui.theme.subtleBorder
|
|||||||
import com.vitorpamplona.quartz.encoders.ATag
|
import com.vitorpamplona.quartz.encoders.ATag
|
||||||
import com.vitorpamplona.quartz.encoders.toNpub
|
import com.vitorpamplona.quartz.encoders.toNpub
|
||||||
import com.vitorpamplona.quartz.events.AppDefinitionEvent
|
import com.vitorpamplona.quartz.events.AppDefinitionEvent
|
||||||
|
import com.vitorpamplona.quartz.events.AudioHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
import com.vitorpamplona.quartz.events.AudioTrackEvent
|
||||||
import com.vitorpamplona.quartz.events.BadgeAwardEvent
|
import com.vitorpamplona.quartz.events.BadgeAwardEvent
|
||||||
import com.vitorpamplona.quartz.events.BadgeDefinitionEvent
|
import com.vitorpamplona.quartz.events.BadgeDefinitionEvent
|
||||||
@@ -1045,6 +1046,14 @@ private fun RenderNoteRow(
|
|||||||
RenderAppDefinition(baseNote, accountViewModel, nav)
|
RenderAppDefinition(baseNote, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is AudioTrackEvent -> {
|
||||||
|
RenderAudioTrack(baseNote, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
|
is AudioHeaderEvent -> {
|
||||||
|
RenderAudioHeader(baseNote, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
is ReactionEvent -> {
|
is ReactionEvent -> {
|
||||||
RenderReaction(baseNote, backgroundColor, accountViewModel, nav)
|
RenderReaction(baseNote, backgroundColor, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
@@ -1077,10 +1086,6 @@ private fun RenderNoteRow(
|
|||||||
DisplayRelaySet(baseNote, backgroundColor, accountViewModel, nav)
|
DisplayRelaySet(baseNote, backgroundColor, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
is AudioTrackEvent -> {
|
|
||||||
RenderAudioTrack(baseNote, accountViewModel, nav)
|
|
||||||
}
|
|
||||||
|
|
||||||
is PinListEvent -> {
|
is PinListEvent -> {
|
||||||
RenderPinListEvent(baseNote, backgroundColor, accountViewModel, nav)
|
RenderPinListEvent(baseNote, backgroundColor, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
@@ -2251,6 +2256,17 @@ private fun RenderAudioTrack(
|
|||||||
AudioTrackHeader(noteEvent, note, accountViewModel, nav)
|
AudioTrackHeader(noteEvent, note, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RenderAudioHeader(
|
||||||
|
note: Note,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: (String) -> Unit
|
||||||
|
) {
|
||||||
|
val noteEvent = note.event as? AudioHeaderEvent ?: return
|
||||||
|
|
||||||
|
AudioHeader(noteEvent, note, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RenderLongFormContent(
|
private fun RenderLongFormContent(
|
||||||
note: Note,
|
note: Note,
|
||||||
@@ -3343,8 +3359,7 @@ fun AudioTrackHeader(noteEvent: AudioTrackEvent, note: Note, accountViewModel: A
|
|||||||
|
|
||||||
media?.let { media ->
|
media?.let { media ->
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
modifier = Modifier.padding(10.dp)
|
|
||||||
) {
|
) {
|
||||||
cover?.let { cover ->
|
cover?.let { cover ->
|
||||||
LoadThumbAndThenVideoView(
|
LoadThumbAndThenVideoView(
|
||||||
@@ -3368,6 +3383,62 @@ fun AudioTrackHeader(noteEvent: AudioTrackEvent, note: Note, accountViewModel: A
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AudioHeader(noteEvent: AudioHeaderEvent, note: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
|
val media = remember { noteEvent.stream() ?: noteEvent.download() }
|
||||||
|
val subject = remember { noteEvent.subject()?.ifBlank { null } }
|
||||||
|
val content = remember { noteEvent.content().ifBlank { null } }
|
||||||
|
|
||||||
|
Row(modifier = Modifier.padding(top = 5.dp)) {
|
||||||
|
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
media?.let { media ->
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
VideoView(
|
||||||
|
videoUri = media,
|
||||||
|
title = noteEvent.subject(),
|
||||||
|
authorName = note.author?.toBestDisplayName(),
|
||||||
|
accountViewModel = accountViewModel,
|
||||||
|
nostrUriCallback = note.toNostrUri()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row() {
|
||||||
|
subject?.let {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)) {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row() {
|
||||||
|
content?.let {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)) {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val hashtags = remember(noteEvent) { noteEvent.hashtags().toImmutableList() }
|
||||||
|
DisplayUncitedHashtags(hashtags, content ?: "", nav)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RenderLiveActivityEvent(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun RenderLiveActivityEvent(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
Row(modifier = Modifier.padding(top = 5.dp)) {
|
Row(modifier = Modifier.padding(top = 5.dp)) {
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.vitorpamplona.quartz.events
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||||
|
import com.vitorpamplona.quartz.crypto.CryptoUtils
|
||||||
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
class AudioHeaderEvent(
|
||||||
|
id: HexKey,
|
||||||
|
pubKey: HexKey,
|
||||||
|
createdAt: Long,
|
||||||
|
tags: List<List<String>>,
|
||||||
|
content: String,
|
||||||
|
sig: HexKey
|
||||||
|
) : Event(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||||
|
|
||||||
|
fun download() = tags.firstOrNull { it.size > 1 && it[0] == DOWNLOAD_URL }?.get(1)
|
||||||
|
fun stream() = tags.firstOrNull { it.size > 1 && it[0] == STREAM_URL }?.get(1)
|
||||||
|
fun wavefrom() = tags.firstOrNull { it.size > 1 && it[0] == WAVEFORM }?.get(1)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val kind = 1808
|
||||||
|
|
||||||
|
private const val DOWNLOAD_URL = "download_url"
|
||||||
|
private const val STREAM_URL = "stream_url"
|
||||||
|
private const val WAVEFORM = "waveform"
|
||||||
|
|
||||||
|
fun create(
|
||||||
|
description: String,
|
||||||
|
downloadUrl: String,
|
||||||
|
streamUrl: String? = null,
|
||||||
|
wavefront: String? = null,
|
||||||
|
sensitiveContent: Boolean? = null,
|
||||||
|
privateKey: ByteArray,
|
||||||
|
createdAt: Long = TimeUtils.now()
|
||||||
|
): AudioHeaderEvent {
|
||||||
|
val tags = listOfNotNull(
|
||||||
|
downloadUrl.let { listOf(DOWNLOAD_URL, it) },
|
||||||
|
streamUrl?.let { listOf(STREAM_URL, it) },
|
||||||
|
wavefront?.let { listOf(WAVEFORM, it) },
|
||||||
|
sensitiveContent?.let {
|
||||||
|
if (it) {
|
||||||
|
listOf("content-warning", "")
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val content = description
|
||||||
|
val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey()
|
||||||
|
val id = generateId(pubKey, createdAt, kind, tags, content)
|
||||||
|
val sig = CryptoUtils.sign(id, privateKey)
|
||||||
|
return AudioHeaderEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ class EventFactory {
|
|||||||
AdvertisedRelayListEvent.kind -> AdvertisedRelayListEvent(id, pubKey, createdAt, tags, content, sig)
|
AdvertisedRelayListEvent.kind -> AdvertisedRelayListEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
AppDefinitionEvent.kind -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
|
AppDefinitionEvent.kind -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
AppRecommendationEvent.kind -> AppRecommendationEvent(id, pubKey, createdAt, tags, content, sig)
|
AppRecommendationEvent.kind -> AppRecommendationEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
|
AudioHeaderEvent.kind -> AudioHeaderEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
AudioTrackEvent.kind -> AudioTrackEvent(id, pubKey, createdAt, tags, content, sig)
|
AudioTrackEvent.kind -> AudioTrackEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
BadgeAwardEvent.kind -> BadgeAwardEvent(id, pubKey, createdAt, tags, content, sig)
|
BadgeAwardEvent.kind -> BadgeAwardEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
BadgeDefinitionEvent.kind -> BadgeDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
|
BadgeDefinitionEvent.kind -> BadgeDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
|
|||||||
Reference in New Issue
Block a user