Merge branch 'vitorpamplona:main' into nostrbuildv2
This commit is contained in:
@@ -1514,9 +1514,9 @@ class Account(
|
|||||||
|
|
||||||
private fun isAcceptableDirect(note: Note): Boolean {
|
private fun isAcceptableDirect(note: Note): Boolean {
|
||||||
if (!warnAboutPostsWithReports) {
|
if (!warnAboutPostsWithReports) {
|
||||||
return note.reportsBy(userProfile()).isEmpty()
|
return !note.hasReportsBy(userProfile())
|
||||||
}
|
}
|
||||||
return note.reportsBy(userProfile()).isEmpty() && // if user has not reported this post
|
return !note.hasReportsBy(userProfile()) && // if user has not reported this post
|
||||||
note.countReportAuthorsBy(followingKeySet()) < 5 // if it has 5 reports by reliable users
|
note.countReportAuthorsBy(followingKeySet()) < 5 // if it has 5 reports by reliable users
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,20 +51,20 @@ open class Note(val idHex: String) {
|
|||||||
var replyTo: List<Note>? = null
|
var replyTo: List<Note>? = null
|
||||||
|
|
||||||
// These fields are updated every time an event related to this note is received.
|
// These fields are updated every time an event related to this note is received.
|
||||||
var replies = setOf<Note>()
|
var replies = listOf<Note>()
|
||||||
private set
|
private set
|
||||||
var reactions = mapOf<String, Set<Note>>()
|
var reactions = mapOf<String, List<Note>>()
|
||||||
private set
|
private set
|
||||||
var boosts = setOf<Note>()
|
var boosts = listOf<Note>()
|
||||||
private set
|
private set
|
||||||
var reports = mapOf<User, Set<Note>>()
|
var reports = mapOf<User, List<Note>>()
|
||||||
private set
|
private set
|
||||||
var zaps = mapOf<Note, Note?>()
|
var zaps = mapOf<Note, Note?>()
|
||||||
private set
|
private set
|
||||||
var zapPayments = mapOf<Note, Note?>()
|
var zapPayments = mapOf<Note, Note?>()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var relays = setOf<String>()
|
var relays = listOf<String>()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var lastReactionsDownloadTime: Map<String, EOSETime> = emptyMap()
|
var lastReactionsDownloadTime: Map<String, EOSETime> = emptyMap()
|
||||||
@@ -151,15 +151,20 @@ open class Note(val idHex: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun removeReply(note: Note) {
|
fun removeReply(note: Note) {
|
||||||
replies = replies - note
|
if (note in replies) {
|
||||||
liveSet?.replies?.invalidateData()
|
replies = replies - note
|
||||||
}
|
liveSet?.replies?.invalidateData()
|
||||||
fun removeBoost(note: Note) {
|
}
|
||||||
boosts = boosts - note
|
|
||||||
liveSet?.boosts?.invalidateData()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeAllChildNotes(): Set<Note> {
|
fun removeBoost(note: Note) {
|
||||||
|
if (note in boosts) {
|
||||||
|
boosts = boosts - note
|
||||||
|
liveSet?.boosts?.invalidateData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeAllChildNotes(): List<Note> {
|
||||||
val toBeRemoved = replies +
|
val toBeRemoved = replies +
|
||||||
reactions.values.flatten() +
|
reactions.values.flatten() +
|
||||||
boosts +
|
boosts +
|
||||||
@@ -169,13 +174,13 @@ open class Note(val idHex: String) {
|
|||||||
zapPayments.keys +
|
zapPayments.keys +
|
||||||
zapPayments.values.filterNotNull()
|
zapPayments.values.filterNotNull()
|
||||||
|
|
||||||
replies = setOf<Note>()
|
replies = listOf<Note>()
|
||||||
reactions = mapOf<String, Set<Note>>()
|
reactions = mapOf<String, List<Note>>()
|
||||||
boosts = setOf<Note>()
|
boosts = listOf<Note>()
|
||||||
reports = mapOf<User, Set<Note>>()
|
reports = mapOf<User, List<Note>>()
|
||||||
zaps = mapOf<Note, Note?>()
|
zaps = mapOf<Note, Note?>()
|
||||||
zapPayments = mapOf<Note, Note?>()
|
zapPayments = mapOf<Note, Note?>()
|
||||||
relays = setOf<String>()
|
relays = listOf<String>()
|
||||||
lastReactionsDownloadTime = emptyMap()
|
lastReactionsDownloadTime = emptyMap()
|
||||||
|
|
||||||
liveSet?.replies?.invalidateData()
|
liveSet?.replies?.invalidateData()
|
||||||
@@ -193,14 +198,16 @@ open class Note(val idHex: String) {
|
|||||||
|
|
||||||
if (reaction in reactions.keys && reactions[reaction]?.contains(note) == true) {
|
if (reaction in reactions.keys && reactions[reaction]?.contains(note) == true) {
|
||||||
reactions[reaction]?.let {
|
reactions[reaction]?.let {
|
||||||
val newList = it.minus(note)
|
if (note in it) {
|
||||||
if (newList.isEmpty()) {
|
val newList = it.minus(note)
|
||||||
reactions = reactions.minus(reaction)
|
if (newList.isEmpty()) {
|
||||||
} else {
|
reactions = reactions.minus(reaction)
|
||||||
reactions = reactions + Pair(reaction, newList)
|
} else {
|
||||||
}
|
reactions = reactions + Pair(reaction, newList)
|
||||||
|
}
|
||||||
|
|
||||||
liveSet?.reactions?.invalidateData()
|
liveSet?.reactions?.invalidateData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +313,7 @@ open class Note(val idHex: String) {
|
|||||||
val reaction = note.event?.content()?.firstFullCharOrEmoji(ImmutableListOfLists(tags)) ?: "+"
|
val reaction = note.event?.content()?.firstFullCharOrEmoji(ImmutableListOfLists(tags)) ?: "+"
|
||||||
|
|
||||||
if (reaction !in reactions.keys) {
|
if (reaction !in reactions.keys) {
|
||||||
reactions = reactions + Pair(reaction, setOf(note))
|
reactions = reactions + Pair(reaction, listOf(note))
|
||||||
liveSet?.reactions?.invalidateData()
|
liveSet?.reactions?.invalidateData()
|
||||||
} else if (reactions[reaction]?.contains(note) == false) {
|
} else if (reactions[reaction]?.contains(note) == false) {
|
||||||
reactions = reactions + Pair(reaction, (reactions[reaction] ?: emptySet()) + note)
|
reactions = reactions + Pair(reaction, (reactions[reaction] ?: emptySet()) + note)
|
||||||
@@ -318,7 +325,7 @@ open class Note(val idHex: String) {
|
|||||||
val author = note.author ?: return
|
val author = note.author ?: return
|
||||||
|
|
||||||
if (author !in reports.keys) {
|
if (author !in reports.keys) {
|
||||||
reports = reports + Pair(author, setOf(note))
|
reports = reports + Pair(author, listOf(note))
|
||||||
liveSet?.reports?.invalidateData()
|
liveSet?.reports?.invalidateData()
|
||||||
} else if (reports[author]?.contains(note) == false) {
|
} else if (reports[author]?.contains(note) == false) {
|
||||||
reports = reports + Pair(author, (reports[author] ?: emptySet()) + note)
|
reports = reports + Pair(author, (reports[author] ?: emptySet()) + note)
|
||||||
@@ -411,8 +418,8 @@ open class Note(val idHex: String) {
|
|||||||
return boosts.any { it.author?.pubkeyHex == user.pubkeyHex }
|
return boosts.any { it.author?.pubkeyHex == user.pubkeyHex }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportsBy(user: User): Set<Note> {
|
fun hasReportsBy(user: User): Boolean {
|
||||||
return reports[user] ?: emptySet()
|
return reports[user]?.isNotEmpty() ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportAuthorsBy(users: Set<HexKey>): List<User> {
|
fun reportAuthorsBy(users: Set<HexKey>): List<User> {
|
||||||
@@ -576,9 +583,9 @@ open class Note(val idHex: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
replyTo = null
|
replyTo = null
|
||||||
replies = emptySet()
|
replies = emptyList()
|
||||||
reactions = emptyMap()
|
reactions = emptyMap()
|
||||||
boosts = emptySet()
|
boosts = emptyList()
|
||||||
reports = emptyMap()
|
reports = emptyMap()
|
||||||
zaps = emptyMap()
|
zaps = emptyMap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.vitorpamplona.amethyst.model.TimeUtils
|
|||||||
import com.vitorpamplona.amethyst.model.toHexKey
|
import com.vitorpamplona.amethyst.model.toHexKey
|
||||||
import com.vitorpamplona.amethyst.service.CryptoUtils
|
import com.vitorpamplona.amethyst.service.CryptoUtils
|
||||||
import com.vitorpamplona.amethyst.service.nip19.Nip19
|
import com.vitorpamplona.amethyst.service.nip19.Nip19
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.bytesUsedInMemory
|
||||||
import fr.acinq.secp256k1.Hex
|
import fr.acinq.secp256k1.Hex
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
@@ -24,6 +25,16 @@ open class Event(
|
|||||||
val content: String,
|
val content: String,
|
||||||
val sig: HexKey
|
val sig: HexKey
|
||||||
) : EventInterface {
|
) : EventInterface {
|
||||||
|
|
||||||
|
override fun countMemory(): Long {
|
||||||
|
return 12L +
|
||||||
|
id.bytesUsedInMemory() +
|
||||||
|
pubKey.bytesUsedInMemory() +
|
||||||
|
tags.sumOf { it.sumOf { it.bytesUsedInMemory() } } +
|
||||||
|
content.bytesUsedInMemory() +
|
||||||
|
sig.bytesUsedInMemory()
|
||||||
|
}
|
||||||
|
|
||||||
override fun id(): HexKey = id
|
override fun id(): HexKey = id
|
||||||
|
|
||||||
override fun pubKey(): HexKey = pubKey
|
override fun pubKey(): HexKey = pubKey
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import java.math.BigDecimal
|
|||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
interface EventInterface {
|
interface EventInterface {
|
||||||
|
fun countMemory(): Long
|
||||||
|
|
||||||
fun id(): HexKey
|
fun id(): HexKey
|
||||||
|
|
||||||
fun pubKey(): HexKey
|
fun pubKey(): HexKey
|
||||||
|
|||||||
@@ -56,9 +56,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val uri = intent?.data?.toString()
|
|
||||||
val startingPage = uriToRoute(uri)
|
|
||||||
|
|
||||||
LocalPreferences.migrateSingleUserPrefs()
|
LocalPreferences.migrateSingleUserPrefs()
|
||||||
val language = LocalPreferences.getPreferredLanguage()
|
val language = LocalPreferences.getPreferredLanguage()
|
||||||
if (language.isNotBlank()) {
|
if (language.isNotBlank()) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.components
|
package com.vitorpamplona.amethyst.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
@@ -64,19 +65,30 @@ fun RobohashFallbackAsyncImage(
|
|||||||
model = Robohash.imageRequest(context, robot)
|
model = Robohash.imageRequest(context, robot)
|
||||||
)
|
)
|
||||||
|
|
||||||
AsyncImage(
|
if (model != null) {
|
||||||
model = model,
|
AsyncImage(
|
||||||
contentDescription = contentDescription,
|
model = model,
|
||||||
modifier = modifier,
|
contentDescription = contentDescription,
|
||||||
placeholder = painter,
|
modifier = modifier,
|
||||||
fallback = painter,
|
placeholder = painter,
|
||||||
error = painter,
|
fallback = painter,
|
||||||
alignment = alignment,
|
error = painter,
|
||||||
contentScale = contentScale,
|
alignment = alignment,
|
||||||
alpha = alpha,
|
contentScale = contentScale,
|
||||||
colorFilter = colorFilter,
|
alpha = alpha,
|
||||||
filterQuality = filterQuality
|
colorFilter = colorFilter,
|
||||||
)
|
filterQuality = filterQuality
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Image(
|
||||||
|
painter = painter,
|
||||||
|
contentDescription = contentDescription,
|
||||||
|
modifier = modifier,
|
||||||
|
alignment = alignment,
|
||||||
|
contentScale = contentScale,
|
||||||
|
colorFilter = colorFilter
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ fun AppNavigation(
|
|||||||
|
|
||||||
navController: NavHostController,
|
navController: NavHostController,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
startingPage: String? = null,
|
|
||||||
themeViewModel: ThemeViewModel
|
themeViewModel: ThemeViewModel
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
@@ -250,7 +249,10 @@ fun AppNavigation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var actionableNextPage by remember { mutableStateOf(startingPage) }
|
val activity = LocalContext.current.getActivity()
|
||||||
|
var actionableNextPage by remember {
|
||||||
|
mutableStateOf(uriToRoute(activity.intent?.data?.toString()?.ifBlank { null }))
|
||||||
|
}
|
||||||
actionableNextPage?.let {
|
actionableNextPage?.let {
|
||||||
LaunchedEffect(it) {
|
LaunchedEffect(it) {
|
||||||
navController.navigate(it) {
|
navController.navigate(it) {
|
||||||
@@ -261,7 +263,6 @@ fun AppNavigation(
|
|||||||
actionableNextPage = null
|
actionableNextPage = null
|
||||||
}
|
}
|
||||||
|
|
||||||
val activity = LocalContext.current.getActivity()
|
|
||||||
DisposableEffect(navController) {
|
DisposableEffect(navController) {
|
||||||
val consumer = Consumer<Intent> { intent ->
|
val consumer = Consumer<Intent> { intent ->
|
||||||
val uri = intent?.data?.toString()
|
val uri = intent?.data?.toString()
|
||||||
|
|||||||
@@ -514,6 +514,8 @@ fun debugState(context: Context) {
|
|||||||
Log.d("STATE DUMP", "Addressables: " + LocalCache.addressables.filter { it.value.event != null }.size + "/" + LocalCache.addressables.size)
|
Log.d("STATE DUMP", "Addressables: " + LocalCache.addressables.filter { it.value.event != null }.size + "/" + LocalCache.addressables.size)
|
||||||
Log.d("STATE DUMP", "Users: " + LocalCache.users.filter { it.value.info?.latestMetadata != null }.size + "/" + LocalCache.users.size)
|
Log.d("STATE DUMP", "Users: " + LocalCache.users.filter { it.value.info?.latestMetadata != null }.size + "/" + LocalCache.users.size)
|
||||||
|
|
||||||
|
Log.d("STATE DUMP", "Memory used by Events: " + LocalCache.notes.values.sumOf { it.event?.countMemory() ?: 0 } / (1024 * 1024) + " MB")
|
||||||
|
|
||||||
LocalCache.notes.values.groupBy { it.event?.kind() }.forEach {
|
LocalCache.notes.values.groupBy { it.event?.kind() }.forEach {
|
||||||
Log.d("STATE DUMP", "Kind ${it.key}: \t${it.value.size} elements ")
|
Log.d("STATE DUMP", "Kind ${it.key}: \t${it.value.size} elements ")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -412,65 +412,97 @@ private fun ReactionDetailGallery(
|
|||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
) {
|
) {
|
||||||
val zapsState by baseNote.live().zaps.observeAsState()
|
|
||||||
val boostsState by baseNote.live().boosts.observeAsState()
|
|
||||||
val reactionsState by baseNote.live().reactions.observeAsState()
|
|
||||||
|
|
||||||
val defaultBackgroundColor = MaterialTheme.colors.background
|
val defaultBackgroundColor = MaterialTheme.colors.background
|
||||||
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
|
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
|
||||||
|
|
||||||
val hasReactions by remember(zapsState, boostsState, reactionsState) {
|
val hasReactions by baseNote.live().zaps.combineWith(
|
||||||
derivedStateOf {
|
baseNote.live().boosts,
|
||||||
baseNote.zaps.isNotEmpty() ||
|
baseNote.live().reactions
|
||||||
baseNote.boosts.isNotEmpty() ||
|
) { zapState, boostState, reactionState ->
|
||||||
baseNote.reactions.isNotEmpty()
|
zapState?.note?.zaps?.isNotEmpty() ?: false ||
|
||||||
}
|
boostState?.note?.boosts?.isNotEmpty() ?: false ||
|
||||||
}
|
reactionState?.note?.reactions?.isNotEmpty() ?: false
|
||||||
|
}.distinctUntilChanged().observeAsState(
|
||||||
|
baseNote.zaps.isNotEmpty() || baseNote.boosts.isNotEmpty() || baseNote.reactions.isNotEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
if (hasReactions) {
|
if (hasReactions) {
|
||||||
Row(verticalAlignment = CenterVertically, modifier = Modifier.padding(start = 10.dp, top = 5.dp)) {
|
Row(verticalAlignment = CenterVertically, modifier = Modifier.padding(start = 10.dp, top = 5.dp)) {
|
||||||
Column() {
|
Column() {
|
||||||
val zapEvents by remember(zapsState) { derivedStateOf { baseNote.zaps.mapNotNull { it.value?.let { zapEvent -> CombinedZap(it.key, zapEvent) } }.toImmutableList() } }
|
WatchZapAndRenderGallery(baseNote, backgroundColor, nav, accountViewModel)
|
||||||
val boostEvents by remember(boostsState) { derivedStateOf { baseNote.boosts.toImmutableList() } }
|
WatchBoostsAndRenderGallery(baseNote, nav, accountViewModel)
|
||||||
val likeEvents by remember(reactionsState) { derivedStateOf { baseNote.reactions.toImmutableMap() } }
|
WatchReactionsAndRenderGallery(baseNote, nav, accountViewModel)
|
||||||
|
|
||||||
val hasZapEvents by remember(zapsState) { derivedStateOf { baseNote.zaps.isNotEmpty() } }
|
|
||||||
val hasBoostEvents by remember(boostsState) { derivedStateOf { baseNote.boosts.isNotEmpty() } }
|
|
||||||
val hasLikeEvents by remember(reactionsState) { derivedStateOf { baseNote.reactions.isNotEmpty() } }
|
|
||||||
|
|
||||||
if (hasZapEvents) {
|
|
||||||
RenderZapGallery(
|
|
||||||
zapEvents,
|
|
||||||
backgroundColor,
|
|
||||||
nav,
|
|
||||||
accountViewModel
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasBoostEvents) {
|
|
||||||
RenderBoostGallery(
|
|
||||||
boostEvents,
|
|
||||||
nav,
|
|
||||||
accountViewModel
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasLikeEvents) {
|
|
||||||
likeEvents.forEach {
|
|
||||||
val reactions = remember(it.value) { it.value.toImmutableList() }
|
|
||||||
RenderLikeGallery(
|
|
||||||
it.key,
|
|
||||||
reactions,
|
|
||||||
nav,
|
|
||||||
accountViewModel
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun WatchBoostsAndRenderGallery(
|
||||||
|
baseNote: Note,
|
||||||
|
nav: (String) -> Unit,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
val boostsState by baseNote.live().boosts.observeAsState()
|
||||||
|
val boostsEvents by remember(boostsState) {
|
||||||
|
derivedStateOf { baseNote.boosts.toImmutableList() }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boostsEvents.isNotEmpty()) {
|
||||||
|
RenderBoostGallery(
|
||||||
|
boostsEvents,
|
||||||
|
nav,
|
||||||
|
accountViewModel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun WatchReactionsAndRenderGallery(
|
||||||
|
baseNote: Note,
|
||||||
|
nav: (String) -> Unit,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
val reactionsState by baseNote.live().reactions.observeAsState()
|
||||||
|
val reactionEvents by remember(reactionsState) {
|
||||||
|
derivedStateOf { baseNote.reactions.toImmutableMap() }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reactionEvents.isNotEmpty()) {
|
||||||
|
reactionEvents.forEach {
|
||||||
|
val reactions = remember(it.value) { it.value.toImmutableList() }
|
||||||
|
RenderLikeGallery(
|
||||||
|
it.key,
|
||||||
|
reactions,
|
||||||
|
nav,
|
||||||
|
accountViewModel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun WatchZapAndRenderGallery(
|
||||||
|
baseNote: Note,
|
||||||
|
backgroundColor: MutableState<Color>,
|
||||||
|
nav: (String) -> Unit,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
val zapsState by baseNote.live().zaps.observeAsState()
|
||||||
|
val zapEvents by remember(zapsState) {
|
||||||
|
derivedStateOf { baseNote.zaps.mapNotNull { it.value?.let { zapEvent -> CombinedZap(it.key, zapEvent) } }.toImmutableList() }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zapEvents.isNotEmpty()) {
|
||||||
|
RenderZapGallery(
|
||||||
|
zapEvents,
|
||||||
|
backgroundColor,
|
||||||
|
nav,
|
||||||
|
accountViewModel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun BoostWithDialog(
|
private fun BoostWithDialog(
|
||||||
baseNote: Note,
|
baseNote: Note,
|
||||||
|
|||||||
@@ -169,7 +169,11 @@
|
|||||||
<string name="report_hateful_speech">Signaler Discours haineux</string>
|
<string name="report_hateful_speech">Signaler Discours haineux</string>
|
||||||
<string name="report_nudity_porn">Signaler Nudité / Porno</string>
|
<string name="report_nudity_porn">Signaler Nudité / Porno</string>
|
||||||
<string name="others">autres</string>
|
<string name="others">autres</string>
|
||||||
<string name="account_backup_tips_md">
|
<string name="mark_all_known_as_read">Marquer tous les Connus comme lu</string>
|
||||||
|
<string name="mark_all_new_as_read">Marquer tous les Nouveaux comme lu</string>
|
||||||
|
<string name="mark_all_as_read">Tout marquer comme lu</string>
|
||||||
|
<string name="backup_keys">Clés de sauvegarde</string>
|
||||||
|
<string name="account_backup_tips_md" tools:ignore="Typos">
|
||||||
## Sauvegarde des clés et conseils de sécurité
|
## Sauvegarde des clés et conseils de sécurité
|
||||||
\n\nVotre compte est sécurisé par une clé secrète. La clé est une longue chaîne aléatoire commençant par **nsec1**. Toute personne ayant accès à votre clé secrète peut publier du contenu en utilisant votre identité.
|
\n\nVotre compte est sécurisé par une clé secrète. La clé est une longue chaîne aléatoire commençant par **nsec1**. Toute personne ayant accès à votre clé secrète peut publier du contenu en utilisant votre identité.
|
||||||
\n\n- Ne communiquez **jamais** votre clé secrète à un site Web ou un logiciel auquel vous ne faites pas confiance.
|
\n\n- Ne communiquez **jamais** votre clé secrète à un site Web ou un logiciel auquel vous ne faites pas confiance.
|
||||||
@@ -177,5 +181,322 @@
|
|||||||
\n- **Conservez** une sauvegarde sécurisée de votre clé secrète pour la récupération de compte. Nous vous recommandons d\'utiliser un gestionnaire de mots de passe.
|
\n- **Conservez** une sauvegarde sécurisée de votre clé secrète pour la récupération de compte. Nous vous recommandons d\'utiliser un gestionnaire de mots de passe.
|
||||||
</string>
|
</string>
|
||||||
<string name="secret_key_copied_to_clipboard">Clé secrète (nsec) copiée dans le presse-papiers</string>
|
<string name="secret_key_copied_to_clipboard">Clé secrète (nsec) copiée dans le presse-papiers</string>
|
||||||
<string name="backup_keys">Clés de sauvegarde</string>
|
<string name="copy_my_secret_key">Copier ma clé secrète</string>
|
||||||
|
<string name="biometric_authentication_failed">Échec de l'authentification</string>
|
||||||
|
<string name="biometric_error">Erreur</string>
|
||||||
|
<string name="badge_created_by">"Créé par %1$s"</string>
|
||||||
|
<string name="badge_award_image_for">"Image de badge pour %1$s"</string>
|
||||||
|
<string name="new_badge_award_notif">Vous avez reçu un nouveau Badge</string>
|
||||||
|
<string name="award_granted_to">Le Badge a été décerné à</string>
|
||||||
|
<string name="copied_note_text_to_clipboard">Copie du contenu de la note dans le presse-papiers</string>
|
||||||
|
<string name="copied_user_id_to_clipboard" tools:ignore="Typos">Copie du @npub utilisateur dans le presse-papiers</string>
|
||||||
|
<string name="copied_note_id_to_clipboard" tools:ignore="Typos">Copie de l'ID de la note (@note1) dans le presse-papiers</string>
|
||||||
|
<string name="select_text_dialog_top">Sélectionner le Texte</string>
|
||||||
|
|
||||||
|
<string name="private_conversation_notification">"<Impossible de déchiffrer le message privé>\n\nVous avez été cité dans une conversation privée/cryptée entre %1$s et %2$s."</string>
|
||||||
|
<string name="account_switch_add_account_dialog_title">Ajouter un Nouveau Compte</string>
|
||||||
|
<string name="drawer_accounts">Comptes</string>
|
||||||
|
<string name="account_switch_select_account">Sélectionner un Compte</string>
|
||||||
|
<string name="account_switch_add_account_btn">Ajouter un Nouveau Compte</string>
|
||||||
|
<string name="account_switch_active_account">Compte actif</string>
|
||||||
|
<string name="account_switch_has_private_key">Avec une clé privée</string>
|
||||||
|
<string name="account_switch_pubkey_only">Lecture seule, pas de clé privée</string>
|
||||||
|
<string name="back">Retour</string>
|
||||||
|
<string name="quick_action_select">Sélectionner</string>
|
||||||
|
<string name="quick_action_share_browser_link">Partager le Lien Navigateur</string>
|
||||||
|
<string name="quick_action_share">Partager</string>
|
||||||
|
<string name="quick_action_copy_user_id">ID Author</string>
|
||||||
|
<string name="quick_action_copy_note_id">ID Note</string>
|
||||||
|
<string name="quick_action_copy_text">Copier le Texte</string>
|
||||||
|
<string name="quick_action_delete">Supprimer</string>
|
||||||
|
<string name="quick_action_unfollow">Ne plus suivre</string>
|
||||||
|
<string name="quick_action_follow">Suivre</string>
|
||||||
|
<string name="quick_action_request_deletion_alert_title">Demande de Suppression</string>
|
||||||
|
<string name="quick_action_request_deletion_alert_body">Amethyst demandera que votre note soit supprimée des relais auxquels vous êtes actuellement connecté. Il n'y a aucune garantie que votre note sera définitivement supprimée de ces relais, ou d'autres relais où elle peut être stockée.</string>
|
||||||
|
<string name="quick_action_block_dialog_btn">Bloquer</string>
|
||||||
|
<string name="quick_action_delete_dialog_btn">Supprimer</string>
|
||||||
|
<string name="quick_action_block">Bloquer</string>
|
||||||
|
<string name="quick_action_report">Signaler</string>
|
||||||
|
<string name="quick_action_delete_button">Supprimer</string>
|
||||||
|
<string name="quick_action_dont_show_again_button">Ne plus montrer</string>
|
||||||
|
<string name="report_dialog_spam">Spam ou arnaque</string>
|
||||||
|
<string name="report_dialog_profanity">Grossièreté ou contenu haineux</string>
|
||||||
|
<string name="report_dialog_impersonation">Usurpation d'identité</string>
|
||||||
|
<string name="report_dialog_nudity">Nudité ou contenu graphique</string>
|
||||||
|
<string name="report_dialog_illegal">Comportement illégal</string>
|
||||||
|
<string name="report_dialog_blocking_a_user">Bloquer un utilisateur cachera son contenu dans votre application. Vos notes sont toujours visibles publiquement, y compris pour les personnes que vous bloquez. Les utilisateurs bloqués sont listés sur l'écran Filtres de Sécurité.</string>
|
||||||
|
<string name="report_dialog_block_hide_user_btn"><![CDATA[Bloquer et Masquer l'Utilisateur]]></string>
|
||||||
|
<string name="report_dialog_report_btn">Signaler un Abus</string>
|
||||||
|
<string name="report_dialog_reminder_public">Tous les rapports publiés seront visibles publiquement.</string>
|
||||||
|
<string name="report_dialog_additional_reason_placeholder">Fournir un contexte optionnel supplémentaire sur votre signalement...</string>
|
||||||
|
<string name="report_dialog_additional_reason_label">Contexte additionnel</string>
|
||||||
|
<string name="report_dialog_select_reason_label">Raison</string>
|
||||||
|
<string name="report_dialog_select_reason_placeholder">Sélectionner une raison...</string>
|
||||||
|
<string name="report_dialog_post_report_btn">Publier le signalement</string>
|
||||||
|
<string name="report_dialog_title">Bloquer et Signaler</string>
|
||||||
|
<string name="block_only">Bloquer</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="bookmarks">Favoris</string>
|
||||||
|
<string name="private_bookmarks">Favoris Privés</string>
|
||||||
|
<string name="public_bookmarks">Favoris Publics</string>
|
||||||
|
<string name="add_to_private_bookmarks">Ajouter aux Favoris Privés</string>
|
||||||
|
<string name="add_to_public_bookmarks">Ajouter aux Favoris Publics</string>
|
||||||
|
<string name="remove_from_private_bookmarks">Supprimer des Favoris Privés</string>
|
||||||
|
<string name="remove_from_public_bookmarks">Supprimer des Favoris Publics</string>
|
||||||
|
|
||||||
|
<string name="wallet_connect_service">Service Wallet Connect</string>
|
||||||
|
<string name="wallet_connect_service_explainer">Autorise un Nostr Secret à payer des zaps sans quitter l'application. Gardez le secret en toute sécurité et utilisez un relais privé si possible</string>
|
||||||
|
<string name="wallet_connect_service_pubkey">Wallet Connect Pubkey</string>
|
||||||
|
<string name="wallet_connect_service_relay">Wallet Connect Relay</string>
|
||||||
|
<string name="wallet_connect_service_secret">Wallet Connect Secret</string>
|
||||||
|
<string name="wallet_connect_service_show_secret">Montrer la clé secrète</string>
|
||||||
|
<string name="wallet_connect_service_secret_placeholder">Clé privée nsec / hex</string>
|
||||||
|
|
||||||
|
<string name="pledge_amount_in_sats">Montant engagé en Sats</string>
|
||||||
|
<string name="post_poll">Message Sondage</string>
|
||||||
|
<string name="poll_heading_required">Champs requis:</string>
|
||||||
|
<string name="poll_zap_recipients">Bénéficiaires du Zap</string>
|
||||||
|
<string name="poll_primary_description">Description du sondage primaire...</string>
|
||||||
|
<string name="poll_option_index">Option %s</string>
|
||||||
|
<string name="poll_option_description">Description de l'option du Sondage</string>
|
||||||
|
<string name="poll_heading_optional">Champs optionels:</string>
|
||||||
|
<string name="poll_zap_value_min">Zap minimum</string>
|
||||||
|
<string name="poll_zap_value_max">Zap maximum</string>
|
||||||
|
<string name="poll_consensus_threshold">Consensus</string>
|
||||||
|
<string name="poll_consensus_threshold_percent">(0–100)%</string>
|
||||||
|
<string name="poll_closing_time">Clôturer après</string>
|
||||||
|
<string name="poll_closing_time_days">jours</string>
|
||||||
|
<string name="poll_is_closed">Le Sondage est fermé aux nouveaux votes</string>
|
||||||
|
<string name="poll_zap_amount">Montant des Zap</string>
|
||||||
|
<string name="one_vote_per_user_on_atomic_votes">Un seul vote par utilisateur est autorisé sur ce type de sondage</string>
|
||||||
|
|
||||||
|
<string name="looking_for_event">"Recherche de l'Evénement %1$s"</string>
|
||||||
|
|
||||||
|
<string name="custom_zaps_add_a_message">Ajouter un message public</string>
|
||||||
|
<string name="custom_zaps_add_a_message_private">Ajouter un message privé</string>
|
||||||
|
<string name="custom_zaps_add_a_message_nonzap">Ajouter un message facture</string>
|
||||||
|
|
||||||
|
<string name="custom_zaps_add_a_message_example">Merci pour tout votre travail !</string>
|
||||||
|
|
||||||
|
<string name="lightning_create_and_add_invoice">Créer et Ajouter</string>
|
||||||
|
<string name="poll_author_no_vote">Les auteurs du sondage ne peuvent pas voter dans leurs propres sondages.</string>
|
||||||
|
|
||||||
|
<string name="hash_verification_passed">Ce contenu est le même depuis le message</string>
|
||||||
|
<string name="hash_verification_failed">Ce contenu a changé. L'auteur n'a peut-être pas vu ou approuvé le changement</string>
|
||||||
|
|
||||||
|
<string name="content_description_add_image">Ajouter une Image</string>
|
||||||
|
<string name="content_description_add_video">Ajouter une Vidéo</string>
|
||||||
|
<string name="content_description_add_document">Ajouter un Document</string>
|
||||||
|
|
||||||
|
<string name="add_content">Ajouter au Message</string>
|
||||||
|
<string name="content_description">Description des contenus</string>
|
||||||
|
<string name="content_description_example">Un bateau bleu sur une plage de sable blanc au coucher du soleil</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="zap_type">Type de Zap</string>
|
||||||
|
<string name="zap_type_explainer">Zap Type pour toutes les options</string>
|
||||||
|
|
||||||
|
<string name="zap_type_public">Public</string>
|
||||||
|
<string name="zap_type_public_explainer">Tout le monde peut voir la transaction et le message</string>
|
||||||
|
|
||||||
|
<string name="zap_type_private">Privé</string>
|
||||||
|
<string name="zap_type_private_explainer">L'expéditeur et le receveur peuvent se voir et lire le message</string>
|
||||||
|
|
||||||
|
<string name="zap_type_anonymous">Anonyme</string>
|
||||||
|
<string name="zap_type_anonymous_explainer">Le receveur et le public ne savent pas qui a envoyé le paiement</string>
|
||||||
|
|
||||||
|
<string name="zap_type_nonzap">Non-Zap</string>
|
||||||
|
<string name="zap_type_nonzap_explainer">Aucune trace sur Nostr, seulement sur le Lightning</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="file_server">Serveur fichier</string>
|
||||||
|
<string name="zap_forward_lnAddress">Adresse LN ou @Utilisateur</string>
|
||||||
|
|
||||||
|
<string name="upload_server_imgur">imgur.com - de confiance</string>
|
||||||
|
<string name="upload_server_imgur_explainer">Imgur peut modifier le fichier</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrimg">nostrimg.com - de confiance</string>
|
||||||
|
<string name="upload_server_nostrimg_explainer">NostrImg peut modifier le fichier</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrbuild">nostr.build - de confiance</string>
|
||||||
|
<string name="upload_server_nostrbuild_explainer">Nostr.build peut modifier le fichier</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrfilesdev">nostrfiles.dev - de confiance</string>
|
||||||
|
<string name="upload_server_nostrfilesdev_explainer">Nostrfiles.dev peut modifier le fichier</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrcheckme">nostrcheck.me - de confiance</string>
|
||||||
|
<string name="upload_server_nostrcheckme_explainer">nostrcheck.me peut modifier le fichier</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="upload_server_imgur_nip94">Verifiable Imgur (NIP-94)</string>
|
||||||
|
<string name="upload_server_imgur_nip94_explainer">Vérifie si Imgur a modifié le fichier. Nouveau NIP: certains clients pourraient ne pas le voir</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrimg_nip94">Verifiable NostrImg (NIP-94)</string>
|
||||||
|
<string name="upload_server_nostrimg_nip94_explainer">Vérifie si NostrImg a modifié le fichier. Nouveau NIP: certains clients pourraient ne pas le voir</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrbuild_nip94">Verifiable Nostr.build (NIP-94)</string>
|
||||||
|
<string name="upload_server_nostrbuild_nip94_explainer">Vérifie si Nostr.build a modifié le fichier. Nouveau NIP: certains clients pourraient ne pas le voir</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrfilesdev_nip94">Verifiable Nostrfiles.dev (NIP-94)</string>
|
||||||
|
<string name="upload_server_nostrfilesdev_nip94_explainer">Vérifie si Nostrfiles.dev a modifié le fichier. Nouveau NIP: certains clients pourraient ne pas le voir</string>
|
||||||
|
|
||||||
|
<string name="upload_server_nostrcheckme_nip94">Verifiable Nostrcheck.me (NIP-94)</string>
|
||||||
|
<string name="upload_server_nostrcheckme_nip94_explainer">Vérifie si Nostrcheck.me a modifié le fichier. Nouveau NIP: certains clients pourraient ne pas le voir</string>
|
||||||
|
|
||||||
|
<string name="upload_server_relays_nip95">Vos relais (NIP-95)</string>
|
||||||
|
<string name="upload_server_relays_nip95_explainer">Les fichiers sont hébergés par vos relais. Nouveau NIP: vérifiez s'ils sont supportés</string>
|
||||||
|
|
||||||
|
<string name="connect_via_tor_short">Configuration Tor/Orbot</string>
|
||||||
|
<string name="connect_via_tor">Se connecter à travers la configuration Orbot</string>
|
||||||
|
|
||||||
|
<string name="do_you_really_want_to_disable_tor_title">Se déconnecter de Orbot/Tor?</string>
|
||||||
|
<string name="do_you_really_want_to_disable_tor_text">Vos données seront immédiatement transférées sur le réseau classique</string>
|
||||||
|
<string name="yes">Oui</string>
|
||||||
|
<string name="no">Non</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="follow_list_selection">Liste des Abonnés</string>
|
||||||
|
<string name="follow_list_kind3follows">Tous les abonnements</string>
|
||||||
|
<string name="follow_list_global">Global</string>
|
||||||
|
<string name="connect_through_your_orbot_setup_markdown">
|
||||||
|
## Se connecter à travers Tor avec Orbot
|
||||||
|
\n\n1. Installe [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)
|
||||||
|
\n2. Démarre Orbot
|
||||||
|
\n3. Dans Orbot, vérifie le port Socks. Par défaut 9050
|
||||||
|
\n4. Si nécessaire change le port dans Orbot
|
||||||
|
\n5. Configure le port Socks sur cet écran
|
||||||
|
\n6. Appuyer sur le bouton Activer pour utiliser Orbot comme proxy
|
||||||
|
</string>
|
||||||
|
<string name="orbot_socks_port">Port Socks Orbot</string>
|
||||||
|
<string name="invalid_port_number">Numéro de port invalide</string>
|
||||||
|
<string name="use_orbot">Utiliser Orbot</string>
|
||||||
|
<string name="disconnect_from_your_orbot_setup">Déconnecter Tor/Orbot</string>
|
||||||
|
|
||||||
|
<string name="app_notification_dms_channel_name">Messages privés</string>
|
||||||
|
<string name="app_notification_dms_channel_description">Vous notifie lorsqu'un message privé est reçu</string>
|
||||||
|
|
||||||
|
<string name="app_notification_zaps_channel_name">Zaps reçus</string>
|
||||||
|
<string name="app_notification_zaps_channel_description">Vous notifie lorsque quelqu'un vous zap</string>
|
||||||
|
<string name="app_notification_zaps_channel_message">%1$s sats</string>
|
||||||
|
<string name="app_notification_zaps_channel_message_from">De %1$s</string>
|
||||||
|
<string name="app_notification_zaps_channel_message_for">pour %1$s</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="reply_notify">Notifier: </string>
|
||||||
|
|
||||||
|
<string name="channel_list_join_conversation">Rejoindre Conversation</string>
|
||||||
|
<string name="channel_list_user_or_group_id">Utilisateur ou Groupe ID</string>
|
||||||
|
<string name="channel_list_user_or_group_id_demo">npub, nevent ou hex</string>
|
||||||
|
<string name="channel_list_create_channel">Créer</string>
|
||||||
|
<string name="channel_list_join_channel">Rejoindre</string>
|
||||||
|
|
||||||
|
<string name="today">Aujourd'hui</string>
|
||||||
|
|
||||||
|
<string name="content_warning">Avertissement de contenu</string>
|
||||||
|
<string name="content_warning_explanation">Ce message contient du contenu sensible que certaines personnes peuvent trouver offensant ou dérangeant</string>
|
||||||
|
<string name="content_warning_hide_all_sensitive_content">Toujours cacher les contenus sensibles</string>
|
||||||
|
<string name="content_warning_show_all_sensitive_content">Toujours afficher les contenus sensibles</string>
|
||||||
|
<string name="content_warning_see_warnings">Toujours afficher les avertissements de contenu</string>
|
||||||
|
|
||||||
|
<string name="recommended_apps">Recommendations: </string>
|
||||||
|
<string name="filter_spam_from_strangers">Filtrer le spam des étrangers</string>
|
||||||
|
<string name="warn_when_posts_have_reports_from_your_follows">Avertir lorsque les messages ont été rapportés par vos abonnés</string>
|
||||||
|
|
||||||
|
<string name="new_reaction_symbol">Nouveau symbole de réaction</string>
|
||||||
|
<string name="no_reaction_type_setup_long_press_to_change">Aucun type de réaction sélectionné. Appuyer longuement pour changer</string>
|
||||||
|
|
||||||
|
<string name="zapraiser">Zapraiser</string>
|
||||||
|
<string name="zapraiser_explainer">Ajoute une quantité cible de sats pour ce message. Les clients compatible peuvent afficher une barre de progrès pour encourager les dons</string>
|
||||||
|
<string name="zapraiser_target_amount_in_sats">Quantité ciblée en Sats</string>
|
||||||
|
|
||||||
|
<string name="sats_to_complete">Zapraiser à %1$s. %2$s sats pour objectif</string>
|
||||||
|
<string name="read_from_relay">Lire depuis le Relay</string>
|
||||||
|
<string name="write_to_relay">Écrire sur le Relay</string>
|
||||||
|
<string name="an_error_occurred_trying_to_get_relay_information">Une erreur s'est produite en récupérant les informations du relay depuis %1$s</string>
|
||||||
|
<string name="owner">Propriétaire</string>
|
||||||
|
<string name="version">Version</string>
|
||||||
|
<string name="software">Logiciel</string>
|
||||||
|
<string name="contact">Contact</string>
|
||||||
|
<string name="supports">NIPs supportés</string>
|
||||||
|
<string name="admission_fees">Frais d'admission</string>
|
||||||
|
<string name="payments_url">URL de payments</string>
|
||||||
|
<string name="limitations">Limitations</string>
|
||||||
|
<string name="countries">Pays</string>
|
||||||
|
<string name="languages">Langages</string>
|
||||||
|
<string name="tags">Tags</string>
|
||||||
|
<string name="posting_policy">Politique de publication</string>
|
||||||
|
<string name="message_length">Longueur du message</string>
|
||||||
|
<string name="subscriptions">Abonnements</string>
|
||||||
|
<string name="filters">Filtres</string>
|
||||||
|
<string name="subscription_id_length">Longueur de l'id de souscription</string>
|
||||||
|
<string name="minimum_prefix">Préfixe minimum</string>
|
||||||
|
<string name="maximum_event_tags">Tags d'événement maximum</string>
|
||||||
|
<string name="content_length">Longueur du contenu</string>
|
||||||
|
<string name="minimum_pow">PoW minimum</string>
|
||||||
|
<string name="auth">Authentification</string>
|
||||||
|
<string name="payment">Paiement</string>
|
||||||
|
<string name="cashu">Jeton Cashu</string>
|
||||||
|
<string name="cashu_redeem">Échanger</string>
|
||||||
|
<string name="no_lightning_address_set">Adresse Lightning non définie</string>
|
||||||
|
<string name="copied_token_to_clipboard">Jeton copié dans le presse-papiers</string>
|
||||||
|
|
||||||
|
<string name="live_stream_live_tag">EN DIRECT</string>
|
||||||
|
<string name="live_stream_offline_tag">DÉCONNECTÉ</string>
|
||||||
|
<string name="live_stream_ended_tag">TERMINÉ</string>
|
||||||
|
<string name="live_stream_planned_tag">PLANIFIÉ</string>
|
||||||
|
|
||||||
|
<string name="live_stream_is_offline">Livestream est déconnecté</string>
|
||||||
|
<string name="live_stream_has_ended">Livestream terminé</string>
|
||||||
|
<string name="are_you_sure_you_want_to_log_out">Se déconnecter supprime toutes vos informations locales. Assurez-vous d'avoir vos clés privées sauvegardées pour éviter de perdre votre compte. Voulez-vous continuer ?</string>
|
||||||
|
<string name="followed_tags">Tags suivis</string>
|
||||||
|
|
||||||
|
<string name="relay_setup">Relays</string>
|
||||||
|
|
||||||
|
<string name="discover_live">Direct</string>
|
||||||
|
<string name="discover_community">Communauté</string>
|
||||||
|
<string name="discover_chat">Chats</string>
|
||||||
|
<string name="community_approved_posts">Messages approuvés</string>
|
||||||
|
|
||||||
|
<string name="groups_no_descriptor">Ce groupe n'a pas de description ou de règles. Parlez au propriétaire pour en ajouter une</string>
|
||||||
|
<string name="community_no_descriptor">Cette communauté n'a pas de description. Parlez au propriétaire pour en ajouter une</string>
|
||||||
|
|
||||||
|
<string name="add_sensitive_content_label">Contenu sensible</string>
|
||||||
|
<string name="add_sensitive_content_description">Ajouter un avertissement de contenu sensible avant de montrer ce contenu</string>
|
||||||
|
<string name="settings">Paramètres</string>
|
||||||
|
<string name="connectivity_type_always">Toujours</string>
|
||||||
|
<string name="connectivity_type_wifi_only">Wifi uniquement</string>
|
||||||
|
<string name="connectivity_type_never">Jamais</string>
|
||||||
|
|
||||||
|
<string name="system">Système</string>
|
||||||
|
<string name="light">Clair</string>
|
||||||
|
<string name="dark">Sombre</string>
|
||||||
|
<string name="application_preferences">Préférences de l'application</string>
|
||||||
|
<string name="language">Langage</string>
|
||||||
|
<string name="theme">Thème</string>
|
||||||
|
<string name="automatically_load_images_gifs">Chargement automatique des images/gifs</string>
|
||||||
|
<string name="automatically_play_videos">Démarrage automatique des vidéos</string>
|
||||||
|
<string name="automatically_show_url_preview">Prévisualisation automatique des liens</string>
|
||||||
|
<string name="load_image">Charger l'image</string>
|
||||||
|
|
||||||
|
<string name="spamming_users">Spammeurs</string>
|
||||||
|
|
||||||
|
<string name="muted_button">Silencieux. Cliquer pour réactiver le son</string>
|
||||||
|
<string name="mute_button">Son activé. Cliquer pour mettre en silencieux</string>
|
||||||
|
<string name="search_button">Recherche d'enregistrements locaux et distants</string>
|
||||||
|
|
||||||
|
<string name="nip05_verified">L'adresse Nostr a été vérfiée</string>
|
||||||
|
<string name="nip05_failed">La vérification de l'adresse Nostr a échouée</string>
|
||||||
|
<string name="nip05_checking">Vérification de l'adresse Nostr</string>
|
||||||
|
<string name="select_deselect_all">Tout sélectionner/désélectionner</string>
|
||||||
|
<string name="default_relays">Défaut</string>
|
||||||
|
<string name="select_a_relay_to_continue">Sélectionner un relay pour continuer</string>
|
||||||
|
|
||||||
|
<string name="zap_forward_title">Transférer les Zaps à:</string>
|
||||||
|
<string name="zap_forward_explainer">Les clients compatibles transmettront des zaps sur l'adresse LN ou le profil Utilisateur ci-dessous au lieu du vôtre.</string>
|
||||||
|
|
||||||
|
<string name="geohash_title">Révéler la localisation comme </string>
|
||||||
|
<string name="geohash_explainer">Ajoute un Geohash de votre emplacement au message. Le public saura que vous êtes à moins de 5km de l'emplacement actuel</string>
|
||||||
|
|
||||||
|
<string name="add_sensitive_content_explainer">Ajoute un avertissement de contenu sensible avant de montrer votre contenu. C'est idéal pour tout contenu NSFW ou contenu que certaines personnes peuvent trouver offensant ou dérangeant</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user