diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataScreen.kt new file mode 100644 index 000000000..ff48090e9 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataScreen.kt @@ -0,0 +1,357 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * 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 + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +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.stringRes +import com.vitorpamplona.amethyst.ui.theme.MinHorzSpacer +import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer +import com.vitorpamplona.amethyst.ui.theme.placeholderText + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun NewUserMetadataScreen( + nav: INav, + accountViewModel: AccountViewModel, +) { + val postViewModel: NewUserMetadataViewModel = viewModel() + val context = LocalContext.current + + LaunchedEffect(Unit) { + postViewModel.load(accountViewModel.account) + } + + DisposableEffect(Unit) { + onDispose { + postViewModel.clear() + } + } + + Scaffold( + topBar = { + TopAppBar( + title = { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Spacer(modifier = MinHorzSpacer) + + Text( + text = stringRes(R.string.profile), + modifier = Modifier.weight(1f), + textAlign = TextAlign.Center, + style = MaterialTheme.typography.titleLarge, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + ) + + SaveButton( + onPost = { + postViewModel.create() + nav.popBack() + }, + true, + ) + } + }, + navigationIcon = { + Row { + Spacer(modifier = StdHorzSpacer) + CloseButton( + onPress = { + postViewModel.clear() + nav.popBack() + }, + ) + } + }, + colors = + TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.surface, + ), + ) + }, + ) { pad -> + Column( + modifier = + Modifier + .padding( + start = 10.dp, + end = 10.dp, + top = pad.calculateTopPadding(), + bottom = pad.calculateBottomPadding(), + ).consumeWindowInsets(pad) + .imePadding(), + ) { + Column( + modifier = Modifier.padding(10.dp).verticalScroll(rememberScrollState()), + ) { + OutlinedTextField( + label = { Text(text = stringRes(R.string.display_name)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.displayName.value, + onValueChange = { postViewModel.displayName.value = it }, + placeholder = { + Text( + text = stringRes(R.string.my_display_name), + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + keyboardOptions = + KeyboardOptions.Default.copy( + capitalization = KeyboardCapitalization.Sentences, + ), + singleLine = true, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.about_me)) }, + modifier = Modifier.fillMaxWidth().height(100.dp), + value = postViewModel.about.value, + onValueChange = { postViewModel.about.value = it }, + placeholder = { + Text( + text = stringRes(id = R.string.about_me), + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + keyboardOptions = + KeyboardOptions.Default.copy( + capitalization = KeyboardCapitalization.Sentences, + ), + maxLines = 10, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.avatar_url)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.picture.value, + onValueChange = { postViewModel.picture.value = it }, + placeholder = { + Text( + text = "https://mywebsite.com/me.jpg", + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + leadingIcon = { + SelectSingleFromGallery( + isUploading = postViewModel.isUploadingImageForPicture, + tint = MaterialTheme.colorScheme.placeholderText, + modifier = Modifier.padding(start = 5.dp), + ) { + postViewModel.uploadForPicture(it, context, onError = accountViewModel::toast) + } + }, + singleLine = true, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.banner_url)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.banner.value, + onValueChange = { postViewModel.banner.value = it }, + placeholder = { + Text( + text = "https://mywebsite.com/mybanner.jpg", + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + leadingIcon = { + SelectSingleFromGallery( + isUploading = postViewModel.isUploadingImageForBanner, + tint = MaterialTheme.colorScheme.placeholderText, + modifier = Modifier.padding(start = 5.dp), + ) { + postViewModel.uploadForBanner(it, context, onError = accountViewModel::toast) + } + }, + singleLine = true, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.pronouns)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.pronouns.value, + onValueChange = { postViewModel.pronouns.value = it }, + placeholder = { + Text( + text = "they/them, ...", + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + singleLine = true, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.website_url)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.website.value, + onValueChange = { postViewModel.website.value = it }, + placeholder = { + Text( + text = "https://mywebsite.com", + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + singleLine = true, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.nip_05)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.nip05.value, + onValueChange = { postViewModel.nip05.value = it }, + placeholder = { + Text( + text = "_@mywebsite.com", + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + singleLine = true, + ) + + Spacer(modifier = Modifier.height(10.dp)) + OutlinedTextField( + label = { Text(text = stringRes(R.string.ln_address)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.lnAddress.value, + onValueChange = { postViewModel.lnAddress.value = it }, + placeholder = { + Text( + text = "me@mylightningnode.com", + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + singleLine = true, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.ln_url_outdated)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.lnURL.value, + onValueChange = { postViewModel.lnURL.value = it }, + placeholder = { + Text( + text = stringRes(R.string.lnurl), + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.twitter)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.twitter.value, + onValueChange = { postViewModel.twitter.value = it }, + placeholder = { + Text( + text = stringRes(R.string.twitter_proof_url_template), + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.mastodon)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.mastodon.value, + onValueChange = { postViewModel.mastodon.value = it }, + placeholder = { + Text( + text = stringRes(R.string.mastodon_proof_url_template), + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + ) + + Spacer(modifier = Modifier.height(10.dp)) + + OutlinedTextField( + label = { Text(text = stringRes(R.string.github)) }, + modifier = Modifier.fillMaxWidth(), + value = postViewModel.github.value, + onValueChange = { postViewModel.github.value = it }, + placeholder = { + Text( + text = stringRes(R.string.github_proof_url_template), + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + ) + } + } + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataView.kt deleted file mode 100644 index 0772cf52f..000000000 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataView.kt +++ /dev/null @@ -1,317 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * 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 - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.unit.dp -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.actions.uploads.SelectSingleFromGallery -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.stringRes -import com.vitorpamplona.amethyst.ui.theme.placeholderText - -@Composable -fun NewUserMetadataView( - onClose: () -> Unit, - accountViewModel: AccountViewModel, -) { - val postViewModel: NewUserMetadataViewModel = viewModel() - val context = LocalContext.current - - LaunchedEffect(Unit) { - postViewModel.load(accountViewModel.account) - } - - Dialog( - onDismissRequest = { onClose() }, - properties = - DialogProperties( - usePlatformDefaultWidth = false, - dismissOnClickOutside = false, - ), - ) { - Surface { - Column( - modifier = Modifier.padding(10.dp), - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - CloseButton( - onPress = { - postViewModel.clear() - onClose() - }, - ) - - SaveButton( - onPost = { - postViewModel.create() - onClose() - }, - true, - ) - } - - Column( - modifier = Modifier.padding(10.dp).verticalScroll(rememberScrollState()), - ) { - OutlinedTextField( - label = { Text(text = stringRes(R.string.display_name)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.displayName.value, - onValueChange = { postViewModel.displayName.value = it }, - placeholder = { - Text( - text = stringRes(R.string.my_display_name), - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - keyboardOptions = - KeyboardOptions.Default.copy( - capitalization = KeyboardCapitalization.Sentences, - ), - singleLine = true, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.about_me)) }, - modifier = Modifier.fillMaxWidth().height(100.dp), - value = postViewModel.about.value, - onValueChange = { postViewModel.about.value = it }, - placeholder = { - Text( - text = stringRes(id = R.string.about_me), - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - keyboardOptions = - KeyboardOptions.Default.copy( - capitalization = KeyboardCapitalization.Sentences, - ), - maxLines = 10, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.avatar_url)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.picture.value, - onValueChange = { postViewModel.picture.value = it }, - placeholder = { - Text( - text = "https://mywebsite.com/me.jpg", - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - leadingIcon = { - SelectSingleFromGallery( - isUploading = postViewModel.isUploadingImageForPicture, - tint = MaterialTheme.colorScheme.placeholderText, - modifier = Modifier.padding(start = 5.dp), - ) { - postViewModel.uploadForPicture(it, context, onError = accountViewModel::toast) - } - }, - singleLine = true, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.banner_url)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.banner.value, - onValueChange = { postViewModel.banner.value = it }, - placeholder = { - Text( - text = "https://mywebsite.com/mybanner.jpg", - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - leadingIcon = { - SelectSingleFromGallery( - isUploading = postViewModel.isUploadingImageForBanner, - tint = MaterialTheme.colorScheme.placeholderText, - modifier = Modifier.padding(start = 5.dp), - ) { - postViewModel.uploadForBanner(it, context, onError = accountViewModel::toast) - } - }, - singleLine = true, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.pronouns)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.pronouns.value, - onValueChange = { postViewModel.pronouns.value = it }, - placeholder = { - Text( - text = "they/them, ...", - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - singleLine = true, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.website_url)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.website.value, - onValueChange = { postViewModel.website.value = it }, - placeholder = { - Text( - text = "https://mywebsite.com", - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - singleLine = true, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.nip_05)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.nip05.value, - onValueChange = { postViewModel.nip05.value = it }, - placeholder = { - Text( - text = "_@mywebsite.com", - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - singleLine = true, - ) - - Spacer(modifier = Modifier.height(10.dp)) - OutlinedTextField( - label = { Text(text = stringRes(R.string.ln_address)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.lnAddress.value, - onValueChange = { postViewModel.lnAddress.value = it }, - placeholder = { - Text( - text = "me@mylightningnode.com", - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - singleLine = true, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.ln_url_outdated)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.lnURL.value, - onValueChange = { postViewModel.lnURL.value = it }, - placeholder = { - Text( - text = stringRes(R.string.lnurl), - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.twitter)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.twitter.value, - onValueChange = { postViewModel.twitter.value = it }, - placeholder = { - Text( - text = stringRes(R.string.twitter_proof_url_template), - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.mastodon)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.mastodon.value, - onValueChange = { postViewModel.mastodon.value = it }, - placeholder = { - Text( - text = stringRes(R.string.mastodon_proof_url_template), - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - ) - - Spacer(modifier = Modifier.height(10.dp)) - - OutlinedTextField( - label = { Text(text = stringRes(R.string.github)) }, - modifier = Modifier.fillMaxWidth(), - value = postViewModel.github.value, - onValueChange = { postViewModel.github.value = it }, - placeholder = { - Text( - text = stringRes(R.string.github_proof_url_template), - color = MaterialTheme.colorScheme.placeholderText, - ) - }, - ) - } - } - } - } -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 791adcfc3..02478658a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -49,6 +49,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.MainActivity +import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataScreen import com.vitorpamplona.amethyst.ui.actions.relays.AllRelayListView import com.vitorpamplona.amethyst.ui.components.DisplayErrorMessages import com.vitorpamplona.amethyst.ui.components.DisplayNotifyMessages @@ -113,6 +114,7 @@ fun AppNavigation( composable(Route.Video.route) { VideoScreen(accountViewModel, nav) } composable(Route.Discover.route) { DiscoverScreen(accountViewModel, nav) } composable(Route.Notification.route) { NotificationScreen(sharedPreferencesViewModel, accountViewModel, nav) } + composable(Route.EditProfile.route) { NewUserMetadataScreen(nav, accountViewModel) } composable(Route.Search.route) { SearchScreen(accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt index 02f6d2015..5f542f652 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt @@ -209,6 +209,12 @@ sealed class Route( icon = R.drawable.ic_settings, ) + object EditProfile : + Route( + route = "EditProfile", + icon = R.drawable.ic_settings, + ) + object EditRelays : Route( route = "EditRelays?toAdd={toAdd}", diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt index 088341a28..7c0c0cb4a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt @@ -125,7 +125,6 @@ import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.actions.InformationDialog -import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataView import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.DisplayNip05ProfileStatus import com.vitorpamplona.amethyst.ui.components.InvoiceRequestCard @@ -137,6 +136,7 @@ import com.vitorpamplona.amethyst.ui.dal.UserProfileReportsFeedFilter import com.vitorpamplona.amethyst.ui.feeds.FeedState import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.ui.navigation.INav +import com.vitorpamplona.amethyst.ui.navigation.Route import com.vitorpamplona.amethyst.ui.navigation.routeToMessage import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.note.DrawPlayName @@ -862,7 +862,7 @@ private fun ProfileHeader( ) { MessageButton(baseUser, accountViewModel, nav) - ProfileActions(baseUser, accountViewModel) + ProfileActions(baseUser, accountViewModel, nav) } } @@ -886,12 +886,13 @@ private fun ProfileHeader( private fun ProfileActions( baseUser: User, accountViewModel: AccountViewModel, + nav: INav, ) { val isMe by remember(accountViewModel) { derivedStateOf { accountViewModel.userProfile() == baseUser } } if (isMe) { - EditButton(accountViewModel) + EditButton(nav) } WatchIsHiddenUser(baseUser, accountViewModel) { isHidden -> @@ -1847,14 +1848,8 @@ private fun MessageButton( } @Composable -private fun EditButton(accountViewModel: AccountViewModel) { - var wantsToEdit by remember { mutableStateOf(false) } - - if (wantsToEdit) { - NewUserMetadataView({ wantsToEdit = false }, accountViewModel) - } - - InnerEditButton { wantsToEdit = true } +private fun EditButton(nav: INav) { + InnerEditButton { nav.nav(Route.EditProfile.route) } } @Preview diff --git a/amethyst/src/main/res/values-ar/strings.xml b/amethyst/src/main/res/values-ar/strings.xml index 8833f69d3..3ed653b87 100644 --- a/amethyst/src/main/res/values-ar/strings.xml +++ b/amethyst/src/main/res/values-ar/strings.xml @@ -18,6 +18,7 @@ محتوى عشوائي التمثيل تصرف غير قانوني + أخرى غير معروف أيقونة الخادم كاتب غير معروف @@ -45,6 +46,7 @@ تعزيز معزز تم تعديلها + تعديل #%1$s الأصلية إقتباس مبلغ جديد في Sats diff --git a/amethyst/src/main/res/values-bn-rBD/strings.xml b/amethyst/src/main/res/values-bn-rBD/strings.xml index f43160d58..731d0bb49 100644 --- a/amethyst/src/main/res/values-bn-rBD/strings.xml +++ b/amethyst/src/main/res/values-bn-rBD/strings.xml @@ -184,7 +184,7 @@ প্রথমে %1$s ভাষায় দেখান সবসময় %1$s ভাষায় অনুবাদ করুন কখনোই %1$s ভাষা থেকে অনুবাদ করবেন না - নস্টার ঠিকানা + Nostr Address কখনো না এখন h @@ -323,6 +323,7 @@ ফাইল সার্ভার বিজলি-ঠিকানা বা @ব্যবহারকারী ডিফল্ট তালিকা ব্যবহার করুন + শুরু হয়নি আপনার রিলেগুলি (NIP-95) ফাইলগুলো আপনার রিলে দ্বারা গৃহীত হয়। নতুন NIP: তারা এটি সমর্থন করে কিনা দেখে নিন Tor/Orbot সেটআপ করুন @@ -344,6 +345,7 @@ \n৬. Orbot কে প্রক্সি হিসেবে ব্যবহার করতে Activate বোতামটি চাপুন Orbot এর Socks পোর্ট + পছন্দমতন পোর্ট নম্বরটি অকার্যকর Orbot ব্যবহার করুন Tor/Orbot থেকে সংযোগ বিচ্ছিন্ন করুন @@ -534,6 +536,7 @@ অনুসন্ধান করুন আবিস্কার বার্তা + অবহিতকরন নিরাপত্তা-ফিল্টার নতুন পোস্ট উত্তর @@ -544,6 +547,7 @@ ভোট পোল নিষ্ক্রিয় করুন অবস্থান + অবস্থান সরান ঠিকানা সঠিক নয় আপনার অনুদান আমাদের পার্থক্য গড়তে সাহায্য করে। প্রতিটি ইঞ্চি গুরুত্বপূর্ণ! এখনই দান করুন diff --git a/amethyst/src/main/res/values-fr/strings.xml b/amethyst/src/main/res/values-fr/strings.xml index 8d0cfecc4..3a2d6e712 100644 --- a/amethyst/src/main/res/values-fr/strings.xml +++ b/amethyst/src/main/res/values-fr/strings.xml @@ -347,6 +347,7 @@ Ajouter au Message Ajouter une légende Mon adorable ami + Utiliser l\'URL directe Description des contenus Un bateau bleu sur une plage de sable blanc au coucher du soleil Type de Zap @@ -810,6 +811,7 @@ La création d\'une liste de relais spécialement conçue pour la recherche et l\'étiquetage utilisateur améliorera ces résultats. Insérez de 1 à 3 relais à utiliser lors de la recherche de contenu ou de l\'étiquetage utilisateur. Assurez-vous que les relais que vous avez choisis implémentent le NIP-50 De bonnes options sont:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com + Téléversement de MP Paramètres du relais Relais publics d\'accueil Ce type de relais stocke tout votre contenu. Amethyst enverra vos messages ici et d\'autres utiliseront ces relais pour trouver votre contenu. Insérez entre 1 et 3 relais : il peut s\'agir de relais personnels, de relais payants ou de relais publics. diff --git a/amethyst/src/main/res/values-hi-rIN/strings.xml b/amethyst/src/main/res/values-hi-rIN/strings.xml index 34fb95589..19fb944a7 100644 --- a/amethyst/src/main/res/values-hi-rIN/strings.xml +++ b/amethyst/src/main/res/values-hi-rIN/strings.xml @@ -347,6 +347,7 @@ संदेश में जोड दें शीर्षक जोडें मेरे प्रिय मित्र + सीधे जालपता का उपयोग करें विषयवस्तु का विवरण एक नीला नाव श्वेत रेतीला तट पर सूर्यास्त पर ज्साप प्रकार diff --git a/amethyst/src/main/res/values-hu/strings.xml b/amethyst/src/main/res/values-hu/strings.xml index 581910c8e..d39920f84 100644 --- a/amethyst/src/main/res/values-hu/strings.xml +++ b/amethyst/src/main/res/values-hu/strings.xml @@ -13,7 +13,7 @@ Csatornakép A hivatkozott esemény nem található Nem sikerült visszafejteni az üzenetet - Csoportkép + Csoport profilképe Szókimondó tartalom Kéretlen tartalom Az erről az átjátszóról érkező kéretlen tartalmú események száma @@ -347,6 +347,7 @@ Hozzáadás az üzenethez Képaláírás hozzáadása Kedves barátom + Közvetlen webcím használata Tartalmi leírás Egy kék csónak a fehér homokos tengerparton naplementekor Zap-típus @@ -669,7 +670,7 @@ A kedvezményezett lightning-szolgáltatása ennél: %1$s nem érhető el. A(z) „%2$s” lightning-cím lett kiszámítva. Hiba: %3$s. Ellenőrizze, hogy a kiszolgáló működik-e, és hogy a lightning-cím helyes-e Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e.\n\nKivéve: %3$s - Nem sikerült a számlát a következőtől lekérni: %1$s + Nem sikerült lekérni a számlát a következőtől: %1$s Nem sikerült lekérni a számlát a következőtől: %1$s: %2$s Hiba a Lightning-címből származó JSON elemzésekor. Ellenőrizze a felhasználó Lightning-beállítását Hiba történt a(z) %1$s JSON elemzésekor. Ellenőrizze a felhasználó Lightning-beállítását diff --git a/amethyst/src/main/res/values-nl/strings.xml b/amethyst/src/main/res/values-nl/strings.xml index 6bf293042..cb6b179a2 100644 --- a/amethyst/src/main/res/values-nl/strings.xml +++ b/amethyst/src/main/res/values-nl/strings.xml @@ -347,6 +347,7 @@ Voeg toe aan bericht Onderschrift toevoegen Mijn goede vriend + Directe URL gebruiken Beschrijving van de inhoud Een blauwe boot in een wit zandstrand bij zonsondergang Zap type diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 35296233b..7bbddd0b4 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -52,8 +52,8 @@ Używasz klucza publicznego, a klucze publiczne są tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc pokazać słowo lub zdanie Zapy Liczba wyświetleń - Repost - reposted + Promuj + promowany edytowano edytuj #%1$s oryginalny @@ -76,8 +76,8 @@ Pokaż Więcej Faktura LN Zapłać - Lightning-wskazówki - Notatka dla odbiorcy + Lightning transfer + Wiadomość dla odbiorcy Dziękuję bardzo! Kwota w Satsach Wyślij Satsy @@ -121,6 +121,8 @@ Adres URL LN (nieaktualny) Zapisz w galerii Zdjęcie zostało zapisane w galerii + Rozpoczęto pobieranie wideo… + Rozpoczęto pobieranie plików… Nie udało się zapisać zdjęcia Film zapisany w galerii filmów Nie udało się zapisać filmu @@ -205,11 +207,11 @@ Automatycznie przetłumaczono z do - Najpierw pokaż w %1$s + Najpierw wyświetl język %1$s Temat czatu: %1$s Temat dyskusji %1$s Zawsze tłumacz na %1$s - Nigdy nie tłumacz z %1$s + Język %1$s pokaż nietłumaczony Adres Nostr nigdy teraz @@ -218,7 +220,7 @@ d Nagość Wulgaryzmy / Mowa nienawiści - Zgłoś nienawistną mowę + Zgłoś mowę nienawiści Zgłoś Nagość / Pornografię inne Oznacz wszystkie popularne jako przeczytane @@ -342,9 +344,10 @@ Dodaj zdjęcie Dodaj wideo Dodaj dokument - Dodaj do wiadomości + Załącz Dodaj nagłówek Mój przyjacielu + Użyj bezpośredniego adresu URL Opis zawartości Błękitna łódź na białej piaszczystej plaży o zachodzie słońca Typ Zap-a @@ -535,7 +538,7 @@ Nigdy Kompletny Uproszczony - Wydajność + Dynamiczny Automatyczny Jasny Ciemny @@ -597,7 +600,9 @@ Udostępnij lub Zapisz Kopiuj adres URL do schowka Kopiuj ID wpisu do schowka - Dodaj media do Galerii + Dodaj pliki do Galerii + Dodano pliki + Pliki dodane do Twojej galerii profilu Utworzono Zasady Zaloguj się za pomocą Amber @@ -606,6 +611,7 @@ Głosy są oceniane na podstawie ilości zapperów. Możesz ustawić minimalną kwotę, aby uniknąć spamerów i maksymalną kwotę, aby uniknąć przejęcia ankiety przez dużych zapperów. Użyj tej samej kwoty w obu polach, aby upewnić się, że każdy głos ma taką samą wartość. Pozostaw to pole puste, aby zaakceptować dowolną kwotę. Nie można wysłać zapa Wyślij wiadomość użytkownikowi + Wiadomość %1$s OK Nieudane połączenie z %1$s: %2$s Nie udało się skompilować adresu URL NIP-11 dla %1$s: %2$s @@ -665,6 +671,7 @@ Nie można rozwiązać %1$s. Sprawdź, czy jesteś połączony, czy serwer jest gotowy i czy lightning adres %2$s jest poprawny Nie można rozwiązać %1$s. Sprawdź, czy jesteś połączony, czy serwer jest gotowy i czy lightning adres %2$s jest poprawny.\n\nWyjątkiem było: %3$s Nie można pobrać faktury z %1$s + Nie można pobrać faktury od %1$s: %2$s Błąd przetwarzania JSON z adresu lightning. Sprawdź konfigurację lightning użytkownika Błąd przetwarzania JSON z %1$s. Sprawdź konfigurację lightning użytkownika Adres zwrotny nie został znaleziony w konfiguracji serwera adresu lightning użytkownika @@ -737,7 +744,7 @@ Nie udało się wgrać pliku do %1$s: %2$s Nie udało się przesłać: %1$s Nie udało się usunąć: %1$s - Media są zbyt duże dla NIP-95 + Pliki są zbyt duże dla NIP-95 Nie można załadować miniatury Nie można przygotować informacji nagłówkowych: %1$s Kompresja anulowana @@ -804,6 +811,7 @@ Stworzenie listy transmiterów specjalnie przeznaczonych do wyszukiwania i tagowania użytkowników poprawi te wyniki. Wstaw od 1 do 3 transmiterów, które będą używane podczas wyszukiwania treści lub tagowania użytkowników. Upewnij się, że zaimplementowano NIP-50 Dobre opcje to:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com + Wgrywanie DM Ustawienia Transmiterów Publiczne transmitery domowe Ten typ transmitera przechowuje całą zawartość. Amethyst będzie wysyłać Twoje posty tutaj, a inni będą korzystać z tych transmiterów, aby znaleźć Twoje treści. Wstaw od 1 do 3 transmiterów. Mogą to być transmitery prywatne, płatne lub publiczne. @@ -854,7 +862,7 @@ Zeskanuj QR kod Przejdź do Alby zewnętrznego dostawcy portfela Nie jest możliwa odpowiedź na szkic wpisu - Nie jest możliwe zacytowanie szkicu notatki + Nie jest możliwe zacytowanie szkicu wpisu Nie jest możliwe reagowanie na szkic wpisu Nie jest możliwy zap dla szkicu wpisu Szkic wpisu diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index 3c71f1cdb..fbf7caf88 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -150,7 +150,7 @@ Prijavi se s privatnim ključem, za prikaz skritih besed in stavkov Zapiski Pogovori Galerija - "Sledim" + "Sledi" "Reportaže" Več možnosti " Releji" @@ -355,6 +355,7 @@ Prijavi se s privatnim ključem, za prikaz skritih besed in stavkov Dodaj v sporočilo Dodaj napis Moja draga družba + Uporabi direktni URL Opis vsebine Modra jadrnica pri beli peščeni plaži ob sončnem zahodu Vrsta Zap-a @@ -615,7 +616,7 @@ Prijavi se s privatnim ključem, za prikaz skritih besed in stavkov Prijavi se z Amber Posodobi svoj status Napaka pri razčlembi sporočila o napaki - Glasovi so ovrednoteni glede na količino Zapov. Lahko nastavite minimalni znesek, da se izognete neželeni pošti, in največji znesek, da preprečite, da bi bogatejši volilci prevzeli glasovanje. V obeh poljih uporabite enak znesek, da zagotovite, da je vsak glas enako ovrednoten. Pustite prazno, če želite sprejeti poljubno količino. + Glasovi so ovrednoteni glede na količino Zapov. Lahko nastavite minimalni znesek, da se izognete nezaželjenim glasovom, in največji znesek, da preprečite, da bi bogatejši volilci prevzeli glasovanje. V obeh poljih uporabite enak znesek, da zagotovite, da je vsak glas enako ovrednoten. Pustite prazno, če želite sprejeti poljubno količino. Zap ni uspel Pošlji sporočilo uporabniku Sporočilo %1$s @@ -686,10 +687,10 @@ Prijavi se s privatnim ključem, za prikaz skritih besed in stavkov Napaka pri razčlenjevanju JSON med pridobivanjem fakture iz \"lightning\" naslova. Preverite uporabnikove nastavitve za \"Lightning\" Napaka pri razčlenjevanju JSON med pridobivanjem fakture iz %1$s. Preverite uporabnikove nastavitve za \"Lightning\" Napačen znesek fakture (%1$s sat) od %2$s. Moral bi biti %3$s - Ni mogoče ustvariti lightning računa pred Zap-anjem. Lightning denarnica prejemnika je poslala naslednjo napako: %1$s - Ni mogoče ustvariti lightning računa. Sporočilo od %1$s: %2$s. - Ni mogoče ustvariti lightning računa pred Zap-anjem. Element \'pr\' ni bil najden v JSON-u. - Ni mogoče ustvariti lightning računa od %1$s: Element \'pr\' ni bil najden v JSON-u. + Ni mogoče ustvariti lightning fakture pred plačilom. Lightning denarnica prejemnika je poslala naslednjo napako: %1$s + Ni mogoče ustvariti lightning fakture. Sporočilo od %1$s: %2$s + Ni mogoče ustvariti lightning fakture pred plačilom. Element \'pr\' ni bil najden v JSON-u. + Ni mogoče ustvariti lightning fakture od %1$s: Element \'pr\' ni bil najden v JSON-u. Uporabnik samo za branje Ni nastavitev za reakcije Izberi \"UnifiedPush\" aplikacijo @@ -803,7 +804,7 @@ Prijavi se s privatnim ključem, za prikaz skritih besed in stavkov Odstrani opozorilo o vsebini Prikaži npub kot QR kodo Neveljaven naslov - Amethyst je prejel zahtevo za odprtje URI-ja, vendar je bil ta URI neveljaven: %1$s + Amethyst je prejel zahtevo da odpre URI, vendar je bil ta URI neveljaven: %1$s Releji predala zasebnih sporočil Releji: %1$s Uporaba običajnih relejev @@ -819,6 +820,7 @@ Prijavi se s privatnim ključem, za prikaz skritih besed in stavkov Ustvarjanje seznama relejev, posebej zasnovanega za iskanje in označevanje uporabnikov, bo izboljšalo te rezultate. Vnesite 1–3 releje za iskanje vsebine ali označevanje uporabnikov. Prepričajte se, da vaši izbrani releji podpirajo NIP-50 Dobre možnosti so\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com + Naloži ZS Nastavitve relejev Javni za odhajajočo pošto/domači releji Ta tip releja shranjuje vse vaše vsebine. Amethyst bo sem pošiljal vaše objave, ostali uporabniki pa bodo te releje uporabljali za iskanje vaših vsebin. Vstavite 1–3 releje. To so lahko osebni releji, plačljivi releji ali javni releji.