Centralizes stringResource calls to cache them.

This commit is contained in:
Vitor Pamplona 2024-06-19 15:12:07 -04:00
parent 73513713eb
commit f115111c49
145 changed files with 1443 additions and 1312 deletions

View File

@ -43,7 +43,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
@ -79,7 +78,7 @@ fun SelectNotificationProvider(sharedPreferencesViewModel: SharedPreferencesView
LoadDistributors { currentDistributor, list, readableListWithExplainer ->
if (readableListWithExplainer.size > 1) {
SpinnerSelectionDialog(
title = stringResource(id = R.string.select_push_server),
title = stringRes(id = R.string.select_push_server),
options = readableListWithExplainer,
onSelect = { index ->
if (list[index] == "None") {
@ -101,9 +100,9 @@ fun SelectNotificationProvider(sharedPreferencesViewModel: SharedPreferencesView
} else {
AlertDialog(
onDismissRequest = { distributorPresent = true },
title = { Text(stringResource(R.string.push_server_install_app)) },
title = { Text(stringRes(R.string.push_server_install_app)) },
text = {
val content = stringResource(R.string.push_server_install_app_description)
val content = stringRes(R.string.push_server_install_app_description)
val astNode =
remember {
@ -128,7 +127,7 @@ fun SelectNotificationProvider(sharedPreferencesViewModel: SharedPreferencesView
sharedPreferencesViewModel.dontShowPushNotificationSelector()
},
) {
Text(stringResource(R.string.quick_action_dont_show_again_button))
Text(stringRes(R.string.quick_action_dont_show_again_button))
}
Button(
onClick = { distributorPresent = true },
@ -142,7 +141,7 @@ fun SelectNotificationProvider(sharedPreferencesViewModel: SharedPreferencesView
contentDescription = null,
)
Spacer(Modifier.width(8.dp))
Text(stringResource(R.string.error_dialog_button_ok))
Text(stringRes(R.string.error_dialog_button_ok))
}
}
}
@ -168,20 +167,19 @@ fun LoadDistributors(onInner: @Composable (String, ImmutableList<String>, Immuta
}
val readableListWithExplainer =
PushDistributorHandler.formattedDistributorNames()
PushDistributorHandler
.formattedDistributorNames()
.mapIndexed { index, name ->
TitleExplainer(
name,
stringResource(id = R.string.push_server_uses_app_explainer, list[index]),
stringRes(id = R.string.push_server_uses_app_explainer, list[index]),
)
}
.plus(
}.plus(
TitleExplainer(
stringResource(id = R.string.push_server_none),
stringResource(id = R.string.push_server_none_explainer),
stringRes(id = R.string.push_server_none),
stringRes(id = R.string.push_server_none_explainer),
),
)
.toImmutableList()
).toImmutableList()
onInner(
currentDistributor,

View File

@ -28,6 +28,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
import com.vitorpamplona.amethyst.ui.components.GenericLoadable
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.events.Event
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
@ -46,9 +47,7 @@ data class CashuToken(
object CachedCashuProcessor {
val cashuCache = LruCache<String, GenericLoadable<CashuToken>>(20)
fun cached(token: String): GenericLoadable<CashuToken> {
return cashuCache[token] ?: GenericLoadable.Loading()
}
fun cached(token: String): GenericLoadable<CashuToken> = cashuCache[token] ?: GenericLoadable.Loading()
fun parse(token: String): GenericLoadable<CashuToken> {
if (cashuCache[token] !is GenericLoadable.Loaded) {
@ -150,7 +149,12 @@ class CashuProcessor {
val mediaType = "application/json; charset=utf-8".toMediaType()
val requestBody = jsonObject.toString().toRequestBody(mediaType)
val request = Request.Builder().url(url).post(requestBody).build()
val request =
Request
.Builder()
.url(url)
.post(requestBody)
.build()
client.newCall(request).execute().use {
val body = it.body.string()
@ -163,13 +167,19 @@ class CashuProcessor {
feeCost,
)
} else {
val msg = tree?.get("detail")?.asText()?.split('.')?.getOrNull(0)?.ifBlank { null }
val msg =
tree
?.get("detail")
?.asText()
?.split('.')
?.getOrNull(0)
?.ifBlank { null }
onError(
context.getString(R.string.cashu_failed_redemption),
stringRes(context, R.string.cashu_failed_redemption),
if (msg != null) {
context.getString(R.string.cashu_failed_redemption_explainer_error_msg, msg)
stringRes(context, R.string.cashu_failed_redemption_explainer_error_msg, msg)
} else {
context.getString(R.string.cashu_failed_redemption_explainer_error_msg)
stringRes(context, R.string.cashu_failed_redemption_explainer_error_msg)
},
)
}
@ -177,8 +187,8 @@ class CashuProcessor {
} catch (e: Exception) {
if (e is CancellationException) throw e
onError(
context.getString(R.string.cashu_successful_redemption),
context.getString(R.string.cashu_failed_redemption_explainer_error_msg, e.message),
stringRes(context, R.string.cashu_successful_redemption),
stringRes(context, R.string.cashu_failed_redemption_explainer_error_msg, e.message),
)
}
}
@ -203,7 +213,12 @@ class CashuProcessor {
val mediaType = "application/json; charset=utf-8".toMediaType()
val requestBody = jsonObject.toString().toRequestBody(mediaType)
val request = Request.Builder().url(url).post(requestBody).build()
val request =
Request
.Builder()
.url(url)
.post(requestBody)
.build()
client.newCall(request).execute().use {
val body = it.body.string()
@ -213,21 +228,28 @@ class CashuProcessor {
if (successful) {
onSuccess(
context.getString(R.string.cashu_successful_redemption),
context.getString(
stringRes(context, R.string.cashu_successful_redemption),
stringRes(
context,
R.string.cashu_successful_redemption_explainer,
token.totalAmount.toString(),
fees.toString(),
),
)
} else {
val msg = tree?.get("detail")?.asText()?.split('.')?.getOrNull(0)?.ifBlank { null }
val msg =
tree
?.get("detail")
?.asText()
?.split('.')
?.getOrNull(0)
?.ifBlank { null }
onError(
context.getString(R.string.cashu_failed_redemption),
stringRes(context, R.string.cashu_failed_redemption),
if (msg != null) {
context.getString(R.string.cashu_failed_redemption_explainer_error_msg, msg)
stringRes(context, R.string.cashu_failed_redemption_explainer_error_msg, msg)
} else {
context.getString(R.string.cashu_failed_redemption_explainer_error_msg)
stringRes(context, R.string.cashu_failed_redemption_explainer_error_msg)
},
)
}
@ -235,8 +257,8 @@ class CashuProcessor {
} catch (e: Exception) {
if (e is CancellationException) throw e
onError(
context.getString(R.string.cashu_successful_redemption),
context.getString(R.string.cashu_failed_redemption_explainer_error_msg, e.message),
stringRes(context, R.string.cashu_successful_redemption),
stringRes(context, R.string.cashu_failed_redemption_explainer_error_msg, e.message),
)
}
}

View File

@ -29,6 +29,7 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
import com.vitorpamplona.amethyst.ui.screen.loggedIn.collectSuccessfulSigningOperations
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent
import com.vitorpamplona.quartz.events.AppDefinitionEvent
import com.vitorpamplona.quartz.events.LiveActivitiesEvent
@ -41,7 +42,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlin.math.round
class ZapPaymentHandler(val account: Account) {
class ZapPaymentHandler(
val account: Account,
) {
@Immutable
data class Payable(
val info: ZapSplitSetup,
@ -79,8 +82,9 @@ class ZapPaymentHandler(val account: Account) {
if (lud16.isNullOrBlank()) {
onError(
context.getString(R.string.missing_lud16),
context.getString(
stringRes(context, R.string.missing_lud16),
stringRes(
context,
R.string.user_does_not_have_a_lightning_address_setup_to_receive_sats,
),
)
@ -94,8 +98,9 @@ class ZapPaymentHandler(val account: Account) {
if (lud16.isNullOrBlank()) {
onError(
context.getString(R.string.missing_lud16),
context.getString(
stringRes(context, R.string.missing_lud16),
stringRes(
context,
R.string.user_does_not_have_a_lightning_address_setup_to_receive_sats,
),
)
@ -132,7 +137,8 @@ class ZapPaymentHandler(val account: Account) {
}
} else {
onPayViaIntent(
it.map {
it
.map {
Payable(
info = it.key.first,
user = it.key.second.user,
@ -172,9 +178,12 @@ class ZapPaymentHandler(val account: Account) {
onAllDone: suspend (MutableMap<ZapSplitSetup, SignAllZapRequestsReturn>) -> Unit,
) {
val authorRelayList =
note.author?.pubkeyHex?.let {
note.author
?.pubkeyHex
?.let {
(
LocalCache.getAddressableNoteIfExists(
LocalCache
.getAddressableNoteIfExists(
AdvertisedRelayListEvent.createAddressTag(it),
)?.event as? AdvertisedRelayListEvent?
)?.readRelays()
@ -194,7 +203,8 @@ class ZapPaymentHandler(val account: Account) {
val userRelayList =
(
(
LocalCache.getAddressableNoteIfExists(
LocalCache
.getAddressableNoteIfExists(
AdvertisedRelayListEvent.createAddressTag(next.lnAddressOrPubKeyHex),
)?.event as? AdvertisedRelayListEvent?
)?.readRelays()?.toSet() ?: emptySet()
@ -272,8 +282,9 @@ class ZapPaymentHandler(val account: Account) {
progressAllPayments += 0.5f / invoices.size
onProgress(progressAllPayments)
onError(
context.getString(R.string.error_dialog_pay_invoice_error),
context.getString(
stringRes(context, R.string.error_dialog_pay_invoice_error),
stringRes(
context,
R.string.wallet_connect_pay_invoice_error_error,
response.error?.message
?: response.error?.code?.toString() ?: "Error parsing error message",
@ -339,10 +350,12 @@ class ZapPaymentHandler(val account: Account) {
} else {
if (showErrorIfNoLnAddress) {
onError(
context.getString(
stringRes(
context,
R.string.missing_lud16,
),
context.getString(
stringRes(
context,
R.string.user_x_does_not_have_a_lightning_address_setup_to_receive_sats,
user?.toBestDisplayName() ?: splitSetup.lnAddressOrPubKeyHex,
),

View File

@ -26,6 +26,7 @@ import com.vitorpamplona.amethyst.BuildConfig
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.service.HttpClientManager
import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.encoders.LnInvoiceUtil
import com.vitorpamplona.quartz.encoders.Lud06
import okhttp3.Request
@ -34,7 +35,7 @@ import java.math.RoundingMode
import java.net.URLEncoder
import kotlin.coroutines.cancellation.CancellationException
class LightningAddressResolver() {
class LightningAddressResolver {
val client = HttpClientManager.getHttpClient()
fun assembleUrl(lnaddress: String): String? {
@ -63,8 +64,9 @@ class LightningAddressResolver() {
if (url == null) {
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string.could_not_assemble_lnurl_from_lightning_address_check_the_user_s_setup,
lnaddress,
),
@ -74,7 +76,8 @@ class LightningAddressResolver() {
try {
val request: Request =
Request.Builder()
Request
.Builder()
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
.url(url)
.build()
@ -84,8 +87,9 @@ class LightningAddressResolver() {
onSuccess(it.body.string())
} else {
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string
.the_receiver_s_lightning_service_at_is_not_available_it_was_calculated_from_the_lightning_address_error_check_if_the_server_is_up_and_if_the_lightning_address_is_correct,
url,
@ -99,8 +103,9 @@ class LightningAddressResolver() {
if (e is CancellationException) throw e
e.printStackTrace()
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string
.could_not_resolve_check_if_you_are_connected_if_the_server_is_up_and_if_the_lightning_address_is_correct_exception,
url,
@ -133,7 +138,8 @@ class LightningAddressResolver() {
}
val request: Request =
Request.Builder()
Request
.Builder()
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
.url(url)
.build()
@ -143,8 +149,8 @@ class LightningAddressResolver() {
onSuccess(it.body.string())
} else {
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(R.string.could_not_fetch_invoice_from, lnCallback),
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(context, R.string.could_not_fetch_invoice_from, lnCallback),
)
}
}
@ -173,8 +179,9 @@ class LightningAddressResolver() {
} catch (t: Throwable) {
if (t is CancellationException) throw t
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string.error_parsing_json_from_lightning_address_check_the_user_s_lightning_setup_with_user,
lnaddress,
),
@ -186,8 +193,9 @@ class LightningAddressResolver() {
if (callback == null) {
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string.callback_url_not_found_in_the_user_s_lightning_address_server_configuration_with_user,
lnaddress,
),
@ -211,8 +219,9 @@ class LightningAddressResolver() {
} catch (t: Throwable) {
if (t is CancellationException) throw t
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string
.error_parsing_json_from_lightning_address_s_invoice_fetch_check_the_user_s_lightning_setup_with_user,
lnaddress,
@ -236,8 +245,9 @@ class LightningAddressResolver() {
} else {
onProgress(0.0f)
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string.incorrect_invoice_amount_sats_from_it_should_have_been,
invoiceAmount.toLong().toString(),
lnaddress,
@ -253,8 +263,9 @@ class LightningAddressResolver() {
?.let { reason ->
onProgress(0.0f)
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string
.unable_to_create_a_lightning_invoice_before_sending_the_zap_the_receiver_s_lightning_wallet_sent_the_following_error_with_user,
lnaddress,
@ -265,8 +276,9 @@ class LightningAddressResolver() {
?: run {
onProgress(0.0f)
onError(
context.getString(R.string.error_unable_to_fetch_invoice),
context.getString(
stringRes(context, R.string.error_unable_to_fetch_invoice),
stringRes(
context,
R.string
.unable_to_create_a_lightning_invoice_before_sending_the_zap_element_pr_not_found_in_the_resulting_json_with_user,
lnaddress,

View File

@ -31,6 +31,7 @@ import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendDMNotification
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendZapNotification
import com.vitorpamplona.amethyst.ui.note.showAmount
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.events.ChatMessageEvent
import com.vitorpamplona.quartz.events.ChatroomKey
@ -44,7 +45,9 @@ import com.vitorpamplona.quartz.utils.TimeUtils
import kotlinx.collections.immutable.persistentSetOf
import java.math.BigDecimal
class EventNotificationConsumer(private val applicationContext: Context) {
class EventNotificationConsumer(
private val applicationContext: Context,
) {
suspend fun consume(event: GiftWrapEvent) {
Log.d("EventNotificationConsumer", "New Notification Arrived")
if (!LocalCache.justVerify(event)) return
@ -124,7 +127,8 @@ class EventNotificationConsumer(private val applicationContext: Context) {
acc: Account,
) {
if (
event.createdAt > TimeUtils.fifteenMinutesAgo() && // old event being re-broadcasted
event.createdAt > TimeUtils.fifteenMinutesAgo() &&
// old event being re-broadcasted
event.pubKey != acc.userProfile().pubkeyHex
) { // from the user
@ -137,7 +141,8 @@ class EventNotificationConsumer(private val applicationContext: Context) {
(
acc.userProfile().privateChatrooms[chatRoom]?.senderIntersects(followingKeySet) == true ||
acc.userProfile().hasSentMessagesTo(chatRoom)
) && !acc.isAllHidden(chatRoom.users)
) &&
!acc.isAllHidden(chatRoom.users)
if (isKnownRoom) {
val content = chatNote.event?.content() ?: ""
@ -178,9 +183,9 @@ class EventNotificationConsumer(private val applicationContext: Context) {
(
acc.userProfile().privateChatrooms[it]?.senderIntersects(followingKeySet) == true ||
acc.userProfile().hasSentMessagesTo(it)
) && !acc.isAllHidden(it.users)
}
.toSet()
) &&
!acc.isAllHidden(it.users)
}.toSet()
note.author?.let {
if (ChatroomKey(persistentSetOf(it.pubkeyHex)) in knownChatrooms) {
@ -223,17 +228,19 @@ class EventNotificationConsumer(private val applicationContext: Context) {
val user = senderInfo.first.toBestDisplayName()
var title =
applicationContext.getString(R.string.app_notification_zaps_channel_message, amount)
stringRes(applicationContext, R.string.app_notification_zaps_channel_message, amount)
senderInfo.second?.ifBlank { null }?.let { title += " ($it)" }
var content =
applicationContext.getString(
stringRes(
applicationContext,
R.string.app_notification_zaps_channel_message_from,
user,
)
zappedContent?.let {
content +=
" " +
applicationContext.getString(
stringRes(
applicationContext,
R.string.app_notification_zaps_channel_message_for,
zappedContent,
)
@ -255,8 +262,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
}
}
fun notificationManager(): NotificationManager {
return ContextCompat.getSystemService(applicationContext, NotificationManager::class.java)
fun notificationManager(): NotificationManager =
ContextCompat.getSystemService(applicationContext, NotificationManager::class.java)
as NotificationManager
}
}

View File

@ -34,6 +34,7 @@ import coil.executeBlocking
import coil.request.ImageRequest
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.MainActivity
import com.vitorpamplona.amethyst.ui.stringRes
object NotificationUtils {
private var dmChannel: NotificationChannel? = null
@ -46,13 +47,12 @@ object NotificationUtils {
dmChannel =
NotificationChannel(
applicationContext.getString(R.string.app_notification_dms_channel_id),
applicationContext.getString(R.string.app_notification_dms_channel_name),
stringRes(applicationContext, R.string.app_notification_dms_channel_id),
stringRes(applicationContext, R.string.app_notification_dms_channel_name),
NotificationManager.IMPORTANCE_DEFAULT,
)
.apply {
).apply {
description =
applicationContext.getString(R.string.app_notification_dms_channel_description)
stringRes(applicationContext, R.string.app_notification_dms_channel_description)
}
// Register the channel with the system
@ -69,13 +69,12 @@ object NotificationUtils {
zapChannel =
NotificationChannel(
applicationContext.getString(R.string.app_notification_zaps_channel_id),
applicationContext.getString(R.string.app_notification_zaps_channel_name),
stringRes(applicationContext, R.string.app_notification_zaps_channel_id),
stringRes(applicationContext, R.string.app_notification_zaps_channel_name),
NotificationManager.IMPORTANCE_DEFAULT,
)
.apply {
).apply {
description =
applicationContext.getString(R.string.app_notification_zaps_channel_description)
stringRes(applicationContext, R.string.app_notification_zaps_channel_description)
}
// Register the channel with the system
@ -96,7 +95,7 @@ object NotificationUtils {
applicationContext: Context,
) {
val zapChannel = getOrCreateZapChannel(applicationContext)
val channelId = applicationContext.getString(R.string.app_notification_zaps_channel_id)
val channelId = stringRes(applicationContext, R.string.app_notification_zaps_channel_id)
sendNotification(
id,
@ -119,7 +118,7 @@ object NotificationUtils {
applicationContext: Context,
) {
val dmChannel = getOrCreateDMChannel(applicationContext)
val channelId = applicationContext.getString(R.string.app_notification_dms_channel_id)
val channelId = stringRes(applicationContext, R.string.app_notification_dms_channel_id)
sendNotification(
id,
@ -205,13 +204,13 @@ object NotificationUtils {
// Build the notification
val builderPublic =
NotificationCompat.Builder(
NotificationCompat
.Builder(
applicationContext,
channelId,
)
.setSmallIcon(R.drawable.amethyst)
).setSmallIcon(R.drawable.amethyst)
.setContentTitle(messageTitle)
.setContentText(applicationContext.getString(R.string.app_notification_private_message))
.setContentText(stringRes(applicationContext, R.string.app_notification_private_message))
.setLargeIcon(picture?.bitmap)
// .setGroup(messageTitle)
// .setGroup(notificationGroupKey) //-> Might need a Group summary as well before we
@ -222,11 +221,11 @@ object NotificationUtils {
// Build the notification
val builder =
NotificationCompat.Builder(
NotificationCompat
.Builder(
applicationContext,
channelId,
)
.setSmallIcon(R.drawable.amethyst)
).setSmallIcon(R.drawable.amethyst)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setLargeIcon(picture?.bitmap)

View File

@ -30,14 +30,15 @@ import com.vitorpamplona.quartz.ots.exceptions.CommitmentNotFoundException
import com.vitorpamplona.quartz.ots.exceptions.DeserializationException
import com.vitorpamplona.quartz.ots.exceptions.ExceededSizeException
import com.vitorpamplona.quartz.ots.exceptions.UrlException
import com.vitorpamplona.quartz.ots.http.Request
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
/**
* Class representing remote calendar server interface.
*/
class OkHttpCalendar(val url: String) : ICalendar {
class OkHttpCalendar(
val url: String,
) : ICalendar {
/**
* Submitting a digest to remote calendar. Returns a com.eternitywall.ots.Timestamp committing to that digest.
*
@ -57,7 +58,8 @@ class OkHttpCalendar(val url: String) : ICalendar {
val requestBody = digest.toRequestBody(mediaType)
val request =
okhttp3.Request.Builder()
okhttp3.Request
.Builder()
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
.header("Accept", "application/vnd.opentimestamps.v1")
.header("Content-Type", "application/x-www-form-urlencoded")
@ -104,7 +106,8 @@ class OkHttpCalendar(val url: String) : ICalendar {
val url = url + "/timestamp/" + Hex.encode(commitment)
val request =
okhttp3.Request.Builder()
okhttp3.Request
.Builder()
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
.header("Accept", "application/vnd.opentimestamps.v1")
.header("Content-Type", "application/x-www-form-urlencoded")

View File

@ -90,6 +90,11 @@ class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
val locales = this.applicationContext.resources.configuration.locales
if (!locales.isEmpty) {
checkLanguage(locales.get(0).language)
}
Log.d("Lifetime Event", "MainActivity.onResume")
// starts muted every time
@ -263,8 +268,8 @@ class GetMediaActivityResultContract : ActivityResultContracts.GetContent() {
}
}
fun uriToRoute(uri: String?): String? {
return if (uri.equals("nostr:Notifications", true)) {
fun uriToRoute(uri: String?): String? =
if (uri.equals("nostr:Notifications", true)) {
Route.Notification.route.replace("{scrollToTop}", "true")
} else {
if (uri?.startsWith("nostr:Hashtag?id=") == true) {
@ -317,4 +322,3 @@ fun uriToRoute(uri: String?): String? {
null
}
}
}

View File

@ -0,0 +1,79 @@
/**
* 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
import android.content.Context
import android.util.LruCache
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
/**
* Cache for stringResource because it seems to be > 1ms function in some phones
*/
private val resourceCache = LruCache<Int, String>(300)
private var resourceCacheLanguage: String? = null
fun checkLanguage(currentLanguage: String) {
if (resourceCacheLanguage == null) {
resourceCacheLanguage = currentLanguage
} else {
if (resourceCacheLanguage != currentLanguage) {
resourceCacheLanguage = currentLanguage
resourceCache.evictAll()
}
}
}
@Composable
fun stringRes(id: Int): String = resourceCache.get(id) ?: stringResource(id).also { resourceCache.put(id, it) }
@Composable
fun stringRes(
id: Int,
vararg args: Any,
): String =
String
.format(
LocalConfiguration.current.locales.get(0),
resourceCache.get(id) ?: stringResource(id),
*args,
).also { resourceCache.put(id, it) }
fun stringRes(
ctx: Context,
id: Int,
): String = resourceCache.get(id) ?: ctx.getString(id).also { resourceCache.put(id, it) }
fun stringRes(
ctx: Context,
id: Int,
vararg args: Any?,
): String {
val res = ctx.resources
return String
.format(
res.configuration.locales.get(0),
resourceCache.get(id) ?: res.getString(id),
*args,
).also { resourceCache.put(id, it) }
}

View File

@ -78,7 +78,6 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextDirection
@ -98,6 +97,7 @@ import com.vitorpamplona.amethyst.ui.components.VideoView
import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.UserLine
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
@ -189,7 +189,7 @@ fun EditPostView(
) {
Icon(
painter = painterResource(R.drawable.relays),
contentDescription = stringResource(id = R.string.relay_list_selector),
contentDescription = stringRes(id = R.string.relay_list_selector),
modifier = Modifier.height(25.dp),
tint = MaterialTheme.colorScheme.onBackground,
)
@ -236,8 +236,7 @@ fun EditPostView(
top = pad.calculateTopPadding(),
end = Size10dp,
bottom = pad.calculateBottomPadding(),
)
.fillMaxSize(),
).fillMaxSize(),
) {
Column(
modifier =
@ -365,8 +364,8 @@ fun EditPostView(
lud16,
user.pubkeyHex,
accountViewModel.account,
stringResource(id = R.string.lightning_invoice),
stringResource(id = R.string.lightning_create_and_add_invoice),
stringRes(id = R.string.lightning_invoice),
stringRes(id = R.string.lightning_create_and_add_invoice),
onSuccess = {
postViewModel.message =
TextFieldValue(postViewModel.message.text + "\n\n" + it)
@ -386,7 +385,7 @@ fun EditPostView(
) {
Column {
Text(
text = stringResource(R.string.message_to_author),
text = stringRes(R.string.message_to_author),
fontSize = 18.sp,
fontWeight = FontWeight.W500,
)
@ -399,7 +398,7 @@ fun EditPostView(
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(
text = stringResource(R.string.message_to_author_placeholder),
text = stringRes(R.string.message_to_author_placeholder),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -514,8 +513,7 @@ private fun MessageField(postViewModel: EditPostViewModel) {
width = 1.dp,
color = MaterialTheme.colorScheme.surface,
shape = RoundedCornerShape(8.dp),
)
.focusRequester(focusRequester)
).focusRequester(focusRequester)
.onFocusChanged {
if (it.isFocused) {
keyboardController?.show()
@ -523,7 +521,7 @@ private fun MessageField(postViewModel: EditPostViewModel) {
},
placeholder = {
Text(
text = stringResource(R.string.what_s_on_your_mind),
text = stringRes(R.string.what_s_on_your_mind),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -548,14 +546,14 @@ private fun AddLnInvoiceButton(
if (!isLnInvoiceActive) {
Icon(
imageVector = Icons.Default.CurrencyBitcoin,
contentDescription = stringResource(id = R.string.add_bitcoin_invoice),
contentDescription = stringRes(id = R.string.add_bitcoin_invoice),
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.onBackground,
)
} else {
Icon(
imageVector = Icons.Default.CurrencyBitcoin,
contentDescription = stringResource(id = R.string.cancel_bitcoin_invoice),
contentDescription = stringRes(id = R.string.cancel_bitcoin_invoice),
modifier = Modifier.size(20.dp),
tint = BitcoinOrange,
)

View File

@ -34,8 +34,8 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.res.stringResource
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size16dp
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
@ -64,7 +64,7 @@ fun InformationDialog(
contentDescription = null,
)
Spacer(StdHorzSpacer)
Text(stringResource(R.string.error_dialog_button_ok))
Text(stringRes(R.string.error_dialog_button_ok))
}
}
},

View File

@ -61,7 +61,6 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@ -83,6 +82,7 @@ import com.vitorpamplona.amethyst.ui.note.SearchIcon
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SearchBarViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
@ -161,7 +161,7 @@ fun JoinUserOrChannelView(
)
Text(
text = stringResource(R.string.channel_list_join_conversation),
text = stringRes(R.string.channel_list_join_conversation),
fontWeight = FontWeight.Bold,
)
@ -278,7 +278,7 @@ private fun SearchEditTextForJoin(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.channel_list_user_or_group_id)) },
label = { Text(text = stringRes(R.string.channel_list_user_or_group_id)) },
value = searchBarViewModel.searchValue,
onValueChange = {
searchBarViewModel.updateSearchValue(it)
@ -297,7 +297,7 @@ private fun SearchEditTextForJoin(
},
placeholder = {
Text(
text = stringResource(R.string.channel_list_user_or_group_id_demo),
text = stringRes(R.string.channel_list_user_or_group_id_demo),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -311,7 +311,7 @@ private fun SearchEditTextForJoin(
) {
Icon(
imageVector = Icons.Default.Clear,
contentDescription = stringResource(R.string.clear),
contentDescription = stringRes(R.string.clear),
)
}
}

View File

@ -38,7 +38,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.unit.dp
@ -48,6 +47,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.PublicChatChannel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@Composable
@ -87,20 +87,21 @@ fun NewChannelView(
postViewModel.create()
onClose()
},
postViewModel.channelName.value.text.isNotBlank(),
postViewModel.channelName.value.text
.isNotBlank(),
)
}
Spacer(modifier = Modifier.height(15.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.channel_name)) },
label = { Text(text = stringRes(R.string.channel_name)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.channelName.value,
onValueChange = { postViewModel.channelName.value = it },
placeholder = {
Text(
text = stringResource(R.string.my_awesome_group),
text = stringRes(R.string.my_awesome_group),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -114,7 +115,7 @@ fun NewChannelView(
Spacer(modifier = Modifier.height(15.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.picture_url)) },
label = { Text(text = stringRes(R.string.picture_url)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.channelPicture.value,
onValueChange = { postViewModel.channelPicture.value = it },
@ -129,13 +130,13 @@ fun NewChannelView(
Spacer(modifier = Modifier.height(15.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.description)) },
label = { Text(text = stringRes(R.string.description)) },
modifier = Modifier.fillMaxWidth().height(100.dp),
value = postViewModel.channelDescription.value,
onValueChange = { postViewModel.channelDescription.value = it },
placeholder = {
Text(
text = stringResource(R.string.about_us),
text = stringRes(R.string.about_us),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -36,6 +36,7 @@ import com.vitorpamplona.amethyst.service.FileHeader
import com.vitorpamplona.amethyst.service.Nip96MediaServers
import com.vitorpamplona.amethyst.service.Nip96Uploader
import com.vitorpamplona.amethyst.ui.components.MediaCompressor
import com.vitorpamplona.amethyst.ui.stringRes
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -114,7 +115,7 @@ open class NewMediaModel : ViewModel() {
}
?: run {
viewModelScope.launch {
onError(context.getString(R.string.could_not_open_the_compressed_file))
onError(stringRes(context, R.string.could_not_open_the_compressed_file))
isUploadingImage = false
uploadingPercentage.value = 0.00f
uploadingDescription.value = null
@ -153,7 +154,7 @@ open class NewMediaModel : ViewModel() {
isUploadingImage = false
uploadingPercentage.value = 0.00f
uploadingDescription.value = null
onError(context.getString(R.string.failed_to_upload_media, e.message))
onError(stringRes(context, R.string.failed_to_upload_media, e.message))
}
}
}
@ -162,7 +163,7 @@ open class NewMediaModel : ViewModel() {
isUploadingImage = false
uploadingPercentage.value = 0.00f
uploadingDescription.value = null
onError(context.getString(R.string.error_when_compressing_media, it))
onError(stringRes(context, R.string.error_when_compressing_media, it))
},
)
}
@ -179,9 +180,7 @@ open class NewMediaModel : ViewModel() {
selectedServer = ServerOption(defaultServer(), false)
}
fun canPost(): Boolean {
return !isUploadingImage && galleryUri != null && selectedServer != null
}
fun canPost(): Boolean = !isUploadingImage && galleryUri != null && selectedServer != null
suspend fun createNIP94Record(
uploadingResult: Nip96Uploader.PartialEvent,
@ -197,11 +196,20 @@ open class NewMediaModel : ViewModel() {
val imageUrl = uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "url" }?.get(1)
val remoteMimeType =
uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "m" }?.get(1)?.ifBlank { null }
uploadingResult.tags
?.firstOrNull { it.size > 1 && it[0] == "m" }
?.get(1)
?.ifBlank { null }
val originalHash =
uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "ox" }?.get(1)?.ifBlank { null }
uploadingResult.tags
?.firstOrNull { it.size > 1 && it[0] == "ox" }
?.get(1)
?.ifBlank { null }
val dim =
uploadingResult.tags?.firstOrNull { it.size > 1 && it[0] == "dim" }?.get(1)?.ifBlank { null }
uploadingResult.tags
?.firstOrNull { it.size > 1 && it[0] == "dim" }
?.get(1)
?.ifBlank { null }
val magnet =
uploadingResult.tags
?.firstOrNull { it.size > 1 && it[0] == "magnet" }
@ -214,7 +222,7 @@ open class NewMediaModel : ViewModel() {
uploadingPercentage.value = 0.00f
uploadingDescription.value = null
isUploadingImage = false
onError(context.getString(R.string.server_did_not_provide_a_url_after_uploading))
onError(stringRes(context, R.string.server_did_not_provide_a_url_after_uploading))
return
}
@ -254,7 +262,7 @@ open class NewMediaModel : ViewModel() {
uploadingPercentage.value = 0.00f
uploadingDescription.value = null
isUploadingImage = false
onError(context.getString(R.string.could_not_prepare_local_file_to_upload, it))
onError(stringRes(context, R.string.could_not_prepare_local_file_to_upload, it))
},
)
} else {
@ -263,7 +271,7 @@ open class NewMediaModel : ViewModel() {
uploadingPercentage.value = 0.00f
uploadingDescription.value = null
isUploadingImage = false
onError(context.getString(R.string.could_not_download_from_the_server))
onError(stringRes(context, R.string.could_not_download_from_the_server))
}
}
@ -312,7 +320,7 @@ open class NewMediaModel : ViewModel() {
uploadingPercentage.value = 0.00f
isUploadingImage = false
cancel()
onError(context.getString(R.string.could_not_prepare_local_file_to_upload, it))
onError(stringRes(context, R.string.could_not_prepare_local_file_to_upload, it))
},
)
}

View File

@ -58,7 +58,6 @@ import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
@ -70,6 +69,7 @@ import com.vitorpamplona.amethyst.ui.components.VideoView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CancellationException
@ -93,7 +93,7 @@ fun NewMediaView(
LaunchedEffect(uri) {
val mediaType = resolver.getType(uri) ?: ""
postViewModel.load(account, uri, mediaType) {
accountViewModel.toast(context.getString(R.string.failed_to_upload_media_no_details), it)
accountViewModel.toast(stringRes(context, R.string.failed_to_upload_media_no_details), it)
}
}
@ -124,7 +124,8 @@ fun NewMediaView(
Column(
modifier =
Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp)
Modifier
.padding(start = 10.dp, end = 10.dp, top = 10.dp)
.fillMaxWidth()
.fillMaxHeight()
.imePadding(),
@ -194,7 +195,7 @@ fun ImageVideoPost(
ServerOption(
Nip96MediaServers.ServerName(
"NIP95",
stringResource(id = R.string.upload_server_relays_nip95),
stringRes(id = R.string.upload_server_relays_nip95),
),
true,
),
@ -209,7 +210,8 @@ fun ImageVideoPost(
Row(
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier.fillMaxWidth()
Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)
.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)),
) {
@ -219,7 +221,8 @@ fun ImageVideoPost(
contentDescription = postViewModel.galleryUri.toString(),
contentScale = ContentScale.FillWidth,
modifier =
Modifier.padding(top = 4.dp)
Modifier
.padding(top = 4.dp)
.fillMaxWidth()
.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)),
)
@ -265,7 +268,7 @@ fun ImageVideoPost(
modifier = Modifier.fillMaxWidth(),
) {
TextSpinner(
label = stringResource(id = R.string.file_server),
label = stringRes(id = R.string.file_server),
placeholder =
fileServers
.firstOrNull { it.server == accountViewModel.account.defaultFileServer }
@ -296,13 +299,13 @@ fun ImageVideoPost(
modifier = Modifier.fillMaxWidth().windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)),
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.content_description)) },
label = { Text(text = stringRes(R.string.content_description)) },
modifier = Modifier.fillMaxWidth().windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)),
value = postViewModel.alt,
onValueChange = { postViewModel.alt = it },
placeholder = {
Text(
text = stringResource(R.string.content_description_example),
text = stringRes(R.string.content_description_example),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -36,12 +36,12 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
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.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.CancellationException
@ -87,13 +87,13 @@ fun NewPollClosing(pollViewModel: NewPostViewModel) {
colors = if (pollViewModel.isValidClosedAt.value) colorValid else colorInValid,
label = {
Text(
text = stringResource(R.string.poll_closing_time),
text = stringRes(R.string.poll_closing_time),
color = MaterialTheme.colorScheme.placeholderText,
)
},
placeholder = {
Text(
text = stringResource(R.string.poll_closing_time_days),
text = stringRes(R.string.poll_closing_time_days),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -36,12 +36,12 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
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.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.CancellationException
@ -87,13 +87,13 @@ fun NewPollConsensusThreshold(pollViewModel: NewPostViewModel) {
colors = if (pollViewModel.isValidConsensusThreshold.value) colorValid else colorInValid,
label = {
Text(
text = stringResource(R.string.poll_consensus_threshold),
text = stringRes(R.string.poll_consensus_threshold),
color = MaterialTheme.colorScheme.placeholderText,
)
},
placeholder = {
Text(
text = stringResource(R.string.poll_consensus_threshold_percent),
text = stringRes(R.string.poll_consensus_threshold_percent),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -31,10 +31,10 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.tooling.preview.Preview
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@Composable
@ -51,7 +51,7 @@ fun NewPollOption(
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = stringResource(R.string.clear),
contentDescription = stringRes(R.string.clear),
)
}
}
@ -64,13 +64,13 @@ fun NewPollOption(
},
label = {
Text(
text = stringResource(R.string.poll_option_index).format(optionIndex + 1),
text = stringRes(R.string.poll_option_index).format(optionIndex + 1),
color = MaterialTheme.colorScheme.placeholderText,
)
},
placeholder = {
Text(
text = stringResource(R.string.poll_option_description),
text = stringRes(R.string.poll_option_description),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -37,13 +37,13 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
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.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@OptIn(ExperimentalComposeUiApi::class)
@ -74,7 +74,7 @@ fun NewPollPrimaryDescription(pollViewModel: NewPostViewModel) {
onValueChange = { pollViewModel.updateMessage(it) },
label = {
Text(
text = stringResource(R.string.poll_primary_description),
text = stringRes(R.string.poll_primary_description),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -90,7 +90,7 @@ fun NewPollPrimaryDescription(pollViewModel: NewPostViewModel) {
},
placeholder = {
Text(
text = stringResource(R.string.poll_primary_description),
text = stringRes(R.string.poll_primary_description),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -26,10 +26,10 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@Composable
@ -51,13 +51,13 @@ fun NewPollRecipientsField(
enabled = false,
label = {
Text(
text = stringResource(R.string.poll_zap_recipients),
text = stringRes(R.string.poll_zap_recipients),
color = MaterialTheme.colorScheme.placeholderText,
)
},
placeholder = {
Text(
text = stringResource(R.string.poll_zap_recipients),
text = stringRes(R.string.poll_zap_recipients),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -34,11 +34,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
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.stringRes
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@ -67,13 +67,13 @@ fun NewPollVoteValueRange(pollViewModel: NewPostViewModel) {
colors = if (pollViewModel.isValidvalueMinimum.value) colorValid else colorInValid,
label = {
Text(
text = stringResource(R.string.poll_zap_value_min),
text = stringRes(R.string.poll_zap_value_min),
color = MaterialTheme.colorScheme.placeholderText,
)
},
placeholder = {
Text(
text = stringResource(R.string.sats),
text = stringRes(R.string.sats),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -89,13 +89,13 @@ fun NewPollVoteValueRange(pollViewModel: NewPostViewModel) {
colors = if (pollViewModel.isValidvalueMaximum.value) colorValid else colorInValid,
label = {
Text(
text = stringResource(R.string.poll_zap_value_max),
text = stringRes(R.string.poll_zap_value_max),
color = MaterialTheme.colorScheme.placeholderText,
)
},
placeholder = {
Text(
text = stringResource(R.string.sats),
text = stringRes(R.string.sats),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -107,7 +107,7 @@ fun NewPollVoteValueRange(pollViewModel: NewPostViewModel) {
horizontalArrangement = Arrangement.Center,
) {
Text(
text = stringResource(R.string.poll_zap_value_min_max_explainer),
text = stringRes(R.string.poll_zap_value_min_max_explainer),
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.padding(vertical = 10.dp),
)

View File

@ -105,7 +105,6 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization
@ -150,6 +149,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.MyTextField
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ShowUserSuggestionList
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
@ -276,7 +276,7 @@ fun NewPostView(
) {
Icon(
painter = painterResource(R.drawable.relays),
contentDescription = stringResource(id = R.string.relay_list_selector),
contentDescription = stringRes(id = R.string.relay_list_selector),
modifier = Modifier.height(25.dp),
tint = MaterialTheme.colorScheme.onBackground,
)
@ -510,8 +510,8 @@ fun NewPostView(
lud16,
accountViewModel.account.userProfile().pubkeyHex,
accountViewModel.account,
stringResource(id = R.string.lightning_invoice),
stringResource(id = R.string.lightning_create_and_add_invoice),
stringRes(id = R.string.lightning_invoice),
stringRes(id = R.string.lightning_create_and_add_invoice),
onSuccess = {
postViewModel.insertAtCursor(it)
postViewModel.wantsInvoice = false
@ -530,7 +530,7 @@ fun NewPostView(
modifier = Modifier.padding(vertical = Size5dp, horizontal = Size10dp),
) {
ZapRaiserRequest(
stringResource(id = R.string.zapraiser),
stringRes(id = R.string.zapraiser),
postViewModel,
)
}
@ -574,7 +574,7 @@ private fun BottomRowActions(postViewModel: NewPostViewModel) {
if (postViewModel.canUsePoll) {
// These should be hashtag recommendations the user selects in the future.
// val hashtag = stringResource(R.string.poll_hashtag)
// val hashtag = stringRes(R.string.poll_hashtag)
// postViewModel.includePollHashtagInMessage(postViewModel.wantsPoll, hashtag)
AddPollButton(postViewModel.wantsPoll) {
postViewModel.wantsPoll = !postViewModel.wantsPoll
@ -685,9 +685,9 @@ private fun MessageField(postViewModel: NewPostViewModel) {
Text(
text =
if (postViewModel.wantsProduct) {
stringResource(R.string.description)
stringRes(R.string.description)
} else {
stringResource(R.string.what_s_on_your_mind)
stringRes(R.string.what_s_on_your_mind)
},
color = MaterialTheme.colorScheme.placeholderText,
)
@ -721,7 +721,7 @@ fun ContentSensitivityExplainer(postViewModel: NewPostViewModel) {
) {
Icon(
imageVector = Icons.Default.VisibilityOff,
contentDescription = stringResource(id = R.string.content_warning),
contentDescription = stringRes(id = R.string.content_warning),
modifier =
Modifier
.size(18.dp)
@ -730,7 +730,7 @@ fun ContentSensitivityExplainer(postViewModel: NewPostViewModel) {
)
Icon(
imageVector = Icons.Rounded.Warning,
contentDescription = stringResource(id = R.string.content_warning),
contentDescription = stringRes(id = R.string.content_warning),
modifier =
Modifier
.size(10.dp)
@ -740,7 +740,7 @@ fun ContentSensitivityExplainer(postViewModel: NewPostViewModel) {
}
Text(
text = stringResource(R.string.add_sensitive_content_label),
text = stringRes(R.string.add_sensitive_content_label),
fontSize = 20.sp,
fontWeight = FontWeight.W500,
modifier = Modifier.padding(start = 10.dp),
@ -750,7 +750,7 @@ fun ContentSensitivityExplainer(postViewModel: NewPostViewModel) {
HorizontalDivider(thickness = DividerThickness)
Text(
text = stringResource(R.string.add_sensitive_content_explainer),
text = stringRes(R.string.add_sensitive_content_explainer),
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.padding(vertical = 10.dp),
)
@ -767,7 +767,7 @@ fun SendDirectMessageTo(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.messages_new_message_to),
text = stringRes(R.string.messages_new_message_to),
fontSize = Font14SP,
fontWeight = FontWeight.W500,
)
@ -778,7 +778,7 @@ fun SendDirectMessageTo(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(
text = stringResource(R.string.messages_new_message_to_caption),
text = stringRes(R.string.messages_new_message_to_caption),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -801,7 +801,7 @@ fun SendDirectMessageTo(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.messages_new_message_subject),
text = stringRes(R.string.messages_new_message_subject),
fontSize = Font14SP,
fontWeight = FontWeight.W500,
)
@ -812,7 +812,7 @@ fun SendDirectMessageTo(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(
text = stringResource(R.string.messages_new_message_subject_caption),
text = stringRes(R.string.messages_new_message_subject_caption),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -842,7 +842,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.classifieds_title),
text = stringRes(R.string.classifieds_title),
fontSize = Font14SP,
fontWeight = FontWeight.W500,
)
@ -855,7 +855,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(
text = stringResource(R.string.classifieds_title_placeholder),
text = stringRes(R.string.classifieds_title_placeholder),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -878,7 +878,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.classifieds_price),
text = stringRes(R.string.classifieds_price),
fontSize = Font14SP,
fontWeight = FontWeight.W500,
)
@ -915,7 +915,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.classifieds_condition),
text = stringRes(R.string.classifieds_condition),
fontSize = Font14SP,
fontWeight = FontWeight.W500,
)
@ -924,23 +924,23 @@ fun SellProduct(postViewModel: NewPostViewModel) {
listOf(
Triple(
ClassifiedsEvent.CONDITION.NEW,
stringResource(id = R.string.classifieds_condition_new),
stringResource(id = R.string.classifieds_condition_new_explainer),
stringRes(id = R.string.classifieds_condition_new),
stringRes(id = R.string.classifieds_condition_new_explainer),
),
Triple(
ClassifiedsEvent.CONDITION.USED_LIKE_NEW,
stringResource(id = R.string.classifieds_condition_like_new),
stringResource(id = R.string.classifieds_condition_like_new_explainer),
stringRes(id = R.string.classifieds_condition_like_new),
stringRes(id = R.string.classifieds_condition_like_new_explainer),
),
Triple(
ClassifiedsEvent.CONDITION.USED_GOOD,
stringResource(id = R.string.classifieds_condition_good),
stringResource(id = R.string.classifieds_condition_good_explainer),
stringRes(id = R.string.classifieds_condition_good),
stringRes(id = R.string.classifieds_condition_good_explainer),
),
Triple(
ClassifiedsEvent.CONDITION.USED_FAIR,
stringResource(id = R.string.classifieds_condition_fair),
stringResource(id = R.string.classifieds_condition_fair_explainer),
stringRes(id = R.string.classifieds_condition_fair),
stringRes(id = R.string.classifieds_condition_fair_explainer),
),
)
@ -982,7 +982,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.classifieds_category),
text = stringRes(R.string.classifieds_category),
fontSize = Font14SP,
fontWeight = FontWeight.W500,
)
@ -1007,7 +1007,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
R.string.classifieds_category_other,
)
val categoryTypes = categoryList.map { Triple(it, stringResource(id = it), null) }
val categoryTypes = categoryList.map { Triple(it, stringRes(id = it), null) }
val categoryOptions =
remember {
@ -1048,7 +1048,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.classifieds_location),
text = stringRes(R.string.classifieds_location),
fontSize = Font14SP,
fontWeight = FontWeight.W500,
)
@ -1061,7 +1061,7 @@ fun SellProduct(postViewModel: NewPostViewModel) {
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(
text = stringResource(R.string.classifieds_location_placeholder),
text = stringRes(R.string.classifieds_location_placeholder),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -1099,21 +1099,21 @@ fun FowardZapTo(
ZapSplitIcon()
Text(
text = stringResource(R.string.zap_split_title),
text = stringRes(R.string.zap_split_title),
fontSize = 20.sp,
fontWeight = FontWeight.W500,
modifier = Modifier.padding(horizontal = 10.dp).weight(1f),
)
OutlinedButton(onClick = { postViewModel.updateZapFromText() }) {
Text(text = stringResource(R.string.load_from_text))
Text(text = stringRes(R.string.load_from_text))
}
}
HorizontalDivider(thickness = DividerThickness)
Text(
text = stringResource(R.string.zap_split_explainer),
text = stringRes(R.string.zap_split_explainer),
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.padding(vertical = 10.dp),
)
@ -1154,11 +1154,11 @@ fun FowardZapTo(
OutlinedTextField(
value = postViewModel.forwardZapToEditting,
onValueChange = { postViewModel.updateZapForwardTo(it) },
label = { Text(text = stringResource(R.string.zap_split_search_and_add_user)) },
label = { Text(text = stringRes(R.string.zap_split_search_and_add_user)) },
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(
text = stringResource(R.string.zap_split_search_and_add_user_placeholder),
text = stringRes(R.string.zap_split_search_and_add_user_placeholder),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -1205,7 +1205,7 @@ fun LocationAsHash(postViewModel: NewPostViewModel) {
}
Text(
text = stringResource(R.string.geohash_title),
text = stringRes(R.string.geohash_title),
fontSize = 20.sp,
fontWeight = FontWeight.W500,
modifier = Modifier.padding(start = 10.dp),
@ -1217,7 +1217,7 @@ fun LocationAsHash(postViewModel: NewPostViewModel) {
HorizontalDivider(thickness = DividerThickness)
Text(
text = stringResource(R.string.geohash_explainer),
text = stringRes(R.string.geohash_explainer),
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.padding(vertical = 10.dp),
)
@ -1275,7 +1275,7 @@ fun Notifying(
FlowRow(horizontalArrangement = Arrangement.spacedBy(5.dp)) {
if (!mentions.isNullOrEmpty()) {
Text(
stringResource(R.string.reply_notify),
stringRes(R.string.reply_notify),
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.align(CenterVertically),
@ -1348,7 +1348,7 @@ private fun AddZapraiserButton(
)
Icon(
imageVector = Icons.Default.Bolt,
contentDescription = stringResource(R.string.add_zapraiser),
contentDescription = stringRes(R.string.add_zapraiser),
modifier =
Modifier
.size(13.dp)
@ -1367,7 +1367,7 @@ private fun AddZapraiserButton(
)
Icon(
imageVector = Icons.Default.Bolt,
contentDescription = stringResource(R.string.cancel_zapraiser),
contentDescription = stringRes(R.string.cancel_zapraiser),
modifier =
Modifier
.size(13.dp)
@ -1390,14 +1390,14 @@ fun AddGeoHash(
if (!postViewModel.wantsToAddGeoHash) {
Icon(
imageVector = Icons.Default.LocationOff,
contentDescription = stringResource(id = R.string.add_location),
contentDescription = stringRes(id = R.string.add_location),
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.onBackground,
)
} else {
Icon(
imageVector = Icons.Default.LocationOn,
contentDescription = stringResource(id = R.string.remove_location),
contentDescription = stringRes(id = R.string.remove_location),
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.primary,
)
@ -1416,14 +1416,14 @@ private fun AddLnInvoiceButton(
if (!isLnInvoiceActive) {
Icon(
imageVector = Icons.Default.CurrencyBitcoin,
contentDescription = stringResource(id = R.string.add_bitcoin_invoice),
contentDescription = stringRes(id = R.string.add_bitcoin_invoice),
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.onBackground,
)
} else {
Icon(
imageVector = Icons.Default.CurrencyBitcoin,
contentDescription = stringResource(id = R.string.cancel_bitcoin_invoice),
contentDescription = stringRes(id = R.string.cancel_bitcoin_invoice),
modifier = Modifier.size(20.dp),
tint = BitcoinOrange,
)
@ -1458,14 +1458,14 @@ private fun AddClassifiedsButton(
if (!postViewModel.wantsProduct) {
Icon(
imageVector = Icons.Default.Sell,
contentDescription = stringResource(R.string.classifieds),
contentDescription = stringRes(R.string.classifieds),
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.onBackground,
)
} else {
Icon(
imageVector = Icons.Default.Sell,
contentDescription = stringResource(id = R.string.cancel_classifieds),
contentDescription = stringRes(id = R.string.cancel_classifieds),
modifier = Modifier.size(20.dp),
tint = BitcoinOrange,
)
@ -1489,7 +1489,7 @@ private fun MarkAsSensitive(
if (!postViewModel.wantsToMarkAsSensitive) {
Icon(
imageVector = Icons.Default.Visibility,
contentDescription = stringResource(R.string.add_content_warning),
contentDescription = stringRes(R.string.add_content_warning),
modifier =
Modifier
.size(18.dp)
@ -1498,7 +1498,7 @@ private fun MarkAsSensitive(
)
Icon(
imageVector = Icons.Rounded.Warning,
contentDescription = stringResource(R.string.add_content_warning),
contentDescription = stringRes(R.string.add_content_warning),
modifier =
Modifier
.size(10.dp)
@ -1508,7 +1508,7 @@ private fun MarkAsSensitive(
} else {
Icon(
imageVector = Icons.Default.VisibilityOff,
contentDescription = stringResource(id = R.string.remove_content_warning),
contentDescription = stringRes(id = R.string.remove_content_warning),
modifier =
Modifier
.size(18.dp)
@ -1517,7 +1517,7 @@ private fun MarkAsSensitive(
)
Icon(
imageVector = Icons.Rounded.Warning,
contentDescription = stringResource(id = R.string.remove_content_warning),
contentDescription = stringRes(id = R.string.remove_content_warning),
modifier =
Modifier
.size(10.dp)
@ -1550,7 +1550,7 @@ fun PostButton(
enabled = isActive,
onClick = onPost,
) {
Text(text = stringResource(R.string.post))
Text(text = stringRes(R.string.post))
}
}
@ -1565,7 +1565,7 @@ fun SaveButton(
modifier = modifier,
onClick = onPost,
) {
Text(text = stringResource(R.string.save))
Text(text = stringRes(R.string.save))
}
}
@ -1588,7 +1588,7 @@ fun CreateButton(
containerColor = if (isActive) MaterialTheme.colorScheme.primary else Color.Gray,
),
) {
Text(text = stringResource(R.string.create), color = Color.White)
Text(text = stringRes(R.string.create), color = Color.White)
}
}
@ -1613,7 +1613,7 @@ fun ImageVideoDescription(
ServerOption(
Nip96MediaServers.ServerName(
"NIP95",
stringResource(id = R.string.upload_server_relays_nip95),
stringRes(id = R.string.upload_server_relays_nip95),
),
true,
),
@ -1655,7 +1655,7 @@ fun ImageVideoDescription(
) {
Text(
text =
stringResource(
stringRes(
if (isImage) {
R.string.content_description_add_image
} else {
@ -1745,7 +1745,7 @@ fun ImageVideoDescription(
modifier = Modifier.fillMaxWidth(),
) {
TextSpinner(
label = stringResource(id = R.string.file_server),
label = stringRes(id = R.string.file_server),
placeholder =
fileServers
.firstOrNull { it.server == accountViewModel.account.defaultFileServer }
@ -1785,7 +1785,7 @@ fun ImageVideoDescription(
.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)),
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.content_description)) },
label = { Text(text = stringRes(R.string.content_description)) },
modifier =
Modifier
.fillMaxWidth()
@ -1794,7 +1794,7 @@ fun ImageVideoDescription(
onValueChange = { message = it },
placeholder = {
Text(
text = stringResource(R.string.content_description_example),
text = stringRes(R.string.content_description_example),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -1817,7 +1817,7 @@ fun ImageVideoDescription(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(text = stringResource(R.string.add_content), color = Color.White, fontSize = 20.sp)
Text(text = stringRes(R.string.add_content), color = Color.White, fontSize = 20.sp)
}
}
}
@ -1851,12 +1851,12 @@ fun SettingSwitchItem(
verticalArrangement = Arrangement.spacedBy(Size5dp),
) {
Text(
text = stringResource(id = title),
text = stringRes(id = title),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
text = stringResource(id = description),
text = stringRes(id = description),
style = MaterialTheme.typography.bodySmall,
color = Color.Gray,
maxLines = 2,

View File

@ -40,7 +40,6 @@ 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.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
@ -48,6 +47,7 @@ import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -108,13 +108,13 @@ fun NewUserMetadataView(
modifier = Modifier.padding(10.dp).verticalScroll(rememberScrollState()),
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.display_name)) },
label = { Text(text = stringRes(R.string.display_name)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.displayName.value,
onValueChange = { postViewModel.displayName.value = it },
placeholder = {
Text(
text = stringResource(R.string.my_display_name),
text = stringRes(R.string.my_display_name),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -128,13 +128,13 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.about_me)) },
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 = stringResource(id = R.string.about_me),
text = stringRes(id = R.string.about_me),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -148,7 +148,7 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.avatar_url)) },
label = { Text(text = stringRes(R.string.avatar_url)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.picture.value,
onValueChange = { postViewModel.picture.value = it },
@ -173,7 +173,7 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.banner_url)) },
label = { Text(text = stringRes(R.string.banner_url)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.banner.value,
onValueChange = { postViewModel.banner.value = it },
@ -198,7 +198,7 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.website_url)) },
label = { Text(text = stringRes(R.string.website_url)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.website.value,
onValueChange = { postViewModel.website.value = it },
@ -214,7 +214,7 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.nip_05)) },
label = { Text(text = stringRes(R.string.nip_05)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.nip05.value,
onValueChange = { postViewModel.nip05.value = it },
@ -229,7 +229,7 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.ln_address)) },
label = { Text(text = stringRes(R.string.ln_address)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.lnAddress.value,
onValueChange = { postViewModel.lnAddress.value = it },
@ -245,13 +245,13 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.ln_url_outdated)) },
label = { Text(text = stringRes(R.string.ln_url_outdated)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.lnURL.value,
onValueChange = { postViewModel.lnURL.value = it },
placeholder = {
Text(
text = stringResource(R.string.lnurl),
text = stringRes(R.string.lnurl),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -260,13 +260,13 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.twitter)) },
label = { Text(text = stringRes(R.string.twitter)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.twitter.value,
onValueChange = { postViewModel.twitter.value = it },
placeholder = {
Text(
text = stringResource(R.string.twitter_proof_url_template),
text = stringRes(R.string.twitter_proof_url_template),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -275,13 +275,13 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.mastodon)) },
label = { Text(text = stringRes(R.string.mastodon)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.mastodon.value,
onValueChange = { postViewModel.mastodon.value = it },
placeholder = {
Text(
text = stringResource(R.string.mastodon_proof_url_template),
text = stringRes(R.string.mastodon_proof_url_template),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -290,13 +290,13 @@ fun NewUserMetadataView(
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextField(
label = { Text(text = stringResource(R.string.github)) },
label = { Text(text = stringRes(R.string.github)) },
modifier = Modifier.fillMaxWidth(),
value = postViewModel.github.value,
onValueChange = { postViewModel.github.value = it },
placeholder = {
Text(
text = stringResource(R.string.github_proof_url_template),
text = stringRes(R.string.github_proof_url_template),
color = MaterialTheme.colorScheme.placeholderText,
)
},

View File

@ -38,10 +38,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size16dp
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.quartz.events.EmptyTagList
@ -89,7 +89,7 @@ fun NotifyRequestDialog(
contentDescription = null,
)
Spacer(StdHorzSpacer)
Text(stringResource(R.string.error_dialog_button_ok))
Text(stringRes(R.string.error_dialog_button_ok))
}
}
},

View File

@ -51,6 +51,7 @@ import com.vitorpamplona.amethyst.model.RelaySetupInfo
import com.vitorpamplona.amethyst.service.Nip11Retriever
import com.vitorpamplona.amethyst.ui.actions.relays.RelayInformationDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
import com.vitorpamplona.quartz.encoders.Nip11RelayInformation
import kotlinx.collections.immutable.ImmutableList
@ -141,7 +142,7 @@ fun RelaySelectionDialog(
}
RelaySwitch(
text = context.getString(R.string.select_deselect_all),
text = stringRes(context, R.string.select_deselect_all),
checked = selected,
onClick = {
selected = !selected
@ -185,25 +186,29 @@ fun RelaySelectionDialog(
val msg =
when (errorCode) {
Nip11Retriever.ErrorCode.FAIL_TO_ASSEMBLE_URL ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_TO_REACH_SERVER ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_TO_PARSE_RESULT ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_WITH_HTTP_STATUS ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
@ -211,7 +216,7 @@ fun RelaySelectionDialog(
}
accountViewModel.toast(
context.getString(R.string.unable_to_download_relay_document),
stringRes(context, R.string.unable_to_download_relay_document),
msg,
)
},

View File

@ -28,11 +28,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import kotlinx.coroutines.launch
import java.io.File
@ -54,22 +54,22 @@ fun SaveToGallery(url: String) {
url = url,
onSuccess = {
scope.launch {
Toast.makeText(
Toast
.makeText(
localContext,
localContext.getString(R.string.image_saved_to_the_gallery),
stringRes(localContext, R.string.image_saved_to_the_gallery),
Toast.LENGTH_SHORT,
)
.show()
).show()
}
},
onError = {
scope.launch {
Toast.makeText(
Toast
.makeText(
localContext,
localContext.getString(R.string.failed_to_save_the_image),
stringRes(localContext, R.string.failed_to_save_the_image),
Toast.LENGTH_SHORT,
)
.show()
).show()
}
},
)
@ -96,7 +96,7 @@ fun SaveToGallery(url: String) {
}
},
) {
Text(text = stringResource(id = R.string.save))
Text(text = stringRes(id = R.string.save))
}
}
@ -116,22 +116,22 @@ fun SaveToGallery(
mimeType = mimeType,
onSuccess = {
scope.launch {
Toast.makeText(
Toast
.makeText(
localContext,
localContext.getString(R.string.image_saved_to_the_gallery),
stringRes(localContext, R.string.image_saved_to_the_gallery),
Toast.LENGTH_SHORT,
)
.show()
).show()
}
},
onError = {
scope.launch {
Toast.makeText(
Toast
.makeText(
localContext,
localContext.getString(R.string.failed_to_save_the_image),
stringRes(localContext, R.string.failed_to_save_the_image),
Toast.LENGTH_SHORT,
)
.show()
).show()
}
},
)
@ -159,6 +159,6 @@ fun SaveToGallery(
},
shape = ButtonBorder,
) {
Text(text = stringResource(id = R.string.save))
Text(text = stringRes(id = R.string.save))
}
}

View File

@ -50,7 +50,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.google.accompanist.permissions.ExperimentalPermissionsApi
@ -58,6 +57,7 @@ import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.GetMediaActivityResultContract
import com.vitorpamplona.amethyst.ui.stringRes
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import java.util.concurrent.atomic.AtomicBoolean
@ -114,7 +114,7 @@ private fun UploadBoxButton(
if (!isUploading) {
Icon(
imageVector = Icons.Default.AddPhotoAlternate,
contentDescription = stringResource(id = R.string.upload_image),
contentDescription = stringRes(id = R.string.upload_image),
modifier = Modifier.height(25.dp),
tint = tint,
)
@ -137,8 +137,7 @@ val DefaultAnimationColors =
Color(0xFFFCAF45),
Color(0xFFFFDC80),
Color(0xFF5851D8),
)
.toImmutableList()
).toImmutableList()
@Composable
fun LoadingAnimation(
@ -164,7 +163,8 @@ fun LoadingAnimation(
CircularProgressIndicator(
modifier =
Modifier.size(size = indicatorSize)
Modifier
.size(size = indicatorSize)
.rotate(degrees = rotateAnimation)
.border(
width = 4.dp,

View File

@ -37,7 +37,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
@ -46,6 +45,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.actions.CloseButton
import com.vitorpamplona.amethyst.ui.actions.SaveButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.imageModifier
@ -76,7 +76,7 @@ fun AddDMRelayListDialog(
) {
Spacer(modifier = StdHorzSpacer)
Text(stringResource(R.string.dm_relays_title))
Text(stringRes(R.string.dm_relays_title))
SaveButton(
onPost = {
@ -126,13 +126,13 @@ private fun Explanation() {
Card(modifier = MaterialTheme.colorScheme.imageModifier) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(id = R.string.dm_relays_not_found_editing),
text = stringRes(id = R.string.dm_relays_not_found_editing),
)
Spacer(modifier = StdVertSpacer)
Text(
text = stringResource(id = R.string.dm_relays_not_found_examples),
text = stringRes(id = R.string.dm_relays_not_found_examples),
)
}
}

View File

@ -37,7 +37,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
@ -46,6 +45,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.actions.CloseButton
import com.vitorpamplona.amethyst.ui.actions.SaveButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.imageModifier
@ -76,7 +76,7 @@ fun AddSearchRelayListDialog(
) {
Spacer(modifier = StdHorzSpacer)
Text(stringResource(R.string.search_relays_title))
Text(stringRes(R.string.search_relays_title))
SaveButton(
onPost = {
@ -126,13 +126,13 @@ private fun Explanation() {
Card(modifier = MaterialTheme.colorScheme.imageModifier) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = stringResource(id = R.string.search_relays_not_found_editing),
text = stringRes(id = R.string.search_relays_not_found_editing),
)
Spacer(modifier = StdVertSpacer)
Text(
text = stringResource(id = R.string.search_relays_not_found_examples),
text = stringRes(id = R.string.search_relays_not_found_examples),
)
}
}

View File

@ -40,7 +40,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
@ -52,6 +51,7 @@ import com.vitorpamplona.amethyst.service.relays.RelayStat
import com.vitorpamplona.amethyst.ui.actions.CloseButton
import com.vitorpamplona.amethyst.ui.actions.SaveButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
import com.vitorpamplona.amethyst.ui.theme.MinHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
@ -110,7 +110,7 @@ fun AllRelayListView(
Spacer(modifier = MinHorzSpacer)
Text(
text = stringResource(R.string.relay_settings),
text = stringRes(R.string.relay_settings),
style = MaterialTheme.typography.titleLarge,
)
@ -166,8 +166,8 @@ fun AllRelayListView(
LazyColumn(contentPadding = FeedPadding) {
item {
SettingsCategory(
stringResource(R.string.public_home_section),
stringResource(R.string.public_home_section_explainer),
stringRes(R.string.public_home_section),
stringRes(R.string.public_home_section_explainer),
Modifier.padding(bottom = 8.dp),
)
}
@ -175,32 +175,32 @@ fun AllRelayListView(
item {
SettingsCategory(
stringResource(R.string.public_notif_section),
stringResource(R.string.public_notif_section_explainer),
stringRes(R.string.public_notif_section),
stringRes(R.string.public_notif_section_explainer),
)
}
renderNip65NotifItems(notifFeedState, nip65ViewModel, accountViewModel, onClose, nav)
item {
SettingsCategory(
stringResource(R.string.private_inbox_section),
stringResource(R.string.private_inbox_section_explainer),
stringRes(R.string.private_inbox_section),
stringRes(R.string.private_inbox_section_explainer),
)
}
renderDMItems(dmFeedState, dmViewModel, accountViewModel, onClose, nav)
item {
SettingsCategory(
stringResource(R.string.private_outbox_section),
stringResource(R.string.private_outbox_section_explainer),
stringRes(R.string.private_outbox_section),
stringRes(R.string.private_outbox_section_explainer),
)
}
renderPrivateOutboxItems(privateOutboxFeedState, privateOutboxViewModel, accountViewModel, onClose, nav)
item {
SettingsCategoryWithButton(
stringResource(R.string.search_section),
stringResource(R.string.search_section_explainer),
stringRes(R.string.search_section),
stringRes(R.string.search_section_explainer),
action = {
ResetSearchRelays(searchViewModel)
},
@ -210,16 +210,16 @@ fun AllRelayListView(
item {
SettingsCategory(
stringResource(R.string.local_section),
stringResource(R.string.local_section_explainer),
stringRes(R.string.local_section),
stringRes(R.string.local_section_explainer),
)
}
renderLocalItems(localFeedState, localViewModel, accountViewModel, onClose, nav)
item {
SettingsCategoryWithButton(
stringResource(R.string.kind_3_section),
stringResource(R.string.kind_3_section_description),
stringRes(R.string.kind_3_section),
stringRes(R.string.kind_3_section_description),
action = {
ResetKind3Relays(kind3ViewModel)
},
@ -241,7 +241,7 @@ fun ResetKind3Relays(postViewModel: Kind3RelayListViewModel) {
postViewModel.loadRelayDocuments()
},
) {
Text(stringResource(R.string.default_relays))
Text(stringRes(R.string.default_relays))
}
}
@ -254,7 +254,7 @@ fun ResetSearchRelays(postViewModel: SearchRelayListViewModel) {
postViewModel.loadRelayDocuments()
},
) {
Text(stringResource(R.string.default_relays))
Text(stringRes(R.string.default_relays))
}
}

View File

@ -32,6 +32,7 @@ import com.vitorpamplona.amethyst.model.RelayBriefInfoCache
import com.vitorpamplona.amethyst.service.Nip11Retriever
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
@Composable
fun BasicRelaySetupInfoDialog(
@ -69,28 +70,32 @@ fun BasicRelaySetupInfoDialog(
val msg =
when (errorCode) {
Nip11Retriever.ErrorCode.FAIL_TO_ASSEMBLE_URL ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_TO_REACH_SERVER ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_TO_PARSE_RESULT ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_WITH_HTTP_STATUS ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
@ -98,7 +103,7 @@ fun BasicRelaySetupInfoDialog(
}
accountViewModel.toast(
context.getString(R.string.unable_to_download_relay_document),
stringRes(context, R.string.unable_to_download_relay_document),
msg,
)
},

View File

@ -27,7 +27,6 @@ import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel

View File

@ -61,7 +61,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -77,6 +76,7 @@ import com.vitorpamplona.amethyst.service.relays.RelayStat
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
@ -224,28 +224,32 @@ fun LoadRelayInfo(
val msg =
when (errorCode) {
Nip11Retriever.ErrorCode.FAIL_TO_ASSEMBLE_URL ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_TO_REACH_SERVER ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_TO_PARSE_RESULT ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
)
Nip11Retriever.ErrorCode.FAIL_WITH_HTTP_STATUS ->
context.getString(
stringRes(
context,
R.string.relay_information_document_error_assemble_url,
url,
exceptionMessage,
@ -253,7 +257,7 @@ fun LoadRelayInfo(
}
accountViewModel.toast(
context.getString(R.string.unable_to_download_relay_document),
stringRes(context, R.string.unable_to_download_relay_document),
msg,
)
},
@ -346,7 +350,7 @@ private fun StatusRow(
Icon(
imageVector = Icons.Default.Download,
contentDescription = stringResource(R.string.read_from_relay),
contentDescription = stringRes(R.string.read_from_relay),
modifier =
Modifier
.size(15.dp)
@ -357,7 +361,7 @@ private fun StatusRow(
Toast
.makeText(
context,
context.getString(R.string.read_from_relay),
stringRes(context, R.string.read_from_relay),
Toast.LENGTH_SHORT,
).show()
}
@ -383,7 +387,7 @@ private fun StatusRow(
Icon(
imageVector = Icons.Default.Upload,
stringResource(R.string.write_to_relay),
stringRes(R.string.write_to_relay),
modifier =
Modifier
.size(15.dp)
@ -394,7 +398,7 @@ private fun StatusRow(
Toast
.makeText(
context,
context.getString(R.string.write_to_relay),
stringRes(context, R.string.write_to_relay),
Toast.LENGTH_SHORT,
).show()
}
@ -420,7 +424,7 @@ private fun StatusRow(
Icon(
imageVector = Icons.Default.SyncProblem,
stringResource(R.string.errors),
stringRes(R.string.errors),
modifier =
Modifier
.size(15.dp)
@ -431,7 +435,7 @@ private fun StatusRow(
Toast
.makeText(
context,
context.getString(R.string.errors),
stringRes(context, R.string.errors),
Toast.LENGTH_SHORT,
).show()
}
@ -455,7 +459,7 @@ private fun StatusRow(
Icon(
imageVector = Icons.Default.DeleteSweep,
stringResource(R.string.spam),
stringRes(R.string.spam),
modifier =
Modifier
.size(15.dp)
@ -466,7 +470,7 @@ private fun StatusRow(
Toast
.makeText(
context,
context.getString(R.string.spam),
stringRes(context, R.string.spam),
Toast.LENGTH_SHORT,
).show()
}
@ -502,7 +506,7 @@ private fun ActiveToggles(
val context = LocalContext.current
Text(
text = stringResource(id = R.string.active_for),
text = stringRes(id = R.string.active_for),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = MaterialTheme.colorScheme.placeholderText,
@ -516,7 +520,7 @@ private fun ActiveToggles(
) {
Icon(
painterResource(R.drawable.ic_home),
stringResource(R.string.home_feed),
stringRes(R.string.home_feed),
modifier =
Modifier
.padding(horizontal = 5.dp)
@ -528,7 +532,7 @@ private fun ActiveToggles(
Toast
.makeText(
context,
context.getString(R.string.home_feed),
stringRes(context, R.string.home_feed),
Toast.LENGTH_SHORT,
).show()
}
@ -550,7 +554,7 @@ private fun ActiveToggles(
) {
Icon(
painterResource(R.drawable.ic_dm),
stringResource(R.string.private_message_feed),
stringRes(R.string.private_message_feed),
modifier =
Modifier
.padding(horizontal = 5.dp)
@ -562,7 +566,7 @@ private fun ActiveToggles(
Toast
.makeText(
context,
context.getString(R.string.private_message_feed),
stringRes(context, R.string.private_message_feed),
Toast.LENGTH_SHORT,
).show()
}
@ -584,7 +588,7 @@ private fun ActiveToggles(
) {
Icon(
imageVector = Icons.Default.Groups,
contentDescription = stringResource(R.string.public_chat_feed),
contentDescription = stringRes(R.string.public_chat_feed),
modifier =
Modifier
.padding(horizontal = 5.dp)
@ -596,7 +600,7 @@ private fun ActiveToggles(
Toast
.makeText(
context,
context.getString(R.string.public_chat_feed),
stringRes(context, R.string.public_chat_feed),
Toast.LENGTH_SHORT,
).show()
}
@ -618,7 +622,7 @@ private fun ActiveToggles(
) {
Icon(
imageVector = Icons.Default.Public,
stringResource(R.string.global_feed),
stringRes(R.string.global_feed),
modifier =
Modifier
.padding(horizontal = 5.dp)
@ -630,7 +634,7 @@ private fun ActiveToggles(
Toast
.makeText(
context,
context.getString(R.string.global_feed),
stringRes(context, R.string.global_feed),
Toast.LENGTH_SHORT,
).show()
}
@ -680,7 +684,7 @@ private fun FirstLine(
) {
Icon(
imageVector = Icons.Default.Cancel,
contentDescription = stringResource(id = R.string.remove),
contentDescription = stringRes(id = R.string.remove),
modifier = Modifier.padding(start = 10.dp).size(15.dp),
tint = WarningColor,
)
@ -699,7 +703,7 @@ fun Kind3RelayEditBox(
Row(verticalAlignment = Alignment.CenterVertically) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.add_a_relay)) },
label = { Text(text = stringRes(R.string.add_a_relay)) },
modifier = Modifier.weight(1f),
value = url,
onValueChange = { url = it },
@ -716,7 +720,7 @@ fun Kind3RelayEditBox(
IconButton(onClick = { read = !read }) {
Icon(
imageVector = Icons.Default.Download,
contentDescription = stringResource(id = R.string.read_from_relay),
contentDescription = stringRes(id = R.string.read_from_relay),
modifier = Modifier.size(Size35dp).padding(horizontal = 5.dp),
tint =
if (read) {
@ -730,7 +734,7 @@ fun Kind3RelayEditBox(
IconButton(onClick = { write = !write }) {
Icon(
imageVector = Icons.Default.Upload,
contentDescription = stringResource(id = R.string.write_to_relay),
contentDescription = stringRes(id = R.string.write_to_relay),
modifier = Modifier.size(Size35dp).padding(horizontal = 5.dp),
tint =
if (write) {
@ -769,7 +773,7 @@ fun Kind3RelayEditBox(
},
),
) {
Text(text = stringResource(id = R.string.add), color = Color.White)
Text(text = stringRes(id = R.string.add), color = Color.White)
}
}
}

View File

@ -27,7 +27,6 @@ import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel

View File

@ -27,7 +27,6 @@ import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel

View File

@ -27,7 +27,6 @@ import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel

View File

@ -42,7 +42,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -62,6 +61,7 @@ import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon
import com.vitorpamplona.amethyst.ui.note.UserCompose
import com.vitorpamplona.amethyst.ui.note.timeAgo
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.StdPadding
@ -144,7 +144,7 @@ fun RelayInformationDialog(
}
}
item {
Section(stringResource(R.string.owner))
Section(stringRes(R.string.owner))
relayInfo.pubkey?.let {
DisplayOwnerInformation(it, accountViewModel) {
@ -154,16 +154,16 @@ fun RelayInformationDialog(
}
}
item {
Section(stringResource(R.string.software))
Section(stringRes(R.string.software))
DisplaySoftwareInformation(relayInfo)
Section(stringResource(R.string.version))
Section(stringRes(R.string.version))
SectionContent(relayInfo.version ?: "")
}
item {
Section(stringResource(R.string.contact))
Section(stringRes(R.string.contact))
Box(modifier = Modifier.padding(start = 10.dp)) {
relayInfo.contact?.let {
@ -178,21 +178,21 @@ fun RelayInformationDialog(
}
}
item {
Section(stringResource(R.string.supports))
Section(stringRes(R.string.supports))
DisplaySupportedNips(relayInfo)
}
item {
relayInfo.fees?.admission?.let {
if (it.isNotEmpty()) {
Section(stringResource(R.string.admission_fees))
Section(stringRes(R.string.admission_fees))
it.forEach { item -> SectionContent("${item.amount?.div(1000) ?: 0} sats") }
}
}
relayInfo.payments_url?.let {
Section(stringResource(R.string.payments_url))
Section(stringRes(R.string.payments_url))
Box(modifier = Modifier.padding(start = 10.dp)) {
ClickableUrl(
@ -204,68 +204,68 @@ fun RelayInformationDialog(
}
item {
relayInfo.limitation?.let {
Section(stringResource(R.string.limitations))
Section(stringRes(R.string.limitations))
val authRequiredText =
if (it.auth_required ?: false) stringResource(R.string.yes) else stringResource(R.string.no)
if (it.auth_required ?: false) stringRes(R.string.yes) else stringRes(R.string.no)
val paymentRequiredText =
if (it.payment_required ?: false) stringResource(R.string.yes) else stringResource(R.string.no)
if (it.payment_required ?: false) stringRes(R.string.yes) else stringRes(R.string.no)
val restrictedWritesText =
if (it.restricted_writes ?: false) stringResource(R.string.yes) else stringResource(R.string.no)
if (it.restricted_writes ?: false) stringRes(R.string.yes) else stringRes(R.string.no)
Column {
SectionContent(
"${stringResource(R.string.message_length)}: ${it.max_message_length ?: 0}",
"${stringRes(R.string.message_length)}: ${it.max_message_length ?: 0}",
)
SectionContent(
"${stringResource(R.string.subscriptions)}: ${it.max_subscriptions ?: 0}",
"${stringRes(R.string.subscriptions)}: ${it.max_subscriptions ?: 0}",
)
SectionContent("${stringResource(R.string.filters)}: ${it.max_filters ?: 0}")
SectionContent("${stringRes(R.string.filters)}: ${it.max_filters ?: 0}")
SectionContent(
"${stringResource(R.string.subscription_id_length)}: ${it.max_subid_length ?: 0}",
"${stringRes(R.string.subscription_id_length)}: ${it.max_subid_length ?: 0}",
)
SectionContent("${stringResource(R.string.minimum_prefix)}: ${it.min_prefix ?: 0}")
SectionContent("${stringRes(R.string.minimum_prefix)}: ${it.min_prefix ?: 0}")
SectionContent(
"${stringResource(R.string.maximum_event_tags)}: ${it.max_event_tags ?: 0}",
"${stringRes(R.string.maximum_event_tags)}: ${it.max_event_tags ?: 0}",
)
SectionContent(
"${stringResource(R.string.content_length)}: ${it.max_content_length ?: 0}",
"${stringRes(R.string.content_length)}: ${it.max_content_length ?: 0}",
)
SectionContent(
"${stringResource(R.string.max_limit)}: ${it.max_limit ?: 0}",
"${stringRes(R.string.max_limit)}: ${it.max_limit ?: 0}",
)
SectionContent("${stringResource(R.string.minimum_pow)}: ${it.min_pow_difficulty ?: 0}")
SectionContent("${stringResource(R.string.auth)}: $authRequiredText")
SectionContent("${stringResource(R.string.payment)}: $paymentRequiredText")
SectionContent("${stringResource(R.string.restricted_writes)}: $restrictedWritesText")
SectionContent("${stringRes(R.string.minimum_pow)}: ${it.min_pow_difficulty ?: 0}")
SectionContent("${stringRes(R.string.auth)}: $authRequiredText")
SectionContent("${stringRes(R.string.payment)}: $paymentRequiredText")
SectionContent("${stringRes(R.string.restricted_writes)}: $restrictedWritesText")
}
}
}
item {
relayInfo.relay_countries?.let {
Section(stringResource(R.string.countries))
Section(stringRes(R.string.countries))
FlowRow { it.forEach { item -> SectionContent(item) } }
}
}
item {
relayInfo.language_tags?.let {
Section(stringResource(R.string.languages))
Section(stringRes(R.string.languages))
FlowRow { it.forEach { item -> SectionContent(item) } }
}
}
item {
relayInfo.tags?.let {
Section(stringResource(R.string.tags))
Section(stringRes(R.string.tags))
FlowRow { it.forEach { item -> SectionContent(item) } }
}
}
item {
relayInfo.posting_policy?.let {
Section(stringResource(R.string.posting_policy))
Section(stringRes(R.string.posting_policy))
Box(Modifier.padding(10.dp)) {
ClickableUrl(
@ -277,7 +277,7 @@ fun RelayInformationDialog(
}
item {
Section(stringResource(R.string.relay_error_messages))
Section(stringRes(R.string.relay_error_messages))
}
items(messages) { msg ->

View File

@ -34,10 +34,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.WarningColor
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
@ -76,7 +76,7 @@ fun RelayNameAndRemoveButton(
) {
Icon(
imageVector = Icons.Default.Cancel,
contentDescription = stringResource(id = R.string.remove),
contentDescription = stringRes(id = R.string.remove),
modifier =
Modifier
.padding(start = 10.dp)

View File

@ -36,11 +36,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.amethyst.ui.theme.warningColor
@ -58,7 +58,7 @@ fun RelayStatusRow(
Icon(
imageVector = Icons.Default.Download,
contentDescription = stringResource(R.string.read_from_relay),
contentDescription = stringRes(R.string.read_from_relay),
modifier =
Modifier
.size(15.dp)
@ -84,7 +84,7 @@ fun RelayStatusRow(
Icon(
imageVector = Icons.Default.Upload,
stringResource(R.string.write_to_relay),
stringRes(R.string.write_to_relay),
modifier =
Modifier
.size(15.dp)
@ -110,7 +110,7 @@ fun RelayStatusRow(
Icon(
imageVector = Icons.Default.SyncProblem,
stringResource(R.string.errors),
stringRes(R.string.errors),
modifier =
Modifier
.size(15.dp)
@ -141,7 +141,7 @@ fun RelayStatusRow(
Icon(
imageVector = Icons.Default.DeleteSweep,
stringResource(R.string.spam),
stringRes(R.string.spam),
modifier =
Modifier
.size(15.dp)
@ -153,12 +153,12 @@ fun RelayStatusRow(
R.string.spam_description,
)
scope.launch {
Toast.makeText(
Toast
.makeText(
context,
context.getString(R.string.spam),
stringRes(context, R.string.spam),
Toast.LENGTH_SHORT,
)
.show()
).show()
}
},
),

View File

@ -35,9 +35,9 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.service.relays.RelayStat
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@ -49,7 +49,7 @@ fun RelayUrlEditField(onNewRelay: (BasicRelaySetupInfo) -> Unit) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(Size10dp)) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.add_a_relay)) },
label = { Text(text = stringRes(R.string.add_a_relay)) },
modifier = Modifier.weight(1f),
value = url,
onValueChange = { url = it },
@ -81,7 +81,7 @@ fun RelayUrlEditField(onNewRelay: (BasicRelaySetupInfo) -> Unit) {
},
),
) {
Text(text = stringResource(id = R.string.add), color = Color.White)
Text(text = stringRes(id = R.string.add), color = Color.White)
}
}
}

View File

@ -27,7 +27,6 @@ import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel

View File

@ -38,13 +38,13 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.actions.NewChannelView
import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Font12SP
import com.vitorpamplona.amethyst.ui.theme.Size55Modifier
@ -86,7 +86,7 @@ fun ChannelFabColumn(
containerColor = MaterialTheme.colorScheme.primary,
) {
Text(
text = stringResource(R.string.messages_new_message),
text = stringRes(R.string.messages_new_message),
color = Color.White,
textAlign = TextAlign.Center,
fontSize = Font12SP,
@ -105,7 +105,7 @@ fun ChannelFabColumn(
containerColor = MaterialTheme.colorScheme.primary,
) {
Text(
text = stringResource(R.string.messages_create_public_chat),
text = stringRes(R.string.messages_create_public_chat),
color = Color.White,
textAlign = TextAlign.Center,
fontSize = Font12SP,
@ -123,7 +123,7 @@ fun ChannelFabColumn(
) {
Icon(
imageVector = Icons.Outlined.Add,
contentDescription = stringResource(R.string.messages_create_public_private_chat_description),
contentDescription = stringRes(R.string.messages_create_public_private_chat_description),
modifier = Modifier.size(26.dp),
tint = Color.White,
)

View File

@ -35,11 +35,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.actions.NewChannelView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size55Modifier
import com.vitorpamplona.amethyst.ui.theme.ZeroPadding
@ -61,7 +61,7 @@ fun NewChannelButton(accountViewModel: AccountViewModel) {
) {
Icon(
imageVector = Icons.Outlined.Add,
contentDescription = stringResource(R.string.new_channel),
contentDescription = stringRes(R.string.new_channel),
modifier = Modifier.size(26.dp),
tint = Color.White,
)

View File

@ -33,13 +33,13 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.components.LoadNote
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size55Modifier
@Composable
@ -73,7 +73,7 @@ fun NewCommunityNoteButton(
) {
Icon(
painter = painterResource(R.drawable.ic_compose),
contentDescription = stringResource(id = R.string.new_community_note),
contentDescription = stringRes(id = R.string.new_community_note),
modifier = Modifier.size(26.dp),
tint = Color.White,
)

View File

@ -46,7 +46,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -60,6 +59,7 @@ import com.vitorpamplona.amethyst.ui.actions.NewMediaModel
import com.vitorpamplona.amethyst.ui.actions.NewMediaView
import com.vitorpamplona.amethyst.ui.navigation.Route
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size55Modifier
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -136,7 +136,7 @@ fun NewImageButton(
) {
Icon(
painter = painterResource(R.drawable.ic_compose),
contentDescription = stringResource(id = R.string.new_short),
contentDescription = stringRes(id = R.string.new_short),
modifier = Modifier.size(26.dp),
tint = Color.White,
)
@ -152,8 +152,7 @@ private fun ShowProgress(postViewModel: NewMediaModel) {
animateFloatAsState(
targetValue = postViewModel.uploadingPercentage.value,
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
)
.value,
).value,
modifier =
Size55Modifier
.clip(CircleShape)

View File

@ -33,11 +33,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size55Modifier
@Composable
@ -59,7 +59,7 @@ fun NewNoteButton(
) {
Icon(
painter = painterResource(R.drawable.ic_compose),
contentDescription = stringResource(R.string.new_post),
contentDescription = stringRes(R.string.new_post),
modifier = Modifier.size(26.dp),
tint = Color.White,
)

View File

@ -52,7 +52,6 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDirection
@ -76,6 +75,7 @@ import com.vitorpamplona.amethyst.ui.note.OpenInNewIcon
import com.vitorpamplona.amethyst.ui.note.ZapIcon
import com.vitorpamplona.amethyst.ui.screen.SharedPreferencesViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.AmethystTheme
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
@ -190,7 +190,7 @@ fun CashuPreview(
)
Text(
text = stringResource(R.string.cashu),
text = stringRes(R.string.cashu),
fontSize = 20.sp,
fontWeight = FontWeight.W500,
modifier = Modifier.padding(start = 10.dp),
@ -200,7 +200,7 @@ fun CashuPreview(
HorizontalDivider(thickness = DividerThickness)
Text(
text = "${token.totalAmount} ${stringResource(id = R.string.sats)}",
text = "${token.totalAmount} ${stringRes(id = R.string.sats)}",
fontSize = 25.sp,
fontWeight = FontWeight.W500,
modifier =
@ -239,7 +239,7 @@ fun CashuPreview(
Spacer(DoubleHorzSpacer)
Text(
stringResource(id = R.string.cashu_redeem_to_zap),
stringRes(id = R.string.cashu_redeem_to_zap),
color = Color.White,
fontSize = 16.sp,
)
@ -256,7 +256,7 @@ fun CashuPreview(
startActivity(context, intent, null)
} catch (e: Exception) {
if (e is CancellationException) throw e
toast("Cashu", context.getString(R.string.cashu_no_wallet_found))
toast(stringRes(context, R.string.cashu), stringRes(context, R.string.cashu_no_wallet_found))
}
},
shape = QuoteBorder,
@ -268,7 +268,7 @@ fun CashuPreview(
CashuIcon(Size20Modifier)
Spacer(DoubleHorzSpacer)
Text(
stringResource(id = R.string.cashu_redeem_to_cashu),
stringRes(id = R.string.cashu_redeem_to_cashu),
color = Color.White,
fontSize = 16.sp,
)
@ -287,7 +287,7 @@ fun CashuPreview(
) {
CopyIcon(Size20Modifier, Color.White)
Spacer(DoubleHorzSpacer)
Text(stringResource(id = R.string.cashu_copy_token), color = Color.White, fontSize = 16.sp)
Text(stringRes(id = R.string.cashu_copy_token), color = Color.White, fontSize = 16.sp)
}
Spacer(modifier = StdHorzSpacer)
}
@ -328,14 +328,14 @@ fun CashuPreviewNew(
)
Text(
text = stringResource(R.string.cashu),
text = stringRes(R.string.cashu),
fontSize = 12.sp,
modifier = Modifier.padding(start = 5.dp, bottom = 1.dp),
)
}
Text(
text = "${token.totalAmount} ${stringResource(id = R.string.sats)}",
text = "${token.totalAmount} ${stringRes(id = R.string.sats)}",
fontSize = 20.sp,
modifier = Modifier.padding(top = 5.dp),
)
@ -378,7 +378,7 @@ fun CashuPreviewNew(
startActivity(context, intent, null)
} catch (e: Exception) {
if (e is CancellationException) throw e
toast("Cashu", context.getString(R.string.cashu_no_wallet_found))
toast(stringRes(context, R.string.cashu), stringRes(context, R.string.cashu_no_wallet_found))
}
},
shape = SmallishBorder,

View File

@ -470,13 +470,12 @@ fun CreateTextWithEmoji(
overflow: TextOverflow = TextOverflow.Clip,
modifier: Modifier = Modifier,
) {
val textColor =
color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } }
CustomEmojiChecker(
text,
tags,
onEmojiText = {
val textColor =
color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } }
val style =
LocalTextStyle.current
.merge(
@ -486,12 +485,13 @@ fun CreateTextWithEmoji(
fontWeight = fontWeight,
fontSize = fontSize,
),
)
.toSpanStyle()
).toSpanStyle()
InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier)
},
onRegularText = {
val textColor =
color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } }
Text(
text = it,
color = textColor,
@ -536,8 +536,7 @@ fun CreateTextWithEmoji(
fontWeight = fontWeight,
fontSize = fontSize,
),
)
.toSpanStyle()
).toSpanStyle()
}
InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier)
@ -672,8 +671,7 @@ fun ClickableInLineIconRenderer(
} else {
null
}
}
.associate { it.first to it.second }
}.associate { it.first to it.second }
val annotatedText =
buildAnnotatedString {
@ -757,8 +755,7 @@ fun InLineIconRenderer(
} else {
null
}
}
.associate { it.first to it.second }
}.associate { it.first to it.second }
val annotatedText =
remember {

View File

@ -38,6 +38,7 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog
import com.vitorpamplona.amethyst.ui.note.payViaIntent
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.encoders.LnWithdrawalUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -75,7 +76,7 @@ fun ClickableWithdrawal(withdrawalString: String) {
if (showErrorMessageDialog != null) {
ErrorMessageDialog(
title = context.getString(R.string.error_dialog_pay_withdraw_error),
title = stringRes(context, R.string.error_dialog_pay_withdraw_error),
textContent = showErrorMessageDialog ?: "",
onDismiss = { showErrorMessageDialog = null },
)

View File

@ -40,11 +40,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.richtext.ExpandableTextCutOffCalculator
import com.vitorpamplona.amethyst.ui.note.getGradient
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.ButtonPadding
import com.vitorpamplona.amethyst.ui.theme.StdTopPadding
@ -110,7 +110,8 @@ fun ExpandableRichTextViewer(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier =
Modifier.align(Alignment.BottomCenter)
Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.background(getGradient(backgroundColor)),
) {
@ -135,6 +136,6 @@ fun ShowMoreButton(onClick: () -> Unit) {
),
contentPadding = ButtonPadding,
) {
Text(text = stringResource(R.string.show_more), color = Color.White)
Text(text = stringRes(R.string.show_more), color = Color.White)
}
}

View File

@ -43,7 +43,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.unit.dp
@ -57,6 +56,7 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog
import com.vitorpamplona.amethyst.ui.note.payViaIntent
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
@ -112,7 +112,7 @@ fun InvoicePreview(
if (showErrorMessageDialog != null) {
ErrorMessageDialog(
title = context.getString(R.string.error_dialog_pay_invoice_error),
title = stringRes(context, R.string.error_dialog_pay_invoice_error),
textContent = showErrorMessageDialog ?: "",
onDismiss = { showErrorMessageDialog = null },
)
@ -147,7 +147,7 @@ fun InvoicePreview(
)
Text(
text = stringResource(R.string.lightning_invoice),
text = stringRes(R.string.lightning_invoice),
fontSize = 20.sp,
fontWeight = FontWeight.W500,
modifier = Modifier.padding(start = 10.dp),
@ -158,7 +158,7 @@ fun InvoicePreview(
amount?.let {
Text(
text = "$it ${stringResource(id = R.string.sats)}",
text = "$it ${stringRes(id = R.string.sats)}",
fontSize = 25.sp,
fontWeight = FontWeight.W500,
modifier =
@ -180,7 +180,7 @@ fun InvoicePreview(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(text = stringResource(R.string.pay), color = Color.White, fontSize = 20.sp)
Text(text = stringRes(R.string.pay), color = Color.White, fontSize = 20.sp)
}
}
}

View File

@ -44,7 +44,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
@ -56,6 +55,7 @@ import com.vitorpamplona.amethyst.commons.hashtags.Lightning
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
@ -78,7 +78,8 @@ fun InvoiceRequestCard(
) {
Column(
modifier =
Modifier.fillMaxWidth()
Modifier
.fillMaxWidth()
.padding(start = 30.dp, end = 30.dp)
.clip(shape = QuoteBorder)
.border(1.dp, MaterialTheme.colorScheme.subtleBorder, QuoteBorder),
@ -126,7 +127,7 @@ fun InvoiceRequest(
)
Text(
text = titleText ?: stringResource(R.string.lightning_tips),
text = titleText ?: stringRes(R.string.lightning_tips),
fontSize = 20.sp,
fontWeight = FontWeight.W500,
modifier = Modifier.padding(start = 10.dp),
@ -139,13 +140,13 @@ fun InvoiceRequest(
var amount by remember { mutableStateOf(1000L) }
OutlinedTextField(
label = { Text(text = stringResource(R.string.note_to_receiver)) },
label = { Text(text = stringRes(R.string.note_to_receiver)) },
modifier = Modifier.fillMaxWidth(),
value = message,
onValueChange = { message = it },
placeholder = {
Text(
text = stringResource(R.string.thank_you_so_much),
text = stringRes(R.string.thank_you_so_much),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -157,7 +158,7 @@ fun InvoiceRequest(
)
OutlinedTextField(
label = { Text(text = stringResource(R.string.amount_in_sats)) },
label = { Text(text = stringRes(R.string.amount_in_sats)) },
modifier = Modifier.fillMaxWidth(),
value = amount.toString(),
onValueChange = {
@ -199,9 +200,7 @@ fun InvoiceRequest(
context = context,
)
} else {
account.createZapRequestFor(toUserPubKeyHex, message, account.defaultZapType) {
zapRequest,
->
account.createZapRequestFor(toUserPubKeyHex, message, account.defaultZapType) { zapRequest ->
LocalCache.justConsume(zapRequest, null)
LightningAddressResolver()
.lnAddressInvoice(
@ -225,7 +224,7 @@ fun InvoiceRequest(
),
) {
Text(
text = buttonText ?: stringResource(R.string.send_sats),
text = buttonText ?: stringRes(R.string.send_sats),
color = Color.White,
fontSize = 20.sp,
)

View File

@ -29,7 +29,6 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material3.Icon

View File

@ -29,7 +29,6 @@ import androidx.compose.material.icons.filled.Face
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter

View File

@ -37,11 +37,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Size24dp
@ -74,7 +74,7 @@ fun SelectTextDialog(
) {
ArrowBackIcon()
}
Text(text = stringResource(R.string.select_text_dialog_top))
Text(text = stringRes(R.string.select_text_dialog_top))
}
HorizontalDivider(thickness = DividerThickness)
Column(

View File

@ -46,7 +46,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@ -55,6 +54,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.ButtonPadding
import com.vitorpamplona.quartz.events.EventInterface
@ -122,13 +122,13 @@ fun ContentWarningNote(onDismiss: () -> Unit) {
) {
Icon(
imageVector = Icons.Default.Visibility,
contentDescription = stringResource(R.string.content_warning),
contentDescription = stringRes(R.string.content_warning),
modifier = Modifier.size(70.dp).align(Alignment.BottomStart),
tint = MaterialTheme.colorScheme.onBackground,
)
Icon(
imageVector = Icons.Rounded.Warning,
contentDescription = stringResource(R.string.content_warning),
contentDescription = stringRes(R.string.content_warning),
modifier = Modifier.size(30.dp).align(Alignment.TopEnd),
tint = MaterialTheme.colorScheme.onBackground,
)
@ -137,7 +137,7 @@ fun ContentWarningNote(onDismiss: () -> Unit) {
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
Text(
text = stringResource(R.string.content_warning),
text = stringRes(R.string.content_warning),
fontWeight = FontWeight.Bold,
fontSize = 18.sp,
)
@ -145,7 +145,7 @@ fun ContentWarningNote(onDismiss: () -> Unit) {
Row {
Text(
text = stringResource(R.string.content_warning_explanation),
text = stringRes(R.string.content_warning_explanation),
color = Color.Gray,
modifier = Modifier.padding(top = 10.dp),
textAlign = TextAlign.Center,
@ -164,7 +164,7 @@ fun ContentWarningNote(onDismiss: () -> Unit) {
contentPadding = ButtonPadding,
) {
Text(
text = stringResource(R.string.show_anyway),
text = stringRes(R.string.show_anyway),
color = Color.White,
)
}

View File

@ -36,12 +36,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import coil.compose.AsyncImage
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.service.previews.UrlInfoItem
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.MaxWidthWithHorzPadding
import com.vitorpamplona.amethyst.ui.theme.innerPostModifier
@ -59,7 +59,7 @@ private fun CopyToClipboard(
) {
val clipboardManager = LocalClipboardManager.current
DropdownMenuItem(
text = { Text(stringResource(R.string.copy_url_to_clipboard)) },
text = { Text(stringRes(R.string.copy_url_to_clipboard)) },
onClick = {
clipboardManager.setText(AnnotatedString(content))
onDismiss()
@ -103,7 +103,7 @@ fun UrlPreviewCard(
) {
AsyncImage(
model = previewInfo.imageUrlFullPath,
contentDescription = stringResource(R.string.preview_card_image_for, previewInfo.url),
contentDescription = previewInfo.title,
contentScale = ContentScale.Crop,
modifier = previewCardImageModifier,
)

View File

@ -81,7 +81,6 @@ import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle
@ -108,6 +107,7 @@ import com.vitorpamplona.amethyst.ui.note.LyricsOffIcon
import com.vitorpamplona.amethyst.ui.note.MuteIcon
import com.vitorpamplona.amethyst.ui.note.MutedIcon
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.PinBottomIconSize
import com.vitorpamplona.amethyst.ui.theme.Size110dp
import com.vitorpamplona.amethyst.ui.theme.Size165dp
@ -374,13 +374,15 @@ data class MediaItemData(
val artworkUri: String? = null,
)
class MediaItemCache() : GenericBaseCache<MediaItemData, MediaItem>(20) {
override suspend fun compute(key: MediaItemData): MediaItem {
return MediaItem.Builder()
class MediaItemCache : GenericBaseCache<MediaItemData, MediaItem>(20) {
override suspend fun compute(key: MediaItemData): MediaItem =
MediaItem
.Builder()
.setMediaId(key.videoUri)
.setUri(key.videoUri)
.setMediaMetadata(
MediaMetadata.Builder()
MediaMetadata
.Builder()
.setArtist(key.authorName?.ifBlank { null })
.setTitle(key.title?.ifBlank { null } ?: key.videoUri)
.setArtworkUri(
@ -394,11 +396,8 @@ class MediaItemCache() : GenericBaseCache<MediaItemData, MediaItem>(20) {
if (e is CancellationException) throw e
null
},
)
.build(),
)
.build()
}
).build(),
).build()
}
@Composable
@ -619,7 +618,7 @@ var keepPlayingMutex: MediaController? = null
val trackingVideos = mutableListOf<VisibilityData>()
@Stable
class VisibilityData() {
class VisibilityData {
var distanceToCenter: Float? = null
}
@ -645,8 +644,7 @@ fun VideoPlayerActiveMutex(
val myModifier =
remember(videoUri) {
Modifier.fillMaxWidth().defaultMinSize(minHeight = 70.dp).onVisiblePositionChanges {
distanceToCenter ->
Modifier.fillMaxWidth().defaultMinSize(minHeight = 70.dp).onVisiblePositionChanges { distanceToCenter ->
myCache.distanceToCenter = distanceToCenter
if (distanceToCenter != null) {
@ -815,8 +813,7 @@ private fun pollCurrentDuration(controller: MediaController) =
emit(controller.currentPosition / controller.duration.toFloat())
delay(100)
}
}
.conflate()
}.conflate()
@Composable
fun Waveform(
@ -1000,7 +997,8 @@ private fun MuteButton(
) {
Box(modifier = VolumeBottomIconSize) {
Box(
Modifier.clip(CircleShape)
Modifier
.clip(CircleShape)
.fillMaxSize(0.6f)
.align(Alignment.Center)
.background(MaterialTheme.colorScheme.background),
@ -1040,7 +1038,8 @@ private fun KeepPlayingButton(
) {
Box(modifier = PinBottomIconSize) {
Box(
Modifier.clip(CircleShape)
Modifier
.clip(CircleShape)
.fillMaxSize(0.6f)
.align(Alignment.Center)
.background(MaterialTheme.colorScheme.background),
@ -1099,7 +1098,8 @@ fun AnimatedShareButton(
fun ShareButton(innerAction: @Composable (MutableState<Boolean>, () -> Unit) -> Unit) {
Box(modifier = PinBottomIconSize) {
Box(
Modifier.clip(CircleShape)
Modifier
.clip(CircleShape)
.fillMaxSize(0.6f)
.align(Alignment.Center)
.background(MaterialTheme.colorScheme.background),
@ -1116,7 +1116,7 @@ fun ShareButton(innerAction: @Composable (MutableState<Boolean>, () -> Unit) ->
Icon(
imageVector = Icons.Default.Share,
modifier = Size20Modifier,
contentDescription = stringResource(R.string.share_or_save),
contentDescription = stringRes(R.string.share_or_save),
)
innerAction(popupExpanded) { popupExpanded.value = false }
@ -1129,7 +1129,8 @@ fun ShareButton(innerAction: @Composable (MutableState<Boolean>, () -> Unit) ->
fun SaveButton(onSaveClick: (localContext: Context) -> Unit) {
Box(modifier = PinBottomIconSize) {
Box(
Modifier.clip(CircleShape)
Modifier
.clip(CircleShape)
.fillMaxSize(0.6f)
.align(Alignment.Center)
.background(MaterialTheme.colorScheme.background),
@ -1160,7 +1161,7 @@ fun SaveButton(onSaveClick: (localContext: Context) -> Unit) {
Icon(
imageVector = Icons.Default.Download,
modifier = Size20Modifier,
contentDescription = stringResource(R.string.save_to_gallery),
contentDescription = stringRes(R.string.save_to_gallery),
)
}
}

View File

@ -34,7 +34,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
@ -43,6 +42,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.commons.hashtags.Lightning
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@ -67,7 +67,7 @@ fun ZapRaiserRequest(
)
Text(
text = titleText ?: stringResource(R.string.zapraiser),
text = titleText ?: stringRes(R.string.zapraiser),
fontSize = 20.sp,
fontWeight = FontWeight.W500,
modifier = Modifier.padding(start = 10.dp),
@ -77,13 +77,13 @@ fun ZapRaiserRequest(
HorizontalDivider(thickness = DividerThickness)
Text(
text = stringResource(R.string.zapraiser_explainer),
text = stringRes(R.string.zapraiser_explainer),
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.padding(vertical = 10.dp),
)
OutlinedTextField(
label = { Text(text = stringResource(R.string.zapraiser_target_amount_in_sats)) },
label = { Text(text = stringRes(R.string.zapraiser_target_amount_in_sats)) },
modifier = Modifier.fillMaxWidth(),
value =
if (newPostViewModel.zapRaiserAmount != null) {

View File

@ -31,7 +31,6 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
@ -67,7 +66,6 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.core.net.toUri
@ -86,6 +84,7 @@ import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage
import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo
import com.vitorpamplona.amethyst.ui.actions.ImageSaver
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size15dp
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
@ -234,7 +233,12 @@ private fun DialogContent(
exit = remember { fadeOut() },
) {
Row(
modifier = Modifier.padding(horizontal = Size15dp, vertical = Size10dp).statusBarsPadding().systemBarsPadding().fillMaxWidth(),
modifier =
Modifier
.padding(horizontal = Size15dp, vertical = Size10dp)
.statusBarsPadding()
.systemBarsPadding()
.fillMaxWidth(),
horizontalArrangement = spacedBy(Size10dp),
verticalAlignment = Alignment.CenterVertically,
) {
@ -245,7 +249,7 @@ private fun DialogContent(
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back),
contentDescription = stringRes(R.string.back),
)
}
@ -262,7 +266,7 @@ private fun DialogContent(
Icon(
imageVector = Icons.Default.Share,
modifier = Size20Modifier,
contentDescription = stringResource(R.string.quick_action_share),
contentDescription = stringRes(R.string.quick_action_share),
)
ShareImageAction(popupExpanded = popupExpanded, myContent, onDismiss = { popupExpanded.value = false })
@ -294,7 +298,7 @@ private fun DialogContent(
Icon(
imageVector = Icons.Default.Download,
modifier = Size20Modifier,
contentDescription = stringResource(R.string.save_to_gallery),
contentDescription = stringRes(R.string.save_to_gallery),
)
}
}

View File

@ -28,7 +28,6 @@ import android.view.Window
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
@ -56,7 +55,6 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
@ -64,7 +62,6 @@ import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.window.DialogWindowProvider
import androidx.core.net.toFile
import androidx.core.net.toUri
import coil.annotation.ExperimentalCoilApi
import coil.compose.AsyncImage
@ -89,6 +86,7 @@ import com.vitorpamplona.amethyst.ui.note.DownloadForOfflineIcon
import com.vitorpamplona.amethyst.ui.note.HashCheckFailedIcon
import com.vitorpamplona.amethyst.ui.note.HashCheckIcon
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Font17SP
import com.vitorpamplona.amethyst.ui.theme.Size20dp
import com.vitorpamplona.amethyst.ui.theme.Size24dp
@ -99,7 +97,7 @@ import com.vitorpamplona.amethyst.ui.theme.imageModifier
import com.vitorpamplona.quartz.crypto.CryptoUtils
import com.vitorpamplona.quartz.encoders.toHexKey
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -109,21 +107,20 @@ import kotlinx.coroutines.withContext
@Composable
fun ZoomableContentView(
content: BaseMediaContent,
images: ImmutableList<BaseMediaContent> = remember(content) { listOf(content).toImmutableList() },
images: ImmutableList<BaseMediaContent> = remember(content) { persistentListOf(content) },
roundedCorner: Boolean,
isFiniteHeight: Boolean,
accountViewModel: AccountViewModel,
) {
// store the dialog open or close state
var dialogOpen by remember(content) { mutableStateOf(false) }
val mainImageModifier = Modifier.fillMaxWidth().clickable { dialogOpen = true }
val loadedImageModifier = if (roundedCorner) MaterialTheme.colorScheme.imageModifier else Modifier.fillMaxWidth()
when (content) {
is MediaUrlImage ->
SensitivityWarning(content.contentWarning != null, accountViewModel) {
TwoSecondController(content) { controllerVisible ->
val mainImageModifier = Modifier.fillMaxWidth().clickable { dialogOpen = true }
val loadedImageModifier = if (roundedCorner) MaterialTheme.colorScheme.imageModifier else Modifier.fillMaxWidth()
UrlImageView(content, mainImageModifier, loadedImageModifier, isFiniteHeight, controllerVisible, accountViewModel = accountViewModel)
}
}
@ -148,6 +145,9 @@ fun ZoomableContentView(
}
is MediaLocalImage ->
TwoSecondController(content) { controllerVisible ->
val mainImageModifier = Modifier.fillMaxWidth().clickable { dialogOpen = true }
val loadedImageModifier = if (roundedCorner) MaterialTheme.colorScheme.imageModifier else Modifier.fillMaxWidth()
LocalImageView(content, mainImageModifier, loadedImageModifier, isFiniteHeight, controllerVisible, accountViewModel = accountViewModel)
}
is MediaLocalVideo ->
@ -315,15 +315,13 @@ fun UrlImageView(
)
}
val contentScale = if (isFiniteHeight) ContentScale.Fit else ContentScale.FillWidth
val ratio = remember(content) { aspectRatio(content.dim) }
if (showImage.value) {
SubcomposeAsyncImage(
model = content.url,
contentDescription = content.description,
contentScale = contentScale,
contentScale = if (isFiniteHeight) ContentScale.Fit else ContentScale.FillWidth,
modifier = mainImageModifier,
) {
when (painter.state) {
@ -635,7 +633,7 @@ fun ShareImageAction(
if (videoUri != null && !videoUri.startsWith("file")) {
DropdownMenuItem(
text = { Text(stringResource(R.string.copy_url_to_clipboard)) },
text = { Text(stringRes(R.string.copy_url_to_clipboard)) },
onClick = {
clipboardManager.setText(AnnotatedString(videoUri))
onDismiss()
@ -645,7 +643,7 @@ fun ShareImageAction(
postNostrUri?.let {
DropdownMenuItem(
text = { Text(stringResource(R.string.copy_the_note_id_to_the_clipboard)) },
text = { Text(stringRes(R.string.copy_the_note_id_to_the_clipboard)) },
onClick = {
clipboardManager.setText(AnnotatedString(it))
onDismiss()
@ -677,7 +675,7 @@ private fun HashVerificationSymbol(verifiedHash: Boolean) {
openDialogMsg.value?.let {
InformationDialog(
title = localContext.getString(R.string.hash_verification_info_title),
title = stringRes(localContext, R.string.hash_verification_info_title),
textContent = it,
) {
openDialogMsg.value = null
@ -688,7 +686,7 @@ private fun HashVerificationSymbol(verifiedHash: Boolean) {
IconButton(
modifier = hashVerifierMark,
onClick = {
openDialogMsg.value = localContext.getString(R.string.hash_verification_passed)
openDialogMsg.value = stringRes(localContext, R.string.hash_verification_passed)
},
) {
HashCheckIcon(Size30dp)
@ -697,7 +695,7 @@ private fun HashVerificationSymbol(verifiedHash: Boolean) {
IconButton(
modifier = hashVerifierMark,
onClick = {
openDialogMsg.value = localContext.getString(R.string.hash_verification_failed)
openDialogMsg.value = stringRes(localContext, R.string.hash_verification_failed)
},
) {
HashCheckFailedIcon(Size30dp)

View File

@ -37,11 +37,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.note.NewItemsBubble
import com.vitorpamplona.amethyst.ui.note.elements.TimeAgo
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ChatHeadlineBorders
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
@ -57,7 +57,7 @@ fun ChannelNamePreview() {
channelPicture = {
Image(
painter = painterResource(R.drawable.github),
contentDescription = stringResource(id = R.string.profile_banner),
contentDescription = stringRes(id = R.string.profile_banner),
contentScale = ContentScale.FillWidth,
)
},
@ -90,7 +90,7 @@ fun ChannelNamePreview() {
leadingContent = {
Image(
painter = painterResource(R.drawable.github),
contentDescription = stringResource(id = R.string.profile_banner),
contentDescription = stringRes(id = R.string.profile_banner),
contentScale = ContentScale.FillWidth,
modifier = Size55Modifier,
)

View File

@ -37,7 +37,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@ -46,6 +45,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.note.LikeIcon
import com.vitorpamplona.amethyst.ui.note.TextCount
import com.vitorpamplona.amethyst.ui.note.ZappedIcon
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.Size16Modifier
@ -66,7 +66,7 @@ fun LeftPictureLayoutPreviewCard() {
onImage = {
Image(
painter = painterResource(R.drawable.github),
contentDescription = stringResource(id = R.string.profile_banner),
contentDescription = stringRes(id = R.string.profile_banner),
contentScale = ContentScale.FillWidth,
modifier = Modifier.fillMaxSize().clip(QuoteBorder),
)

View File

@ -55,7 +55,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@ -74,6 +73,7 @@ import com.vitorpamplona.amethyst.ui.note.toShortenHex
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginOrSignupScreen
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.AccountPictureModifier
import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size55dp
@ -101,7 +101,7 @@ fun AccountSwitchBottomSheet(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Text(stringResource(R.string.account_switch_select_account), fontWeight = FontWeight.Bold)
Text(stringRes(R.string.account_switch_select_account), fontWeight = FontWeight.Bold)
}
accounts.forEach { acc -> DisplayAccount(acc, accountViewModel, accountStateViewModel) }
Row(
@ -113,7 +113,7 @@ fun AccountSwitchBottomSheet(
verticalAlignment = Alignment.CenterVertically,
) {
TextButton(onClick = { popupExpanded = true }) {
Text(stringResource(R.string.account_switch_add_account_btn))
Text(stringRes(R.string.account_switch_add_account_btn))
}
}
}
@ -128,7 +128,7 @@ fun AccountSwitchBottomSheet(
LoginOrSignupScreen(accountStateViewModel, isFirstLogin = false)
TopAppBar(
title = {
Text(text = stringResource(R.string.account_switch_add_account_dialog_title))
Text(text = stringRes(R.string.account_switch_add_account_dialog_title))
},
navigationIcon = {
IconButton(onClick = { popupExpanded = false }) { ArrowBackIcon() }
@ -222,7 +222,7 @@ private fun ActiveMarker(
if (isCurrentUser) {
Icon(
imageVector = Icons.Default.RadioButtonChecked,
contentDescription = stringResource(R.string.account_switch_active_account),
contentDescription = stringRes(R.string.account_switch_active_account),
tint = MaterialTheme.colorScheme.secondary,
)
}
@ -239,7 +239,7 @@ private fun AccountPicture(
RobohashFallbackAsyncImage(
robot = user.pubkeyHex,
model = profilePicture,
contentDescription = stringResource(R.string.profile_image),
contentDescription = stringRes(R.string.profile_image),
modifier = AccountPictureModifier,
loadProfilePicture = loadProfilePicture,
loadRobohash = loadRobohash,
@ -277,8 +277,8 @@ private fun LogoutButton(
var logoutDialog by remember { mutableStateOf(false) }
if (logoutDialog) {
AlertDialog(
title = { Text(text = stringResource(R.string.log_out)) },
text = { Text(text = stringResource(R.string.are_you_sure_you_want_to_log_out)) },
title = { Text(text = stringRes(R.string.log_out)) },
text = { Text(text = stringRes(R.string.are_you_sure_you_want_to_log_out)) },
onDismissRequest = { logoutDialog = false },
confirmButton = {
TextButton(
@ -287,14 +287,14 @@ private fun LogoutButton(
accountStateViewModel.logOff(acc)
},
) {
Text(text = stringResource(R.string.log_out))
Text(text = stringRes(R.string.log_out))
}
},
dismissButton = {
TextButton(
onClick = { logoutDialog = false },
) {
Text(text = stringResource(R.string.cancel))
Text(text = stringRes(R.string.cancel))
}
},
)
@ -305,7 +305,7 @@ private fun LogoutButton(
) {
Icon(
imageVector = Icons.Default.Logout,
contentDescription = stringResource(R.string.log_out),
contentDescription = stringRes(R.string.log_out),
tint = MaterialTheme.colorScheme.onSurface,
)
}

View File

@ -43,10 +43,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavBackStackEntry
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BottomTopHeight
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Size0dp
@ -176,7 +176,7 @@ private fun NotifiableIcon(
Box(route.notifSize) {
Icon(
painter = painterResource(id = route.icon),
contentDescription = stringResource(route.contentDescriptor),
contentDescription = stringRes(route.contentDescriptor),
modifier = route.iconSize,
tint = if (selected) MaterialTheme.colorScheme.primary else Color.Unspecified,
)

View File

@ -63,7 +63,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@ -128,6 +127,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.RoomNameOnlyDisplay
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ShortChannelHeader
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SpinnerSelectionDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.observeAppDefinition
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BottomTopHeight
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
@ -149,7 +149,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combineTransform
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.transformLatest
@ -195,9 +194,9 @@ private fun RenderTopRouteBar(
Route.Video.base -> StoriesTopBar(followLists, openDrawer, accountViewModel, nav)
Route.Discover.base -> DiscoveryTopBar(followLists, openDrawer, accountViewModel, nav)
Route.Notification.base -> NotificationTopBar(followLists, openDrawer, accountViewModel, nav)
Route.Settings.base -> TopBarWithBackButton(stringResource(id = R.string.application_preferences), navPopBack)
Route.Bookmarks.base -> TopBarWithBackButton(stringResource(id = R.string.bookmarks), navPopBack)
Route.Drafts.base -> TopBarWithBackButton(stringResource(id = R.string.drafts), navPopBack)
Route.Settings.base -> TopBarWithBackButton(stringRes(id = R.string.application_preferences), navPopBack)
Route.Bookmarks.base -> TopBarWithBackButton(stringRes(id = R.string.bookmarks), navPopBack)
Route.Drafts.base -> TopBarWithBackButton(stringRes(id = R.string.drafts), navPopBack)
else -> {
if (id != null) {
@ -226,7 +225,7 @@ private fun ThreadTopBar(
navPopBack: () -> Unit,
) {
FlexibleTopBarWithBackButton(
title = { Text(stringResource(id = R.string.thread_title)) },
title = { Text(stringRes(id = R.string.thread_title)) },
popBack = navPopBack,
)
}
@ -588,7 +587,7 @@ private fun LoggedInUserPictureDrawer(
RobohashFallbackAsyncImage(
robot = accountViewModel.userProfile().pubkeyHex,
model = profilePicture,
contentDescription = stringResource(id = R.string.your_profile_image),
contentDescription = stringRes(id = R.string.your_profile_image),
modifier = HeaderPictureModifier,
contentScale = ContentScale.Crop,
loadProfilePicture = accountViewModel.settings.showProfilePictures.value,
@ -656,7 +655,7 @@ class ResourceName(
) : Name() {
override fun name() = " $resourceId " // Space to make sure it goes first
override fun name(context: Context) = context.getString(resourceId)
override fun name(context: Context) = stringRes(context, resourceId)
}
class PeopleListName(
@ -797,7 +796,7 @@ fun SimpleTextSpinner(
val context = LocalContext.current
val selectAnOption =
stringResource(
stringRes(
id = R.string.select_an_option,
)
@ -879,7 +878,7 @@ fun RenderOption(option: Name) {
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(id = option.resourceId),
text = stringRes(id = option.resourceId),
color = MaterialTheme.colorScheme.onSurface,
)
}

View File

@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.navigation
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
@ -44,7 +43,6 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.DrawerState
import androidx.compose.material3.HorizontalDivider
@ -72,7 +70,6 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
@ -99,6 +96,7 @@ import com.vitorpamplona.amethyst.ui.qrcode.ShowQRDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountBackupDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.Font18SP
@ -214,14 +212,14 @@ fun ProfileContentTemplate(
if (profileBanner != null) {
AsyncImage(
model = profileBanner,
contentDescription = stringResource(id = R.string.profile_image),
contentDescription = stringRes(id = R.string.profile_image),
contentScale = ContentScale.FillWidth,
modifier = bannerModifier,
)
} else {
Image(
painter = painterResource(R.drawable.profile_banner),
contentDescription = stringResource(R.string.profile_banner),
contentDescription = stringRes(R.string.profile_banner),
contentScale = ContentScale.FillWidth,
modifier = bannerModifier,
)
@ -231,7 +229,7 @@ fun ProfileContentTemplate(
RobohashFallbackAsyncImage(
robot = profilePubHex,
model = profilePicture,
contentDescription = stringResource(id = R.string.profile_image),
contentDescription = stringRes(id = R.string.profile_image),
modifier =
Modifier
.width(100.dp)
@ -293,11 +291,11 @@ fun StatusEditBar(
OutlinedTextField(
value = currentStatus.value,
onValueChange = { currentStatus.value = it },
label = { Text(text = stringResource(R.string.status_update)) },
label = { Text(text = stringRes(R.string.status_update)) },
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(
text = stringResource(R.string.status_update),
text = stringRes(R.string.status_update),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -399,7 +397,7 @@ private fun FollowingAndFollowerCounts(
fontWeight = FontWeight.Bold,
)
Text(stringResource(R.string.following))
Text(stringRes(R.string.following))
Spacer(modifier = DoubleHorzSpacer)
@ -408,7 +406,7 @@ private fun FollowingAndFollowerCounts(
fontWeight = FontWeight.Bold,
)
Text(stringResource(R.string.followers))
Text(stringRes(R.string.followers))
}
}
@ -462,7 +460,7 @@ fun ListContent(
Column(modifier) {
NavigationRow(
title = stringResource(R.string.profile),
title = stringRes(R.string.profile),
icon = Route.Profile.icon,
tint = MaterialTheme.colorScheme.primary,
nav = nav,
@ -471,7 +469,7 @@ fun ListContent(
)
NavigationRow(
title = stringResource(R.string.bookmarks),
title = stringRes(R.string.bookmarks),
icon = Route.Bookmarks.icon,
tint = MaterialTheme.colorScheme.onBackground,
nav = nav,
@ -480,7 +478,7 @@ fun ListContent(
)
NavigationRow(
title = stringResource(R.string.drafts),
title = stringRes(R.string.drafts),
icon = Route.Drafts.icon,
tint = MaterialTheme.colorScheme.onBackground,
nav = nav,
@ -497,7 +495,7 @@ fun ListContent(
)
NavigationRow(
title = stringResource(R.string.security_filters),
title = stringRes(R.string.security_filters),
icon = Route.BlockedUsers.icon,
tint = MaterialTheme.colorScheme.onBackground,
nav = nav,
@ -507,7 +505,7 @@ fun ListContent(
accountViewModel.account.keyPair.privKey?.let {
IconRow(
title = stringResource(R.string.backup_keys),
title = stringRes(R.string.backup_keys),
icon = R.drawable.ic_key,
tint = MaterialTheme.colorScheme.onBackground,
onClick = {
@ -520,9 +518,9 @@ fun ListContent(
IconRow(
title =
if (checked) {
stringResource(R.string.disconnect_from_your_orbot_setup)
stringRes(R.string.disconnect_from_your_orbot_setup)
} else {
stringResource(R.string.connect_via_tor_short)
stringRes(R.string.connect_via_tor_short)
},
icon = R.drawable.ic_tor,
tint = MaterialTheme.colorScheme.onBackground,
@ -541,7 +539,7 @@ fun ListContent(
)
NavigationRow(
title = stringResource(R.string.settings),
title = stringRes(R.string.settings),
icon = Route.Settings.icon,
tint = MaterialTheme.colorScheme.onBackground,
nav = nav,
@ -552,7 +550,7 @@ fun ListContent(
Spacer(modifier = Modifier.weight(1f))
IconRow(
title = stringResource(R.string.drawer_accounts),
title = stringRes(R.string.drawer_accounts),
icon = R.drawable.manage_accounts,
tint = MaterialTheme.colorScheme.onBackground,
onClick = openSheet,
@ -576,7 +574,7 @@ fun ListContent(
},
onError = {
accountViewModel.toast(
context.getString(R.string.could_not_connect_to_tor),
stringRes(context, R.string.could_not_connect_to_tor),
it,
)
},
@ -586,8 +584,8 @@ fun ListContent(
if (disconnectTorDialog) {
AlertDialog(
title = { Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_title)) },
text = { Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_text)) },
title = { Text(text = stringRes(R.string.do_you_really_want_to_disable_tor_title)) },
text = { Text(text = stringRes(R.string.do_you_really_want_to_disable_tor_text)) },
onDismissRequest = { disconnectTorDialog = false },
confirmButton = {
TextButton(
@ -597,14 +595,14 @@ fun ListContent(
accountViewModel.enableTor(false, proxyPort)
},
) {
Text(text = stringResource(R.string.yes))
Text(text = stringRes(R.string.yes))
}
},
dismissButton = {
TextButton(
onClick = { disconnectTorDialog = false },
) {
Text(text = stringResource(R.string.no))
Text(text = stringRes(R.string.no))
}
},
)
@ -728,7 +726,7 @@ fun IconRowRelays(
Text(
modifier = Modifier.padding(start = 16.dp),
text = stringResource(id = R.string.relay_setup),
text = stringRes(id = R.string.relay_setup),
fontSize = 18.sp,
)
@ -791,7 +789,7 @@ fun BottomContent(
) {
Icon(
painter = painterResource(R.drawable.ic_qrcode),
contentDescription = stringResource(id = R.string.show_npub_as_a_qr_code),
contentDescription = stringRes(id = R.string.show_npub_as_a_qr_code),
modifier = Modifier.size(24.dp),
tint = MaterialTheme.colorScheme.primary,
)

View File

@ -24,7 +24,6 @@ import android.os.Bundle
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.navigation.NamedNavArgument
import androidx.navigation.NavBackStackEntry

View File

@ -45,7 +45,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
@ -54,6 +53,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.NoteDropDownMenu
import com.vitorpamplona.amethyst.ui.note.types.BadgeDisplay
import com.vitorpamplona.amethyst.ui.screen.BadgeCard
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.launch
@ -67,7 +67,10 @@ fun BadgeCompose(
accountViewModel: AccountViewModel,
nav: (String) -> Unit,
) {
val noteState by likeSetCard.note.live().metadata.observeAsState()
val noteState by likeSetCard.note
.live()
.metadata
.observeAsState()
val note = noteState?.note
val context = LocalContext.current.applicationContext
@ -89,15 +92,15 @@ fun BadgeCompose(
Column(
modifier =
Modifier.background(backgroundColor.value)
Modifier
.background(backgroundColor.value)
.combinedClickable(
onClick = {
scope.launch {
routeFor(
note,
accountViewModel.userProfile(),
)
?.let { nav(it) }
)?.let { nav(it) }
}
},
onLongClick = enablePopup,
@ -128,7 +131,7 @@ fun BadgeCompose(
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
Row {
Text(
stringResource(R.string.new_badge_award_notif),
stringRes(R.string.new_badge_award_notif),
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(bottom = 5.dp).weight(1f),
)
@ -145,7 +148,7 @@ fun BadgeCompose(
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(id = R.string.more_options),
contentDescription = stringRes(id = R.string.more_options),
modifier = Size15Modifier,
tint = MaterialTheme.colorScheme.placeholderText,
)

View File

@ -34,7 +34,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -42,6 +41,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.components.mockAccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.ButtonPadding
import com.vitorpamplona.amethyst.ui.theme.Size35dp
@ -75,7 +75,7 @@ fun BlankNote(
horizontalArrangement = Arrangement.Center,
) {
Text(
text = stringResource(R.string.post_not_found) + if (idHex != null) ": $idHex" else "",
text = stringRes(R.string.post_not_found) + if (idHex != null) ": $idHex" else "",
modifier = Modifier.padding(30.dp),
color = Color.Gray,
textAlign = TextAlign.Center,
@ -125,7 +125,7 @@ fun HiddenNote(
modifier = Modifier.padding(30.dp),
) {
Text(
text = stringResource(R.string.post_was_flagged_as_inappropriate_by),
text = stringRes(R.string.post_was_flagged_as_inappropriate_by),
color = Color.Gray,
)
FlowRow(modifier = Modifier.padding(top = 10.dp)) {
@ -157,7 +157,7 @@ fun HiddenNote(
),
contentPadding = ButtonPadding,
) {
Text(text = stringResource(R.string.show_anyway), color = Color.White)
Text(text = stringRes(R.string.show_anyway), color = Color.White)
}
}
}
@ -188,7 +188,7 @@ fun HiddenNoteByMe(
modifier = Modifier.padding(30.dp),
) {
Text(
text = stringResource(R.string.post_was_hidden),
text = stringRes(R.string.post_was_hidden),
color = Color.Gray,
textAlign = TextAlign.Center,
)
@ -203,7 +203,7 @@ fun HiddenNoteByMe(
),
contentPadding = ButtonPadding,
) {
Text(text = stringResource(R.string.show_anyway), color = Color.White)
Text(text = stringRes(R.string.show_anyway), color = Color.White)
}
}
}

View File

@ -24,7 +24,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.model.Note

View File

@ -45,7 +45,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
@ -68,6 +67,7 @@ import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
import com.vitorpamplona.amethyst.ui.layouts.ChatHeaderLayout
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.AccountPictureModifier
import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.grayText
@ -183,9 +183,9 @@ private fun ChannelRoomCompose(
val description =
if (noteEvent is ChannelCreateEvent) {
stringResource(R.string.channel_created)
stringRes(R.string.channel_created)
} else if (noteEvent is ChannelMetadataEvent) {
"${stringResource(R.string.channel_information_changed_to)} "
"${stringRes(R.string.channel_information_changed_to)} "
} else {
noteEvent?.content()
}
@ -216,7 +216,7 @@ private fun ChannelTitleWithLabelInfo(
channelName: String,
modifier: Modifier,
) {
val label = stringResource(id = R.string.public_chat)
val label = stringRes(id = R.string.public_chat)
val placeHolderColor = MaterialTheme.colorScheme.placeholderText
val channelNameAndBoostInfo =
remember(channelName) {
@ -465,7 +465,7 @@ fun ChannelName(
RobohashFallbackAsyncImage(
robot = channelIdHex,
model = channelPicture,
contentDescription = stringResource(R.string.channel_image),
contentDescription = stringRes(R.string.channel_image),
modifier = AccountPictureModifier,
loadProfilePicture = loadProfilePicture,
loadRobohash = loadRobohash,
@ -506,7 +506,7 @@ fun ChannelName(
)
} else {
Text(
stringResource(R.string.referenced_event_not_found),
stringRes(R.string.referenced_event_not_found),
color = MaterialTheme.colorScheme.grayText,
maxLines = 1,
overflow = TextOverflow.Ellipsis,

View File

@ -46,7 +46,6 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -54,7 +53,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import com.vitorpamplona.amethyst.R
@ -65,6 +63,7 @@ import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ChatBubbleMaxSizeModifier
import com.vitorpamplona.amethyst.ui.theme.ChatBubbleShapeMe
import com.vitorpamplona.amethyst.ui.theme.ChatBubbleShapeThem
@ -623,10 +622,8 @@ fun IncognitoBadge(baseNote: Note) {
@Composable
fun ChatTimeAgo(baseNote: Note) {
val nowStr = stringResource(id = R.string.now)
val time by
remember(baseNote) { derivedStateOf { timeAgoShort(baseNote.createdAt() ?: 0, nowStr) } }
val nowStr = stringRes(id = R.string.now)
val time = remember(baseNote) { timeAgoShort(baseNote.createdAt() ?: 0, nowStr) }
Text(
text = time,
@ -668,7 +665,7 @@ private fun RenderRegularTextNote(
}
} else {
TranslatableRichTextViewer(
content = stringResource(id = R.string.could_not_decrypt_the_message),
content = stringRes(id = R.string.could_not_decrypt_the_message),
canPreview = true,
quotesLeft = 0,
modifier = HalfTopPadding,
@ -690,11 +687,11 @@ private fun RenderChangeChannelMetadataNote(note: Note) {
val channelInfo = noteEvent.channelInfo()
val text =
note.author?.toBestDisplayName().toString() +
" ${stringResource(R.string.changed_chat_name_to)} '" +
" ${stringRes(R.string.changed_chat_name_to)} '" +
(channelInfo.name ?: "") +
"', ${stringResource(R.string.description_to)} '" +
"', ${stringRes(R.string.description_to)} '" +
(channelInfo.about ?: "") +
"', ${stringResource(R.string.and_picture_to)} '" +
"', ${stringRes(R.string.and_picture_to)} '" +
(channelInfo.picture ?: "") +
"'"
@ -711,11 +708,11 @@ private fun RenderCreateChannelNote(note: Note) {
val text =
note.author?.toBestDisplayName().toString() +
" ${stringResource(R.string.created)} " +
" ${stringRes(R.string.created)} " +
(channelInfo.name ?: "") +
" ${stringResource(R.string.with_description_of)} '" +
" ${stringRes(R.string.with_description_of)} '" +
(channelInfo.about ?: "") +
"', ${stringResource(R.string.and_picture)} '" +
"', ${stringRes(R.string.and_picture)} '" +
(channelInfo.picture ?: "") +
"'"

View File

@ -29,7 +29,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.OpenInNew
import androidx.compose.material.icons.automirrored.filled.Reply
import androidx.compose.material.icons.automirrored.filled.VolumeOff
import androidx.compose.material.icons.automirrored.filled.VolumeUp
import androidx.compose.material.icons.filled.Bolt
@ -56,7 +55,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@ -73,6 +71,7 @@ import com.vitorpamplona.amethyst.commons.icons.Reposted
import com.vitorpamplona.amethyst.commons.icons.Search
import com.vitorpamplona.amethyst.commons.icons.Zap
import com.vitorpamplona.amethyst.commons.icons.ZapSplit
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.Size18Modifier
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
@ -85,7 +84,7 @@ import com.vitorpamplona.amethyst.ui.theme.subtleButton
fun AmethystIcon(iconSize: Dp) {
Icon(
imageVector = CustomHashTagIcons.Amethyst,
contentDescription = stringResource(id = R.string.app_logo),
contentDescription = stringRes(id = R.string.app_logo),
modifier = Modifier.size(iconSize),
tint = Color.Unspecified,
)
@ -100,7 +99,7 @@ fun FollowingIcon(iconSize: Dp) {
fun FollowingIcon(modifier: Modifier) {
Icon(
imageVector = Following,
contentDescription = stringResource(id = R.string.following),
contentDescription = stringRes(id = R.string.following),
modifier = modifier,
tint = Color.Unspecified,
)
@ -110,7 +109,7 @@ fun FollowingIcon(modifier: Modifier) {
fun ArrowBackIcon() {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back),
contentDescription = stringRes(R.string.back),
tint = MaterialTheme.colorScheme.grayText,
)
}
@ -132,7 +131,7 @@ fun DownloadForOfflineIcon(
) {
Icon(
imageVector = Icons.Default.DownloadForOffline,
contentDescription = stringResource(id = R.string.accessibility_download_for_offline),
contentDescription = stringRes(id = R.string.accessibility_download_for_offline),
modifier = remember(iconSize) { Modifier.size(iconSize) },
tint = tint,
)
@ -142,7 +141,7 @@ fun DownloadForOfflineIcon(
fun HashCheckIcon(iconSize: Dp) {
Icon(
painter = painterResource(R.drawable.original),
contentDescription = stringResource(id = R.string.hash_verification_passed),
contentDescription = stringRes(id = R.string.hash_verification_passed),
modifier = remember(iconSize) { Modifier.size(iconSize) },
tint = Color.Unspecified,
)
@ -152,7 +151,7 @@ fun HashCheckIcon(iconSize: Dp) {
fun HashCheckFailedIcon(iconSize: Dp) {
Icon(
imageVector = Icons.Default.Report,
contentDescription = stringResource(id = R.string.hash_verification_failed),
contentDescription = stringRes(id = R.string.hash_verification_failed),
modifier = remember(iconSize) { Modifier.size(iconSize) },
tint = Color.Red,
)
@ -165,7 +164,7 @@ fun LikedIcon(
) {
Icon(
imageVector = Liked,
stringResource(id = R.string.like_description),
stringRes(id = R.string.like_description),
modifier = modifier,
tint = tint,
)
@ -178,7 +177,7 @@ fun LikeIcon(
) {
Icon(
imageVector = Like,
contentDescription = stringResource(id = R.string.like_description),
contentDescription = stringRes(id = R.string.like_description),
modifier = iconSizeModifier,
tint = grayTint,
)
@ -191,7 +190,7 @@ fun RepostIcon(
) {
Icon(
imageVector = Repost,
contentDescription = stringResource(id = R.string.boost_or_quote_description),
contentDescription = stringRes(id = R.string.boost_or_quote_description),
modifier = modifier,
tint = tint,
)
@ -204,7 +203,7 @@ fun RepostedIcon(
) {
Icon(
imageVector = Reposted,
contentDescription = stringResource(id = R.string.boost_or_quote_description),
contentDescription = stringRes(id = R.string.boost_or_quote_description),
modifier = modifier,
tint = tint,
)
@ -217,7 +216,7 @@ fun LightningAddressIcon(
) {
Icon(
imageVector = Icons.Default.Bolt,
contentDescription = stringResource(R.string.lightning_address),
contentDescription = stringRes(R.string.lightning_address),
tint = tint,
modifier = modifier,
)
@ -255,7 +254,7 @@ fun ZapIcon(
) {
Icon(
imageVector = Icons.Default.Bolt,
contentDescription = stringResource(contentDescriptor),
contentDescription = stringRes(contentDescriptor),
tint = tint,
modifier = modifier,
)
@ -269,7 +268,7 @@ fun OutlinedZapIcon(
) {
Icon(
imageVector = Zap,
contentDescription = stringResource(contentDescriptor),
contentDescription = stringRes(contentDescriptor),
tint = tint,
modifier = modifier,
)
@ -283,7 +282,7 @@ fun ShareIcon(
Icon(
imageVector = Icons.Default.Share,
modifier = modifier,
contentDescription = stringResource(R.string.share_or_save),
contentDescription = stringRes(R.string.share_or_save),
tint = tint,
)
}
@ -292,7 +291,7 @@ fun ShareIcon(
fun CashuIcon(modifier: Modifier) {
Icon(
imageVector = CustomHashTagIcons.Cashu,
"Cashu",
stringRes(R.string.cashu),
tint = Color.Unspecified,
modifier = modifier,
)
@ -305,7 +304,7 @@ fun CopyIcon(
) {
Icon(
imageVector = Icons.Default.ContentCopy,
stringResource(id = R.string.copy_to_clipboard),
stringRes(id = R.string.copy_to_clipboard),
tint = tint,
modifier = modifier,
)
@ -318,7 +317,7 @@ fun OpenInNewIcon(
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.OpenInNew,
stringResource(id = R.string.copy_to_clipboard),
stringRes(id = R.string.copy_to_clipboard),
tint = tint,
modifier = modifier,
)
@ -331,7 +330,7 @@ fun ExpandLessIcon(
) {
Icon(
imageVector = Icons.Default.ExpandLess,
contentDescription = stringResource(id = contentDescriptor),
contentDescription = stringRes(id = contentDescriptor),
modifier = modifier,
tint = MaterialTheme.colorScheme.subtleButton,
)
@ -344,7 +343,7 @@ fun ExpandMoreIcon(
) {
Icon(
imageVector = Icons.Default.ExpandMore,
contentDescription = stringResource(id = contentDescriptor),
contentDescription = stringRes(id = contentDescriptor),
modifier = modifier,
tint = MaterialTheme.colorScheme.subtleButton,
)
@ -357,7 +356,7 @@ fun CommentIcon(
) {
Icon(
imageVector = Reply,
contentDescription = stringResource(id = R.string.reply_description),
contentDescription = stringRes(id = R.string.reply_description),
modifier = iconSizeModifier,
tint = tint,
)
@ -367,7 +366,7 @@ fun CommentIcon(
fun PollIcon() {
Icon(
painter = painterResource(R.drawable.ic_poll),
contentDescription = stringResource(id = R.string.poll),
contentDescription = stringRes(id = R.string.poll),
modifier = Size20Modifier,
tint = MaterialTheme.colorScheme.onBackground,
)
@ -377,7 +376,7 @@ fun PollIcon() {
fun RegularPostIcon() {
Icon(
painter = painterResource(R.drawable.ic_lists),
contentDescription = stringResource(id = R.string.disable_poll),
contentDescription = stringRes(id = R.string.disable_poll),
modifier = Size20Modifier,
tint = MaterialTheme.colorScheme.onBackground,
)
@ -387,7 +386,7 @@ fun RegularPostIcon() {
fun CancelIcon() {
Icon(
imageVector = Icons.Default.Cancel,
contentDescription = stringResource(id = R.string.cancel),
contentDescription = stringRes(id = R.string.cancel),
modifier = Size30Modifier,
tint = MaterialTheme.colorScheme.placeholderText,
)
@ -397,7 +396,7 @@ fun CancelIcon() {
fun CloseIcon() {
Icon(
painter = painterResource(id = R.drawable.ic_close),
contentDescription = stringResource(id = R.string.cancel),
contentDescription = stringRes(id = R.string.cancel),
modifier = Size20Modifier,
)
}
@ -406,7 +405,7 @@ fun CloseIcon() {
fun MutedIcon() {
Icon(
imageVector = Icons.AutoMirrored.Filled.VolumeOff,
contentDescription = stringResource(id = R.string.muted_button),
contentDescription = stringRes(id = R.string.muted_button),
tint = MaterialTheme.colorScheme.onBackground,
modifier = Size30Modifier,
)
@ -416,7 +415,7 @@ fun MutedIcon() {
fun MuteIcon() {
Icon(
imageVector = Icons.AutoMirrored.Filled.VolumeUp,
contentDescription = stringResource(id = R.string.mute_button),
contentDescription = stringRes(id = R.string.mute_button),
tint = MaterialTheme.colorScheme.onBackground,
modifier = Size30Modifier,
)
@ -429,7 +428,7 @@ fun SearchIcon(
) {
Icon(
imageVector = Search,
contentDescription = stringResource(id = R.string.search_button),
contentDescription = stringRes(id = R.string.search_button),
modifier = modifier,
tint = tint,
)
@ -442,7 +441,7 @@ fun PlayIcon(
) {
Icon(
imageVector = Icons.Outlined.PlayCircle,
contentDescription = stringResource(id = R.string.accessibility_play_username),
contentDescription = stringRes(id = R.string.accessibility_play_username),
modifier = modifier,
tint = tint,
)
@ -468,7 +467,7 @@ fun LyricsIcon(
) {
Icon(
painter = painterResource(id = R.drawable.lyrics_on),
contentDescription = stringResource(id = R.string.accessibility_lyrics_on),
contentDescription = stringRes(id = R.string.accessibility_lyrics_on),
modifier = modifier,
tint = tint,
)
@ -481,7 +480,7 @@ fun LyricsOffIcon(
) {
Icon(
painter = painterResource(id = R.drawable.lyrics_off),
contentDescription = stringResource(id = R.string.accessibility_lyrics_off),
contentDescription = stringRes(id = R.string.accessibility_lyrics_off),
modifier = modifier,
tint = tint,
)
@ -491,7 +490,7 @@ fun LyricsOffIcon(
fun ClearTextIcon() {
Icon(
imageVector = Icons.Default.Clear,
contentDescription = stringResource(R.string.clear),
contentDescription = stringRes(R.string.clear),
)
}
@ -502,7 +501,7 @@ fun LinkIcon(
) {
Icon(
imageVector = Icons.Default.Link,
contentDescription = stringResource(R.string.website),
contentDescription = stringRes(R.string.website),
modifier = modifier,
tint = tint,
)
@ -512,7 +511,7 @@ fun LinkIcon(
fun VerticalDotsIcon(contentDescriptor: Int? = null) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = contentDescriptor?.let { stringResource(id = it) },
contentDescription = contentDescriptor?.let { stringRes(id = it) },
modifier = Size18Modifier,
tint = MaterialTheme.colorScheme.placeholderText,
)
@ -522,7 +521,7 @@ fun VerticalDotsIcon(contentDescriptor: Int? = null) {
fun NIP05CheckingIcon(modifier: Modifier) {
Icon(
imageVector = Icons.Default.Downloading,
contentDescription = stringResource(id = R.string.nip05_checking),
contentDescription = stringRes(id = R.string.nip05_checking),
modifier = modifier,
tint = Color.Yellow,
)
@ -532,7 +531,7 @@ fun NIP05CheckingIcon(modifier: Modifier) {
fun NIP05VerifiedIcon(modifier: Modifier) {
Icon(
painter = painterResource(R.drawable.nip_05),
contentDescription = stringResource(id = R.string.nip05_verified),
contentDescription = stringRes(id = R.string.nip05_verified),
modifier = modifier,
tint = Color.Unspecified,
)
@ -542,7 +541,7 @@ fun NIP05VerifiedIcon(modifier: Modifier) {
fun NIP05FailedVerification(modifier: Modifier) {
Icon(
imageVector = Icons.Default.Report,
contentDescription = stringResource(id = R.string.nip05_failed),
contentDescription = stringRes(id = R.string.nip05_failed),
modifier = modifier,
tint = Color.Red,
)
@ -555,7 +554,7 @@ fun IncognitoIconOn(
) {
Icon(
painter = painterResource(id = R.drawable.incognito),
contentDescription = stringResource(id = R.string.accessibility_turn_off_sealed_message),
contentDescription = stringRes(id = R.string.accessibility_turn_off_sealed_message),
modifier = modifier,
tint = tint,
)
@ -568,7 +567,7 @@ fun IncognitoIconOff(
) {
Icon(
painter = painterResource(id = R.drawable.incognito_off),
contentDescription = stringResource(id = R.string.accessibility_turn_on_sealed_message),
contentDescription = stringRes(id = R.string.accessibility_turn_on_sealed_message),
modifier = modifier,
tint = tint,
)
@ -581,7 +580,7 @@ fun ZapSplitIcon(
) {
Icon(
imageVector = ZapSplit,
contentDescription = stringResource(id = R.string.zap_split_title),
contentDescription = stringRes(id = R.string.zap_split_title),
modifier = modifier,
tint = tint,
)
@ -598,7 +597,7 @@ fun ZapSplitPreview() {
) {
Icon(
imageVector = Icons.Outlined.Bolt,
contentDescription = stringResource(id = R.string.zaps),
contentDescription = stringRes(id = R.string.zaps),
modifier =
Modifier
.size(20.dp)
@ -607,7 +606,7 @@ fun ZapSplitPreview() {
)
Icon(
imageVector = Icons.Outlined.ArrowForwardIos,
contentDescription = stringResource(id = R.string.zaps),
contentDescription = stringRes(id = R.string.zaps),
modifier =
Modifier
.size(13.dp)

View File

@ -53,7 +53,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@ -72,6 +71,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.NoteDropDownMenu
import com.vitorpamplona.amethyst.ui.screen.CombinedZap
import com.vitorpamplona.amethyst.ui.screen.MultiSetCard
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.HalfTopPadding
import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifier
import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifierSmaller
@ -524,7 +524,7 @@ fun WatchUserMetadataAndFollowsAndRenderUserProfilePicture(
RobohashFallbackAsyncImage(
robot = author.pubkeyHex,
model = baseUserPicture,
contentDescription = stringResource(id = R.string.profile_image),
contentDescription = stringRes(id = R.string.profile_image),
modifier = MaterialTheme.colorScheme.profile35dpModifier,
contentScale = ContentScale.Crop,
loadProfilePicture = accountViewModel.settings.showProfilePictures.value,

View File

@ -46,7 +46,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.distinctUntilChanged
@ -113,6 +112,7 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderWikiContent
import com.vitorpamplona.amethyst.ui.note.types.VideoDisplay
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.RenderChannelHeader
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.Font12SP
import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer
@ -1120,7 +1120,7 @@ private fun ChannelNotePicture(
RobohashFallbackAsyncImage(
robot = baseChannel.idHex,
model = model,
contentDescription = stringResource(R.string.group_picture),
contentDescription = stringRes(R.string.group_picture),
modifier = MaterialTheme.colorScheme.channelNotePictureModifier,
loadProfilePicture = loadProfilePicture,
loadRobohash = loadRobohash,

View File

@ -73,7 +73,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextAlign
@ -89,6 +88,7 @@ import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.components.SelectTextDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.WarningColor
import com.vitorpamplona.amethyst.ui.theme.isLight
import com.vitorpamplona.amethyst.ui.theme.secondaryButtonBackground
@ -260,12 +260,12 @@ private fun RenderMainPopup(
MaterialTheme.colorScheme.secondaryButtonBackground
}
val showToast = { stringResource: Int ->
val showToast = { stringRes: Int ->
scope.launch {
Toast
.makeText(
context,
context.getString(stringResource),
stringRes(context, stringRes),
Toast.LENGTH_SHORT,
).show()
}
@ -284,7 +284,7 @@ private fun RenderMainPopup(
Row(modifier = Modifier.height(IntrinsicSize.Min)) {
NoteQuickActionItem(
icon = Icons.Default.ContentCopy,
label = stringResource(R.string.quick_action_copy_text),
label = stringRes(R.string.quick_action_copy_text),
) {
accountViewModel.decrypt(note) {
clipboardManager.setText(AnnotatedString(it))
@ -296,7 +296,7 @@ private fun RenderMainPopup(
VerticalDivider(color = primaryLight)
NoteQuickActionItem(
Icons.Default.AlternateEmail,
stringResource(R.string.quick_action_copy_user_id),
stringRes(R.string.quick_action_copy_user_id),
) {
scope.launch(Dispatchers.IO) {
clipboardManager.setText(AnnotatedString("nostr:${note.author?.pubkeyNpub()}"))
@ -307,7 +307,7 @@ private fun RenderMainPopup(
VerticalDivider(color = primaryLight)
NoteQuickActionItem(
Icons.Default.FormatQuote,
stringResource(R.string.quick_action_copy_note_id),
stringRes(R.string.quick_action_copy_note_id),
) {
scope.launch(Dispatchers.IO) {
clipboardManager.setText(AnnotatedString("nostr:${note.toNEvent()}"))
@ -321,7 +321,7 @@ private fun RenderMainPopup(
NoteQuickActionItem(
Icons.Default.Block,
stringResource(R.string.quick_action_block),
stringRes(R.string.quick_action_block),
) {
if (accountViewModel.hideBlockAlertDialog) {
note.author?.let { accountViewModel.hide(it) }
@ -339,7 +339,7 @@ private fun RenderMainPopup(
if (isOwnNote) {
NoteQuickActionItem(
Icons.Default.Delete,
stringResource(R.string.quick_action_delete),
stringRes(R.string.quick_action_delete),
) {
if (accountViewModel.hideDeleteRequestDialog) {
accountViewModel.delete(note)
@ -351,7 +351,7 @@ private fun RenderMainPopup(
} else if (isFollowingUser) {
NoteQuickActionItem(
Icons.Default.PersonRemove,
stringResource(R.string.quick_action_unfollow),
stringRes(R.string.quick_action_unfollow),
) {
accountViewModel.unfollow(note.author!!)
onDismiss()
@ -359,7 +359,7 @@ private fun RenderMainPopup(
} else {
NoteQuickActionItem(
Icons.Default.PersonAdd,
stringResource(R.string.quick_action_follow),
stringRes(R.string.quick_action_follow),
) {
accountViewModel.follow(note.author!!)
onDismiss()
@ -369,7 +369,7 @@ private fun RenderMainPopup(
VerticalDivider(color = primaryLight)
NoteQuickActionItem(
icon = ImageVector.vectorResource(id = R.drawable.relays),
label = stringResource(R.string.broadcast),
label = stringRes(R.string.broadcast),
) {
accountViewModel.broadcast(note)
// showSelectTextDialog = true
@ -379,7 +379,7 @@ private fun RenderMainPopup(
if (isOwnNote && note.isDraft()) {
NoteQuickActionItem(
Icons.Default.Edit,
stringResource(R.string.edit_draft),
stringRes(R.string.edit_draft),
) {
onDismiss()
onWantsToEditDraft()
@ -387,7 +387,7 @@ private fun RenderMainPopup(
} else {
NoteQuickActionItem(
icon = Icons.Default.Share,
label = stringResource(R.string.quick_action_share),
label = stringRes(R.string.quick_action_share),
) {
val sendIntent =
Intent().apply {
@ -399,14 +399,14 @@ private fun RenderMainPopup(
)
putExtra(
Intent.EXTRA_TITLE,
context.getString(R.string.quick_action_share_browser_link),
stringRes(context, R.string.quick_action_share_browser_link),
)
}
val shareIntent =
Intent.createChooser(
sendIntent,
context.getString(R.string.quick_action_share),
stringRes(context, R.string.quick_action_share),
)
ContextCompat.startActivity(context, shareIntent, null)
onDismiss()
@ -418,7 +418,7 @@ private fun RenderMainPopup(
NoteQuickActionItem(
Icons.Default.Report,
stringResource(R.string.quick_action_report),
stringRes(R.string.quick_action_report),
) {
showReportDialog.value = true
}
@ -463,10 +463,10 @@ fun DeleteAlertDialog(
onDismiss: () -> Unit,
) {
QuickActionAlertDialog(
title = stringResource(R.string.quick_action_request_deletion_alert_title),
textContent = stringResource(R.string.quick_action_request_deletion_alert_body),
title = stringRes(R.string.quick_action_request_deletion_alert_title),
textContent = stringRes(R.string.quick_action_request_deletion_alert_body),
buttonIcon = Icons.Default.Delete,
buttonText = stringResource(R.string.quick_action_delete_dialog_btn),
buttonText = stringRes(R.string.quick_action_delete_dialog_btn),
onClickDoOnce = {
accountViewModel.delete(note)
onDismiss()
@ -486,10 +486,10 @@ private fun BlockAlertDialog(
accountViewModel: AccountViewModel,
onDismiss: () -> Unit,
) = QuickActionAlertDialog(
title = stringResource(R.string.report_dialog_block_hide_user_btn),
textContent = stringResource(R.string.report_dialog_blocking_a_user),
title = stringRes(R.string.report_dialog_block_hide_user_btn),
textContent = stringRes(R.string.report_dialog_blocking_a_user),
buttonIcon = Icons.Default.Block,
buttonText = stringResource(R.string.quick_action_block_dialog_btn),
buttonText = stringRes(R.string.quick_action_block_dialog_btn),
buttonColors =
ButtonDefaults.buttonColors(
containerColor = WarningColor,
@ -587,7 +587,7 @@ fun QuickActionAlertDialog(
horizontalArrangement = Arrangement.SpaceBetween,
) {
TextButton(onClick = onClickDontShowAgain) {
Text(stringResource(R.string.quick_action_dont_show_again_button))
Text(stringRes(R.string.quick_action_dont_show_again_button))
}
Button(
onClick = onClickDoOnce,

View File

@ -61,7 +61,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@ -76,6 +75,7 @@ import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
import com.vitorpamplona.amethyst.ui.navigation.routeToMessage
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.StringToastMsg
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BigPadding
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
@ -437,7 +437,7 @@ fun ZapVote(
zappingProgress = 0f
showErrorMessageDialog =
StringToastMsg(
context.getString(R.string.error_dialog_zap_error),
stringRes(context, R.string.error_dialog_zap_error),
it,
)
}
@ -446,7 +446,7 @@ fun ZapVote(
scope.launch {
showErrorMessageDialog =
StringToastMsg(
context.getString(R.string.error_dialog_zap_error),
stringRes(context, R.string.error_dialog_zap_error),
it,
)
}
@ -471,7 +471,7 @@ fun ZapVote(
zappingProgress = 1f
Icon(
imageVector = Icons.Default.Bolt,
contentDescription = stringResource(R.string.zaps),
contentDescription = stringRes(R.string.zaps),
modifier = Modifier.size(20.dp),
tint = BitcoinOrange,
)
@ -479,7 +479,7 @@ fun ZapVote(
if (zappingProgress < 0.1 || zappingProgress > 0.99) {
Icon(
imageVector = Icons.Outlined.Bolt,
contentDescription = stringResource(id = R.string.zaps),
contentDescription = stringRes(id = R.string.zaps),
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.placeholderText,
)

View File

@ -77,7 +77,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.style.TextAlign
@ -103,6 +102,7 @@ import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer
import com.vitorpamplona.amethyst.ui.navigation.routeToMessage
import com.vitorpamplona.amethyst.ui.note.types.EditState
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.DarkerGreen
import com.vitorpamplona.amethyst.ui.theme.Font14SP
@ -228,14 +228,14 @@ fun ShareReaction(
)
putExtra(
Intent.EXTRA_TITLE,
context.getString(R.string.quick_action_share_browser_link),
stringRes(context, R.string.quick_action_share_browser_link),
)
}
val shareIntent =
Intent.createChooser(
sendIntent,
context.getString(R.string.quick_action_share),
stringRes(context, R.string.quick_action_share),
)
ContextCompat.startActivity(context, shareIntent, null)
},
@ -355,7 +355,7 @@ fun RenderZapRaiser(
Text(
text =
stringResource(id = R.string.sats_to_complete, totalPercentage, zapraiserStatus.left),
stringRes(id = R.string.sats_to_complete, totalPercentage, zapraiserStatus.left),
modifier = NoSoTinyBorders,
color = MaterialTheme.colorScheme.placeholderText,
fontSize = Font14SP,
@ -1050,7 +1050,7 @@ fun ZapReaction(
if (showErrorMessageDialog.isNotEmpty()) {
val msg = showErrorMessageDialog.joinToString("\n")
ErrorMessageDialog(
title = stringResource(id = R.string.error_dialog_zap_error),
title = stringRes(id = R.string.error_dialog_zap_error),
textContent = msg,
onClickStartMessage = {
baseNote.author?.let {
@ -1160,13 +1160,13 @@ fun zapClick(
if (accountViewModel.account.zapAmountChoices.isEmpty()) {
accountViewModel.toast(
context.getString(R.string.error_dialog_zap_error),
context.getString(R.string.no_zap_amount_setup_long_press_to_change),
R.string.error_dialog_zap_error,
R.string.no_zap_amount_setup_long_press_to_change,
)
} else if (!accountViewModel.isWriteable()) {
accountViewModel.toast(
context.getString(R.string.error_dialog_zap_error),
context.getString(R.string.login_with_a_private_key_to_be_able_to_send_zaps),
R.string.error_dialog_zap_error,
R.string.login_with_a_private_key_to_be_able_to_send_zaps,
)
} else if (accountViewModel.account.zapAmountChoices.size == 1) {
accountViewModel.zap(
@ -1272,7 +1272,7 @@ private fun BoostTypeChoicePopup(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(stringResource(R.string.boost), color = Color.White, textAlign = TextAlign.Center)
Text(stringRes(R.string.boost), color = Color.White, textAlign = TextAlign.Center)
}
Button(
@ -1284,7 +1284,7 @@ private fun BoostTypeChoicePopup(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(stringResource(R.string.quote), color = Color.White, textAlign = TextAlign.Center)
Text(stringRes(R.string.quote), color = Color.White, textAlign = TextAlign.Center)
}
Button(
@ -1296,7 +1296,7 @@ private fun BoostTypeChoicePopup(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(stringResource(R.string.fork), color = Color.White, textAlign = TextAlign.Center)
Text(stringRes(R.string.fork), color = Color.White, textAlign = TextAlign.Center)
}
}
}

View File

@ -38,13 +38,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.RelayInfo
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.ButtonPadding
import com.vitorpamplona.amethyst.ui.theme.StdPadding
@ -90,7 +90,7 @@ fun RelayCompose(
}
Text(
"${relay.counter} ${stringResource(R.string.posts_received)}",
"${relay.counter} ${stringRes(R.string.posts_received)}",
color = MaterialTheme.colorScheme.placeholderText,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
@ -114,7 +114,8 @@ private fun RelayOptions(
val isNotUsingRelay =
remember(userState) {
accountViewModel.account.connectToRelays.value.none { it.url == relay.url }
accountViewModel.account.connectToRelays.value
.none { it.url == relay.url }
}
if (isNotUsingRelay) {
@ -136,7 +137,7 @@ fun AddRelayButton(onClick: () -> Unit) {
),
contentPadding = ButtonPadding,
) {
Text(text = stringResource(id = R.string.add), color = Color.White)
Text(text = stringRes(id = R.string.add), color = Color.White)
}
}
@ -152,12 +153,12 @@ fun RemoveRelayButton(onClick: () -> Unit) {
),
contentPadding = ButtonPadding,
) {
Text(text = stringResource(R.string.remove), color = Color.White)
Text(text = stringRes(R.string.remove), color = Color.White)
}
}
fun formattedDateTime(timestamp: Long): String {
return Instant.ofEpochSecond(timestamp)
fun formattedDateTime(timestamp: Long): String =
Instant
.ofEpochSecond(timestamp)
.atZone(ZoneId.systemDefault())
.format(DateTimeFormatter.ofPattern("MMM d, uuuu hh:mm a"))
}

View File

@ -46,7 +46,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@ -54,6 +53,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonBoxModifer
import com.vitorpamplona.amethyst.ui.theme.Size17Modifier
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
@ -239,7 +239,7 @@ private fun ShowMoreRelaysButton(onClick: () -> Unit) {
) {
Icon(
imageVector = Icons.Default.ExpandMore,
contentDescription = stringResource(id = R.string.expand_relay_list),
contentDescription = stringRes(id = R.string.expand_relay_list),
tint = MaterialTheme.colorScheme.placeholderText,
)
}

View File

@ -36,7 +36,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.FeatureSetType
@ -48,6 +47,7 @@ import com.vitorpamplona.amethyst.ui.actions.relays.RelayInformationDialog
import com.vitorpamplona.amethyst.ui.components.ClickableBox
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
import com.vitorpamplona.amethyst.ui.theme.Size17dp
@ -94,7 +94,7 @@ fun ChatRelayExpandButton(onClick: () -> Unit) {
) {
Icon(
imageVector = Icons.Default.ChevronRight,
contentDescription = stringResource(id = R.string.expand_relay_list),
contentDescription = stringRes(id = R.string.expand_relay_list),
modifier = Size15Modifier,
tint = MaterialTheme.colorScheme.placeholderText,
)
@ -195,7 +195,7 @@ fun RenderRelayIcon(
RobohashFallbackAsyncImage(
robot = displayUrl,
model = iconUrl,
contentDescription = stringResource(id = R.string.relay_info, displayUrl),
contentDescription = stringRes(id = R.string.relay_info, displayUrl),
colorFilter = RelayIconFilter,
modifier = iconModifier,
loadProfilePicture = loadProfilePicture,

View File

@ -33,13 +33,13 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.lessImportantLink
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@ -85,7 +85,7 @@ fun ReplyInformationChannel(
if (mentions != null && mentions.isNotEmpty()) {
if (replyTo != null && replyTo.isNotEmpty()) {
Text(
stringResource(id = R.string.replying_to),
stringRes(id = R.string.replying_to),
fontSize = 13.sp,
color = MaterialTheme.colorScheme.placeholderText,
)
@ -101,7 +101,7 @@ fun ReplyInformationChannel(
)
} else if (idx < mentions.size - 1) {
Text(
" ${stringResource(id = R.string.and)} ",
" ${stringRes(id = R.string.and)} ",
fontSize = 13.sp,
color = MaterialTheme.colorScheme.placeholderText,
)

View File

@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.note
import android.content.Context
import android.text.format.DateUtils
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.utils.TimeUtils
import java.text.SimpleDateFormat
import java.util.Locale
@ -36,7 +37,7 @@ fun timeAgo(
context: Context,
): String {
if (time == null) return " "
if (time == 0L) return "${context.getString(R.string.never)}"
if (time == 0L) return "${stringRes(context, R.string.never)}"
val timeDifference = TimeUtils.now() - time
@ -61,13 +62,13 @@ fun timeAgo(
monthFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_DAY) {
// 2 days
"" + (timeDifference / TimeUtils.ONE_DAY).toString() + context.getString(R.string.d)
"" + (timeDifference / TimeUtils.ONE_DAY).toString() + stringRes(context, R.string.d)
} else if (timeDifference > TimeUtils.ONE_HOUR) {
"" + (timeDifference / TimeUtils.ONE_HOUR).toString() + context.getString(R.string.h)
"" + (timeDifference / TimeUtils.ONE_HOUR).toString() + stringRes(context, R.string.h)
} else if (timeDifference > TimeUtils.ONE_MINUTE) {
"" + (timeDifference / TimeUtils.ONE_MINUTE).toString() + context.getString(R.string.m)
"" + (timeDifference / TimeUtils.ONE_MINUTE).toString() + stringRes(context, R.string.m)
} else {
"" + context.getString(R.string.now)
"" + stringRes(context, R.string.now)
}
}
@ -76,7 +77,7 @@ fun timeAgoNoDot(
context: Context,
): String {
if (time == null) return " "
if (time == 0L) return " ${context.getString(R.string.never)}"
if (time == 0L) return " ${stringRes(context, R.string.never)}"
val timeDifference = TimeUtils.now() - time
@ -101,13 +102,13 @@ fun timeAgoNoDot(
monthFormatter.format(time * 1000)
} else if (timeDifference > TimeUtils.ONE_DAY) {
// 2 days
(timeDifference / TimeUtils.ONE_DAY).toString() + context.getString(R.string.d)
(timeDifference / TimeUtils.ONE_DAY).toString() + stringRes(context, R.string.d)
} else if (timeDifference > TimeUtils.ONE_HOUR) {
(timeDifference / TimeUtils.ONE_HOUR).toString() + context.getString(R.string.h)
(timeDifference / TimeUtils.ONE_HOUR).toString() + stringRes(context, R.string.h)
} else if (timeDifference > TimeUtils.ONE_MINUTE) {
(timeDifference / TimeUtils.ONE_MINUTE).toString() + context.getString(R.string.m)
(timeDifference / TimeUtils.ONE_MINUTE).toString() + stringRes(context, R.string.m)
} else {
context.getString(R.string.now)
stringRes(context, R.string.now)
}
}
@ -118,13 +119,13 @@ fun timeAgoShort(
if (mills == null) return " "
var humanReadable =
DateUtils.getRelativeTimeSpanString(
DateUtils
.getRelativeTimeSpanString(
mills * 1000,
System.currentTimeMillis(),
DateUtils.MINUTE_IN_MILLIS,
DateUtils.FORMAT_ABBREV_ALL,
)
.toString()
).toString()
if (humanReadable.startsWith("In") || humanReadable.startsWith("0")) {
humanReadable = stringForNow
}

View File

@ -58,7 +58,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
@ -82,6 +81,7 @@ import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer
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.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.encoders.ATag
@ -217,7 +217,7 @@ fun UpdateReactionTypeDialog(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.new_reaction_symbol)) },
label = { Text(text = stringRes(R.string.new_reaction_symbol)) },
value = postViewModel.nextChoice,
onValueChange = { postViewModel.nextChoice = it },
keyboardOptions =
@ -243,7 +243,7 @@ fun UpdateReactionTypeDialog(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(text = stringResource(R.string.add), color = Color.White)
Text(text = stringRes(R.string.add), color = Color.White)
}
}
}

View File

@ -72,7 +72,6 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
@ -95,6 +94,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
import com.vitorpamplona.amethyst.ui.screen.loggedIn.getFragmentActivity
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Font14SP
@ -108,7 +108,9 @@ import com.vitorpamplona.quartz.events.LnZapEvent
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CancellationException
class UpdateZapAmountViewModel(val account: Account) : ViewModel() {
class UpdateZapAmountViewModel(
val account: Account,
) : ViewModel() {
var nextAmount by mutableStateOf(TextFieldValue(""))
var amountSet by mutableStateOf(listOf<Long>())
var walletConnectRelay by mutableStateOf(TextFieldValue(""))
@ -134,9 +136,7 @@ class UpdateZapAmountViewModel(val account: Account) : ViewModel() {
this.selectedZapType = account.defaultZapType
}
fun toListOfAmounts(commaSeparatedAmounts: String): List<Long> {
return commaSeparatedAmounts.split(",").map { it.trim().toLongOrNull() ?: 0 }
}
fun toListOfAmounts(commaSeparatedAmounts: String): List<Long> = commaSeparatedAmounts.split(",").map { it.trim().toLongOrNull() ?: 0 }
fun addAmount() {
val newValue = nextAmount.text.trim().toLongOrNull()
@ -193,15 +193,14 @@ class UpdateZapAmountViewModel(val account: Account) : ViewModel() {
nextAmount = TextFieldValue("")
}
fun hasChanged(): Boolean {
return (
fun hasChanged(): Boolean =
(
selectedZapType != account?.defaultZapType ||
amountSet != account?.zapAmountChoices ||
walletConnectPubkey.text != (account?.zapPaymentRequest?.pubKeyHex ?: "") ||
walletConnectRelay.text != (account?.zapPaymentRequest?.relayUri ?: "") ||
walletConnectSecret.text != (account?.zapPaymentRequest?.secret ?: "")
)
}
fun updateNIP47(uri: String) {
val contact = Nip47WalletConnect.parse(uri)
@ -212,10 +211,10 @@ class UpdateZapAmountViewModel(val account: Account) : ViewModel() {
}
}
class Factory(val account: Account) : ViewModelProvider.Factory {
override fun <UpdateZapAmountViewModel : ViewModel> create(modelClass: Class<UpdateZapAmountViewModel>): UpdateZapAmountViewModel {
return UpdateZapAmountViewModel(account) as UpdateZapAmountViewModel
}
class Factory(
val account: Account,
) : ViewModelProvider.Factory {
override fun <UpdateZapAmountViewModel : ViewModel> create(modelClass: Class<UpdateZapAmountViewModel>): UpdateZapAmountViewModel = UpdateZapAmountViewModel(account) as UpdateZapAmountViewModel
}
}
@ -241,23 +240,23 @@ fun UpdateZapAmountDialog(
listOf(
Triple(
LnZapEvent.ZapType.PUBLIC,
stringResource(id = R.string.zap_type_public),
stringResource(id = R.string.zap_type_public_explainer),
stringRes(id = R.string.zap_type_public),
stringRes(id = R.string.zap_type_public_explainer),
),
Triple(
LnZapEvent.ZapType.PRIVATE,
stringResource(id = R.string.zap_type_private),
stringResource(id = R.string.zap_type_private_explainer),
stringRes(id = R.string.zap_type_private),
stringRes(id = R.string.zap_type_private_explainer),
),
Triple(
LnZapEvent.ZapType.ANONYMOUS,
stringResource(id = R.string.zap_type_anonymous),
stringResource(id = R.string.zap_type_anonymous_explainer),
stringRes(id = R.string.zap_type_anonymous),
stringRes(id = R.string.zap_type_anonymous_explainer),
),
Triple(
LnZapEvent.ZapType.NONZAP,
stringResource(id = R.string.zap_type_nonzap),
stringResource(id = R.string.zap_type_nonzap_explainer),
stringRes(id = R.string.zap_type_nonzap),
stringRes(id = R.string.zap_type_nonzap_explainer),
),
)
@ -274,13 +273,13 @@ fun UpdateZapAmountDialog(
} catch (e: IllegalArgumentException) {
if (e.message != null) {
accountViewModel.toast(
context.getString(R.string.error_parsing_nip47_title),
context.getString(R.string.error_parsing_nip47, nip47uri, e.message!!),
stringRes(context, R.string.error_parsing_nip47_title),
stringRes(context, R.string.error_parsing_nip47, nip47uri, e.message!!),
)
} else {
accountViewModel.toast(
context.getString(R.string.error_parsing_nip47_title),
context.getString(R.string.error_parsing_nip47_no_error, nip47uri),
stringRes(context, R.string.error_parsing_nip47_title),
stringRes(context, R.string.error_parsing_nip47_no_error, nip47uri),
)
}
}
@ -367,7 +366,7 @@ fun UpdateZapAmountDialog(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.new_amount_in_sats)) },
label = { Text(text = stringRes(R.string.new_amount_in_sats)) },
value = postViewModel.nextAmount,
onValueChange = { postViewModel.nextAmount = it },
keyboardOptions =
@ -393,7 +392,7 @@ fun UpdateZapAmountDialog(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(text = stringResource(R.string.add), color = Color.White)
Text(text = stringRes(R.string.add), color = Color.White)
}
}
@ -402,7 +401,7 @@ fun UpdateZapAmountDialog(
verticalAlignment = Alignment.CenterVertically,
) {
TextSpinner(
label = stringResource(id = R.string.zap_type_explainer),
label = stringRes(id = R.string.zap_type_explainer),
placeholder =
zapTypes.filter { it.first == accountViewModel.defaultZapType() }.first().second,
options = zapOptions,
@ -423,7 +422,7 @@ fun UpdateZapAmountDialog(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
stringResource(id = R.string.wallet_connect_service),
stringRes(id = R.string.wallet_connect_service),
Modifier.weight(1f),
)
@ -447,7 +446,7 @@ fun UpdateZapAmountDialog(
) {
Icon(
painter = painterResource(R.drawable.alby),
contentDescription = stringResource(id = R.string.accessibility_navigate_to_alby),
contentDescription = stringRes(id = R.string.accessibility_navigate_to_alby),
modifier = Modifier.size(24.dp),
tint = Color.Unspecified,
)
@ -460,7 +459,7 @@ fun UpdateZapAmountDialog(
) {
Icon(
Icons.Default.ContentPaste,
contentDescription = stringResource(id = R.string.paste_from_clipboard),
contentDescription = stringRes(id = R.string.paste_from_clipboard),
modifier = Modifier.size(24.dp),
tint = MaterialTheme.colorScheme.primary,
)
@ -469,7 +468,7 @@ fun UpdateZapAmountDialog(
IconButton(onClick = { qrScanning = true }) {
Icon(
painter = painterResource(R.drawable.ic_qrcode),
contentDescription = stringResource(id = R.string.accessibility_scan_qr_code),
contentDescription = stringRes(id = R.string.accessibility_scan_qr_code),
modifier = Modifier.size(24.dp),
tint = MaterialTheme.colorScheme.primary,
)
@ -481,7 +480,7 @@ fun UpdateZapAmountDialog(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
stringResource(id = R.string.wallet_connect_service_explainer),
stringRes(id = R.string.wallet_connect_service_explainer),
Modifier.weight(1f),
color = MaterialTheme.colorScheme.placeholderText,
fontSize = Font14SP,
@ -497,13 +496,13 @@ fun UpdateZapAmountDialog(
} catch (e: IllegalArgumentException) {
if (e.message != null) {
accountViewModel.toast(
context.getString(R.string.error_parsing_nip47_title),
context.getString(R.string.error_parsing_nip47, it, e.message!!),
stringRes(context, R.string.error_parsing_nip47_title),
stringRes(context, R.string.error_parsing_nip47, it, e.message!!),
)
} else {
accountViewModel.toast(
context.getString(R.string.error_parsing_nip47_title),
context.getString(R.string.error_parsing_nip47_no_error, it),
stringRes(context, R.string.error_parsing_nip47_title),
stringRes(context, R.string.error_parsing_nip47_no_error, it),
)
}
}
@ -516,7 +515,7 @@ fun UpdateZapAmountDialog(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.wallet_connect_service_pubkey)) },
label = { Text(text = stringRes(R.string.wallet_connect_service_pubkey)) },
value = postViewModel.walletConnectPubkey,
onValueChange = { postViewModel.walletConnectPubkey = it },
keyboardOptions =
@ -539,7 +538,7 @@ fun UpdateZapAmountDialog(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.wallet_connect_service_relay)) },
label = { Text(text = stringRes(R.string.wallet_connect_service_relay)) },
modifier = Modifier.weight(1f),
value = postViewModel.walletConnectRelay,
onValueChange = { postViewModel.walletConnectRelay = it },
@ -559,21 +558,20 @@ fun UpdateZapAmountDialog(
val context = LocalContext.current
val keyguardLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
showPassword = true
}
}
val authTitle = stringResource(id = R.string.wallet_connect_service_show_secret)
val authTitle = stringRes(id = R.string.wallet_connect_service_show_secret)
Row(
modifier = Modifier.fillMaxWidth().padding(vertical = 5.dp),
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.wallet_connect_service_secret)) },
label = { Text(text = stringRes(R.string.wallet_connect_service_secret)) },
modifier = Modifier.weight(1f),
value = postViewModel.walletConnectSecret,
onValueChange = { postViewModel.walletConnectSecret = it },
@ -585,7 +583,7 @@ fun UpdateZapAmountDialog(
),
placeholder = {
Text(
text = stringResource(R.string.wallet_connect_service_secret_placeholder),
text = stringRes(R.string.wallet_connect_service_secret_placeholder),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -614,9 +612,9 @@ fun UpdateZapAmountDialog(
},
contentDescription =
if (showPassword) {
stringResource(R.string.show_password)
stringRes(R.string.show_password)
} else {
stringResource(
stringRes(
R.string.hide_password,
)
},
@ -654,7 +652,7 @@ fun authenticate(
fun keyguardPrompt() {
val intent =
keyguardManager.createConfirmDeviceCredentialIntent(
context.getString(R.string.app_name_release),
stringRes(context, R.string.app_name_release),
title,
)
@ -672,8 +670,9 @@ fun authenticate(
BiometricManager.Authenticators.DEVICE_CREDENTIAL
val promptInfo =
BiometricPrompt.PromptInfo.Builder()
.setTitle(context.getString(R.string.app_name_release))
BiometricPrompt.PromptInfo
.Builder()
.setTitle(stringRes(context, R.string.app_name_release))
.setSubtitle(title)
.setAllowedAuthenticators(authenticators)
.build()
@ -693,8 +692,9 @@ fun authenticate(
BiometricPrompt.ERROR_LOCKOUT -> keyguardPrompt()
else ->
onError(
context.getString(R.string.biometric_authentication_failed),
context.getString(
stringRes(context, R.string.biometric_authentication_failed),
stringRes(
context,
R.string.biometric_authentication_failed_explainer_with_error,
errString,
),
@ -705,8 +705,8 @@ fun authenticate(
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
onError(
context.getString(R.string.biometric_authentication_failed),
context.getString(R.string.biometric_authentication_failed_explainer),
stringRes(context, R.string.biometric_authentication_failed),
stringRes(context, R.string.biometric_authentication_failed_explainer),
)
}

View File

@ -30,12 +30,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map
@ -46,6 +44,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.quartz.events.ChatroomKey
@Composable
@ -91,7 +90,7 @@ fun DisplayBlankAuthor(
RobohashAsyncImage(
robot = "authornotfound",
contentDescription = stringResource(R.string.unknown_author),
contentDescription = stringRes(R.string.unknown_author),
modifier = nullModifier,
loadRobohash = accountViewModel.settings.featureSet != FeatureSetType.PERFORMANCE,
)
@ -347,9 +346,9 @@ fun InnerUserPicture(
model = userPicture,
contentDescription =
if (userName != null) {
stringResource(id = R.string.profile_image_of_user, userName)
stringRes(id = R.string.profile_image_of_user, userName)
} else {
stringResource(id = R.string.profile_image)
stringRes(id = R.string.profile_image)
},
modifier = myImageModifier,
contentScale = ContentScale.Crop,

View File

@ -39,7 +39,6 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -60,6 +59,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.ui.components.BundledInsert
import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.RoyalBlue
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
@ -99,7 +99,7 @@ fun UserReactionsRow(
) {
Row(verticalAlignment = CenterVertically, modifier = Modifier.width(68.dp)) {
Text(
text = stringResource(id = R.string.today),
text = stringRes(id = R.string.today),
fontWeight = FontWeight.Bold,
)
@ -133,7 +133,7 @@ fun UserReactionsRow(
private fun UserZapModel(model: UserReactionsViewModel) {
Icon(
imageVector = Icons.Default.Bolt,
contentDescription = stringResource(R.string.zaps),
contentDescription = stringRes(R.string.zaps),
modifier = Size24Modifier,
tint = BitcoinOrange,
)

View File

@ -57,7 +57,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
@ -78,6 +77,7 @@ import com.vitorpamplona.amethyst.ui.actions.CloseButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
@ -127,23 +127,23 @@ fun ZapCustomDialog(
listOf(
Triple(
LnZapEvent.ZapType.PUBLIC,
stringResource(id = R.string.zap_type_public),
stringResource(id = R.string.zap_type_public_explainer),
stringRes(id = R.string.zap_type_public),
stringRes(id = R.string.zap_type_public_explainer),
),
Triple(
LnZapEvent.ZapType.PRIVATE,
stringResource(id = R.string.zap_type_private),
stringResource(id = R.string.zap_type_private_explainer),
stringRes(id = R.string.zap_type_private),
stringRes(id = R.string.zap_type_private_explainer),
),
Triple(
LnZapEvent.ZapType.ANONYMOUS,
stringResource(id = R.string.zap_type_anonymous),
stringResource(id = R.string.zap_type_anonymous_explainer),
stringRes(id = R.string.zap_type_anonymous),
stringRes(id = R.string.zap_type_anonymous_explainer),
),
Triple(
LnZapEvent.ZapType.NONZAP,
stringResource(id = R.string.zap_type_nonzap),
stringResource(id = R.string.zap_type_nonzap_explainer),
stringRes(id = R.string.zap_type_nonzap),
stringRes(id = R.string.zap_type_nonzap_explainer),
),
)
@ -200,8 +200,8 @@ fun ZapCustomDialog(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
// stringResource(R.string.new_amount_in_sats
label = { Text(text = stringResource(id = R.string.amount_in_sats)) },
// stringRes(R.string.new_amount_in_sats
label = { Text(text = stringRes(id = R.string.amount_in_sats)) },
value = postViewModel.customAmount,
onValueChange = { postViewModel.customAmount = it },
keyboardOptions =
@ -220,7 +220,7 @@ fun ZapCustomDialog(
)
TextSpinner(
label = stringResource(id = R.string.zap_type),
label = stringRes(id = R.string.zap_type),
placeholder =
zapTypes
.filter { it.first == accountViewModel.account.defaultZapType }
@ -237,17 +237,17 @@ fun ZapCustomDialog(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
// stringResource(R.string.new_amount_in_sats
// stringRes(R.string.new_amount_in_sats
label = {
if (
selectedZapType == LnZapEvent.ZapType.PUBLIC ||
selectedZapType == LnZapEvent.ZapType.ANONYMOUS
) {
Text(text = stringResource(id = R.string.custom_zaps_add_a_message))
Text(text = stringRes(id = R.string.custom_zaps_add_a_message))
} else if (selectedZapType == LnZapEvent.ZapType.PRIVATE) {
Text(text = stringResource(id = R.string.custom_zaps_add_a_message_private))
Text(text = stringRes(id = R.string.custom_zaps_add_a_message_private))
} else if (selectedZapType == LnZapEvent.ZapType.NONZAP) {
Text(text = stringResource(id = R.string.custom_zaps_add_a_message_nonzap))
Text(text = stringRes(id = R.string.custom_zaps_add_a_message_nonzap))
}
},
value = postViewModel.customMessage,
@ -259,7 +259,7 @@ fun ZapCustomDialog(
),
placeholder = {
Text(
text = stringResource(id = R.string.custom_zaps_add_a_message_example),
text = stringRes(id = R.string.custom_zaps_add_a_message_example),
color = MaterialTheme.colorScheme.placeholderText,
)
},
@ -313,7 +313,7 @@ fun ErrorMessageDialog(
contentDescription = null,
)
Spacer(StdHorzSpacer)
Text(stringResource(R.string.error_dialog_talk_to_user))
Text(stringRes(R.string.error_dialog_talk_to_user))
}
}
Button(
@ -329,7 +329,7 @@ fun ErrorMessageDialog(
contentDescription = null,
)
Spacer(StdHorzSpacer)
Text(stringResource(R.string.error_dialog_button_ok))
Text(stringRes(R.string.error_dialog_button_ok))
}
}
}
@ -389,7 +389,7 @@ fun PayViaIntentDialog(
UsernameDisplay(it.user, accountViewModel = accountViewModel)
} else {
Text(
text = stringResource(id = R.string.wallet_number, index + 1),
text = stringRes(id = R.string.wallet_number, index + 1),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontWeight = FontWeight.Bold,
@ -406,7 +406,7 @@ fun PayViaIntentDialog(
)
Spacer(modifier = StdHorzSpacer)
Text(
text = stringResource(id = R.string.sats),
text = stringRes(id = R.string.sats),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontWeight = FontWeight.Bold,
@ -444,9 +444,9 @@ fun payViaIntent(
if (e is CancellationException) throw e
// don't display ugly error messages
// if (e.message != null) {
// onError(context.getString(R.string.no_wallet_found_with_error, e.message!!))
// onError(stringRes(context, R.string.no_wallet_found_with_error, e.message!!))
// } else {
onError(context.getString(R.string.no_wallet_found))
onError(stringRes(context, R.string.no_wallet_found))
// }
}
}
@ -468,9 +468,9 @@ fun PayButton(
contentPadding = ZeroPadding,
) {
if (isActive) {
Text(text = stringResource(R.string.pay), color = Color.White)
Text(text = stringRes(R.string.pay), color = Color.White)
} else {
Text(text = stringResource(R.string.paid), color = Color.White)
Text(text = stringRes(R.string.paid), color = Color.White)
}
}
}

View File

@ -34,7 +34,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
@ -47,6 +46,7 @@ import com.vitorpamplona.amethyst.ui.actions.relays.AddDMRelayListDialog
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
import com.vitorpamplona.amethyst.ui.screen.SharedPreferencesViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BigPadding
import com.vitorpamplona.amethyst.ui.theme.StdPadding
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
@ -159,7 +159,7 @@ fun AddInboxRelayForDMCard(
) {
// Title
Text(
text = stringResource(id = R.string.dm_relays_not_found),
text = stringRes(id = R.string.dm_relays_not_found),
style =
TextStyle(
fontSize = 20.sp,
@ -170,13 +170,13 @@ fun AddInboxRelayForDMCard(
Spacer(modifier = StdVertSpacer)
Text(
text = stringResource(id = R.string.dm_relays_not_found_description),
text = stringRes(id = R.string.dm_relays_not_found_description),
)
Spacer(modifier = StdVertSpacer)
Text(
text = stringResource(id = R.string.dm_relays_not_found_examples),
text = stringRes(id = R.string.dm_relays_not_found_examples),
)
Spacer(modifier = StdVertSpacer)
@ -192,7 +192,7 @@ fun AddInboxRelayForDMCard(
},
modifier = Modifier.fillMaxWidth(),
) {
Text(text = stringResource(id = R.string.dm_relays_not_found_create_now))
Text(text = stringRes(id = R.string.dm_relays_not_found_create_now))
}
}
}

View File

@ -34,7 +34,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
@ -47,6 +46,7 @@ import com.vitorpamplona.amethyst.ui.actions.relays.AddSearchRelayListDialog
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
import com.vitorpamplona.amethyst.ui.screen.SharedPreferencesViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BigPadding
import com.vitorpamplona.amethyst.ui.theme.StdPadding
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
@ -159,7 +159,7 @@ fun AddInboxRelayForSearchCard(
) {
// Title
Text(
text = stringResource(id = R.string.search_relays_not_found),
text = stringRes(id = R.string.search_relays_not_found),
style =
TextStyle(
fontSize = 20.sp,
@ -170,7 +170,7 @@ fun AddInboxRelayForSearchCard(
Spacer(modifier = StdVertSpacer)
Text(
text = stringResource(id = R.string.search_relays_not_found_description),
text = stringRes(id = R.string.search_relays_not_found_description),
)
Spacer(modifier = StdVertSpacer)
@ -186,7 +186,7 @@ fun AddInboxRelayForSearchCard(
},
modifier = Modifier.fillMaxWidth(),
) {
Text(text = stringResource(id = R.string.dm_relays_not_found_create_now))
Text(text = stringRes(id = R.string.dm_relays_not_found_create_now))
}
}
}

View File

@ -29,11 +29,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
@ -73,7 +73,7 @@ fun AddButton(
enabled = isActive,
contentPadding = PaddingValues(vertical = 0.dp, horizontal = 16.dp),
) {
Text(text = stringResource(text), color = Color.White, textAlign = TextAlign.Center)
Text(text = stringRes(text), color = Color.White, textAlign = TextAlign.Center)
}
}
@ -93,6 +93,6 @@ fun RemoveButton(
enabled = isActive,
contentPadding = PaddingValues(vertical = 0.dp, horizontal = 16.dp),
) {
Text(text = stringResource(R.string.remove), color = Color.White)
Text(text = stringRes(R.string.remove), color = Color.White)
}
}

View File

@ -23,16 +23,16 @@ package com.vitorpamplona.amethyst.ui.note.elements
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@Composable
fun BoostedMark() {
Text(
stringResource(id = R.string.boosted),
stringRes(id = R.string.boosted),
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.placeholderText,
maxLines = 1,

View File

@ -31,7 +31,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.vitorpamplona.amethyst.R
@ -40,6 +39,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.note.BaseUserPicture
import com.vitorpamplona.amethyst.ui.note.WatchAuthor
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.authorNotePictureForImageHeader
@ -69,7 +69,7 @@ fun BannerImage(
AsyncImage(
model = it,
contentDescription =
stringResource(
stringRes(
R.string.preview_card_image_for,
it,
),
@ -80,7 +80,7 @@ fun BannerImage(
} ?: run {
Image(
painter = painterResource(R.drawable.profile_banner),
contentDescription = stringResource(R.string.profile_banner),
contentDescription = stringRes(R.string.profile_banner),
contentScale = ContentScale.Crop,
modifier = imageModifier,
)

View File

@ -24,11 +24,11 @@ import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.note.types.EditState
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
import com.vitorpamplona.amethyst.ui.theme.placeholderText
@ -38,11 +38,11 @@ fun DisplayEditStatus(editState: EditState) {
text =
buildAnnotatedString {
if (editState.showingVersion.value == editState.originalVersionId()) {
append(stringResource(id = R.string.original))
append(stringRes(id = R.string.original))
} else if (editState.showingVersion.value == editState.lastVersionId()) {
append(stringResource(id = R.string.edited))
append(stringRes(id = R.string.edited))
} else {
append(stringResource(id = R.string.edited_number, editState.versionId()))
append(stringRes(id = R.string.edited_number, editState.versionId()))
}
},
onClick = {

View File

@ -29,7 +29,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import com.vitorpamplona.amethyst.R
@ -37,6 +36,7 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.note.LoadOts
import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.lessImportantLink
import java.text.SimpleDateFormat
@ -65,7 +65,7 @@ fun DisplayOts(
text =
buildAnnotatedString {
append(
stringResource(
stringRes(
id = R.string.existed_since,
timeStr,
),
@ -76,8 +76,9 @@ fun DisplayOts(
SimpleDateFormat.getDateTimeInstance().format(Date(unixtimestamp * 1000))
accountViewModel.toast(
context.getString(R.string.ots_info_title),
context.getString(R.string.ots_info_description, fullDateTime),
R.string.ots_info_title,
R.string.ots_info_description,
fullDateTime,
)
},
style =
@ -91,7 +92,7 @@ fun DisplayOts(
},
whenPending = {
Text(
stringResource(id = R.string.timestamp_pending_short),
stringRes(id = R.string.timestamp_pending_short),
color = MaterialTheme.colorScheme.lessImportantLink,
fontSize = Font14SP,
fontWeight = FontWeight.Bold,

View File

@ -48,7 +48,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
@ -68,13 +67,16 @@ 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.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.math.BigDecimal
@Stable data class Reward(val amount: BigDecimal)
@Stable data class Reward(
val amount: BigDecimal,
)
@Composable
fun DisplayReward(
@ -199,9 +201,7 @@ class AddBountyAmountViewModel : ViewModel() {
nextAmount = TextFieldValue("")
}
fun hasChanged(): Boolean {
return nextAmount.text.trim().toLongOrNull() != null
}
fun hasChanged(): Boolean = nextAmount.text.trim().toLongOrNull() != null
}
@Composable
@ -254,7 +254,7 @@ fun AddBountyAmountDialog(
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringResource(R.string.pledge_amount_in_sats)) },
label = { Text(text = stringRes(R.string.pledge_amount_in_sats)) },
value = postViewModel.nextAmount,
onValueChange = { postViewModel.nextAmount = it },
keyboardOptions =

View File

@ -24,12 +24,10 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.text.AnnotatedString

View File

@ -38,7 +38,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.core.content.ContextCompat
import com.vitorpamplona.amethyst.R
@ -52,6 +51,7 @@ import com.vitorpamplona.amethyst.ui.note.externalLinkForNote
import com.vitorpamplona.amethyst.ui.note.types.EditState
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Size24Modifier
import com.vitorpamplona.quartz.events.TextNoteEvent
@ -177,7 +177,7 @@ fun NoteDropDownMenu(
if (!state.isFollowingAuthor) {
DropdownMenuItem(
text = { Text(stringResource(R.string.follow)) },
text = { Text(stringRes(R.string.follow)) },
onClick = {
val author = note.author ?: return@DropdownMenuItem
accountViewModel.follow(author)
@ -187,7 +187,7 @@ fun NoteDropDownMenu(
HorizontalDivider(thickness = DividerThickness)
}
DropdownMenuItem(
text = { Text(stringResource(R.string.copy_text)) },
text = { Text(stringRes(R.string.copy_text)) },
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.decrypt(note) { clipboardManager.setText(AnnotatedString(it)) }
@ -196,7 +196,7 @@ fun NoteDropDownMenu(
},
)
DropdownMenuItem(
text = { Text(stringResource(R.string.copy_user_pubkey)) },
text = { Text(stringRes(R.string.copy_user_pubkey)) },
onClick = {
scope.launch(Dispatchers.IO) {
clipboardManager.setText(AnnotatedString("nostr:${note.author?.pubkeyNpub()}"))
@ -205,7 +205,7 @@ fun NoteDropDownMenu(
},
)
DropdownMenuItem(
text = { Text(stringResource(R.string.copy_note_id)) },
text = { Text(stringRes(R.string.copy_note_id)) },
onClick = {
scope.launch(Dispatchers.IO) {
clipboardManager.setText(AnnotatedString("nostr:" + note.toNEvent()))
@ -214,7 +214,7 @@ fun NoteDropDownMenu(
},
)
DropdownMenuItem(
text = { Text(stringResource(R.string.quick_action_share)) },
text = { Text(stringRes(R.string.quick_action_share)) },
onClick = {
val sendIntent =
Intent().apply {
@ -226,12 +226,12 @@ fun NoteDropDownMenu(
)
putExtra(
Intent.EXTRA_TITLE,
actContext.getString(R.string.quick_action_share_browser_link),
stringRes(actContext, R.string.quick_action_share_browser_link),
)
}
val shareIntent =
Intent.createChooser(sendIntent, appContext.getString(R.string.quick_action_share))
Intent.createChooser(sendIntent, stringRes(actContext, R.string.quick_action_share))
ContextCompat.startActivity(actContext, shareIntent, null)
onDismiss()
},
@ -239,7 +239,7 @@ fun NoteDropDownMenu(
HorizontalDivider(thickness = DividerThickness)
if (state.isLoggedUser && note.isDraft()) {
DropdownMenuItem(
text = { Text(stringResource(R.string.edit_draft)) },
text = { Text(stringRes(R.string.edit_draft)) },
onClick = {
wantsToEditDraft.value = true
},
@ -248,14 +248,14 @@ fun NoteDropDownMenu(
if (note.event is TextNoteEvent && !note.isDraft()) {
if (state.isLoggedUser) {
DropdownMenuItem(
text = { Text(stringResource(R.string.edit_post)) },
text = { Text(stringRes(R.string.edit_post)) },
onClick = {
wantsToEditPost.value = true
},
)
} else {
DropdownMenuItem(
text = { Text(stringResource(R.string.propose_an_edit)) },
text = { Text(stringRes(R.string.propose_an_edit)) },
onClick = {
wantsToEditPost.value = true
},
@ -263,7 +263,7 @@ fun NoteDropDownMenu(
}
}
DropdownMenuItem(
text = { Text(stringResource(R.string.broadcast)) },
text = { Text(stringRes(R.string.broadcast)) },
onClick = {
accountViewModel.broadcast(note)
onDismiss()
@ -272,14 +272,14 @@ fun NoteDropDownMenu(
HorizontalDivider(thickness = DividerThickness)
if (accountViewModel.account.hasPendingAttestations(note)) {
DropdownMenuItem(
text = { Text(stringResource(R.string.timestamp_pending)) },
text = { Text(stringRes(R.string.timestamp_pending)) },
onClick = {
onDismiss()
},
)
} else {
DropdownMenuItem(
text = { Text(stringResource(R.string.timestamp_it)) },
text = { Text(stringRes(R.string.timestamp_it)) },
onClick = {
accountViewModel.timestamp(note)
onDismiss()
@ -289,7 +289,7 @@ fun NoteDropDownMenu(
HorizontalDivider(thickness = DividerThickness)
if (state.isPrivateBookmarkNote) {
DropdownMenuItem(
text = { Text(stringResource(R.string.remove_from_private_bookmarks)) },
text = { Text(stringRes(R.string.remove_from_private_bookmarks)) },
onClick = {
accountViewModel.removePrivateBookmark(note)
onDismiss()
@ -297,7 +297,7 @@ fun NoteDropDownMenu(
)
} else {
DropdownMenuItem(
text = { Text(stringResource(R.string.add_to_private_bookmarks)) },
text = { Text(stringRes(R.string.add_to_private_bookmarks)) },
onClick = {
accountViewModel.addPrivateBookmark(note)
onDismiss()
@ -306,7 +306,7 @@ fun NoteDropDownMenu(
}
if (state.isPublicBookmarkNote) {
DropdownMenuItem(
text = { Text(stringResource(R.string.remove_from_public_bookmarks)) },
text = { Text(stringRes(R.string.remove_from_public_bookmarks)) },
onClick = {
accountViewModel.removePublicBookmark(note)
onDismiss()
@ -314,7 +314,7 @@ fun NoteDropDownMenu(
)
} else {
DropdownMenuItem(
text = { Text(stringResource(R.string.add_to_public_bookmarks)) },
text = { Text(stringRes(R.string.add_to_public_bookmarks)) },
onClick = {
accountViewModel.addPublicBookmark(note)
onDismiss()
@ -324,7 +324,7 @@ fun NoteDropDownMenu(
HorizontalDivider(thickness = DividerThickness)
if (state.showSensitiveContent == null || state.showSensitiveContent == true) {
DropdownMenuItem(
text = { Text(stringResource(R.string.content_warning_hide_all_sensitive_content)) },
text = { Text(stringRes(R.string.content_warning_hide_all_sensitive_content)) },
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.hideSensitiveContent()
@ -335,7 +335,7 @@ fun NoteDropDownMenu(
}
if (state.showSensitiveContent == null || state.showSensitiveContent == false) {
DropdownMenuItem(
text = { Text(stringResource(R.string.content_warning_show_all_sensitive_content)) },
text = { Text(stringRes(R.string.content_warning_show_all_sensitive_content)) },
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.disableContentWarnings()
@ -346,7 +346,7 @@ fun NoteDropDownMenu(
}
if (state.showSensitiveContent != null) {
DropdownMenuItem(
text = { Text(stringResource(R.string.content_warning_see_warnings)) },
text = { Text(stringRes(R.string.content_warning_see_warnings)) },
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.seeContentWarnings()
@ -358,7 +358,7 @@ fun NoteDropDownMenu(
HorizontalDivider(thickness = DividerThickness)
if (state.isLoggedUser) {
DropdownMenuItem(
text = { Text(stringResource(R.string.request_deletion)) },
text = { Text(stringRes(R.string.request_deletion)) },
onClick = {
scope.launch(Dispatchers.IO) {
accountViewModel.delete(note)
@ -368,7 +368,7 @@ fun NoteDropDownMenu(
)
} else {
DropdownMenuItem(
text = { Text(stringResource(R.string.block_report)) },
text = { Text(stringRes(R.string.block_report)) },
onClick = { reportDialogShowing = true },
)
}

View File

@ -31,7 +31,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import com.vitorpamplona.amethyst.R
@ -41,6 +40,7 @@ import com.vitorpamplona.amethyst.ui.components.LoadNote
import com.vitorpamplona.amethyst.ui.navigation.routeFor
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.nip05
@ -90,7 +90,7 @@ fun ForkInformationRowLightColor(
ClickableText(
text =
buildAnnotatedString {
append(stringResource(id = R.string.forked_from))
append(stringRes(id = R.string.forked_from))
append(" ")
},
onClick = { nav(route) },
@ -139,7 +139,7 @@ fun ForkInformationRow(
val author = note.author ?: return
val meta by author.live().userMetadataInfo.observeAsState(author.info)
Text(stringResource(id = R.string.forked_from))
Text(stringRes(id = R.string.forked_from))
Spacer(modifier = StdHorzSpacer)
val userMetadata by author.live().userMetadataInfo.observeAsState()

Some files were not shown because too many files have changed in this diff Show More