Making NewPost Screen to be about Kind 1 and polls only
This commit is contained in:
@@ -94,8 +94,8 @@ import com.vitorpamplona.amethyst.ui.note.creators.uploads.ImageVideoDescription
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList
|
||||
import com.vitorpamplona.amethyst.ui.painterRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.UserSuggestionState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
||||
|
||||
@@ -70,10 +70,10 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.contentWarning.SettingSwitchItem
|
||||
import com.vitorpamplona.amethyst.ui.painterRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size5dp
|
||||
|
||||
@@ -41,13 +41,13 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import kotlinx.coroutines.CancellationException
|
||||
|
||||
@Composable
|
||||
fun NewPollClosing(pollViewModel: NewPostViewModel) {
|
||||
fun NewPollClosing(pollViewModel: ShortNotePostViewModel) {
|
||||
var text by rememberSaveable { mutableStateOf("") }
|
||||
|
||||
pollViewModel.isValidClosedAt.value = true
|
||||
@@ -106,5 +106,5 @@ fun NewPollClosing(pollViewModel: NewPostViewModel) {
|
||||
@Preview
|
||||
@Composable
|
||||
fun NewPollClosingPreview() {
|
||||
NewPollClosing(NewPostViewModel())
|
||||
NewPollClosing(ShortNotePostViewModel())
|
||||
}
|
||||
|
||||
+3
-3
@@ -41,13 +41,13 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import kotlinx.coroutines.CancellationException
|
||||
|
||||
@Composable
|
||||
fun NewPollConsensusThreshold(pollViewModel: NewPostViewModel) {
|
||||
fun NewPollConsensusThreshold(pollViewModel: ShortNotePostViewModel) {
|
||||
var text by rememberSaveable { mutableStateOf("") }
|
||||
|
||||
pollViewModel.isValidConsensusThreshold.value = true
|
||||
@@ -106,5 +106,5 @@ fun NewPollConsensusThreshold(pollViewModel: NewPostViewModel) {
|
||||
@Preview
|
||||
@Composable
|
||||
fun NewPollConsensusThresholdPreview() {
|
||||
NewPollConsensusThreshold(NewPostViewModel())
|
||||
NewPollConsensusThreshold(ShortNotePostViewModel())
|
||||
}
|
||||
|
||||
@@ -35,12 +35,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
@Composable
|
||||
fun NewPollOption(
|
||||
pollViewModel: NewPostViewModel,
|
||||
pollViewModel: ShortNotePostViewModel,
|
||||
optionIndex: Int,
|
||||
) {
|
||||
Row {
|
||||
@@ -90,5 +91,5 @@ fun NewPollOption(
|
||||
@Preview
|
||||
@Composable
|
||||
fun NewPollOptionPreview() {
|
||||
NewPollOption(NewPostViewModel(), 0)
|
||||
NewPollOption(ShortNotePostViewModel(), 0)
|
||||
}
|
||||
|
||||
+2
-2
@@ -41,14 +41,14 @@ import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||
import androidx.compose.ui.text.style.TextDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.actions.UrlUserTagTransformation
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun NewPollPrimaryDescription(pollViewModel: NewPostViewModel) {
|
||||
fun NewPollPrimaryDescription(pollViewModel: ShortNotePostViewModel) {
|
||||
// initialize focus reference to be able to request focus programmatically
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
|
||||
+2
-2
@@ -28,13 +28,13 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
@Composable
|
||||
fun NewPollRecipientsField(
|
||||
pollViewModel: NewPostViewModel,
|
||||
pollViewModel: ShortNotePostViewModel,
|
||||
account: Account,
|
||||
) {
|
||||
// if no recipients, add user's pubkey
|
||||
|
||||
+3
-2
@@ -39,12 +39,13 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
@Composable
|
||||
fun NewPollVoteValueRange(pollViewModel: NewPostViewModel) {
|
||||
fun NewPollVoteValueRange(pollViewModel: ShortNotePostViewModel) {
|
||||
val colorInValid =
|
||||
OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = MaterialTheme.colorScheme.error,
|
||||
@@ -122,6 +123,6 @@ fun NewPollVoteValueRangePreview() {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
NewPollVoteValueRange(NewPostViewModel())
|
||||
NewPollVoteValueRange(ShortNotePostViewModel())
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -54,8 +54,8 @@ import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.MinHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
|
||||
+2
-2
@@ -52,8 +52,8 @@ import com.vitorpamplona.amethyst.service.Nip11Retriever
|
||||
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationDialog
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
|
||||
+2
-2
@@ -59,8 +59,8 @@ import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategoryWithButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
|
||||
@@ -55,7 +55,6 @@ import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.SharedPreferencesViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountSwitcherAndLeftDrawerLayout
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.NewPostScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.BookmarkListScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.ChatroomByAuthorScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.ChatroomScreen
|
||||
@@ -75,6 +74,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.geohash.GeoHashScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.HashtagPostScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.HashtagScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.HomeScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.NotificationScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.privacy.PrivacyOptionsScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.ProfileScreen
|
||||
@@ -193,7 +193,7 @@ fun AppNavigation(
|
||||
}
|
||||
|
||||
composableFromBottomArgs<Route.NewPost> {
|
||||
NewPostScreen(
|
||||
ShortNotePostScreen(
|
||||
message = it.message,
|
||||
attachment = it.attachment?.ifBlank { null }?.toUri(),
|
||||
baseReplyTo = it.baseReplyTo?.let { hex -> accountViewModel.getNoteIfExists(hex) },
|
||||
|
||||
+2
-2
@@ -86,8 +86,8 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.ui.note.types.RenderEmojiPack
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
|
||||
@@ -88,10 +88,10 @@ import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.ui.painterRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.getFragmentActivity
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.SimpleQrCodeScanner
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
|
||||
@@ -67,9 +67,9 @@ import com.vitorpamplona.amethyst.service.ZapPaymentHandler
|
||||
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
||||
import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
|
||||
+2
-2
@@ -32,13 +32,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPollOption
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPollVoteValueRange
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.painterRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size18Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
@Composable
|
||||
fun PollField(postViewModel: NewPostViewModel) {
|
||||
fun PollField(postViewModel: ShortNotePostViewModel) {
|
||||
val optionsList = postViewModel.pollOptions
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
||||
@@ -65,8 +65,8 @@ import com.vitorpamplona.amethyst.ui.note.ZapIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.ZappedIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.showAmount
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
+1
-1
@@ -43,7 +43,6 @@ import com.vitorpamplona.amethyst.service.uploads.MediaCompressor
|
||||
import com.vitorpamplona.amethyst.service.uploads.MultiOrchestrator
|
||||
import com.vitorpamplona.amethyst.service.uploads.UploadOrchestrator
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger
|
||||
import com.vitorpamplona.amethyst.ui.actions.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing
|
||||
@@ -59,6 +58,7 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.SplitBuilder
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.toZapSplitSetup
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.IMetaAttachments
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent
|
||||
|
||||
+3
-3
@@ -84,9 +84,9 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapTo
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapToButton
|
||||
import com.vitorpamplona.amethyst.ui.painterRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.Notifying
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.Notifying
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||
|
||||
+2
-2
@@ -49,8 +49,8 @@ import androidx.compose.ui.window.DialogProperties
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
|
||||
+1
-1
@@ -40,7 +40,6 @@ import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.service.location.LocationState
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger
|
||||
import com.vitorpamplona.amethyst.ui.actions.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.DEFAULT_MEDIA_SERVERS
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.draftTags.DraftTagState
|
||||
@@ -58,6 +57,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.upload
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.upload.ChatFileUploader
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.upload.SuccessfulUploads
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.ChatFileUploadState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.UserSuggestionAnchor
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.getGeoHash
|
||||
|
||||
+2
-2
@@ -115,9 +115,9 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapraiser.ZapRaiserRequest
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapTo
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapToButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.upload.SuccessfulUploads
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.Font14SP
|
||||
|
||||
+2
-2
@@ -53,8 +53,8 @@ import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.JoinButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.JoinButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
|
||||
+3
-3
@@ -60,9 +60,9 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadChannel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CreateButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CreateButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
|
||||
+1
-1
@@ -48,7 +48,6 @@ import com.vitorpamplona.amethyst.service.location.LocationState
|
||||
import com.vitorpamplona.amethyst.service.uploads.MediaCompressor
|
||||
import com.vitorpamplona.amethyst.service.uploads.UploadOrchestrator
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger
|
||||
import com.vitorpamplona.amethyst.ui.actions.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.DEFAULT_MEDIA_SERVERS
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.draftTags.DraftTagState
|
||||
@@ -59,6 +58,7 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.SplitBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.IMetaAttachments
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.ChatFileUploadState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.experimental.ephemChat.chat.EphemeralChatEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
||||
|
||||
+2
-2
@@ -88,8 +88,8 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapTo
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapToButton
|
||||
import com.vitorpamplona.amethyst.ui.painterRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.PostButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||
|
||||
+1
-1
@@ -44,7 +44,6 @@ import com.vitorpamplona.amethyst.service.uploads.MediaCompressor
|
||||
import com.vitorpamplona.amethyst.service.uploads.MultiOrchestrator
|
||||
import com.vitorpamplona.amethyst.service.uploads.UploadOrchestrator
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger
|
||||
import com.vitorpamplona.amethyst.ui.actions.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing
|
||||
@@ -60,6 +59,7 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.SplitBuilder
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.toZapSplitSetup
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.IMetaAttachments
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.UserSuggestionAnchor
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
|
||||
+234
-232
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.home
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -61,10 +61,8 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -76,13 +74,13 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.util.Consumer
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUser
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
|
||||
import com.vitorpamplona.amethyst.ui.actions.RelaySelectionDialog
|
||||
import com.vitorpamplona.amethyst.ui.actions.RelaySelectionDialogEasy
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||
@@ -117,6 +115,7 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapraiser.ZapRaiserRequest
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapTo
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.ForwardZapToButton
|
||||
import com.vitorpamplona.amethyst.ui.painterRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
@@ -138,15 +137,11 @@ import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, FlowPreview::class)
|
||||
@Composable
|
||||
fun NewPostScreen(
|
||||
fun ShortNotePostScreen(
|
||||
message: String? = null,
|
||||
attachment: Uri? = null,
|
||||
baseReplyTo: Note? = null,
|
||||
@@ -157,28 +152,12 @@ fun NewPostScreen(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: Nav,
|
||||
) {
|
||||
val postViewModel: NewPostViewModel = viewModel()
|
||||
val postViewModel: ShortNotePostViewModel = viewModel()
|
||||
postViewModel.init(accountViewModel)
|
||||
|
||||
val context = LocalContext.current
|
||||
val activity = context.getActivity()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
val scope = rememberCoroutineScope()
|
||||
var showRelaysDialog by remember { mutableStateOf(false) }
|
||||
var relayList = remember { accountViewModel.account.activeWriteRelays().toImmutableList() }
|
||||
|
||||
LaunchedEffect(key1 = postViewModel.draftTag) {
|
||||
launch(Dispatchers.IO) {
|
||||
postViewModel.draftTextChanges
|
||||
.receiveAsFlow()
|
||||
.debounce(1000)
|
||||
.collectLatest {
|
||||
postViewModel.sendDraft(relayList = relayList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
launch(Dispatchers.IO) {
|
||||
postViewModel.load(baseReplyTo, quote, fork, version, draft)
|
||||
@@ -194,7 +173,6 @@ fun NewPostScreen(
|
||||
|
||||
DisposableEffect(nav, activity) {
|
||||
// Microsoft's swift key sends Gifs as new actions
|
||||
|
||||
val consumer =
|
||||
Consumer<Intent> { intent ->
|
||||
if (intent.action == Intent.ACTION_SEND) {
|
||||
@@ -213,6 +191,18 @@ fun NewPostScreen(
|
||||
onDispose { activity.removeOnNewIntentListener(consumer) }
|
||||
}
|
||||
|
||||
NewPostScreenInner(postViewModel, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun NewPostScreenInner(
|
||||
postViewModel: ShortNotePostViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: Nav,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
WatchAndLoadMyEmojiList(accountViewModel)
|
||||
|
||||
Scaffold(
|
||||
@@ -222,14 +212,14 @@ fun NewPostScreen(
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
verticalAlignment = CenterVertically,
|
||||
) {
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
|
||||
Box {
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
onClick = { showRelaysDialog = true },
|
||||
onClick = { postViewModel.showRelaysDialog = true },
|
||||
) {
|
||||
Icon(
|
||||
painter = painterRes(R.drawable.relays),
|
||||
@@ -241,8 +231,10 @@ fun NewPostScreen(
|
||||
}
|
||||
PostButton(
|
||||
onPost = {
|
||||
postViewModel.sendPost(relayList = relayList)
|
||||
scope.launch {
|
||||
// uses the accountViewModel scope to avoid cancelling this
|
||||
// function when the postViewModel is released
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||
postViewModel.sendPostSync()
|
||||
delay(100)
|
||||
nav.popBack()
|
||||
}
|
||||
@@ -256,13 +248,12 @@ fun NewPostScreen(
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
CloseButton(
|
||||
onPress = {
|
||||
scope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
postViewModel.sendDraftSync(relayList = relayList)
|
||||
postViewModel.cancel()
|
||||
}
|
||||
delay(100)
|
||||
// uses the accountViewModel scope to avoid cancelling this
|
||||
// function when the postViewModel is released
|
||||
accountViewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||
postViewModel.sendDraftSync()
|
||||
nav.popBack()
|
||||
postViewModel.cancel()
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -275,11 +266,11 @@ fun NewPostScreen(
|
||||
)
|
||||
},
|
||||
) { pad ->
|
||||
if (showRelaysDialog) {
|
||||
RelaySelectionDialog(
|
||||
preSelectedList = relayList,
|
||||
onClose = { showRelaysDialog = false },
|
||||
onPost = { relayList = it },
|
||||
if (postViewModel.showRelaysDialog) {
|
||||
RelaySelectionDialogEasy(
|
||||
preSelectedList = postViewModel.relayList ?: persistentListOf(),
|
||||
onClose = { postViewModel.showRelaysDialog = false },
|
||||
onPost = { postViewModel.relayList = it.map { it.url }.toImmutableList() },
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
@@ -291,199 +282,210 @@ fun NewPostScreen(
|
||||
.consumeWindowInsets(pad)
|
||||
.imePadding(),
|
||||
) {
|
||||
Column(
|
||||
modifier =
|
||||
Modifier.fillMaxSize(),
|
||||
) {
|
||||
Row(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = Size10dp,
|
||||
end = Size10dp,
|
||||
).weight(1f),
|
||||
) {
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(scrollState),
|
||||
) {
|
||||
postViewModel.originalNote?.let {
|
||||
Row {
|
||||
NoteCompose(
|
||||
baseNote = it,
|
||||
modifier = MaterialTheme.colorScheme.replyModifier,
|
||||
isQuotedNote = true,
|
||||
unPackReply = false,
|
||||
makeItShort = true,
|
||||
quotesLeft = 1,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
Notifying(postViewModel.pTags?.toImmutableList(), accountViewModel) {
|
||||
postViewModel.removeFromReplyList(it)
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(vertical = Size10dp),
|
||||
) {
|
||||
BaseUserPicture(
|
||||
accountViewModel.userProfile(),
|
||||
Size35dp,
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
MessageField(
|
||||
R.string.what_s_on_your_mind,
|
||||
postViewModel,
|
||||
)
|
||||
}
|
||||
|
||||
if (postViewModel.wantsPoll) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
PollField(postViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
DisplayPreviews(postViewModel, accountViewModel, nav)
|
||||
|
||||
if (postViewModel.wantsToMarkAsSensitive) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
ContentSensitivityExplainer()
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsToAddGeoHash) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
LocationAsHash(postViewModel) {
|
||||
SettingsRow(
|
||||
R.string.geohash_exclusive,
|
||||
R.string.geohash_exclusive_explainer,
|
||||
) {
|
||||
Switch(postViewModel.wantsExclusiveGeoPost, onCheckedChange = { postViewModel.wantsExclusiveGeoPost = it })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsForwardZapTo) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(top = Size5dp, bottom = Size5dp, start = Size10dp),
|
||||
) {
|
||||
ForwardZapTo(postViewModel, accountViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
postViewModel.multiOrchestrator?.let {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
ImageVideoDescription(
|
||||
it,
|
||||
accountViewModel.account.settings.defaultFileServer,
|
||||
onAdd = { alt, server, sensitiveContent, mediaQuality ->
|
||||
postViewModel.upload(alt, if (sensitiveContent) "" else null, mediaQuality, false, server, accountViewModel.toastManager::toast, context)
|
||||
if (server.type != ServerType.NIP95) {
|
||||
accountViewModel.account.settings.changeDefaultFileServer(server)
|
||||
}
|
||||
},
|
||||
onDelete = postViewModel::deleteMediaToUpload,
|
||||
onCancel = { postViewModel.multiOrchestrator = null },
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsInvoice) {
|
||||
postViewModel.lnAddress()?.let { lud16 ->
|
||||
InvoiceRequest(
|
||||
lud16,
|
||||
accountViewModel.account.userProfile().pubkeyHex,
|
||||
accountViewModel,
|
||||
stringRes(id = R.string.lightning_invoice),
|
||||
stringRes(id = R.string.lightning_create_and_add_invoice),
|
||||
onSuccess = {
|
||||
postViewModel.insertAtCursor(it)
|
||||
postViewModel.wantsInvoice = false
|
||||
},
|
||||
onError = { title, message -> accountViewModel.toastManager.toast(title, message) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsSecretEmoji) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
SecretEmojiRequest {
|
||||
postViewModel.insertAtCursor(it)
|
||||
postViewModel.wantsSecretEmoji = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsZapraiser && postViewModel.hasLnAddress()) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
ZapRaiserRequest(
|
||||
stringRes(id = R.string.zapraiser),
|
||||
postViewModel,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
postViewModel.userSuggestions?.let {
|
||||
ShowUserSuggestionList(
|
||||
it,
|
||||
postViewModel::autocompleteWithUser,
|
||||
accountViewModel,
|
||||
modifier = Modifier.heightIn(0.dp, 300.dp),
|
||||
)
|
||||
}
|
||||
|
||||
postViewModel.emojiSuggestions?.let {
|
||||
ShowEmojiSuggestionList(
|
||||
it,
|
||||
postViewModel::autocompleteWithEmoji,
|
||||
postViewModel::autocompleteWithEmojiUrl,
|
||||
accountViewModel,
|
||||
modifier = Modifier.heightIn(0.dp, 300.dp),
|
||||
)
|
||||
}
|
||||
|
||||
BottomRowActions(postViewModel)
|
||||
}
|
||||
NewPostScreenBody(postViewModel, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomRowActions(postViewModel: NewPostViewModel) {
|
||||
private fun NewPostScreenBody(
|
||||
postViewModel: ShortNotePostViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: Nav,
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
modifier =
|
||||
Modifier.fillMaxSize(),
|
||||
) {
|
||||
Row(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = Size10dp,
|
||||
end = Size10dp,
|
||||
).weight(1f),
|
||||
) {
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(scrollState),
|
||||
) {
|
||||
postViewModel.originalNote?.let {
|
||||
Row {
|
||||
NoteCompose(
|
||||
baseNote = it,
|
||||
modifier = MaterialTheme.colorScheme.replyModifier,
|
||||
isQuotedNote = true,
|
||||
unPackReply = false,
|
||||
makeItShort = true,
|
||||
quotesLeft = 1,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
Notifying(postViewModel.pTags?.toImmutableList(), accountViewModel) {
|
||||
postViewModel.removeFromReplyList(it)
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(vertical = Size10dp),
|
||||
) {
|
||||
BaseUserPicture(
|
||||
accountViewModel.userProfile(),
|
||||
Size35dp,
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
MessageField(
|
||||
R.string.what_s_on_your_mind,
|
||||
postViewModel,
|
||||
)
|
||||
}
|
||||
|
||||
if (postViewModel.wantsPoll) {
|
||||
Row(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
PollField(postViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
DisplayPreviews(postViewModel, accountViewModel, nav)
|
||||
|
||||
if (postViewModel.wantsToMarkAsSensitive) {
|
||||
Row(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
ContentSensitivityExplainer()
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsToAddGeoHash) {
|
||||
Row(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
LocationAsHash(postViewModel) {
|
||||
SettingsRow(
|
||||
R.string.geohash_exclusive,
|
||||
R.string.geohash_exclusive_explainer,
|
||||
) {
|
||||
Switch(postViewModel.wantsExclusiveGeoPost, onCheckedChange = { postViewModel.wantsExclusiveGeoPost = it })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsForwardZapTo) {
|
||||
Row(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = Modifier.padding(top = Size5dp, bottom = Size5dp, start = Size10dp),
|
||||
) {
|
||||
ForwardZapTo(postViewModel, accountViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
postViewModel.multiOrchestrator?.let {
|
||||
Row(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
ImageVideoDescription(
|
||||
it,
|
||||
accountViewModel.account.settings.defaultFileServer,
|
||||
onAdd = { alt, server, sensitiveContent, mediaQuality ->
|
||||
postViewModel.upload(alt, if (sensitiveContent) "" else null, mediaQuality, server, accountViewModel.toastManager::toast, context)
|
||||
if (server.type != ServerType.NIP95) {
|
||||
accountViewModel.account.settings.changeDefaultFileServer(server)
|
||||
}
|
||||
},
|
||||
onDelete = postViewModel::deleteMediaToUpload,
|
||||
onCancel = { postViewModel.multiOrchestrator = null },
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsInvoice) {
|
||||
postViewModel.lnAddress()?.let { lud16 ->
|
||||
InvoiceRequest(
|
||||
lud16,
|
||||
accountViewModel.account.userProfile().pubkeyHex,
|
||||
accountViewModel,
|
||||
stringRes(id = R.string.lightning_invoice),
|
||||
stringRes(id = R.string.lightning_create_and_add_invoice),
|
||||
onSuccess = {
|
||||
postViewModel.insertAtCursor(it)
|
||||
postViewModel.wantsInvoice = false
|
||||
},
|
||||
onError = { title, message -> accountViewModel.toastManager.toast(title, message) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsSecretEmoji) {
|
||||
Row(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
SecretEmojiRequest {
|
||||
postViewModel.insertAtCursor(it)
|
||||
postViewModel.wantsSecretEmoji = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (postViewModel.wantsZapraiser && postViewModel.hasLnAddress()) {
|
||||
Row(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
|
||||
) {
|
||||
ZapRaiserRequest(
|
||||
stringRes(id = R.string.zapraiser),
|
||||
postViewModel,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
postViewModel.userSuggestions?.let {
|
||||
ShowUserSuggestionList(
|
||||
it,
|
||||
postViewModel::autocompleteWithUser,
|
||||
accountViewModel,
|
||||
modifier = Modifier.heightIn(0.dp, 300.dp),
|
||||
)
|
||||
}
|
||||
|
||||
postViewModel.emojiSuggestions?.let {
|
||||
ShowEmojiSuggestionList(
|
||||
it,
|
||||
postViewModel::autocompleteWithEmoji,
|
||||
postViewModel::autocompleteWithEmojiUrl,
|
||||
accountViewModel,
|
||||
modifier = Modifier.heightIn(0.dp, 300.dp),
|
||||
)
|
||||
}
|
||||
|
||||
BottomRowActions(postViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomRowActions(postViewModel: ShortNotePostViewModel) {
|
||||
val scrollState = rememberScrollState()
|
||||
Row(
|
||||
modifier =
|
||||
@@ -548,7 +550,7 @@ private fun BottomRowActions(postViewModel: NewPostViewModel) {
|
||||
|
||||
@Composable
|
||||
fun DisplayPreviews(
|
||||
postViewModel: NewPostViewModel,
|
||||
postViewModel: ShortNotePostViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
+135
-422
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.actions
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.home
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
@@ -38,20 +38,19 @@ import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LiveActivitiesChannel
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.model.nip30CustomEmojis.EmojiPackState.EmojiMedia
|
||||
import com.vitorpamplona.amethyst.service.location.LocationState
|
||||
import com.vitorpamplona.amethyst.service.uploads.MediaCompressor
|
||||
import com.vitorpamplona.amethyst.service.uploads.MultiOrchestrator
|
||||
import com.vitorpamplona.amethyst.service.uploads.UploadOrchestrator
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger
|
||||
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.amethyst.ui.note.creators.draftTags.DraftTagState
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.EmojiSuggestionState
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.location.ILocationGrabber
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.messagefield.IMessageField
|
||||
@@ -64,7 +63,6 @@ import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.toZapSplitSetup
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.IMetaAttachments
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
|
||||
@@ -76,9 +74,7 @@ import com.vitorpamplona.quartz.experimental.zapPolls.tags.PollOptionTag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTags
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.getGeoHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||
@@ -90,27 +86,16 @@ import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findNostrUris
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.notify
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.positionalMarkedTags
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.taggedQuoteIds
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip22Comments.RootScope
|
||||
import com.vitorpamplona.quartz.nip22Comments.notify
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.notify
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.emojis
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.reply.GitReplyEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.reply.notify
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.contentWarning
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitive
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.notify
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupLnAddress
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.zapSplitSetup
|
||||
@@ -118,7 +103,6 @@ import com.vitorpamplona.quartz.nip57Zaps.splits.zapSplits
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiser
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.location.GeohashId
|
||||
import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder
|
||||
import com.vitorpamplona.quartz.nip92IMeta.imetas
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.alt
|
||||
@@ -131,12 +115,11 @@ 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.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.UUID
|
||||
|
||||
enum class UserSuggestionAnchor {
|
||||
MAIN_MESSAGE,
|
||||
@@ -145,13 +128,21 @@ enum class UserSuggestionAnchor {
|
||||
}
|
||||
|
||||
@Stable
|
||||
open class NewPostViewModel :
|
||||
open class ShortNotePostViewModel :
|
||||
ViewModel(),
|
||||
ILocationGrabber,
|
||||
IMessageField,
|
||||
IZapField,
|
||||
IZapRaiser {
|
||||
var draftTag: String by mutableStateOf(UUID.randomUUID().toString())
|
||||
val draftTag = DraftTagState()
|
||||
|
||||
init {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
draftTag.versions.collectLatest {
|
||||
sendDraftSync()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var accountViewModel: AccountViewModel? = null
|
||||
var account: Account? = null
|
||||
@@ -220,7 +211,8 @@ open class NewPostViewModel :
|
||||
var wantsZapraiser by mutableStateOf(false)
|
||||
override val zapRaiserAmount = mutableStateOf<Long?>(null)
|
||||
|
||||
val draftTextChanges = Channel<String>(Channel.CONFLATED)
|
||||
var showRelaysDialog by mutableStateOf(false)
|
||||
var relayList by mutableStateOf<ImmutableList<String>?>(null)
|
||||
|
||||
fun lnAddress(): String? = account?.userProfile()?.info?.lnAddress()
|
||||
|
||||
@@ -258,9 +250,9 @@ open class NewPostViewModel :
|
||||
if (innerNote != null) {
|
||||
val oldTag = (draft.event as? AddressableEvent)?.dTag()
|
||||
if (oldTag != null) {
|
||||
draftTag = oldTag
|
||||
draftTag.set(oldTag)
|
||||
}
|
||||
loadFromDraft(innerNote, accountViewModel)
|
||||
loadFromDraft(innerNote)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -372,15 +364,16 @@ open class NewPostViewModel :
|
||||
urlPreviews.update(message)
|
||||
}
|
||||
|
||||
private fun loadFromDraft(
|
||||
draft: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
Log.d("draft", draft.event!!.toJson())
|
||||
private fun loadFromDraft(draft: Note) {
|
||||
val draftEvent = draft.event ?: return
|
||||
if (draftEvent !is TextNoteEvent) return
|
||||
|
||||
canAddInvoice = accountViewModel.userProfile().info?.lnAddress() != null
|
||||
canAddZapRaiser = accountViewModel.userProfile().info?.lnAddress() != null
|
||||
loadFromDraft(draftEvent)
|
||||
}
|
||||
|
||||
private fun loadFromDraft(draftEvent: TextNoteEvent) {
|
||||
canAddInvoice = accountViewModel?.userProfile()?.info?.lnAddress() != null
|
||||
canAddZapRaiser = accountViewModel?.userProfile()?.info?.lnAddress() != null
|
||||
multiOrchestrator = null
|
||||
|
||||
val localfowardZapTo = draftEvent.tags.filter { it.size > 1 && it[0] == "zap" }
|
||||
@@ -471,38 +464,59 @@ open class NewPostViewModel :
|
||||
urlPreviews.update(message)
|
||||
}
|
||||
|
||||
fun sendPost(relayList: List<RelaySetupInfo>) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
innerSendPost(relayList, null)
|
||||
accountViewModel?.deleteDraft(draftTag)
|
||||
cancel()
|
||||
suspend fun sendPostSync() {
|
||||
val template = createTemplate() ?: return
|
||||
val relayList = relayList
|
||||
|
||||
if (nip95attachments.isNotEmpty() && relayList != null) {
|
||||
val usedImages = template.tags.taggedQuoteIds().toSet()
|
||||
nip95attachments.forEach {
|
||||
if (usedImages.contains(it.second.id) == true) {
|
||||
account?.sendNip95Privately(it.first, it.second, relayList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
accountViewModel?.account?.signAndSendPrivatelyOrBroadcast(
|
||||
template,
|
||||
relayList = { relayList },
|
||||
)
|
||||
|
||||
accountViewModel?.deleteDraft(draftTag.current)
|
||||
|
||||
cancel()
|
||||
}
|
||||
|
||||
fun sendDraft(relayList: List<RelaySetupInfo>) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
sendDraftSync(relayList)
|
||||
}
|
||||
}
|
||||
suspend fun sendDraftSync() {
|
||||
val accountViewModel = accountViewModel ?: return
|
||||
|
||||
suspend fun sendDraftSync(relayList: List<RelaySetupInfo>) {
|
||||
if (message.text.isBlank()) {
|
||||
account?.deleteDraft(draftTag)
|
||||
accountViewModel.account.deleteDraft(draftTag.current)
|
||||
} else {
|
||||
innerSendPost(relayList, draftTag)
|
||||
val template = createTemplate() ?: return
|
||||
accountViewModel.account.createAndSendDraft(draftTag.current, template)
|
||||
|
||||
nip95attachments.forEach {
|
||||
account?.sendToPrivateOutboxAndLocal(it.first)
|
||||
account?.sendToPrivateOutboxAndLocal(it.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun innerSendPost(
|
||||
relayList: List<RelaySetupInfo>,
|
||||
localDraft: String?,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
private suspend fun createTemplate(): EventTemplate<out Event>? {
|
||||
if (accountViewModel == null) {
|
||||
cancel()
|
||||
return@withContext
|
||||
return null
|
||||
}
|
||||
|
||||
val tagger = NewMessageTagger(message.text, pTags, eTags, originalNote?.channelHex(), accountViewModel!!)
|
||||
val tagger =
|
||||
NewMessageTagger(
|
||||
message.text,
|
||||
pTags,
|
||||
eTags,
|
||||
originalNote?.channelHex(),
|
||||
accountViewModel!!,
|
||||
)
|
||||
tagger.run()
|
||||
|
||||
val zapReceiver = if (wantsForwardZapTo) forwardZapTo.value.toZapSplitSetup() else null
|
||||
@@ -510,367 +524,56 @@ open class NewPostViewModel :
|
||||
val geoHash = (location?.value as? LocationState.LocationResult.Success)?.geoHash?.toString()
|
||||
val localZapRaiserAmount = if (wantsZapraiser) zapRaiserAmount.value else null
|
||||
|
||||
nip95attachments.forEach {
|
||||
if (eTags?.contains(LocalCache.getNoteIfExists(it.second.id)) == true) {
|
||||
account?.sendNip95(it.first, it.second, relayList)
|
||||
}
|
||||
}
|
||||
|
||||
val emojis = findEmoji(tagger.message, account?.emoji?.myEmojis?.value)
|
||||
val urls = findURLs(tagger.message)
|
||||
val usedAttachments = iMetaAttachments.filterIsIn(urls.toSet())
|
||||
|
||||
val replyingTo = originalNote
|
||||
val contentWarningReason = if (wantsToMarkAsSensitive) "" else null
|
||||
|
||||
val channel = originalNote?.channelHex()?.let { LocalCache.getChannelIfExists(it) }
|
||||
return if (wantsPoll) {
|
||||
val options = pollOptions.map { PollOptionTag(it.key, it.value) }
|
||||
|
||||
if (replyingTo?.event is CommentEvent || replyingTo?.event is RootScope) {
|
||||
val eventHint = replyingTo.toEventHint<Event>() ?: return@withContext
|
||||
if (options.isEmpty()) return null
|
||||
|
||||
val template =
|
||||
CommentEvent.replyBuilder(
|
||||
msg = tagger.message,
|
||||
replyingTo = eventHint,
|
||||
) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
val quotes = findNostrUris(tagger.message)
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
PollNoteEvent.build(tagger.message, options) {
|
||||
valueMinimum?.let { minAmount(it) }
|
||||
valueMaximum?.let { maxAmount(it) }
|
||||
closedAt?.let { closedAt(it) }
|
||||
consensusThreshold?.let { consensusThreshold(it / 100.0) }
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
pTags(tagger.directMentionsUsers.map { it.toPTag() })
|
||||
quotes(quotes)
|
||||
hashtags(findHashtags(tagger.message))
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
account?.signAndSend(localDraft, template, relayList, setOf(replyingTo))
|
||||
} else if (wantsExclusiveGeoPost && geoHash != null && originalNote == null) {
|
||||
val template =
|
||||
CommentEvent.replyExternalIdentity(
|
||||
msg = tagger.message,
|
||||
extId = GeohashId(geoHash),
|
||||
) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
|
||||
account?.signAndSend(localDraft, template, relayList, emptyList())
|
||||
} else if (channel != null) {
|
||||
if (channel is PublicChatChannel) {
|
||||
val replyingToEvent = originalNote?.toEventHint<ChannelMessageEvent>()
|
||||
val channelEvent = channel.event
|
||||
val channelRelays = channel.relays()
|
||||
|
||||
val template =
|
||||
if (replyingToEvent != null) {
|
||||
ChannelMessageEvent.reply(tagger.message, replyingToEvent) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
} else if (channelEvent != null) {
|
||||
val hint = EventHintBundle(channelEvent, channelRelays.firstOrNull())
|
||||
ChannelMessageEvent.message(tagger.message, hint) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
} else {
|
||||
ChannelMessageEvent.message(tagger.message, ETag(channel.idHex, channelRelays.firstOrNull())) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
}
|
||||
|
||||
val broadcast = tagger.directMentionsNotes + (tagger.eTags ?: emptyList())
|
||||
|
||||
account?.signAndSendWithList(draftTag, template, channelRelays, broadcast)
|
||||
} else if (channel is LiveActivitiesChannel) {
|
||||
val replyingToEvent = originalNote?.toEventHint<LiveActivitiesChatMessageEvent>()
|
||||
val activity = channel.info
|
||||
val channelRelays = channel.relays()
|
||||
|
||||
val template =
|
||||
if (replyingToEvent != null) {
|
||||
LiveActivitiesChatMessageEvent.reply(tagger.message, replyingToEvent) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
} else if (activity != null) {
|
||||
val hint = EventHintBundle(activity, channelRelays.firstOrNull() ?: replyingToEvent?.relay)
|
||||
|
||||
LiveActivitiesChatMessageEvent.message(tagger.message, hint) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
} else {
|
||||
LiveActivitiesChatMessageEvent.message(tagger.message, channel.toATag()) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
}
|
||||
|
||||
val broadcast = tagger.directMentionsNotes + (tagger.eTags ?: emptyList())
|
||||
|
||||
account?.signAndSendWithList(draftTag, template, channelRelays, broadcast)
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
} else if (originalNote?.event is GitIssueEvent) {
|
||||
val originalNoteHint = originalNote?.toEventHint<GitIssueEvent>() ?: return@withContext
|
||||
|
||||
val template =
|
||||
GitReplyEvent.replyIssue(
|
||||
tagger.message,
|
||||
originalNoteHint,
|
||||
) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
|
||||
val broadcast = tagger.directMentionsNotes + (tagger.eTags ?: emptyList())
|
||||
|
||||
account?.signAndSend(localDraft, template, relayList, broadcast)
|
||||
} else if (originalNote?.event is TorrentCommentEvent) {
|
||||
val replyToEvent = originalNote?.event as TorrentCommentEvent
|
||||
|
||||
val rootETag = replyToEvent.torrent()
|
||||
val rootNote = rootETag?.eventId?.let { LocalCache.getNoteIfExists(it) }
|
||||
val rootNoteEvent = rootNote?.event
|
||||
|
||||
// only uses the root node if the event is loaded.
|
||||
val root =
|
||||
if (rootNoteEvent != null) {
|
||||
rootNote // refreshes author and relay hint to what we have.
|
||||
} else {
|
||||
rootETag?.let { LocalCache.getOrCreateNote(it) } // keeps what came in.
|
||||
?: originalNote?.replyTo?.firstOrNull { it.event != null && it.replyTo?.isEmpty() == true } // if it has loaded events with zero replies in the reply list
|
||||
?: originalNote?.replyTo?.firstOrNull() // old rules, first item is root.
|
||||
?: originalNote
|
||||
}
|
||||
|
||||
if (root != null) {
|
||||
val replyToSet =
|
||||
if (forkedFromNote != null) {
|
||||
(listOfNotNull(forkedFromNote) + (tagger.eTags ?: emptyList())).ifEmpty { null }
|
||||
} else {
|
||||
tagger.eTags
|
||||
}
|
||||
|
||||
val sortedAndMarked =
|
||||
eTags?.map { it.toETag() }?.positionalMarkedTags(
|
||||
root = root.toETag(),
|
||||
replyingTo = replyingTo?.toETag(),
|
||||
forkedFrom = forkedFromNote?.toETag(),
|
||||
)
|
||||
|
||||
val template =
|
||||
TorrentCommentEvent.build(tagger.message) {
|
||||
sortedAndMarked?.let { eTags(sortedAndMarked) }
|
||||
|
||||
pTags(tagger.directMentionsUsers.map { it.toPTag() })
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
|
||||
val broadcast = tagger.directMentionsNotes + (replyToSet ?: emptySet())
|
||||
|
||||
account?.sendTorrentComment(localDraft, template, broadcast, relayList)
|
||||
}
|
||||
} else if (originalNote?.event is TorrentEvent) {
|
||||
val replyToSet =
|
||||
if (forkedFromNote != null) {
|
||||
(listOfNotNull(forkedFromNote) + (tagger.eTags ?: emptyList())).ifEmpty { null }
|
||||
} else {
|
||||
tagger.eTags
|
||||
}
|
||||
|
||||
val sortedAndMarked =
|
||||
eTags?.map { it.toETag() }?.positionalMarkedTags(
|
||||
root = originalNote?.toETag(),
|
||||
replyingTo = null,
|
||||
forkedFrom = forkedFromNote?.toETag(),
|
||||
)
|
||||
|
||||
val template =
|
||||
TorrentCommentEvent.build(tagger.message) {
|
||||
sortedAndMarked?.let { eTags(sortedAndMarked) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
|
||||
val broadcast = tagger.directMentionsNotes + (replyToSet ?: emptySet())
|
||||
|
||||
account?.sendTorrentComment(localDraft, template, broadcast, relayList)
|
||||
} else {
|
||||
if (wantsPoll) {
|
||||
val options = pollOptions.map { PollOptionTag(it.key, it.value) }
|
||||
TextNoteEvent.build(
|
||||
note = tagger.message,
|
||||
replyingTo = originalNote?.toEventHint<TextNoteEvent>(),
|
||||
forkingFrom = forkedFromNote?.toEventHint<TextNoteEvent>(),
|
||||
) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
if (options.isEmpty()) return@withContext
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
val quotes = findNostrUris(tagger.message)
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
val template =
|
||||
PollNoteEvent.build(tagger.message, options) {
|
||||
valueMinimum?.let { minAmount(it) }
|
||||
valueMaximum?.let { maxAmount(it) }
|
||||
closedAt?.let { closedAt(it) }
|
||||
consensusThreshold?.let { consensusThreshold(it / 100.0) }
|
||||
|
||||
pTags(tagger.directMentionsUsers.map { it.toPTag() })
|
||||
quotes(quotes)
|
||||
hashtags(findHashtags(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
|
||||
account?.signAndSend(localDraft, template, relayList, quotes)
|
||||
} else {
|
||||
val replyToSet =
|
||||
if (forkedFromNote != null) {
|
||||
(listOfNotNull(forkedFromNote) + (tagger.eTags ?: emptyList())).ifEmpty { null }
|
||||
} else {
|
||||
tagger.eTags
|
||||
}
|
||||
|
||||
val template =
|
||||
TextNoteEvent.build(
|
||||
note = tagger.message,
|
||||
replyingTo = originalNote?.toEventHint<TextNoteEvent>(),
|
||||
forkingFrom = forkedFromNote?.toEventHint<TextNoteEvent>(),
|
||||
) {
|
||||
tagger.pTags?.let { notify(it.map { it.toPTag() }) }
|
||||
|
||||
hashtags(findHashtags(tagger.message))
|
||||
references(findURLs(tagger.message))
|
||||
quotes(findNostrUris(tagger.message))
|
||||
|
||||
geoHash?.let { geohash(it) }
|
||||
localZapRaiserAmount?.let { zapraiser(it) }
|
||||
zapReceiver?.let { zapSplits(it) }
|
||||
contentWarningReason?.let { contentWarning(it) }
|
||||
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
|
||||
val broadcast = tagger.directMentionsNotes + (replyToSet ?: emptySet())
|
||||
|
||||
account?.signAndSend(localDraft, template, relayList, broadcast)
|
||||
emojis(emojis)
|
||||
imetas(usedAttachments)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -889,7 +592,6 @@ open class NewPostViewModel :
|
||||
alt: String?,
|
||||
contentWarningReason: String?,
|
||||
mediaQuality: Int,
|
||||
isPrivate: Boolean = false,
|
||||
server: ServerName,
|
||||
onError: (title: String, message: String) -> Unit,
|
||||
context: Context,
|
||||
@@ -1000,13 +702,27 @@ open class NewPostViewModel :
|
||||
|
||||
emojiSuggestions?.reset()
|
||||
|
||||
draftTag = UUID.randomUUID().toString()
|
||||
showRelaysDialog = false
|
||||
|
||||
reloadRelaySet()
|
||||
|
||||
draftTag.rotate()
|
||||
}
|
||||
|
||||
fun deleteDraft() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
accountViewModel?.deleteDraft(draftTag)
|
||||
}
|
||||
fun reloadRelaySet() {
|
||||
val account = accountViewModel?.account ?: return
|
||||
|
||||
val nip65 = account.normalizedNIP65WriteRelayList.value
|
||||
val private = account.normalizedPrivateOutBoxRelaySet.value
|
||||
val local = account.settings.localRelayServers
|
||||
|
||||
relayList =
|
||||
if (nip65.isEmpty()) {
|
||||
account.activeWriteRelays().map { it.url }.toImmutableList()
|
||||
} else {
|
||||
val combined: Set<String> = (nip65 + private + local)
|
||||
combined.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteMediaToUpload(selected: SelectedMediaProcessing) {
|
||||
@@ -1017,10 +733,6 @@ open class NewPostViewModel :
|
||||
pTags = pTags?.filter { it != userToRemove }
|
||||
}
|
||||
|
||||
private fun saveDraft() {
|
||||
draftTextChanges.trySend("")
|
||||
}
|
||||
|
||||
open fun addToMessage(it: String) {
|
||||
updateMessage(TextFieldValue(message.text + " " + it))
|
||||
}
|
||||
@@ -1038,7 +750,7 @@ open class NewPostViewModel :
|
||||
emojiSuggestions?.processCurrentWord(lastWord)
|
||||
}
|
||||
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
override fun updateZapForwardTo(newZapForwardTo: TextFieldValue) {
|
||||
@@ -1065,10 +777,10 @@ open class NewPostViewModel :
|
||||
userSuggestions.reset()
|
||||
}
|
||||
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
open fun autocompleteWithEmoji(item: EmojiPackState.EmojiMedia) {
|
||||
open fun autocompleteWithEmoji(item: EmojiMedia) {
|
||||
val wordToInsert = ":${item.code}:"
|
||||
|
||||
message = message.replaceCurrentWord(wordToInsert)
|
||||
@@ -1076,10 +788,10 @@ open class NewPostViewModel :
|
||||
|
||||
emojiSuggestions?.reset()
|
||||
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
open fun autocompleteWithEmojiUrl(item: EmojiPackState.EmojiMedia) {
|
||||
open fun autocompleteWithEmojiUrl(item: EmojiMedia) {
|
||||
val wordToInsert = item.link.url + " "
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
@@ -1094,7 +806,7 @@ open class NewPostViewModel :
|
||||
|
||||
emojiSuggestions?.reset()
|
||||
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
private fun newStateMapPollOptions(): SnapshotStateMap<Int, String> = mutableStateMapOf(Pair(0, ""), Pair(1, ""))
|
||||
@@ -1138,13 +850,13 @@ open class NewPostViewModel :
|
||||
fun updateMinZapAmountForPoll(textMin: String) {
|
||||
valueMinimum = textMin.toLongOrNull()?.takeIf { it > 0 }
|
||||
checkMinMax()
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
fun updateMaxZapAmountForPoll(textMax: String) {
|
||||
valueMaximum = textMax.toLongOrNull()?.takeIf { it > 0 }
|
||||
checkMinMax()
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
fun checkMinMax() {
|
||||
@@ -1166,7 +878,8 @@ open class NewPostViewModel :
|
||||
|
||||
override fun updateZapFromText() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
val tagger = NewMessageTagger(message.text, emptyList(), emptyList(), null, accountViewModel!!)
|
||||
val tagger =
|
||||
NewMessageTagger(message.text, emptyList(), emptyList(), null, accountViewModel!!)
|
||||
tagger.run()
|
||||
tagger.pTags?.forEach { taggedUser ->
|
||||
if (!forwardZapTo.value.items.any { it.key == taggedUser }) {
|
||||
@@ -1178,12 +891,12 @@ open class NewPostViewModel :
|
||||
|
||||
override fun updateZapRaiserAmount(newAmount: Long?) {
|
||||
zapRaiserAmount.value = newAmount
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
fun removePollOption(optionIndex: Int) {
|
||||
pollOptions.removeOrdered(optionIndex)
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
private fun MutableMap<Int, String>.removeOrdered(index: Int) {
|
||||
@@ -1207,12 +920,12 @@ open class NewPostViewModel :
|
||||
text: String,
|
||||
) {
|
||||
pollOptions[optionIndex] = text
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
fun toggleMarkAsSensitive() {
|
||||
wantsToMarkAsSensitive = !wantsToMarkAsSensitive
|
||||
saveDraft()
|
||||
draftTag.newVersion()
|
||||
}
|
||||
|
||||
override fun locationManager(): LocationState = Amethyst.instance.locationManager
|
||||
+2
-2
@@ -44,8 +44,8 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.tor.PrivacySettingsBody
|
||||
|
||||
+2
-2
@@ -52,8 +52,8 @@ import com.vitorpamplona.amethyst.model.DefaultDMRelayList
|
||||
import com.vitorpamplona.amethyst.model.DefaultSearchRelayList
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm.DMRelayListViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm.renderDMItems
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ import com.vitorpamplona.amethyst.model.DefaultDMRelayList
|
||||
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ import com.vitorpamplona.amethyst.model.DefaultSearchRelayList
|
||||
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search.SearchRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search.SearchRelayListViewModel
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountContent
|
||||
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -48,9 +48,9 @@ import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.CloseButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||
|
||||
+7
-6
@@ -26,6 +26,7 @@ import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.nip30CustomEmojis.EmojiPackState.EmojiMedia
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.ShortNotePostViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
@@ -51,13 +52,13 @@ class NewPostViewModelTest {
|
||||
@MockK(relaxed = true)
|
||||
lateinit var replyingTo: Note
|
||||
|
||||
private lateinit var newPostViewModelUnderTest: NewPostViewModel
|
||||
private lateinit var shortNoteViewModelUnderTest: ShortNotePostViewModel
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
mockkObject(LocalCache)
|
||||
every { LocalCache.getOrCreateUser(any<HexKey>()) } returns mockk<User>()
|
||||
newPostViewModelUnderTest = NewPostViewModel()
|
||||
shortNoteViewModelUnderTest = ShortNotePostViewModel()
|
||||
MockKAnnotations.init(this)
|
||||
}
|
||||
|
||||
@@ -81,8 +82,8 @@ class NewPostViewModelTest {
|
||||
every { accountViewModel.account.emoji.myEmojis } returns mockk<StateFlow<List<EmojiMedia>>>(relaxed = true)
|
||||
|
||||
// Act: Call load with mentions
|
||||
newPostViewModelUnderTest.init(accountViewModel)
|
||||
newPostViewModelUnderTest.load(replyingTo, quote = null, fork = null, version = null, draft = null)
|
||||
shortNoteViewModelUnderTest.init(accountViewModel)
|
||||
shortNoteViewModelUnderTest.load(replyingTo, quote = null, fork = null, version = null, draft = null)
|
||||
|
||||
// Assert
|
||||
// Two mentions should call LocalCache.getOrCreateUser twice
|
||||
@@ -102,7 +103,7 @@ class NewPostViewModelTest {
|
||||
every { accountViewModel.userProfile() } returns mockk<User>(relaxed = true)
|
||||
|
||||
// Act: Call load with empty mentions
|
||||
newPostViewModelUnderTest.load(replyingTo, quote = null, fork = null, version = null, draft = null)
|
||||
shortNoteViewModelUnderTest.load(replyingTo, quote = null, fork = null, version = null, draft = null)
|
||||
|
||||
// Assert
|
||||
// With no mentions LocalCache.getOrCreateUser should not be called
|
||||
@@ -122,7 +123,7 @@ class NewPostViewModelTest {
|
||||
every { accountViewModel.userProfile() } returns mockk<User>(relaxed = true)
|
||||
|
||||
// Act: Call load with empty mentions
|
||||
newPostViewModelUnderTest.load(replyingTo, quote = null, fork = null, version = null, draft = null)
|
||||
shortNoteViewModelUnderTest.load(replyingTo, quote = null, fork = null, version = null, draft = null)
|
||||
|
||||
// Assert
|
||||
// Verify LocalCache.getOrCreateUser(it) is not called with empty hex, it will crash the app
|
||||
|
||||
Reference in New Issue
Block a user