mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-04-10 21:09:40 +02:00
Merge branch 'main' into amber
This commit is contained in:
commit
36a3c4123c
44
.github/workflows/create-release.yml
vendored
44
.github/workflows/create-release.yml
vendored
@ -112,6 +112,28 @@ jobs:
|
||||
asset_name: amethyst-googleplay-x86_64-${{ github.ref_name }}.apk
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload Play APK arm64-v8a Asset
|
||||
id: upload-release-asset-play-arm64-v8a-apk
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: app/build/outputs/apk/play/release/app-play-arm64-v8a-release-unsigned-signed.apk
|
||||
asset_name: amethyst-googleplay-arm64-v8a-${{ github.ref_name }}.apk
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload Play APK armeabi-v7a Asset
|
||||
id: upload-release-asset-play-armeabi-v7a-apk
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: app/build/outputs/apk/play/release/app-play-armeabi-v7a-release-unsigned-signed.apk
|
||||
asset_name: amethyst-googleplay-armeabi-v7a-${{ github.ref_name }}.apk
|
||||
asset_content_type: application/zip
|
||||
|
||||
# F-Droid APK
|
||||
- name: Upload F-Droid APK Universal Asset
|
||||
id: upload-release-asset-fdroid-universal-apk
|
||||
@ -146,6 +168,28 @@ jobs:
|
||||
asset_name: amethyst-fdroid-x86_64-${{ github.ref_name }}.apk
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload F-Droid APK arm64-v8a Asset
|
||||
id: upload-release-asset-fdroid-arm64-v8a-apk
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: app/build/outputs/apk/fdroid/release/app-fdroid-arm64-v8a-release-unsigned-signed.apk
|
||||
asset_name: amethyst-fdroid-arm64-v8a-${{ github.ref_name }}.apk
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload F-Droid APK armeabi-v7a Asset
|
||||
id: upload-release-asset-fdroid-armeabi-v7a-apk
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: app/build/outputs/apk/fdroid/release/app-fdroid-armeabi-v7a-release-unsigned-signed.apk
|
||||
asset_name: amethyst-fdroid-armeabi-v7a-${{ github.ref_name }}.apk
|
||||
asset_content_type: application/zip
|
||||
|
||||
|
||||
|
||||
# Google Play AAB
|
||||
|
@ -20,7 +20,7 @@ android {
|
||||
vectorDrawables {
|
||||
useSupportLibrary true
|
||||
}
|
||||
resourceConfigurations += ['ar', 'cs', 'de', 'eo', 'es', 'fa', 'fr', 'hu', 'ja', 'night', 'nl', 'pt-rBR', 'ru', 'sv-rSE', 'ta', 'th', 'tr', 'uk', 'zh', 'sh-rHK', 'zh-rTW']
|
||||
resourceConfigurations += ['ar', 'cs', 'de', 'eo', 'es', 'fa', 'fr', 'hu', 'in', 'ja', 'night', 'nl', 'pt-rBR', 'ru', 'sv-rSE', 'ta', 'th', 'tr', 'uk', 'zh', 'sh-rHK', 'zh-rTW']
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@ -54,7 +54,7 @@ android {
|
||||
abi {
|
||||
enable true
|
||||
reset()
|
||||
include "x86", "x86_64"
|
||||
include "x86", "x86_64", "arm64-v8a", "armeabi-v7a"
|
||||
universalApk true
|
||||
}
|
||||
}
|
||||
|
@ -2628,14 +2628,18 @@ class Account(
|
||||
|
||||
// Ugly, but forces nostr.band as the only search-supporting relay today.
|
||||
// TODO: Remove when search becomes more available.
|
||||
if (usersRelayList.none { it.activeTypes.contains(FeedType.SEARCH) }) {
|
||||
usersRelayList = usersRelayList + Relay(
|
||||
Constants.forcedRelayForSearch.url,
|
||||
Constants.forcedRelayForSearch.read,
|
||||
Constants.forcedRelayForSearch.write,
|
||||
Constants.forcedRelayForSearch.feedTypes,
|
||||
proxy
|
||||
)
|
||||
val searchRelays = usersRelayList.filter { it.url.removeSuffix("/") in Constants.forcedRelaysForSearchSet }
|
||||
val hasSearchRelay = usersRelayList.any { it.activeTypes.contains(FeedType.SEARCH) }
|
||||
if (!hasSearchRelay && searchRelays.isEmpty()) {
|
||||
usersRelayList = usersRelayList + Constants.forcedRelayForSearch.map {
|
||||
Relay(
|
||||
it.url,
|
||||
it.read,
|
||||
it.write,
|
||||
it.feedTypes,
|
||||
proxy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return usersRelayList.toTypedArray()
|
||||
@ -2653,6 +2657,10 @@ class Account(
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
fun activeWriteRelays(): List<Relay> {
|
||||
return (activeRelays() ?: convertLocalRelays()).filter { it.write }
|
||||
}
|
||||
|
||||
fun reconnectIfRelaysHaveChanged() {
|
||||
val newRelaySet = activeRelays() ?: convertLocalRelays()
|
||||
if (!Client.isSameRelaySetConfig(newRelaySet)) {
|
||||
|
@ -734,6 +734,12 @@ class NoteLiveSet(u: Note) {
|
||||
it.note.boosts.toImmutableList()
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val relayInfo = innerRelays.map {
|
||||
it.note.relays.map {
|
||||
RelayBriefInfo(it)
|
||||
}.toImmutableList()
|
||||
}
|
||||
|
||||
fun isInUse(): Boolean {
|
||||
return metadata.hasObservers() ||
|
||||
reactions.hasObservers() ||
|
||||
@ -812,3 +818,10 @@ class NoteLoadingLiveData<Y>(val note: Note, initialValue: Y?) : MediatorLiveDat
|
||||
|
||||
@Immutable
|
||||
class NoteState(val note: Note)
|
||||
|
||||
@Immutable
|
||||
data class RelayBriefInfo(
|
||||
val url: String,
|
||||
val displayUrl: String = url.trim().removePrefix("wss://").removePrefix("ws://").removeSuffix("/").intern(),
|
||||
val favIcon: String = "https://$displayUrl/favicon.ico".intern()
|
||||
)
|
||||
|
@ -14,4 +14,6 @@ data class RelaySetupInfo(
|
||||
val spamCount: Int = 0,
|
||||
val feedTypes: Set<FeedType>,
|
||||
val paidRelay: Boolean = false
|
||||
)
|
||||
) {
|
||||
val briefInfo: RelayBriefInfo = RelayBriefInfo(url)
|
||||
}
|
||||
|
@ -0,0 +1,103 @@
|
||||
package com.vitorpamplona.amethyst.service
|
||||
|
||||
import android.util.Log
|
||||
import android.util.LruCache
|
||||
import com.vitorpamplona.amethyst.model.RelayInformation
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import java.io.IOException
|
||||
|
||||
object Nip11CachedRetriever {
|
||||
val relayInformationDocumentCache = LruCache<String, RelayInformation>(100)
|
||||
val retriever = Nip11Retriever()
|
||||
|
||||
suspend fun loadRelayInfo(
|
||||
dirtyUrl: String,
|
||||
onInfo: (RelayInformation) -> Unit,
|
||||
onError: (String, Nip11Retriever.ErrorCode, String?) -> Unit
|
||||
) {
|
||||
val url = retriever.cleanUrl(dirtyUrl)
|
||||
val doc = relayInformationDocumentCache.get(url)
|
||||
|
||||
if (doc != null) {
|
||||
onInfo(doc)
|
||||
} else {
|
||||
Nip11Retriever().loadRelayInfo(
|
||||
url,
|
||||
dirtyUrl,
|
||||
onInfo = {
|
||||
relayInformationDocumentCache.put(url, it)
|
||||
onInfo(it)
|
||||
},
|
||||
onError
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Nip11Retriever {
|
||||
enum class ErrorCode {
|
||||
FAIL_TO_ASSEMBLE_URL,
|
||||
FAIL_TO_REACH_SERVER,
|
||||
FAIL_TO_PARSE_RESULT,
|
||||
FAIL_WITH_HTTP_STATUS
|
||||
}
|
||||
|
||||
fun cleanUrl(dirtyUrl: String): String {
|
||||
return if (dirtyUrl.contains("://")) {
|
||||
dirtyUrl
|
||||
.replace("wss://", "https://")
|
||||
.replace("ws://", "http://")
|
||||
} else {
|
||||
"https://$dirtyUrl"
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun loadRelayInfo(
|
||||
url: String,
|
||||
dirtyUrl: String,
|
||||
onInfo: (RelayInformation) -> Unit,
|
||||
onError: (String, ErrorCode, String?) -> Unit
|
||||
) {
|
||||
try {
|
||||
val request: Request = Request
|
||||
.Builder()
|
||||
.header("Accept", "application/nostr+json")
|
||||
.url(url)
|
||||
.build()
|
||||
|
||||
HttpClient.getHttpClient()
|
||||
.newCall(request)
|
||||
.enqueue(
|
||||
object : Callback {
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
checkNotInMainThread()
|
||||
response.use {
|
||||
val body = it.body.string()
|
||||
try {
|
||||
if (it.isSuccessful) {
|
||||
onInfo(RelayInformation.fromJson(body))
|
||||
} else {
|
||||
onError(dirtyUrl, ErrorCode.FAIL_WITH_HTTP_STATUS, it.code.toString())
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("RelayInfoFail", "Resulting Message from Relay $dirtyUrl in not parseable: $body", e)
|
||||
onError(dirtyUrl, ErrorCode.FAIL_TO_PARSE_RESULT, e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
Log.e("RelayInfoFail", "$dirtyUrl unavailable", e)
|
||||
onError(dirtyUrl, ErrorCode.FAIL_TO_REACH_SERVER, e.message)
|
||||
}
|
||||
}
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e("RelayInfoFail", "Invalid URL $dirtyUrl", e)
|
||||
onError(dirtyUrl, ErrorCode.FAIL_TO_ASSEMBLE_URL, e.message)
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.Error
|
||||
|
||||
abstract class NostrDataSource(val debugName: String) {
|
||||
@ -23,6 +24,7 @@ abstract class NostrDataSource(val debugName: String) {
|
||||
data class Counter(var counter: Int)
|
||||
|
||||
private var eventCounter = mapOf<String, Counter>()
|
||||
var changingFilters = AtomicBoolean()
|
||||
|
||||
fun printCounter() {
|
||||
eventCounter.forEach {
|
||||
@ -59,11 +61,17 @@ abstract class NostrDataSource(val debugName: String) {
|
||||
|
||||
if (type == Relay.Type.EOSE && subscriptionId != null && subscriptionId in subscriptions.keys) {
|
||||
// updates a per subscripton since date
|
||||
subscriptions[subscriptionId]?.updateEOSE(TimeUtils.now(), relay.url)
|
||||
subscriptions[subscriptionId]?.updateEOSE(
|
||||
TimeUtils.fiveMinutesAgo(), // in case people's clock is slighly off.
|
||||
relay.url
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSendResponse(eventId: String, success: Boolean, message: String, relay: Relay) {
|
||||
if (success) {
|
||||
markAsSeenOnRelay(eventId, relay)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAuth(relay: Relay, challenge: String) {
|
||||
@ -136,6 +144,8 @@ abstract class NostrDataSource(val debugName: String) {
|
||||
// saves the current content to only update if it changes
|
||||
val currentFilters = activeSubscriptions.associate { it.id to it.toJson() }
|
||||
|
||||
changingFilters.getAndSet(true)
|
||||
|
||||
updateChannelFilters()
|
||||
|
||||
// Makes sure to only send an updated filter when it actually changes.
|
||||
@ -167,12 +177,18 @@ abstract class NostrDataSource(val debugName: String) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changingFilters.getAndSet(false)
|
||||
}
|
||||
|
||||
open fun consume(event: Event, relay: Relay) {
|
||||
LocalCache.verifyAndConsume(event, relay)
|
||||
}
|
||||
|
||||
open fun markAsSeenOnRelay(eventId: String, relay: Relay) {
|
||||
LocalCache.getNoteIfExists(eventId)?.addRelay(relay)
|
||||
}
|
||||
|
||||
abstract fun updateChannelFilters()
|
||||
open fun auth(relay: Relay, challenge: String) = Unit
|
||||
}
|
||||
|
@ -134,6 +134,9 @@ object NostrSingleEventDataSource : NostrDataSource("SingleEventFeed") {
|
||||
}
|
||||
|
||||
val singleEventChannel = requestNewChannel { time, relayUrl ->
|
||||
// Ignores EOSE if it is in the middle of a filter change.
|
||||
if (changingFilters.get()) return@requestNewChannel
|
||||
|
||||
checkNotInMainThread()
|
||||
|
||||
eventsToWatch.forEach {
|
||||
|
@ -16,9 +16,7 @@ object Constants {
|
||||
}
|
||||
|
||||
val defaultRelays = arrayOf(
|
||||
// Free relays for DMs and Follows
|
||||
RelaySetupInfo("wss://no.str.cr", read = true, write = true, feedTypes = activeTypes),
|
||||
RelaySetupInfo("wss://relay.snort.social", read = true, write = true, feedTypes = activeTypes),
|
||||
// Free relays for only DMs and Follows due to the amount of spam
|
||||
RelaySetupInfo("wss://relay.damus.io", read = true, write = true, feedTypes = activeTypes),
|
||||
|
||||
// Chats
|
||||
@ -40,6 +38,7 @@ object Constants {
|
||||
// NewRelayListViewModel.Relay("wss://brb.io", read = true, write = true, feedTypes = activeTypes),
|
||||
|
||||
// Paid relays
|
||||
RelaySetupInfo("wss://relay.snort.social", read = true, write = false, feedTypes = activeTypesGlobalChats),
|
||||
RelaySetupInfo("wss://relay.nostr.com.au", read = true, write = false, feedTypes = activeTypesGlobalChats),
|
||||
RelaySetupInfo("wss://eden.nostr.land", read = true, write = false, feedTypes = activeTypesGlobalChats),
|
||||
RelaySetupInfo("wss://nostr.milou.lol", read = true, write = false, feedTypes = activeTypesGlobalChats),
|
||||
@ -51,8 +50,15 @@ object Constants {
|
||||
RelaySetupInfo("wss://relay.nostrati.com", read = true, write = false, feedTypes = activeTypesGlobalChats),
|
||||
|
||||
// Supporting NIP-50
|
||||
RelaySetupInfo("wss://relay.nostr.band", read = true, write = false, feedTypes = activeTypesSearch)
|
||||
RelaySetupInfo("wss://relay.nostr.band", read = true, write = false, feedTypes = activeTypesSearch),
|
||||
RelaySetupInfo("wss://filter.nostr.wine", read = true, write = false, feedTypes = activeTypesSearch),
|
||||
RelaySetupInfo("wss://relay.noswhere.com", read = true, write = false, feedTypes = activeTypesSearch)
|
||||
)
|
||||
|
||||
val forcedRelayForSearch = RelaySetupInfo("wss://relay.nostr.band", read = true, write = false, feedTypes = activeTypesSearch)
|
||||
val forcedRelayForSearch = arrayOf(
|
||||
RelaySetupInfo("wss://relay.nostr.band", read = true, write = false, feedTypes = activeTypesSearch),
|
||||
RelaySetupInfo("wss://filter.nostr.wine", read = true, write = false, feedTypes = activeTypesSearch),
|
||||
RelaySetupInfo("wss://relay.noswhere.com", read = true, write = false, feedTypes = activeTypesSearch)
|
||||
)
|
||||
val forcedRelaysForSearchSet = forcedRelayForSearch.map { it.url }
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package com.vitorpamplona.amethyst.service.relays
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.quartz.events.Event
|
||||
import com.vitorpamplona.quartz.events.EventInterface
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
|
||||
/**
|
||||
* RelayPool manages the connection to multiple Relays and lets consumers deal with simple events.
|
||||
@ -12,6 +16,11 @@ object RelayPool : Relay.Listener {
|
||||
private var relays = listOf<Relay>()
|
||||
private var listeners = setOf<Listener>()
|
||||
|
||||
// Backing property to avoid flow emissions from other classes
|
||||
private var _lastStatus = RelayPoolStatus(0, 0)
|
||||
private val _statusFlow = MutableSharedFlow<RelayPoolStatus>(1, 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
val statusFlow: SharedFlow<RelayPoolStatus> = _statusFlow.asSharedFlow()
|
||||
|
||||
fun availableRelays(): Int {
|
||||
return relays.size
|
||||
}
|
||||
@ -76,11 +85,13 @@ object RelayPool : Relay.Listener {
|
||||
fun addRelay(relay: Relay) {
|
||||
relay.register(this)
|
||||
relays += relay
|
||||
updateStatus()
|
||||
}
|
||||
|
||||
fun removeRelay(relay: Relay) {
|
||||
relay.unregister(this)
|
||||
relays = relays.minus(relay)
|
||||
updateStatus()
|
||||
}
|
||||
|
||||
fun register(listener: Listener) {
|
||||
@ -109,12 +120,14 @@ object RelayPool : Relay.Listener {
|
||||
|
||||
override fun onError(relay: Relay, subscriptionId: String, error: Error) {
|
||||
listeners.forEach { it.onError(error, subscriptionId, relay) }
|
||||
refreshObservers()
|
||||
updateStatus()
|
||||
}
|
||||
|
||||
override fun onRelayStateChange(relay: Relay, type: Relay.Type, channel: String?) {
|
||||
listeners.forEach { it.onRelayStateChange(type, relay, channel) }
|
||||
refreshObservers()
|
||||
if (type != Relay.Type.EOSE) {
|
||||
updateStatus()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSendResponse(relay: Relay, eventId: String, success: Boolean, message: String) {
|
||||
@ -125,18 +138,15 @@ object RelayPool : Relay.Listener {
|
||||
listeners.forEach { it.onAuth(relay, challenge) }
|
||||
}
|
||||
|
||||
// Observers line up here.
|
||||
val live: RelayPoolLiveData = RelayPoolLiveData(this)
|
||||
|
||||
private fun refreshObservers() {
|
||||
live.refresh()
|
||||
private fun updateStatus() {
|
||||
val connected = connectedRelays()
|
||||
val available = availableRelays()
|
||||
if (_lastStatus.connected != connected || _lastStatus.available != available) {
|
||||
_lastStatus = RelayPoolStatus(connected, available)
|
||||
_statusFlow.tryEmit(_lastStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RelayPoolLiveData(val relays: RelayPool) : LiveData<RelayPoolState>(RelayPoolState(relays)) {
|
||||
fun refresh() {
|
||||
postValue(RelayPoolState(relays))
|
||||
}
|
||||
}
|
||||
|
||||
class RelayPoolState(val relays: RelayPool)
|
||||
@Immutable
|
||||
data class RelayPoolStatus(val connected: Int, val available: Int, val isConnected: Boolean = connected > 0)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.vitorpamplona.amethyst.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.ConnectivityManager
|
||||
@ -68,7 +69,10 @@ class MainActivity : AppCompatActivity() {
|
||||
themeViewModel.onChange(LocalPreferences.getTheme())
|
||||
AmethystTheme(themeViewModel) {
|
||||
// A surface container using the 'background' color from the theme
|
||||
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colors.background
|
||||
) {
|
||||
val accountStateViewModel: AccountStateViewModel = viewModel {
|
||||
AccountStateViewModel(this@MainActivity)
|
||||
}
|
||||
@ -84,7 +88,8 @@ class MainActivity : AppCompatActivity() {
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
.build()
|
||||
|
||||
val connectivityManager = getSystemService(ConnectivityManager::class.java) as ConnectivityManager
|
||||
val connectivityManager =
|
||||
getSystemService(ConnectivityManager::class.java) as ConnectivityManager
|
||||
connectivityManager.requestNetwork(networkRequest, networkCallback)
|
||||
}
|
||||
|
||||
@ -162,7 +167,8 @@ class MainActivity : AppCompatActivity() {
|
||||
super.onCapabilitiesChanged(network, networkCapabilities)
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val hasMobileData = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
val hasMobileData =
|
||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
val hasWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
Log.d("NETWORKCALLBACK", "onCapabilitiesChanged: hasMobileData $hasMobileData")
|
||||
Log.d("NETWORKCALLBACK", "onCapabilitiesChanged: hasWifi $hasWifi")
|
||||
@ -189,9 +195,15 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
class GetMediaActivityResultContract : ActivityResultContracts.GetContent() {
|
||||
|
||||
@SuppressLint("MissingSuperCall")
|
||||
override fun createIntent(context: Context, input: String): Intent {
|
||||
return super.createIntent(context, input).apply {
|
||||
// Force only images and videos to be selectable
|
||||
// Force OPEN Document because of the resulting URI must be passed to the
|
||||
// Playback service and the picker's permissions only allow the activity to read the URI
|
||||
return Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
// Force only images and videos to be selectable
|
||||
type = "*/*"
|
||||
putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.ui.actions
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.util.Size
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.Image
|
||||
@ -79,13 +80,7 @@ fun NewMediaView(uri: Uri, onClose: () -> Unit, postViewModel: NewMediaModel, ac
|
||||
var showRelaysDialog by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
var relayList = account.activeRelays()?.filter {
|
||||
it.write
|
||||
}?.map {
|
||||
it
|
||||
} ?: account.convertLocalRelays().filter {
|
||||
it.write
|
||||
}
|
||||
var relayList = account.activeWriteRelays()
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = { onClose() },
|
||||
@ -101,7 +96,7 @@ fun NewMediaView(uri: Uri, onClose: () -> Unit, postViewModel: NewMediaModel, ac
|
||||
) {
|
||||
if (showRelaysDialog) {
|
||||
RelaySelectionDialog(
|
||||
list = relayList,
|
||||
preSelectedList = relayList,
|
||||
onClose = {
|
||||
showRelaysDialog = false
|
||||
},
|
||||
@ -221,7 +216,8 @@ fun ImageVideoPost(postViewModel: NewMediaModel, accountViewModel: AccountViewMo
|
||||
try {
|
||||
bitmap = resolver.loadThumbnail(it, Size(1200, 1000), null)
|
||||
} catch (e: Exception) {
|
||||
postViewModel.imageUploadingError.emit("Unable to load file")
|
||||
postViewModel.imageUploadingError.emit("Unable to load thumbnail, but the video can be uploaded")
|
||||
Log.w("NewPostView", "Couldn't create thumbnail, but the video can be uploaded", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,13 +133,7 @@ fun NewPostView(
|
||||
var showRelaysDialog by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
var relayList = account.activeRelays()?.filter {
|
||||
it.write
|
||||
}?.map {
|
||||
it
|
||||
} ?: account.convertLocalRelays().filter {
|
||||
it.write
|
||||
}
|
||||
var relayList = account.activeWriteRelays()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
postViewModel.load(account, baseReplyTo, quote)
|
||||
@ -169,7 +163,7 @@ fun NewPostView(
|
||||
) {
|
||||
if (showRelaysDialog) {
|
||||
RelaySelectionDialog(
|
||||
list = relayList,
|
||||
preSelectedList = relayList,
|
||||
onClose = {
|
||||
showRelaysDialog = false
|
||||
},
|
||||
@ -1376,8 +1370,8 @@ fun ImageVideoDescription(
|
||||
try {
|
||||
bitmap = resolver.loadThumbnail(uri, Size(1200, 1000), null)
|
||||
} catch (e: Exception) {
|
||||
onError("Unable to load file")
|
||||
Log.e("NewPostView", "Couldn't create thumbnail for $uri")
|
||||
onError("Unable to load thumbnail")
|
||||
Log.w("NewPostView", "Couldn't create thumbnail, but the video can be uploaded", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.RelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
||||
import com.vitorpamplona.amethyst.service.relays.Constants
|
||||
import com.vitorpamplona.amethyst.service.relays.FeedType
|
||||
import com.vitorpamplona.amethyst.service.relays.RelayPool
|
||||
@ -24,6 +25,7 @@ class NewRelayListViewModel : ViewModel() {
|
||||
fun load(account: Account) {
|
||||
this.account = account
|
||||
clear()
|
||||
loadRelayDocuments()
|
||||
}
|
||||
|
||||
fun create() {
|
||||
@ -36,17 +38,34 @@ class NewRelayListViewModel : ViewModel() {
|
||||
clear()
|
||||
}
|
||||
|
||||
fun loadRelayDocuments() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
_relays.value.forEach { item ->
|
||||
Nip11CachedRetriever.loadRelayInfo(
|
||||
dirtyUrl = item.url,
|
||||
onInfo = {
|
||||
togglePaidRelay(item, it.limitation?.payment_required ?: false)
|
||||
},
|
||||
onError = { url, errorCode, exceptionMessage ->
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
_relays.update {
|
||||
var relayFile = account.userProfile().latestContactList?.relays()
|
||||
|
||||
// Ugly, but forces nostr.band as the only search-supporting relay today.
|
||||
// TODO: Remove when search becomes more available.
|
||||
if (relayFile?.none { it.key == Constants.forcedRelayForSearch.url } == true) {
|
||||
relayFile = relayFile + Pair(
|
||||
Constants.forcedRelayForSearch.url,
|
||||
ContactListEvent.ReadWrite(Constants.forcedRelayForSearch.read, Constants.forcedRelayForSearch.write)
|
||||
)
|
||||
if (relayFile?.none { it.key.removeSuffix("/") in Constants.forcedRelaysForSearchSet } == true) {
|
||||
relayFile = relayFile + Constants.forcedRelayForSearch.map {
|
||||
Pair(
|
||||
it.url,
|
||||
ContactListEvent.ReadWrite(it.read, it.write)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (relayFile != null) {
|
||||
|
@ -1,8 +1,5 @@
|
||||
package com.vitorpamplona.amethyst.ui.actions
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@ -28,27 +25,24 @@ import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.RelayBriefInfo
|
||||
import com.vitorpamplona.amethyst.model.RelayInformation
|
||||
import com.vitorpamplona.amethyst.service.HttpClient
|
||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.ui.components.ClickableEmail
|
||||
import com.vitorpamplona.amethyst.ui.components.ClickableUrl
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadUser
|
||||
import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import java.io.IOException
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size55dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun RelayInformationDialog(
|
||||
onClose: () -> Unit,
|
||||
relayBriefInfo: RelayBriefInfo,
|
||||
relayInfo: RelayInformation,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: (String) -> Unit
|
||||
@ -79,18 +73,25 @@ fun RelayInformationDialog(
|
||||
})
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
Title(relayInfo.name ?: "")
|
||||
}
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center, modifier = StdPadding.fillMaxWidth()) {
|
||||
Column() {
|
||||
RenderRelayIcon(
|
||||
relayBriefInfo.favIcon,
|
||||
Size55dp
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
SectionContent(relayInfo.description ?: "")
|
||||
Spacer(modifier = DoubleHorzSpacer)
|
||||
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Row() {
|
||||
Title(relayInfo.name?.trim() ?: "")
|
||||
}
|
||||
|
||||
Row() {
|
||||
SubtitleContent(relayInfo.description?.trim() ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section(stringResource(R.string.owner))
|
||||
@ -212,7 +213,7 @@ private fun DisplaySupportedNips(relayInfo: RelayInformation) {
|
||||
val text = item.toString().padStart(2, '0')
|
||||
Box(Modifier.padding(10.dp)) {
|
||||
ClickableUrl(
|
||||
urlText = "$text",
|
||||
urlText = text,
|
||||
url = "https://github.com/nostr-protocol/nips/blob/master/$text.md"
|
||||
)
|
||||
}
|
||||
@ -222,7 +223,7 @@ private fun DisplaySupportedNips(relayInfo: RelayInformation) {
|
||||
val text = item.padStart(2, '0')
|
||||
Box(Modifier.padding(10.dp)) {
|
||||
ClickableUrl(
|
||||
urlText = "$text",
|
||||
urlText = text,
|
||||
url = "https://github.com/nostr-protocol/nips/blob/master/$text.md"
|
||||
)
|
||||
}
|
||||
@ -258,13 +259,18 @@ private fun DisplayOwnerInformation(
|
||||
|
||||
@Composable
|
||||
fun Title(text: String) {
|
||||
Spacer(modifier = DoubleVertSpacer)
|
||||
Text(
|
||||
text = text,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 24.sp
|
||||
)
|
||||
Spacer(modifier = DoubleVertSpacer)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SubtitleContent(text: String) {
|
||||
Text(
|
||||
text = text
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ -285,85 +291,3 @@ fun SectionContent(text: String) {
|
||||
text = text
|
||||
)
|
||||
}
|
||||
|
||||
fun loadRelayInfo(
|
||||
dirtyUrl: String,
|
||||
context: Context,
|
||||
scope: CoroutineScope,
|
||||
onInfo: (RelayInformation) -> Unit
|
||||
) {
|
||||
try {
|
||||
val url = if (dirtyUrl.contains("://")) {
|
||||
dirtyUrl
|
||||
.replace("wss://", "https://")
|
||||
.replace("ws://", "http://")
|
||||
} else {
|
||||
"https://$dirtyUrl"
|
||||
}
|
||||
|
||||
val request: Request = Request
|
||||
.Builder()
|
||||
.header("Accept", "application/nostr+json")
|
||||
.url(url)
|
||||
.build()
|
||||
|
||||
HttpClient.getHttpClient()
|
||||
.newCall(request)
|
||||
.enqueue(
|
||||
object : Callback {
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
checkNotInMainThread()
|
||||
response.use {
|
||||
val body = it.body.string()
|
||||
try {
|
||||
if (it.isSuccessful) {
|
||||
onInfo(RelayInformation.fromJson(body))
|
||||
} else {
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
context.getString(R.string.an_error_occurred_trying_to_get_relay_information, dirtyUrl),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("RelayInfoFail", "Resulting Message from Relay $dirtyUrl in not parseable: $body", e)
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
context.getString(R.string.an_error_occurred_trying_to_get_relay_information, dirtyUrl),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
Log.e("RelayInfoFail", "$dirtyUrl unavailable", e)
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
context.getString(R.string.an_error_occurred_trying_to_get_relay_information, dirtyUrl),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e("RelayInfoFail", "Invalid URL $dirtyUrl", e)
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
context.getString(R.string.an_error_occurred_trying_to_get_relay_information, dirtyUrl),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,19 +29,27 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.RelayBriefInfo
|
||||
import com.vitorpamplona.amethyst.model.RelayInformation
|
||||
import com.vitorpamplona.amethyst.service.Nip11Retriever
|
||||
import com.vitorpamplona.amethyst.service.relays.Relay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
data class RelayList(
|
||||
val relay: Relay,
|
||||
val relayInfo: RelayBriefInfo,
|
||||
val isSelected: Boolean
|
||||
)
|
||||
|
||||
data class RelayInfoDialog(
|
||||
val relayBriefInfo: RelayBriefInfo,
|
||||
val relayInfo: RelayInformation
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun RelaySelectionDialog(
|
||||
list: List<Relay>,
|
||||
preSelectedList: List<Relay>,
|
||||
onClose: () -> Unit,
|
||||
onPost: (list: List<Relay>) -> Unit,
|
||||
accountViewModel: AccountViewModel,
|
||||
@ -49,34 +57,29 @@ fun RelaySelectionDialog(
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val relayList = accountViewModel.account.activeRelays()?.filter {
|
||||
it.write
|
||||
}?.map {
|
||||
it
|
||||
} ?: accountViewModel.account.convertLocalRelays().filter {
|
||||
it.write
|
||||
}
|
||||
|
||||
var relays by remember {
|
||||
mutableStateOf(
|
||||
relayList.map {
|
||||
accountViewModel.account.activeWriteRelays().map {
|
||||
RelayList(
|
||||
it,
|
||||
list.any { relay -> it.url == relay.url }
|
||||
relay = it,
|
||||
relayInfo = RelayBriefInfo(it.url),
|
||||
isSelected = preSelectedList.any { relay -> it.url == relay.url }
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
var relayInfo: RelayInformation? by remember { mutableStateOf(null) }
|
||||
var relayInfo: RelayInfoDialog? by remember { mutableStateOf(null) }
|
||||
|
||||
if (relayInfo != null) {
|
||||
relayInfo?.let {
|
||||
RelayInformationDialog(
|
||||
onClose = {
|
||||
relayInfo = null
|
||||
},
|
||||
relayInfo = relayInfo!!,
|
||||
accountViewModel,
|
||||
nav
|
||||
relayInfo = it.relayInfo,
|
||||
relayBriefInfo = it.relayBriefInfo,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav
|
||||
)
|
||||
}
|
||||
|
||||
@ -115,14 +118,14 @@ fun RelaySelectionDialog(
|
||||
}
|
||||
)
|
||||
|
||||
PostButton(
|
||||
SaveButton(
|
||||
onPost = {
|
||||
val selectedRelays = relays.filter { it.isSelected }
|
||||
if (selectedRelays.isEmpty()) {
|
||||
scope.launch {
|
||||
Toast.makeText(context, context.getString(R.string.select_a_relay_to_continue), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
return@PostButton
|
||||
return@SaveButton
|
||||
}
|
||||
onPost(selectedRelays.map { it.relay })
|
||||
onClose()
|
||||
@ -153,10 +156,7 @@ fun RelaySelectionDialog(
|
||||
key = { _, item -> item.relay.url }
|
||||
) { index, item ->
|
||||
RelaySwitch(
|
||||
text = item.relay.url
|
||||
.removePrefix("ws://")
|
||||
.removePrefix("wss://")
|
||||
.removeSuffix("/"),
|
||||
text = item.relayInfo.displayUrl,
|
||||
checked = item.isSelected,
|
||||
onClick = {
|
||||
relays = relays.mapIndexed { j, item ->
|
||||
@ -168,9 +168,30 @@ fun RelaySelectionDialog(
|
||||
}
|
||||
},
|
||||
onLongPress = {
|
||||
loadRelayInfo(item.relay.url, context, scope) {
|
||||
relayInfo = it
|
||||
}
|
||||
accountViewModel.retrieveRelayDocument(
|
||||
item.relay.url,
|
||||
onInfo = {
|
||||
relayInfo = RelayInfoDialog(RelayBriefInfo(item.relay.url), it)
|
||||
},
|
||||
onError = { url, errorCode, exceptionMessage ->
|
||||
val msg = when (errorCode) {
|
||||
Nip11Retriever.ErrorCode.FAIL_TO_ASSEMBLE_URL -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
Nip11Retriever.ErrorCode.FAIL_TO_REACH_SERVER -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
Nip11Retriever.ErrorCode.FAIL_TO_PARSE_RESULT -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
Nip11Retriever.ErrorCode.FAIL_WITH_HTTP_STATUS -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
}
|
||||
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
msg,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -451,8 +451,6 @@ fun GenericMainTopBar(
|
||||
nav: (String) -> Unit,
|
||||
content: @Composable (AccountViewModel) -> Unit
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
Column(modifier = BottomTopHeight) {
|
||||
MyTopAppBar(
|
||||
elevation = 0.dp,
|
||||
@ -476,6 +474,7 @@ fun GenericMainTopBar(
|
||||
}
|
||||
},
|
||||
navigationIcon = {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
LoggedInUserPictureDrawer(accountViewModel) {
|
||||
coroutineScope.launch {
|
||||
scaffoldState.drawerState.open()
|
||||
@ -506,10 +505,9 @@ private fun LoggedInUserPictureDrawer(
|
||||
accountViewModel: AccountViewModel,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
val accountUserState by accountViewModel.account.userProfile().live().metadata.observeAsState()
|
||||
val profilePicture by accountViewModel.account.userProfile().live().profilePictureChanges.observeAsState()
|
||||
|
||||
val pubkeyHex = remember { accountUserState?.user?.pubkeyHex ?: "" }
|
||||
val profilePicture = remember(accountUserState) { accountUserState?.user?.profilePicture() }
|
||||
val pubkeyHex = remember { accountViewModel.userProfile().pubkeyHex }
|
||||
|
||||
IconButton(
|
||||
onClick = onClick
|
||||
|
@ -40,6 +40,7 @@ import androidx.compose.material.icons.filled.Send
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
@ -63,7 +64,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.map
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import coil.compose.AsyncImage
|
||||
import com.vitorpamplona.amethyst.BuildConfig
|
||||
import com.vitorpamplona.amethyst.LocalPreferences
|
||||
@ -72,11 +72,12 @@ import com.vitorpamplona.amethyst.ServiceManager
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.HttpClient
|
||||
import com.vitorpamplona.amethyst.service.relays.RelayPool
|
||||
import com.vitorpamplona.amethyst.service.relays.RelayPoolStatus
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewRelayListView
|
||||
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
||||
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadStatuses
|
||||
import com.vitorpamplona.amethyst.ui.screen.RelayPoolViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountBackupDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
|
||||
@ -454,7 +455,6 @@ fun ListContent(
|
||||
}
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val relayViewModel: RelayPoolViewModel = viewModel { RelayPoolViewModel() }
|
||||
var wantsToEditRelays by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
@ -490,7 +490,7 @@ fun ListContent(
|
||||
)
|
||||
|
||||
IconRowRelays(
|
||||
relayViewModel = relayViewModel,
|
||||
accountViewModel = accountViewModel,
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
scaffoldState.drawerState.close()
|
||||
@ -633,27 +633,37 @@ private fun enableTor(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RelayStatus(
|
||||
relayViewModel: RelayPoolViewModel
|
||||
) {
|
||||
val connectedRelaysText by relayViewModel.connectionStatus.observeAsState("--/--")
|
||||
val isConnected by relayViewModel.isConnected.observeAsState(false)
|
||||
private fun RelayStatus(accountViewModel: AccountViewModel) {
|
||||
val connectedRelaysText by RelayPool.statusFlow.collectAsState(initial = RelayPoolStatus(0, 0))
|
||||
|
||||
RenderRelayStatus(connectedRelaysText, isConnected)
|
||||
RenderRelayStatus(connectedRelaysText)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderRelayStatus(
|
||||
connectedRelaysText: String,
|
||||
isConnected: Boolean
|
||||
relayPool: RelayPoolStatus
|
||||
) {
|
||||
val text by remember(relayPool) {
|
||||
derivedStateOf {
|
||||
"${relayPool.connected}/${relayPool.available}"
|
||||
}
|
||||
}
|
||||
|
||||
val placeHolder = MaterialTheme.colors.placeholderText
|
||||
|
||||
val color by remember(relayPool) {
|
||||
derivedStateOf {
|
||||
if (relayPool.isConnected) {
|
||||
placeHolder
|
||||
} else {
|
||||
Color.Red
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = connectedRelaysText,
|
||||
color = if (isConnected) {
|
||||
MaterialTheme.colors.placeholderText
|
||||
} else {
|
||||
Color.Red
|
||||
},
|
||||
text = text,
|
||||
color = color,
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
@ -709,7 +719,7 @@ fun IconRow(title: String, icon: Int, tint: Color, onClick: () -> Unit, onLongCl
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun IconRowRelays(relayViewModel: RelayPoolViewModel, onClick: () -> Unit) {
|
||||
fun IconRowRelays(accountViewModel: AccountViewModel, onClick: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@ -736,7 +746,7 @@ fun IconRowRelays(relayViewModel: RelayPoolViewModel, onClick: () -> Unit) {
|
||||
|
||||
Spacer(modifier = Modifier.width(Size16dp))
|
||||
|
||||
RelayStatus(relayViewModel = relayViewModel)
|
||||
RelayStatus(accountViewModel = accountViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ import com.vitorpamplona.amethyst.model.Channel
|
||||
import com.vitorpamplona.amethyst.model.ConnectivityType
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.RelayBriefInfo
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.AmberUtils
|
||||
import com.vitorpamplona.amethyst.service.OnlineChecker
|
||||
@ -1663,9 +1664,9 @@ fun DisplayRelaySet(
|
||||
) {
|
||||
val noteEvent = baseNote.event as? RelaySetEvent ?: return
|
||||
|
||||
val relays by remember {
|
||||
mutableStateOf<ImmutableList<String>>(
|
||||
noteEvent.relays().toImmutableList()
|
||||
val relays by remember(baseNote) {
|
||||
mutableStateOf(
|
||||
noteEvent.relays().map { RelayBriefInfo(it) }.toImmutableList()
|
||||
)
|
||||
}
|
||||
|
||||
@ -1720,7 +1721,7 @@ fun DisplayRelaySet(
|
||||
toMembersShow.forEach { relay ->
|
||||
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = CenterVertically) {
|
||||
Text(
|
||||
relay.trim().removePrefix("wss://").removePrefix("ws://").removeSuffix("/"),
|
||||
text = relay.displayUrl,
|
||||
fontWeight = FontWeight.Bold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
@ -1730,7 +1731,7 @@ fun DisplayRelaySet(
|
||||
)
|
||||
|
||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||
RelayOptionsAction(relay, accountViewModel, nav)
|
||||
RelayOptionsAction(relay.url, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2436,40 +2437,41 @@ private fun ReplyRow(
|
||||
}
|
||||
}
|
||||
|
||||
val showChannelInfo by remember(note) {
|
||||
derivedStateOf {
|
||||
if (noteEvent is ChannelMessageEvent || noteEvent is LiveActivitiesChatMessageEvent) {
|
||||
note.channelHex()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showChannelInfo?.let {
|
||||
ChannelHeader(
|
||||
channelHex = it,
|
||||
showVideo = false,
|
||||
showBottomDiviser = false,
|
||||
sendToChannel = true,
|
||||
modifier = MaterialTheme.colors.replyModifier.padding(10.dp),
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav
|
||||
)
|
||||
}
|
||||
|
||||
if (showReply) {
|
||||
val replyingDirectlyTo = remember { note.replyTo?.lastOrNull { it.event?.kind() != CommunityDefinitionEvent.kind } }
|
||||
if (replyingDirectlyTo != null && unPackReply) {
|
||||
ReplyNoteComposition(replyingDirectlyTo, backgroundColor, accountViewModel, nav)
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
} else {
|
||||
// ReplyInformation(note.replyTo, noteEvent.mentions(), accountViewModel, nav)
|
||||
}
|
||||
} else {
|
||||
val showChannelReply by remember {
|
||||
derivedStateOf {
|
||||
(noteEvent is ChannelMessageEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser())) ||
|
||||
(noteEvent is LiveActivitiesChatMessageEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser()))
|
||||
} else if (showChannelInfo != null) {
|
||||
val replies = remember { note.replyTo?.toImmutableList() }
|
||||
val mentions = remember {
|
||||
(note.event as? BaseTextNoteEvent)?.mentions()?.toImmutableList()
|
||||
?: persistentListOf()
|
||||
}
|
||||
}
|
||||
|
||||
if (showChannelReply) {
|
||||
val channelHex = note.channelHex()
|
||||
channelHex?.let {
|
||||
ChannelHeader(
|
||||
channelHex = channelHex,
|
||||
showVideo = false,
|
||||
showBottomDiviser = false,
|
||||
sendToChannel = true,
|
||||
modifier = remember { Modifier.padding(vertical = 5.dp) },
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav
|
||||
)
|
||||
|
||||
val replies = remember { note.replyTo?.toImmutableList() }
|
||||
val mentions = remember { (note.event as? BaseTextNoteEvent)?.mentions()?.toImmutableList() ?: persistentListOf() }
|
||||
|
||||
ReplyInformationChannel(replies, mentions, accountViewModel, nav)
|
||||
}
|
||||
ReplyInformationChannel(replies, mentions, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,17 +11,16 @@ import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ExpandMore
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.screen.equalImmutableLists
|
||||
import com.vitorpamplona.amethyst.model.RelayBriefInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonBoxModifer
|
||||
@ -29,80 +28,40 @@ import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonIconButtonModifie
|
||||
import com.vitorpamplona.amethyst.ui.theme.ShowMoreRelaysButtonIconModifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
public fun RelayBadges(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
var showShowMore by remember { mutableStateOf(false) }
|
||||
|
||||
var lazyRelayList by remember {
|
||||
val baseNumber = baseNote.relays.map {
|
||||
it.removePrefix("wss://").removePrefix("ws://")
|
||||
}.toImmutableList()
|
||||
|
||||
mutableStateOf(baseNumber)
|
||||
}
|
||||
var shortRelayList by remember {
|
||||
mutableStateOf(lazyRelayList.take(3).toImmutableList())
|
||||
}
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
WatchRelayLists(baseNote) { relayList ->
|
||||
if (!equalImmutableLists(relayList, lazyRelayList)) {
|
||||
scope.launch(Dispatchers.Main) {
|
||||
lazyRelayList = relayList
|
||||
shortRelayList = relayList.take(3).toImmutableList()
|
||||
}
|
||||
}
|
||||
|
||||
val nextShowMore = relayList.size > 3
|
||||
if (nextShowMore != showShowMore) {
|
||||
scope.launch(Dispatchers.Main) {
|
||||
// only triggers recomposition when actually different
|
||||
showShowMore = nextShowMore
|
||||
}
|
||||
val relayList by baseNote.live().relayInfo.observeAsState(persistentListOf())
|
||||
val shortRelayList by remember {
|
||||
derivedStateOf {
|
||||
relayList.take(3).toImmutableList()
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(DoubleVertSpacer)
|
||||
|
||||
if (expanded) {
|
||||
VerticalRelayPanelWithFlow(lazyRelayList, accountViewModel, nav)
|
||||
VerticalRelayPanelWithFlow(relayList, accountViewModel, nav)
|
||||
} else {
|
||||
VerticalRelayPanelWithFlow(shortRelayList, accountViewModel, nav)
|
||||
}
|
||||
|
||||
if (showShowMore && !expanded) {
|
||||
if (relayList.size > 3 && !expanded) {
|
||||
ShowMoreRelaysButton {
|
||||
expanded = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WatchRelayLists(baseNote: Note, onListChanges: (ImmutableList<String>) -> Unit) {
|
||||
val noteRelaysState by baseNote.live().relays.observeAsState()
|
||||
|
||||
LaunchedEffect(key1 = noteRelaysState) {
|
||||
launch(Dispatchers.IO) {
|
||||
val relayList = noteRelaysState?.note?.relays?.map {
|
||||
it.removePrefix("wss://").removePrefix("ws://")
|
||||
} ?: emptyList()
|
||||
|
||||
onListChanges(relayList.toImmutableList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
@Stable
|
||||
private fun VerticalRelayPanelWithFlow(
|
||||
relays: ImmutableList<String>,
|
||||
relays: ImmutableList<RelayBriefInfo>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: (String) -> Unit
|
||||
) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.vitorpamplona.amethyst.ui.note
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
@ -17,7 +18,6 @@ import androidx.compose.material.icons.filled.ChevronRight
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -29,13 +29,15 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.map
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.RelayBriefInfo
|
||||
import com.vitorpamplona.amethyst.model.RelayInformation
|
||||
import com.vitorpamplona.amethyst.service.Nip11Retriever
|
||||
import com.vitorpamplona.amethyst.ui.actions.RelayInformationDialog
|
||||
import com.vitorpamplona.amethyst.ui.actions.loadRelayInfo
|
||||
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter
|
||||
@ -44,6 +46,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size15dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdStartPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
public fun RelayBadgesHorizontal(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
@ -59,15 +63,13 @@ public fun RelayBadgesHorizontal(baseNote: Note, accountViewModel: AccountViewMo
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun RenderRelayList(baseNote: Note, expanded: MutableState<Boolean>, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
val noteRelays by baseNote.live().relays.map {
|
||||
it.note.relays
|
||||
}.observeAsState(baseNote.relays)
|
||||
val noteRelays by baseNote.live().relayInfo.observeAsState()
|
||||
|
||||
FlowRow(StdStartPadding) {
|
||||
val relaysToDisplay = remember(noteRelays, expanded.value) {
|
||||
if (expanded.value) noteRelays else noteRelays.take(3)
|
||||
if (expanded.value) noteRelays else noteRelays?.take(3)?.toImmutableList()
|
||||
}
|
||||
relaysToDisplay.forEach {
|
||||
relaysToDisplay?.forEach {
|
||||
RenderRelay(it, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
@ -104,14 +106,7 @@ fun ChatRelayExpandButton(onClick: () -> Unit) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RenderRelay(dirtyUrl: String, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
val iconUrl by remember(dirtyUrl) {
|
||||
derivedStateOf {
|
||||
val cleanUrl = dirtyUrl.trim().removePrefix("wss://").removePrefix("ws://").removeSuffix("/")
|
||||
"https://$cleanUrl/favicon.ico"
|
||||
}
|
||||
}
|
||||
|
||||
fun RenderRelay(relay: RelayBriefInfo, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
var relayInfo: RelayInformation? by remember { mutableStateOf(null) }
|
||||
|
||||
if (relayInfo != null) {
|
||||
@ -120,8 +115,9 @@ fun RenderRelay(dirtyUrl: String, accountViewModel: AccountViewModel, nav: (Stri
|
||||
relayInfo = null
|
||||
},
|
||||
relayInfo = relayInfo!!,
|
||||
accountViewModel,
|
||||
nav
|
||||
relayBriefInfo = relay,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav
|
||||
)
|
||||
}
|
||||
|
||||
@ -130,7 +126,7 @@ fun RenderRelay(dirtyUrl: String, accountViewModel: AccountViewModel, nav: (Stri
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val ripple = rememberRipple(bounded = false, radius = Size15dp)
|
||||
|
||||
val clickableModifier = remember(dirtyUrl) {
|
||||
val clickableModifier = remember(relay) {
|
||||
Modifier
|
||||
.padding(1.dp)
|
||||
.size(Size15dp)
|
||||
@ -139,9 +135,30 @@ fun RenderRelay(dirtyUrl: String, accountViewModel: AccountViewModel, nav: (Stri
|
||||
interactionSource = interactionSource,
|
||||
indication = ripple,
|
||||
onClick = {
|
||||
loadRelayInfo(dirtyUrl, context, scope) {
|
||||
relayInfo = it
|
||||
}
|
||||
accountViewModel.retrieveRelayDocument(
|
||||
relay.url,
|
||||
onInfo = {
|
||||
relayInfo = it
|
||||
},
|
||||
onError = { url, errorCode, exceptionMessage ->
|
||||
val msg = when (errorCode) {
|
||||
Nip11Retriever.ErrorCode.FAIL_TO_ASSEMBLE_URL -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
Nip11Retriever.ErrorCode.FAIL_TO_REACH_SERVER -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
Nip11Retriever.ErrorCode.FAIL_TO_PARSE_RESULT -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
Nip11Retriever.ErrorCode.FAIL_WITH_HTTP_STATUS -> context.getString(R.string.relay_information_document_error_assemble_url, url, exceptionMessage)
|
||||
}
|
||||
|
||||
scope.launch {
|
||||
Toast
|
||||
.makeText(
|
||||
context,
|
||||
msg,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -149,17 +166,17 @@ fun RenderRelay(dirtyUrl: String, accountViewModel: AccountViewModel, nav: (Stri
|
||||
Box(
|
||||
modifier = clickableModifier
|
||||
) {
|
||||
RenderRelayIcon(iconUrl)
|
||||
RenderRelayIcon(relay.favIcon)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderRelayIcon(iconUrl: String) {
|
||||
fun RenderRelayIcon(iconUrl: String, size: Dp = Size13dp) {
|
||||
val backgroundColor = MaterialTheme.colors.background
|
||||
|
||||
val iconModifier = remember {
|
||||
Modifier
|
||||
.size(Size13dp)
|
||||
.size(size)
|
||||
.clip(shape = CircleShape)
|
||||
.background(backgroundColor)
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.distinctUntilChanged
|
||||
import androidx.lifecycle.map
|
||||
import com.vitorpamplona.amethyst.service.relays.RelayPool
|
||||
|
||||
@Stable
|
||||
class RelayPoolViewModel : ViewModel() {
|
||||
val connectionStatus = RelayPool.live.map {
|
||||
val connectedRelays = it.relays.connectedRelays()
|
||||
val availableRelays = it.relays.availableRelays()
|
||||
"$connectedRelays/$availableRelays"
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val isConnected = RelayPool.live.map {
|
||||
it.relays.connectedRelays() > 0
|
||||
}.distinctUntilChanged()
|
||||
}
|
@ -19,10 +19,13 @@ import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.model.ConnectivityType
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.RelayInformation
|
||||
import com.vitorpamplona.amethyst.model.UrlCachedPreviewer
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.UserState
|
||||
import com.vitorpamplona.amethyst.service.Nip05Verifier
|
||||
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
||||
import com.vitorpamplona.amethyst.service.Nip11Retriever
|
||||
import com.vitorpamplona.amethyst.service.OnlineChecker
|
||||
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
|
||||
import com.vitorpamplona.amethyst.ui.components.UrlPreviewState
|
||||
@ -571,6 +574,16 @@ class AccountViewModel(val account: Account) : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun retrieveRelayDocument(
|
||||
dirtyUrl: String,
|
||||
onInfo: (RelayInformation) -> Unit,
|
||||
onError: (String, Nip11Retriever.ErrorCode, String?) -> Unit
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
Nip11CachedRetriever.loadRelayInfo(dirtyUrl, onInfo, onError)
|
||||
}
|
||||
}
|
||||
|
||||
class Factory(val account: Account) : ViewModelProvider.Factory {
|
||||
override fun <AccountViewModel : ViewModel> create(modelClass: Class<AccountViewModel>): AccountViewModel {
|
||||
return AccountViewModel(account) as AccountViewModel
|
||||
|
@ -416,14 +416,11 @@ private fun VideoUserOptionAction(
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun RelayBadges(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
val noteRelaysState by baseNote.live().relays.observeAsState()
|
||||
val noteRelays = remember(noteRelaysState) {
|
||||
noteRelaysState?.note?.relays ?: emptySet()
|
||||
}
|
||||
val noteRelays by baseNote.live().relayInfo.observeAsState()
|
||||
|
||||
FlowRow() {
|
||||
noteRelays.forEach { dirtyUrl ->
|
||||
RenderRelay(dirtyUrl, accountViewModel, nav)
|
||||
noteRelays?.forEach { relayInfo ->
|
||||
RenderRelay(relayInfo, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,3 +24,9 @@ val DarkerGreen = Color.Green.copy(alpha = 0.32f)
|
||||
val WarningColor = Color(0xFFC62828)
|
||||
|
||||
val RelayIconFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0.5f) })
|
||||
|
||||
val LightWarningColor = Color(0xFFffcc00)
|
||||
val DarkWarningColor = Color(0xFFF8DE22)
|
||||
|
||||
val LightAllGoodColor = Color(0xFF339900)
|
||||
val DarkAllGoodColor = Color(0xFF99cc33)
|
||||
|
@ -286,6 +286,12 @@ val Colors.overPictureBackground: Color
|
||||
val Colors.bitcoinColor: Color
|
||||
get() = if (isLight) BitcoinLight else BitcoinDark
|
||||
|
||||
val Colors.warningColor: Color
|
||||
get() = if (isLight) LightWarningColor else DarkWarningColor
|
||||
|
||||
val Colors.allGoodColor: Color
|
||||
get() = if (isLight) LightAllGoodColor else DarkAllGoodColor
|
||||
|
||||
val Colors.markdownStyle: RichTextStyle
|
||||
get() = if (isLight) MarkDownStyleOnLight else MarkDownStyleOnDark
|
||||
|
||||
|
@ -37,7 +37,8 @@
|
||||
<string name="login_with_a_private_key_to_be_able_to_unfollow">Přihlaste se pomocí soukromého klíče, abyste mohli zrušit sledování</string>
|
||||
<string name="zaps">Zapy</string>
|
||||
<string name="view_count">Počet zobrazení</string>
|
||||
<string name="boosted">boostováno</string>
|
||||
<string name="boost">Zvýšení</string>
|
||||
<string name="boosted">zvýšeno</string>
|
||||
<string name="quote">Citovat</string>
|
||||
<string name="new_amount_in_sats">Nová částka v sats</string>
|
||||
<string name="add">Přidat</string>
|
||||
@ -290,6 +291,7 @@
|
||||
<string name="zap_type_private_explainer">Odesílatel a příjemce si mohou navzájem vidět a číst zprávu</string>
|
||||
<string name="zap_type_anonymous">Anonymní</string>
|
||||
<string name="zap_type_anonymous_explainer">Příjemce a veřejnost neví, kdo platbu poslal</string>
|
||||
<string name="zap_type_nonzap">Né Zap</string>
|
||||
<string name="zap_type_nonzap_explainer">Žádná stopa v Nostr, pouze v Lightning</string>
|
||||
<string name="file_server">Souborový server</string>
|
||||
<string name="zap_forward_lnAddress">LnAddress nebo @Uživatel</string>
|
||||
@ -358,6 +360,7 @@
|
||||
<string name="warn_when_posts_have_reports_from_your_follows">Varovat, když příspěvky obsahují hlášení od vašich sledovaných osob</string>
|
||||
<string name="new_reaction_symbol">Nový symbol reakce</string>
|
||||
<string name="no_reaction_type_setup_long_press_to_change">Nebyly vybrány žádné typy reakcí. Dlouhým stiskem změňte</string>
|
||||
<string name="zapraiser">Zap-sběr</string>
|
||||
<string name="zapraiser_explainer">Přidá cílovou částku sats pro tento příspěvek. Podporované klienty ji mohou zobrazovat jako ukazatel postupu k podněcování darování</string>
|
||||
<string name="zapraiser_target_amount_in_sats">Cílová částka v sats</string>
|
||||
<string name="sats_to_complete">Zapraiser na %1$s. Do cíle zbývá %2$s sats</string>
|
||||
@ -451,4 +454,13 @@
|
||||
<string name="automatically_play_videos_description">Automaticky přehrávat videa a GIFy</string>
|
||||
<string name="automatically_show_url_preview_description">Zobrazit náhledy URL</string>
|
||||
<string name="load_image_description">Kdy načíst obrázek</string>
|
||||
<string name="copy_url_to_clipboard">Kopírovat URL do schránky</string>
|
||||
<string name="copy_the_note_id_to_the_clipboard">Kopírovat ID poznámky do schránky</string>
|
||||
<string name="created_at">Vytvořeno</string>
|
||||
<string name="rules">Pravidla</string>
|
||||
<string name="status_update">Aktualizovat svůj stav</string>
|
||||
<string name="lightning_wallets_not_found">Chyba při zpracování chybové zprávy</string>
|
||||
<string name="poll_zap_value_min_max_explainer">Hlasy jsou váženy podle hodnoty zapu. Můžete nastavit minimální částku, abyste se vyhnuli spammerům, a maximální částku, abyste zabránili velkým zapperům, kteří by mohli ovládnout hlasování. Použijte stejnou částku v obou polích, aby byla hodnota každého hlasu stejná. Nechte prázdné pro přijetí libovolné částky.</string>
|
||||
<string name="error_dialog_zap_error">Nelze odeslat zap</string>
|
||||
<string name="error_dialog_talk_to_user">Poslat zprávu uživateli</string>
|
||||
</resources>
|
||||
|
@ -36,6 +36,7 @@
|
||||
<string name="login_with_a_private_key_to_be_able_to_follow">Melden Sie sich mit einem privaten Schlüssel an, um zu folgen</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_unfollow">Melden Sie sich mit einem privaten Schlüssel an, um nicht mehr zu folgen</string>
|
||||
<string name="view_count">Aufrufe</string>
|
||||
<string name="boost">Verstärken</string>
|
||||
<string name="boosted">Verstärkt</string>
|
||||
<string name="quote">Zitat</string>
|
||||
<string name="new_amount_in_sats">Neuer Betrag in Sats</string>
|
||||
@ -169,6 +170,8 @@ anz der Bedingungen ist erforderlich</string>
|
||||
<string name="nip_05">Nostr-Adresse</string>
|
||||
<string name="never">nie</string>
|
||||
<string name="now">jetzt</string>
|
||||
<string name="h">s</string>
|
||||
<string name="d">t</string>
|
||||
<string name="nudity">Nacktheit</string>
|
||||
<string name="profanity_hateful_speech">Beleidigungen / Hassrede</string>
|
||||
<string name="report_hateful_speech">Hassrede melden</string>
|
||||
@ -246,8 +249,11 @@ anz der Bedingungen ist erforderlich</string>
|
||||
<string name="add_to_public_bookmarks">Zu den öffentlichen Lesezeichen hinzufügen</string>
|
||||
<string name="remove_from_private_bookmarks">Aus den privaten Lesezeichen entfernen</string>
|
||||
<string name="remove_from_public_bookmarks">Aus den öffentlichen Lesezeichen entfernen</string>
|
||||
<string name="wallet_connect_service">Wallet-Verbindungsdienst</string>
|
||||
<string name="wallet_connect_service_explainer">Autorisiert einen Nostr Secret, Zaps ohne Verlassen der App zu bezahlen. Bewahren Sie den geheimen Schlüssel sicher auf und verwenden Sie nach Möglichkeit ein privates Relay</string>
|
||||
<string name="wallet_connect_service_pubkey">Wallet Connect Public Key</string>
|
||||
<string name="wallet_connect_service_relay">Wallet-Verbindungs-Relay</string>
|
||||
<string name="wallet_connect_service_secret">Wallet-Verbindungs-Geheimnis</string>
|
||||
<string name="wallet_connect_service_show_secret">Geheimen Schlüssel anzeigen</string>
|
||||
<string name="wallet_connect_service_secret_placeholder">nsec / hexadezimaler privater Schlüssel</string>
|
||||
<string name="pledge_amount_in_sats">Spendenbetrag in Sats</string>
|
||||
@ -288,6 +294,7 @@ anz der Bedingungen ist erforderlich</string>
|
||||
<string name="zap_type_private_explainer">Absender und Empfänger können einander sehen und die Nachricht lesen</string>
|
||||
<string name="zap_type_anonymous">Anonym</string>
|
||||
<string name="zap_type_anonymous_explainer">Empfänger und die Öffentlichkeit wissen nicht, wer die Zahlung gesendet hat</string>
|
||||
<string name="zap_type_nonzap">Keine Zap</string>
|
||||
<string name="zap_type_nonzap_explainer">Keine Spur in Nostr, nur in Lightning</string>
|
||||
<string name="file_server">Dateiserver</string>
|
||||
<string name="zap_forward_lnAddress">LnAddress oder @Benutzer</string>
|
||||
@ -321,6 +328,7 @@ anz der Bedingungen ist erforderlich</string>
|
||||
<string name="no">Nein</string>
|
||||
<string name="follow_list_selection">Folgen-Liste</string>
|
||||
<string name="follow_list_kind3follows">Alle Folgen</string>
|
||||
<string name="follow_list_global">Weltweit</string>
|
||||
<string name="connect_through_your_orbot_setup_markdown"> ## Über Tor mit Orbot verbinden
|
||||
\n\n1. Installiere [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)
|
||||
\n2. Starte Orbot
|
||||
@ -356,6 +364,7 @@ anz der Bedingungen ist erforderlich</string>
|
||||
<string name="warn_when_posts_have_reports_from_your_follows">Warnung bei Meldungen von deinen Abonnements</string>
|
||||
<string name="new_reaction_symbol">Neues Reaktionssymbol</string>
|
||||
<string name="no_reaction_type_setup_long_press_to_change">Keine Reaktionstypen ausgewählt. Lange drücken, um zu ändern</string>
|
||||
<string name="zapraiser">Zap-Sammlung</string>
|
||||
<string name="zapraiser_explainer">Fügt einen Zielbetrag in Sats für diesen Beitrag hinzu. Unterstützende Clients können dies als Fortschrittsbalken anzeigen, um Spenden zu fördern</string>
|
||||
<string name="zapraiser_target_amount_in_sats">Zielbetrag in Sats</string>
|
||||
<string name="sats_to_complete">Zapraiser bei %1$s. %2$s Sats bis zum Ziel</string>
|
||||
@ -443,4 +452,13 @@ anz der Bedingungen ist erforderlich</string>
|
||||
<string name="automatically_play_videos_description">Videos und GIFs automatisch abspielen</string>
|
||||
<string name="automatically_show_url_preview_description">URL-Vorschauen anzeigen</string>
|
||||
<string name="load_image_description">Wann Bilder geladen werden sollen</string>
|
||||
<string name="copy_url_to_clipboard">URL in die Zwischenablage kopieren</string>
|
||||
<string name="copy_the_note_id_to_the_clipboard">Notiz-ID in die Zwischenablage kopieren</string>
|
||||
<string name="created_at">Erstellt am</string>
|
||||
<string name="rules">Regeln</string>
|
||||
<string name="status_update">Status aktualisieren</string>
|
||||
<string name="lightning_wallets_not_found">Fehler beim Verarbeiten der Fehlermeldung</string>
|
||||
<string name="poll_zap_value_min_max_explainer">Die Abstimmungen werden nach der Höhe des Zaps gewichtet. Sie können einen Mindestbetrag festlegen, um Spam zu verhindern, und einen Höchstbetrag, um zu verhindern, dass große Zapper die Abstimmung dominieren. Verwenden Sie denselben Betrag in beiden Feldern, um sicherzustellen, dass jeder Stimme der gleiche Wert zukommt. Lassen Sie es leer, um jeden Betrag zu akzeptieren.</string>
|
||||
<string name="error_dialog_zap_error">Zap konnte nicht gesendet werden</string>
|
||||
<string name="error_dialog_talk_to_user">Mit dem Benutzer kommunizieren</string>
|
||||
</resources>
|
||||
|
530
app/src/main/res/values-in/strings.xml
Normal file
530
app/src/main/res/values-in/strings.xml
Normal file
@ -0,0 +1,530 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="point_to_the_qr_code">Arahkan ke Kode QR</string>
|
||||
<string name="show_qr">Tampilkan QR</string>
|
||||
<string name="profile_image">Foto Profil</string>
|
||||
<string name="scan_qr">Pindai QR</string>
|
||||
<string name="show_anyway">Tampilkan Saja</string>
|
||||
<string name="post_was_flagged_as_inappropriate_by">Postingan dilaporkan oleh</string>
|
||||
<string name="post_not_found">Data sedang dimuat atau tidak dapat ditemukan di daftar relai Anda</string>
|
||||
<string name="channel_image">Gambar Kanal</string>
|
||||
<string name="referenced_event_not_found">Data yang direferensikan tidak ditemukan</string>
|
||||
<string name="could_not_decrypt_the_message">Tidak dapat mendeskripsikan pesan</string>
|
||||
<string name="group_picture">Gambar Grup</string>
|
||||
<string name="explicit_content">Konten Eksplisit</string>
|
||||
<string name="spam">Spam</string>
|
||||
<string name="impersonation">Peniruan/penipuan</string>
|
||||
<string name="illegal_behavior">Perilaku Ilegal</string>
|
||||
<string name="unknown">Tidak dikenal</string>
|
||||
<string name="relay_icon">Ikon Relai</string>
|
||||
<string name="unknown_author">Penulis Tidak Dikenal</string>
|
||||
<string name="copy_text">Salin Teks</string>
|
||||
<string name="copy_user_pubkey">Salin ID Penulis (Author ID)</string>
|
||||
<string name="copy_note_id">Salin ID Tulisan (Note ID)</string>
|
||||
<string name="broadcast">Siarkan</string>
|
||||
<string name="request_deletion">Minta Penghapusan</string>
|
||||
<string name="block_report">Blokir / Laporkan</string>
|
||||
<string name="block_hide_user"><![CDATA[Blokir & Sembunyikan Pengguna]]></string>
|
||||
<string name="report_spam_scam">Laporkan Spam / Penipuan</string>
|
||||
<string name="report_impersonation">Laporkan Peniruan</string>
|
||||
<string name="report_explicit_content">Laporkan Konten Eksplisit</string>
|
||||
<string name="report_illegal_behaviour">Laporkan Perilaku Ilegal</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_reply">Masuk dengan Kunci pribadi (nsec) untuk dapat membalas tulisan</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_boost_posts">Masuk dengan Kunci pribadi (nsec) untuk dapat mempromosikan tulisan</string>
|
||||
<string name="login_with_a_private_key_to_like_posts">Masuk dengan Kunci pribadi (nsec) untuk dapat menyukai tulisan</string>
|
||||
<string name="no_zap_amount_setup_long_press_to_change">Tidak Ada Pengaturan Jumlah Zap. Tekan dan tahan tombol untuk mengubah</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_send_zaps">Masuk dengan Kunci pribadi (nsec) untuk dapat mengirim Zaps</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_follow">Masuk dengan Kunci pribadi (nsec) untuk dapat mengikuti</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_unfollow">Masuk dengan Kunci pribadi (nsec) untuk berhenti mengikuti</string>
|
||||
<string name="zaps">Zaps</string>
|
||||
<string name="view_count">Jumlah pengamat</string>
|
||||
<string name="boost">Promosi</string>
|
||||
<string name="boosted">dipromosikan</string>
|
||||
<string name="quote">Kutipan</string>
|
||||
<string name="new_amount_in_sats">Jumlah Baru dalam Sats</string>
|
||||
<string name="add">Tambah</string>
|
||||
<string name="replying_to">"membalas kepada "</string>
|
||||
<string name="and">" dan "</string>
|
||||
<string name="in_channel">dalam kanal</string>
|
||||
<string name="profile_banner">Spanduk Profil</string>
|
||||
<string name="payment_successful">Pembayaran Berhasil</string>
|
||||
<string name="error_parsing_error_message">Gagal menguraikan pesan kesalahan</string>
|
||||
<string name="following">" Mengikuti"</string>
|
||||
<string name="followers">" Pengikut"</string>
|
||||
<string name="profile">Profil</string>
|
||||
<string name="security_filters">Filter Keamanan</string>
|
||||
<string name="log_out">Keluar</string>
|
||||
<string name="show_more">Tampilkan lebih banyak</string>
|
||||
<string name="lightning_invoice">Faktur Tagihan Lightning</string>
|
||||
<string name="pay">Bayar</string>
|
||||
<string name="lightning_tips">Lightning Tip</string>
|
||||
<string name="note_to_receiver">Catatan ke Penerima</string>
|
||||
<string name="thank_you_so_much">Terima kasih banyak!</string>
|
||||
<string name="amount_in_sats">Jumlah dalam Sats</string>
|
||||
<string name="send_sats">Kirim Sats</string>
|
||||
<string name="error_parsing_preview_for">Gagal menampilkan pratinjau untuk %1$s : %2$s</string>
|
||||
<string name="preview_card_image_for">Pratinjau Gambar Kartu untuk %1$s</string>
|
||||
<string name="new_channel">Kanal Baru</string>
|
||||
<string name="channel_name">Nama Kanal</string>
|
||||
<string name="my_awesome_group">Grupku yang Hebat</string>
|
||||
<string name="picture_url">Alamat Url Gambar</string>
|
||||
<string name="description">Deskripsi</string>
|
||||
<string name="about_us">"Tentang kami.. "</string>
|
||||
<string name="what_s_on_your_mind">Apa yang anda pikirkan?</string>
|
||||
<string name="post">Kirim</string>
|
||||
<string name="save">Simpan</string>
|
||||
<string name="create">Buat</string>
|
||||
<string name="cancel">Batal</string>
|
||||
<string name="failed_to_upload_the_image">Gagal mengunggah gambar</string>
|
||||
<string name="relay_address">Alamat Relai</string>
|
||||
<string name="posts">Kiriman</string>
|
||||
<string name="bytes">Bytes</string>
|
||||
<string name="errors">Errors</string>
|
||||
<string name="home_feed">Beranda</string>
|
||||
<string name="private_message_feed">Area Pesan Pribadi</string>
|
||||
<string name="public_chat_feed">Area Percakapan Publik</string>
|
||||
<string name="global_feed">Area Global</string>
|
||||
<string name="search_feed">Area Pencarian</string>
|
||||
<string name="add_a_relay">Tambah Relai</string>
|
||||
<string name="display_name">Nama ditampilkan</string>
|
||||
<string name="my_display_name">Namaku yg ditampilkan</string>
|
||||
<string name="username">Nama pengguna</string>
|
||||
<string name="my_username">Nama penggunaku</string>
|
||||
<string name="about_me">Tentang saya</string>
|
||||
<string name="avatar_url">URL Avatar</string>
|
||||
<string name="banner_url">"URL Spanduk/Banner "</string>
|
||||
<string name="website_url">URL Situs Web</string>
|
||||
<string name="ln_address">Alamat LN</string>
|
||||
<string name="ln_url_outdated">LN URL (versi lama)</string>
|
||||
<string name="image_saved_to_the_gallery">Gambar disimpan ke galeri</string>
|
||||
<string name="failed_to_save_the_image">Gagal menyimpan gambar</string>
|
||||
<string name="upload_image">Unggah Gambar</string>
|
||||
<string name="uploading">Mengunggah…</string>
|
||||
<string name="user_does_not_have_a_lightning_address_setup_to_receive_sats">Pengguna tidak memiliki alamat lightning (LN) yang diatur untuk menerima sats</string>
|
||||
<string name="reply_here">"balas di sini.. "</string>
|
||||
<string name="copies_the_note_id_to_the_clipboard_for_sharing">Menyalin ID Catatan ke papan klip untuk dibagikan di Nostr</string>
|
||||
<string name="copy_channel_id_note_to_the_clipboard">Salin ID Kanal (Catatan) ke Papan Klip</string>
|
||||
<string name="edits_the_channel_metadata">Ubah Metadata Kanal</string>
|
||||
<string name="join">Gabung</string>
|
||||
<string name="known">Dikenali</string>
|
||||
<string name="new_requests">Permintaan Baru</string>
|
||||
<string name="blocked_users">Pengguna diblokir</string>
|
||||
<string name="new_threads">Utas Baru</string>
|
||||
<string name="conversations">Percakapan</string>
|
||||
<string name="notes">Catatan</string>
|
||||
<string name="replies">Balasan</string>
|
||||
<string name="follows">Mengikuti</string>
|
||||
<string name="reports">Laporan</string>
|
||||
<string name="more_options">Lebih banyak pilihan</string>
|
||||
<string name="relays">" Relai"</string>
|
||||
<string name="website">Situs Web</string>
|
||||
<string name="lightning_address">Alamat Lightning</string>
|
||||
<string name="copies_the_nsec_id_your_password_to_the_clipboard_for_backup">Salin Nsec ID (kata sandi anda) ke papan klip sebagai cadangan</string>
|
||||
<string name="copy_private_key_to_the_clipboard">Salin Kunci Privat ke papan klip</string>
|
||||
<string name="copies_the_public_key_to_the_clipboard_for_sharing">Salin Kunci Publik ke papan klip untuk dibagikan</string>
|
||||
<string name="copy_public_key_npub_to_the_clipboard">Salin Kunci Publik (NPub) ke papan klip</string>
|
||||
<string name="send_a_direct_message">Kirim Pesan Langsung</string>
|
||||
<string name="edits_the_user_s_metadata">Ubah Metadata Pengguna</string>
|
||||
<string name="follow">Ikuti</string>
|
||||
<string name="follow_back">Ikuti balik</string>
|
||||
<string name="unblock">Batalkan blokir</string>
|
||||
<string name="copy_user_id">Salin ID Pengguna</string>
|
||||
<string name="unblock_user">Batalkan blokir pengguna</string>
|
||||
<string name="npub_hex_username">npub, nama pengguna, teks</string>
|
||||
<string name="clear">Bersihkan</string>
|
||||
<string name="app_logo">Logo Aplikasi</string>
|
||||
<string name="nsec_npub_hex_private_key">nsec.. or npub..</string>
|
||||
<string name="show_password">Tampilkan Kata Sandi</string>
|
||||
<string name="hide_password">Sembunyikan Kata Sandi</string>
|
||||
<string name="invalid_key">Kunci tidak sah</string>
|
||||
<string name="i_accept_the">Saya menerima</string>
|
||||
<string name="terms_of_use">syarat penggunaan</string>
|
||||
<string name="acceptance_of_terms_is_required">Penerimaan persyaratan diperlukan</string>
|
||||
<string name="key_is_required">Kunci diperlukan</string>
|
||||
<string name="login">Masuk</string>
|
||||
<string name="generate_a_new_key">Buat kunci baru</string>
|
||||
<string name="loading_feed">Memuat data umpan</string>
|
||||
<string name="error_loading_replies">"Gagal memuat balasan: "</string>
|
||||
<string name="try_again">Coba lagi</string>
|
||||
<string name="feed_is_empty">Data umpan kosong.</string>
|
||||
<string name="refresh">Perbarui</string>
|
||||
<string name="created">dibuat</string>
|
||||
<string name="with_description_of">"dengan deskripsi "</string>
|
||||
<string name="and_picture">dan gambar</string>
|
||||
<string name="changed_chat_name_to">mengubah nama percakapan menjadi</string>
|
||||
<string name="description_to">deskripsi untuk</string>
|
||||
<string name="and_picture_to">dan gambar untuk</string>
|
||||
<string name="leave">Tinggalkan</string>
|
||||
<string name="unfollow">Berhenti mengikuti</string>
|
||||
<string name="channel_created">Kanal dibuat</string>
|
||||
<string name="channel_information_changed_to">Informasi kanal diubah menjadi</string>
|
||||
<string name="public_chat">Percakapan Publik</string>
|
||||
<string name="posts_received">kiriman diterima</string>
|
||||
<string name="remove">Hapus</string>
|
||||
<string name="translations_auto">Otomatis</string>
|
||||
<string name="translations_translated_from">diterjemahkan dari</string>
|
||||
<string name="translations_to">ke</string>
|
||||
<string name="translations_show_in_lang_first">Tampilkan dalam %1$s (prioritas)</string>
|
||||
<string name="translations_always_translate_to_lang">Selalu terjemahkan ke %1$s</string>
|
||||
<string name="translations_never_translate_from_lang">Jangan terjemahkan dari %1$s</string>
|
||||
<string name="nip_05">Alamat Nostr</string>
|
||||
<string name="never">tidak pernah</string>
|
||||
<string name="now">sekarang</string>
|
||||
<string name="h">jam</string>
|
||||
<string name="m">menit</string>
|
||||
<string name="d">hari</string>
|
||||
<string name="nudity">Ketelanjangan</string>
|
||||
<string name="profanity_hateful_speech">Ujaran kotor/kebencian</string>
|
||||
<string name="report_hateful_speech">Laporkan ujaran kebencian</string>
|
||||
<string name="report_nudity_porn">Laporkan Ketelanjangan / Pornografi</string>
|
||||
<string name="others">lainnya</string>
|
||||
<string name="mark_all_known_as_read">Tandai semua yg dikenal telah dibaca</string>
|
||||
<string name="mark_all_new_as_read">Tandai pesan baru telah dibaca</string>
|
||||
<string name="mark_all_as_read">Tandai semua telah dibaca</string>
|
||||
<string name="backup_keys">Cadangkan Kunci</string>
|
||||
<string name="account_backup_tips_md" tools:ignore="Typos">"\n ## Tip Pencadangan dan Keamanan Utama\n \n\nAkun Anda diamankan dengan kunci rahasia. Kuncinya adalah string acak panjang yang dimulai dengan **nsec1**.. Siapa pun yang memiliki akses ke kunci rahasia Anda dapat mempublikasikan konten menggunakan identitas Anda.\n \n\n- **Jangan** letakkan kunci rahasia Anda di situs web atau perangkat lunak apa pun yang tidak Anda percayai.\n \n- Pengembang Aplikasi Amethyst **tidak akan pernah** meminta kunci rahasia Anda.\n \n- **Pastikan** simpan cadangan aman kunci rahasia Anda untuk pemulihan akun. Kami merekomendasikan menggunakan aplikasi khusus pengelola kata sandi.\n "</string>
|
||||
<string name="secret_key_copied_to_clipboard">Kunci rahasia (nsec) disalin ke clipboard</string>
|
||||
<string name="copy_my_secret_key">Salin kunci rahasia saya</string>
|
||||
<string name="biometric_authentication_failed">Autentikasi gagal</string>
|
||||
<string name="biometric_error">Kesalahan</string>
|
||||
<string name="badge_created_by">Dibuat oleh %1$s</string>
|
||||
<string name="badge_award_image_for">Gambar penghargaan lencana untuk %1$s</string>
|
||||
<string name="new_badge_award_notif">Anda Menerima Penghargaan Lencana baru</string>
|
||||
<string name="award_granted_to">Penghargaan lencana diberikan kepada</string>
|
||||
<string name="copied_note_text_to_clipboard">Teks catatan disalin ke papan klip</string>
|
||||
<string name="copied_user_id_to_clipboard" tools:ignore="Typos">\@npub Penulis disalin ke papan klip</string>
|
||||
<string name="copied_note_id_to_clipboard" tools:ignore="Typos">Note ID (@note1) disalin ke papan klip</string>
|
||||
<string name="select_text_dialog_top">Pilih Teks</string>
|
||||
<string name="private_conversation_notification"><Gagal mendeskripsikan pesan pribadi>\n\nAnda dikutip dalam percakapan pribadi/terenkripsi antara %1$s dan %2$s.</string>
|
||||
<string name="account_switch_add_account_dialog_title">Tambah Akun Baru</string>
|
||||
<string name="drawer_accounts">Akun</string>
|
||||
<string name="account_switch_select_account">Pilih Akun</string>
|
||||
<string name="account_switch_add_account_btn">Tambah Akun Baru</string>
|
||||
<string name="account_switch_active_account">Akun Aktif</string>
|
||||
<string name="account_switch_has_private_key">Memiliki kunci pribadi</string>
|
||||
<string name="account_switch_pubkey_only">Baca saja, tidak ada kunci pribadi</string>
|
||||
<string name="back">Kembali</string>
|
||||
<string name="quick_action_select">Pilih</string>
|
||||
<string name="quick_action_share_browser_link">Bagikan Tauatan ke Peramban</string>
|
||||
<string name="quick_action_share">Bagikan</string>
|
||||
<string name="quick_action_copy_user_id">ID Penulis</string>
|
||||
<string name="quick_action_copy_note_id">ID Catatan</string>
|
||||
<string name="quick_action_copy_text">Salin Teks</string>
|
||||
<string name="quick_action_delete">Hapus</string>
|
||||
<string name="quick_action_unfollow">Berhenti mengikuti</string>
|
||||
<string name="quick_action_follow">Ikuti</string>
|
||||
<string name="quick_action_request_deletion_alert_title">Meminta Penghapusan</string>
|
||||
<string name="quick_action_request_deletion_alert_body">Amethyst akan meminta agar catatan Anda dihapus dari relai yang saat ini Anda sambungkan. Tidak ada jaminan bahwa catatan Anda akan dihapus secara permanen dari relai tersebut, atau dari relai lain tempat catatan itu disimpan.</string>
|
||||
<string name="quick_action_block_dialog_btn">Blokir</string>
|
||||
<string name="quick_action_delete_dialog_btn">Hapus</string>
|
||||
<string name="quick_action_block">Blokir</string>
|
||||
<string name="quick_action_report">Laporkan</string>
|
||||
<string name="quick_action_delete_button">Hapus</string>
|
||||
<string name="quick_action_dont_show_again_button">Jangan tampilkan lagi</string>
|
||||
<string name="report_dialog_spam">Spam atau penipuan</string>
|
||||
<string name="report_dialog_profanity">Perilaku tidak senonoh atau penuh kebencian</string>
|
||||
<string name="report_dialog_impersonation">Peniruan identitas yang berbahaya</string>
|
||||
<string name="report_dialog_nudity">Konten ketelanjangan atau grafis</string>
|
||||
<string name="report_dialog_illegal">Perilaku Ilegal</string>
|
||||
<string name="report_dialog_blocking_a_user">Memblokir pengguna akan menyembunyikan konten mereka di aplikasi Anda. Catatan Anda masih dapat dilihat oleh publik, termasuk oleh orang yang Anda blokir. Pengguna yang diblokir terdaftar di layar Filter Keamanan.</string>
|
||||
<string name="report_dialog_block_hide_user_btn"><![CDATA[Blokir & Sembuniykan Pengguna]]></string>
|
||||
<string name="report_dialog_report_btn">Laporkan Penyalahgunaan</string>
|
||||
<string name="report_dialog_reminder_public">Semua laporan yang diposting akan terlihat oleh publik.</string>
|
||||
<string name="report_dialog_additional_reason_placeholder">Secara opsional, berikan konteks tambahan tentang laporan Anda…</string>
|
||||
<string name="report_dialog_additional_reason_label">Konteks Tambahan</string>
|
||||
<string name="report_dialog_select_reason_label">Alasan</string>
|
||||
<string name="report_dialog_select_reason_placeholder">Pilih alasan…</string>
|
||||
<string name="report_dialog_post_report_btn">Kirim Laporan</string>
|
||||
<string name="report_dialog_title">Blokir dan Laporkan</string>
|
||||
<string name="block_only">Blokir</string>
|
||||
|
||||
<string name="bookmarks">Penanda</string>
|
||||
<string name="private_bookmarks">Penanda Pribadi</string>
|
||||
<string name="public_bookmarks">Penanda Publik</string>
|
||||
<string name="add_to_private_bookmarks">Tambahkan Penanda Pribadi</string>
|
||||
<string name="add_to_public_bookmarks">Tambahkan Penanda Publik</string>
|
||||
<string name="remove_from_private_bookmarks">Hapus dari Penanda Pribadi</string>
|
||||
<string name="remove_from_public_bookmarks">Hapus dari Penanda Publik</string>
|
||||
|
||||
<string name="wallet_connect_service">Layanan Wallet Connect</string>
|
||||
<string name="wallet_connect_service_explainer">Mengijinkan Kunci Rahasia Nostr untuk membayar zaps tanpa meninggalkan aplikasi. Jaga kunci tetap aman dan gunakan relai pribadi jika memungkinkan</string>
|
||||
<string name="wallet_connect_service_pubkey">Kunci Publik Wallet Connect</string>
|
||||
<string name="wallet_connect_service_relay">Relai Wallet Connect</string>
|
||||
<string name="wallet_connect_service_secret">Kunci Rahasia Wallet Connect</string>
|
||||
<string name="wallet_connect_service_show_secret">Tampilkan kunci rahasia</string>
|
||||
<string name="wallet_connect_service_secret_placeholder">nsec / hex (kunci pribadi)</string>
|
||||
|
||||
<string name="pledge_amount_in_sats">Jumlah Dijanjikan dalam Sats</string>
|
||||
<string name="post_poll">Kirim Pemungutan Suara</string>
|
||||
<string name="poll_heading_required">Bidang yang wajib diisi:</string>
|
||||
<string name="poll_zap_recipients">Penerima Zap</string>
|
||||
<string name="poll_primary_description">Deskripsi Utama Pemungutan Suara…</string>
|
||||
<string name="poll_option_index">Pilihan %s</string>
|
||||
<string name="poll_option_description">Deskripsi pilihan pemungutan suara</string>
|
||||
<string name="poll_heading_optional">Bidang pilihan (tidak wajib):</string>
|
||||
<string name="poll_zap_value_min">Zap terendah</string>
|
||||
<string name="poll_zap_value_max">Zap tertinggi</string>
|
||||
<string name="poll_consensus_threshold">Konsensus</string>
|
||||
<string name="poll_consensus_threshold_percent">(0–100)%</string>
|
||||
<string name="poll_closing_time">Berakhir pada</string>
|
||||
<string name="poll_closing_time_days">hari</string>
|
||||
<string name="poll_is_closed">Pemungutan suara ditutup untuk voting baru</string>
|
||||
<string name="poll_zap_amount">Jumlah Zap</string>
|
||||
<string name="one_vote_per_user_on_atomic_votes">Hanya satu suara per pengguna yang diperbolehkan pada jenis pemungutan suara ini</string>
|
||||
|
||||
<string name="looking_for_event">Mencari data event %1$s</string>
|
||||
|
||||
<string name="custom_zaps_add_a_message">Tambah pesan publik</string>
|
||||
<string name="custom_zaps_add_a_message_private">Tambah pesan pribadi</string>
|
||||
<string name="custom_zaps_add_a_message_nonzap">Tambah pesan faktur tagihan</string>
|
||||
|
||||
<string name="custom_zaps_add_a_message_example">Terima kasih atas semua pekerjaan Anda!</string>
|
||||
|
||||
<string name="lightning_create_and_add_invoice">Buat dan Tambah</string>
|
||||
<string name="poll_author_no_vote">Pembuat Pemungutan Suara tidak dapat memberikan suara dalam pemungutan suara sendiri.</string>
|
||||
|
||||
<string name="hash_verification_passed">Konten ini sama sejak kiriman tersebut dibuat</string>
|
||||
<string name="hash_verification_failed">Konten ini telah berubah. Penulis mungkin tidak melihat atau menyetujui perubahan tersebut</string>
|
||||
|
||||
<string name="content_description_add_image">Tambah Gambar</string>
|
||||
<string name="content_description_add_video">Tambah Video</string>
|
||||
<string name="content_description_add_document">Tambah Dokumen</string>
|
||||
|
||||
<string name="add_content">Tambahkan ke Pesan</string>
|
||||
<string name="content_description">Deskripsi Konten</string>
|
||||
<string name="content_description_example">Perahu berwarna biru di pantai berpasir putih saat matahari terbenam</string>
|
||||
|
||||
<string name="zap_type">Tipe Zap</string>
|
||||
<string name="zap_type_explainer">Tipe Zap untuk semua pilihan</string>
|
||||
|
||||
<string name="zap_type_public">Publik</string>
|
||||
<string name="zap_type_public_explainer">Semua orang dapat melihat transaksi dan pesannya</string>
|
||||
|
||||
<string name="zap_type_private">Pribadi</string>
|
||||
<string name="zap_type_private_explainer">Pengirim dan Penerima dapat saling melihat dan membaca pesan</string>
|
||||
|
||||
<string name="zap_type_anonymous">Anonim</string>
|
||||
<string name="zap_type_anonymous_explainer">Penerima dan semua orang tidak dapat mengetahui siapa pengirim pembayaran</string>
|
||||
|
||||
<string name="zap_type_nonzap">Bukan Zap</string>
|
||||
<string name="zap_type_nonzap_explainer">Tidak ada jejak di Nostr, hanya di Lightning Network</string>
|
||||
|
||||
|
||||
<string name="file_server">Server Berkas</string>
|
||||
<string name="zap_forward_lnAddress">Alamat LN atau @Pengguna</string>
|
||||
|
||||
<string name="upload_server_imgur">imgur.com - terpercaya</string>
|
||||
<string name="upload_server_imgur_explainer">Imgur dapat memodifikasi berkas</string>
|
||||
|
||||
<string name="upload_server_nostrimg">nostrimg.com - terpercaya</string>
|
||||
<string name="upload_server_nostrimg_explainer">NostrImg dapat memodifikasi berkas</string>
|
||||
|
||||
<string name="upload_server_nostrbuild">nostr.build - terpercaya</string>
|
||||
<string name="upload_server_nostrbuild_explainer">Nostr.build dapat memodifikasi berkas</string>
|
||||
|
||||
<string name="upload_server_nostrfilesdev">nostrfiles.dev - terpercaya</string>
|
||||
<string name="upload_server_nostrfilesdev_explainer">Nostrfiles.dev dapat memodifikasi berkas</string>
|
||||
|
||||
<string name="upload_server_nostrcheckme">nostrcheck.me - terpercaya</string>
|
||||
<string name="upload_server_nostrcheckme_explainer">nostrcheck.me dapat memodifikasi berkas</string>
|
||||
|
||||
|
||||
<string name="upload_server_imgur_nip94">Imgur yg dapat diverifikasi (NIP-94)</string>
|
||||
<string name="upload_server_imgur_nip94_explainer">Periksa jika Imgur mengubah berkas. NIP baru: aplikasi Nostr lain mungkin belum mendukung</string>
|
||||
|
||||
<string name="upload_server_nostrimg_nip94">NostrImg yg dapat diverifikasi (NIP-94)</string>
|
||||
<string name="upload_server_nostrimg_nip94_explainer">Periksa jika NostrImg mengubah berkas. NIP baru: aplikasi Nostr lain mungkin belum mendukung</string>
|
||||
|
||||
<string name="upload_server_nostrbuild_nip94">Nostr.build yg dapat diverifikasi (NIP-94)</string>
|
||||
<string name="upload_server_nostrbuild_nip94_explainer">Periksa jika Nostr.build mengubah berkas. NIP baru: aplikasi Nostr lain mungkin belum mendukung</string>
|
||||
|
||||
<string name="upload_server_nostrfilesdev_nip94">Nostrfiles.dev yg dapat diverifikasi (NIP-94)</string>
|
||||
<string name="upload_server_nostrfilesdev_nip94_explainer">Periksa jika Nostrfiles.dev mengubah berkas. NIP baru: aplikasi Nostr lain mungkin belum mendukung</string>
|
||||
|
||||
<string name="upload_server_nostrcheckme_nip94">Nostrcheck.me yg dapat diverifikasi (NIP-94)</string>
|
||||
<string name="upload_server_nostrcheckme_nip94_explainer">Periksa jika Nostrcheck.me mengubah berkas. NIP baru: aplikasi Nostr lain mungkin belum mendukung</string>
|
||||
|
||||
<string name="upload_server_relays_nip95">Relai anda (NIP-95)</string>
|
||||
<string name="upload_server_relays_nip95_explainer">Berkas disimpan di relai anda. NIP baru: periksa apakah relai mendukung fitur</string>
|
||||
|
||||
<string name="connect_via_tor_short">Pengaturan Tor/Orbot</string>
|
||||
<string name="connect_via_tor">Hubungkan melalui pengaturan Orbot Anda</string>
|
||||
|
||||
<string name="do_you_really_want_to_disable_tor_title">Putuskan sambungan dari Orbot/Tor Anda?</string>
|
||||
<string name="do_you_really_want_to_disable_tor_text">Data Anda akan segera ditransfer di jaringan reguler (bukan TOR)</string>
|
||||
<string name="yes">Ya</string>
|
||||
<string name="no">Tidak</string>
|
||||
|
||||
|
||||
<string name="follow_list_selection">Daftar yang Diikuti</string>
|
||||
<string name="follow_list_kind3follows">Semua yang diikuti</string>
|
||||
<string name="follow_list_global">Global</string>
|
||||
<string name="connect_through_your_orbot_setup_markdown">"\n ## Terhubung melalui Tor menggunakan Orbot\n \n\n1. Pasang [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)\n \n2. Jalankan Orbot\n \n3. Di dalam Orbot, periksa nomor port Socks. Secara bawaan menggunakan nomor 9050\n \n4. Jika diperlukan, ubah nomor port Orbot\n \n5. Atur nomor port Socks pada layar ini\n \n6. Tekan tombol Aktifkan untuk menggunakan Orbot sebagai proxy\n "</string>
|
||||
<string name="orbot_socks_port">Port Orbot Socks</string>
|
||||
<string name="invalid_port_number">Nomor port tidak sah</string>
|
||||
<string name="use_orbot">Gunakan Orbot</string>
|
||||
<string name="disconnect_from_your_orbot_setup">Putuskan Tor/Orbot</string>
|
||||
|
||||
<string name="app_notification_dms_channel_name">Pesan Pribadi</string>
|
||||
<string name="app_notification_dms_channel_description">Memberi tahu Anda ketika pesan pribadi tiba</string>
|
||||
|
||||
<string name="app_notification_zaps_channel_name">Zaps diterima</string>
|
||||
<string name="app_notification_zaps_channel_description">Memberi tahu Anda ketika seseorang mengirimkan anda zap</string>
|
||||
<string name="app_notification_zaps_channel_message">%1$s sats</string>
|
||||
<string name="app_notification_zaps_channel_message_from">Dari %1$s</string>
|
||||
<string name="app_notification_zaps_channel_message_for">untuk %1$s</string>
|
||||
|
||||
<string name="reply_notify">"Beritahu: "</string>
|
||||
|
||||
<string name="channel_list_join_conversation">Gabung Percakapan</string>
|
||||
<string name="channel_list_user_or_group_id">ID Pengguna atau Grup</string>
|
||||
<string name="channel_list_user_or_group_id_demo">npub, nevent atau kode heksa</string>
|
||||
<string name="channel_list_create_channel">Buat</string>
|
||||
<string name="channel_list_join_channel">Gabung</string>
|
||||
|
||||
<string name="today">Hari ini</string>
|
||||
|
||||
<string name="content_warning">Peringatan konten</string>
|
||||
<string name="content_warning_explanation">Postingan ini berisi konten sensitif yang mungkin dianggap menyinggung atau mengganggu oleh sebagian orang</string>
|
||||
<string name="content_warning_hide_all_sensitive_content">Selalu sembunyikan konten sensitif</string>
|
||||
<string name="content_warning_show_all_sensitive_content">Selalu tampilkan konten sensitif</string>
|
||||
<string name="content_warning_see_warnings">Selalu tampilkan peringatan konten</string>
|
||||
|
||||
<string name="recommended_apps">"Rekomendasi: "</string>
|
||||
<string name="filter_spam_from_strangers">Saring spam dari orang asing (tak diikuti)</string>
|
||||
<string name="warn_when_posts_have_reports_from_your_follows">Peringatkan ketika kiriman memiliki laporan dari pengikut Anda</string>
|
||||
|
||||
<string name="new_reaction_symbol">Simbol Reaksi Baru</string>
|
||||
<string name="no_reaction_type_setup_long_press_to_change">Tidak ada jenis reaksi yang dipilih. Tekan dan tahan untuk mengubah</string>
|
||||
|
||||
<string name="zapraiser">Galang Dana Zap</string>
|
||||
<string name="zapraiser_explainer">Menambahkan jumlah target sats yang ingin dikumpulkan untuk kiriman ini. Klien yang mendukung mungkin menunjukkan hal ini sebagai indikator kemajuan dalam memberi insentif pada donasi</string>
|
||||
<string name="zapraiser_target_amount_in_sats">Jumlah Target dalam Sats</string>
|
||||
|
||||
<string name="sats_to_complete">Galang Dana Zap mencapai %1$s. %2$s sats untuk memenuhi target</string>
|
||||
<string name="read_from_relay">Baca dari Relai</string>
|
||||
<string name="write_to_relay">Tulis ke Relai</string>
|
||||
<string name="an_error_occurred_trying_to_get_relay_information">Terjadi kesalahan saat mencoba mendapatkan informasi relai %1$s</string>
|
||||
<string name="owner">Pemilik</string>
|
||||
<string name="version">Versi</string>
|
||||
<string name="software">Perangkat Lunak</string>
|
||||
<string name="contact">Kontak</string>
|
||||
<string name="supports">NIP yg didukung</string>
|
||||
<string name="admission_fees">Biaya Pendaftaran</string>
|
||||
<string name="payments_url">Alamat Pembayaran</string>
|
||||
<string name="limitations">Batasan</string>
|
||||
<string name="countries">Negara</string>
|
||||
<string name="languages">Bahasa</string>
|
||||
<string name="tags">Tags</string>
|
||||
<string name="posting_policy">Kebijakan kiriman</string>
|
||||
<string name="message_length">Panjang pesan</string>
|
||||
<string name="subscriptions">Langganan</string>
|
||||
<string name="filters">Penyaringan</string>
|
||||
<string name="subscription_id_length">Panjang ID Subscription</string>
|
||||
<string name="minimum_prefix">Awalan minimal</string>
|
||||
<string name="maximum_event_tags">Jumlah Tags maksimum</string>
|
||||
<string name="content_length">Panjang konten</string>
|
||||
<string name="minimum_pow">PoW terendah</string>
|
||||
<string name="auth">Autentikasi</string>
|
||||
<string name="payment">Pembayaran</string>
|
||||
<string name="cashu">Token Cashu</string>
|
||||
<string name="cashu_redeem">Tukarkan</string>
|
||||
<string name="no_lightning_address_set">Tidak ada alamat Lightning yang diatur</string>
|
||||
<string name="copied_token_to_clipboard">Token disalin ke papan klip</string>
|
||||
|
||||
<string name="live_stream_live_tag">DARING (ON)</string>
|
||||
<string name="live_stream_offline_tag">LURING (OFF)</string>
|
||||
<string name="live_stream_ended_tag">BERAKHIR</string>
|
||||
<string name="live_stream_planned_tag">DIJADWALKAN</string>
|
||||
|
||||
<string name="live_stream_is_offline">Siaran langsung sedang luring</string>
|
||||
<string name="live_stream_has_ended">Siaran langsung berakhir</string>
|
||||
<string name="are_you_sure_you_want_to_log_out">Keluar akan menghapus semua informasi lokal Anda. Pastikan kunci pribadi Anda dicadangkan untuk menghindari kehilangan akun Anda. Apakah Anda ingin melanjutkan?</string>
|
||||
<string name="followed_tags">Tags yg diikuti</string>
|
||||
|
||||
<string name="relay_setup">Relai</string>
|
||||
|
||||
<string name="discover_live">Siaran Langsung</string>
|
||||
<string name="discover_community">Komunitas</string>
|
||||
<string name="discover_chat">Percakapan</string>
|
||||
<string name="community_approved_posts">Kiriman yg disetujui</string>
|
||||
|
||||
<string name="groups_no_descriptor">Grup ini tidak memiliki deskripsi atau aturan. Bicaralah dengan pemiliknya untuk menambahkannya</string>
|
||||
<string name="community_no_descriptor">Komunitas ini tidak memiliki deskripsi. Bicaralah dengan pemiliknya untuk menambahkannya</string>
|
||||
|
||||
<string name="add_sensitive_content_label">Konten Sensitif</string>
|
||||
<string name="add_sensitive_content_description">Menambahkan peringatan konten sensitif sebelum menampilkan konten ini</string>
|
||||
<string name="settings">Pengaturan</string>
|
||||
<string name="connectivity_type_always">Selalu</string>
|
||||
<string name="connectivity_type_wifi_only">Hanya Wifi</string>
|
||||
<string name="connectivity_type_never">Tidak Pernah</string>
|
||||
|
||||
<string name="system">Sistem</string>
|
||||
<string name="light">Terang</string>
|
||||
<string name="dark">Gelap</string>
|
||||
<string name="application_preferences">Pengaturan Aplikasi</string>
|
||||
<string name="language">Bahasa</string>
|
||||
<string name="theme">Tema</string>
|
||||
<string name="automatically_load_images_gifs">Pratinjau Gambar</string>
|
||||
<string name="automatically_play_videos">Pemutaran Video</string>
|
||||
<string name="automatically_show_url_preview">Pratinjau URL</string>
|
||||
<string name="load_image">Muat Gambar</string>
|
||||
|
||||
<string name="spamming_users">Pengirim Spam</string>
|
||||
|
||||
<string name="muted_button">Diredam. Klik untuk bersuara</string>
|
||||
<string name="mute_button">Bersuara. Kilik untuk meredam</string>
|
||||
<string name="search_button">Cari catatan lokal dan jarak jauh</string>
|
||||
|
||||
<string name="nip05_verified">Alamat Nostr diverifikasi</string>
|
||||
<string name="nip05_failed">Alamat Nostr gagal diverifikasi</string>
|
||||
<string name="nip05_checking">Memeriksa Alamat Nostr</string>
|
||||
<string name="select_deselect_all">Pilih / Hapus Semua</string>
|
||||
<string name="default_relays">Bawaan</string>
|
||||
<string name="select_a_relay_to_continue">Pilih Relai untuk melanjutkan</string>
|
||||
|
||||
<string name="zap_forward_title">Teruskan Zaps ke:</string>
|
||||
<string name="zap_forward_explainer">Klien yg mendukung akan meneruskan zaps ke Alamat LN atau Profil Pengguna di bawah ini, bukan ke alamat LN Anda</string>
|
||||
|
||||
<string name="geohash_title">Paparkan Lokasi sebagai</string>
|
||||
<string name="geohash_explainer">Menambahkan Geohash lokasi Anda ke postingan. Publik akan mengetahui bahwa Anda berada dalam jarak 5 km (3 mil) dari lokasi saat ini</string>
|
||||
|
||||
<string name="add_sensitive_content_explainer">Menambahkan peringatan konten sensitif sebelum menampilkan konten Anda. Ini ideal untuk konten NSFW apa pun atau konten yang mungkin dianggap menyinggung atau mengganggu oleh sebagian orang</string>
|
||||
|
||||
<string name="new_feature_nip24_might_not_be_available_title">Fitur Baru</string>
|
||||
<string name="new_feature_nip24_might_not_be_available_description">Mengaktifkan mode ini mengharuskan Amethyst mengirim pesan NIP-24 (GiftWrapped, Sealed Direct, dan Group Messages). NIP-24 masih baru dan sebagian besar klien belum menerapkannya. Pastikan penerima menggunakan klien yang kompatibel.</string>
|
||||
<string name="new_feature_nip24_activate">Aktifkan</string>
|
||||
|
||||
<string name="messages_create_public_chat">Publik</string>
|
||||
<string name="messages_new_message">Pribadi</string>
|
||||
<string name="messages_new_message_to">Ke</string>
|
||||
<string name="messages_new_message_subject">Subjek</string>
|
||||
<string name="messages_new_message_subject_caption">Topik percakapan</string>
|
||||
<string name="messages_new_message_to_caption">\@Pengguna1, @Pengguna2, @Pengguna3</string>
|
||||
|
||||
<string name="messages_group_descriptor">Anggota grup ini</string>
|
||||
<string name="messages_new_subject_message">Penjelasan kepada anggota</string>
|
||||
<string name="messages_new_subject_message_placeholder">Mengubah nama untuk tujuan baru.</string>
|
||||
|
||||
<string name="language_description">Untuk Antarmuka Aplikasi</string>
|
||||
<string name="theme_description">Tema Gelap, Terang, atau Sistem</string>
|
||||
<string name="automatically_load_images_gifs_description">Memuat gambar dan GIF secara otomatis</string>
|
||||
<string name="automatically_play_videos_description">Memutar video dan GIF secara otomatis</string>
|
||||
<string name="automatically_show_url_preview_description">Tampilkan pratinjau URL</string>
|
||||
<string name="load_image_description">Kapan memuat gambar</string>
|
||||
|
||||
<string name="copy_url_to_clipboard">Salin URL ke papan klip</string>
|
||||
<string name="copy_the_note_id_to_the_clipboard">Salin ID Catatan ke papan klip</string>
|
||||
|
||||
<string name="created_at">Dibuat pada</string>
|
||||
<string name="rules">Aturan</string>
|
||||
|
||||
<string name="status_update">Perbaharui statusmu</string>
|
||||
|
||||
<string name="lightning_wallets_not_found">Kesalahan menguraikan pesan kesalahan</string>
|
||||
<string name="poll_zap_value_min_max_explainer">Suara ditimbang berdasarkan jumlah zap. Anda dapat menetapkan jumlah minimum untuk menghindari pembuat spam dan jumlah maksimum untuk menghindari pengirim zap besar mengambil alih pemungutan suara. Gunakan jumlah yang sama di kedua kolom untuk memastikan setiap suara bernilai sama. Biarkan kosong untuk menerima jumlah berapa pun.</string>
|
||||
|
||||
<string name="error_dialog_zap_error">Tidak dapat mengirim zap</string>
|
||||
<string name="error_dialog_talk_to_user">Kirim Pesan ke Pengguna</string>
|
||||
<string name="error_dialog_button_ok">Ok</string>
|
||||
</resources>
|
@ -21,6 +21,7 @@
|
||||
<string name="copy_text">Copia testo</string>
|
||||
<string name="copy_user_pubkey">Copia ID autore</string>
|
||||
<string name="copy_note_id">Copia ID nota</string>
|
||||
<string name="broadcast">Trasmissione</string>
|
||||
<string name="request_deletion">Richiedi cancellazione</string>
|
||||
<string name="block_report">Blocca / Segnala</string>
|
||||
<string name="block_hide_user"><![CDATA[Blocca e Nascondi Utente]]></string>
|
||||
@ -39,4 +40,101 @@
|
||||
<string name="view_count">Visualizzazioni</string>
|
||||
<string name="boost">Boost</string>
|
||||
<string name="boosted">ricondiviso</string>
|
||||
<string name="quote">Cita</string>
|
||||
<string name="new_amount_in_sats">Nuovo importo in Sats</string>
|
||||
<string name="add">Aggiungi</string>
|
||||
<string name="replying_to">"rispondendo a"</string>
|
||||
<string name="and">" e "</string>
|
||||
<string name="in_channel">"nel canale "</string>
|
||||
<string name="profile_banner">Immagine copertina</string>
|
||||
<string name="payment_successful">Pagamento effettuato</string>
|
||||
<string name="error_parsing_error_message">Errore durante l\'interpretazione del messaggio d\'errore</string>
|
||||
<string name="following">" Seguiti"</string>
|
||||
<string name="followers">" Seguaci"</string>
|
||||
<string name="profile">Profilo</string>
|
||||
<string name="security_filters">Filtri di sicurezza</string>
|
||||
<string name="log_out">Esci</string>
|
||||
<string name="show_more">Mostra altro</string>
|
||||
<string name="lightning_invoice">Fattura Lightning</string>
|
||||
<string name="pay">Paga</string>
|
||||
<string name="lightning_tips">Mance Lightning</string>
|
||||
<string name="note_to_receiver">Nota per il Ricevente</string>
|
||||
<string name="thank_you_so_much">Grazie mille!</string>
|
||||
<string name="amount_in_sats">Importo in Sats</string>
|
||||
<string name="send_sats">Invia Sats</string>
|
||||
<string name="error_parsing_preview_for">"Errore nella creazione dell'anteprima di %1$s : %2$s"</string>
|
||||
<string name="preview_card_image_for">"Anteprima immagine per %1$s"</string>
|
||||
<string name="new_channel">Nuovo canale</string>
|
||||
<string name="channel_name">Nome canale</string>
|
||||
<string name="my_awesome_group">Il mio fantastico gruppo</string>
|
||||
<string name="picture_url">Url foto</string>
|
||||
<string name="description">Descrizione</string>
|
||||
<string name="about_us">"Su di noi... "</string>
|
||||
<string name="what_s_on_your_mind">A cosa stai pensando?</string>
|
||||
<string name="post">Post</string>
|
||||
<string name="save">Salva</string>
|
||||
<string name="create">Crea</string>
|
||||
<string name="cancel">Cancella</string>
|
||||
<string name="failed_to_upload_the_image">Impossibile caricare l\'immagine</string>
|
||||
<string name="relay_address">Indirizzo Relay</string>
|
||||
<string name="posts">Posts</string>
|
||||
<string name="bytes">Bytes</string>
|
||||
<string name="errors">Errori</string>
|
||||
<string name="home_feed">Home Feed</string>
|
||||
<string name="private_message_feed">Lista Messaggi Privati</string>
|
||||
<string name="public_chat_feed">Lista Chat Pubbliche</string>
|
||||
<string name="global_feed">Feed Globale</string>
|
||||
<string name="search_feed">Risultati Ricerca</string>
|
||||
<string name="add_a_relay">Aggiungi un Relay</string>
|
||||
<string name="display_name">Nome Visualizzato</string>
|
||||
<string name="my_display_name">Il mio nome visualizzato</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="acceptance_of_terms_is_required">L\'accettazione dei termini è obbligatoria</string>
|
||||
<string name="key_is_required">La chiave è obbligatoria</string>
|
||||
<string name="login">Accesso</string>
|
||||
<string name="generate_a_new_key">Genera una nuova chiave</string>
|
||||
<string name="loading_feed">Caricamento del feed</string>
|
||||
<string name="error_loading_replies">"Errore durante il caricamento delle risposte: "</string>
|
||||
<string name="try_again">Prova di nuovo</string>
|
||||
<string name="feed_is_empty">Il feed è vuoto.</string>
|
||||
<string name="refresh">Aggiorna</string>
|
||||
<string name="created">creato</string>
|
||||
<string name="with_description_of">con la descrizione di</string>
|
||||
<string name="and_picture">e l\'immagine</string>
|
||||
<string name="changed_chat_name_to">modificato il nome della chat in</string>
|
||||
<string name="description_to">descrizione per</string>
|
||||
<string name="and_picture_to">e immagine per</string>
|
||||
<string name="leave">Esci</string>
|
||||
<string name="unfollow">Non seguire più</string>
|
||||
<string name="channel_created">Canale creato</string>
|
||||
<string name="channel_information_changed_to">"Informazioni del canale modificate in"</string>
|
||||
<string name="public_chat">Chat Pubblica</string>
|
||||
<string name="posts_received">post ricevuti</string>
|
||||
<string name="remove">Cancella</string>
|
||||
<string name="translations_auto">Auto</string>
|
||||
<string name="translations_translated_from">tradotto da</string>
|
||||
<string name="translations_to">a</string>
|
||||
<string name="translations_always_translate_to_lang">Traduci sempre in %1$s</string>
|
||||
<string name="translations_never_translate_from_lang">Non tradurre mai da %1$s</string>
|
||||
<string name="nip_05">Indirizzo Nostr</string>
|
||||
<string name="never">mai</string>
|
||||
<string name="now">adesso</string>
|
||||
<string name="h">h</string>
|
||||
<string name="m">m</string>
|
||||
<string name="d">d</string>
|
||||
<string name="nudity">Nuditá</string>
|
||||
<string name="profanity_hateful_speech">Volgaritá / Linguaggio forte</string>
|
||||
<string name="report_hateful_speech">Segnala linguaggio forte</string>
|
||||
<string name="report_nudity_porn">Segnala Nuditá / Pornografia</string>
|
||||
<string name="others">altri</string>
|
||||
<string name="mark_all_known_as_read">Segna tutti i conosciuti come letti</string>
|
||||
<string name="mark_all_new_as_read">Segna tutti i nuovi come letti</string>
|
||||
<string name="mark_all_as_read">Segna tutti come letti</string>
|
||||
<string name="backup_keys">Esegui backup delle chiavi</string>
|
||||
<string name="account_backup_tips_md" tools:ignore="Typos"> ## Backup delle Chiavi e Consigli di Sicurezza
|
||||
\n\nIl tuo account è reso sicuro da una chiave privata. La chiave è una lunga stringa di caratteri casuali che inizia con **nsec1**. Chiunque abbia accesso alla tua chiave privata puó pubblicare contenuti con la tua identitá.
|
||||
\n\n- Non devi **mai** inserire la tua chiave privata in un sito o software di cui non ti fidi.
|
||||
\n- Gli sviluppatori di Amethyst non chiederanno **mai** la tua chiave privata.
|
||||
\n- Mantieni **sempre** al sicuro un backup della tua chiave privata per recuperare l\'account. Ti suggeriamo di usare un password manager.
|
||||
</string>
|
||||
</resources>
|
||||
|
@ -1,2 +1,476 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools"></resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="point_to_the_qr_code">Elekeza kwa Msimbo wa QR</string>
|
||||
<string name="show_qr">Onyesha QR</string>
|
||||
<string name="profile_image">Picha ya Wasifu</string>
|
||||
<string name="scan_qr">Changanua QR</string>
|
||||
<string name="show_anyway">Onyesha Hata hivyo</string>
|
||||
<string name="post_was_flagged_as_inappropriate_by">Chapisho liliripotiwa na</string>
|
||||
<string name="post_not_found">Tukio linapakia au halipatikani kwenye orodha yako ya upeanaji</string>
|
||||
<string name="channel_image">Picha ya Kituo</string>
|
||||
<string name="referenced_event_not_found">Tukio linalorejelewa halijapatikana</string>
|
||||
<string name="could_not_decrypt_the_message">Haikuweza kusimbua ujumbe</string>
|
||||
<string name="group_picture">Picha ya Kikundi</string>
|
||||
<string name="explicit_content">Maudhui Dhahiri</string>
|
||||
<string name="spam">Barua taka</string>
|
||||
<string name="impersonation">Uigaji</string>
|
||||
<string name="illegal_behavior">Tabia Haramu</string>
|
||||
<string name="unknown">Haijulikani</string>
|
||||
<string name="relay_icon">Aikoni ya Relay</string>
|
||||
<string name="unknown_author">Mwandishi asiyejulikana</string>
|
||||
<string name="copy_text">Nakili Maandishi</string>
|
||||
<string name="copy_user_pubkey">Nakili Kitambulisho cha Mwandishi</string>
|
||||
<string name="copy_note_id">Nakili Kitambulisho cha Dokezo</string>
|
||||
<string name="broadcast">Tangaza</string>
|
||||
<string name="request_deletion">Omba Kufutwa</string>
|
||||
<string name="block_report">Zuia / Ripoti</string>
|
||||
<string name="block_hide_user"><![CDATA[Zuia na Ufiche Mtumiaji]]></string>
|
||||
<string name="report_spam_scam">Ripoti Barua Taka / Ulaghai</string>
|
||||
<string name="report_impersonation">Ripoti Uigaji</string>
|
||||
<string name="report_explicit_content">Ripoti Maudhui Dhahiri</string>
|
||||
<string name="report_illegal_behaviour">Ripoti Tabia Haramu</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_reply">Ingia kwa kutumia Ufunguo wa Faragha ili uweze kujibu</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_boost_posts">Ingia kwa kutumia ufunguo wa Faragha ili uweze kuboresha machapisho</string>
|
||||
<string name="login_with_a_private_key_to_like_posts">Ingia kwa kutumia ufunguo wa Faragha ili kupenda Machapisho</string>
|
||||
<string name="no_zap_amount_setup_long_press_to_change">Hakuna Usanidi wa Kiasi cha Zap. Bonyeza kwa Muda mrefu ili kubadilisha</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_send_zaps">Ingia kwa kutumia ufunguo wa Faragha ili uweze kutuma Zaps</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_follow">Ingia kwa kutumia Ufunguo wa Faragha ili uweze Kufuata</string>
|
||||
<string name="login_with_a_private_key_to_be_able_to_unfollow">Ingia kwa kutumia Ufunguo wa Faragha ili uweze Kuacha Kufuata</string>
|
||||
<string name="zaps">Zaps</string>
|
||||
<string name="view_count">Idadi ya maoni</string>
|
||||
<string name="boost">Kuongeza</string>
|
||||
<string name="boosted">imeimarishwa</string>
|
||||
<string name="quote">Nukuu</string>
|
||||
<string name="new_amount_in_sats">Kiasi Kipya kwa Sats</string>
|
||||
<string name="add">Ongeza</string>
|
||||
<string name="replying_to">"kujibu "</string>
|
||||
<string name="and">" na "</string>
|
||||
<string name="in_channel">"katika chaneli "</string>
|
||||
<string name="profile_banner">Bango la Wasifu</string>
|
||||
<string name="payment_successful">Malipo Yamefaulu</string>
|
||||
<string name="error_parsing_error_message">Hitilafu katika kuchanganua ujumbe wa hitilafu</string>
|
||||
<string name="following">" Kufuatia"</string>
|
||||
<string name="followers">" Wafuasi"</string>
|
||||
<string name="profile">Wasifu</string>
|
||||
<string name="security_filters">Vichujio vya Usalama</string>
|
||||
<string name="log_out">Ondoka</string>
|
||||
<string name="show_more">Onyesha Zaidi</string>
|
||||
<string name="lightning_invoice">Ankara ya umeme</string>
|
||||
<string name="pay">Lipa</string>
|
||||
<string name="lightning_tips">Vidokezo vya Umeme</string>
|
||||
<string name="note_to_receiver">Kumbuka kwa Mpokeaji</string>
|
||||
<string name="thank_you_so_much">Asante sana!</string>
|
||||
<string name="amount_in_sats">Kiasi katika Sats</string>
|
||||
<string name="send_sats">Tuma Sats</string>
|
||||
<string name="error_parsing_preview_for">"Hitilafu katika kuchanganua onyesho la kukagua %1$s : %2$s"</string>
|
||||
<string name="preview_card_image_for">"Hakiki Picha ya Kadi ya %1$s"</string>
|
||||
<string name="new_channel">Kituo Kipya</string>
|
||||
<string name="channel_name">Kituo Kipya</string>
|
||||
<string name="my_awesome_group">Kundi Langu la Ajabu</string>
|
||||
<string name="picture_url">Url ya picha</string>
|
||||
<string name="description">Maelezo</string>
|
||||
<string name="about_us">"Kuhusu sisi.. "</string>
|
||||
<string name="what_s_on_your_mind">Unafikiria nini?</string>
|
||||
<string name="post">Tuma</string>
|
||||
<string name="save">Hifadhi</string>
|
||||
<string name="create">Unda</string>
|
||||
<string name="cancel">Ghairi</string>
|
||||
<string name="failed_to_upload_the_image">Kushindwa kupakia picha</string>
|
||||
<string name="relay_address">Anwani ya Relay</string>
|
||||
<string name="posts">Machapisho</string>
|
||||
<string name="bytes">Bayti</string>
|
||||
<string name="errors">Makosa</string>
|
||||
<string name="home_feed">Malisho ya Nyumbani</string>
|
||||
<string name="private_message_feed">Malisho ya Ujumbe Binafsi</string>
|
||||
<string name="public_chat_feed">Malisho ya Mazungumzo ya Umma</string>
|
||||
<string name="global_feed">Malisho ya Kimataifa</string>
|
||||
<string name="search_feed">Malisho ya Utafutaji</string>
|
||||
<string name="add_a_relay">Ongeza Relay</string>
|
||||
<string name="display_name">Jina la Kuonyesha</string>
|
||||
<string name="my_display_name">Jina langu la kuonyesha</string>
|
||||
<string name="username">Jina la mtumiaji</string>
|
||||
<string name="my_username">Jina langu la mtumiaji</string>
|
||||
<string name="about_me">Kuhusu mimi</string>
|
||||
<string name="avatar_url">URL ya Picha ya Profaili</string>
|
||||
<string name="banner_url">URL ya Bango</string>
|
||||
<string name="website_url">URL ya Tovuti</string>
|
||||
<string name="ln_address">Anwani ya LN</string>
|
||||
<string name="ln_url_outdated">URL ya LN (imepitwa na wakati)</string>
|
||||
<string name="image_saved_to_the_gallery">Picha imesave kwenye galeria</string>
|
||||
<string name="failed_to_save_the_image">Kushindwa kuhifadhi picha</string>
|
||||
<string name="upload_image">Pakia Picha</string>
|
||||
<string name="uploading">Inapakia…</string>
|
||||
<string name="user_does_not_have_a_lightning_address_setup_to_receive_sats">Mtumiaji hana anwani ya umeme iliyoandaliwa kupokea sati</string>
|
||||
<string name="reply_here">"jibu hapa.. "</string>
|
||||
<string name="copies_the_note_id_to_the_clipboard_for_sharing">Hunakili Kitambulisho cha Dokezo kwenye ubao wa kunakili ili kushiriki katika Nostr</string>
|
||||
<string name="copy_channel_id_note_to_the_clipboard">Nakili Kitambulisho cha Kituo (Kumbuka) kwenye Ubao wa kunakili</string>
|
||||
<string name="edits_the_channel_metadata">Huhariri Metadata ya Kituo</string>
|
||||
<string name="join">Jiunge</string>
|
||||
<string name="known">Inajulikana</string>
|
||||
<string name="new_requests">Maombi Mapya</string>
|
||||
<string name="blocked_users">Watumiaji Waliozuiwa</string>
|
||||
<string name="new_threads">Nyuzi Mpya</string>
|
||||
<string name="conversations">Mazungumzo</string>
|
||||
<string name="notes">Vidokezo</string>
|
||||
<string name="replies">Majibu</string>
|
||||
<string name="follows">"Anafuata"</string>
|
||||
<string name="reports">"Reports"</string>
|
||||
<string name="more_options">Chaguo Zaidi</string>
|
||||
<string name="relays">" Relays"</string>
|
||||
<string name="website">Tovuti</string>
|
||||
<string name="lightning_address">Anwani ya Umeme</string>
|
||||
<string name="copies_the_nsec_id_your_password_to_the_clipboard_for_backup">Hunakili Kitambulisho cha Nsec (nywila yako) kwenye ubao wa kunakili kwa ajili ya nakala rudufu</string>
|
||||
<string name="copy_private_key_to_the_clipboard">Nakili Ufunguo wa Siri kwenye Ubao wa Kunakili</string>
|
||||
<string name="copies_the_public_key_to_the_clipboard_for_sharing">Hunakili ufunguo wa umma kwenye ubao wa kunakili kwa ajili ya kushiriki</string>
|
||||
<string name="copy_public_key_npub_to_the_clipboard">Nakili Ufunguo wa Umma (NPub) kwenye Ubao wa Kunakili</string>
|
||||
<string name="send_a_direct_message">Tuma Ujumbe wa Moja kwa Moja</string>
|
||||
<string name="edits_the_user_s_metadata">Huhariri Metadata ya Mtumiaji</string>
|
||||
<string name="follow">Fuata</string>
|
||||
<string name="follow_back">Fuata tena</string>
|
||||
<string name="unblock">Fungua</string>
|
||||
<string name="copy_user_id">Nakili Kitambulisho cha Mtumiaji</string>
|
||||
<string name="unblock_user">Fungua Mtumiaji</string>
|
||||
<string name="npub_hex_username">"npub, jina la mtumiaji, maandishi"</string>
|
||||
<string name="clear">Ondoa</string>
|
||||
<string name="app_logo">Nembo ya Programu</string>
|
||||
<string name="nsec_npub_hex_private_key">nsec.. au npub..</string>
|
||||
<string name="show_password">Onyesha Nywila</string>
|
||||
<string name="hide_password">Ficha Nywila</string>
|
||||
<string name="invalid_key">Ufunguo usiofaa</string>
|
||||
<string name="i_accept_the">"Nakubali "</string>
|
||||
<string name="terms_of_use">masharti ya matumizi</string>
|
||||
<string name="acceptance_of_terms_is_required">Kukubaliana na masharti ni lazima</string>
|
||||
<string name="key_is_required">Ufunguo unahitajika</string>
|
||||
<string name="login">Ingia</string>
|
||||
<string name="generate_a_new_key">Tengeneza Ufunguo Mpya</string>
|
||||
<string name="loading_feed">Inapakia malisho</string>
|
||||
<string name="error_loading_replies">"Kosa katika kupakia majibu: "</string>
|
||||
<string name="try_again">Jaribu tena</string>
|
||||
<string name="feed_is_empty">Malisho ni tupu.</string>
|
||||
<string name="refresh">Sasisha</string>
|
||||
<string name="created">imeundwa</string>
|
||||
<string name="with_description_of">na maelezo ya</string>
|
||||
<string name="and_picture">na picha</string>
|
||||
<string name="changed_chat_name_to">ilisitisha jina la mazungumzo hadi</string>
|
||||
<string name="description_to">maelezo ya</string>
|
||||
<string name="and_picture_to">na picha ya</string>
|
||||
<string name="leave">Ondoka</string>
|
||||
<string name="unfollow">Acha kufuata</string>
|
||||
<string name="channel_created">Kituo kimeundwa</string>
|
||||
<string name="channel_information_changed_to">"Maelezo ya Kituo yamebadilika hadi"</string>
|
||||
<string name="public_chat">Mazungumzo ya Umma</string>
|
||||
<string name="posts_received">machapisho yamepokelewa</string>
|
||||
<string name="remove">Ondoa</string>
|
||||
<string name="translations_auto">Auto</string>
|
||||
<string name="translations_translated_from">imetafsiriwa kutoka</string>
|
||||
<string name="translations_to">kwa</string>
|
||||
<string name="translations_show_in_lang_first">Onyesha kwa %1$s kwanza</string>
|
||||
<string name="translations_always_translate_to_lang">Daima itafsiriwe kwa %1$s</string>
|
||||
<string name="translations_never_translate_from_lang">Kamwe usitafsiri kutoka %1$s</string>
|
||||
<string name="nip_05">Anwani ya Nostr</string>
|
||||
<string name="never">kamwe</string>
|
||||
<string name="now">sasa</string>
|
||||
<string name="h">h</string>
|
||||
<string name="m">m</string>
|
||||
<string name="d">d</string>
|
||||
<string name="nudity">Uchi</string>
|
||||
<string name="profanity_hateful_speech">Lugha chafu / Maneno yenye chuki</string>
|
||||
<string name="report_hateful_speech">Ripoti Lugha yenye chuki</string>
|
||||
<string name="report_nudity_porn">Ripoti Uchi / Pornografia</string>
|
||||
<string name="others">wengine</string>
|
||||
<string name="mark_all_known_as_read">Funga kama Zimejulikana</string>
|
||||
<string name="mark_all_new_as_read">Funga kama Mpya</string>
|
||||
<string name="mark_all_as_read">Funga kama Zimejulikana</string>
|
||||
<string name="backup_keys">Nakili Nakala za Ufunguo</string>
|
||||
<string name="account_backup_tips_md" tools:ignore="Typos"> ## Ufundi wa Nakala ya Ufunguo na Usalama
|
||||
\n\nAkaunti yako inalindwa na ufunguo wa siri. Ufunguo ni mfululizo mrefu wa herufi zisizo na mpangilio, ukitangulia na **nsec1**. Mtu yeyote aliye na ufikiaji wa ufunguo wako wa siri anaweza kuchapisha maudhui kwa kutumia kitambulisho chako.
|
||||
\n\n- **Usiweke** ufunguo wako wa siri kwenye tovuti au programu usio na imani.
|
||||
\n- Watengenezaji wa Amethyst **hawata** kuuliza ufunguo wako wa siri.
|
||||
\n- **Tunashauri** kuwa na nakala rudufu salama ya ufunguo wako wa siri kwa ajili ya kupata akaunti. Tunapendekeza kutumia meneja wa nywila.
|
||||
</string>
|
||||
<string name="secret_key_copied_to_clipboard">Ufunguo wa siri (nsec) umeinakiliwa kwenye ubao wa kunakili</string>
|
||||
<string name="copy_my_secret_key">Nakili Ufunguo Wangu wa Siri</string>
|
||||
<string name="biometric_authentication_failed">Uthibitishaji umeshindwa</string>
|
||||
<string name="biometric_error">Kosa</string>
|
||||
<string name="badge_created_by">"Imeundwa na %1$s"</string>
|
||||
<string name="badge_award_image_for">"Picha ya tuzo ya alama kwa %1$s"</string>
|
||||
<string name="new_badge_award_notif">Umepokea Tuzo Mpya ya Alama</string>
|
||||
<string name="award_granted_to">Tuzo ya alama imetolewa kwa</string>
|
||||
<string name="copied_note_text_to_clipboard">Maudhui ya dokezo yamenakiliwa kwenye ubao wa kunakili</string>
|
||||
<string name="copied_user_id_to_clipboard" tools:ignore="Typos">Imesakinishwa @npub ya mwandishi kwa ubao wa kunakili</string>
|
||||
<string name="copied_note_id_to_clipboard" tools:ignore="Typos">Imesakinishwa ID ya andiko (@note1) kwa ubao wa kunakili</string>
|
||||
<string name="select_text_dialog_top">Chagua Matini</string>
|
||||
<string name="private_conversation_notification">"<Haiwezi kuifanyia utawala ujumbe binafsi uliofichwa>\n\nUlinukuliwa katika mazungumzo ya faragha/yaliyofichwa kati ya %1$s na %2$s."</string>
|
||||
<string name="account_switch_add_account_dialog_title">Ongeza Akaunti Mpya</string>
|
||||
<string name="drawer_accounts">Akaunti</string>
|
||||
<string name="account_switch_select_account">Chagua Akaunti</string>
|
||||
<string name="account_switch_add_account_btn">Ongeza Akaunti Mpya</string>
|
||||
<string name="account_switch_active_account">Akaunti Iliyo Hai</string>
|
||||
<string name="account_switch_has_private_key">Ina ufunguo wa faragha</string>
|
||||
<string name="account_switch_pubkey_only">Soma tu, hakuna ufunguo wa faragha</string>
|
||||
<string name="back">Rudi</string>
|
||||
<string name="quick_action_select">Chagua</string>
|
||||
<string name="quick_action_share_browser_link">Shiriki Kiungo cha Kivinjari</string>
|
||||
<string name="quick_action_share">Shiriki</string>
|
||||
<string name="quick_action_copy_user_id">ID ya Mwandishi</string>
|
||||
<string name="quick_action_copy_note_id">ID ya Andiko</string>
|
||||
<string name="quick_action_copy_text">Nakili Matini</string>
|
||||
<string name="quick_action_delete">Futa</string>
|
||||
<string name="quick_action_unfollow">Acha Kufuata</string>
|
||||
<string name="quick_action_follow">Fuata</string>
|
||||
<string name="quick_action_request_deletion_alert_title">Omba Kufutwa</string>
|
||||
<string name="quick_action_request_deletion_alert_body">Amethyst itaomba kwamba andiko lako lifutwe kutoka kwa relays ambazo umekuwa umeunganishwa. Hakuna dhamana kwamba andiko lako litafutwa kabisa kutoka kwa relays hizo, au kutoka kwa relays nyingine ambapo linaweza kuwa limehifadhiwa.</string>
|
||||
<string name="quick_action_block_dialog_btn">Zuia</string>
|
||||
<string name="quick_action_delete_dialog_btn">Futa</string>
|
||||
<string name="quick_action_block">Zuia</string>
|
||||
<string name="quick_action_report">Ripoti</string>
|
||||
<string name="quick_action_delete_button">Futa</string>
|
||||
<string name="quick_action_dont_show_again_button">Usionyeshe Tena</string>
|
||||
<string name="report_dialog_spam">Barua Taka au Udanganyifu</string>
|
||||
<string name="report_dialog_profanity">Lugha chafu au tabia yenye chuki</string>
|
||||
<string name="report_dialog_impersonation">Uigaaji mbaya</string>
|
||||
<string name="report_dialog_nudity">Uchi au yaliyomo ya kushangaza</string>
|
||||
<string name="report_dialog_illegal">Tabia Haramu</string>
|
||||
<string name="report_dialog_blocking_a_user">Kuzuia mtumiaji kutaficha maudhui yao kwenye programu yako. Andiko zako bado zinaweza kuonekana kwa umma, pamoja na watu wanaokuzuia. Watumiaji waliozuiliwa wameorodheshwa kwenye skrini ya Filta za Usalama.</string>
|
||||
<string name="report_dialog_block_hide_user_btn"><![CDATA[Zuia na Ficha Mtumiaji]]></string>
|
||||
<string name="report_dialog_report_btn">Ripoti Matusi</string>
|
||||
<string name="report_dialog_reminder_public">Ripoti zote zilizopostiwa zitaonekana kwa umma.</string>
|
||||
<string name="report_dialog_additional_reason_placeholder">Toa muktadha wa ziada ikiwa unataka…</string>
|
||||
<string name="report_dialog_additional_reason_label">Muktadha wa Ziada</string>
|
||||
<string name="report_dialog_select_reason_label">Sababu</string>
|
||||
<string name="report_dialog_select_reason_placeholder">Chagua sababu…</string>
|
||||
<string name="report_dialog_post_report_btn">Chapisha Ripoti</string>
|
||||
<string name="report_dialog_title">Zuia na Ripoti</string>
|
||||
<string name="block_only">Zuia</string>
|
||||
<string name="bookmarks">Vialamisho</string>
|
||||
<string name="private_bookmarks">Vialamisho Binafsi</string>
|
||||
<string name="public_bookmarks">Vialamisho vya Umma</string>
|
||||
<string name="add_to_private_bookmarks">Ongeza kwenye Vialamisho Binafsi</string>
|
||||
<string name="add_to_public_bookmarks">Ongeza kwenye Vialamisho vya Umma</string>
|
||||
<string name="remove_from_private_bookmarks">Ondoa kutoka kwenye Vialamisho Binafsi</string>
|
||||
<string name="remove_from_public_bookmarks">Ondoa kutoka kwenye Vialamisho vya Umma</string>
|
||||
<string name="wallet_connect_service">Huduma ya Kuchanganya Pochi</string>
|
||||
<string name="wallet_connect_service_explainer">Inaidhinisha Nostr Secret kulipa zaps bila kuacha programu. Weka siri salama na tumia relay ya faragha ikiwezekana</string>
|
||||
<string name="wallet_connect_service_pubkey">Ufunguo wa Umma wa Kuchanganya Pochi</string>
|
||||
<string name="wallet_connect_service_relay">Kuchanganya Relay</string>
|
||||
<string name="wallet_connect_service_secret">Siri ya Kuchanganya Pochi</string>
|
||||
<string name="wallet_connect_service_show_secret">Onyesha ufunguo wa siri</string>
|
||||
<string name="wallet_connect_service_secret_placeholder">nsec / ufunguo wa siri wa hex</string>
|
||||
<string name="pledge_amount_in_sats">Kiasi cha Ahadi katika Sats</string>
|
||||
<string name="post_poll">Chapisha Kura</string>
|
||||
<string name="poll_heading_required">Sehemu zinazohitajika:</string>
|
||||
<string name="poll_zap_recipients">Wapokeaji wa Zaps</string>
|
||||
<string name="poll_primary_description">Maelezo ya msingi ya kura…</string>
|
||||
<string name="poll_option_index">Chaguo %s</string>
|
||||
<string name="poll_option_description">Maelezo ya chaguo cha kura</string>
|
||||
<string name="poll_heading_optional">Sehemu za hiari:</string>
|
||||
<string name="poll_zap_value_min">Kima cha Chini cha Zaps</string>
|
||||
<string name="poll_zap_value_max">Kima cha Juu cha Zaps</string>
|
||||
<string name="poll_consensus_threshold">Uamuzi</string>
|
||||
<string name="poll_consensus_threshold_percent">(0–100)%</string>
|
||||
<string name="poll_closing_time">Funga baada ya</string>
|
||||
<string name="poll_closing_time_days">siku</string>
|
||||
<string name="poll_is_closed">Kura imefungwa kwa kura mpya</string>
|
||||
<string name="poll_zap_amount">Kiasi cha Zaps</string>
|
||||
<string name="one_vote_per_user_on_atomic_votes">Kura moja tu kwa mtumiaji inaruhusiwa kwenye aina hii ya kura</string>
|
||||
<string name="looking_for_event">"Inatafuta Tukio %1$s"</string>
|
||||
<string name="custom_zaps_add_a_message">Ongeza ujumbe wa umma</string>
|
||||
<string name="custom_zaps_add_a_message_private">Ongeza ujumbe wa faragha</string>
|
||||
<string name="custom_zaps_add_a_message_nonzap">Ongeza ujumbe wa ankra</string>
|
||||
<string name="custom_zaps_add_a_message_example">Asante kwa kazi yako yote!</string>
|
||||
<string name="lightning_create_and_add_invoice">Tengeneza na Ongeza</string>
|
||||
<string name="poll_author_no_vote">Waandishi wa kura hawawezi kupiga kura kwenye kura zao wenyewe.</string>
|
||||
<string name="hash_verification_passed">Yaliyomo haya ni sawa tangu chapisho</string>
|
||||
<string name="hash_verification_failed">Yaliyomo haya yamebadilika. Mwandishi huenda hakuyapata au kuyaidhinisha mabadiliko</string>
|
||||
<string name="content_description_add_image">Ongeza Picha</string>
|
||||
<string name="content_description_add_video">Ongeza Video</string>
|
||||
<string name="content_description_add_document">Ongeza Hati</string>
|
||||
<string name="add_content">Ongeza kwenye Ujumbe</string>
|
||||
<string name="content_description">Maelezo ya yaliyomo</string>
|
||||
<string name="content_description_example">Boti ya buluu kwenye ufukwe mweupe wa mchanga wakati wa jua</string>
|
||||
<string name="zap_type">Aina ya Zap</string>
|
||||
<string name="zap_type_explainer">Aina ya Zap kwa chaguo zote</string>
|
||||
<string name="zap_type_public">Umma</string>
|
||||
<string name="zap_type_public_explainer">Kila mtu anaweza kuona shughuli na ujumbe</string>
|
||||
<string name="zap_type_private">Faragha</string>
|
||||
<string name="zap_type_private_explainer">Mpokeaji na Mjumbe wanaweza kuona kila mmoja na kusoma ujumbe</string>
|
||||
<string name="zap_type_anonymous">Bila Kutambuliwa</string>
|
||||
<string name="zap_type_anonymous_explainer">Mpokeaji na umma hawajui ni nani aliyetuma malipo</string>
|
||||
<string name="zap_type_nonzap">Bila Zap</string>
|
||||
<string name="zap_type_nonzap_explainer">Hakuna alama katika Nostr, tu katika Lightning</string>
|
||||
<string name="file_server">Seva ya Faili</string>
|
||||
<string name="zap_forward_lnAddress">LnAddress au @Mtumiaji</string>
|
||||
<string name="upload_server_imgur">imgur.com - inaaminika</string>
|
||||
<string name="upload_server_imgur_explainer">Imgur inaweza kubadilisha faili</string>
|
||||
<string name="upload_server_nostrimg">nostrimg.com - inaaminika</string>
|
||||
<string name="upload_server_nostrimg_explainer">NostrImg inaweza kubadilisha faili</string>
|
||||
<string name="upload_server_nostrbuild">nostr.build - inaaminika</string>
|
||||
<string name="upload_server_nostrbuild_explainer">Nostr.build inaweza kubadilisha faili</string>
|
||||
<string name="upload_server_nostrfilesdev">nostrfiles.dev - inaaminika</string>
|
||||
<string name="upload_server_nostrfilesdev_explainer">Nostrfiles.dev inaweza kubadilisha faili</string>
|
||||
<string name="upload_server_nostrcheckme">nostrcheck.me - inaaminika</string>
|
||||
<string name="upload_server_nostrcheckme_explainer">nostrcheck.me inaweza kubadilisha faili</string>
|
||||
<string name="upload_server_imgur_nip94">Imgur inayoweza kuthibitika (NIP-94)</string>
|
||||
<string name="upload_server_imgur_nip94_explainer">Inachunguza ikiwa Imgur imebadilisha faili. NIP mpya: wateja wengine huenda wasiione</string>
|
||||
<string name="upload_server_nostrimg_nip94">NostrImg inayoweza kuthibitika (NIP-94)</string>
|
||||
<string name="upload_server_nostrimg_nip94_explainer">Inachunguza ikiwa NostrImg imebadilisha faili. NIP mpya: wateja wengine huenda wasiione</string>
|
||||
<string name="upload_server_nostrbuild_nip94">Nostr.build inayoweza kuthibitika (NIP-94)</string>
|
||||
<string name="upload_server_nostrbuild_nip94_explainer">Inachunguza ikiwa Nostr.build imebadilisha faili. NIP mpya: wateja wengine huenda wasiione</string>
|
||||
<string name="upload_server_nostrfilesdev_nip94">Nostrfiles.dev inayoweza kuthibitika (NIP-94)</string>
|
||||
<string name="upload_server_nostrfilesdev_nip94_explainer">Inachunguza ikiwa Nostrfiles.dev imebadilisha faili. NIP mpya: wateja wengine huenda wasiione</string>
|
||||
<string name="upload_server_nostrcheckme_nip94">Nostrcheck.me inayoweza kuthibitika (NIP-94)</string>
|
||||
<string name="upload_server_nostrcheckme_nip94_explainer">Inachunguza ikiwa Nostrcheck.me imebadilisha faili. NIP mpya: wateja wengine huenda wasiione</string>
|
||||
<string name="upload_server_relays_nip95">Relays Zako (NIP-95)</string>
|
||||
<string name="upload_server_relays_nip95_explainer">Faili zinahifadhiwa na relays zako. NIP mpya: hakikisha zinazisaidia</string>
|
||||
<string name="connect_via_tor_short">Usanidi wa Tor/Orbot</string>
|
||||
<string name="connect_via_tor">Unaweza kuunganisha kupitia usanidi wako wa Orbot</string>
|
||||
<string name="do_you_really_want_to_disable_tor_title">Kujitenga na Orbot/Tor yako?</string>
|
||||
<string name="do_you_really_want_to_disable_tor_text">Data yako itahamishwa mara moja kwenye mtandao wa kawaida</string>
|
||||
<string name="yes">Ndio</string>
|
||||
<string name="no">Hapana</string>
|
||||
<string name="follow_list_selection">Orodha ya Kufuatilia</string>
|
||||
<string name="follow_list_kind3follows">Yafuatayo Yote</string>
|
||||
<string name="follow_list_global">Kote</string>
|
||||
<string name="connect_through_your_orbot_setup_markdown">## Kuungana kupitia Tor na Orbot
|
||||
\n\n1. Sakinisha [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)
|
||||
\n2. Anza Orbot
|
||||
\n3. Katika Orbot, angalia bandari ya Socks. Chaguo-msingi hutumia 9050
|
||||
\n4. Ikiwa ni lazima, badilisha bandari katika Orbot
|
||||
\n5. Sanidi bandari ya Socks kwenye skrini hii
|
||||
\n6. Bonyeza kitufe cha Kuamilisha kutumia Orbot kama mbadala</string>
|
||||
<string name="orbot_socks_port">Bandari ya Socks ya Orbot</string>
|
||||
<string name="invalid_port_number">Nambari ya bandari sio sahihi</string>
|
||||
<string name="use_orbot">Tumia Orbot</string>
|
||||
<string name="disconnect_from_your_orbot_setup">Jitenge na Tor/Orbot yako</string>
|
||||
<string name="app_notification_dms_channel_name">Ujumbe Binafsi</string>
|
||||
<string name="app_notification_dms_channel_description">Inakuarifu wakati ujumbe binafsi unapowasili</string>
|
||||
<string name="app_notification_zaps_channel_name">Zaps Zilizopokelewa</string>
|
||||
<string name="app_notification_zaps_channel_description">Inakuarifu wakati mtu anapokuzap</string>
|
||||
<string name="app_notification_zaps_channel_message">%1$s sats</string>
|
||||
<string name="app_notification_zaps_channel_message_from">Kutoka kwa %1$s</string>
|
||||
<string name="app_notification_zaps_channel_message_for">kwa %1$s</string>
|
||||
<string name="reply_notify">Taarifa: </string>
|
||||
<string name="channel_list_join_conversation">jiunge kwenye mazungumzo</string>
|
||||
<string name="channel_list_user_or_group_id">Kitambulisho cha Mtumiaji au Kikundi</string>
|
||||
<string name="channel_list_user_or_group_id_demo">npub, nevent au hex</string>
|
||||
<string name="channel_list_create_channel">Unda</string>
|
||||
<string name="channel_list_join_channel">jiunge</string>
|
||||
<string name="today">Leo</string>
|
||||
<string name="content_warning">Onyo la Yaliyomo</string>
|
||||
<string name="content_warning_explanation">Chapisho hili lina yaliyomo nyeti ambayo baadhi ya watu wanaweza kuona kama ya kuchukiza au kusumbua</string>
|
||||
<string name="content_warning_hide_all_sensitive_content">Daima ficha yaliyomo nyeti</string>
|
||||
<string name="content_warning_show_all_sensitive_content">Daima onyesha yaliyomo nyeti</string>
|
||||
<string name="content_warning_see_warnings">Daima onyesha onyo za yaliyomo</string>
|
||||
<string name="recommended_apps">Inapendekeza: </string>
|
||||
<string name="filter_spam_from_strangers">Chuja barua taka kutoka kwa wageni</string>
|
||||
<string name="warn_when_posts_have_reports_from_your_follows">Onya wakati machapisho yana ripoti kutoka kwa wafuatavyo wako</string>
|
||||
<string name="new_reaction_symbol">Alama Mpya ya Majibu</string>
|
||||
<string name="no_reaction_type_setup_long_press_to_change">Hakuna aina za majibu zilizochaguliwa. Bonyeza kwa muda mrefu kubadilisha</string>
|
||||
<string name="zapraiser">Mzushi wa Zaps</string>
|
||||
<string name="zapraiser_explainer">Inaongeza kiasi lengwa cha sats kwa chapisho hili. Wateja wanaosaidia wanaweza kuonyesha hii kama bar ya maendeleo ili kuhimiza michango</string>
|
||||
<string name="zapraiser_target_amount_in_sats">Kiasi Lengo katika Sats</string>
|
||||
<string name="sats_to_complete">Mzushi wa Zaps kwa %1$s. Sats %2$s hadi kufikia lengo</string>
|
||||
<string name="read_from_relay">Soma kutoka kwa Relay</string>
|
||||
<string name="write_to_relay">Andika kwa Relay</string>
|
||||
<string name="an_error_occurred_trying_to_get_relay_information">Kuna kosa lililotokea jaribu kupata habari za Relay kutoka kwa %1$s</string>
|
||||
<string name="owner">Mmiliki</string>
|
||||
<string name="version">Toleo</string>
|
||||
<string name="software">Programu</string>
|
||||
<string name="contact">Wasiliana</string>
|
||||
<string name="supports">NIPs Zinazoungwa mkono</string>
|
||||
<string name="admission_fees">Ada za Kuingia</string>
|
||||
<string name="payments_url">URL ya Malipo</string>
|
||||
<string name="limitations">Vikwazo</string>
|
||||
<string name="countries">Nchi</string>
|
||||
<string name="languages">Lugha</string>
|
||||
<string name="tags">Alama</string>
|
||||
<string name="posting_policy">Sera ya Kutuma</string>
|
||||
<string name="message_length">Urefu wa Ujumbe</string>
|
||||
<string name="subscriptions">Michango</string>
|
||||
<string name="filters">Vichujio</string>
|
||||
<string name="subscription_id_length">Urefu wa Kitambulisho cha Michango</string>
|
||||
<string name="minimum_prefix">Awamu ya Chini</string>
|
||||
<string name="maximum_event_tags">Vichwa vya Tukio vya Juu</string>
|
||||
<string name="content_length">Urefu wa Yaliyomo</string>
|
||||
<string name="minimum_pow">PoW ya Chini</string>
|
||||
<string name="auth">Uthibitishaji</string>
|
||||
<string name="payment">Malipo</string>
|
||||
<string name="cashu">Cashu Token</string>
|
||||
<string name="cashu_redeem">Kukomboa</string>
|
||||
<string name="no_lightning_address_set">Hakuna Anwani ya Lightning Imewekwa</string>
|
||||
<string name="copied_token_to_clipboard">Kitufe kimekopwa kwenye ubao wa kunakili</string>
|
||||
<string name="live_stream_live_tag">Moja kwa Moja</string>
|
||||
<string name="live_stream_offline_tag">Nje ya Mtandao</string>
|
||||
<string name="live_stream_ended_tag">Imemalizika</string>
|
||||
<string name="live_stream_planned_tag">Imepangwa</string>
|
||||
<string name="live_stream_is_offline">Moja kwa Moja Imekwama</string>
|
||||
<string name="live_stream_has_ended">Moja kwa Moja Imekwisha</string>
|
||||
<string name="are_you_sure_you_want_to_log_out">Kutoka kunaondoa taarifa zako za eneo la kuhifadhia data. Hakikisha una nakala za funguo zako binafsi ili kuepuka kupoteza akaunti yako. Je, unataka kuendelea?</string>
|
||||
<string name="followed_tags">Mada Zinazofuatwa</string>
|
||||
<string name="relay_setup">Usanidi wa Relays</string>
|
||||
<string name="discover_live">Moja kwa Moja</string>
|
||||
<string name="discover_community">Jumuiya</string>
|
||||
<string name="discover_chat">Mazungumzo</string>
|
||||
<string name="community_approved_posts">Machapisho Yaliyoidhinishwa</string>
|
||||
<string name="groups_no_descriptor">Kikundi hiki hakitumii maelezo au kanuni. Ongea na mmiliki ili aongeze.</string>
|
||||
<string name="community_no_descriptor">Jumuiya hii haitumii maelezo. Ongea na mmiliki ili aongeze.</string>
|
||||
<string name="add_sensitive_content_label">Yaliyomo Nyeti</string>
|
||||
<string name="add_sensitive_content_description">Inaongeza onyo la yaliyomo nyeti kabla ya kuonyesha yaliyomo hii</string>
|
||||
<string name="settings">Mipangilio</string>
|
||||
<string name="connectivity_type_always">Daima</string>
|
||||
<string name="connectivity_type_wifi_only">Wi-Fi tu</string>
|
||||
<string name="connectivity_type_never">Kamwe</string>
|
||||
<string name="system">Mfumo</string>
|
||||
<string name="light">Mwanga</string>
|
||||
<string name="dark">Giza</string>
|
||||
<string name="application_preferences">Mapendeleo ya Programu</string>
|
||||
<string name="language">Lugha</string>
|
||||
<string name="theme">Mandhari</string>
|
||||
<string name="automatically_load_images_gifs">Onesha Picha</string>
|
||||
<string name="automatically_play_videos">Cheza Video</string>
|
||||
<string name="automatically_show_url_preview">Onesha Hakikisho za URL</string>
|
||||
<string name="load_image">Soma Picha</string>
|
||||
<string name="spamming_users">Wahasibu</string>
|
||||
<string name="muted_button">Walemavu. Bonyeza kuwasha sauti</string>
|
||||
<string name="mute_button">Sauti imewashwa. Bonyeza kulegeza</string>
|
||||
<string name="search_button">Tafuta rekodi za eneo la kuhifadhia data na rekodi za mbali</string>
|
||||
<string name="nip05_verified">Anwani ya Nostr ilithibitishwa</string>
|
||||
<string name="nip05_failed">Anwani ya Nostr ilishindwa kuthibitishwa</string>
|
||||
<string name="nip05_checking">Kuthibitisha Anwani ya Nostr</string>
|
||||
<string name="select_deselect_all">Chagua/Chagua Vingine Vyote</string>
|
||||
<string name="default_relays">Chaguo-msingi</string>
|
||||
<string name="select_a_relay_to_continue">Chagua kiotomatiki kuendelea</string>
|
||||
<string name="zap_forward_title">Tuma Zaps kwa:</string>
|
||||
<string name="zap_forward_explainer">Wateja wanaosaidia watatuma Zaps kwa LNAddress au Wasifu wa Mtumiaji hapa chini badala ya yako</string>
|
||||
<string name="geohash_title">Tumia Mahali kama </string>
|
||||
<string name="geohash_explainer">Inaongeza Geohash ya eneo lako kwenye chapisho. Umma utajua kuwa uko ndani ya kilometa 5 (maili 3) ya eneo la sasa</string>
|
||||
<string name="add_sensitive_content_explainer">Inaongeza onyo la yaliyomo nyeti kabla ya kuonyesha yaliyomo yako. Hii ni nzuri kwa yaliyomo yoyote ya NSFW au yaliyomo ambayo baadhi ya watu wanaweza kuona kama ya kuchukiza au kusumbua</string>
|
||||
<string name="new_feature_nip24_might_not_be_available_title">Kipengee Kipya</string>
|
||||
<string name="new_feature_nip24_might_not_be_available_description">Kuwezesha hali hii kunahitaji Amethyst kutuma ujumbe wa NIP-24 (Ufungaji wa Zawadi, Ujumbe wa Moja kwa Moja Uliosajiliwa, na Ujumbe wa Kikundi). NIP-24 ni mpya na wateja wengi bado hawajaijumuisha. Hakikisha mpokeaji anatumia mteja unaokubaliana.</string>
|
||||
<string name="new_feature_nip24_activate">Tumia</string>
|
||||
<string name="messages_create_public_chat">Umma</string>
|
||||
<string name="messages_new_message">Binafsi</string>
|
||||
<string name="messages_new_message_to">Kwa</string>
|
||||
<string name="messages_new_message_subject">Somo</string>
|
||||
<string name="messages_new_message_subject_caption">Mada ya mazungumzo</string>
|
||||
<string name="messages_new_message_to_caption">"\@User1, @User2, @User3"</string>
|
||||
<string name="messages_group_descriptor">Wanachama wa kikundi hiki</string>
|
||||
<string name="messages_new_subject_message">Maelezo kwa wanachama</string>
|
||||
<string name="messages_new_subject_message_placeholder">Kubadilisha jina kwa malengo mapya.</string>
|
||||
<string name="language_description">Kwa Interface ya Programu</string>
|
||||
<string name="theme_description">Mada ya Giza, Mada ya Mwanga, au Mada ya Mfumo</string>
|
||||
<string name="automatically_load_images_gifs_description">Lisha picha na GIFs kiotomatiki</string>
|
||||
<string name="automatically_play_videos_description">Cheza video na GIFs kiotomatiki</string>
|
||||
<string name="automatically_show_url_preview_description">Onyesha hakikisho za URL kiotomatiki</string>
|
||||
<string name="load_image_description">Lini kusoma picha</string>
|
||||
<string name="copy_url_to_clipboard">Nakili URL kwa ubao wa kunakili</string>
|
||||
<string name="copy_the_note_id_to_the_clipboard">Nakili Kitambulisho cha Andiko kwa ubao wa kunakili</string>
|
||||
<string name="created_at">Imetengenezwa saa</string>
|
||||
<string name="rules">Miongozo</string>
|
||||
<string name="status_update">Sasisha hali yako</string>
|
||||
<string name="lightning_wallets_not_found">Kosa katika uchambuzi wa ujumbe wa kosa</string>
|
||||
<string name="poll_zap_value_min_max_explainer">Kura zina uzito kulingana na kiasi cha zap. Unaweza kuweka kiasi cha chini ili kuepuka wahasibu na kiasi cha juu ili kuepuka wahasibu wakubwa kuchukua kura ya maoni. Tumia kiasi sawa katika sehemu zote mbili ili kuhakikisha kila kura inathaminiwa kwa kiasi sawa. Acha tupu ili kukubali kiasi chochote.</string>
|
||||
<string name="error_dialog_zap_error">Haiwezekani kutuma zap</string>
|
||||
<string name="error_dialog_talk_to_user">Tuma ujumbe kwa mtumiaji</string>
|
||||
<string name="error_dialog_button_ok">Sawa</string>
|
||||
</resources>
|
||||
|
@ -123,6 +123,7 @@
|
||||
<string name="send_a_direct_message">发送直接消息</string>
|
||||
<string name="edits_the_user_s_metadata">编辑用户元数据</string>
|
||||
<string name="follow">关注</string>
|
||||
<string name="follow_back">回关</string>
|
||||
<string name="unblock">不隐藏</string>
|
||||
<string name="copy_user_id">复制用户ID</string>
|
||||
<string name="unblock_user">隐藏该用户</string>
|
||||
@ -251,6 +252,9 @@
|
||||
<string name="wallet_connect_service_show_secret">显示私钥</string>
|
||||
<string name="wallet_connect_service_secret_placeholder">nsec / 十六进制私钥</string>
|
||||
<string name="pledge_amount_in_sats">聪数量</string>
|
||||
<string name="poll_heading_required">必填字段:</string>
|
||||
<string name="poll_zap_recipients">打闪接收人</string>
|
||||
<string name="poll_option_index">选项 %s</string>
|
||||
<string name="poll_heading_optional">可选字段:</string>
|
||||
<string name="poll_zap_value_min">打闪最低金额</string>
|
||||
<string name="poll_zap_value_max">打闪最高金额</string>
|
||||
@ -259,6 +263,7 @@
|
||||
<string name="poll_zap_amount">打闪金额</string>
|
||||
<string name="looking_for_event">"“正在查找事件%1$s”"</string>
|
||||
<string name="custom_zaps_add_a_message">添加公开消息</string>
|
||||
<string name="custom_zaps_add_a_message_private">添加私信</string>
|
||||
<string name="custom_zaps_add_a_message_nonzap">添加发票消息</string>
|
||||
<string name="lightning_create_and_add_invoice">创建并添加</string>
|
||||
<string name="content_description_add_image">添加图片</string>
|
||||
@ -268,18 +273,50 @@
|
||||
<string name="content_description">内容描述</string>
|
||||
<string name="content_description_example">一艘蓝色船,位于白沙滩的日落点</string>
|
||||
<string name="zap_type">打闪种类</string>
|
||||
<string name="zap_type_explainer">所有选项的打闪类型</string>
|
||||
<string name="zap_type_public">公开</string>
|
||||
<string name="zap_type_public_explainer">所有人都能看到交易和消息</string>
|
||||
<string name="zap_type_private">私人</string>
|
||||
<string name="zap_type_private_explainer">发送方和接收方能互相看到并读取消息</string>
|
||||
<string name="zap_type_anonymous">匿名</string>
|
||||
<string name="zap_type_nonzap">非打闪</string>
|
||||
<string name="upload_server_relays_nip95">你的中继器 (NIP-95)</string>
|
||||
<string name="connect_via_tor_short">Tor/Orbot 设置</string>
|
||||
<string name="connect_via_tor">通过你的 Orbot 设置连接</string>
|
||||
<string name="do_you_really_want_to_disable_tor_title">断开与你的 Orbot/Tor 连接?</string>
|
||||
<string name="yes">是</string>
|
||||
<string name="no">否</string>
|
||||
<string name="follow_list_selection">关注列表</string>
|
||||
<string name="follow_list_kind3follows">所有关注</string>
|
||||
<string name="follow_list_global">全球</string>
|
||||
<string name="orbot_socks_port">Orbot Socks 端口</string>
|
||||
<string name="invalid_port_number">无效端口</string>
|
||||
<string name="use_orbot">使用 Orbot</string>
|
||||
<string name="disconnect_from_your_orbot_setup">断开 Tor/Orbot 连接</string>
|
||||
<string name="app_notification_dms_channel_name">私信</string>
|
||||
<string name="app_notification_dms_channel_description">收到私信时通知你</string>
|
||||
<string name="app_notification_zaps_channel_name">收到打闪</string>
|
||||
<string name="app_notification_zaps_channel_description">收到打闪时通知你</string>
|
||||
<string name="app_notification_zaps_channel_message">%1$s聪</string>
|
||||
<string name="reply_notify">通知:</string>
|
||||
<string name="channel_list_join_conversation">加入对话</string>
|
||||
<string name="channel_list_user_or_group_id">用户或群组 ID</string>
|
||||
<string name="channel_list_user_or_group_id_demo">npub、nevent 或 hex</string>
|
||||
<string name="channel_list_create_channel">创建</string>
|
||||
<string name="channel_list_join_channel">加入</string>
|
||||
<string name="today">今天</string>
|
||||
<string name="content_warning">内容警告</string>
|
||||
<string name="content_warning_hide_all_sensitive_content">始终隐藏敏感内容</string>
|
||||
<string name="content_warning_show_all_sensitive_content">始终显示敏感内容</string>
|
||||
<string name="content_warning_see_warnings">始终显示内容警告</string>
|
||||
<string name="recommended_apps">推荐:</string>
|
||||
<string name="filter_spam_from_strangers">过滤来自陌生人的垃圾信息</string>
|
||||
<string name="new_reaction_symbol">新反应符号</string>
|
||||
<string name="zapraiser">Zapraiser</string>
|
||||
<string name="zapraiser_target_amount_in_sats">目标聪金额</string>
|
||||
<string name="sats_to_complete">Zapraiser 位于 %1$s。距离目标%2$s聪</string>
|
||||
<string name="read_from_relay">从中继器读取</string>
|
||||
<string name="write_to_relay">写入到继电器</string>
|
||||
<string name="version">版本</string>
|
||||
<string name="software">软件</string>
|
||||
<string name="contact">联络</string>
|
||||
@ -293,13 +330,24 @@
|
||||
<string name="message_length">消息长度</string>
|
||||
<string name="subscriptions">订阅</string>
|
||||
<string name="filters">筛选器</string>
|
||||
<string name="subscription_id_length">订阅 ID 长度</string>
|
||||
<string name="content_length">内容长度</string>
|
||||
<string name="auth">认证</string>
|
||||
<string name="payment">支付</string>
|
||||
<string name="cashu_redeem">兑换</string>
|
||||
<string name="no_lightning_address_set">未设置闪电地址</string>
|
||||
<string name="copied_token_to_clipboard">已复制令牌至剪贴板</string>
|
||||
<string name="live_stream_live_tag">直播</string>
|
||||
<string name="live_stream_offline_tag">离线</string>
|
||||
<string name="live_stream_ended_tag">已结束</string>
|
||||
<string name="live_stream_is_offline">直播处于离线状态</string>
|
||||
<string name="live_stream_has_ended">直播已结束</string>
|
||||
<string name="followed_tags">已关注的标签</string>
|
||||
<string name="relay_setup">中继器</string>
|
||||
<string name="discover_live">直播</string>
|
||||
<string name="discover_community">社区</string>
|
||||
<string name="discover_chat">聊天</string>
|
||||
<string name="community_approved_posts">批准帖子</string>
|
||||
<string name="add_sensitive_content_label">敏感内容</string>
|
||||
<string name="settings">设置</string>
|
||||
<string name="connectivity_type_always">始终</string>
|
||||
@ -308,13 +356,45 @@
|
||||
<string name="system">系统</string>
|
||||
<string name="light">浅色</string>
|
||||
<string name="dark">深色</string>
|
||||
<string name="application_preferences">应用程序首选项</string>
|
||||
<string name="language">语言</string>
|
||||
<string name="theme">主题</string>
|
||||
<string name="automatically_load_images_gifs">图像预览</string>
|
||||
<string name="automatically_play_videos">视频播放</string>
|
||||
<string name="automatically_show_url_preview">URL 预览</string>
|
||||
<string name="load_image">加载图像</string>
|
||||
<string name="muted_button">静音。点击取消静音</string>
|
||||
<string name="mute_button">声音开启。点击静音</string>
|
||||
<string name="nip05_verified">Nostr 地址已验证</string>
|
||||
<string name="nip05_failed">Nostr 地址验证失败</string>
|
||||
<string name="nip05_checking">正在检查 Nostr 地址</string>
|
||||
<string name="default_relays">默认</string>
|
||||
<string name="select_a_relay_to_continue">选择中继器以继续</string>
|
||||
<string name="zap_forward_title">将打闪转发到:</string>
|
||||
<string name="geohash_title">将位置显示为 </string>
|
||||
<string name="new_feature_nip24_might_not_be_available_title">新功能</string>
|
||||
<string name="new_feature_nip24_activate">启用</string>
|
||||
<string name="messages_create_public_chat">公开</string>
|
||||
<string name="messages_new_message">私人</string>
|
||||
<string name="messages_new_message_to">至</string>
|
||||
<string name="messages_new_message_subject">主题</string>
|
||||
<string name="messages_new_message_subject_caption">对话主题</string>
|
||||
<string name="messages_new_message_to_caption">"\@User1、@User2、@User3"</string>
|
||||
<string name="messages_group_descriptor">此群组成员</string>
|
||||
<string name="messages_new_subject_message">对成员的解释</string>
|
||||
<string name="language_description">用于应用程序界面</string>
|
||||
<string name="theme_description">暗色、亮色或系统主题</string>
|
||||
<string name="automatically_load_images_gifs_description">自动加载图像和 GIF</string>
|
||||
<string name="automatically_play_videos_description">自动播放视频和 GIF</string>
|
||||
<string name="automatically_show_url_preview_description">显示 URL 预览</string>
|
||||
<string name="load_image_description">何时加载图像</string>
|
||||
<string name="copy_url_to_clipboard">复制链接到剪贴板</string>
|
||||
<string name="copy_the_note_id_to_the_clipboard">复制笔记 ID 到剪贴板</string>
|
||||
<string name="created_at">创建于</string>
|
||||
<string name="rules">规则</string>
|
||||
<string name="status_update">更新你的状态</string>
|
||||
<string name="lightning_wallets_not_found">错误解析错误消息</string>
|
||||
<string name="error_dialog_zap_error">无法发送打闪</string>
|
||||
<string name="error_dialog_talk_to_user">向用户发送消息</string>
|
||||
<string name="error_dialog_button_ok">好</string>
|
||||
</resources>
|
||||
|
@ -233,8 +233,10 @@
|
||||
<string name="content_description_add_video">添加視頻</string>
|
||||
<string name="content_description_add_document">添加文件</string>
|
||||
<string name="add_content">添加到消息</string>
|
||||
<string name="content_description">內容描述</string>
|
||||
<string name="zap_type">打閃種類</string>
|
||||
<string name="zap_type_public">公開</string>
|
||||
<string name="zap_type_private">私人</string>
|
||||
<string name="zap_type_anonymous">匿名</string>
|
||||
<string name="zap_type_nonzap">非打閃</string>
|
||||
<string name="connect_via_tor_short">Tor/Orbot 設置</string>
|
||||
@ -242,6 +244,34 @@
|
||||
<string name="do_you_really_want_to_disable_tor_title">斷開與你的 Orbot/Tor 連接?</string>
|
||||
<string name="yes">是</string>
|
||||
<string name="no">否</string>
|
||||
<string name="follow_list_selection">關注列表</string>
|
||||
<string name="follow_list_kind3follows">所有關注</string>
|
||||
<string name="follow_list_global">全球</string>
|
||||
<string name="orbot_socks_port">Orbot Socks 端口</string>
|
||||
<string name="invalid_port_number">無效端口</string>
|
||||
<string name="use_orbot">使用 Orbot</string>
|
||||
<string name="disconnect_from_your_orbot_setup">斷連 Tor/Orbot</string>
|
||||
<string name="app_notification_dms_channel_name">私信</string>
|
||||
<string name="app_notification_zaps_channel_message">%1$s聰</string>
|
||||
<string name="app_notification_zaps_channel_message_from">來自%1$s</string>
|
||||
<string name="channel_list_user_or_group_id_demo">npub,、nevent 或 hex</string>
|
||||
<string name="channel_list_create_channel">創建</string>
|
||||
<string name="channel_list_join_channel">加入</string>
|
||||
<string name="today">今天</string>
|
||||
<string name="content_warning">內容警告</string>
|
||||
<string name="recommended_apps">推薦:</string>
|
||||
<string name="version">版本</string>
|
||||
<string name="software">軟體</string>
|
||||
<string name="contact">聯絡</string>
|
||||
<string name="limitations">限制</string>
|
||||
<string name="countries">國家</string>
|
||||
<string name="languages">語言</string>
|
||||
<string name="tags">標籤</string>
|
||||
<string name="subscriptions">訂閱</string>
|
||||
<string name="auth">認證</string>
|
||||
<string name="payment">付款</string>
|
||||
<string name="cashu_redeem">兌換</string>
|
||||
<string name="no_lightning_address_set">未設定閃電地址</string>
|
||||
<string name="live_stream_live_tag">直播</string>
|
||||
<string name="live_stream_offline_tag">離線</string>
|
||||
<string name="live_stream_ended_tag">已結束</string>
|
||||
@ -250,6 +280,8 @@
|
||||
<string name="relay_setup">中繼器</string>
|
||||
<string name="discover_live">直播</string>
|
||||
<string name="discover_community">社群</string>
|
||||
<string name="discover_chat">聊天</string>
|
||||
<string name="add_sensitive_content_label">敏感內容</string>
|
||||
<string name="settings">設置</string>
|
||||
<string name="connectivity_type_always">始終</string>
|
||||
<string name="connectivity_type_never">永不</string>
|
||||
@ -261,5 +293,23 @@
|
||||
<string name="automatically_load_images_gifs">圖像預覽</string>
|
||||
<string name="automatically_show_url_preview">鏈接預覽</string>
|
||||
<string name="load_image">加載圖像</string>
|
||||
<string name="nip05_verified">Nostr 地址已驗證</string>
|
||||
<string name="nip05_failed">Nostr 地址驗證失敗</string>
|
||||
<string name="nip05_checking">正在檢查 Nostr 地址</string>
|
||||
<string name="default_relays">默認</string>
|
||||
<string name="zap_forward_title">將打閃轉發到:</string>
|
||||
<string name="new_feature_nip24_might_not_be_available_title">新功能</string>
|
||||
<string name="new_feature_nip24_activate">啟用</string>
|
||||
<string name="messages_create_public_chat">公開</string>
|
||||
<string name="messages_new_message">私人</string>
|
||||
<string name="messages_new_message_to">至</string>
|
||||
<string name="messages_new_message_subject">主題</string>
|
||||
<string name="load_image_description">何時加載圖像</string>
|
||||
<string name="copy_url_to_clipboard">將 URL 複製到剪貼簿</string>
|
||||
<string name="copy_the_note_id_to_the_clipboard">將筆記 ID 複製到剪貼簿</string>
|
||||
<string name="created_at">創建於</string>
|
||||
<string name="rules">規則</string>
|
||||
<string name="status_update">更新你的狀態</string>
|
||||
<string name="error_dialog_zap_error">無法發送打閃</string>
|
||||
<string name="error_dialog_button_ok">確定</string>
|
||||
</resources>
|
||||
|
@ -562,4 +562,16 @@
|
||||
<string name="error_dialog_zap_error">Unable to send zap</string>
|
||||
<string name="error_dialog_talk_to_user">Message the User</string>
|
||||
<string name="error_dialog_button_ok">Ok</string>
|
||||
|
||||
<string name="relay_information_document_error_assemble_url">Failed to reach %1$s: %2$s</string>
|
||||
<string name="relay_information_document_error_reach_server">Failed to reach %1$s: %2$s</string>
|
||||
<string name="relay_information_document_error_parse_result">Failed to parse result from %1$s: %2$s</string>
|
||||
<string name="relay_information_document_error_http_status">%1$s failed with code %2$s</string>
|
||||
<string name="active_for">Active for: </string>
|
||||
|
||||
<string name="active_for_home">Home</string>
|
||||
<string name="active_for_msg">DMs</string>
|
||||
<string name="active_for_chats">Chats</string>
|
||||
<string name="active_for_global">Global</string>
|
||||
<string name="active_for_search">Search</string>
|
||||
</resources>
|
||||
|
@ -10,6 +10,7 @@
|
||||
<locale android:name="fa"/>
|
||||
<locale android:name="fr"/>
|
||||
<locale android:name="hu"/>
|
||||
<locale android:name="in"/>
|
||||
<locale android:name="ja"/>
|
||||
<locale android:name="nl"/>
|
||||
<locale android:name="pt-BR"/>
|
||||
|
@ -19,6 +19,7 @@ files:
|
||||
fa: fa
|
||||
fr: fr
|
||||
hu: hu
|
||||
in: in
|
||||
ja: ja
|
||||
nl: nl
|
||||
ru: ru
|
||||
|
@ -4,7 +4,7 @@ import java.util.regex.Pattern
|
||||
|
||||
object LnWithdrawalUtil {
|
||||
private val withdrawalPattern = Pattern.compile(
|
||||
"lnurl.+",
|
||||
"lnurl1[02-9ac-hj-np-z]+",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
)
|
||||
|
||||
|
@ -62,7 +62,7 @@ open class Event(
|
||||
|
||||
override fun toJson(): String = mapper.writeValueAsString(toJsonObject())
|
||||
|
||||
fun hasAnyTaggedUser() = tags.any { it.size > 1 && it[0] == "p" }
|
||||
override fun hasAnyTaggedUser() = tags.any { it.size > 1 && it[0] == "p" }
|
||||
|
||||
override fun taggedUsers() = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] }
|
||||
override fun taggedEvents() = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] }
|
||||
|
@ -63,6 +63,8 @@ interface EventInterface {
|
||||
fun subject(): String?
|
||||
fun zapraiserAmount(): Long?
|
||||
|
||||
fun hasAnyTaggedUser(): Boolean
|
||||
|
||||
fun taggedAddresses(): List<ATag>
|
||||
fun taggedUsers(): List<HexKey>
|
||||
fun taggedEvents(): List<HexKey>
|
||||
|
Loading…
x
Reference in New Issue
Block a user