diff --git a/src/Simplex/Chat/Core.hs b/src/Simplex/Chat/Core.hs index 6b48e824aa..1c4de3aa46 100644 --- a/src/Simplex/Chat/Core.hs +++ b/src/Simplex/Chat/Core.hs @@ -19,6 +19,7 @@ import Control.Monad.Except import Control.Monad.Reader import qualified Data.ByteString.Char8 as B import Data.List (find) +import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8) import Data.Time.Clock (getCurrentTime) @@ -43,7 +44,7 @@ import Text.Read (readMaybe) import UnliftIO.Async simplexChatCore :: ChatConfig -> ChatOpts -> (User -> ChatController -> IO ()) -> IO () -simplexChatCore cfg@ChatConfig {confirmMigrations, testView, chatHooks} opts@ChatOpts {coreOptions = coreOptions@CoreChatOpts {dbOptions, logAgent, yesToUpMigrations, migrationBackupPath, maintenance}, createBot} chat = +simplexChatCore cfg@ChatConfig {confirmMigrations, testView, chatHooks} opts@ChatOpts {coreOptions = coreOptions@CoreChatOpts {dbOptions, logAgent, yesToUpMigrations, migrationBackupPath, maintenance}, createBot, userDisplayName} chat = case logAgent of Just level -> do setLogLevel level @@ -58,10 +59,14 @@ simplexChatCore cfg@ChatConfig {confirmMigrations, testView, chatHooks} opts@Cha run db@ChatDatabase {chatStore} = do users <- withTransaction chatStore getUsers u_ <- selectActiveUser coreOptions chatStore users + forM_ ((,) <$> userDisplayName <*> u_) $ \(name, User {localDisplayName}) -> + when (localDisplayName /= name) $ do + putStrLn $ "Active user display name " <> show localDisplayName <> " does not match --user-display-name " <> show name + exitFailure let backgroundMode = maintenance cc <- newChatController db u_ cfg opts backgroundMode forM_ (preStartHook chatHooks) ($ cc) - u <- maybe (noMaintenance >> createActiveUser cc coreOptions createBot) pure u_ + u <- maybe (noMaintenance >> createActiveUser cc coreOptions createBot userDisplayName) pure u_ unless testView $ putStrLn $ "Current user: " <> userStr u runSimplexChat cfg opts u cc chat noMaintenance = when maintenance $ do @@ -116,24 +121,26 @@ selectActiveUser CoreChatOpts {chatRelay} st users let user = users !! (n - 1) in Just <$> withTransaction st (`setActiveUser` user) -createActiveUser :: ChatController -> CoreChatOpts -> Maybe CreateBotOpts -> IO User -createActiveUser cc CoreChatOpts {chatRelay} = \case +createActiveUser :: ChatController -> CoreChatOpts -> Maybe CreateBotOpts -> Maybe Text -> IO User +createActiveUser cc CoreChatOpts {chatRelay} createBot_ userDisplayName_ = case createBot_ of Just CreateBotOpts {botDisplayName, allowFiles} -> do let preferences = if allowFiles then Nothing else Just emptyChatPrefs {files = Just FilesPreference {allow = FANo}} createUser exitFailure $ (mkProfile botDisplayName) {peerType = Just CPTBot, preferences} - Nothing - | chatRelay -> do - putStrLn - "No chat relay user profile found, it will be created now.\n\ - \Please choose chat relay display name." - loop - | otherwise -> do - putStrLn - "No user profiles found, it will be created now.\n\ - \Please choose your display name.\n\ - \It will be sent to your contacts when you connect.\n\ - \It is only stored on your device and you can change it later." - loop + Nothing -> case userDisplayName_ of + Just displayName -> createUser exitFailure $ mkProfile displayName + Nothing + | chatRelay -> do + putStrLn + "No chat relay user profile found, it will be created now.\n\ + \Please choose chat relay display name." + loop + | otherwise -> do + putStrLn + "No user profiles found, it will be created now.\n\ + \Please choose your display name.\n\ + \It will be sent to your contacts when you connect.\n\ + \It is only stored on your device and you can change it later." + loop where loop = do displayName <- T.pack <$> withPrompt "display name: " getLine diff --git a/src/Simplex/Chat/Mobile.hs b/src/Simplex/Chat/Mobile.hs index f061061327..3364a9d477 100644 --- a/src/Simplex/Chat/Mobile.hs +++ b/src/Simplex/Chat/Mobile.hs @@ -271,7 +271,8 @@ mobileChatOpts dbOptions = autoAcceptFileSize = 0, muteNotifications = True, markRead = False, - createBot = Nothing + createBot = Nothing, + userDisplayName = Nothing } defaultMobileConfig :: ChatConfig diff --git a/src/Simplex/Chat/Options.hs b/src/Simplex/Chat/Options.hs index 7f7d7edb22..236f61c049 100644 --- a/src/Simplex/Chat/Options.hs +++ b/src/Simplex/Chat/Options.hs @@ -22,7 +22,7 @@ where import Control.Logger.Simple (LogLevel (..)) import qualified Data.Attoparsec.ByteString.Char8 as A import qualified Data.ByteString.Char8 as B -import Data.Maybe (fromMaybe) +import Data.Maybe (fromMaybe, isJust) import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8) @@ -50,7 +50,8 @@ data ChatOpts = ChatOpts autoAcceptFileSize :: Integer, muteNotifications :: Bool, markRead :: Bool, - createBot :: Maybe CreateBotOpts + createBot :: Maybe CreateBotOpts, + userDisplayName :: Maybe Text } data CoreChatOpts = CoreChatOpts @@ -402,6 +403,13 @@ chatOptsP appDir defaultDbName = do ( long "create-bot-allow-files" <> help "Flag for created bot to allow files (only allowed together with --create-bot option)" ) + userDisplayName <- + optional $ + strOption + ( long "user-display-name" + <> metavar "NAME" + <> help "Use existing active user with this display name, or create one on the first start (incompatible with --create-bot-display-name)" + ) pure ChatOpts { coreOptions, @@ -417,10 +425,13 @@ chatOptsP appDir defaultDbName = do muteNotifications, markRead, createBot = case createBotDisplayName of - Just botDisplayName -> Just CreateBotOpts {botDisplayName, allowFiles = createBotAllowFiles} + Just botDisplayName + | isJust userDisplayName -> error "--user-display-name and --create-bot-display-name are mutually exclusive" + | otherwise -> Just CreateBotOpts {botDisplayName, allowFiles = createBotAllowFiles} Nothing | createBotAllowFiles -> error "--create-bot-allow-files option requires --create-bot-name option" - | otherwise -> Nothing + | otherwise -> Nothing, + userDisplayName } parseProtocolServers :: ProtocolTypeI p => ReadM [ProtoServerWithAuth p]