Dropdown menu to copy information from the note.

pull/3/head
Vitor Pamplona 2023-01-13 10:20:54 -05:00
rodzic 9d4f4c67f1
commit 962bd9eb2d
3 zmienionych plików z 57 dodań i 2 usunięć

Wyświetl plik

@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.model
import com.vitorpamplona.amethyst.ui.note.toDisplayHex import com.vitorpamplona.amethyst.ui.note.toDisplayHex
import fr.acinq.secp256k1.Hex import fr.acinq.secp256k1.Hex
import java.util.regex.Pattern import java.util.regex.Pattern
import nostr.postr.Bech32
import nostr.postr.Persona import nostr.postr.Persona
import nostr.postr.bechToBytes import nostr.postr.bechToBytes
import nostr.postr.toHex import nostr.postr.toHex
@ -10,6 +11,8 @@ import nostr.postr.toHex
/** Makes the distinction between String and Hex **/ /** Makes the distinction between String and Hex **/
typealias HexKey = String typealias HexKey = String
fun ByteArray.toNote() = Bech32.encodeBytes(hrp = "note", this, Bech32.Encoding.Bech32)
fun ByteArray.toHexKey(): HexKey { fun ByteArray.toHexKey(): HexKey {
return toHex() return toHex()
} }

Wyświetl plik

@ -1,10 +1,11 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import android.text.format.DateUtils
import android.text.format.DateUtils.getRelativeTimeSpanString import android.text.format.DateUtils.getRelativeTimeSpanString
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -12,38 +13,56 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Divider import androidx.compose.material.Divider
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.toNote
import com.vitorpamplona.amethyst.service.model.ReactionEvent import com.vitorpamplona.amethyst.service.model.ReactionEvent
import com.vitorpamplona.amethyst.service.model.RepostEvent import com.vitorpamplona.amethyst.service.model.RepostEvent
import com.vitorpamplona.amethyst.ui.components.RichTextViewer import com.vitorpamplona.amethyst.ui.components.RichTextViewer
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import nostr.postr.events.TextNoteEvent import nostr.postr.events.TextNoteEvent
import nostr.postr.toNpub
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun NoteCompose(baseNote: Note, modifier: Modifier = Modifier, isInnerNote: Boolean = false, accountViewModel: AccountViewModel, navController: NavController) { fun NoteCompose(baseNote: Note, modifier: Modifier = Modifier, isInnerNote: Boolean = false, accountViewModel: AccountViewModel, navController: NavController) {
val noteState by baseNote.live.observeAsState() val noteState by baseNote.live.observeAsState()
val note = noteState?.note val note = noteState?.note
var popupExpanded by remember { mutableStateOf(false) }
if (note?.event == null) { if (note?.event == null) {
BlankNote(modifier, isInnerNote) BlankNote(modifier, isInnerNote)
} else { } else {
val authorState by note.author!!.live.observeAsState() val authorState by note.author!!.live.observeAsState()
val author = authorState?.user val author = authorState?.user
Column(modifier = modifier.clickable ( onClick = { navController.navigate("Note/${note.idHex}") } )) { Column(modifier =
modifier.combinedClickable(
onClick = { navController.navigate("Note/${note.idHex}") },
onLongClick = { popupExpanded = true },
)
) {
Row( Row(
modifier = Modifier modifier = Modifier
.padding( .padding(
@ -135,8 +154,34 @@ fun NoteCompose(baseNote: Note, modifier: Modifier = Modifier, isInnerNote: Bool
thickness = 0.25.dp thickness = 0.25.dp
) )
} }
NoteDropDownMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel)
} }
} }
} }
} }
}
@Composable
fun NoteDropDownMenu(note: Note, popupExpanded: Boolean, onDismiss: () -> Unit, accountViewModel: AccountViewModel) {
val clipboardManager = LocalClipboardManager.current
DropdownMenu(
expanded = popupExpanded,
onDismissRequest = onDismiss
) {
DropdownMenuItem(onClick = { clipboardManager.setText(AnnotatedString(note.event?.content ?: "")); onDismiss() }) {
Text("Copy Text")
}
DropdownMenuItem(onClick = { clipboardManager.setText(AnnotatedString(note.author?.pubkey?.toNpub() ?: "")); onDismiss() }) {
Text("Copy User ID")
}
DropdownMenuItem(onClick = { clipboardManager.setText(AnnotatedString(note.id.toNote())); onDismiss() }) {
Text("Copy Note ID")
}
Divider()
DropdownMenuItem(onClick = { accountViewModel.broadcast(note); onDismiss() }) {
Text("Broadcast")
}
}
} }

Wyświetl plik

@ -7,6 +7,7 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.AccountState import com.vitorpamplona.amethyst.model.AccountState
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.UserState import com.vitorpamplona.amethyst.model.UserState
import com.vitorpamplona.amethyst.service.relays.Client
class AccountViewModel(private val account: Account): ViewModel() { class AccountViewModel(private val account: Account): ViewModel() {
val accountLiveData: LiveData<AccountState> = Transformations.map(account.live) { it } val accountLiveData: LiveData<AccountState> = Transformations.map(account.live) { it }
@ -19,4 +20,10 @@ class AccountViewModel(private val account: Account): ViewModel() {
fun boost(note: Note) { fun boost(note: Note) {
account.boost(note) account.boost(note)
} }
fun broadcast(note: Note) {
note.event?.let {
Client.send(it)
}
}
} }