mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-01 09:20:22 +00:00
cli: add new notifications
This commit is contained in:
@@ -67,6 +67,7 @@ runInputLoop ct@ChatTerminal {termState, liveMessageState} cc = forever $ do
|
||||
Right r' -> processResp cmd rh r'
|
||||
Left _ -> when (isMessage cmd) $ echo s
|
||||
printRespToTerminal ct cc False rh r
|
||||
chatResponseNotification ct r
|
||||
mapM_ (startLiveMessage cmd) r
|
||||
where
|
||||
echo s = printToTerminal ct [plain s]
|
||||
|
||||
@@ -6,25 +6,21 @@
|
||||
|
||||
module Simplex.Chat.Terminal.Notification (Notification (..), initializeNotifications) where
|
||||
|
||||
import Control.Monad (void)
|
||||
import Data.List (isInfixOf)
|
||||
import Data.Map (Map, fromList)
|
||||
import qualified Data.Map as M
|
||||
import Data.Maybe (fromMaybe, isJust)
|
||||
import Data.Text (Text)
|
||||
import Data.Maybe (isJust)
|
||||
import qualified Data.Text as T
|
||||
import Simplex.Messaging.Util (catchAll_)
|
||||
import System.Directory (createDirectoryIfMissing, doesFileExist, findExecutable, getAppUserDataDirectory)
|
||||
import System.FilePath (combine)
|
||||
import System.Info (os)
|
||||
import System.Process (readCreateProcess, shell)
|
||||
import System.Process (callProcess)
|
||||
|
||||
data Notification = Notification {title :: Text, text :: Text}
|
||||
data Notification = Notification {title :: T.Text, text :: T.Text}
|
||||
|
||||
initializeNotifications :: IO (Notification -> IO ())
|
||||
initializeNotifications =
|
||||
hideException <$> case os of
|
||||
"darwin" -> pure $ notify macScript
|
||||
"darwin" -> pure macNotify
|
||||
"mingw32" -> initWinNotify
|
||||
"linux" ->
|
||||
doesFileExist "/proc/sys/kernel/osrelease" >>= \case
|
||||
@@ -45,44 +41,36 @@ hideException f a = f a `catchAll_` pure ()
|
||||
initLinuxNotify :: IO (Notification -> IO ())
|
||||
initLinuxNotify = do
|
||||
found <- isJust <$> findExecutable "notify-send"
|
||||
pure $ if found then notify linuxScript else noNotifications
|
||||
pure $ if found then linuxNotify else noNotifications
|
||||
|
||||
notify :: (Notification -> Text) -> Notification -> IO ()
|
||||
notify script notification =
|
||||
void $ readCreateProcess (shell . T.unpack $ script notification) ""
|
||||
linuxNotify :: Notification -> IO ()
|
||||
linuxNotify Notification {title, text} =
|
||||
callProcess "notify-send" [T.unpack title, T.unpack text]
|
||||
|
||||
linuxScript :: Notification -> Text
|
||||
linuxScript Notification {title, text} = "notify-send '" <> linuxEscape title <> "' '" <> linuxEscape text <> "'"
|
||||
macNotify :: Notification -> IO ()
|
||||
macNotify Notification {title, text} =
|
||||
callProcess "osascript" ["-e", "display notification \"" <> macEscape text <> "\" with title \"" <> macEscape title <> "\""]
|
||||
|
||||
linuxEscape :: Text -> Text
|
||||
linuxEscape = replaceAll $ fromList [('\'', "'\\''")]
|
||||
|
||||
macScript :: Notification -> Text
|
||||
macScript Notification {title, text} = "osascript -e 'display notification \"" <> macEscape text <> "\" with title \"" <> macEscape title <> "\"'"
|
||||
|
||||
macEscape :: Text -> Text
|
||||
macEscape = replaceAll $ fromList [('"', "\\\""), ('\'', "")]
|
||||
macEscape :: T.Text -> String
|
||||
macEscape = concatMap esc . T.unpack
|
||||
where
|
||||
esc '\\' = "\\\\"
|
||||
esc '"' = "\\\""
|
||||
esc c = [c]
|
||||
|
||||
initWslNotify :: IO (Notification -> IO ())
|
||||
initWslNotify = notify . wslScript <$> savePowershellScript
|
||||
initWslNotify = wslNotify <$> savePowershellScript
|
||||
|
||||
wslScript :: FilePath -> Notification -> Text
|
||||
wslScript path Notification {title, text} = "powershell.exe \"" <> T.pack path <> " \\\"" <> wslEscape title <> "\\\" \\\"" <> wslEscape text <> "\\\"\""
|
||||
|
||||
wslEscape :: Text -> Text
|
||||
wslEscape = replaceAll $ fromList [('`', "\\`\\`"), ('\\', "\\\\"), ('"', "\\`\\\"")]
|
||||
wslNotify :: FilePath -> Notification -> IO ()
|
||||
wslNotify path Notification {title, text} =
|
||||
callProcess "powershell.exe" ["-File", path, T.unpack title, T.unpack text]
|
||||
|
||||
initWinNotify :: IO (Notification -> IO ())
|
||||
initWinNotify = notify . winScript <$> savePowershellScript
|
||||
initWinNotify = winNotify <$> savePowershellScript
|
||||
|
||||
winScript :: FilePath -> Notification -> Text
|
||||
winScript path Notification {title, text} = "powershell.exe \"" <> T.pack path <> " '" <> winRemoveQuotes title <> "' '" <> winRemoveQuotes text <> "'\""
|
||||
|
||||
winRemoveQuotes :: Text -> Text
|
||||
winRemoveQuotes = replaceAll $ fromList [('`', ""), ('\'', ""), ('"', "")]
|
||||
|
||||
replaceAll :: Map Char Text -> Text -> Text
|
||||
replaceAll rules = T.concatMap $ \c -> T.singleton c `fromMaybe` M.lookup c rules
|
||||
winNotify :: FilePath -> Notification -> IO ()
|
||||
winNotify path Notification {title, text} =
|
||||
callProcess "powershell.exe" ["-File", path, T.unpack title, T.unpack text]
|
||||
|
||||
savePowershellScript :: IO FilePath
|
||||
savePowershellScript = do
|
||||
|
||||
@@ -208,10 +208,22 @@ chatEventNotification t@ChatTerminal {sendNotification} cc = \case
|
||||
when (groupNtf u g False) $ sendNtf ("#" <> viewGroupName g, "member " <> viewMemberName m <> " is connected")
|
||||
CEvtReceivedContactRequest u UserContactRequest {localDisplayName = n} _ ->
|
||||
when (userNtf u) $ sendNtf (viewName n <> ">", "wants to connect to you")
|
||||
CEvtDeletedMemberUser _u g m _withMessages ->
|
||||
sendNtf ("#" <> viewGroupName g, viewMemberName m <> " removed you from the group")
|
||||
_ -> pure ()
|
||||
where
|
||||
sendNtf = maybe (\_ -> pure ()) (. uncurry Notification) sendNotification
|
||||
|
||||
chatResponseNotification :: ChatTerminal -> Either ChatError ChatResponse -> IO ()
|
||||
chatResponseNotification ChatTerminal {sendNotification} = \case
|
||||
Right r -> case r of
|
||||
CRUserContactLinkCreated {} -> sendNtf ("SimpleX", "contact link created")
|
||||
CRUserProfileUpdated {} -> sendNtf ("SimpleX", "profile updated")
|
||||
_ -> pure ()
|
||||
Left _ -> pure ()
|
||||
where
|
||||
sendNtf = maybe (\_ -> pure ()) (. uncurry Notification) sendNotification
|
||||
|
||||
msgText :: MsgContent -> Maybe MarkdownList -> Text
|
||||
msgText (MCFile _) _ = "wants to send a file"
|
||||
msgText mc md_ = maybe (msgContentText mc) (mconcat . map hideSecret) md_
|
||||
|
||||
Reference in New Issue
Block a user