diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index ef98ddc678..d342b277ce 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -1935,7 +1935,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1960,7 +1960,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES_THIN; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -1984,7 +1984,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -2009,7 +2009,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -2025,11 +2025,11 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = 5NN7GUYB6T; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -2045,11 +2045,11 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = 5NN7GUYB6T; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -2070,7 +2070,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GCC_OPTIMIZATION_LEVEL = s; @@ -2085,7 +2085,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2107,7 +2107,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_CODE_COVERAGE = NO; @@ -2122,7 +2122,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2144,7 +2144,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -2170,7 +2170,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; @@ -2195,7 +2195,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -2221,7 +2221,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; @@ -2246,7 +2246,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -2261,7 +2261,7 @@ "@executable_path/../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -2280,7 +2280,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -2295,7 +2295,7 @@ "@executable_path/../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 6.2.1; + MARKETING_VERSION = 6.2.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; diff --git a/apps/multiplatform/android/src/main/AndroidManifest.xml b/apps/multiplatform/android/src/main/AndroidManifest.xml index 67bc0d70c8..bb6a6f8f8a 100644 --- a/apps/multiplatform/android/src/main/AndroidManifest.xml +++ b/apps/multiplatform/android/src/main/AndroidManifest.xml @@ -27,6 +27,14 @@ + + + + + + + + = if (Build.VERSION.SDK_INT >= 33) { +// pm.queryIntentActivities(openIntent, PackageManager.ResolveInfoFlags.of((PackageManager.MATCH_DEFAULT_ONLY).toLong())) +// } else { +// pm.queryIntentActivities(openIntent, PackageManager.MATCH_DEFAULT_ONLY) +// }.sortedBy { it.priority } +// val first = resInfoList.firstOrNull { it.isDefault } ?: resInfoList.firstOrNull() ?: return null + val act = pm.resolveActivity(openIntent, PackageManager.MATCH_DEFAULT_ONLY) ?: return null +// Log.d(TAG, "Default launch action ${act} ${act.loadLabel(pm)} ${act.activityInfo?.name}") + val label = act.loadLabel(pm).toString() + val icon = act.loadIcon(pm).toBitmap().asImageBitmap() + val chooser = act.activityInfo?.name?.endsWith("ResolverActivity") == true + return OpenDefaultApp(label, icon, chooser) } actual fun shareFile(text: String, fileSource: CryptoFile) { diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.android.kt new file mode 100644 index 0000000000..b24150ed24 --- /dev/null +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.android.kt @@ -0,0 +1,57 @@ +package chat.simplex.common.views.chat.item + +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.* +import chat.simplex.common.model.CryptoFile +import chat.simplex.common.platform.* +import chat.simplex.common.views.helpers.DefaultDropdownMenu +import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource +import dev.icerock.moko.resources.compose.stringResource +import java.net.URI + +@Composable +actual fun SaveOrOpenFileMenu( + showMenu: MutableState, + encrypted: Boolean, + ext: String?, + encryptedUri: URI, + fileSource: CryptoFile, + saveFile: () -> Unit +) { + val defaultApp = remember(encryptedUri.toString()) { if (ext != null) queryDefaultAppForExtension(ext, encryptedUri) else null } + DefaultDropdownMenu(showMenu) { + if (defaultApp != null) { + if (!defaultApp.isSystemChooser) { + ItemAction( + stringResource(MR.strings.open_with_app).format(defaultApp.name), + defaultApp.icon, + textColor = MaterialTheme.colors.primary, + onClick = { + openOrShareFile("", fileSource, justOpen = true, useChooser = false) + showMenu.value = false + } + ) + } else { + ItemAction( + stringResource(MR.strings.open_with_app).format("…"), + painterResource(MR.images.ic_open_in_new), + color = MaterialTheme.colors.primary, + onClick = { + openOrShareFile("", fileSource, justOpen = true, useChooser = false) + showMenu.value = false + } + ) + } + } + ItemAction( + stringResource(MR.strings.save_verb), + painterResource(if (encrypted) MR.images.ic_lock_open_right else MR.images.ic_download), + color = MaterialTheme.colors.primary, + onClick = { + saveFile() + showMenu.value = false + } + ) + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt index ed661245a3..9b580edb62 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt @@ -697,13 +697,19 @@ fun ChatInfoHeader(cInfo: ChatInfo, contact: Contact) { Icon(painterResource(MR.images.ic_verified_user), null, tint = MaterialTheme.colors.secondary) } ) + val clipboard = LocalClipboardManager.current + val copyNameToClipboard = { + clipboard.setText(AnnotatedString(contact.profile.displayName)) + showToast(generalGetString(MR.strings.copied)) + } Text( text, inlineContent = inlineContent, style = MaterialTheme.typography.h1.copy(fontWeight = FontWeight.Normal), textAlign = TextAlign.Center, maxLines = 3, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, + modifier = Modifier.combinedClickable(onClick = copyNameToClipboard, onLongClick = copyNameToClipboard).onRightClick(copyNameToClipboard) ) if (cInfo.fullName != "" && cInfo.fullName != cInfo.displayName && cInfo.fullName != contact.profile.displayName) { Text( @@ -711,7 +717,8 @@ fun ChatInfoHeader(cInfo: ChatInfo, contact: Contact) { color = MaterialTheme.colors.onBackground, textAlign = TextAlign.Center, maxLines = 4, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, + modifier = Modifier.combinedClickable(onClick = copyNameToClipboard, onLongClick = copyNameToClipboard).onRightClick(copyNameToClipboard) ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt index 5ee6e40e6e..c92ac2ddc3 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt @@ -9,6 +9,7 @@ import SectionSpacer import SectionTextFooter import SectionView import androidx.compose.desktop.ui.tooling.preview.Preview +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.* import androidx.compose.material.* @@ -17,6 +18,8 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.text.AnnotatedString import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight @@ -446,12 +449,18 @@ private fun GroupChatInfoHeader(cInfo: ChatInfo) { horizontalAlignment = Alignment.CenterHorizontally ) { ChatInfoImage(cInfo, size = 192.dp, iconColor = if (isInDarkTheme()) GroupDark else SettingsSecondaryLight) + val clipboard = LocalClipboardManager.current + val copyNameToClipboard = { + clipboard.setText(AnnotatedString(cInfo.displayName)) + showToast(generalGetString(MR.strings.copied)) + } Text( cInfo.displayName, style = MaterialTheme.typography.h1.copy(fontWeight = FontWeight.Normal), color = MaterialTheme.colors.onBackground, textAlign = TextAlign.Center, maxLines = 4, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, + modifier = Modifier.combinedClickable(onClick = copyNameToClipboard, onLongClick = copyNameToClipboard).onRightClick(copyNameToClipboard) ) if (cInfo.fullName != "" && cInfo.fullName != cInfo.displayName) { Text( @@ -459,7 +468,8 @@ private fun GroupChatInfoHeader(cInfo: ChatInfo) { color = MaterialTheme.colors.onBackground, textAlign = TextAlign.Center, maxLines = 8, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, + modifier = Modifier.combinedClickable(onClick = copyNameToClipboard, onLongClick = copyNameToClipboard).onRightClick(copyNameToClipboard) ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt index e4e5494364..e607efeddc 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt @@ -8,6 +8,7 @@ import SectionSpacer import SectionTextFooter import SectionView import androidx.compose.desktop.ui.tooling.preview.Preview +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.appendInlineContent @@ -537,13 +538,19 @@ fun GroupMemberInfoHeader(member: GroupMember) { Icon(painterResource(MR.images.ic_verified_user), null, tint = MaterialTheme.colors.secondary) } ) + val clipboard = LocalClipboardManager.current + val copyNameToClipboard = { + clipboard.setText(AnnotatedString(member.displayName)) + showToast(generalGetString(MR.strings.copied)) + } Text( text, inlineContent = inlineContent, style = MaterialTheme.typography.h1.copy(fontWeight = FontWeight.Normal), textAlign = TextAlign.Center, maxLines = 3, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, + modifier = Modifier.combinedClickable(onClick = copyNameToClipboard, onLongClick = copyNameToClipboard).onRightClick(copyNameToClipboard) ) if (member.fullName != "" && member.fullName != member.displayName) { Text( @@ -551,7 +558,8 @@ fun GroupMemberInfoHeader(member: GroupMember) { color = MaterialTheme.colors.onBackground, textAlign = TextAlign.Center, maxLines = 4, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, + modifier = Modifier.combinedClickable(onClick = copyNameToClipboard, onLongClick = copyNameToClipboard).onRightClick(copyNameToClipboard) ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt index 59643afdf4..2c16de40e9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt @@ -1,12 +1,12 @@ package chat.simplex.common.views.chat.item -import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -184,14 +184,26 @@ fun CIFileView( } } + val showOpenSaveMenu = rememberSaveable(file?.fileId) { mutableStateOf(false) } + val ext = file?.fileSource?.filePath?.substringAfterLast(".")?.takeIf { it.isNotBlank() } + val loadedFilePath = if (appPlatform.isAndroid && file?.fileSource != null) getLoadedFilePath(file) else null + if (loadedFilePath != null && file?.fileSource != null) { + val encrypted = file.fileSource.cryptoArgs != null + SaveOrOpenFileMenu(showOpenSaveMenu, encrypted, ext, File(loadedFilePath).toURI(), file.fileSource, saveFile = { fileAction() }) + } Row( Modifier .combinedClickable( - onClick = { fileAction() }, + onClick = { + if (appPlatform.isAndroid && loadedFilePath != null) { + showOpenSaveMenu.value = true + } else { + fileAction() + } + }, onLongClick = { showMenu.value = true } ) .padding(if (smallView) PaddingValues() else PaddingValues(top = 4.sp.toDp(), bottom = 6.sp.toDp(), start = 6.sp.toDp(), end = 12.sp.toDp())), - //Modifier.clickable(enabled = file?.fileSource != null) { if (file?.fileSource != null && getLoadedFilePath(file) != null) openFile(file.fileSource) }.padding(top = 4.dp, bottom = 6.dp, start = 6.dp, end = 12.dp), verticalAlignment = Alignment.Bottom, horizontalArrangement = Arrangement.spacedBy(2.sp.toDp()) ) { @@ -223,6 +235,16 @@ fun CIFileView( fun fileSizeValid(file: CIFile): Boolean = file.fileSize <= getMaxFileSize(file.fileProtocol) +@Composable +expect fun SaveOrOpenFileMenu( + showMenu: MutableState, + encrypted: Boolean, + ext: String?, + encryptedUri: URI, + fileSource: CryptoFile, + saveFile: () -> Unit +) + @Composable fun rememberSaveFileLauncher(ciFile: CIFile?): FileChooserLauncher = rememberFileChooserLauncher(false, ciFile) { to: URI? -> diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt index 22842eb350..647c74da06 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt @@ -867,6 +867,32 @@ fun ItemAction(text: String, icon: Painter, color: Color = Color.Unspecified, on } } +@Composable +fun ItemAction(text: String, icon: ImageBitmap, textColor: Color = Color.Unspecified, iconColor: Color = Color.Unspecified, onClick: () -> Unit) { + val finalColor = if (textColor == Color.Unspecified) { + MenuTextColor + } else textColor + DropdownMenuItem(onClick, contentPadding = PaddingValues(horizontal = DEFAULT_PADDING * 1.5f)) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + text, + modifier = Modifier + .fillMaxWidth() + .weight(1F) + .padding(end = 15.dp), + color = finalColor, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + if (iconColor == Color.Unspecified) { + Image(icon, text, Modifier.size(22.dp)) + } else { + Icon(icon, text, Modifier.size(22.dp), tint = iconColor) + } + } + } +} + @Composable fun ItemAction( text: String, diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index a209126a89..a45d1a5458 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -482,6 +482,7 @@ Please, wait while the file is being loaded from the linked mobile File error Temporary file error + Open with %s Voice message diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.desktop.kt new file mode 100644 index 0000000000..eceb7de9be --- /dev/null +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.desktop.kt @@ -0,0 +1,18 @@ +package chat.simplex.common.views.chat.item + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import chat.simplex.common.model.CryptoFile +import java.net.URI + +@Composable +actual fun SaveOrOpenFileMenu( + showMenu: MutableState, + encrypted: Boolean, + ext: String?, + encryptedUri: URI, + fileSource: CryptoFile, + saveFile: () -> Unit +) { + +} diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index cde173f24c..00c7578a8e 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -24,11 +24,11 @@ android.nonTransitiveRClass=true kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.jvm.target=11 -android.version_name=6.2.1 -android.version_code=261 +android.version_name=6.2.2 +android.version_code=263 -desktop.version_name=6.2.1 -desktop.version_code=83 +desktop.version_name=6.2.2 +desktop.version_code=84 kotlin.version=1.9.23 gradle.plugin.version=8.2.0 diff --git a/blog/20241210-simplex-network-v6-2-servers-by-flux-business-chats.md b/blog/20241210-simplex-network-v6-2-servers-by-flux-business-chats.md index 502a42c559..339fab4d16 100644 --- a/blog/20241210-simplex-network-v6-2-servers-by-flux-business-chats.md +++ b/blog/20241210-simplex-network-v6-2-servers-by-flux-business-chats.md @@ -72,7 +72,7 @@ This is a small but important change - you can now see who reacted to your messa ### Improving notifications in iOS app -iOS notifications in a decentralized network is a complex problems. We [support iOS notifications](./20220404-simplex-chat-instant-notifications.md#ios-notifications-require-a-server) from early versions of the app, focussing on preserving privacy as much as possible. But the reliability of notifications was not good enough. +iOS notifications in a decentralized network is a complex problem. We [support iOS notifications](./20220404-simplex-chat-instant-notifications.md#ios-notifications-require-a-server) from early versions of the app, focussing on preserving privacy as much as possible. But the reliability of notifications was not good enough. We solved several problems of notification delivery in this release: - messaging servers no longer lose notifications while notification servers are restarted. diff --git a/cabal.project b/cabal.project index c8ab5b4c28..327342f8a7 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: f5cef2556b05cf384db284644c112f822407b361 + tag: 426bf68763c4461e218f6775e4cec8143393640f source-repository-package type: git diff --git a/package.yaml b/package.yaml index 2eec40d9d1..57e67c3329 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 6.2.0.7 +version: 6.2.2.0 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 7887987f12..353310605f 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."f5cef2556b05cf384db284644c112f822407b361" = "14w0fji1fdr63w4pjkhlrdiz93p2axghzkb1ykvnrw111by87g8l"; + "https://github.com/simplex-chat/simplexmq.git"."426bf68763c4461e218f6775e4cec8143393640f" = "1h2hxn1qv33frpdaspbqz7ivysrnk5lcrgxsv88mk6mbm6bf7cwy"; "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"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 4e917e885b..feabf61bc8 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 6.2.0.7 +version: 6.2.2.0 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 7a23792a6a..69bdddd220 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -36,7 +36,11 @@ import Simplex.Chat.Protocol import Simplex.Chat.Store import Simplex.Chat.Store.Profiles import Simplex.Chat.Types -import Simplex.Chat.Util (shuffle) +import Simplex.Chat.Types.Preferences +import Simplex.Chat.Types.Shared +import Simplex.Chat.Util (encryptFile, liftIOEither, shuffle) +import qualified Simplex.Chat.Util as U +import Simplex.FileTransfer.Description (maxFileSize, maxFileSizeHard) import Simplex.FileTransfer.Client.Presets (defaultXFTPServers) import Simplex.Messaging.Agent as Agent import Simplex.Messaging.Agent.Env.SQLite (AgentConfig (..), InitialAgentServers (..), ServerCfg (..), ServerRoles (..), allRoles, createAgentStore, defaultAgentConfig, presetServerCfg)