mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 11:48:24 +00:00
Massive refactoring of Quartz to:
- Define each tag in their own class. - Allow extension functions to additional responsibilities to other classes - Migrate from hardcoded tag filters in events to the Tag's parser and assemble functions. - Migrate hardcoded event.create to builders that use extension functions - Restructures threading infrastructure for NIP-10 - Decouple the event signing from the Event building functions via event templates - Create classes to represent Tags and TagArrays and use extension functions to add domain-related methods to the tag array of each nip. - Uses external functions on event template builders to better point to which functions and which tags can be used in which event kinds. - Separates Event kinds in packages inside each nip. - Improves support for NIP-89 - Correctly establishes which imeta params can be used in each nip (video, picture, files) - Decouples the iMeta builder from any nip. - Fixes mute list word and user removal when inserted from a different client. - Migrates the Account class to avoiding having to build each Event inside of it
This commit is contained in:
@@ -35,7 +35,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.DEFAULT_MEDIA_SERVERS
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
||||
import com.vitorpamplona.quartz.CryptoUtils
|
||||
import com.vitorpamplona.quartz.nip01Core.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import junit.framework.TestCase.fail
|
||||
|
||||
@@ -23,10 +23,11 @@ package com.vitorpamplona.amethyst
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.vitorpamplona.amethyst.service.ots.OkHttpBlockstreamExplorer
|
||||
import com.vitorpamplona.amethyst.service.ots.OkHttpCalendarBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsResolver
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.ots.OpenTimestamps
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import org.junit.Assert
|
||||
@@ -46,27 +47,27 @@ class OkHttpOtsTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
OtsEvent.otsInstance = OpenTimestamps(OkHttpBlockstreamExplorer(forceProxy = { false }), OkHttpCalendarBuilder(forceProxy = { false }))
|
||||
OtsResolver.ots = OpenTimestamps(OkHttpBlockstreamExplorer(forceProxy = { false }), OkHttpCalendarBuilder(forceProxy = { false }))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyNostrEvent() {
|
||||
val ots = EventMapper.fromJson(otsEvent) as OtsEvent
|
||||
println(ots.info())
|
||||
println(OtsResolver.info(ots.otsByteArray()))
|
||||
assertEquals(1707688818L, ots.verify())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyNostrEvent2() {
|
||||
val ots = EventMapper.fromJson(otsEvent2) as OtsEvent
|
||||
println(ots.info())
|
||||
println(OtsResolver.info(ots.otsByteArray()))
|
||||
assertEquals(1706322179L, ots.verify())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyNostrPendingEvent() {
|
||||
val ots = EventMapper.fromJson(otsPendingEvent) as OtsEvent
|
||||
println(ots.info())
|
||||
println(OtsResolver.info(ots.otsByteArray()))
|
||||
assertEquals(null, ots.verify())
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ class OkHttpOtsTest {
|
||||
|
||||
val otsFile = OtsEvent.stamp(otsEvent2Digest)
|
||||
|
||||
OtsEvent.create(otsEvent2Digest, otsFile, signer) {
|
||||
signer.sign(OtsEvent.build(otsEvent2Digest, otsFile)) {
|
||||
ots = it
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
@@ -87,7 +88,7 @@ class OkHttpOtsTest {
|
||||
Assert.assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
|
||||
|
||||
println(ots!!.toJson())
|
||||
println(ots!!.info())
|
||||
println(OtsResolver.info(ots!!.otsByteArray()))
|
||||
|
||||
// Should not be valid because we need to wait for confirmations
|
||||
assertEquals(null, ots!!.verify())
|
||||
|
||||
@@ -26,11 +26,11 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.ui.dal.ThreadFeedFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.hasValidSignature
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.verify
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -125,7 +125,7 @@ class ThreadAssemblerTest {
|
||||
|
||||
var counter = 0
|
||||
eventArray.forEach {
|
||||
TestCase.assertTrue("${it.id} failed signature check", it.hasValidSignature())
|
||||
TestCase.assertTrue("${it.id} failed signature check", it.verify())
|
||||
LocalCache.verifyAndConsume(it, null)
|
||||
counter++
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.ui.actions.buildAnnotatedStringWithUrlHighlighting
|
||||
import com.vitorpamplona.quartz.nip01Core.UserMetadata
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodePublicKey
|
||||
import org.junit.Assert.assertEquals
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import com.vitorpamplona.amethyst.LocalPreferences
|
||||
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateDMChannel
|
||||
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateZapChannel
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -46,14 +46,14 @@ import com.vitorpamplona.amethyst.ui.tor.TorType
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
|
||||
@@ -58,7 +58,7 @@ import com.vitorpamplona.amethyst.ui.tor.TorManager
|
||||
import com.vitorpamplona.amethyst.ui.tor.TorType
|
||||
import com.vitorpamplona.ammolite.relays.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsResolver
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.ots.OpenTimestamps
|
||||
import com.vitorpamplona.quartz.nip19Bech32.bech32.bechToBytes
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodePublicKeyAsHexOrNull
|
||||
@@ -110,13 +110,13 @@ class ServiceManager(
|
||||
else -> HttpClientManager.setDefaultProxy(null)
|
||||
}
|
||||
|
||||
OtsEvent.otsInstance =
|
||||
OtsResolver.ots =
|
||||
OpenTimestamps(
|
||||
OkHttpBlockstreamExplorer(myAccount::shouldUseTorForMoneyOperations),
|
||||
OkHttpCalendarBuilder(myAccount::shouldUseTorForMoneyOperations),
|
||||
)
|
||||
} else {
|
||||
OtsEvent.otsInstance =
|
||||
OtsResolver.ots =
|
||||
OpenTimestamps(
|
||||
OkHttpBlockstreamExplorer { false },
|
||||
OkHttpCalendarBuilder { false },
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,12 +31,12 @@ import com.vitorpamplona.ammolite.relays.Constants
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
|
||||
@@ -28,12 +28,15 @@ import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder
|
||||
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
||||
import com.vitorpamplona.ammolite.relays.BundledUpdate
|
||||
import com.vitorpamplona.ammolite.relays.Relay
|
||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNAddr
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.ChannelData
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@@ -41,11 +44,23 @@ import kotlinx.coroutines.Dispatchers
|
||||
class PublicChatChannel(
|
||||
idHex: String,
|
||||
) : Channel(idHex) {
|
||||
var info = ChannelCreateEvent.ChannelData(null, null, null)
|
||||
var event: ChannelCreateEvent? = null
|
||||
var info = ChannelData(null, null, null, null)
|
||||
|
||||
override fun relays() = info.relays ?: super.relays()
|
||||
|
||||
fun updateChannelInfo(
|
||||
creator: User,
|
||||
channelInfo: ChannelCreateEvent.ChannelData,
|
||||
channelInfo: ChannelCreateEvent,
|
||||
updatedAt: Long,
|
||||
) {
|
||||
this.event = channelInfo
|
||||
updateChannelInfo(creator, channelInfo.channelInfo(), updatedAt)
|
||||
}
|
||||
|
||||
fun updateChannelInfo(
|
||||
creator: User,
|
||||
channelInfo: ChannelData,
|
||||
updatedAt: Long,
|
||||
) {
|
||||
this.info = channelInfo
|
||||
@@ -76,6 +91,8 @@ class LiveActivitiesChannel(
|
||||
|
||||
fun address() = address
|
||||
|
||||
override fun relays() = info?.allRelayUrls() ?: super.relays()
|
||||
|
||||
fun updateChannelInfo(
|
||||
creator: User,
|
||||
channelInfo: LiveActivitiesEvent,
|
||||
@@ -97,6 +114,10 @@ class LiveActivitiesChannel(
|
||||
.isNotEmpty()
|
||||
}
|
||||
|
||||
data class Counter(
|
||||
var number: Int = 0,
|
||||
)
|
||||
|
||||
@Stable
|
||||
abstract class Channel(
|
||||
val idHex: String,
|
||||
@@ -105,6 +126,7 @@ abstract class Channel(
|
||||
var updatedMetadataAt: Long = 0
|
||||
val notes = LargeCache<HexKey, Note>()
|
||||
var lastNoteCreatedAt: Long = 0
|
||||
private var relays = mapOf<RelayBriefInfoCache.RelayBriefInfo, Counter>()
|
||||
|
||||
open fun id() = Hex.decode(idHex)
|
||||
|
||||
@@ -120,6 +142,14 @@ abstract class Channel(
|
||||
|
||||
open fun profilePicture(): String? = creator?.info?.banner
|
||||
|
||||
open fun relays() =
|
||||
relays.keys
|
||||
.toSortedSet { o1, o2 ->
|
||||
val o1Count = relays[o1]?.number ?: 0
|
||||
val o2Count = relays[o2]?.number ?: 0
|
||||
o2Count.compareTo(o1Count) // descending
|
||||
}.map { it.url }
|
||||
|
||||
open fun updateChannelInfo(
|
||||
creator: User,
|
||||
updatedAt: Long,
|
||||
@@ -130,12 +160,31 @@ abstract class Channel(
|
||||
live.invalidateData()
|
||||
}
|
||||
|
||||
fun addNote(note: Note) {
|
||||
@Synchronized
|
||||
fun addRelaySync(briefInfo: RelayBriefInfoCache.RelayBriefInfo) {
|
||||
if (briefInfo !in relays) {
|
||||
relays = relays + Pair(briefInfo, Counter(1))
|
||||
}
|
||||
}
|
||||
|
||||
fun addNote(
|
||||
note: Note,
|
||||
relay: Relay? = null,
|
||||
) {
|
||||
notes.put(note.idHex, note)
|
||||
|
||||
if ((note.createdAt() ?: 0) > lastNoteCreatedAt) {
|
||||
lastNoteCreatedAt = note.createdAt() ?: 0
|
||||
}
|
||||
|
||||
if (relay != null) {
|
||||
val counter = relays[relay.brief]
|
||||
if (counter != null) {
|
||||
counter.number++
|
||||
} else {
|
||||
addRelaySync(relay.brief)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeNote(note: Note) {
|
||||
|
||||
@@ -31,49 +31,51 @@ import com.vitorpamplona.amethyst.model.observables.LatestByKindWithETag
|
||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.ammolite.relays.BundledInsert
|
||||
import com.vitorpamplona.ammolite.relays.Relay
|
||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||
import com.vitorpamplona.quartz.blossom.BlossomServersEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent
|
||||
import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.FileStorageEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.nns.NNSEvent
|
||||
import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent
|
||||
import com.vitorpamplona.quartz.experimental.relationshipStatus.RelationshipStatusEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.checkSignature
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.tagValueContains
|
||||
import com.vitorpamplona.quartz.nip01Core.hasValidSignature
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.mapTaggedAddress
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.GenericETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.forEachTaggedEventId
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.isTaggedEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.mapTaggedEventId
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUsers
|
||||
import com.vitorpamplona.quartz.nip01Core.verify
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.VerificationState
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodeEventIdAsHexOrNull
|
||||
@@ -82,18 +84,18 @@ import com.vitorpamplona.quartz.nip19Bech32.isATag
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelHideMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMuteUserEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitReplyEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelHideMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMuteUserEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.reply.GitReplyEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
@@ -113,8 +115,8 @@ import com.vitorpamplona.quartz.nip52Calendar.CalendarDateSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.CalendarRSVPEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.CalendarTimeSlotEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
@@ -122,27 +124,28 @@ import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
||||
import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityListEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryRequestEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.FileServersEvent
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.config.FileServersEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -287,7 +290,7 @@ object LocalCache {
|
||||
|
||||
fun getOrCreateNote(event: Event): Note =
|
||||
if (event is AddressableEvent) {
|
||||
getOrCreateAddressableNote(event.address())
|
||||
getOrCreateAddressableNote(event.aTag())
|
||||
} else {
|
||||
getOrCreateNote(event.id)
|
||||
}
|
||||
@@ -301,6 +304,8 @@ object LocalCache {
|
||||
return null
|
||||
}
|
||||
|
||||
fun checkGetOrCreateNote(atag: ATag) = getOrCreateAddressableNote(atag)
|
||||
|
||||
fun checkGetOrCreateNote(key: String): Note? {
|
||||
checkNotInMainThread()
|
||||
|
||||
@@ -312,7 +317,7 @@ object LocalCache {
|
||||
val noteEvent = note.event
|
||||
return if (noteEvent is AddressableEvent) {
|
||||
// upgrade to the latest
|
||||
val newNote = checkGetOrCreateAddressableNote(noteEvent.address().toTag())
|
||||
val newNote = checkGetOrCreateAddressableNote(noteEvent.aTag().toTag())
|
||||
|
||||
if (newNote != null && newNote.event == null) {
|
||||
val author = note.author ?: getOrCreateUser(noteEvent.pubKey)
|
||||
@@ -412,13 +417,18 @@ object LocalCache {
|
||||
return note
|
||||
}
|
||||
|
||||
fun getOrCreateNote(key: ETag): Note {
|
||||
fun getOrCreateNote(key: GenericETag): Note {
|
||||
val note = getOrCreateNote(key.eventId)
|
||||
// Loads the user outside a Syncronized block to avoid blocking
|
||||
val possibleAuthor = key.authorPubKeyHex
|
||||
val possibleAuthor = key.author
|
||||
if (note.author == null && possibleAuthor != null) {
|
||||
note.author = checkGetOrCreateUser(possibleAuthor)
|
||||
}
|
||||
val relayHint = key.relay
|
||||
if (!relayHint.isNullOrBlank()) {
|
||||
val relay = RelayBriefInfoCache.get(RelayUrlFormatter.normalize(relayHint))
|
||||
note.addRelayBrief(relay)
|
||||
}
|
||||
return note
|
||||
}
|
||||
|
||||
@@ -521,7 +531,7 @@ object LocalCache {
|
||||
|
||||
val replyTo = computeReplyTo(event)
|
||||
|
||||
if (event is BaseTextNoteEvent && antiSpam.isSpam(event, relay)) {
|
||||
if (event is BaseThreadedEvent && antiSpam.isSpam(event, relay)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -588,7 +598,7 @@ object LocalCache {
|
||||
relay: Relay?,
|
||||
) {
|
||||
val version = getOrCreateNote(event.id)
|
||||
val note = getOrCreateAddressableNote(event.address())
|
||||
val note = getOrCreateAddressableNote(event.aTag())
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
if (version.event == null) {
|
||||
@@ -622,7 +632,7 @@ object LocalCache {
|
||||
relay: Relay?,
|
||||
) {
|
||||
val version = getOrCreateNote(event.id)
|
||||
val note = getOrCreateAddressableNote(event.address())
|
||||
val note = getOrCreateAddressableNote(event.aTag())
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
if (version.event == null) {
|
||||
@@ -681,7 +691,9 @@ object LocalCache {
|
||||
is GenericRepostEvent ->
|
||||
event.boostedPost().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.taggedAddresses().map { getOrCreateAddressableNote(it) }
|
||||
is CommunityPostApprovalEvent -> event.approvedEvents().mapNotNull { checkGetOrCreateNote(it) }
|
||||
is CommunityPostApprovalEvent ->
|
||||
event.approvedEvents().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.approvedAddresses().map { checkGetOrCreateNote(it) }
|
||||
is ReactionEvent ->
|
||||
event.originalPost().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.taggedAddresses().map { getOrCreateAddressableNote(it) }
|
||||
@@ -691,7 +703,7 @@ object LocalCache {
|
||||
is ChannelMessageEvent ->
|
||||
event
|
||||
.tagsWithoutCitations()
|
||||
.filter { it != event.channel() }
|
||||
.filter { it != event.channelId() }
|
||||
.mapNotNull { checkGetOrCreateNote(it) }
|
||||
is LiveActivitiesChatMessageEvent ->
|
||||
event
|
||||
@@ -718,7 +730,7 @@ object LocalCache {
|
||||
relay: Relay?,
|
||||
) {
|
||||
val version = getOrCreateNote(event.id)
|
||||
val note = getOrCreateAddressableNote(event.address())
|
||||
val note = getOrCreateAddressableNote(event.aTag())
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
if (version.event == null) {
|
||||
@@ -735,7 +747,7 @@ object LocalCache {
|
||||
getOrCreateChannel(note.idHex) { LiveActivitiesChannel(note.address) }
|
||||
as? LiveActivitiesChannel
|
||||
|
||||
val creator = event.host()?.ifBlank { null }?.let { checkGetOrCreateUser(it) } ?: author
|
||||
val creator = event.host()?.let { checkGetOrCreateUser(it.pubKey) } ?: author
|
||||
|
||||
channel?.updateChannelInfo(creator, event, event.createdAt)
|
||||
|
||||
@@ -888,7 +900,7 @@ object LocalCache {
|
||||
relay: Relay?,
|
||||
) {
|
||||
val version = getOrCreateNote(event.id)
|
||||
val note = getOrCreateAddressableNote(event.address())
|
||||
val note = getOrCreateAddressableNote(event.aTag())
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
if (version.event == null) {
|
||||
@@ -945,7 +957,7 @@ object LocalCache {
|
||||
|
||||
fun consume(event: BadgeProfilesEvent) {
|
||||
val version = getOrCreateNote(event.id)
|
||||
val note = getOrCreateAddressableNote(event.address())
|
||||
val note = getOrCreateAddressableNote(event.aTag())
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
if (version.event == null) {
|
||||
@@ -1017,7 +1029,7 @@ object LocalCache {
|
||||
relay: Relay?,
|
||||
) {
|
||||
val version = getOrCreateNote(event.id)
|
||||
val note = getOrCreateAddressableNote(event.address())
|
||||
val note = getOrCreateAddressableNote(event.aTag())
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
val replyTos = computeReplyTo(event)
|
||||
@@ -1182,7 +1194,7 @@ object LocalCache {
|
||||
getChannelIfExists(it.toTag())?.removeNote(deleteNote)
|
||||
}
|
||||
|
||||
(deletedEvent as? TorrentCommentEvent)?.torrent()?.let {
|
||||
(deletedEvent as? TorrentCommentEvent)?.torrentIds()?.let {
|
||||
getNoteIfExists(it)?.removeReply(deleteNote)
|
||||
}
|
||||
|
||||
@@ -1353,14 +1365,17 @@ object LocalCache {
|
||||
refreshObservers(note)
|
||||
}
|
||||
|
||||
fun consume(event: ChannelCreateEvent) {
|
||||
fun consume(
|
||||
event: ChannelCreateEvent,
|
||||
relay: Relay?,
|
||||
) {
|
||||
// Log.d("MT", "New Event ${event.content} ${event.id.toHex()}")
|
||||
val oldChannel = getOrCreateChannel(event.id) { PublicChatChannel(it) }
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
val note = getOrCreateNote(event.id)
|
||||
if (note.event == null) {
|
||||
oldChannel.addNote(note)
|
||||
oldChannel.addNote(note, relay)
|
||||
note.loadEvent(event, author, emptyList())
|
||||
|
||||
refreshObservers(note)
|
||||
@@ -1371,13 +1386,16 @@ object LocalCache {
|
||||
}
|
||||
if (oldChannel.creator == null || oldChannel.creator == author) {
|
||||
if (oldChannel is PublicChatChannel) {
|
||||
oldChannel.updateChannelInfo(author, event.channelInfo(), event.createdAt)
|
||||
oldChannel.updateChannelInfo(author, event, event.createdAt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun consume(event: ChannelMetadataEvent) {
|
||||
val channelId = event.channel()
|
||||
fun consume(
|
||||
event: ChannelMetadataEvent,
|
||||
relay: Relay?,
|
||||
) {
|
||||
val channelId = event.channelId()
|
||||
// Log.d("MT", "New PublicChatMetadata ${event.channelInfo()}")
|
||||
if (channelId.isNullOrBlank()) return
|
||||
|
||||
@@ -1396,7 +1414,7 @@ object LocalCache {
|
||||
|
||||
val note = getOrCreateNote(event.id)
|
||||
if (note.event == null) {
|
||||
oldChannel.addNote(note)
|
||||
oldChannel.addNote(note, relay)
|
||||
note.loadEvent(event, author, emptyList())
|
||||
|
||||
refreshObservers(note)
|
||||
@@ -1407,14 +1425,14 @@ object LocalCache {
|
||||
event: ChannelMessageEvent,
|
||||
relay: Relay?,
|
||||
) {
|
||||
val channelId = event.channel()
|
||||
val channelId = event.channelId()
|
||||
|
||||
if (channelId.isNullOrBlank()) return
|
||||
|
||||
val channel = checkGetOrCreateChannel(channelId) ?: return
|
||||
|
||||
val note = getOrCreateNote(event.id)
|
||||
channel.addNote(note)
|
||||
channel.addNote(note, relay)
|
||||
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
@@ -1457,7 +1475,7 @@ object LocalCache {
|
||||
val channel = getOrCreateChannel(activityId.toTag()) { LiveActivitiesChannel(activityId) }
|
||||
|
||||
val note = getOrCreateNote(event.id)
|
||||
channel.addNote(note)
|
||||
channel.addNote(note, relay)
|
||||
|
||||
val author = getOrCreateUser(event.pubKey)
|
||||
|
||||
@@ -2102,7 +2120,7 @@ object LocalCache {
|
||||
val noteEvent = note.event
|
||||
if (noteEvent is AddressableEvent) {
|
||||
noteEvent.createdAt <
|
||||
(addressables.get(noteEvent.address().toTag())?.event?.createdAt ?: 0)
|
||||
(addressables.get(noteEvent.aTag().toTag())?.event?.createdAt ?: 0)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -2111,7 +2129,7 @@ object LocalCache {
|
||||
val childrenToBeRemoved = mutableListOf<Note>()
|
||||
|
||||
toBeRemoved.forEach {
|
||||
val newerVersion = (it.event as? AddressableEvent)?.address()?.toTag()?.let { tag -> addressables.get(tag) }
|
||||
val newerVersion = (it.event as? AddressableEvent)?.aTag()?.toTag()?.let { tag -> addressables.get(tag) }
|
||||
if (newerVersion != null) {
|
||||
it.moveAllReferencesTo(newerVersion)
|
||||
}
|
||||
@@ -2295,7 +2313,7 @@ object LocalCache {
|
||||
fun justVerify(event: Event): Boolean {
|
||||
checkNotInMainThread()
|
||||
|
||||
return if (!event.hasValidSignature()) {
|
||||
return if (!event.verify()) {
|
||||
try {
|
||||
event.checkSignature()
|
||||
} catch (e: Exception) {
|
||||
@@ -2327,7 +2345,7 @@ object LocalCache {
|
||||
draftWrap: DraftEvent,
|
||||
draft: Event,
|
||||
) {
|
||||
val note = getOrCreateAddressableNote(draftWrap.address())
|
||||
val note = getOrCreateAddressableNote(draftWrap.aTag())
|
||||
val author = getOrCreateUser(draftWrap.pubKey)
|
||||
|
||||
when (draft) {
|
||||
@@ -2378,9 +2396,9 @@ object LocalCache {
|
||||
}
|
||||
}
|
||||
is ChannelMessageEvent -> {
|
||||
draft.channel()?.let { channelId ->
|
||||
draft.channelId()?.let { channelId ->
|
||||
checkGetOrCreateChannel(channelId)?.let { channel ->
|
||||
channel.addNote(note)
|
||||
channel.addNote(note, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2447,7 +2465,7 @@ object LocalCache {
|
||||
}
|
||||
}
|
||||
is ChannelMessageEvent -> {
|
||||
draft.channel()?.let { channelId ->
|
||||
draft.channelId()?.let { channelId ->
|
||||
checkGetOrCreateChannel(channelId)?.let { channel ->
|
||||
channel.removeNote(draftWrap)
|
||||
}
|
||||
@@ -2506,11 +2524,11 @@ object LocalCache {
|
||||
is CalendarDateSlotEvent -> consume(event, relay)
|
||||
is CalendarTimeSlotEvent -> consume(event, relay)
|
||||
is CalendarRSVPEvent -> consume(event, relay)
|
||||
is ChannelCreateEvent -> consume(event)
|
||||
is ChannelCreateEvent -> consume(event, relay)
|
||||
is ChannelListEvent -> consume(event, relay)
|
||||
is ChannelHideMessageEvent -> consume(event)
|
||||
is ChannelMessageEvent -> consume(event, relay)
|
||||
is ChannelMetadataEvent -> consume(event)
|
||||
is ChannelMetadataEvent -> consume(event, relay)
|
||||
is ChannelMuteUserEvent -> consume(event)
|
||||
is ChatMessageEncryptedFileHeaderEvent -> consume(event, relay)
|
||||
is ChatMessageEvent -> consume(event, relay)
|
||||
|
||||
@@ -37,35 +37,40 @@ import com.vitorpamplona.ammolite.relays.BundledUpdate
|
||||
import com.vitorpamplona.ammolite.relays.Relay
|
||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||
import com.vitorpamplona.ammolite.relays.filters.EOSETime
|
||||
import com.vitorpamplona.quartz.experimental.bounties.addedRewardValue
|
||||
import com.vitorpamplona.quartz.experimental.bounties.hasAdditionalReward
|
||||
import com.vitorpamplona.quartz.lightning.LnInvoiceUtil
|
||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.anyHashTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.isTaggedHash
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNAddr
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentRequestEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceSuccessResponse
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.containsAny
|
||||
@@ -108,6 +113,8 @@ class AddressableNote(
|
||||
val thisEvent = event
|
||||
return deletionAddressables.contains(address) || (thisEvent != null && deletionEvents.contains(thisEvent.id))
|
||||
}
|
||||
|
||||
override fun toATag() = ATag.parse(idHex, relayHintUrl())
|
||||
}
|
||||
|
||||
@Stable
|
||||
@@ -195,11 +202,11 @@ open class Note(
|
||||
event is LiveActivitiesChatMessageEvent ||
|
||||
event is LiveActivitiesEvent
|
||||
) {
|
||||
(event as? ChannelMessageEvent)?.channel()
|
||||
?: (event as? ChannelMetadataEvent)?.channel()
|
||||
(event as? ChannelMessageEvent)?.channelId()
|
||||
?: (event as? ChannelMetadataEvent)?.channelId()
|
||||
?: (event as? ChannelCreateEvent)?.id
|
||||
?: (event as? LiveActivitiesChatMessageEvent)?.activity()?.toTag()
|
||||
?: (event as? LiveActivitiesEvent)?.address()?.toTag()
|
||||
?: (event as? LiveActivitiesEvent)?.aTag()?.toTag()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -442,6 +449,13 @@ open class Note(
|
||||
}
|
||||
}
|
||||
|
||||
fun addRelayBrief(brief: RelayBriefInfoCache.RelayBriefInfo) {
|
||||
if (brief !in relays) {
|
||||
addRelaySync(brief)
|
||||
flowSet?.relays?.invalidateData()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun isPaidByCalculation(
|
||||
account: Account,
|
||||
zapEvents: List<Pair<Note, Note?>>,
|
||||
@@ -702,7 +716,7 @@ open class Note(
|
||||
|
||||
fun hasPledgeBy(user: User): Boolean =
|
||||
replies
|
||||
.filter { it.event?.isTaggedHash("bounty-added-reward") ?: false }
|
||||
.filter { it.event?.hasAdditionalReward() ?: false }
|
||||
.any {
|
||||
val pledgeValue =
|
||||
try {
|
||||
@@ -716,18 +730,7 @@ open class Note(
|
||||
pledgeValue != null && it.author == user
|
||||
}
|
||||
|
||||
fun pledgedAmountByOthers(): BigDecimal =
|
||||
replies
|
||||
.filter { it.event?.isTaggedHash("bounty-added-reward") ?: false }
|
||||
.mapNotNull {
|
||||
try {
|
||||
BigDecimal(it.event?.content)
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
null
|
||||
// do nothing if it can't convert to bigdecimal
|
||||
}
|
||||
}.sumOf { it }
|
||||
fun pledgedAmountByOthers(): BigDecimal = replies.sumOf { it.event?.addedRewardValue() ?: BigDecimal.ZERO }
|
||||
|
||||
fun hasAnyReports(): Boolean {
|
||||
val dayAgo = TimeUtils.oneDayAgo()
|
||||
@@ -839,7 +842,7 @@ open class Note(
|
||||
}
|
||||
|
||||
if (accountChoices.hiddenWordsCase.isNotEmpty()) {
|
||||
if (thisEvent is BaseTextNoteEvent && thisEvent.content.containsAny(accountChoices.hiddenWordsCase)) {
|
||||
if (thisEvent is BaseThreadedEvent && thisEvent.content.containsAny(accountChoices.hiddenWordsCase)) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -915,7 +918,46 @@ open class Note(
|
||||
deletionAddressables: Set<ATag>,
|
||||
): Boolean {
|
||||
val thisEvent = event
|
||||
return deletionEvents.contains(idHex) || (thisEvent is AddressableEvent && deletionAddressables.contains(thisEvent.address()))
|
||||
return deletionEvents.contains(idHex) || (thisEvent is AddressableEvent && deletionAddressables.contains(thisEvent.aTag()))
|
||||
}
|
||||
|
||||
fun toETag(): ETag {
|
||||
val noteEvent = event
|
||||
return if (noteEvent != null) {
|
||||
ETag(noteEvent.id, relayHintUrl(), noteEvent.pubKey)
|
||||
} else {
|
||||
ETag(idHex, relayHintUrl(), author?.pubkeyHex)
|
||||
}
|
||||
}
|
||||
|
||||
fun toEId(): EventReference {
|
||||
val noteEvent = event
|
||||
return if (noteEvent != null) {
|
||||
// uses the confirmed event id if available
|
||||
EventReference(noteEvent.id, noteEvent.pubKey, relayHintUrl())
|
||||
} else {
|
||||
EventReference(idHex, author?.pubkeyHex, relayHintUrl())
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Event> toEventHint() = (event as? T)?.let { EventHintBundle(it, relayHintUrl(), author?.bestRelayHint()) }
|
||||
|
||||
fun toMarkedETag(marker: MarkedETag.MARKER): MarkedETag {
|
||||
val noteEvent = event
|
||||
return if (noteEvent != null) {
|
||||
MarkedETag(noteEvent.id, relayHintUrl(), marker, noteEvent.pubKey)
|
||||
} else {
|
||||
MarkedETag(idHex, relayHintUrl(), marker, author?.pubkeyHex)
|
||||
}
|
||||
}
|
||||
|
||||
open fun toATag(): ATag? {
|
||||
val noteEvent = event
|
||||
return if (noteEvent is AddressableEvent) {
|
||||
ATag(noteEvent.kind, noteEvent.pubKey, noteEvent.dTag(), relayHintUrl())
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ class OnlyLatestVersionSet : MutableSet<Note> {
|
||||
return if (element is AddressableNote && loadedCreatedAt != null) {
|
||||
innerAdd(element.address, element, loadedCreatedAt)
|
||||
} else if (noteEvent is AddressableEvent && loadedCreatedAt != null) {
|
||||
innerAdd(noteEvent.address(), element, loadedCreatedAt)
|
||||
innerAdd(noteEvent.aTag(), element, loadedCreatedAt)
|
||||
} else {
|
||||
set.add(element)
|
||||
}
|
||||
@@ -193,7 +193,7 @@ class OnlyLatestVersionSet : MutableSet<Note> {
|
||||
element.address()?.let {
|
||||
map.remove(it)
|
||||
}
|
||||
(element.event as? AddressableEvent)?.address()?.let {
|
||||
(element.event as? AddressableEvent)?.aTag()?.let {
|
||||
map.remove(it)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,14 +33,15 @@ import com.vitorpamplona.ammolite.relays.Relay
|
||||
import com.vitorpamplona.ammolite.relays.filters.EOSETime
|
||||
import com.vitorpamplona.quartz.lightning.Lud06
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.UserMetadata
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.isTaggedGeoHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.isTaggedHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent
|
||||
@@ -86,14 +87,15 @@ class User(
|
||||
|
||||
fun pubkeyDisplayHex() = pubkeyNpub().toShortenHex()
|
||||
|
||||
fun toNProfile(): String {
|
||||
val relayList = (LocalCache.getAddressableNoteIfExists(AdvertisedRelayListEvent.createAddressTag(pubkeyHex))?.event as? AdvertisedRelayListEvent)?.writeRelays()
|
||||
fun authorRelayList() = (LocalCache.getAddressableNoteIfExists(AdvertisedRelayListEvent.createAddressTag(pubkeyHex))?.event as? AdvertisedRelayListEvent)
|
||||
|
||||
return NProfile.create(
|
||||
pubkeyHex,
|
||||
relayList?.take(3) ?: listOfNotNull(latestMetadataRelay),
|
||||
)
|
||||
}
|
||||
fun toNProfile() = NProfile.create(pubkeyHex, relayHints())
|
||||
|
||||
fun relayHints() = authorRelayList()?.writeRelays()?.take(3) ?: listOfNotNull(latestMetadataRelay)
|
||||
|
||||
fun bestRelayHint() = authorRelayList()?.writeRelays()?.firstOrNull() ?: latestMetadataRelay
|
||||
|
||||
fun toPTag() = PTag(pubkeyHex, bestRelayHint())
|
||||
|
||||
fun toNostrUri() = "nostr:${toNProfile()}"
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ abstract class AmethystNostrDataSource(
|
||||
val note = LocalCache.getNoteIfExists(eventId)
|
||||
val noteEvent = note?.event
|
||||
if (noteEvent is AddressableEvent) {
|
||||
LocalCache.getAddressableNoteIfExists(noteEvent.address().toTag())?.addRelay(relay)
|
||||
LocalCache.getAddressableNoteIfExists(noteEvent.aTag().toTag())?.addRelay(relay)
|
||||
} else {
|
||||
note?.addRelay(relay)
|
||||
}
|
||||
|
||||
+10
-10
@@ -36,20 +36,20 @@ import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStory
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitReplyEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.reply.GitReplyEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent
|
||||
@@ -64,12 +64,12 @@ import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.FileServersEvent
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.config.FileServersEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
// TODO: Migrate this to a property of AccountVi
|
||||
|
||||
@@ -27,8 +27,8 @@ import com.vitorpamplona.amethyst.model.PublicChatChannel
|
||||
import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
|
||||
object NostrChannelDataSource : AmethystNostrDataSource("ChatroomFeed") {
|
||||
var account: Account? = null
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
|
||||
object NostrChatroomDataSource : AmethystNostrDataSource("ChatroomFeed") {
|
||||
lateinit var account: Account
|
||||
|
||||
+3
-3
@@ -27,9 +27,9 @@ import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
|
||||
object NostrChatroomListDataSource : AmethystNostrDataSource("MailBoxFeed") {
|
||||
lateinit var account: Account
|
||||
|
||||
+3
-3
@@ -24,8 +24,8 @@ import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
|
||||
object NostrCommunityDataSource : AmethystNostrDataSource("SingleCommunityFeed") {
|
||||
private var communityToWatch: AddressableNote? = null
|
||||
@@ -38,7 +38,7 @@ object NostrCommunityDataSource : AmethystNostrDataSource("SingleCommunityFeed")
|
||||
val authors =
|
||||
community
|
||||
.moderators()
|
||||
.map { it.key }
|
||||
.map { it.pubKey }
|
||||
.plus(listOfNotNull(myCommunityToWatch.author?.pubkeyHex))
|
||||
|
||||
if (authors.isEmpty()) return null
|
||||
|
||||
+8
-8
@@ -27,14 +27,14 @@ import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SinceAuthorPerRelayFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
||||
@@ -23,13 +23,13 @@ package com.vitorpamplona.amethyst.service
|
||||
import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
|
||||
@@ -23,15 +23,15 @@ package com.vitorpamplona.amethyst.service
|
||||
import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
|
||||
@@ -27,22 +27,22 @@ import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SinceAuthorPerRelayFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PinListEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
+9
-10
@@ -24,14 +24,14 @@ import com.vitorpamplona.ammolite.relays.ALL_FEED_TYPES
|
||||
import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent
|
||||
import com.vitorpamplona.quartz.experimental.nns.NNSEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
@@ -44,19 +44,18 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NRelay
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NSec
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parse
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PinListEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
|
||||
+2
-2
@@ -27,8 +27,8 @@ import com.vitorpamplona.ammolite.relays.EVENT_FINDER_TYPES
|
||||
import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
|
||||
object NostrSingleChannelDataSource : AmethystNostrDataSource("SingleChannelFeed") {
|
||||
private var channelsToWatch = setOf<Channel>()
|
||||
|
||||
+3
-3
@@ -35,12 +35,12 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitReplyEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.reply.GitReplyEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent
|
||||
|
||||
|
||||
+2
-2
@@ -26,8 +26,8 @@ import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.EOSETime
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.experimental.relationshipStatus.RelationshipStatusEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
|
||||
+4
-4
@@ -24,12 +24,12 @@ import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
|
||||
import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
@@ -49,7 +49,7 @@ import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent
|
||||
|
||||
object NostrUserProfileDataSource : AmethystNostrDataSource("UserProfileFeed") {
|
||||
var user: User? = null
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SinceAuthorPerRelayFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
|
||||
@@ -32,14 +32,14 @@ import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource.user
|
||||
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceErrorResponse
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.BaseZapSplitSetup
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupLnAddress
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.zapSplitSetup
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -77,7 +77,7 @@ class ZapPaymentHandler(
|
||||
if (!zapSplitSetup.isNullOrEmpty()) {
|
||||
zapSplitSetup
|
||||
} else if (noteEvent is LiveActivitiesEvent && noteEvent.hasHost()) {
|
||||
noteEvent.hosts().map { ZapSplitSetup(it.pubKeyHex, it.relay, weight = 1.0) }
|
||||
noteEvent.hosts().map { ZapSplitSetup(it.pubKey, it.relayHint, weight = 1.0) }
|
||||
} else if (noteEvent is AppDefinitionEvent) {
|
||||
val appLud16 = noteEvent.appMetaData()?.lnAddress()
|
||||
if (appLud16 != null) {
|
||||
|
||||
+6
-6
@@ -37,18 +37,18 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.NostrSignerExternal
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import java.math.BigDecimal
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
@@ -137,7 +137,7 @@ class EventNotificationConsumer(
|
||||
Log.d(TAG, "New Notification Arrived")
|
||||
if (!LocalCache.justVerify(event)) return
|
||||
|
||||
val users = event.taggedUsers().map { LocalCache.getOrCreateUser(it) }
|
||||
val users = event.taggedUserIds().map { LocalCache.getOrCreateUser(it) }
|
||||
val npubs = users.map { it.pubkeyNpub() }.toSet()
|
||||
|
||||
// PushNotification Wraps don't include a receiver.
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@
|
||||
package com.vitorpamplona.amethyst.service.okhttp
|
||||
|
||||
import android.util.Log
|
||||
import com.vitorpamplona.quartz.nip17Dm.AESGCM
|
||||
import com.vitorpamplona.quartz.nip17Dm.NostrCipher
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.AESGCM
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.NostrCipher
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
package com.vitorpamplona.amethyst.service.okhttp
|
||||
|
||||
import android.util.LruCache
|
||||
import com.vitorpamplona.quartz.nip17Dm.NostrCipher
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.NostrCipher
|
||||
|
||||
/**
|
||||
* Neigther ExoPlayer, nor Coil support passing key and nonce to the Interceptor via
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
package com.vitorpamplona.amethyst.service.okhttp
|
||||
|
||||
import android.util.Log
|
||||
import com.vitorpamplona.quartz.nip17Dm.NostrCipher
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.NostrCipher
|
||||
import okhttp3.OkHttpClient
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Proxy
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.service.okhttp
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.sockets.WebSocket
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.sockets.WebSocketListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.sockets.WebsocketBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.sockets.WebsocketBuilderFactory
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.sockets.WebSocket
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.sockets.WebSocketListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.sockets.WebsocketBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.sockets.WebsocketBuilderFactory
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import com.vitorpamplona.quartz.CryptoUtils
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.NostrCipher
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.NostrCipher
|
||||
import java.io.File
|
||||
|
||||
class EncryptFilesResult(
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.vitorpamplona.amethyst.commons.blurhash.toBlurhash
|
||||
import com.vitorpamplona.amethyst.service.Blurhash
|
||||
import com.vitorpamplona.quartz.CryptoUtils
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import java.io.IOException
|
||||
|
||||
@@ -40,7 +40,7 @@ class FileHeader(
|
||||
val mimeType: String?,
|
||||
val hash: String,
|
||||
val size: Int,
|
||||
val dim: Dimension?,
|
||||
val dim: DimensionTag?,
|
||||
val blurHash: Blurhash?,
|
||||
) {
|
||||
class UnableToDownload(
|
||||
@@ -51,7 +51,7 @@ class FileHeader(
|
||||
suspend fun prepare(
|
||||
fileUrl: String,
|
||||
mimeType: String?,
|
||||
dimPrecomputed: Dimension?,
|
||||
dimPrecomputed: DimensionTag?,
|
||||
forceProxy: Boolean,
|
||||
): Result<FileHeader> =
|
||||
try {
|
||||
@@ -71,7 +71,7 @@ class FileHeader(
|
||||
fun prepare(
|
||||
data: ByteArray,
|
||||
mimeType: String?,
|
||||
dimPrecomputed: Dimension?,
|
||||
dimPrecomputed: DimensionTag?,
|
||||
): Result<FileHeader> =
|
||||
try {
|
||||
val hash = CryptoUtils.sha256(data).toHexKey()
|
||||
@@ -82,7 +82,7 @@ class FileHeader(
|
||||
val opt = BitmapFactory.Options()
|
||||
opt.inPreferredConfig = Bitmap.Config.ARGB_8888
|
||||
val mBitmap = BitmapFactory.decodeByteArray(data, 0, data.size, opt)
|
||||
Pair(Blurhash(mBitmap.toBlurhash()), Dimension(mBitmap.width, mBitmap.height))
|
||||
Pair(Blurhash(mBitmap.toBlurhash()), DimensionTag(mBitmap.width, mBitmap.height))
|
||||
} else if (mimeType?.startsWith("video/") == true) {
|
||||
val mediaMetadataRetriever = MediaMetadataRetriever()
|
||||
mediaMetadataRetriever.setDataSource(ByteArrayMediaDataSource(data))
|
||||
@@ -135,12 +135,12 @@ fun MediaMetadataRetriever.getThumbnail(): Bitmap? {
|
||||
}
|
||||
}
|
||||
|
||||
fun MediaMetadataRetriever.prepareDimFromVideo(): Dimension? {
|
||||
fun MediaMetadataRetriever.prepareDimFromVideo(): DimensionTag? {
|
||||
val width = prepareVideoWidth() ?: return null
|
||||
val height = prepareVideoHeight() ?: return null
|
||||
|
||||
return if (width > 0 && height > 0) {
|
||||
Dimension(width, height)
|
||||
DimensionTag(width, height)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@
|
||||
package com.vitorpamplona.amethyst.service.uploads
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
|
||||
data class MediaUploadResult(
|
||||
// A publicly accessible URL to the BUD-01 GET /<sha256> endpoint (optionally with a file extension)
|
||||
@@ -35,7 +35,7 @@ data class MediaUploadResult(
|
||||
// upload time
|
||||
val uploaded: Long? = null,
|
||||
// dimensions
|
||||
val dimension: Dimension? = null,
|
||||
val dimension: DimensionTag? = null,
|
||||
// magnet link
|
||||
val magnet: String? = null,
|
||||
// info hash
|
||||
|
||||
+6
-6
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing
|
||||
import com.vitorpamplona.quartz.nip17Dm.NostrCipher
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.NostrCipher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.joinAll
|
||||
@@ -49,7 +49,7 @@ class MultiOrchestrator(
|
||||
suspend fun upload(
|
||||
scope: CoroutineScope,
|
||||
alt: String?,
|
||||
sensitiveContent: Boolean,
|
||||
contentWarningReason: String?,
|
||||
mediaQuality: CompressorQuality,
|
||||
server: ServerName,
|
||||
account: Account,
|
||||
@@ -62,7 +62,7 @@ class MultiOrchestrator(
|
||||
item.media.uri,
|
||||
item.media.mimeType,
|
||||
alt,
|
||||
sensitiveContent,
|
||||
contentWarningReason,
|
||||
mediaQuality,
|
||||
server,
|
||||
account,
|
||||
@@ -79,7 +79,7 @@ class MultiOrchestrator(
|
||||
suspend fun uploadEncrypted(
|
||||
scope: CoroutineScope,
|
||||
alt: String?,
|
||||
sensitiveContent: Boolean,
|
||||
contentWarningReason: String?,
|
||||
mediaQuality: CompressorQuality,
|
||||
cipher: NostrCipher,
|
||||
server: ServerName,
|
||||
@@ -93,7 +93,7 @@ class MultiOrchestrator(
|
||||
item.media.uri,
|
||||
item.media.mimeType,
|
||||
alt,
|
||||
sensitiveContent,
|
||||
contentWarningReason,
|
||||
mediaQuality,
|
||||
cipher,
|
||||
server,
|
||||
@@ -126,5 +126,5 @@ class MultiOrchestrator(
|
||||
|
||||
fun size() = list.size
|
||||
|
||||
fun get(index: Int) = list.get(index)
|
||||
fun get(index: Int) = list[index]
|
||||
}
|
||||
|
||||
+11
-11
@@ -29,7 +29,7 @@ import com.vitorpamplona.amethyst.service.uploads.blossom.BlossomUploader
|
||||
import com.vitorpamplona.amethyst.service.uploads.nip96.Nip96Uploader
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
||||
import com.vitorpamplona.quartz.nip17Dm.NostrCipher
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.encryption.NostrCipher
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
@@ -132,7 +132,7 @@ class UploadOrchestrator {
|
||||
contentType: String?,
|
||||
size: Long?,
|
||||
alt: String?,
|
||||
sensitiveContent: Boolean,
|
||||
contentWarningReason: String?,
|
||||
serverBaseUrl: String,
|
||||
contentTypeForResult: String?,
|
||||
originalHash: String?,
|
||||
@@ -147,7 +147,7 @@ class UploadOrchestrator {
|
||||
contentType = contentType,
|
||||
size = size,
|
||||
alt = alt,
|
||||
sensitiveContent = if (sensitiveContent) "" else null,
|
||||
sensitiveContent = contentWarningReason,
|
||||
serverBaseUrl = serverBaseUrl,
|
||||
forceProxy = account::shouldUseTorForNIP96,
|
||||
onProgress = { percent: Float ->
|
||||
@@ -175,7 +175,7 @@ class UploadOrchestrator {
|
||||
contentType: String?,
|
||||
size: Long?,
|
||||
alt: String?,
|
||||
sensitiveContent: Boolean,
|
||||
contentWarningReason: String?,
|
||||
serverBaseUrl: String,
|
||||
contentTypeForResult: String?,
|
||||
originalHash: String?,
|
||||
@@ -191,7 +191,7 @@ class UploadOrchestrator {
|
||||
contentType = contentType,
|
||||
size = size,
|
||||
alt = alt,
|
||||
sensitiveContent = if (sensitiveContent) "" else null,
|
||||
sensitiveContent = contentWarningReason,
|
||||
serverBaseUrl = serverBaseUrl,
|
||||
forceProxy = account::shouldUseTorForNIP96,
|
||||
httpAuth = account::createBlossomUploadAuth,
|
||||
@@ -292,7 +292,7 @@ class UploadOrchestrator {
|
||||
uri: Uri,
|
||||
mimeType: String?,
|
||||
alt: String?,
|
||||
sensitiveContent: Boolean,
|
||||
contentWarningReason: String?,
|
||||
compressionQuality: CompressorQuality,
|
||||
server: ServerName,
|
||||
account: Account,
|
||||
@@ -302,8 +302,8 @@ class UploadOrchestrator {
|
||||
|
||||
return when (server.type) {
|
||||
ServerType.NIP95 -> uploadNIP95(compressed.uri, compressed.contentType, null, null, context)
|
||||
ServerType.NIP96 -> uploadNIP96(compressed.uri, compressed.contentType, compressed.size, alt, sensitiveContent, server.baseUrl, null, null, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(compressed.uri, compressed.contentType, compressed.size, alt, sensitiveContent, server.baseUrl, null, null, account, context)
|
||||
ServerType.NIP96 -> uploadNIP96(compressed.uri, compressed.contentType, compressed.size, alt, contentWarningReason, server.baseUrl, null, null, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(compressed.uri, compressed.contentType, compressed.size, alt, contentWarningReason, server.baseUrl, null, null, account, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ class UploadOrchestrator {
|
||||
uri: Uri,
|
||||
mimeType: String?,
|
||||
alt: String?,
|
||||
sensitiveContent: Boolean,
|
||||
contentWarningReason: String?,
|
||||
compressionQuality: CompressorQuality,
|
||||
encrypt: NostrCipher,
|
||||
server: ServerName,
|
||||
@@ -323,8 +323,8 @@ class UploadOrchestrator {
|
||||
|
||||
return when (server.type) {
|
||||
ServerType.NIP95 -> uploadNIP95(encrypted.uri, encrypted.contentType, compressed.contentType, encrypted.originalHash, context)
|
||||
ServerType.NIP96 -> uploadNIP96(encrypted.uri, encrypted.contentType, encrypted.size, alt, sensitiveContent, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(encrypted.uri, encrypted.contentType, encrypted.size, alt, sensitiveContent, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
ServerType.NIP96 -> uploadNIP96(encrypted.uri, encrypted.contentType, encrypted.size, alt, contentWarningReason, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
ServerType.Blossom -> uploadBlossom(encrypted.uri, encrypted.contentType, encrypted.size, alt, contentWarningReason, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-16
@@ -34,13 +34,12 @@ import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager
|
||||
import com.vitorpamplona.amethyst.service.uploads.MediaUploadResult
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.CONTENT_WARNING
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.AuthToken
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.Nip96Result
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.PartialEvent
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.ResultParser
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.ServerInfo
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.actions.DeleteResult
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.actions.PartialEvent
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.actions.UploadResult
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.info.ServerInfo
|
||||
import com.vitorpamplona.quartz.nip98HttpAuth.HTTPAuthorizationEvent
|
||||
import kotlinx.coroutines.delay
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
@@ -153,7 +152,7 @@ class Nip96Uploader {
|
||||
.addFormDataPart("size", length.toString())
|
||||
.also { body ->
|
||||
alt?.ifBlank { null }?.let { body.addFormDataPart("alt", it) }
|
||||
sensitiveContent?.let { body.addFormDataPart(CONTENT_WARNING, it) }
|
||||
sensitiveContent?.let { body.addFormDataPart(ContentWarningTag.TAG_NAME, it) }
|
||||
contentType?.let { body.addFormDataPart("content_type", it) }
|
||||
}.addFormDataPart(
|
||||
"file",
|
||||
@@ -169,7 +168,7 @@ class Nip96Uploader {
|
||||
},
|
||||
).build()
|
||||
|
||||
httpAuth(server.apiUrl, "POST", null)?.let { requestBuilder.addHeader("Authorization", AuthToken().encodeAuth(it)) }
|
||||
httpAuth(server.apiUrl, "POST", null)?.let { requestBuilder.addHeader("Authorization", it.toAuthToken()) }
|
||||
|
||||
requestBuilder
|
||||
.addHeader("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
|
||||
@@ -181,7 +180,7 @@ class Nip96Uploader {
|
||||
client.newCall(request).execute().use { response ->
|
||||
if (response.isSuccessful) {
|
||||
response.body.use { body ->
|
||||
val result = ResultParser().parseResults(body.string())
|
||||
val result = UploadResult.parse(body.string())
|
||||
if (!result.processingUrl.isNullOrBlank()) {
|
||||
return waitProcessing(result, server, forceProxy, onProgress)
|
||||
} else if (result.status == "success") {
|
||||
@@ -244,7 +243,7 @@ class Nip96Uploader {
|
||||
?.firstOrNull { it.size > 1 && it[0] == "dim" }
|
||||
?.get(1)
|
||||
?.ifBlank { null }
|
||||
?.let { Dimension.parse(it) }
|
||||
?.let { DimensionTag.parse(it) }
|
||||
val magnet =
|
||||
nip96.tags
|
||||
?.firstOrNull { it.size > 1 && it[0] == "magnet" }
|
||||
@@ -265,7 +264,7 @@ class Nip96Uploader {
|
||||
contentType: String?,
|
||||
server: ServerInfo,
|
||||
forceProxy: (String) -> Boolean,
|
||||
httpAuth: (String, String, ByteArray?) -> HTTPAuthorizationEvent,
|
||||
httpAuth: (String, String, ByteArray?) -> HTTPAuthorizationEvent?,
|
||||
context: Context,
|
||||
): Boolean {
|
||||
val extension =
|
||||
@@ -275,7 +274,7 @@ class Nip96Uploader {
|
||||
|
||||
val requestBuilder = Request.Builder()
|
||||
|
||||
httpAuth(server.apiUrl, "DELETE", null)?.let { requestBuilder.addHeader("Authorization", AuthToken().encodeAuth(it)) }
|
||||
httpAuth(server.apiUrl, "DELETE", null)?.let { requestBuilder.addHeader("Authorization", it.toAuthToken()) }
|
||||
|
||||
val request =
|
||||
requestBuilder
|
||||
@@ -287,7 +286,7 @@ class Nip96Uploader {
|
||||
client.newCall(request).execute().use { response ->
|
||||
if (response.isSuccessful) {
|
||||
response.body.use { body ->
|
||||
val result = ResultParser().parseDeleteResults(body.string())
|
||||
val result = DeleteResult.parse(body.string())
|
||||
return result.status == "success"
|
||||
}
|
||||
} else {
|
||||
@@ -302,7 +301,7 @@ class Nip96Uploader {
|
||||
}
|
||||
|
||||
private suspend fun waitProcessing(
|
||||
result: Nip96Result,
|
||||
result: UploadResult,
|
||||
server: ServerInfo,
|
||||
forceProxy: (String) -> Boolean,
|
||||
onProgress: (percentage: Float) -> Unit,
|
||||
@@ -324,7 +323,7 @@ class Nip96Uploader {
|
||||
val client = HttpClientManager.getHttpClient(forceProxy(procUrl))
|
||||
client.newCall(request).execute().use {
|
||||
if (it.isSuccessful) {
|
||||
it.body.use { currentResult = ResultParser().parseResults(it.string()) }
|
||||
it.body.use { currentResult = UploadResult.parse(it.string()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -23,8 +23,8 @@ package com.vitorpamplona.amethyst.service.uploads.nip96
|
||||
import android.util.Log
|
||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.ServerInfo
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.ServerInfoParser
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.info.ServerInfo
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.info.ServerInfoParser
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import okhttp3.Request
|
||||
|
||||
|
||||
@@ -55,12 +55,12 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.Note
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@@ -46,10 +46,19 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.experimental.nip95.FileStorageEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
|
||||
import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.alt
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.blurhash
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.dims
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.hash
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.magnet
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.mimeType
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.originalHash
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.sensitiveContent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.size
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -165,7 +174,7 @@ open class EditPostViewModel : ViewModel() {
|
||||
myMultiOrchestrator.upload(
|
||||
viewModelScope,
|
||||
alt,
|
||||
sensitiveContent,
|
||||
if (sensitiveContent) "" else null,
|
||||
MediaCompressor.intToCompressorQuality(mediaQuality),
|
||||
server,
|
||||
myAccount,
|
||||
@@ -175,7 +184,12 @@ open class EditPostViewModel : ViewModel() {
|
||||
if (results.allGood) {
|
||||
results.successful.forEach { state ->
|
||||
if (state.result is UploadOrchestrator.OrchestratorResult.NIP95Result) {
|
||||
account?.createNip95(state.result.bytes, headerInfo = state.result.fileHeader, alt, sensitiveContent) { nip95 ->
|
||||
account?.createNip95(
|
||||
state.result.bytes,
|
||||
headerInfo = state.result.fileHeader,
|
||||
alt,
|
||||
if (sensitiveContent) "" else null,
|
||||
) { nip95 ->
|
||||
nip95attachments = nip95attachments + nip95
|
||||
val note = nip95.let { it1 -> account?.consumeNip95(it1.first, it1.second) }
|
||||
|
||||
|
||||
+41
-12
@@ -26,6 +26,10 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -53,19 +57,44 @@ class NewChannelViewModel : ViewModel() {
|
||||
fun create() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
account?.let { account ->
|
||||
if (originalChannel == null) {
|
||||
account.sendCreateNewChannel(
|
||||
channelName.value.text,
|
||||
channelDescription.value.text,
|
||||
channelPicture.value.text,
|
||||
)
|
||||
val channel = originalChannel
|
||||
if (channel == null) {
|
||||
val template =
|
||||
ChannelCreateEvent.build(
|
||||
channelName.value.text,
|
||||
channelDescription.value.text,
|
||||
channelPicture.value.text,
|
||||
null,
|
||||
)
|
||||
|
||||
account.sendCreateNewChannel(template)
|
||||
} else {
|
||||
account.sendChangeChannel(
|
||||
channelName.value.text,
|
||||
channelDescription.value.text,
|
||||
channelPicture.value.text,
|
||||
originalChannel!!,
|
||||
)
|
||||
val event = channel.event
|
||||
|
||||
val template =
|
||||
if (event != null) {
|
||||
val hint = EventHintBundle<ChannelCreateEvent>(event, channel.relays().firstOrNull())
|
||||
|
||||
ChannelMetadataEvent.build(
|
||||
channelName.value.text,
|
||||
channelDescription.value.text,
|
||||
channelPicture.value.text,
|
||||
null,
|
||||
hint,
|
||||
)
|
||||
} else {
|
||||
val eTag = ETag(channel.idHex, channel.relays().firstOrNull())
|
||||
|
||||
ChannelMetadataEvent.build(
|
||||
channelName.value.text,
|
||||
channelDescription.value.text,
|
||||
channelPicture.value.text,
|
||||
null,
|
||||
eTag,
|
||||
)
|
||||
}
|
||||
|
||||
account.sendChangeChannel(template)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ open class NewMediaModel : ViewModel() {
|
||||
myMultiOrchestrator.upload(
|
||||
viewModelScope,
|
||||
caption,
|
||||
sensitiveContent,
|
||||
if (sensitiveContent) "" else null,
|
||||
MediaCompressor.intToCompressorQuality(mediaQualitySlider),
|
||||
serverToUse,
|
||||
myAccount,
|
||||
@@ -140,7 +140,7 @@ open class NewMediaModel : ViewModel() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
withTimeoutOrNull(30000) {
|
||||
suspendCancellableCoroutine { continuation ->
|
||||
account?.createNip95(it.bytes, headerInfo = it.fileHeader, caption, sensitiveContent) { nip95 ->
|
||||
account?.createNip95(it.bytes, headerInfo = it.fileHeader, caption, if (sensitiveContent) "" else null) { nip95 ->
|
||||
account?.consumeAndSendNip95(nip95.first, nip95.second, relayList)
|
||||
continuation.resume(true)
|
||||
}
|
||||
@@ -160,7 +160,7 @@ open class NewMediaModel : ViewModel() {
|
||||
it.magnet,
|
||||
it.fileHeader,
|
||||
caption,
|
||||
sensitiveContent,
|
||||
if (sensitiveContent) "" else null,
|
||||
it.uploadedHash,
|
||||
relayList,
|
||||
) {
|
||||
@@ -180,7 +180,7 @@ open class NewMediaModel : ViewModel() {
|
||||
account?.sendAllAsOnePictureEvent(
|
||||
imageUrls,
|
||||
caption,
|
||||
sensitiveContent,
|
||||
if (sensitiveContent) "" else null,
|
||||
relayList,
|
||||
) {
|
||||
continuation.resume(true)
|
||||
|
||||
@@ -24,7 +24,7 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
||||
import com.vitorpamplona.quartz.nip19Bech32.bech32.Bech32
|
||||
import com.vitorpamplona.quartz.nip19Bech32.bech32.bechToBytes
|
||||
|
||||
@@ -52,7 +52,7 @@ fun NewPollClosing(pollViewModel: NewPostViewModel) {
|
||||
pollViewModel.isValidClosedAt.value = true
|
||||
if (text.isNotEmpty()) {
|
||||
try {
|
||||
val int = text.toInt()
|
||||
val int = text.toLong()
|
||||
if (int < 0) {
|
||||
pollViewModel.isValidClosedAt.value = false
|
||||
} else {
|
||||
|
||||
+521
-308
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.grayText
|
||||
import com.vitorpamplona.ammolite.relays.Constants
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||
|
||||
@Composable
|
||||
fun AllRelayListView(
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||
|
||||
@Immutable
|
||||
data class BasicRelaySetupInfo(
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ import com.vitorpamplona.ammolite.relays.Constants
|
||||
import com.vitorpamplona.ammolite.relays.Constants.activeTypesGlobalChats
|
||||
import com.vitorpamplona.ammolite.relays.FeedType
|
||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
|
||||
import com.vitorpamplona.amethyst.ui.theme.largeRelayIconModifier
|
||||
import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip01Core.relays.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -77,7 +77,7 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NRelay
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NSec
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNIP19
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
|
||||
@@ -119,8 +119,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size75dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.VolumeBottomIconSize
|
||||
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.videoGalleryModifier
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.tags.WaveformTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
@@ -208,10 +208,10 @@ fun VideoView(
|
||||
roundedCorner: Boolean,
|
||||
gallery: Boolean = false,
|
||||
contentScale: ContentScale,
|
||||
waveform: ImmutableList<Int>? = null,
|
||||
waveform: WaveformTag? = null,
|
||||
artworkUri: String? = null,
|
||||
authorName: String? = null,
|
||||
dimensions: Dimension? = null,
|
||||
dimensions: DimensionTag? = null,
|
||||
blurhash: String? = null,
|
||||
nostrUriCallback: String? = null,
|
||||
onDialog: ((Boolean) -> Unit)? = null,
|
||||
@@ -239,10 +239,10 @@ fun VideoView(
|
||||
thumb: VideoThumb? = null,
|
||||
borderModifier: Modifier,
|
||||
contentScale: ContentScale,
|
||||
waveform: ImmutableList<Int>? = null,
|
||||
waveform: WaveformTag? = null,
|
||||
artworkUri: String? = null,
|
||||
authorName: String? = null,
|
||||
dimensions: Dimension? = null,
|
||||
dimensions: DimensionTag? = null,
|
||||
blurhash: String? = null,
|
||||
nostrUriCallback: String? = null,
|
||||
onDialog: ((Boolean) -> Unit)? = null,
|
||||
@@ -355,7 +355,7 @@ fun VideoViewInner(
|
||||
showControls: Boolean = true,
|
||||
contentScale: ContentScale,
|
||||
borderModifier: Modifier,
|
||||
waveform: ImmutableList<Int>? = null,
|
||||
waveform: WaveformTag? = null,
|
||||
artworkUri: String? = null,
|
||||
authorName: String? = null,
|
||||
nostrUriCallback: String? = null,
|
||||
@@ -732,7 +732,7 @@ private fun RenderVideoPlayer(
|
||||
showControls: Boolean = true,
|
||||
contentScale: ContentScale,
|
||||
nostrUriCallback: String?,
|
||||
waveform: ImmutableList<Int>? = null,
|
||||
waveform: WaveformTag? = null,
|
||||
keepPlaying: MutableState<Boolean>,
|
||||
automaticallyStartPlayback: State<Boolean>,
|
||||
activeOnScreen: MutableState<Boolean>,
|
||||
@@ -863,7 +863,7 @@ private fun pollCurrentDuration(controller: MediaController) =
|
||||
|
||||
@Composable
|
||||
fun Waveform(
|
||||
waveform: ImmutableList<Int>,
|
||||
waveform: WaveformTag,
|
||||
controller: MediaController,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
@@ -897,13 +897,13 @@ fun Waveform(
|
||||
|
||||
@Composable
|
||||
fun DrawWaveform(
|
||||
waveform: ImmutableList<Int>,
|
||||
waveform: WaveformTag,
|
||||
waveformProgress: MutableFloatState,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
AudioWaveformReadOnly(
|
||||
modifier = modifier.padding(start = 10.dp, end = 10.dp),
|
||||
amplitudes = waveform,
|
||||
amplitudes = waveform.wave,
|
||||
progress = waveformProgress.floatValue,
|
||||
progressBrush =
|
||||
Brush.infiniteLinearGradient(
|
||||
|
||||
+3
-3
@@ -97,7 +97,7 @@ import com.vitorpamplona.quartz.CryptoUtils
|
||||
import com.vitorpamplona.quartz.nip01Core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -514,7 +514,7 @@ fun ShowHash(content: MediaUrlContent) {
|
||||
verifiedHash?.let { HashVerificationSymbol(it) }
|
||||
}
|
||||
|
||||
fun aspectRatio(dim: Dimension?): Float? {
|
||||
fun aspectRatio(dim: DimensionTag?): Float? {
|
||||
if (dim == null) return null
|
||||
|
||||
return dim.width.toFloat() / dim.height.toFloat()
|
||||
@@ -641,7 +641,7 @@ fun ShareImageAction(
|
||||
videoUri: String?,
|
||||
postNostrUri: String?,
|
||||
blurhash: String?,
|
||||
dim: Dimension?,
|
||||
dim: DimensionTag?,
|
||||
hash: String?,
|
||||
mimeType: String?,
|
||||
onDismiss: () -> Unit,
|
||||
|
||||
+4
-5
@@ -48,8 +48,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.LoadedBechLink
|
||||
import com.vitorpamplona.amethyst.ui.theme.Font17SP
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size17Modifier
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEmbed
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
@@ -57,11 +55,12 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NRelay
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NSec
|
||||
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class MarkdownMediaRenderer(
|
||||
val startOfText: String,
|
||||
val tags: ImmutableListOfLists<String>?,
|
||||
val imetaByUrl: Map<String, IMetaTag>,
|
||||
val canPreview: Boolean,
|
||||
val quotesLeft: Int,
|
||||
val backgroundColor: MutableState<Color>,
|
||||
@@ -94,7 +93,7 @@ class MarkdownMediaRenderer(
|
||||
val content =
|
||||
parser.createMediaContent(
|
||||
fullUrl = uri,
|
||||
eventTags = tags ?: EmptyTagList,
|
||||
eventTags = imetaByUrl,
|
||||
description = title?.ifEmpty { null } ?: startOfText,
|
||||
) ?: MediaUrlImage(url = uri, description = title?.ifEmpty { null } ?: startOfText)
|
||||
|
||||
@@ -116,7 +115,7 @@ class MarkdownMediaRenderer(
|
||||
uri: String,
|
||||
richTextStringBuilder: RichTextString.Builder,
|
||||
) {
|
||||
val content = parser.createMediaContent(uri, eventTags = tags ?: EmptyTagList, startOfText, callbackUri)
|
||||
val content = parser.createMediaContent(uri, imetaByUrl, startOfText, callbackUri)
|
||||
|
||||
if (canPreview) {
|
||||
if (content != null) {
|
||||
|
||||
+3
-2
@@ -49,10 +49,11 @@ import com.vitorpamplona.amethyst.ui.theme.MarkdownTextStyle
|
||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow
|
||||
import com.vitorpamplona.amethyst.ui.theme.markdownStyle
|
||||
import com.vitorpamplona.amethyst.ui.uriToRoute
|
||||
import com.vitorpamplona.quartz.nip01Core.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip92IMeta.imetasByUrl
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -93,7 +94,7 @@ fun RenderContentAsMarkdown(
|
||||
remember(content) {
|
||||
MarkdownMediaRenderer(
|
||||
startOfText = content.take(100),
|
||||
tags = tags,
|
||||
imetaByUrl = tags?.lists?.imetasByUrl() ?: emptyMap(),
|
||||
canPreview = canPreview,
|
||||
quotesLeft = quotesLeft,
|
||||
backgroundColor = backgroundColor,
|
||||
|
||||
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.dal
|
||||
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
|
||||
class ChatroomFeedFilter(
|
||||
val withUser: ChatroomKey,
|
||||
|
||||
+3
-3
@@ -25,9 +25,9 @@ import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.actions.relays.updated
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
|
||||
class ChatroomListKnownFeedFilter(
|
||||
val account: Account,
|
||||
|
||||
+2
-2
@@ -24,8 +24,8 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.actions.relays.updated
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
|
||||
class ChatroomListNewFeedFilter(
|
||||
val account: Account,
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.isTaggedAddressableNote
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
|
||||
class CommunityFeedFilter(
|
||||
val note: AddressableNote,
|
||||
|
||||
@@ -24,8 +24,8 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.IsInPublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.IsInPublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
|
||||
@@ -85,7 +85,7 @@ open class DiscoverChatFeedFilter(
|
||||
null
|
||||
}
|
||||
} else if (noteEvent is IsInPublicChatChannel) {
|
||||
val channel = noteEvent.channel()?.let { LocalCache.checkGetOrCreateNote(it) }
|
||||
val channel = noteEvent.channelId()?.let { LocalCache.checkGetOrCreateNote(it) }
|
||||
val channelEvent = channel?.event
|
||||
|
||||
if (channel != null &&
|
||||
|
||||
+2
-2
@@ -27,8 +27,8 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parseAtagUnckecked
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
|
||||
open class DiscoverCommunityFeedFilter(
|
||||
val account: Account,
|
||||
|
||||
@@ -26,10 +26,8 @@ import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.ParticipantListBuilder
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_ENDED
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_LIVE
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_PLANNED
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.StatusTag
|
||||
|
||||
open class DiscoverLiveFeedFilter(
|
||||
val account: Account,
|
||||
@@ -93,9 +91,9 @@ open class DiscoverLiveFeedFilter(
|
||||
|
||||
fun convertStatusToOrder(status: String?): Int =
|
||||
when (status) {
|
||||
STATUS_LIVE -> 2
|
||||
STATUS_PLANNED -> 1
|
||||
STATUS_ENDED -> 0
|
||||
StatusTag.STATUS.LIVE.code -> 2
|
||||
StatusTag.STATUS.PLANNED.code -> 1
|
||||
StatusTag.STATUS.ENDED.code -> 0
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
open class DiscoverNIP89FeedFilter(
|
||||
@@ -76,7 +76,7 @@ open class DiscoverNIP89FeedFilter(
|
||||
val filterParams = buildFilterParams(account)
|
||||
return noteEvent.appMetaData()?.subscription != true &&
|
||||
filterParams.match(noteEvent) &&
|
||||
noteEvent.includeKind("5300") &&
|
||||
noteEvent.includeKind(5300) &&
|
||||
noteEvent.createdAt > TimeUtils.now() - lastAnnounced // && params.match(noteEvent)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.hashtags.isTaggedHashes
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
class FilterByListParams(
|
||||
|
||||
@@ -23,13 +23,13 @@ package com.vitorpamplona.amethyst.ui.dal
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.isTaggedGeoHash
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
|
||||
class GeoHashFeedFilter(
|
||||
|
||||
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.dal
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.isTaggedHash
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
@@ -31,7 +31,7 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
|
||||
class HashtagFeedFilter(
|
||||
|
||||
+2
-2
@@ -27,10 +27,10 @@ import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
|
||||
class HomeConversationsFeedFilter(
|
||||
val account: Account,
|
||||
|
||||
@@ -23,8 +23,8 @@ package com.vitorpamplona.amethyst.ui.dal
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
|
||||
@@ -23,23 +23,25 @@ package com.vitorpamplona.amethyst.ui.dal
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.experimental.forks.forkFromVersion
|
||||
import com.vitorpamplona.quartz.experimental.forks.isForkFromAddressWithPubkey
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent
|
||||
@@ -138,13 +140,13 @@ class NotificationFeedFilter(
|
||||
return true
|
||||
}
|
||||
|
||||
if (event is BaseTextNoteEvent) {
|
||||
if (event is BaseThreadedEvent) {
|
||||
if (note.replyTo?.any { it.author?.pubkeyHex == authorHex } == true) return true
|
||||
|
||||
val isAuthoredPostCited = event.findCitations().any { LocalCache.getNoteIfExists(it)?.author?.pubkeyHex == authorHex }
|
||||
val isAuthorDirectlyCited = event.citedUsers().contains(authorHex)
|
||||
val isAuthorOfAFork =
|
||||
event.isForkFromAddressWithPubkey(authorHex) || (event.forkFromVersion()?.let { LocalCache.getNoteIfExists(it)?.author?.pubkeyHex == authorHex } == true)
|
||||
event.isForkFromAddressWithPubkey(authorHex) || (event.forkFromVersion()?.let { LocalCache.getNoteIfExists(it.eventId)?.author?.pubkeyHex == authorHex } == true)
|
||||
|
||||
return isAuthoredPostCited || isAuthorDirectlyCited || isAuthorOfAFork
|
||||
}
|
||||
|
||||
+3
-2
@@ -23,7 +23,8 @@ package com.vitorpamplona.amethyst.ui.dal
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent
|
||||
|
||||
class UserProfileAppRecommendationsFeedFilter(
|
||||
val user: User,
|
||||
@@ -47,7 +48,7 @@ class UserProfileAppRecommendationsFeedFilter(
|
||||
val noteEvent = it.event
|
||||
if (noteEvent is AppRecommendationEvent) {
|
||||
if (noteEvent.pubKey == user.pubkeyHex) {
|
||||
return noteEvent.recommendations().map { LocalCache.getOrCreateAddressableNote(it) }
|
||||
return noteEvent.recommendations().map { LocalCache.getOrCreateAddressableNote(ATag(it.address)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -27,9 +27,9 @@ import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
|
||||
class UserProfileConversationsFeedFilter(
|
||||
val user: User,
|
||||
|
||||
+2
-2
@@ -25,8 +25,8 @@ import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.service.SUPPORTED_VIDEO_FEED_MIME_TYPES_SET
|
||||
import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
|
||||
@@ -27,15 +27,15 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.IsInPublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.IsInPublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
import java.net.URLEncoder
|
||||
|
||||
@@ -56,11 +56,11 @@ fun routeFor(
|
||||
val innerEvent = noteEvent.preCachedDraft(loggedIn.pubkeyHex)
|
||||
|
||||
if (innerEvent is IsInPublicChatChannel) {
|
||||
innerEvent.channel()?.let {
|
||||
innerEvent.channelId()?.let {
|
||||
return "Channel/$it"
|
||||
}
|
||||
} else if (innerEvent is LiveActivitiesEvent) {
|
||||
innerEvent.address().toTag().let {
|
||||
innerEvent.aTag().toTag().let {
|
||||
return "Channel/${URLEncoder.encode(it, "utf-8")}"
|
||||
}
|
||||
} else if (innerEvent is LiveActivitiesChatMessageEvent) {
|
||||
@@ -72,20 +72,20 @@ fun routeFor(
|
||||
loggedIn.createChatroom(room)
|
||||
return "Room/${room.hashCode()}"
|
||||
} else if (innerEvent is AddressableEvent) {
|
||||
return "Note/${URLEncoder.encode(noteEvent.address().toTag(), "utf-8")}"
|
||||
return "Note/${URLEncoder.encode(noteEvent.aTag().toTag(), "utf-8")}"
|
||||
} else {
|
||||
return "Note/${URLEncoder.encode(noteEvent.id, "utf-8")}"
|
||||
}
|
||||
} else if (noteEvent is AppDefinitionEvent) {
|
||||
return "ContentDiscovery/${noteEvent.id}"
|
||||
} else if (noteEvent is IsInPublicChatChannel) {
|
||||
noteEvent.channel()?.let {
|
||||
noteEvent.channelId()?.let {
|
||||
return "Channel/$it"
|
||||
}
|
||||
} else if (noteEvent is ChannelCreateEvent) {
|
||||
return "Channel/${noteEvent.id}"
|
||||
} else if (noteEvent is LiveActivitiesEvent) {
|
||||
noteEvent.address().toTag().let {
|
||||
noteEvent.aTag().toTag().let {
|
||||
return "Channel/${URLEncoder.encode(it, "utf-8")}"
|
||||
}
|
||||
} else if (noteEvent is LiveActivitiesChatMessageEvent) {
|
||||
@@ -97,9 +97,9 @@ fun routeFor(
|
||||
loggedIn.createChatroom(room)
|
||||
return "Room/${room.hashCode()}"
|
||||
} else if (noteEvent is CommunityDefinitionEvent) {
|
||||
return "Community/${URLEncoder.encode(noteEvent.address().toTag(), "utf-8")}"
|
||||
return "Community/${URLEncoder.encode(noteEvent.aTag().toTag(), "utf-8")}"
|
||||
} else if (noteEvent is AddressableEvent) {
|
||||
return "Note/${URLEncoder.encode(noteEvent.address().toTag(), "utf-8")}"
|
||||
return "Note/${URLEncoder.encode(noteEvent.aTag().toTag(), "utf-8")}"
|
||||
} else {
|
||||
return "Note/${URLEncoder.encode(noteEvent.id, "utf-8")}"
|
||||
}
|
||||
|
||||
@@ -102,16 +102,15 @@ import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.bitcoinColor
|
||||
import com.vitorpamplona.amethyst.ui.theme.grayText
|
||||
import com.vitorpamplona.amethyst.ui.theme.nip05
|
||||
import com.vitorpamplona.quartz.experimental.audio.Participant
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_ENDED
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_LIVE
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_PLANNED
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ParticipantTag
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.StatusTag
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.Price
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.tags.PriceTag
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -295,7 +294,7 @@ private fun RenderNoteRow(
|
||||
data class ClassifiedsThumb(
|
||||
val image: String?,
|
||||
val title: String?,
|
||||
val price: Price?,
|
||||
val price: PriceTag?,
|
||||
)
|
||||
|
||||
@Composable
|
||||
@@ -339,7 +338,7 @@ fun RenderClassifiedsThumbPreview() {
|
||||
ClassifiedsThumb(
|
||||
image = null,
|
||||
title = "Like New",
|
||||
price = Price("800000", "SATS", null),
|
||||
price = PriceTag("800000", "SATS", null),
|
||||
),
|
||||
note = Note("hex"),
|
||||
)
|
||||
@@ -416,7 +415,7 @@ data class LiveActivityCard(
|
||||
val media: String?,
|
||||
val subject: String?,
|
||||
val content: String?,
|
||||
val participants: ImmutableList<Participant>,
|
||||
val participants: ImmutableList<ParticipantTag>,
|
||||
val status: String?,
|
||||
val starts: Long?,
|
||||
)
|
||||
@@ -485,7 +484,7 @@ fun RenderLiveActivityThumb(
|
||||
Box(Modifier.padding(10.dp)) {
|
||||
CrossfadeIfEnabled(targetState = card.status, label = "RenderLiveActivityThumb", accountViewModel = accountViewModel) {
|
||||
when (it) {
|
||||
STATUS_LIVE -> {
|
||||
StatusTag.STATUS.LIVE.code -> {
|
||||
val url = card.media
|
||||
if (url.isNullOrBlank()) {
|
||||
LiveFlag()
|
||||
@@ -499,10 +498,10 @@ fun RenderLiveActivityThumb(
|
||||
}
|
||||
}
|
||||
}
|
||||
STATUS_ENDED -> {
|
||||
StatusTag.STATUS.ENDED.code -> {
|
||||
EndedFlag()
|
||||
}
|
||||
STATUS_PLANNED -> {
|
||||
StatusTag.STATUS.PLANNED.code -> {
|
||||
ScheduledFlag(card.starts)
|
||||
}
|
||||
else -> {
|
||||
@@ -544,7 +543,7 @@ data class CommunityCard(
|
||||
val name: String,
|
||||
val description: String?,
|
||||
val cover: String?,
|
||||
val moderators: ImmutableList<Participant>,
|
||||
val moderators: ImmutableList<HexKey>,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
@@ -574,16 +573,16 @@ fun RenderCommunitiesThumb(
|
||||
CommunityCard(
|
||||
name = noteEvent?.dTag() ?: "",
|
||||
description = noteEvent?.description(),
|
||||
cover = noteEvent?.image()?.ifBlank { null },
|
||||
moderators = noteEvent?.moderators()?.toImmutableList() ?: persistentListOf(),
|
||||
cover = noteEvent?.image()?.imageUrl,
|
||||
moderators = noteEvent?.moderatorKeys()?.toImmutableList() ?: persistentListOf(),
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
.observeAsState(
|
||||
CommunityCard(
|
||||
name = noteEvent.dTag(),
|
||||
description = noteEvent.description(),
|
||||
cover = noteEvent.image()?.ifBlank { null },
|
||||
moderators = noteEvent.moderators().toImmutableList(),
|
||||
cover = noteEvent.image()?.imageUrl,
|
||||
moderators = noteEvent.moderatorKeys().toImmutableList(),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -655,7 +654,7 @@ fun RenderCommunitiesThumb(
|
||||
|
||||
@Composable
|
||||
fun LoadModerators(
|
||||
moderators: ImmutableList<Participant>,
|
||||
moderators: ImmutableList<String>,
|
||||
baseNote: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
content: @Composable (ImmutableList<User>) -> Unit,
|
||||
@@ -670,8 +669,8 @@ fun LoadModerators(
|
||||
launch(Dispatchers.IO) {
|
||||
val hosts =
|
||||
moderators.mapNotNull { part ->
|
||||
if (part.key != baseNote.author?.pubkeyHex) {
|
||||
LocalCache.checkGetOrCreateUser(part.key)
|
||||
if (part != baseNote.author?.pubkeyHex) {
|
||||
LocalCache.checkGetOrCreateUser(part)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -706,7 +705,7 @@ fun LoadModerators(
|
||||
|
||||
@Composable
|
||||
private fun LoadParticipants(
|
||||
participants: ImmutableList<Participant>,
|
||||
participants: ImmutableList<ParticipantTag>,
|
||||
baseNote: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
inner: @Composable (ImmutableList<User>) -> Unit,
|
||||
@@ -721,8 +720,8 @@ private fun LoadParticipants(
|
||||
launch(Dispatchers.IO) {
|
||||
val hosts =
|
||||
participants.mapNotNull { part ->
|
||||
if (part.key != baseNote.author?.pubkeyHex) {
|
||||
LocalCache.checkGetOrCreateUser(part.key)
|
||||
if (part.pubKey != baseNote.author?.pubkeyHex) {
|
||||
LocalCache.checkGetOrCreateUser(part.pubKey)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.NoteDropDownMenu
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.MessageSetCard
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdStartPadding
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@@ -53,7 +54,7 @@ fun MessageSetCompose(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val baseNote = remember { messageSetCard.note }
|
||||
val baseNote = messageSetCard.note
|
||||
|
||||
val popupExpanded = remember { mutableStateOf(false) }
|
||||
val enablePopup = remember { { popupExpanded.value = true } }
|
||||
@@ -90,15 +91,9 @@ fun MessageSetCompose(
|
||||
|
||||
Column(columnModifier) {
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Box(
|
||||
modifier = remember { Modifier.width(55.dp).padding(top = 5.dp, end = 5.dp) },
|
||||
) {
|
||||
MessageIcon(
|
||||
remember { Modifier.size(16.dp).align(Alignment.TopEnd) },
|
||||
)
|
||||
}
|
||||
MessageIconBox()
|
||||
|
||||
Column(modifier = remember { Modifier.padding(start = 10.dp) }) {
|
||||
Column(modifier = StdStartPadding) {
|
||||
NoteCompose(
|
||||
baseNote = baseNote,
|
||||
routeForLastRead = null,
|
||||
@@ -117,3 +112,10 @@ fun MessageSetCompose(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MessageIconBox() {
|
||||
Box(Modifier.width(55.dp).padding(top = 5.dp, end = 5.dp)) {
|
||||
MessageIcon(Modifier.size(16.dp).align(Alignment.TopEnd))
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.lessImportantLink
|
||||
import com.vitorpamplona.amethyst.ui.theme.nip05
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip01Core.UserMetadata
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.firstTaggedAddress
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
|
||||
@@ -149,36 +149,36 @@ import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
||||
import com.vitorpamplona.amethyst.ui.theme.normalWithTopMarginNoteModifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.amethyst.ui.theme.replyModifier
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.bounties.getReward
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.bounties.bountyBaseReward
|
||||
import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent
|
||||
import com.vitorpamplona.quartz.experimental.forks.isAFork
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent
|
||||
import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.isTaggedAddressableKind
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.getGeoHash
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip13Pow.pow
|
||||
import com.vitorpamplona.quartz.nip13Pow.strongPoWOrNull
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
@@ -186,8 +186,8 @@ import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PinListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.RelaySetEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.hasZapSplitSetup
|
||||
@@ -198,10 +198,10 @@ import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
@@ -963,7 +963,7 @@ fun SecondUserInfoRow(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = UserNameMaxRowHeight,
|
||||
) {
|
||||
if (noteEvent is BaseTextNoteEvent && noteEvent.isAFork()) {
|
||||
if (noteEvent is BaseThreadedEvent && noteEvent.isAFork()) {
|
||||
ShowForkInformation(noteEvent, remember(noteEvent) { Modifier.weight(1f) }, accountViewModel, nav)
|
||||
} else {
|
||||
ObserveDisplayNip05Status(noteAuthor, remember(noteEvent) { Modifier.weight(1f) }, accountViewModel, nav)
|
||||
@@ -975,7 +975,7 @@ fun SecondUserInfoRow(
|
||||
DisplayLocation(geo, nav)
|
||||
}
|
||||
|
||||
val baseReward = remember(noteEvent) { noteEvent.getReward()?.let { Reward(it) } }
|
||||
val baseReward = remember(noteEvent) { noteEvent.bountyBaseReward()?.let { Reward(it) } }
|
||||
if (baseReward != null) {
|
||||
Spacer(StdHorzSpacer)
|
||||
DisplayReward(baseReward, note, accountViewModel, nav)
|
||||
|
||||
@@ -95,8 +95,8 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.WarningColor
|
||||
import com.vitorpamplona.amethyst.ui.theme.isLight
|
||||
import com.vitorpamplona.amethyst.ui.theme.secondaryButtonBackground
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.bounties.getReward
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.bounties.bountyBaseReward
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNAddr
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
@@ -124,7 +124,7 @@ val njumpLink = { nip19BechAddress: String ->
|
||||
|
||||
val externalLinkForNote = { note: Note ->
|
||||
if (note is AddressableNote) {
|
||||
if (note.event?.getReward() != null) {
|
||||
if (note.event?.bountyBaseReward() != null) {
|
||||
"https://nostrbounties.com/b/${note.address().toNAddr()}"
|
||||
} else if (note.event is PeopleListEvent) {
|
||||
"https://listr.lol/a/${note.address().toNAddr()}"
|
||||
|
||||
@@ -97,7 +97,7 @@ import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
@@ -124,7 +124,7 @@ fun PollNotePreview() {
|
||||
arrayOf("poll_option", "2", "OP3"),
|
||||
arrayOf("value_maximum", "2"),
|
||||
arrayOf("value_minimum", "2"),
|
||||
AltTagSerializer.toTagArray("Poll event"),
|
||||
arrayOf("alt", "Poll event"),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -196,7 +196,7 @@ fun PollNotePreview2() {
|
||||
arrayOf("poll_option", "1", "Pesquisa em ingles"),
|
||||
arrayOf("value_maximum", "2"),
|
||||
arrayOf("value_minimum", "2"),
|
||||
AltTagSerializer.toTagArray("Poll event"),
|
||||
AltTag.assemble("Poll event"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -28,11 +28,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.CLOSED_AT
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.CONSENSUS_THRESHOLD
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.VALUE_MAXIMUM
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.VALUE_MINIMUM
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -81,17 +77,12 @@ class PollNoteViewModel : ViewModel() {
|
||||
pollNote = note
|
||||
pollEvent = pollNote?.event as PollNoteEvent
|
||||
pollOptions = pollEvent?.pollOptions()
|
||||
valueMaximum = pollEvent?.getTagLong(VALUE_MAXIMUM)
|
||||
valueMinimum = pollEvent?.getTagLong(VALUE_MINIMUM)
|
||||
valueMaximum = pollEvent?.maxAmount()
|
||||
valueMinimum = pollEvent?.minAmount()
|
||||
valueMinimumBD = valueMinimum?.let { BigDecimal(it) }
|
||||
valueMaximumBD = valueMaximum?.let { BigDecimal(it) }
|
||||
consensusThreshold =
|
||||
pollEvent
|
||||
?.getTagLong(CONSENSUS_THRESHOLD)
|
||||
?.toFloat()
|
||||
?.div(100)
|
||||
?.toBigDecimal()
|
||||
closedAt = pollEvent?.getTagLong(CLOSED_AT)
|
||||
consensusThreshold = pollEvent?.consensusThreshold()?.toBigDecimal()
|
||||
closedAt = pollEvent?.closedAt()
|
||||
|
||||
totalZapped = BigDecimal.ZERO
|
||||
wasZappedByLoggedInAccount = false
|
||||
|
||||
@@ -147,7 +147,7 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.amethyst.ui.theme.reactionBox
|
||||
import com.vitorpamplona.amethyst.ui.theme.ripple24dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.selectedReactionBoxModifier
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
@@ -579,7 +579,7 @@ private fun BoostWithDialog(
|
||||
val replyTo =
|
||||
remember(wantsToFork) {
|
||||
val forkEvent = wantsToFork?.event
|
||||
if (forkEvent is BaseTextNoteEvent) {
|
||||
if (forkEvent is BaseThreadedEvent) {
|
||||
val hex = forkEvent.replyingTo()
|
||||
wantsToFork?.replyTo?.filter { it.event?.id == hex }?.firstOrNull()
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
||||
+6
-6
@@ -89,8 +89,8 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -116,7 +116,7 @@ class UpdateReactionTypeViewModel : ViewModel() {
|
||||
nextChoice = TextFieldValue("")
|
||||
}
|
||||
|
||||
fun addChoice(customEmoji: EmojiUrl) {
|
||||
fun addChoice(customEmoji: EmojiUrlTag) {
|
||||
reactionSet = reactionSet + (customEmoji.encode())
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ private fun RenderReactionOption(
|
||||
private fun EmojiSelector(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
onClick: ((EmojiUrl) -> Unit)? = null,
|
||||
onClick: ((EmojiUrlTag) -> Unit)? = null,
|
||||
) {
|
||||
LoadAddressableNote(
|
||||
aTag =
|
||||
@@ -372,7 +372,7 @@ fun EmojiCollectionGallery(
|
||||
emojiCollections: ImmutableList<ATag>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
onClick: ((EmojiUrl) -> Unit)? = null,
|
||||
onClick: ((EmojiUrlTag) -> Unit)? = null,
|
||||
) {
|
||||
val color = MaterialTheme.colorScheme.background
|
||||
val bgColor = remember { mutableStateOf(color) }
|
||||
@@ -396,7 +396,7 @@ private fun WatchAndRenderNote(
|
||||
bgColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
onClick: ((EmojiUrl) -> Unit)?,
|
||||
onClick: ((EmojiUrlTag) -> Unit)?,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
|
||||
@Composable
|
||||
fun NoteAuthorPicture(
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.getTagOfAddressableKind
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
|
||||
@Composable
|
||||
fun DisplayFollowingCommunityInPost(
|
||||
|
||||
+10
-15
@@ -177,24 +177,19 @@ class AddBountyAmountViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun sendPost() {
|
||||
val newValue = nextAmount.text.trim().toLongOrNull()
|
||||
val newValue = nextAmount.text.trim().toBigDecimalOrNull()
|
||||
|
||||
if (newValue != null) {
|
||||
viewModelScope.launch {
|
||||
account?.let {
|
||||
it.sendPost(
|
||||
message = newValue.toString(),
|
||||
replyTo = listOfNotNull(bounty),
|
||||
mentions = listOfNotNull(bounty?.author),
|
||||
tags = listOf("bounty-added-reward"),
|
||||
wantsToMarkAsSensitive = false,
|
||||
replyingTo = null,
|
||||
root = null,
|
||||
directMentions = setOf(),
|
||||
forkedFrom = null,
|
||||
draftTag = null,
|
||||
relayList = it.activeWriteRelays().toImmutableList(),
|
||||
)
|
||||
account?.let { myAccount ->
|
||||
bounty?.let { bountyInner ->
|
||||
myAccount.sendAddBounty(
|
||||
newValue,
|
||||
bountyInner,
|
||||
draftTag = null,
|
||||
relayList = myAccount.activeWriteRelays().toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
nextAmount = TextFieldValue("")
|
||||
|
||||
@@ -45,11 +45,13 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Font14SP
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.nip05
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.experimental.forks.forkFromAddress
|
||||
import com.vitorpamplona.quartz.experimental.forks.forkFromVersion
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
|
||||
@Composable
|
||||
fun ShowForkInformation(
|
||||
noteEvent: BaseTextNoteEvent,
|
||||
noteEvent: BaseThreadedEvent,
|
||||
modifier: Modifier,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
@@ -66,7 +68,7 @@ fun ShowForkInformation(
|
||||
}
|
||||
}
|
||||
} else if (forkedEvent != null) {
|
||||
LoadNote(forkedEvent, accountViewModel = accountViewModel) { event ->
|
||||
LoadNote(forkedEvent.eventId, accountViewModel = accountViewModel) { event ->
|
||||
if (event != null) {
|
||||
ForkInformationRowLightColor(event, modifier, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.AppMetadata
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppMetadata
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
||||
@@ -51,15 +51,12 @@ import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.Participant
|
||||
import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent
|
||||
import com.vitorpamplona.quartz.experimental.audio.track.tags.ParticipantTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags
|
||||
import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists
|
||||
import com.vitorpamplona.quartz.nip14Subject.subject
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun RenderAudioTrack(
|
||||
@@ -84,10 +81,9 @@ fun AudioTrackHeader(
|
||||
val media = remember { noteEvent.media() }
|
||||
val cover = remember { noteEvent.cover() }
|
||||
val subject = remember { noteEvent.subject() }
|
||||
val content = remember { noteEvent.content }
|
||||
val participants = remember { noteEvent.participants() }
|
||||
|
||||
var participantUsers by remember { mutableStateOf<List<Pair<Participant, User>>>(emptyList()) }
|
||||
var participantUsers by remember { mutableStateOf<List<Pair<ParticipantTag, User>>>(emptyList()) }
|
||||
|
||||
LaunchedEffect(key1 = participants) {
|
||||
accountViewModel.loadParticipants(participants) { participantUsers = it }
|
||||
@@ -129,13 +125,6 @@ fun AudioTrackHeader(
|
||||
Spacer(Modifier.width(5.dp))
|
||||
UsernameDisplay(it.second, Modifier.weight(1f), accountViewModel = accountViewModel)
|
||||
Spacer(Modifier.width(5.dp))
|
||||
it.first.role?.let {
|
||||
Text(
|
||||
text = it.capitalize(Locale.ROOT),
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +182,7 @@ fun AudioHeader(
|
||||
nav: INav,
|
||||
) {
|
||||
val media = remember { noteEvent.stream() ?: noteEvent.download() }
|
||||
val waveform = remember { noteEvent.wavefrom()?.toImmutableList()?.ifEmpty { null } }
|
||||
val waveform = remember { noteEvent.wavefrom() }
|
||||
val content = remember { noteEvent.content.ifBlank { null } }
|
||||
|
||||
val defaultBackground = MaterialTheme.colorScheme.background
|
||||
|
||||
@@ -155,7 +155,7 @@ fun RenderBadgeAward(
|
||||
|
||||
Text(text = stringRes(R.string.award_granted_to))
|
||||
|
||||
LaunchedEffect(key1 = note) { accountViewModel.loadUsers(noteEvent.awardees()) { awardees = it } }
|
||||
LaunchedEffect(key1 = note) { accountViewModel.loadUsers(noteEvent.awardeeIds()) { awardees = it } }
|
||||
|
||||
FlowRow(modifier = Modifier.padding(top = 5.dp)) {
|
||||
awardees.take(100).forEach { user ->
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.ChannelHeader
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.replyModifier
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
|
||||
@Composable
|
||||
fun RenderChannelMessage(
|
||||
@@ -53,7 +53,7 @@ fun RenderChannelMessage(
|
||||
val showChannelInfo =
|
||||
remember(noteEvent) {
|
||||
if (noteEvent is ChannelMessageEvent) {
|
||||
noteEvent.channel()
|
||||
noteEvent.channelId()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user