From 549ffcefc0b10d7bdb7e98e5dbe2a7c53ce6e25b Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:57:06 +0100 Subject: [PATCH 1/3] blog: v5 announcement placeholder --- ...vision-funding-v5-videos-files-passcode.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.md diff --git a/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.md b/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.md new file mode 100644 index 0000000000..28dc96837a --- /dev/null +++ b/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.md @@ -0,0 +1,32 @@ +--- +layout: layouts/article.html +title: "SimpleX Chat: vision and funding, v5.0 released with videos and files up to 1gb" +date: 2023-04-22 +preview: This version integrates the support of XFTP protocol, allowing to receive up to 1gb files, even when the sender is offline. +# image: images/20230301-xftp.jpg +permalink: "/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.html" +--- + +# SimpleX Chat: vision and funding, v5.0 released with videos and files up to 1gb. + +**Published:** Apr 22, 2023 + +This is a placeholder for v5.0 release announcement. + +## SimpleX Chat vision and funding + +## What's new in v5.0 + +- [send videos and files up to 1gb](#send-files-up-to-1gb) +- [app passcode independent from system authentication](#app-passcode) +- [networking improvements](#networking-improvements) + +Also, we added Polish interface language, thanks to [the users' community and Weblate](https://github.com/simplex-chat/simplex-chat#help-translating-simplex-chat). + +SimpleX Chat apps are now available in 10 languages! + +### Send videos and files up to 1gb! + +### App passcode + +### Networking improvements From a06393f520ae3662538d9c4afe023548e0998d2d Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Fri, 21 Apr 2023 13:36:44 +0400 Subject: [PATCH 2/3] core: file status command for XFTP files (#2222) --- src/Simplex/Chat.hs | 9 +++++++-- src/Simplex/Chat/Controller.hs | 1 + src/Simplex/Chat/View.hs | 23 +++++++++++++++++++++ tests/ChatTests/Files.hs | 37 ++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 9c7db2e5b9..d0ed3f3d92 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -1454,8 +1454,13 @@ processChatCommand = \case getChatItemByFileId db user fileId pure $ CRRcvFileCancelled user ci ftr FileStatus fileId -> withUser $ \user -> do - fileStatus <- withStore $ \db -> getFileTransferProgress db user fileId - pure $ CRFileTransferStatus user fileStatus + ci@(AChatItem _ _ _ ChatItem {file}) <- withStore $ \db -> getChatItemByFileId db user fileId + case file of + Just CIFile {fileProtocol = FPXFTP} -> + pure $ CRFileTransferStatusXFTP user ci + _ -> do + fileStatus <- withStore $ \db -> getFileTransferProgress db user fileId + pure $ CRFileTransferStatus user fileStatus ShowProfile -> withUser $ \user@User {profile} -> pure $ CRUserProfile user (fromLocalProfile profile) UpdateProfile displayName fullName -> withUser $ \user@User {profile} -> do let p = (fromLocalProfile profile :: Profile) {displayName = displayName, fullName = fullName} diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index b793d8497c..b463ad65da 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -411,6 +411,7 @@ data ChatResponse | CRGroupsList {user :: User, groups :: [GroupInfo]} | CRSentGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, member :: GroupMember} | CRFileTransferStatus User (FileTransfer, [Integer]) -- TODO refactor this type to FileTransferStatus + | CRFileTransferStatusXFTP User AChatItem | CRUserProfile {user :: User, profile :: Profile} | CRUserProfileNoChange {user :: User} | CRUserPrivacy {user :: User, updatedUser :: User} diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 93b946bf9b..33223f3ff6 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -118,6 +118,7 @@ responseToView user_ ChatConfig {logLevel, testView} liveItems ts = \case then [ttyContact' c <> " invited to group " <> ttyGroup' g <> " via your group link"] else ["invitation to join the group " <> ttyGroup' g <> " sent to " <> ttyContact' c] CRFileTransferStatus u ftStatus -> ttyUser u $ viewFileTransferStatus ftStatus + CRFileTransferStatusXFTP u ci -> ttyUser u $ viewFileTransferStatusXFTP ci CRUserProfile u p -> ttyUser u $ viewUserProfile p CRUserProfileNoChange u -> ttyUser u ["user profile did not change"] CRUserPrivacy u u' -> ttyUserPrefix u $ viewUserPrivacy u u' @@ -1166,6 +1167,24 @@ viewFileTransferStatus (FTRcv ft@RcvFileTransfer {fileId, fileInvitation = FileI RFSCancelled (Just RcvFileInfo {filePath}) -> "cancelled, received part path: " <> plain filePath RFSCancelled Nothing -> "cancelled" +viewFileTransferStatusXFTP :: AChatItem -> [StyledString] +viewFileTransferStatusXFTP (AChatItem _ _ _ ChatItem {file = Just CIFile {fileId, fileName, fileSize, fileStatus, filePath}}) = + case fileStatus of + CIFSSndStored -> ["sending " <> fstr <> " just started"] + CIFSSndTransfer progress total -> ["sending " <> fstr <> " in progress " <> fileProgressXFTP progress total fileSize] + CIFSSndCancelled -> ["sending " <> fstr <> " cancelled"] + CIFSSndComplete -> ["sending " <> fstr <> " complete"] + CIFSSndError -> ["sending " <> fstr <> " error"] + CIFSRcvInvitation -> ["receiving " <> fstr <> " not accepted yet, use " <> highlight ("/fr " <> show fileId) <> " to receive file"] + CIFSRcvAccepted -> ["receiving " <> fstr <> " just started"] + CIFSRcvTransfer progress total -> ["receiving " <> fstr <> " progress " <> fileProgressXFTP progress total fileSize] + CIFSRcvComplete -> ["receiving " <> fstr <> " complete" <> maybe "" (\fp -> ", path: " <> plain fp) filePath] + CIFSRcvCancelled -> ["receiving " <> fstr <> " cancelled"] + CIFSRcvError -> ["receiving " <> fstr <> " error"] + where + fstr = fileTransferStr fileId fileName +viewFileTransferStatusXFTP _ = ["no file status"] + listRecipients :: [SndFileTransfer] -> StyledString listRecipients = mconcat . intersperse ", " . map (ttyContact . recipientDisplayName) @@ -1173,6 +1192,10 @@ fileProgress :: [Integer] -> Integer -> Integer -> StyledString fileProgress chunksNum chunkSize fileSize = sShow (sum chunksNum * chunkSize * 100 `div` fileSize) <> "% of " <> humanReadableSize fileSize +fileProgressXFTP :: Int64 -> Int64 -> Integer -> StyledString +fileProgressXFTP progress total fileSize = + sShow (progress * 100 `div` total) <> "% of " <> humanReadableSize fileSize + viewCallInvitation :: Contact -> CallType -> Maybe C.Key -> [StyledString] viewCallInvitation ct@Contact {contactId} callType@CallType {media} sharedKey = [ ttyContact' ct <> " wants to connect with you via WebRTC " <> callMediaStr callType <> " call " <> encryptedCallText callType, diff --git a/tests/ChatTests/Files.hs b/tests/ChatTests/Files.hs index d758ac4077..862dcc5489 100644 --- a/tests/ChatTests/Files.hs +++ b/tests/ChatTests/Files.hs @@ -995,6 +995,11 @@ testXFTPFileTransfer = bob <## "started receiving file 1 (test.pdf) from alice" bob <## "completed receiving file 1 (test.pdf) from alice" + alice ##> "/fs 1" + alice <## "sending file 1 (test.pdf) complete" + bob ##> "/fs 1" + bob <## "receiving file 1 (test.pdf) complete, path: ./tests/tmp/test.pdf" + src <- B.readFile "./tests/fixtures/test.pdf" dest <- B.readFile "./tests/tmp/test.pdf" dest `shouldBe` src @@ -1118,6 +1123,13 @@ testXFTPDeleteUploadedFileGroup = ] bob <## "completed receiving file 1 (test.pdf) from alice" + alice ##> "/fs 1" + alice <## "sending file 1 (test.pdf) complete" + bob ##> "/fs 1" + bob <## "receiving file 1 (test.pdf) complete, path: ./tests/tmp/test.pdf" + cath ##> "/fs 1" + cath <## "receiving file 1 (test.pdf) not accepted yet, use /fr 1 to receive file" + src <- B.readFile "./tests/fixtures/test.pdf" dest <- B.readFile "./tests/tmp/test.pdf" dest `shouldBe` src @@ -1128,6 +1140,13 @@ testXFTPDeleteUploadedFileGroup = cath <## "alice cancelled sending file 1 (test.pdf)" ] + alice ##> "/fs 1" + alice <## "sending file 1 (test.pdf) cancelled" + bob ##> "/fs 1" + bob <## "receiving file 1 (test.pdf) complete, path: ./tests/tmp/test.pdf" + cath ##> "/fs 1" + cath <## "receiving file 1 (test.pdf) cancelled" + cath ##> "/fr 1 ./tests/tmp" cath <## "file cancelled: test.pdf" where @@ -1221,6 +1240,10 @@ testXFTPContinueRcv tmp = do bob ##> "/fr 1 ./tests/tmp" bob <## "started receiving file 1 (test.pdf) from alice" bob <## "saving file 1 from alice to ./tests/tmp/test.pdf" + + bob ##> "/fs 1" + bob <## "receiving file 1 (test.pdf) progress 0% of 266.0 KiB" + (bob "/fs 1" + bob <## "receiving file 1 (test.pdf) error" where cfg = testCfg {xftpFileConfig = Just $ XFTPFileConfig {minFileSize = 0}, tempDir = Just "./tests/tmp"} @@ -1311,9 +1337,17 @@ testXFTPCancelRcvRepeat = alice <## "completed uploading file 1 (testfile) for bob" bob <## "started receiving file 1 (testfile) from alice" + threadDelay 100000 + + bob ##> "/fs 1" + bob <##. "receiving file 1 (testfile) progress" + bob ##> "/fc 1" bob <## "cancelled receiving file 1 (testfile) from alice" + bob ##> "/fs 1" + bob <## "receiving file 1 (testfile) not accepted yet, use /fr 1 to receive file" + bob ##> "/fr 1 ./tests/tmp" bob <### [ "saving file 1 from alice to ./tests/tmp/testfile_1", @@ -1321,6 +1355,9 @@ testXFTPCancelRcvRepeat = ] bob <## "completed receiving file 1 (testfile) from alice" + bob ##> "/fs 1" + bob <## "receiving file 1 (testfile) complete, path: ./tests/tmp/testfile_1" + src <- B.readFile "./tests/tmp/testfile" dest <- B.readFile "./tests/tmp/testfile_1" dest `shouldBe` src From 5e0d6d77b9b8bbdeb4a5356a0789b5332cdf6576 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Fri, 21 Apr 2023 13:46:56 +0400 Subject: [PATCH 3/3] core: check max file size before sending (#2224) --- src/Simplex/Chat.hs | 2 ++ src/Simplex/Chat/Controller.hs | 1 + src/Simplex/Chat/View.hs | 1 + 3 files changed, 4 insertions(+) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index d0ed3f3d92..240b09adad 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -59,6 +59,7 @@ import Simplex.Chat.ProfileGenerator (generateRandomProfile) import Simplex.Chat.Protocol import Simplex.Chat.Store import Simplex.Chat.Types +import Simplex.FileTransfer.Client.Main (maxFileSize) import Simplex.FileTransfer.Client.Presets (defaultXFTPServers) import Simplex.FileTransfer.Description (ValidFileDescription, gb, kb, mb) import Simplex.FileTransfer.Protocol (FileParty (..), FilePartyI) @@ -1596,6 +1597,7 @@ processChatCommand = \case ChatConfig {fileChunkSize, inlineFiles} <- asks config xftpCfg <- readTVarIO =<< asks userXFTPFileConfig fileSize <- getFileSize fsFilePath + when (fromInteger fileSize > maxFileSize) $ throwChatError $ CEFileSize f let chunks = - ((- fileSize) `div` fileChunkSize) fileInline = inlineFileMode mc inlineFiles chunks n fileMode = case xftpCfg of diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index b463ad65da..03f04166ed 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -783,6 +783,7 @@ data ChatErrorType | CEGroupCantResendInvitation {groupInfo :: GroupInfo, contactName :: ContactName} | CEGroupInternal {message :: String} | CEFileNotFound {message :: String} + | CEFileSize {filePath :: FilePath} | CEFileAlreadyReceiving {message :: String} | CEFileCancelled {message :: String} | CEFileCancel {fileId :: FileTransferId, message :: String} diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 33223f3ff6..5eedb8e638 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -1314,6 +1314,7 @@ viewChatError logLevel = \case CEGroupCantResendInvitation g c -> viewCannotResendInvitation g c CEGroupInternal s -> ["chat group bug: " <> plain s] CEFileNotFound f -> ["file not found: " <> plain f] + CEFileSize f -> ["file size exceeds the limit: " <> plain f] CEFileAlreadyReceiving f -> ["file is already being received: " <> plain f] CEFileCancelled f -> ["file cancelled: " <> plain f] CEFileCancel fileId e -> ["error cancelling file " <> sShow fileId <> ": " <> sShow e]