kopia lustrzana https://github.com/vitorpamplona/amethyst
Adds a check to see if the receiver has NIP-17 relays setup and if so activates NIP-17 message.
rodzic
fdd1bb9810
commit
f8a77d634c
|
@ -53,6 +53,7 @@ import com.vitorpamplona.quartz.encoders.Hex
|
||||||
import com.vitorpamplona.quartz.encoders.HexKey
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
import com.vitorpamplona.quartz.encoders.toNpub
|
import com.vitorpamplona.quartz.encoders.toNpub
|
||||||
import com.vitorpamplona.quartz.events.AddressableEvent
|
import com.vitorpamplona.quartz.events.AddressableEvent
|
||||||
|
import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.events.BaseTextNoteEvent
|
import com.vitorpamplona.quartz.events.BaseTextNoteEvent
|
||||||
import com.vitorpamplona.quartz.events.ChatMessageEvent
|
import com.vitorpamplona.quartz.events.ChatMessageEvent
|
||||||
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
import com.vitorpamplona.quartz.events.ClassifiedsEvent
|
||||||
|
@ -88,7 +89,7 @@ enum class UserSuggestionAnchor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
open class NewPostViewModel() : ViewModel() {
|
open class NewPostViewModel : ViewModel() {
|
||||||
var draftTag: String by mutableStateOf(UUID.randomUUID().toString())
|
var draftTag: String by mutableStateOf(UUID.randomUUID().toString())
|
||||||
|
|
||||||
var accountViewModel: AccountViewModel? = null
|
var accountViewModel: AccountViewModel? = null
|
||||||
|
@ -175,17 +176,11 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
|
|
||||||
val draftTextChanges = Channel<String>(Channel.CONFLATED)
|
val draftTextChanges = Channel<String>(Channel.CONFLATED)
|
||||||
|
|
||||||
fun lnAddress(): String? {
|
fun lnAddress(): String? = account?.userProfile()?.info?.lnAddress()
|
||||||
return account?.userProfile()?.info?.lnAddress()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun hasLnAddress(): Boolean {
|
fun hasLnAddress(): Boolean = account?.userProfile()?.info?.lnAddress() != null
|
||||||
return account?.userProfile()?.info?.lnAddress() != null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun user(): User? {
|
fun user(): User? = account?.userProfile()
|
||||||
return account?.userProfile()
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun load(
|
open fun load(
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
|
@ -368,15 +363,21 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
originalNote =
|
originalNote =
|
||||||
draftEvent.tags().filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "reply" }.map {
|
draftEvent
|
||||||
LocalCache.checkGetOrCreateNote(it[1])
|
.tags()
|
||||||
}.firstOrNull()
|
.filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "reply" }
|
||||||
|
.map {
|
||||||
|
LocalCache.checkGetOrCreateNote(it[1])
|
||||||
|
}.firstOrNull()
|
||||||
|
|
||||||
if (originalNote == null) {
|
if (originalNote == null) {
|
||||||
originalNote =
|
originalNote =
|
||||||
draftEvent.tags().filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "root" }.map {
|
draftEvent
|
||||||
LocalCache.checkGetOrCreateNote(it[1])
|
.tags()
|
||||||
}.firstOrNull()
|
.filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "root" }
|
||||||
|
.map {
|
||||||
|
LocalCache.checkGetOrCreateNote(it[1])
|
||||||
|
}.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
canUsePoll = originalNote?.event !is PrivateDmEvent && originalNote?.channelHex() == null
|
canUsePoll = originalNote?.event !is PrivateDmEvent && originalNote?.channelHex() == null
|
||||||
|
@ -403,12 +404,45 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
|
|
||||||
wantsProduct = draftEvent.kind() == 30402
|
wantsProduct = draftEvent.kind() == 30402
|
||||||
|
|
||||||
title = TextFieldValue(draftEvent.tags().filter { it.size > 1 && it[0] == "title" }.map { it[1] }?.firstOrNull() ?: "")
|
title =
|
||||||
price = TextFieldValue(draftEvent.tags().filter { it.size > 1 && it[0] == "price" }.map { it[1] }?.firstOrNull() ?: "")
|
TextFieldValue(
|
||||||
category = TextFieldValue(draftEvent.tags().filter { it.size > 1 && it[0] == "t" }.map { it[1] }?.firstOrNull() ?: "")
|
draftEvent
|
||||||
locationText = TextFieldValue(draftEvent.tags().filter { it.size > 1 && it[0] == "location" }.map { it[1] }?.firstOrNull() ?: "")
|
.tags()
|
||||||
|
.filter { it.size > 1 && it[0] == "title" }
|
||||||
|
.map { it[1] }
|
||||||
|
?.firstOrNull() ?: "",
|
||||||
|
)
|
||||||
|
price =
|
||||||
|
TextFieldValue(
|
||||||
|
draftEvent
|
||||||
|
.tags()
|
||||||
|
.filter { it.size > 1 && it[0] == "price" }
|
||||||
|
.map { it[1] }
|
||||||
|
?.firstOrNull() ?: "",
|
||||||
|
)
|
||||||
|
category =
|
||||||
|
TextFieldValue(
|
||||||
|
draftEvent
|
||||||
|
.tags()
|
||||||
|
.filter { it.size > 1 && it[0] == "t" }
|
||||||
|
.map { it[1] }
|
||||||
|
?.firstOrNull() ?: "",
|
||||||
|
)
|
||||||
|
locationText =
|
||||||
|
TextFieldValue(
|
||||||
|
draftEvent
|
||||||
|
.tags()
|
||||||
|
.filter { it.size > 1 && it[0] == "location" }
|
||||||
|
.map { it[1] }
|
||||||
|
?.firstOrNull() ?: "",
|
||||||
|
)
|
||||||
condition = ClassifiedsEvent.CONDITION.entries.firstOrNull {
|
condition = ClassifiedsEvent.CONDITION.entries.firstOrNull {
|
||||||
it.value == draftEvent.tags().filter { it.size > 1 && it[0] == "condition" }.map { it[1] }.firstOrNull()
|
it.value ==
|
||||||
|
draftEvent
|
||||||
|
.tags()
|
||||||
|
.filter { it.size > 1 && it[0] == "condition" }
|
||||||
|
.map { it[1] }
|
||||||
|
.firstOrNull()
|
||||||
} ?: ClassifiedsEvent.CONDITION.USED_LIKE_NEW
|
} ?: ClassifiedsEvent.CONDITION.USED_LIKE_NEW
|
||||||
|
|
||||||
wantsDirectMessage = draftEvent is PrivateDmEvent || draftEvent is ChatMessageEvent
|
wantsDirectMessage = draftEvent is PrivateDmEvent || draftEvent is ChatMessageEvent
|
||||||
|
@ -479,7 +513,8 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
if (split.percentage > 0.00001) {
|
if (split.percentage > 0.00001) {
|
||||||
val homeRelay =
|
val homeRelay =
|
||||||
accountViewModel?.getRelayListFor(split.key)?.writeRelays()?.firstOrNull()
|
accountViewModel?.getRelayListFor(split.key)?.writeRelays()?.firstOrNull()
|
||||||
?: split.key.relaysBeingUsed.keys.firstOrNull { !it.contains("localhost") }
|
?: split.key.relaysBeingUsed.keys
|
||||||
|
.firstOrNull { !it.contains("localhost") }
|
||||||
|
|
||||||
ZapSplitSetup(
|
ZapSplitSetup(
|
||||||
lnAddressOrPubKeyHex = split.key.pubkeyHex,
|
lnAddressOrPubKeyHex = split.key.pubkeyHex,
|
||||||
|
@ -851,9 +886,7 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun findUrlInMessage(): String? {
|
open fun findUrlInMessage(): String? = RichTextParser().parseValidUrls(message.text).firstOrNull()
|
||||||
return RichTextParser().parseValidUrls(message.text).firstOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun removeFromReplyList(userToRemove: User) {
|
open fun removeFromReplyList(userToRemove: User) {
|
||||||
pTags = pTags?.filter { it != userToRemove }
|
pTags = pTags?.filter { it != userToRemove }
|
||||||
|
@ -869,14 +902,18 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
|
|
||||||
if (it.selection.collapsed) {
|
if (it.selection.collapsed) {
|
||||||
val lastWord =
|
val lastWord =
|
||||||
it.text.substring(0, it.selection.end).substringAfterLast("\n").substringAfterLast(" ")
|
it.text
|
||||||
|
.substring(0, it.selection.end)
|
||||||
|
.substringAfterLast("\n")
|
||||||
|
.substringAfterLast(" ")
|
||||||
userSuggestionAnchor = it.selection
|
userSuggestionAnchor = it.selection
|
||||||
userSuggestionsMainMessage = UserSuggestionAnchor.MAIN_MESSAGE
|
userSuggestionsMainMessage = UserSuggestionAnchor.MAIN_MESSAGE
|
||||||
if (lastWord.startsWith("@") && lastWord.length > 2) {
|
if (lastWord.startsWith("@") && lastWord.length > 2) {
|
||||||
NostrSearchEventOrUserDataSource.search(lastWord.removePrefix("@"))
|
NostrSearchEventOrUserDataSource.search(lastWord.removePrefix("@"))
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
userSuggestions =
|
userSuggestions =
|
||||||
LocalCache.findUsersStartingWith(lastWord.removePrefix("@"))
|
LocalCache
|
||||||
|
.findUsersStartingWith(lastWord.removePrefix("@"))
|
||||||
.sortedWith(compareBy({ account?.isFollowing(it) }, { it.toBestDisplayName() }, { it.pubkeyHex }))
|
.sortedWith(compareBy({ account?.isFollowing(it) }, { it.toBestDisplayName() }, { it.pubkeyHex }))
|
||||||
.reversed()
|
.reversed()
|
||||||
}
|
}
|
||||||
|
@ -894,14 +931,18 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
|
|
||||||
if (it.selection.collapsed) {
|
if (it.selection.collapsed) {
|
||||||
val lastWord =
|
val lastWord =
|
||||||
it.text.substring(0, it.selection.end).substringAfterLast("\n").substringAfterLast(" ")
|
it.text
|
||||||
|
.substring(0, it.selection.end)
|
||||||
|
.substringAfterLast("\n")
|
||||||
|
.substringAfterLast(" ")
|
||||||
userSuggestionAnchor = it.selection
|
userSuggestionAnchor = it.selection
|
||||||
userSuggestionsMainMessage = UserSuggestionAnchor.TO_USERS
|
userSuggestionsMainMessage = UserSuggestionAnchor.TO_USERS
|
||||||
if (lastWord.startsWith("@") && lastWord.length > 2) {
|
if (lastWord.startsWith("@") && lastWord.length > 2) {
|
||||||
NostrSearchEventOrUserDataSource.search(lastWord.removePrefix("@"))
|
NostrSearchEventOrUserDataSource.search(lastWord.removePrefix("@"))
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
userSuggestions =
|
userSuggestions =
|
||||||
LocalCache.findUsersStartingWith(lastWord.removePrefix("@"))
|
LocalCache
|
||||||
|
.findUsersStartingWith(lastWord.removePrefix("@"))
|
||||||
.sortedWith(compareBy({ account?.isFollowing(it) }, { it.toBestDisplayName() }, { it.pubkeyHex }))
|
.sortedWith(compareBy({ account?.isFollowing(it) }, { it.toBestDisplayName() }, { it.pubkeyHex }))
|
||||||
.reversed()
|
.reversed()
|
||||||
}
|
}
|
||||||
|
@ -928,15 +969,15 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
NostrSearchEventOrUserDataSource.search(lastWord.removePrefix("@"))
|
NostrSearchEventOrUserDataSource.search(lastWord.removePrefix("@"))
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
userSuggestions =
|
userSuggestions =
|
||||||
LocalCache.findUsersStartingWith(lastWord.removePrefix("@"))
|
LocalCache
|
||||||
|
.findUsersStartingWith(lastWord.removePrefix("@"))
|
||||||
.sortedWith(
|
.sortedWith(
|
||||||
compareBy(
|
compareBy(
|
||||||
{ account?.isFollowing(it) },
|
{ account?.isFollowing(it) },
|
||||||
{ it.toBestDisplayName() },
|
{ it.toBestDisplayName() },
|
||||||
{ it.pubkeyHex },
|
{ it.pubkeyHex },
|
||||||
),
|
),
|
||||||
)
|
).reversed()
|
||||||
.reversed()
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NostrSearchEventOrUserDataSource.clear()
|
NostrSearchEventOrUserDataSource.clear()
|
||||||
|
@ -949,7 +990,10 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
userSuggestionAnchor?.let {
|
userSuggestionAnchor?.let {
|
||||||
if (userSuggestionsMainMessage == UserSuggestionAnchor.MAIN_MESSAGE) {
|
if (userSuggestionsMainMessage == UserSuggestionAnchor.MAIN_MESSAGE) {
|
||||||
val lastWord =
|
val lastWord =
|
||||||
message.text.substring(0, it.end).substringAfterLast("\n").substringAfterLast(" ")
|
message.text
|
||||||
|
.substring(0, it.end)
|
||||||
|
.substringAfterLast("\n")
|
||||||
|
.substringAfterLast(" ")
|
||||||
val lastWordStart = it.end - lastWord.length
|
val lastWordStart = it.end - lastWord.length
|
||||||
val wordToInsert = "@${item.pubkeyNpub()}"
|
val wordToInsert = "@${item.pubkeyNpub()}"
|
||||||
|
|
||||||
|
@ -963,7 +1007,10 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
forwardZapToEditting = TextFieldValue("")
|
forwardZapToEditting = TextFieldValue("")
|
||||||
} else if (userSuggestionsMainMessage == UserSuggestionAnchor.TO_USERS) {
|
} else if (userSuggestionsMainMessage == UserSuggestionAnchor.TO_USERS) {
|
||||||
val lastWord =
|
val lastWord =
|
||||||
toUsers.text.substring(0, it.end).substringAfterLast("\n").substringAfterLast(" ")
|
toUsers.text
|
||||||
|
.substring(0, it.end)
|
||||||
|
.substringAfterLast("\n")
|
||||||
|
.substringAfterLast(" ")
|
||||||
val lastWordStart = it.end - lastWord.length
|
val lastWordStart = it.end - lastWord.length
|
||||||
val wordToInsert = "@${item.pubkeyNpub()}"
|
val wordToInsert = "@${item.pubkeyNpub()}"
|
||||||
|
|
||||||
|
@ -972,6 +1019,9 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
toUsers.text.replaceRange(lastWordStart, it.end, wordToInsert),
|
toUsers.text.replaceRange(lastWordStart, it.end, wordToInsert),
|
||||||
TextRange(lastWordStart + wordToInsert.length, lastWordStart + wordToInsert.length),
|
TextRange(lastWordStart + wordToInsert.length, lastWordStart + wordToInsert.length),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val relayList = (LocalCache.getAddressableNoteIfExists(AdvertisedRelayListEvent.createAddressTag(item.pubkeyHex))?.event as? AdvertisedRelayListEvent)?.readRelays()
|
||||||
|
nip17 = relayList != null
|
||||||
}
|
}
|
||||||
|
|
||||||
userSuggestionAnchor = null
|
userSuggestionAnchor = null
|
||||||
|
@ -982,12 +1032,10 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
saveDraft()
|
saveDraft()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun newStateMapPollOptions(): SnapshotStateMap<Int, String> {
|
private fun newStateMapPollOptions(): SnapshotStateMap<Int, String> = mutableStateMapOf(Pair(0, ""), Pair(1, ""))
|
||||||
return mutableStateMapOf(Pair(0, ""), Pair(1, ""))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun canPost(): Boolean {
|
fun canPost(): Boolean =
|
||||||
return message.text.isNotBlank() &&
|
message.text.isNotBlank() &&
|
||||||
!isUploadingImage &&
|
!isUploadingImage &&
|
||||||
!wantsInvoice &&
|
!wantsInvoice &&
|
||||||
(!wantsZapraiser || zapRaiserAmount != null) &&
|
(!wantsZapraiser || zapRaiserAmount != null) &&
|
||||||
|
@ -1009,7 +1057,6 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
)
|
)
|
||||||
) &&
|
) &&
|
||||||
contentToAddUrl == null
|
contentToAddUrl == null
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun createNIP94Record(
|
suspend fun createNIP94Record(
|
||||||
uploadingResult: Nip96Uploader.PartialEvent,
|
uploadingResult: Nip96Uploader.PartialEvent,
|
||||||
|
@ -1020,11 +1067,20 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
// Images don't seem to be ready immediately after upload
|
// Images don't seem to be ready immediately after upload
|
||||||
val imageUrl = uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "url" }?.get(1)
|
val imageUrl = uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "url" }?.get(1)
|
||||||
val remoteMimeType =
|
val remoteMimeType =
|
||||||
uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "m" }?.get(1)?.ifBlank { null }
|
uploadingResult.tags
|
||||||
|
?.firstOrNull { it.size > 1 && it[0] == "m" }
|
||||||
|
?.get(1)
|
||||||
|
?.ifBlank { null }
|
||||||
val originalHash =
|
val originalHash =
|
||||||
uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "ox" }?.get(1)?.ifBlank { null }
|
uploadingResult.tags
|
||||||
|
?.firstOrNull { it.size > 1 && it[0] == "ox" }
|
||||||
|
?.get(1)
|
||||||
|
?.ifBlank { null }
|
||||||
val dim =
|
val dim =
|
||||||
uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "dim" }?.get(1)?.ifBlank { null }
|
uploadingResult.tags
|
||||||
|
?.firstOrNull { it.size > 1 && it[0] == "dim" }
|
||||||
|
?.get(1)
|
||||||
|
?.ifBlank { null }
|
||||||
val magnet =
|
val magnet =
|
||||||
uploadingResult.tags
|
uploadingResult.tags
|
||||||
?.firstOrNull { it.size > 1 && it[0] == "magnet" }
|
?.firstOrNull { it.size > 1 && it[0] == "magnet" }
|
||||||
|
@ -1270,7 +1326,9 @@ open class NewPostViewModel() : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class GeohashPrecision(val digits: Int) {
|
enum class GeohashPrecision(
|
||||||
|
val digits: Int,
|
||||||
|
) {
|
||||||
KM_5000_X_5000(1), // 5,000km × 5,000km
|
KM_5000_X_5000(1), // 5,000km × 5,000km
|
||||||
KM_1250_X_625(2), // 1,250km × 625km
|
KM_1250_X_625(2), // 1,250km × 625km
|
||||||
KM_156_X_156(3), // 156km × 156km
|
KM_156_X_156(3), // 156km × 156km
|
||||||
|
|
Ładowanie…
Reference in New Issue