Merge remote-tracking branch 'origin/master' into ab/self-chat

This commit is contained in:
IC Rainbow 2023-12-27 19:12:02 +02:00
commit 8748d19c12
35 changed files with 248 additions and 95 deletions

View File

@ -104,7 +104,7 @@ struct ComposeState {
var sendEnabled: Bool {
switch preview {
case .mediaPreviews: return true
case let .mediaPreviews(media): return !media.isEmpty
case .voicePreview: return voiceMessageRecordingState == .finished
case .filePreview: return true
default: return !message.isEmpty || liveMessage != nil
@ -384,7 +384,7 @@ struct ComposeView: View {
}
}
.sheet(isPresented: $showMediaPicker) {
LibraryMediaListPicker(addMedia: addMediaContent, selectionLimit: 10) { itemsSelected in
LibraryMediaListPicker(addMedia: addMediaContent, selectionLimit: 10, finishedPreprocessing: finishedPreprocessingMediaContent) { itemsSelected in
await MainActor.run {
showMediaPicker = false
if itemsSelected {
@ -503,6 +503,15 @@ struct ComposeView: View {
}
}
// When error occurs while converting video, remove media preview
private func finishedPreprocessingMediaContent() {
if case let .mediaPreviews(media) = composeState.preview, media.isEmpty {
DispatchQueue.main.async {
composeState = composeState.copy(preview: .noPreview)
}
}
}
private var maxFileSize: Int64 {
getMaxFileSize(.xftp)
}

View File

@ -33,6 +33,7 @@ struct LibraryMediaListPicker: UIViewControllerRepresentable {
typealias UIViewControllerType = PHPickerViewController
var addMedia: (_ content: UploadContent) async -> Void
var selectionLimit: Int
var finishedPreprocessing: () -> Void = {}
var didFinishPicking: (_ didSelectItems: Bool) async -> Void
class Coordinator: PHPickerViewControllerDelegate {
@ -50,6 +51,7 @@ struct LibraryMediaListPicker: UIViewControllerRepresentable {
for r in results {
await loadItem(r.itemProvider)
}
parent.finishedPreprocessing()
}
}
@ -103,21 +105,27 @@ struct LibraryMediaListPicker: UIViewControllerRepresentable {
await withCheckedContinuation { cont in
loadFileURL(p, type: UTType.movie) { url in
if let url = url {
let tempUrl = URL(fileURLWithPath: generateNewFileName(getTempFilesDirectory().path + "/" + "video", url.pathExtension, fullPath: true))
let tempUrl = URL(fileURLWithPath: generateNewFileName(getTempFilesDirectory().path + "/" + "rawvideo", url.pathExtension, fullPath: true))
let convertedVideoUrl = URL(fileURLWithPath: generateNewFileName(getTempFilesDirectory().path + "/" + "video", "mp4", fullPath: true))
do {
// logger.debug("LibraryMediaListPicker copyItem \(url) to \(tempUrl)")
// logger.debug("LibraryMediaListPicker copyItem \(url) to \(tempUrl)")
try FileManager.default.copyItem(at: url, to: tempUrl)
DispatchQueue.main.async {
_ = ChatModel.shared.filesToDelete.insert(tempUrl)
}
let video = UploadContent.loadVideoFromURL(url: tempUrl)
cont.resume(returning: video)
return
} catch let err {
logger.error("LibraryMediaListPicker copyItem error: \(err.localizedDescription)")
return cont.resume(returning: nil)
}
Task {
let success = await makeVideoQualityLower(tempUrl, outputUrl: convertedVideoUrl)
try? FileManager.default.removeItem(at: tempUrl)
if success {
_ = ChatModel.shared.filesToDelete.insert(convertedVideoUrl)
let video = UploadContent.loadVideoFromURL(url: convertedVideoUrl)
return cont.resume(returning: video)
}
try? FileManager.default.removeItem(at: convertedVideoUrl)
cont.resume(returning: nil)
}
}
cont.resume(returning: nil)
}
}
}
@ -143,7 +151,7 @@ struct LibraryMediaListPicker: UIViewControllerRepresentable {
config.filter = .any(of: [.images, .videos])
config.selectionLimit = selectionLimit
config.selection = .ordered
//config.preferredAssetRepresentationMode = .current
config.preferredAssetRepresentationMode = .current
let controller = PHPickerViewController(configuration: config)
controller.delegate = context.coordinator
return controller

View File

@ -0,0 +1,26 @@
//
// VideoUtils.swift
// SimpleX (iOS)
//
// Created by Avently on 25.12.2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import AVFoundation
import Foundation
import SimpleXChat
func makeVideoQualityLower(_ input: URL, outputUrl: URL) async -> Bool {
let asset: AVURLAsset = AVURLAsset(url: input, options: nil)
if let s = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset640x480) {
s.outputURL = outputUrl
s.outputFileType = .mp4
s.metadataItemFilter = AVMetadataItemFilter.forSharing()
await s.export()
if let err = s.error {
logger.error("Failed to export video with error: \(err)")
}
return s.status == .completed
}
return false
}

View File

@ -81,11 +81,6 @@ struct CreateSimpleXAddress: View {
DispatchQueue.main.async {
m.userAddress = UserContactLink(connReqContact: connReqContact)
}
if let u = try await apiSetProfileAddress(on: true) {
DispatchQueue.main.async {
m.updateUser(u)
}
}
await MainActor.run { progressIndicator = false }
} catch let error {
logger.error("CreateSimpleXAddress create address: \(responseError(error))")
@ -100,7 +95,7 @@ struct CreateSimpleXAddress: View {
} label: {
Text("Create SimpleX address").font(.title)
}
Text("Your contacts in SimpleX will see it.\nYou can change it in Settings.")
Text("You can make it visible to your SimpleX contacts via Settings.")
.multilineTextAlignment(.center)
.font(.footnote)
.padding(.horizontal, 32)

View File

@ -188,6 +188,7 @@
64D0C2C629FAC1EC00B38D5F /* AddContactLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */; };
64E972072881BB22008DBC02 /* CIGroupInvitationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */; };
64F1CC3B28B39D8600CD1FB1 /* IncognitoHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */; };
8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C05382D2B39887E006436DC /* VideoUtils.swift */; };
D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; };
D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A9087294BD7A70047C86D /* NativeTextEditor.swift */; };
D741547829AF89AF0022400A /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547729AF89AF0022400A /* StoreKit.framework */; };
@ -476,6 +477,7 @@
64DAE1502809D9F5000DA960 /* FileUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = "<group>"; };
64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIGroupInvitationView.swift; sourceTree = "<group>"; };
64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncognitoHelp.swift; sourceTree = "<group>"; };
8C05382D2B39887E006436DC /* VideoUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoUtils.swift; sourceTree = "<group>"; };
D72A9087294BD7A70047C86D /* NativeTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTextEditor.swift; sourceTree = "<group>"; };
D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; };
D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; };
@ -642,6 +644,7 @@
64466DCB29FFE3E800E3D48D /* MailView.swift */,
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */,
5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */,
8C05382D2B39887E006436DC /* VideoUtils.swift */,
);
path = Helpers;
sourceTree = "<group>";
@ -1212,6 +1215,7 @@
5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */,
5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */,
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */,
8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */,
5CADE79C292131E900072E13 /* ContactPreferencesView.swift in Sources */,
5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */,
5C9C2DA52894777E00CC63B1 /* GroupProfileView.swift in Sources */,

