Merge branch 'master' into chat-relays

This commit is contained in:
spaced4ndy
2026-03-30 12:33:20 +04:00
64 changed files with 3174 additions and 230 deletions
@@ -772,7 +772,9 @@ fun ChatView(
changeNtfsState = { enabled, currentValue -> toggleNotifications(chatRh, chatInfo, enabled, chatModel, currentValue) },
onSearchValueChanged = onSearchValueChanged,
closeSearch = {
onSearchValueChanged("")
if (chatModel.openAroundItemId.value == null) {
onSearchValueChanged("")
}
showSearch.value = false
searchText.value = ""
contentFilter.value = null
@@ -993,7 +995,7 @@ fun ChatLayout(
useLinkPreviews, linkMode, scrollToItemId, selectedChatItems, showMemberInfo, showChatInfo = info, loadMessages, deleteMessage, deleteMessages, archiveReports,
receiveFile, cancelFile, joinGroup, acceptCall, acceptFeature, openDirectChat, forwardItem,
updateContactStats, updateMemberStats, syncContactConnection, syncMemberConnection, findModelChat, findModelMember,
setReaction, showItemDetails, markItemsRead, markChatRead, closeSearch, remember { { onComposed(it) } }, developerTools, showViaProxy,
setReaction, showItemDetails, markItemsRead, markChatRead, closeSearch, remember { { onComposed(it) } }, developerTools, showViaProxy, contentFilter,
)
}
if (chatInfo is ChatInfo.Group && composeState.value.message.text.isNotEmpty()) {
@@ -1168,6 +1170,7 @@ fun BoxScope.ChatInfoToolbar(
val scope = rememberCoroutineScope()
val showMenu = rememberSaveable { mutableStateOf(false) }
val showContentFilterMenu = rememberSaveable { mutableStateOf(false) }
val showCallMenu = rememberSaveable { mutableStateOf(false) }
val onBackClicked = {
if (!showSearch.value) {
@@ -1186,35 +1189,28 @@ fun BoxScope.ChatInfoToolbar(
val activeCall by remember { chatModel.activeCall }
val showContentFilterButton = availableContent.value.isNotEmpty()
val activeCallInChat = chatInfo is ChatInfo.Direct && activeCall?.contact?.id == chatInfo.id
val canStartCall = chatInfo is ChatInfo.Direct &&
chatInfo.contact.mergedPreferences.calls.enabled.forUser &&
chatInfo.contact.ready &&
chatInfo.contact.active &&
activeCall == null
// Content filter button - shown in bar, or moved to menu during active call
if (showContentFilterButton) {
// Content filter button: always in bar on desktop and for groups; on Android for direct chats it
// goes into the three-dots menu UNLESS calls are unavailable, in which case it appears in the bar
if (showContentFilterButton && (appPlatform.isDesktop || chatInfo is ChatInfo.Group ||
(appPlatform.isAndroid && chatInfo is ChatInfo.Direct && !canStartCall && activeCall == null))) {
val enabled = chatInfo !is ChatInfo.Local || chatInfo.noteFolder.ready
if (activeCallInChat) {
menuItems.add {
ItemAction(
stringResource(MR.strings.content_filter_menu_item),
barButtons.add {
IconButton(
{ showContentFilterMenu.value = true },
enabled = enabled
) {
Icon(
painterResource(MR.images.ic_photo_library),
onClick = {
showMenu.value = false
showContentFilterMenu.value = true
}
null,
tint = MaterialTheme.colors.primary
)
}
} else {
barButtons.add {
IconButton(
{ showContentFilterMenu.value = true },
enabled = enabled
) {
Icon(
painterResource(MR.images.ic_photo_library),
null,
tint = MaterialTheme.colors.primary
)
}
}
}
}
@@ -1268,19 +1264,12 @@ fun BoxScope.ChatInfoToolbar(
}
}
}
// Call buttons moved to menu
if (chatInfo.contact.mergedPreferences.calls.enabled.forUser && chatInfo.contact.ready && chatInfo.contact.active && activeCall == null) {
menuItems.add {
ItemAction(stringResource(MR.strings.icon_descr_audio_call).capitalize(Locale.current), painterResource(MR.images.ic_call_500), onClick = {
showMenu.value = false
startCall(CallMediaType.Audio)
})
}
menuItems.add {
ItemAction(stringResource(MR.strings.icon_descr_video_call).capitalize(Locale.current), painterResource(MR.images.ic_videocam), onClick = {
showMenu.value = false
startCall(CallMediaType.Video)
})
// Call button always in toolbar; tap opens Audio/Video call submenu
if (canStartCall) {
barButtons.add(0) {
IconButton({ showCallMenu.value = true }) {
Icon(painterResource(MR.images.ic_call_500), null, tint = MaterialTheme.colors.primary)
}
}
}
menuItems.add {
@@ -1339,6 +1328,53 @@ fun BoxScope.ChatInfoToolbar(
}
}
// Android only: for direct/local chats where the filter bar button is NOT shown, filter options go in the three-dots menu separated by a divider
if (appPlatform.isAndroid && chatInfo !is ChatInfo.Group && showContentFilterButton &&
!(chatInfo is ChatInfo.Direct && !canStartCall && activeCall == null)) {
menuItems.add { Divider() }
availableContent.value.forEach { filter ->
menuItems.add {
val isSelected = contentFilter.value == filter
ItemAction(
stringResource(filter.label),
painterResource(if (isSelected) filter.iconFilled else filter.icon),
color = if (isSelected) MaterialTheme.colors.primary else Color.Unspecified,
onClick = {
showMenu.value = false
if (contentFilter.value == filter) return@ItemAction
contentFilter.value = filter
showSearch.value = true
scope.launch {
val c = chatModel.getChat(chatInfo.id)
if (c != null) {
apiFindMessages(chatsCtx, c, filter.contentTag, "")
}
}
}
)
}
}
if (showSearch.value) {
menuItems.add {
ItemAction(
stringResource(MR.strings.content_filter_all_messages),
painterResource(MR.images.ic_forum),
onClick = {
showMenu.value = false
contentFilter.value = null
showSearch.value = false
scope.launch {
val c = chatModel.getChat(chatInfo.id)
if (c != null) {
apiFindMessages(chatsCtx, c, null, "")
}
}
}
)
}
}
}
if (menuItems.isNotEmpty()) {
barButtons.add {
IconButton({ showMenu.value = true }) {
@@ -1448,6 +1484,38 @@ fun BoxScope.ChatInfoToolbar(
contentFilterMenuItems.forEach { it() }
}
}
val callMenuWidth = remember { mutableStateOf(250.dp) }
val callMenuHeight = remember { mutableStateOf(0.dp) }
DefaultDropdownMenu(
showCallMenu,
modifier = Modifier.onSizeChanged { with(density) {
callMenuWidth.value = it.width.toDp().coerceAtLeast(250.dp)
if (oneHandUI.value && chatBottomBar.value && (appPlatform.isDesktop || (platform.androidApiLevel ?: 0) >= 30)) callMenuHeight.value = it.height.toDp()
} },
offset = DpOffset(-callMenuWidth.value, if (oneHandUI.value && chatBottomBar.value) -callMenuHeight.value else AppBarHeight)
) {
if (chatInfo is ChatInfo.Direct) {
val callMenuItems: List<@Composable () -> Unit> = buildList {
add {
ItemAction(stringResource(MR.strings.icon_descr_audio_call).capitalize(Locale.current), painterResource(MR.images.ic_call_500), onClick = {
showCallMenu.value = false
startCall(CallMediaType.Audio)
})
}
add {
ItemAction(stringResource(MR.strings.icon_descr_video_call).capitalize(Locale.current), painterResource(MR.images.ic_videocam), onClick = {
showCallMenu.value = false
startCall(CallMediaType.Video)
})
}
}
if (oneHandUI.value && chatBottomBar.value) {
callMenuItems.asReversed().forEach { it() }
} else {
callMenuItems.forEach { it() }
}
}
}
}
}
@@ -1667,7 +1735,8 @@ fun BoxScope.ChatItemsList(
closeSearch: () -> Unit,
onComposed: suspend (chatId: String) -> Unit,
developerTools: Boolean,
showViaProxy: Boolean
showViaProxy: Boolean,
contentFilter: State<ContentFilter?> = remember { mutableStateOf(null) }
) {
val chatInfo = chat.chatInfo
val loadingTopItems = remember { mutableStateOf(false) }
@@ -1687,7 +1756,7 @@ fun BoxScope.ChatItemsList(
}
}
val searchValueIsEmpty = remember { derivedStateOf { searchValue.value.isEmpty() } }
val searchValueIsNotBlank = remember { derivedStateOf { searchValue.value.isNotBlank() } }
val searchValueIsNotBlank = remember { derivedStateOf { searchValue.value.isNotBlank() || contentFilter.value != null } }
val revealedItems = rememberSaveable(stateSaver = serializableSaver()) { mutableStateOf(setOf<Long>()) }
// not using reversedChatItems inside to prevent possible derivedState bug in Compose when one derived state access can cause crash asking another derived state
val mergedItems = remember {
@@ -1722,7 +1791,17 @@ fun BoxScope.ChatItemsList(
val hoveredItemId = remember { mutableStateOf(null as Long?) }
val listState = rememberUpdatedState(rememberSaveable(chatInfo.id, searchValueIsEmpty.value, resetListState.value, saver = LazyListState.Saver) {
val openAroundItemId = chatModel.openAroundItemId.value
val index = mergedItems.value.indexInParentItems[openAroundItemId] ?: mergedItems.value.items.indexOfLast { it.hasUnread() }
val index = mergedItems.value.indexInParentItems[openAroundItemId] ?: run {
// scroll to first unread after last viewed item (items reversed: 0 = newest)
val viewedIdx = mergedItems.value.items.indexOfFirst { !it.hasUnread() }
if (viewedIdx > 0) {
viewedIdx - 1
} else if (viewedIdx < 0) {
mergedItems.value.items.indexOfLast { it.hasUnread() }
} else {
0 // viewed is bottom item, scroll to bottom
}
}
val reportsState = reportsListState
if (openAroundItemId != null) {
highlightedItems.value += openAroundItemId
@@ -1818,7 +1897,7 @@ fun BoxScope.ChatItemsList(
}
@Composable
fun ChatItemViewShortHand(cItem: ChatItem, itemSeparation: ItemSeparation, range: State<IntRange?>, fillMaxWidth: Boolean = true) {
fun ChatItemViewShortHand(cItem: ChatItem, itemSeparation: ItemSeparation, range: State<IntRange?>, fillMaxWidth: Boolean = true, swipeOffset: Float = 0f) {
tryOrShowError("${cItem.id}ChatItem", error = {
CIBrokenComposableView(if (cItem.chatDir.sent) Alignment.CenterEnd else Alignment.CenterStart)
}) {
@@ -1832,7 +1911,7 @@ fun BoxScope.ChatItemsList(
highlightedItems.value = setOf()
}
}
ChatItemView(chatsCtx, remoteHostId, chat, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, highlighted = highlighted, hoveredItemId = hoveredItemId, range = range, searchIsNotBlank = searchValueIsNotBlank, fillMaxWidth = fillMaxWidth, selectedChatItems = selectedChatItems, selectChatItem = { selectUnselectChatItem(true, cItem, revealed, selectedChatItems, reversedChatItems) }, deleteMessage = deleteMessage, deleteMessages = deleteMessages, archiveReports = archiveReports, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, forwardItem = forwardItem, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, scrollToItemId = scrollToItemId, scrollToQuotedItemFromItem = scrollToQuotedItemFromItem, setReaction = setReaction, showItemDetails = showItemDetails, reveal = reveal, showMemberInfo = showMemberInfo, showChatInfo = showChatInfo, developerTools = developerTools, showViaProxy = showViaProxy, itemSeparation = itemSeparation, showTimestamp = itemSeparation.timestamp)
ChatItemView(chatsCtx, remoteHostId, chat, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, highlighted = highlighted, hoveredItemId = hoveredItemId, range = range, searchIsNotBlank = searchValueIsNotBlank, fillMaxWidth = fillMaxWidth, selectedChatItems = selectedChatItems, selectChatItem = { selectUnselectChatItem(true, cItem, revealed, selectedChatItems, reversedChatItems) }, deleteMessage = deleteMessage, deleteMessages = deleteMessages, archiveReports = archiveReports, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, forwardItem = forwardItem, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, scrollToItemId = scrollToItemId, scrollToQuotedItemFromItem = scrollToQuotedItemFromItem, setReaction = setReaction, showItemDetails = showItemDetails, reveal = reveal, showMemberInfo = showMemberInfo, showChatInfo = showChatInfo, developerTools = developerTools, showViaProxy = showViaProxy, itemSeparation = itemSeparation, showTimestamp = itemSeparation.timestamp, swipeOffset = swipeOffset)
}
}
@@ -1953,7 +2032,7 @@ fun BoxScope.ChatItemsList(
MemberImage(member)
}
Box(modifier = Modifier.padding(top = 2.dp, start = 4.dp).chatItemOffset(cItem, itemSeparation.largeGap, revealed = revealed.value)) {
ChatItemViewShortHand(cItem, itemSeparation, range, false)
ChatItemViewShortHand(cItem, itemSeparation, range, false, dismissState.offset.value)
}
}
}
@@ -1978,7 +2057,7 @@ fun BoxScope.ChatItemsList(
.chatItemOffset(cItem, itemSeparation.largeGap, revealed = revealed.value)
.then(swipeableOrSelectionModifier)
) {
ChatItemViewShortHand(cItem, itemSeparation, range)
ChatItemViewShortHand(cItem, itemSeparation, range, swipeOffset = dismissState.offset.value)
}
}
}
@@ -2076,7 +2155,7 @@ fun BoxScope.ChatItemsList(
.chatItemOffset(cItem, itemSeparation.largeGap, revealed = revealed.value)
.then(if (selectionVisible) Modifier else swipeableModifier)
) {
ChatItemViewShortHand(cItem, itemSeparation, range)
ChatItemViewShortHand(cItem, itemSeparation, range, swipeOffset = dismissState.offset.value)
}
}
}
@@ -2094,7 +2173,7 @@ fun BoxScope.ChatItemsList(
.chatItemOffset(cItem, itemSeparation.largeGap, revealed = revealed.value)
.then(if (!selectionVisible || !sent) swipeableOrSelectionModifier else Modifier)
) {
ChatItemViewShortHand(cItem, itemSeparation, range)
ChatItemViewShortHand(cItem, itemSeparation, range, swipeOffset = dismissState.offset.value)
}
}
}
@@ -10,6 +10,7 @@ import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.*
import androidx.compose.ui.graphics.*
@@ -109,6 +110,7 @@ fun ChatItemView(
showTimestamp: Boolean,
itemSeparation: ItemSeparation,
preview: Boolean = false,
swipeOffset: Float = 0f,
) {
val cInfo = chat.chatInfo
val uriHandler = LocalUriHandler.current
@@ -298,8 +300,11 @@ fun ChatItemView(
}
Column(horizontalAlignment = if (cItem.chatDir.sent) Alignment.End else Alignment.Start) {
Row(verticalAlignment = Alignment.CenterVertically) {
val bubbleInteractionSource = remember { MutableInteractionSource() }
val canReply = (cItem.content is CIContent.SndMsgContent || cItem.content is CIContent.RcvMsgContent) &&
cInfo !is ChatInfo.Local && !cItem.isReport && !cItem.meta.isLive && cItem.meta.itemDeleted == null
Box {
Row(verticalAlignment = Alignment.CenterVertically) {
val bubbleInteractionSource = remember { MutableInteractionSource() }
val bubbleHovered = bubbleInteractionSource.collectIsHoveredAsState()
if (cItem.chatDir.sent) {
GoToItemButton(true, bubbleHovered)
@@ -800,6 +805,15 @@ fun ChatItemView(
if (!cItem.chatDir.sent) {
GoToItemButton(false, bubbleHovered)
}
}
if (canReply && swipeOffset < 0) {
Icon(
painterResource(MR.images.ic_reply),
contentDescription = null,
modifier = Modifier.align(Alignment.CenterEnd).offset(x = 26.dp).size(18.dp).alpha(minOf(1f, -swipeOffset / 30f)),
tint = MaterialTheme.colors.secondary
)
}
}
if (cItem.content.msgContent != null && (cItem.meta.itemDeleted == null || revealed.value) && cItem.reactions.isNotEmpty()) {
ChatItemReactions()
@@ -2527,4 +2527,18 @@
<string name="delete_member_messages_confirmation">احذف الرسائل</string>
<string name="member_messages_will_be_deleted_cannot_be_undone">ستُحذف رسائل العضو - ولا يمكن التراجع عن ذلك!</string>
<string name="remove_member_delete_messages_confirmation">أزل واحذف الرسائل</string>
<string name="content_filter_all_messages">كل الرسائل</string>
<string name="info_row_connection_failed">فشل الاتصال</string>
<string name="member_info_member_failed">فشل</string>
<string name="content_filter_files">ملفات</string>
<string name="content_filter_menu_item">تصفية</string>
<string name="content_filter_images">صور</string>
<string name="content_filter_links">روابط</string>
<string name="placeholder_search_files">ابحث عن ملفات</string>
<string name="placeholder_search_images">ابحث عن صور</string>
<string name="placeholder_search_links">ابحث عن روابط</string>
<string name="placeholder_search_videos">ابحث عن فيديوهات</string>
<string name="placeholder_search_voice_messages">ابحث عن رسائل صوتية</string>
<string name="content_filter_videos">فيديوهات</string>
<string name="content_filter_voice_messages">رسائل صوتية</string>
</resources>
@@ -2213,7 +2213,7 @@
<string name="temporary_file_error">Chyba dočasného souboru</string>
<string name="servers_info_transport_sessions_section_header">Přesunout sezení</string>
<string name="network_option_tcp_connection">TCP připojení</string>
<string name="operator_use_operator_toggle_description">Použité servery</string>
<string name="operator_use_operator_toggle_description">Použít servery</string>
<string name="use_servers_of_operator_x">Použit %s</string>
<string name="operator_use_for_messages_receiving">Pro příjem</string>
<string name="color_mode_system">Systém</string>
@@ -2517,7 +2517,7 @@
<string name="cant_send_commands_alert_text">Pro odeslání příkazů musíte být připojen.</string>
<string name="context_user_picker_cant_change_profile_alert_message">Pro použití jiného profilu po pokusu o připojení, smažte chat a znovu použijte odkaz.</string>
<string name="v6_4_1_short_address_update">Aktualizovat vaši adresu</string>
<string name="share_profile_via_link_alert_confirm">Povýšení</string>
<string name="share_profile_via_link_alert_confirm">Povýšit</string>
<string name="share_profile_via_link">Povýšit adresu?</string>
<string name="upgrade_group_link">Povýšit odkaz skupiny</string>
<string name="share_group_profile_via_link">Povýšit odkaz skupiny?</string>
@@ -2528,4 +2528,26 @@
<string name="chat_banner_your_contact">Váš kontakt</string>
<string name="chat_banner_your_group">Vaše skupina</string>
<string name="context_user_picker_your_profile">Váš profil</string>
<string name="content_filter_all_messages">Všechny zprávy</string>
<string name="button_delete_member_messages">Smazat zprávy člena</string>
<string name="button_delete_member_messages_question">Smazat zprávy člena?</string>
<string name="delete_member_messages_confirmation">Smazat zprávy</string>
<string name="content_filter_files">Soubory</string>
<string name="content_filter_menu_item">Filtr</string>
<string name="content_filter_images">Obrázky</string>
<string name="content_filter_links">Odkazy</string>
<string name="member_messages_will_be_deleted_cannot_be_undone">Zprávy člena budou smazány - nemůže být zrušeno!</string>
<string name="server_no_sub">bez předplatného</string>
<string name="remove_member_delete_messages_confirmation">Odebrat a smazat zprávy</string>
<string name="placeholder_search_files">Hledat soubory</string>
<string name="placeholder_search_images">Hledat obrázky</string>
<string name="placeholder_search_links">Hledat odkazy</string>
<string name="placeholder_search_videos">Hledat videa</string>
<string name="placeholder_search_voice_messages">Hledat hlasové zprávy</string>
<string name="content_filter_videos">Videa</string>
<string name="content_filter_voice_messages">Hlasové zprávy</string>
<string name="not_connected_to_server_to_receive_messages_no_sub">Nejste připojen k serveru, který se používá k přijímání zpráv z tohoto připojení (bez předplatného).</string>
<string name="info_row_connection_failed">Připojení selhalo</string>
<string name="member_info_member_failed">selhal</string>
<string name="down_migration_warning_chat_relays">Pokud jste se připojili k nějakým kanálům nebo je vytvořili, přestanou trvale fungovat.</string>
</resources>
@@ -2629,4 +2629,7 @@
<string name="placeholder_search_voice_messages">Sprachnachrichten suchen</string>
<string name="content_filter_videos">Videos</string>
<string name="content_filter_voice_messages">Sprachnachrichten</string>
<string name="info_row_connection_failed">Verbindung fehlgeschlagen</string>
<string name="member_info_member_failed">Fehlgeschlagen</string>
<string name="down_migration_warning_chat_relays">Kanäle, welche Sie erstellt haben oder denen Sie beigetreten sind, werden dauerhaft deaktiviert.</string>
</resources>
@@ -2521,4 +2521,7 @@
<string name="placeholder_search_voice_messages">Αναζήτηση φωνητικών μηνυμάτων</string>
<string name="content_filter_videos">Βίντεο</string>
<string name="content_filter_voice_messages">Φωνητικά μηνύματα</string>
<string name="info_row_connection_failed">Η σύνδεση απέτυχε</string>
<string name="member_info_member_failed">απέτυχε</string>
<string name="down_migration_warning_chat_relays">Αν έχετε συμμετάσχει ή δημιουργήσει κανάλια, θα σταματήσουν να λειτουργούν μόνιμα.</string>
</resources>
@@ -233,7 +233,7 @@
<string name="receipts_section_contacts">Partnerek</string>
<string name="connection_error">Kapcsolódási hiba</string>
<string name="alert_title_contact_connection_pending">A partnere még nem kapcsolódott!</string>
<string name="v5_3_discover_join_groups_descr">- kapcsolódás könyvtár szolgáltatáshoz (BÉTA)!\n- kézbesítési jelentések (legfeljebb 20 tagig).\n- gyorsabb és stabilabb.</string>
<string name="v5_3_discover_join_groups_descr">- kapcsolódás a könyvtárszolgáltatáshoz (BÉTA)!\n- kézbesítési jelentések (legfeljebb 20 tagig).\n- gyorsabb és stabilabb.</string>
<string name="contribute">Közreműködés</string>
<string name="group_member_status_intro_invitation">kapcsolódás (bemutatkozó meghívó)</string>
<string name="create_simplex_address">SimpleX-cím létrehozása</string>
@@ -299,7 +299,7 @@
<string name="display_name_connecting">kapcsolódás…</string>
<string name="icon_descr_call_connecting">Hívás kapcsolása</string>
<string name="delete_files_and_media_question">Törli a fájlokat és a médiatartalmakat?</string>
<string name="group_member_status_complete">befejezett</string>
<string name="group_member_status_complete">kész</string>
<string name="chat_database_section">CSEVEGÉSI ADATBÁZIS</string>
<string name="change_self_destruct_passcode">Önmegsemmisítő jelkód módosítása</string>
<string name="smp_server_test_create_queue">Várólista létrehozása</string>
@@ -1392,7 +1392,7 @@
<string name="you_can_start_chat_via_setting_or_by_restarting_the_app">A csevegés elindítható az alkalmazás „Beállítások / Adatbázis” menüjében vagy az alkalmazás újraindításával.</string>
<string name="verify_code_on_mobile">Kód ellenőrzése a hordozható eszközön</string>
<string name="youve_accepted_group_invitation_connecting_to_inviting_group_member">Ön csatlakozott ehhez a csoporthoz. Kapcsolódás a meghívó csoporttaghoz.</string>
<string name="you_can_connect_to_simplex_chat_founder"><![CDATA[Kapcsolatba léphet <font color="#0088ff">a SimpleX Chat fejlesztőivel, ahol bármiről kérdezhet és értesülhet a friss hírekről</font>.]]></string>
<string name="you_can_connect_to_simplex_chat_founder"><![CDATA[Kapcsolatba léphet <font color="#0088ff">a SimpleX Chat fejlesztőivel, akiktől bármit kérdezhet és értesülhet a friss hírekről</font>.]]></string>
<string name="v4_2_auto_accept_contact_requests_desc">Nem kötelező üdvözlőüzenettel.</string>
<string name="unknown_database_error_with_info">Ismeretlen adatbázishiba: %s</string>
<string name="you_can_hide_or_mute_user_profile">Elrejtheti vagy lenémíthatja a felhasználóprofiljait koppintson (vagy számítógép-alkalmazásban kattintson) hosszan a profilra a felugró menühöz.</string>
@@ -1654,7 +1654,7 @@
<string name="migrate_from_another_device">Átköltöztetés egy másik eszközről</string>
<string name="v5_6_quantum_resistant_encryption">Kvantumbiztos titkosítás</string>
<string name="migrate_from_device_try_again">Megpróbálhatja még egyszer.</string>
<string name="migrate_from_device_migration_complete">Átköltöztetés befejezve</string>
<string name="migrate_from_device_migration_complete">Átköltöztetés kész</string>
<string name="v5_6_app_data_migration_descr">Átköltöztetés egy másik eszközre QR-kód használatával.</string>
<string name="migrate_to_device_migrating">Átköltöztetés</string>
<string name="migrate_from_device_using_on_two_device_breaks_encryption"><![CDATA[<b>Megjegyzés:</b> ha két eszközön is ugyanazt az adatbázist használja, akkor biztonsági védelemként megszakítja a partnereitől érkező üzenetek visszafejtését.]]></string>
@@ -2522,4 +2522,7 @@
<string name="placeholder_search_voice_messages">Hangüzenetek keresése</string>
<string name="content_filter_videos">Videók</string>
<string name="content_filter_voice_messages">Hangüzenetek</string>
<string name="info_row_connection_failed">Nem sikerült létrehozni a kapcsolatot</string>
<string name="member_info_member_failed">sikertelen</string>
<string name="down_migration_warning_chat_relays">Ha csatornákat hozott létre vagy csatlakozott hozzájuk, akkor azok véglegesen le fognak állni.</string>
</resources>
@@ -2558,4 +2558,7 @@
<string name="content_filter_videos">Video</string>
<string name="content_filter_voice_messages">Messaggi vocali</string>
<string name="content_filter_menu_item">Filtro</string>
<string name="info_row_connection_failed">Connessione fallita</string>
<string name="member_info_member_failed">fallito</string>
<string name="down_migration_warning_chat_relays">Se sei dentro canali o ne hai creati, essi smetteranno di funzionare definitivamente.</string>
</resources>
@@ -1826,7 +1826,7 @@
<string name="smp_servers_configured">SMPサーバーの構成</string>
<string name="servers_info_sessions_connected">接続中</string>
<string name="xftp_servers_configured">XFTPサーバーの構成</string>
<string name="one_hand_ui_card_title">チャトリスト切り替え</string>
<string name="one_hand_ui_card_title">チャトリスト表示切り替え</string>
<string name="contact_list_header_title">連絡先</string>
<string name="message_servers">メッセージサーバ</string>
<string name="media_and_file_servers">メディア&amp;ファイルサーバ</string>
@@ -2055,4 +2055,10 @@
<string name="accept_pending_member_alert_confirmation_as_member">メンバーとして承認する</string>
<string name="accept_pending_member_alert_confirmation_as_observer">オブザーバーとして承認する</string>
<string name="blocking_reason_spam">スパム</string>
<string name="archive_verb">アーカイブ</string>
<string name="short_descr__field">自己紹介</string>
<string name="bio_too_large">自己紹介の文字数が上限を超えています</string>
<string name="appearance_bars_blur_radius">ぼかし</string>
<string name="chat_list_contacts">連絡先</string>
<string name="chat_list_favorites">お気に入り</string>
</resources>
@@ -1619,7 +1619,7 @@
<string name="call_service_notification_end_call">Zakończ połączenie</string>
<string name="call_service_notification_video_call">Połączenie wideo</string>
<string name="unable_to_open_browser_title">Błąd podczas otwierania przeglądarki</string>
<string name="unable_to_open_browser_desc">Do połączeń wymagana jest domyślna przeglądarka. Proszę skonfigurować domyślną przeglądarkę systemową, i podzielić się informacją z twórcami.</string>
<string name="unable_to_open_browser_desc">Do wykonywania połączeń wymagana jest domyślna przeglądarka internetowa. Skonfiguruj domyślną przeglądarkę w systemie i przekaż więcej informacji programistom.</string>
<string name="e2ee_info_pq_short">Ten czat jest chroniony przez szyfrowanie e2e odporne na ataki kwantowe.</string>
<string name="e2ee_info_no_pq"><![CDATA[Wiadomości, pliki i połączenia są chronione przez <b>szyfrowanie end-to-end</b> z perfect forward secrecy, zaprzeczalnością i odzyskiwaniem bezpieczeństwa po kompromitacji.]]></string>
<string name="auth_open_migration_to_another_device">Otwórz ekran migrowania</string>
@@ -2234,7 +2234,7 @@
<string name="compose_view_connect">Połącz</string>
<string name="v6_4_connect_faster">Połącz się szybciej! 🚀</string>
<string name="cant_send_message_contact_deleted">kontakt usunięty</string>
<string name="cant_send_message_contact_disabled">kontakt zablokowany</string>
<string name="cant_send_message_contact_disabled">kontakt wyłączony</string>
<string name="cant_send_message_contact_not_ready">kontakt nie gotowy</string>
<string name="settings_section_title_contact_requests_from_groups">PROŚBY O KONTAKT OD GRUP</string>
<string name="contact_should_accept">kontakt powinien zaakceptować…</string>
@@ -2376,7 +2376,7 @@
<string name="v6_2_improved_chat_navigation_descr">- Otwórz czat w pierwszej nieprzeczytanej wiadomości.\n- Przejdź do cytowanych wiadomości.</string>
<string name="privacy_chat_list_open_clean_web_link">Otwórz czysty link</string>
<string name="operator_open_conditions">Otwórz warunki</string>
<string name="privacy_chat_list_open_full_web_link">Otwórz pełen link</string>
<string name="privacy_chat_list_open_full_web_link">Otwórz pełny link</string>
<string name="privacy_chat_list_open_web_link">Otwórz link</string>
<string name="privacy_chat_list_open_links">Otwórz linki z listy czatów</string>
<string name="connect_plan_open_new_chat">Otwórz nowy czat</string>
@@ -2395,8 +2395,8 @@
<string name="restore_passphrase_can_not_be_read_enter_manually_desc">Nie można odczytać hasła w magazynie kluczy. Wprowadź je ręcznie. Mogło się to zdarzyć po aktualizacji systemu niezgodnej z aplikacją. Jeśli tak nie jest, skontaktuj się z programistami.</string>
<string name="restore_passphrase_can_not_be_read_desc">Nie można odczytać hasła w magazynie kluczy. Mogło się to zdarzyć po aktualizacji systemu niezgodnej z aplikacją. Jeśli tak nie jest, skontaktuj się z programistami.</string>
<string name="group_member_status_pending_approval_short">oczekuje</string>
<string name="group_member_status_pending_approval">oczekiwanie zaakceptowane</string>
<string name="group_member_status_pending_review">oczekująca recenzja</string>
<string name="group_member_status_pending_approval">oczekuje na zatwierdzenie</string>
<string name="group_member_status_pending_review">oczekuje na ocenę</string>
<string name="maximum_message_size_reached_text">Zmniejsz rozmiar wiadomości i wyślij ją ponownie.</string>
<string name="maximum_message_size_reached_non_text">Zmniejsz rozmiar wiadomości lub usuń multimedia i wyślij ponownie.</string>
<string name="snd_group_event_user_pending_review">Poczekaj, aż moderatorzy grupy rozpatrzą Twoją prośbę o dołączenie do grupy.</string>
@@ -2418,7 +2418,7 @@
<string name="reject_pending_member_alert_title">Odrzucić członka?</string>
<string name="remote_hosts_section">Zdalne telefony komórkowe</string>
<string name="remove_member_delete_messages_confirmation">Usuń i skasuj wiadomości</string>
<string name="cant_send_message_mem_removed">przeniesiono z grupy</string>
<string name="cant_send_message_mem_removed">usunięty z grupy</string>
<string name="sanitize_links_toggle">Usuń śledzenie linków</string>
<string name="button_remove_members_question">Usunąć członka?</string>
<string name="v6_4_role_moderator_descr">Usuwa wiadomości i blokuje członków.</string>
@@ -2428,7 +2428,7 @@
<string name="report_compose_reason_header_profile">Zgłoś profil członka: będą go widzieć tylko moderatorzy grupy.</string>
<string name="report_compose_reason_header_other">Zgłoś inne: zobaczą to tylko moderatorzy grupy.</string>
<string name="report_reason_alert_title">Jaki jest powód zgłoszenia?</string>
<string name="notification_group_report">Zgłoś: %s</string>
<string name="notification_group_report">Zgłoszenie: %s</string>
<string name="chat_list_group_reports">Zgłoszenia</string>
<string name="report_sent_alert_title">Zgłoszenia wysłane do moderatorów</string>
<string name="report_compose_reason_header_spam">Zgłoś spam: tylko moderatorzy grupy będą to widzieć.</string>
@@ -2437,7 +2437,7 @@
<string name="display_name_requested_to_connect">poproszono o połączenie</string>
<string name="cant_send_message_request_is_sent">prośba została wysłana</string>
<string name="cant_send_message_rejected">prośba o dołączenie została odrzucona</string>
<string name="group_member_status_pending_review_short">przejrzyj</string>
<string name="group_member_status_pending_review_short">ocena</string>
<string name="operator_review_conditions">Przejrzyj warunki</string>
<string name="reviewed_by_admins">sprawdzone przez administratorów</string>
<string name="v6_4_review_members">Przejrzyj członków grupy</string>
@@ -2445,12 +2445,12 @@
<string name="admission_stage_review">Przejrzyj członków</string>
<string name="admission_stage_review_descr">Przejrzyj członków przed przyjęciem (pukanie).</string>
<string name="save_admission_question">Zapisać ustawienia wstępu?</string>
<string name="save_list">Zachowaj listę</string>
<string name="placeholder_search_files">Poszukaj plików</string>
<string name="placeholder_search_images">Poszukaj obrazów</string>
<string name="placeholder_search_links">Poszukaj linków</string>
<string name="placeholder_search_videos">Poszukaj wideo</string>
<string name="placeholder_search_voice_messages">Poszukaj wiadomości głosowych</string>
<string name="save_list">Zapisz listę</string>
<string name="placeholder_search_files">Szukaj plików</string>
<string name="placeholder_search_images">Szukaj zdjęć</string>
<string name="placeholder_search_links">Szukaj linków</string>
<string name="placeholder_search_videos">Szukaj wideo</string>
<string name="placeholder_search_voice_messages">Szukaj wiadomości głosowych</string>
<string name="onboarding_select_network_operators_to_use">Wybierz operatora sieci</string>
<string name="compose_view_send_contact_request_alert_question">Wysłać prośbę o kontakt?</string>
<string name="v6_3_reports">Wyślij prywatne zgłoszenia</string>
@@ -2459,7 +2459,7 @@
<string name="v6_4_support_chat_descr">Wyślij swoją prywatną opinię do grup.</string>
<string name="sent_to_your_contact_after_connection">Wysłano do Twojego kontaktu po połączeniu.</string>
<string name="server_added_to_operator__name">Serwer dodany do operatora %s.</string>
<string name="error_server_operator_changed">Operator serwera zmieniony.</string>
<string name="error_server_operator_changed">Operator serwera został zmieniony.</string>
<string name="onboarding_choose_server_operators">Operatorzy serwera</string>
<string name="error_server_protocol_changed">Protokół serwera zmieniony.</string>
<string name="text_field_set_chat_placeholder">Ustaw nazwę czatu…</string>
@@ -2554,4 +2554,7 @@
<string name="context_user_picker_your_profile">Twój profil</string>
<string name="your_servers">Twoje serwery</string>
<string name="you_will_stop_receiving_messages_from_this_chat_chat_history_will_be_preserved">Przestaniesz otrzymywać wiadomości z tego czatu. Historia czatu zostanie zachowana.</string>
<string name="info_row_connection_failed">Połączenie nie powiodło się</string>
<string name="member_info_member_failed">niepowodzenie</string>
<string name="down_migration_warning_chat_relays">Jeśli dołączyłeś do kanałów lub je utworzyłeś, przestaną one działać na stałe.</string>
</resources>
@@ -2542,4 +2542,7 @@
<string name="placeholder_search_voice_messages">搜索语音消息</string>
<string name="content_filter_videos">视频</string>
<string name="content_filter_voice_messages">语音消息</string>
<string name="info_row_connection_failed">连接失败</string>
<string name="member_info_member_failed">失败</string>
<string name="down_migration_warning_chat_relays">如果你加入了或创建了频道,它们会永远停止工作。</string>
</resources>
@@ -1574,7 +1574,7 @@
<string name="desktop_devices">桌面設備</string>
<string name="linked_desktop_options">已連結桌面選項</string>
<string name="linked_desktops">已連結桌面</string>
<string name="rcv_group_event_member_created_contact">直接連線中</string>
<string name="rcv_group_event_member_created_contact">已請求連接</string>
<string name="action_button_add_members">邀請</string>
<string name="create_group_button">建立群組</string>
<string name="fix_connection_not_supported_by_group_member">修復群組成員不支援的問題</string>
@@ -1677,7 +1677,7 @@
<string name="servers_info_sessions_connecting">連接中</string>
<string name="servers_info_sessions_errors">錯誤</string>
<string name="receipts_groups_title_disable">為群組停用回執?</string>
<string name="past_member_vName">過往的成員 %1$s</string>
<string name="past_member_vName">成員 %1$s</string>
<string name="v5_8_private_routing">私密訊息路由 🚀</string>
<string name="paste_archive_link">貼上封存連結</string>
<string name="open_on_mobile_and_scan_qr_code"><![CDATA[在行動應用中打開<i>從桌面使用</i>並掃描QR code。]]></string>
@@ -1909,7 +1909,7 @@
<string name="non_content_uri_alert_text">你分享了一個無效的檔案路徑。請將此問題報告給應用程式開發者。</string>
<string name="file_not_approved_descr">如果沒有 Tor 或 VPN,你的 IP 位址將對以下 XFTP 中繼可見:\n%1$s。</string>
<string name="app_was_crashed">檢視已崩潰</string>
<string name="add_short_link">新增短連結</string>
<string name="add_short_link">升級地址</string>
<string name="rcv_group_event_member_accepted">接受了 %1$s</string>
<string name="rcv_group_event_user_accepted">接受了你</string>
<string name="button_add_team_members">新增團隊成員</string>
@@ -2128,4 +2128,72 @@
<string name="connect_plan_open_new_chat">開啓新聊天</string>
<string name="accept_contact_request">接受聯絡請求</string>
<string name="chat_banner_accept_contact_request">接受聯絡請求</string>
<string name="chat_banner_bot">機械人</string>
<string name="content_filter_images">圖片</string>
<string name="content_filter_videos">影片</string>
<string name="content_filter_files">檔案</string>
<string name="content_filter_links">連結</string>
<string name="content_filter_menu_item">過濾器</string>
<string name="group_reports_active">%d 個舉報</string>
<string name="deprecated_options_section">已棄用的選項</string>
<string name="server_no_sub">無訂閱</string>
<string name="delete_member_messages_confirmation">刪除訊息</string>
<string name="placeholder_search_images">搜尋圖片</string>
<string name="placeholder_search_videos">搜尋影片</string>
<string name="placeholder_search_files">搜尋檔案</string>
<string name="placeholder_search_links">搜尋連結</string>
<string name="content_filter_voice_messages">語音訊息</string>
<string name="content_filter_all_messages">所有訊息</string>
<string name="connect_plan_repeat_join_request">重複加入請求?</string>
<string name="tap_to_scan">點擊以掃描</string>
<string name="show_internal_errors">顯示內部錯誤</string>
<string name="conn_event_disabled_pq">標準端對端加密</string>
<string name="migrate_from_device_verify_database_passphrase">驗證資料庫密碼</string>
<string name="private_routing_show_message_status">顯示訊息狀態</string>
<string name="chat_theme_set_default_theme">設定預設主題</string>
<string name="v5_8_safe_files">安全地接收檔案</string>
<string name="temporary_file_error">臨時性檔案錯誤</string>
<string name="servers_info_reset_stats">重設所有統計</string>
<string name="servers_info_reset_stats_alert_title">重設所有統計?</string>
<string name="app_check_for_updates_update_available">有更新可用:%s</string>
<string name="app_check_for_updates_button_skip">略過此版本</string>
<string name="app_check_for_updates_canceled">更新下載已取消</string>
<string name="network_options_save_and_reconnect">儲存並重新連接</string>
<string name="reset_all_hints">重設所有提示</string>
<string name="v6_0_upgrade_app">自動升級應用程式</string>
<string name="select_chat_profile">選擇聊天個人檔案</string>
<string name="network_proxy_random_credentials">使用隨機憑證</string>
<string name="network_proxy_incorrect_config_title">儲存代理時發生錯誤</string>
<string name="error_forwarding_messages">轉發訊息時發生錯誤</string>
<string name="forward_alert_title_messages_to_forward">轉發 %1$s 條訊息?</string>
<string name="compose_forward_messages_n">正在轉發 %1$s 條訊息</string>
<string name="compose_save_messages_n">正在儲存 %1$s 條訊息</string>
<string name="failed_to_save_servers">儲存伺服器時發生錯誤</string>
<string name="error_accepting_operator_conditions">接受條款時發生錯誤</string>
<string name="share_address_publicly">公開地分享地址</string>
<string name="for_social_media">用於社交媒體</string>
<string name="operator_use_for_messages">用於訊息</string>
<string name="operator_use_for_messages_private_routing">用於私密路由</string>
<string name="operator_use_for_files">用於檔案</string>
<string name="error_updating_server_title">更新伺服器時發生錯誤</string>
<string name="error_server_operator_changed">伺服器營運者已變更。</string>
<string name="error_adding_server">增加伺服器時發生錯誤</string>
<string name="view_updated_conditions">檢視已更新的條款</string>
<string name="onboarding_notifications_mode_battery">通知和電量</string>
<string name="invite_to_chat_button">邀請加入聊天</string>
<string name="open_with_app">使用 %s 開啟</string>
<string name="no_unread_chats">沒有未讀聊天</string>
<string name="no_chats_found">找不到聊天</string>
<string name="group_preview_open_to_join">開啟以加入</string>
<string name="open_to_connect">開啟以連接</string>
<string name="open_to_use_bot">開啟以使用機械人</string>
<string name="open_to_accept">開啟以接受</string>
<string name="search_or_paste_simplex_link">搜尋或貼上 SimpleX 連結</string>
<string name="max_group_mentions_per_message_reached">你的每個訊息最多可以提及 %1$s 位成員!</string>
<string name="sent_via_proxy">已透過代理傳送</string>
<string name="servers_info_reset_stats_alert_message">伺服器統計資料將被重設—此操作無法撤銷!</string>
<string name="servers_info_proxied_servers_section_footer">你沒有連接至這些伺服器。已使用私密路由將訊息傳送至這些伺服器。</string>
<string name="migrate_from_device_you_must_not_start_database_on_two_device"><![CDATA[你<b>不能</b>在兩部裝置上使用同一資料庫。]]></string>
<string name="migrate_from_device_starting_chat_on_multiple_devices_unsupported">警告:不支援在多個裝置上同時聊天,否則會導致訊息傳送失敗</string>
<string name="chat_archive">或匯入封存檔案</string>
</resources>