terminal: add /image command to send file as image (#681)

* terminal: add /image command sending file as image

* terminal: forward file commands

* terminal: update help

* terminal: update placeholder image

* Update src/Simplex/Chat/Help.hs

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>

* help

* allow forwarding sent file

* typo

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
JRoberts
2022-05-21 18:17:15 +04:00
committed by GitHub
parent d971e7c31f
commit 6ad2eeec89
4 changed files with 40 additions and 2 deletions
+27 -1
View File
@@ -30,7 +30,7 @@ import Data.Char (isSpace)
import Data.Fixed (div')
import Data.Functor (($>))
import Data.Int (Int64)
import Data.List (find)
import Data.List (find, isSuffixOf)
import Data.List.NonEmpty (NonEmpty, nonEmpty)
import qualified Data.List.NonEmpty as L
import Data.Map.Strict (Map)
@@ -105,6 +105,12 @@ _defaultSMPServers =
_defaultNtfServers :: [NtfServer]
_defaultNtfServers = ["smp://ZH1Dkt2_EQRbxUUyjLlcUjg1KAhBrqfvE0xfn7Ki0Zg=@ntf1.simplex.im"]
maxImageSize :: Integer
maxImageSize = 236700
fixedImagePreview :: ImageData
fixedImagePreview = ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAKVJREFUeF7t1kENACEUQ0FQhnVQ9lfGO+xggITQdvbMzArPey+8fa3tAfwAEdABZQspQStgBssEcgAIkSAJkiAJljtEgiRIgmUCSZAESZAESZAEyx0iQRIkwTKBJEiCv5fgvTd1wDmn7QAP4AeIgA4oW0gJWgEzWCZwbQ7gAA7ggLKFOIADOKBMIAeAEAmSIAmSYLlDJEiCJFgmkARJkARJ8N8S/ADTZUewBvnTOQAAAABJRU5ErkJggg=="
logCfg :: LogConfig
logCfg = LogConfig {lc_file = Nothing, lc_stderr = True}
@@ -688,6 +694,15 @@ processChatCommand = \case
SendFile chatName f -> withUser $ \user -> do
chatRef <- getChatRef user chatName
processChatCommand . APISendMessage chatRef $ ComposedMessage (Just f) Nothing (MCFile "")
SendImage chatName f -> withUser $ \user -> do
chatRef <- getChatRef user chatName
filePath <- toFSFilePath f
unless (".jpg" `isSuffixOf` f || ".jpeg" `isSuffixOf` f) $ throwChatError CEFileImageType {filePath}
fileSize <- getFileSize filePath
unless (fileSize <= maxImageSize) $ throwChatError CEFileImageSize {filePath}
processChatCommand . APISendMessage chatRef $ ComposedMessage (Just f) Nothing (MCImage "" fixedImagePreview)
ForwardFile chatName fileId -> forwardFile chatName fileId SendFile
ForwardImage chatName fileId -> forwardFile chatName fileId SendImage
ReceiveFile fileId filePath_ -> withUser $ \user ->
withChatLock . procCmd $ do
ft <- withStore $ \st -> getRcvFileTransfer st user fileId
@@ -829,6 +844,14 @@ processChatCommand = \case
_ -> TM.delete ctId calls
pure CRCmdOk
| otherwise -> throwChatError $ CECallContact contactId
forwardFile :: ChatName -> FileTransferId -> (ChatName -> FilePath -> ChatCommand) -> m ChatResponse
forwardFile chatName fileId sendCommand = withUser $ \user -> do
withStore (\st -> getFileTransfer st user fileId) >>= \case
FTRcv RcvFileTransfer {fileStatus = RFSComplete RcvFileInfo {filePath}} -> forward filePath
FTSnd {fileTransferMeta = FileTransferMeta {filePath}} -> forward filePath
_ -> throwChatError CEFileNotReceived {fileId}
where
forward = processChatCommand . sendCommand chatName
updateCallItemStatus :: ChatMonad m => UserId -> Contact -> Call -> WebRTCCallStatus -> Maybe MessageId -> m ()
updateCallItemStatus userId ct Call {chatItemId} receivedStatus msgId_ = do
@@ -2237,6 +2260,9 @@ chatCommandP =
<|> "/feed " *> (SendMessageBroadcast <$> A.takeByteString)
<|> ("/tail" <|> "/t") *> (LastMessages <$> optional (A.space *> chatNameP) <*> msgCountP)
<|> ("/file " <|> "/f ") *> (SendFile <$> chatNameP' <* A.space <*> filePath)
<|> ("/image " <|> "/img ") *> (SendImage <$> chatNameP' <* A.space <*> filePath)
<|> ("/fforward " <|> "/ff ") *> (ForwardFile <$> chatNameP' <* A.space <*> A.decimal)
<|> ("/image_forward " <|> "/imgf ") *> (ForwardImage <$> chatNameP' <* A.space <*> A.decimal)
<|> ("/freceive " <|> "/fr ") *> (ReceiveFile <$> A.decimal <*> optional (A.space *> filePath))
<|> ("/fcancel " <|> "/fc ") *> (CancelFile <$> A.decimal)
<|> ("/fstatus " <|> "/fs ") *> (FileStatus <$> A.decimal)
+6
View File
@@ -160,6 +160,9 @@ data ChatCommand
| SendGroupMessageQuote {groupName :: GroupName, contactName_ :: Maybe ContactName, quotedMsg :: ByteString, message :: ByteString}
| LastMessages (Maybe ChatName) Int
| SendFile ChatName FilePath
| SendImage ChatName FilePath
| ForwardFile ChatName FileTransferId
| ForwardImage ChatName FileTransferId
| ReceiveFile FileTransferId (Maybe FilePath)
| CancelFile FileTransferId
| FileStatus FileTransferId
@@ -349,6 +352,9 @@ data ChatErrorType
| CEFileSend {fileId :: FileTransferId, agentError :: AgentErrorType}
| CEFileRcvChunk {message :: String}
| CEFileInternal {message :: String}
| CEFileImageType {filePath :: FilePath}
| CEFileImageSize {filePath :: FilePath}
| CEFileNotReceived {fileId :: FileTransferId}
| CEInvalidQuote
| CEInvalidChatItemUpdate
| CEInvalidChatItemDelete
+3 -1
View File
@@ -102,11 +102,13 @@ filesHelpInfo =
[ green "File transfer commands:",
indent <> highlight "/file @<contact> <file_path> " <> " - send file to contact",
indent <> highlight "/file #<group> <file_path> " <> " - send file to group",
indent <> highlight "/image <name> [<file_path>] " <> " - send file as image to @contact or #group",
indent <> highlight "/freceive <file_id> [<file_path>]" <> " - accept to receive file",
indent <> highlight "/fforward <name> [<file_id>] " <> " - forward received file to @contact or #group",
indent <> highlight "/fcancel <file_id> " <> " - cancel sending / receiving file",
indent <> highlight "/fstatus <file_id> " <> " - show file transfer status",
"",
"The commands may be abbreviated: " <> listHighlight ["/f", "/fr", "/fc", "/fs"]
"The commands may be abbreviated: " <> listHighlight ["/f", "/img", "/fr", "/ff", "/fc", "/fs"]
]
groupsHelpInfo :: [StyledString]
+4
View File
@@ -27,6 +27,7 @@ import Data.Time.LocalTime (ZonedTime (..), localDay, localTimeOfDay, timeOfDayT
import GHC.Generics (Generic)
import qualified Network.HTTP.Types as Q
import Numeric (showFFloat)
import Simplex.Chat (maxImageSize)
import Simplex.Chat.Call
import Simplex.Chat.Controller
import Simplex.Chat.Help
@@ -739,6 +740,9 @@ viewChatError = \case
CEFileSend fileId e -> ["error sending file " <> sShow fileId <> ": " <> sShow e]
CEFileRcvChunk e -> ["error receiving file: " <> plain e]
CEFileInternal e -> ["file error: " <> plain e]
CEFileImageType _ -> ["max image size: " <> sShow maxImageSize <> " bytes, resize it or send as a file using " <> highlight' "/f"]
CEFileImageSize _ -> ["image type must be JPG, send as a file using " <> highlight' "/f"]
CEFileNotReceived fileId -> ["file " <> sShow fileId <> " not received"]
CEInvalidQuote -> ["cannot reply to this message"]
CEInvalidChatItemUpdate -> ["cannot update this item"]
CEInvalidChatItemDelete -> ["cannot delete this item"]