View File

@ -223,8 +223,8 @@ afterEvaluate {
return this
}
val fileRegex = Regex("MR/../strings.xml$|MR/..-.../strings.xml$|MR/..-../strings.xml$|MR/base/strings.xml$")
val tree = kotlin.sourceSets["commonMain"].resources.filter { fileRegex.containsMatchIn(it.absolutePath) }.asFileTree
val baseStringsFile = tree.first { it.absolutePath.endsWith("base/strings.xml") } ?: throw Exception("No base/strings.xml found")
val tree = kotlin.sourceSets["commonMain"].resources.filter { fileRegex.containsMatchIn(it.absolutePath.replace("\\", "/")) }.asFileTree
val baseStringsFile = tree.firstOrNull { it.absolutePath.replace("\\", "/").endsWith("base/strings.xml") } ?: throw Exception("No base/strings.xml found")
val treeList = ArrayList(tree.toList())
treeList.remove(baseStringsFile)
treeList.add(0, baseStringsFile)

View File

@ -58,7 +58,7 @@ object ChatModel {
val chatItemStatuses = mutableMapOf<Long, CIStatus>()
val groupMembers = mutableStateListOf<GroupMember>()
val terminalItems = mutableStateListOf<TerminalItem>()
val terminalItems = mutableStateOf<List<TerminalItem>>(listOf())
val userAddress = mutableStateOf<UserContactLinkRec?>(null)
// Allows to temporary save servers that are being edited on multiple screens
val userSMPServersUnsaved = mutableStateOf<(List<ServerCfg>)?>(null)
@ -620,10 +620,10 @@ object ChatModel {
}
fun addTerminalItem(item: TerminalItem) {
if (terminalItems.size >= 500) {
terminalItems.removeAt(0)
if (terminalItems.value.size >= 500) {
terminalItems.value = terminalItems.value.subList(1, terminalItems.value.size)
}
terminalItems.add(item)
terminalItems.value += item
}
val connectedToRemote: Boolean @Composable get() = currentRemoteHost.value != null || remoteCtrlSession.value?.active == true

View File

@ -34,7 +34,6 @@ fun TerminalView(chatModel: ChatModel, close: () -> Unit) {
close()
})
TerminalLayout(
remember { chatModel.terminalItems },
composeState,
sendCommand = { sendCommand(chatModel, composeState) },
close
@ -63,7 +62,6 @@ private fun sendCommand(chatModel: ChatModel, composeState: MutableState<Compose
@Composable
fun TerminalLayout(
terminalItems: List<TerminalItem>,
composeState: MutableState<ComposeState>,
sendCommand: () -> Unit,
close: () -> Unit
@ -111,7 +109,7 @@ fun TerminalLayout(
.fillMaxWidth(),
color = MaterialTheme.colors.background
) {
TerminalLog(terminalItems)
TerminalLog()
}
}
}
@ -120,22 +118,13 @@ fun TerminalLayout(
private var lazyListState = 0 to 0
@Composable
fun TerminalLog(terminalItems: List<TerminalItem>) {
fun TerminalLog() {
val listState = rememberLazyListState(lazyListState.first, lazyListState.second)
DisposableEffect(Unit) {
onDispose { lazyListState = listState.firstVisibleItemIndex to listState.firstVisibleItemScrollOffset }
}
val reversedTerminalItems by remember {
derivedStateOf {
// Such logic prevents concurrent modification
val res = ArrayList<TerminalItem>()
var i = 0
while (i < terminalItems.size) {
res.add(terminalItems[i])
i++
}
res.asReversed()
}
derivedStateOf { chatModel.terminalItems.value.asReversed() }
}
val clipboard = LocalClipboardManager.current
LazyColumn(state = listState, reverseLayout = true) {
@ -152,7 +141,12 @@ fun TerminalLog(terminalItems: List<TerminalItem>) {
.clickable {
ModalManager.start.showModal(endButtons = { ShareButton { clipboard.shareText(item.details) } }) {
SelectionContainer(modifier = Modifier.verticalScroll(rememberScrollState())) {
Text(item.details, modifier = Modifier.padding(horizontal = DEFAULT_PADDING).padding(bottom = DEFAULT_PADDING))
val details = item.details
.let {
if (it.length < 100_000) it
else it.substring(0, 100_000)
}
Text(details, modifier = Modifier.heightIn(max = 50_000.dp).padding(horizontal = DEFAULT_PADDING).padding(bottom = DEFAULT_PADDING))
}
}
}.padding(horizontal = 8.dp, vertical = 4.dp)
@ -170,7 +164,6 @@ fun TerminalLog(terminalItems: List<TerminalItem>) {
fun PreviewTerminalLayout() {
SimpleXTheme {
TerminalLayout(
terminalItems = TerminalItem.sampleData,
composeState = remember { mutableStateOf(ComposeState(useLinkPreviews = false)) },
sendCommand = {},
close = {}

View File

@ -48,14 +48,6 @@ fun CreateSimpleXAddress(m: ChatModel, rhId: Long?) {
val connReqContact = m.controller.apiCreateUserAddress(rhId)
if (connReqContact != null) {
m.userAddress.value = UserContactLinkRec(connReqContact)
try {
val u = m.controller.apiSetProfileAddress(rhId, true)
if (u != null) {
m.updateUser(u)
}
} catch (e: Exception) {
Log.e(TAG, "CreateSimpleXAddress apiSetProfileAddress: ${e.stackTraceToString()}")
}
progressIndicator = false
}
}
@ -100,7 +92,7 @@ private fun CreateSimpleXAddressLayout(
ContinueButton(nextStep)
} else {
CreateAddressButton(createAddress)
TextBelowButton(stringResource(MR.strings.your_contacts_will_see_it))
TextBelowButton(stringResource(MR.strings.you_can_make_address_visible_via_settings))
Spacer(Modifier.weight(1f))
SkipButton(nextStep)
}

View File

@ -1275,8 +1275,6 @@
<string name="gallery_video_button">فيديو</string>
<string name="you_can_share_your_address">يمكنك مشاركة عنوانك كرابط أو رمز QR - يمكن لأي شخص الاتصال بك.</string>
<string name="you_can_create_it_later">يمكنك إنشاؤه لاحقًا</string>
<string name="your_contacts_will_see_it">سوف تراها جهات اتصالك في whatsapp.
\nيمكنك تغييره في الإعدادات.</string>
<string name="invite_prohibited_description">أنت تحاول دعوة جهة اتصال قمت بمشاركة ملف تعريف متخفي معها إلى المجموعة التي تستخدم فيها ملفك الشخصي الرئيسي</string>
<string name="user_unmute">إلغاء الكتم</string>
<string name="unmute_chat">إلغاء الكتم</string>

View File

@ -693,7 +693,7 @@
<string name="continue_to_next_step">Continue</string>
<string name="dont_create_address">Don\'t create address</string>
<string name="you_can_create_it_later">You can create it later</string>
<string name="your_contacts_will_see_it">Your contacts in SimpleX will see it.\nYou can change it in Settings.</string>
<string name="you_can_make_address_visible_via_settings">You can make it visible to your SimpleX contacts via Settings.</string>
<!-- User profile details - UserProfileView.kt -->
<string name="display_name__field">Profile name:</string>

View File

@ -1236,8 +1236,6 @@
<string name="network_disable_socks">Използване на директна интернет връзка\?</string>
<string name="network_use_onion_hosts">Използвай .onion хостове</string>
<string name="network_use_onion_hosts_prefer">Когато са налични</string>
<string name="your_contacts_will_see_it">Вашите контакти в SimpleX ще го видят.
\nМожете да го промените в Настройки.</string>
<string name="your_profile_is_stored_on_your_device">Вашият профил, контакти и доставени съобщения се съхраняват на вашето устройство.</string>
<string name="you_can_use_markdown_to_format_messages__prompt">Можете да използвате markdown за форматиране на съобщенията:</string>
<string name="you_control_servers_to_receive_your_contacts_to_send"><![CDATA[Вие контролирате през кой сървър(и) <b>да получавате</b> съобщенията, вашите контакти сървърите, които използвате, за да им изпращате съобщения.]]></string>

View File

@ -1247,8 +1247,6 @@
<string name="only_your_contact_can_add_message_reactions">Reakce na zprávy může přidávat pouze váš kontakt.</string>
<string name="your_contacts_will_remain_connected">Vaše kontakty zůstanou připojeny.</string>
<string name="you_can_share_this_address_with_your_contacts">Tuto adresu můžete sdílet se svými kontakty, aby se mohli připojit k %s.</string>
<string name="your_contacts_will_see_it">Vaše kontakty v SimpleX ji uvidí.
\nMůžete ji změnit v Nastavení.</string>
<string name="you_can_share_your_address">Svou adresu můžete sdílet jako odkaz nebo QR kód - kdokoli se k vám může připojit.</string>
<string name="you_wont_lose_your_contacts_if_delete_address">Pokud později adresu odstraníte, o kontakty nepřijdete.</string>
<string name="app_passcode_replaced_with_self_destruct">Přístupový kód aplikace je nahrazen sebedestrukčním přístupovým heslem.</string>

View File

@ -1256,8 +1256,6 @@
<string name="import_theme_error_desc">Stellen Sie sicher, dass die Datei die korrekte YAML-Syntax hat. Exportieren Sie das Design, um ein Beispiel für die Dateistruktur des Designs zu erhalten.</string>
<string name="auth_open_chat_profiles">Offene Chat-Profile</string>
<string name="you_can_share_your_address">Sie können Ihre Adresse als Link oder QR-Code teilen jede Person kann sich mit Ihnen verbinden.</string>
<string name="your_contacts_will_see_it">Ihre Kontakte in SimpleX werden es sehen.
\nSie können es in den Einstellungen ändern.</string>
<string name="all_app_data_will_be_cleared">Werden die App-Daten komplett gelöscht.</string>
<string name="empty_chat_profile_is_created">Es wurde ein leeres Chat-Profil mit dem eingegebenen Namen erstellt und die App öffnet wie gewohnt.</string>
<string name="if_you_enter_self_destruct_code">Wenn Sie Ihren Selbstzerstörungs-Zugangscode während des Öffnens der App eingeben:</string>

View File

@ -1174,8 +1174,6 @@
<string name="share_with_contacts">Compartir con contactos</string>
<string name="color_title">Título</string>
<string name="you_can_share_this_address_with_your_contacts">Puedes compartir esta dirección con tus contactos para que puedan conectar con %s.</string>
<string name="your_contacts_will_see_it">Tus contactos en SimpleX lo verán.
\nPuedes cambiarlo en Configuración.</string>
<string name="your_contacts_will_remain_connected">Tus contactos permanecerán conectados.</string>
<string name="you_wont_lose_your_contacts_if_delete_address">Si más tarde decides eliminar tu dirección los contactos no se perderán.</string>
<string name="all_app_data_will_be_cleared">Todos los datos de la aplicación se eliminarán.</string>

View File

@ -1140,8 +1140,6 @@
<string name="theme_colors_section_title">TEEMAN VÄRIT</string>
<string name="update_network_session_mode_question">Päivitä kuljetuksen eristystila\?</string>
<string name="you_can_create_it_later">Voit luoda sen myöhemmin</string>
<string name="your_contacts_will_see_it">Kontaktisi SimpleX:ssä näkevät sen.
\nVoit muuttaa sitä Asetuksista.</string>
<string name="to_reveal_profile_enter_password">Voit paljastaa piilotetun profiilisi kirjoittamalla koko salasanan Keskusteluprofiilit-sivun hakukenttään.</string>
<string name="we_do_not_store_contacts_or_messages_on_servers">Emme tallenna mitään kontaktejasi tai viestejäsi (kun ne on toimitettu) palvelimille.</string>
<string name="to_protect_privacy_simplex_has_ids_for_queues">Yksityisyyden suojaamiseksi kaikkien muiden alustojen käyttämien käyttäjätunnusten sijaan SimpleX käyttää viestijonojen tunnisteita, jotka ovat kaikille kontakteille erillisiä.</string>

View File

@ -1175,8 +1175,6 @@
<string name="read_more_in_user_guide_with_link"><![CDATA[Pour en savoir plus, consultez le <font color="#0088ff">Guide de l\'utilisateur</font>.]]></string>
<string name="save_auto_accept_settings">Sauvegarder les paramètres d\'acceptation automatique</string>
<string name="scan_qr_to_connect_to_contact">Pour se connecter, votre contact peut scanner le code QR ou utiliser le lien dans l\'application.</string>
<string name="your_contacts_will_see_it">Vos contacts dans SimpleX la verront.
\nVous pouvez modifier ce choix dans les Paramètres.</string>
<string name="app_passcode_replaced_with_self_destruct">Le code d\'accès de l\'application est remplacé par un code d\'autodestruction.</string>
<string name="enable_self_destruct">Activer l\'autodestruction</string>
<string name="empty_chat_profile_is_created">Un profil de chat vierge portant le nom fourni est créé et l\'application s\'ouvre normalement.</string>

View File

@ -1140,8 +1140,6 @@
<string name="invite_friends">Invita amici</string>
<string name="save_auto_accept_settings">Salva le impostazioni di accettazione automatica</string>
<string name="you_can_create_it_later">Puoi crearlo più tardi</string>
<string name="your_contacts_will_see_it">I tuoi contatti in SimpleX lo vedranno.
\nPuoi modificarlo nelle impostazioni.</string>
<string name="share_address">Condividi indirizzo</string>
<string name="enter_welcome_message">Inserisci il messaggio di benvenuto…</string>
<string name="group_welcome_preview">Anteprima</string>

View File

@ -1222,8 +1222,6 @@
\nלא ניתן לבטל פעולה זו הפרופיל, אנשי הקשר, ההודעות והקבצים שלך ייאבדו באופן בלתי הפיך.</string>
<string name="your_current_profile">הפרופיל הנוכחי שלך</string>
<string name="your_contacts_will_remain_connected">אנשי הקשר שלך יישארו מחוברים.</string>
<string name="your_contacts_will_see_it">אנשי הקשר שלך ב־SimpleX ייראו זאת.
\nניתן לשנות זאת בהגדרות.</string>
<string name="your_ice_servers">שרתי ה־ICE שלך</string>
<string name="you_will_be_connected_when_your_connection_request_is_accepted">אתם תהיו מחוברים כאשר בקשת החיבור תאושר, אנא חכו או בידקו מאוחר יותר!</string>
<string name="profile_will_be_sent_to_contact_sending_link">הפרופיל שלך יישלח לאיש הקשר ממנו קיבלת קישור זה.</string>

View File

@ -1096,8 +1096,6 @@
\n何らかのバグが原因で、または接続に問題があった場合に発生する可能性があります。</string>
<string name="v5_0_polish_interface_descr">ユーザーに感謝します Weblate 経由で貢献してください!</string>
<string name="you_can_accept_or_reject_connection">接続が要求されたら、それを受け入れるか拒否するかを選択できます。</string>
<string name="your_contacts_will_see_it">SimpleX の連絡先に表示されます。
\n設定で変更できます。</string>
<string name="icon_descr_video_snd_complete">ビデオが送信されました</string>
<string name="v4_6_group_moderation_descr">管理者は次のことができます。
\n- メンバーのメッセージを削除します。

View File

@ -1173,8 +1173,6 @@
<string name="read_more_in_user_guide_with_link"><![CDATA[Lees meer in de <font color="#0088ff">Gebruikershandleiding</font>.]]></string>
<string name="theme_colors_section_title">THEMA KLEUREN</string>
<string name="you_can_share_your_address">U kunt uw adres delen als een link of QR-code - iedereen kan verbinding met u maken.</string>
<string name="your_contacts_will_see_it">Uw contacten in SimpleX kunnen het zien.
\nU kunt dit wijzigen in Instellingen.</string>
<string name="all_app_data_will_be_cleared">Alle app-gegevens worden verwijderd.</string>
<string name="empty_chat_profile_is_created">Er wordt een leeg chatprofiel met de opgegeven naam gemaakt en de app wordt zoals gewoonlijk geopend.</string>
<string name="enabled_self_destruct_passcode">Zelfvernietigings wachtwoord inschakelen</string>

View File

@ -1168,8 +1168,6 @@
<string name="save_auto_accept_settings">Zapisz ustawienia automatycznej akceptacji</string>
<string name="share_with_contacts">Udostępnij kontaktom</string>
<string name="you_can_create_it_later">Możesz go utworzyć później</string>
<string name="your_contacts_will_see_it">Twoje kontakty w SimpleX będą to widzieć.
\nMożesz to zmienić w Ustawieniach.</string>
<string name="address_section_title">Adres</string>
<string name="theme_simplex">SimpleX</string>
<string name="color_secondary">Drugorzędny</string>

View File

@ -1170,8 +1170,6 @@
<string name="opening_database">Abrindo banco de dados…</string>
<string name="auth_open_chat_profiles">Abrir perfis de bate-papo</string>
<string name="share_address_with_contacts_question">Compartilhar endereço com os contatos\?</string>
<string name="your_contacts_will_see_it">Seus contatos no SimpleX o verão.
\nVocê pode alterá-la nas Configurações.</string>
<string name="your_contacts_will_remain_connected">Seus contatos continuarão conectados.</string>
<string name="all_app_data_will_be_cleared">Todos os dados do aplicativo serão excluídos.</string>
<string name="app_passcode_replaced_with_self_destruct">A senha do aplicativo é substituída por uma senha de auto-destruição.</string>

View File

@ -584,8 +584,6 @@
<string name="message_delivery_error_desc">Muito provavelmente este contato eliminou a conexão consigo.</string>
<string name="this_text_is_available_in_settings">Este texto está disponível nas definições</string>
<string name="update_onion_hosts_settings_question">Atualizar definições de servidores .onion\?</string>
<string name="your_contacts_will_see_it">Os seus contatos no SimpleX irão vê-lo.
\nVocê pode alterá-lo nas Definições.</string>
<string name="onboarding_notifications_mode_subtitle">Pode ser alterado mais tarde através das definições.</string>
<string name="settings_section_title_help">AJUDA</string>
<string name="settings_section_title_support">SUPORTE SIMPLEX CHAT</string>

View File

@ -1280,8 +1280,7 @@
<string name="continue_to_next_step">Продолжить</string>
<string name="dont_create_address">Не создавать адрес</string>
<string name="you_can_create_it_later">Вы можете создать его позже</string>
<string name="your_contacts_will_see_it">Ваши контакты в SimpleX получат этот адрес.
\nВы можете изменить это в Настройках.</string>
<string name="you_can_make_address_visible_via_settings">Вы можете сделать его видимым для ваших контактов в SimpleX через Настройки.</string>
<string name="address_section_title">Адрес</string>
<string name="enter_welcome_message">Введите приветственное сообщение…</string>
<string name="group_welcome_preview">Просмотр</string>

View File

@ -1159,8 +1159,6 @@
<string name="theme_colors_section_title">สีของธีม</string>
<string name="your_contacts_will_remain_connected">ผู้ติดต่อของคุณจะยังคงเชื่อมต่ออยู่</string>
<string name="you_can_create_it_later">คุณสามารถสร้างได้ในภายหลัง</string>
<string name="your_contacts_will_see_it">ผู้ติดต่อของคุณใน SimpleX จะเห็น
\nคุณสามารถเปลี่ยนได้ในการตั้งค่า</string>
<string name="you_control_your_chat">คุณเป็นผู้ควบคุมการแชทของคุณ!</string>
<string name="profile_is_only_shared_with_your_contacts">โปรไฟล์นี้แชร์กับผู้ติดต่อของคุณเท่านั้น</string>
<string name="we_do_not_store_contacts_or_messages_on_servers">เราไม่เก็บผู้ติดต่อหรือข้อความของคุณ (เมื่อส่งแล้ว) ไว้บนเซิร์ฟเวอร์</string>

View File

@ -875,8 +875,6 @@
<string name="incognito_info_share">Biriyle gizli bir profil paylaştığınızda, bu profil sizi davet ettikleri gruplar için kullanılacaktır.</string>
<string name="v4_2_auto_accept_contact_requests_desc">İsteğe bağlı karşılama mesajı ile.</string>
<string name="your_contacts_will_remain_connected">Kişileriniz bağlı kalacaktır.</string>
<string name="your_contacts_will_see_it">SimpleX\'teki kişileriniz bunu görecektir.
\nBunu Ayarlardan değiştirebilirsiniz.</string>
<string name="you_can_create_it_later">Daha sonra oluşturabilirsiniz</string>
<string name="you_can_use_markdown_to_format_messages__prompt">Mesajları biçimlendirmek için markdown kullanabilirsiniz:</string>
<string name="your_chat_database">Mesaj veri tabanınız</string>

View File

@ -651,8 +651,6 @@
<string name="developer_options">Ідентифікатори бази даних та опція ізоляції транспорту.</string>
<string name="shutdown_alert_desc">Сповіщення перестануть працювати, поки ви не перезапустите додаток</string>
<string name="you_can_create_it_later">Ви можете створити його пізніше</string>
<string name="your_contacts_will_see_it">Ваші контакти в SimpleX побачать це.
\nВи можете змінити його в Налаштуваннях.</string>
<string name="your_current_profile">Ваш поточний профіль</string>
<string name="delete_image">Видалити зображення</string>
<string name="save_preferences_question">Зберегти налаштування\?</string>

View File

@ -1211,8 +1211,6 @@
<string name="email_invite_body">你好!
\n用 SimpleX Chat 与我联系:%s</string>
<string name="email_invite_subject">让我们一起在 SimpleX Chat 里聊天</string>
<string name="your_contacts_will_see_it">您的 SimpleX 的联系人会看到它。
\n您可以在设置中更改它。</string>
<string name="you_can_create_it_later">您可以以后创建它</string>
<string name="share_address">分享地址</string>
<string name="you_can_share_this_address_with_your_contacts">您可以与您的联系人分享该地址,让他们与 %s 联系。</string>

View File

@ -1178,8 +1178,6 @@
<string name="all_app_data_will_be_cleared">已刪除所有的應用程式數據。</string>
<string name="set_passcode">設定密碼</string>
<string name="you_can_share_this_address_with_your_contacts">你可以與聯絡人分享此地址,讓他們使用 %s 進行連接。</string>
<string name="your_contacts_will_see_it">在 SimpleX ,你的聯絡人會看到此。
\n你可以在設定中修改。</string>
<string name="you_can_create_it_later">你可以在稍後建立它</string>
<string name="scan_qr_to_connect_to_contact">為了連接,你的聯絡人可以掃描二維碼或使用此應用程式的連結。</string>
<string name="if_you_cant_meet_in_person">如果你不能面對面接觸此聯絡人,可於視訊通話中出示你的二維碼,或者分享連結。</string>

View File

@ -14,7 +14,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: 1e15d56e92c0549c7ba6a60d2c9d557b2949b0ff
tag: 22e193237227ed4d243ec9cac8d8249f757d9601
source-repository-package
type: git

View File

@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."1e15d56e92c0549c7ba6a60d2c9d557b2949b0ff" = "1miy6452py1hbf5d1z1zq3krx8b1fncix8xvzgpxxyfw8qq0gw4b";
"https://github.com/simplex-chat/simplexmq.git"."22e193237227ed4d243ec9cac8d8249f757d9601" = "01h16jc0g5pqdq56k1n0afl2248ln2d11l662ikl6hdn3p3zab0d";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";

View File

@ -118,7 +118,7 @@ cChatMigrateInitKey fp key keepKey conf background ctrl = do
setFileSystemEncoding utf8
setForeignEncoding utf8
dbPath <- peekCAString fp
dbPath <- peekCString fp
dbKey <- BA.convert <$> B.packCString key
confirm <- peekCAString conf
r <-

View File

@ -72,11 +72,11 @@ import UnliftIO.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExis
-- when acting as host
minRemoteCtrlVersion :: AppVersion
minRemoteCtrlVersion = AppVersion [5, 4, 0, 4]
minRemoteCtrlVersion = AppVersion [5, 4, 2, 0]
-- when acting as controller
minRemoteHostVersion :: AppVersion
minRemoteHostVersion = AppVersion [5, 4, 0, 4]
minRemoteHostVersion = AppVersion [5, 4, 2, 0]
currentAppVersion :: AppVersion
currentAppVersion = AppVersion SC.version

View File

@ -70,6 +70,8 @@ chatGroupTests = do
it "re-join existing group after leaving" testPlanGroupLinkLeaveRejoin
describe "group links without contact" $ do
it "join via group link without creating contact" testGroupLinkNoContact
it "invitees were previously connected as contacts" testGroupLinkNoContactInviteesWereConnected
it "all members were previously connected as contacts" testGroupLinkNoContactAllMembersWereConnected
it "group link member role" testGroupLinkNoContactMemberRole
it "host incognito" testGroupLinkNoContactHostIncognito
it "invitee incognito" testGroupLinkNoContactInviteeIncognito
@ -2714,6 +2716,169 @@ testGroupLinkNoContact =
alice <# "#team bob> hi cath"
cath <# "#team bob> hi cath"
testGroupLinkNoContactInviteesWereConnected :: HasCallStack => FilePath -> IO ()
testGroupLinkNoContactInviteesWereConnected =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
connectUsers bob cath
bob <##> cath
alice ##> "/g team"
alice <## "group #team is created"
alice <## "to add members use /a team <name> or /create link #team"
alice ##> "/set history #team off"
alice <## "updated group preferences:"
alice <## "Recent history: off"
alice ##> "/create link #team"
gLink <- getGroupLink alice "team" GRMember True
bob ##> ("/c " <> gLink)
bob <## "connection request sent!"
alice <## "bob (Bob): accepting request to join group #team..."
concurrentlyN_
[ alice <## "#team: bob joined the group",
do
bob <## "#team: joining the group..."
bob <## "#team: you joined the group"
]
threadDelay 100000
alice #$> ("/_get chat #1 count=100", chat, [(0, "invited via your group link"), (0, "connected")])
alice @@@ [("#team", "connected")]
bob @@@ [("#team", "connected"), ("@cath", "hey")]
alice ##> "/contacts"
bob ##> "/contacts"
bob <## "cath (Catherine)"
alice #> "#team hello"
bob <# "#team alice> hello"
bob #> "#team hi there"
alice <# "#team bob> hi there"
cath ##> ("/c " <> gLink)
cath <## "connection request sent!"
concurrentlyN_
[ do
alice <## "cath (Catherine): accepting request to join group #team..."
alice <## "#team: cath joined the group",
cath
<### [ "#team: joining the group...",
"#team: you joined the group",
"#team: member bob_1 (Bob) is connected",
"contact and member are merged: bob, #team bob_1",
"use @bob <message> to send messages"
],
bob
<### [ "#team: alice added cath_1 (Catherine) to the group (connecting...)",
"#team: new member cath_1 is connected",
"contact and member are merged: cath, #team cath_1",
"use @cath <message> to send messages"
]
]
-- message delivery works
bob <##> cath
alice #> "#team 1"
[bob, cath] *<# "#team alice> 1"
bob #> "#team 2"
[alice, cath] *<# "#team bob> 2"
cath #> "#team 3"
[alice, bob] *<# "#team cath> 3"
testGroupLinkNoContactAllMembersWereConnected :: HasCallStack => FilePath -> IO ()
testGroupLinkNoContactAllMembersWereConnected =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
connectUsers alice bob
alice <##> bob
connectUsers alice cath
alice <##> cath
connectUsers bob cath
bob <##> cath
alice ##> "/g team"
alice <## "group #team is created"
alice <## "to add members use /a team <name> or /create link #team"
alice ##> "/set history #team off"
alice <## "updated group preferences:"
alice <## "Recent history: off"
alice ##> "/create link #team"
gLink <- getGroupLink alice "team" GRMember True
bob ##> ("/c " <> gLink)
bob <## "connection request sent!"
alice <## "bob_1 (Bob): accepting request to join group #team..."
concurrentlyN_
[ do
alice <## "#team: bob_1 joined the group"
alice <## "contact and member are merged: bob, #team bob_1"
alice <## "use @bob <message> to send messages",
do
bob <## "#team: joining the group..."
bob <## "#team: you joined the group"
bob <## "contact and member are merged: alice, #team alice_1"
bob <## "use @alice <message> to send messages"
]
threadDelay 100000
alice #$> ("/_get chat #1 count=100", chat, [(0, "invited via your group link"), (0, "connected")])
alice @@@ [("#team", "connected"), ("@bob", "hey"), ("@cath", "hey")]
bob @@@ [("#team", "connected"), ("@alice", "hey"), ("@cath", "hey")]
alice ##> "/contacts"
alice <## "bob (Bob)"
alice <## "cath (Catherine)"
bob ##> "/contacts"
bob <## "alice (Alice)"
bob <## "cath (Catherine)"
alice #> "#team hello"
bob <# "#team alice> hello"
bob #> "#team hi there"
alice <# "#team bob> hi there"
cath ##> ("/c " <> gLink)
cath <## "connection request sent!"
concurrentlyN_
[ alice
<### [ "cath_1 (Catherine): accepting request to join group #team...",
"#team: cath_1 joined the group",
"contact and member are merged: cath, #team cath_1",
"use @cath <message> to send messages"
],
cath
<### [ "#team: joining the group...",
"#team: you joined the group",
"#team: member bob_1 (Bob) is connected",
"contact and member are merged: bob, #team bob_1",
"use @bob <message> to send messages",
"contact and member are merged: alice, #team alice_1",
"use @alice <message> to send messages"
],
bob
<### [ "#team: alice added cath_1 (Catherine) to the group (connecting...)",
"#team: new member cath_1 is connected",
"contact and member are merged: cath, #team cath_1",
"use @cath <message> to send messages"
]
]
-- message delivery works
alice <##> bob
alice <##> cath
bob <##> cath
alice #> "#team 1"
[bob, cath] *<# "#team alice> 1"
bob #> "#team 2"
[alice, cath] *<# "#team bob> 2"
cath #> "#team 3"
[alice, bob] *<# "#team cath> 3"
testGroupLinkNoContactMemberRole :: HasCallStack => FilePath -> IO ()
testGroupLinkNoContactMemberRole =
testChat3 aliceProfile bobProfile cathProfile $