mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9a443e049 | |||
| 486c19c1d6 | |||
| 271f0dc6c1 | |||
| ecbcf05218 | |||
| 2dc9c85cf2 | |||
| 587e0a18a9 |
@@ -148,11 +148,11 @@
|
||||
6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */; };
|
||||
6419EC582AB97507004A607A /* CIMemberCreatedContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */; };
|
||||
642BA82D2CE50495005E9412 /* NewServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 642BA82C2CE50495005E9412 /* NewServerView.swift */; };
|
||||
642BA8332CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642BA82E2CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B.a */; };
|
||||
642BA8332CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642BA82E2CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14.a */; };
|
||||
642BA8342CEB3D4B005E9412 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642BA82F2CEB3D4B005E9412 /* libffi.a */; };
|
||||
642BA8352CEB3D4B005E9412 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642BA8302CEB3D4B005E9412 /* libgmp.a */; };
|
||||
642BA8362CEB3D4B005E9412 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642BA8312CEB3D4B005E9412 /* libgmpxx.a */; };
|
||||
642BA8372CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642BA8322CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B-ghc9.6.3.a */; };
|
||||
642BA8372CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642BA8322CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14-ghc9.6.3.a */; };
|
||||
6432857C2925443C00FBE5C8 /* GroupPreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6432857B2925443C00FBE5C8 /* GroupPreferencesView.swift */; };
|
||||
643B3B4E2CCFD6400083A2CF /* OperatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643B3B4D2CCFD6400083A2CF /* OperatorView.swift */; };
|
||||
6440CA00288857A10062C672 /* CIEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6440C9FF288857A10062C672 /* CIEventView.swift */; };
|
||||
@@ -496,11 +496,11 @@
|
||||
6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextInvitingContactMemberView.swift; sourceTree = "<group>"; };
|
||||
6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMemberCreatedContactView.swift; sourceTree = "<group>"; };
|
||||
642BA82C2CE50495005E9412 /* NewServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewServerView.swift; sourceTree = "<group>"; };
|
||||
642BA82E2CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B.a"; sourceTree = "<group>"; };
|
||||
642BA82E2CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14.a"; sourceTree = "<group>"; };
|
||||
642BA82F2CEB3D4B005E9412 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
642BA8302CEB3D4B005E9412 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
642BA8312CEB3D4B005E9412 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
642BA8322CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
642BA8322CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
6432857B2925443C00FBE5C8 /* GroupPreferencesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupPreferencesView.swift; sourceTree = "<group>"; };
|
||||
643B3B4D2CCFD6400083A2CF /* OperatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperatorView.swift; sourceTree = "<group>"; };
|
||||
6440C9FF288857A10062C672 /* CIEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIEventView.swift; sourceTree = "<group>"; };
|
||||
@@ -672,8 +672,8 @@
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
642BA8342CEB3D4B005E9412 /* libffi.a in Frameworks */,
|
||||
642BA8352CEB3D4B005E9412 /* libgmp.a in Frameworks */,
|
||||
642BA8372CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B-ghc9.6.3.a in Frameworks */,
|
||||
642BA8332CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B.a in Frameworks */,
|
||||
642BA8372CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14-ghc9.6.3.a in Frameworks */,
|
||||
642BA8332CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14.a in Frameworks */,
|
||||
642BA8362CEB3D4B005E9412 /* libgmpxx.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -754,8 +754,8 @@
|
||||
642BA82F2CEB3D4B005E9412 /* libffi.a */,
|
||||
642BA8302CEB3D4B005E9412 /* libgmp.a */,
|
||||
642BA8312CEB3D4B005E9412 /* libgmpxx.a */,
|
||||
642BA8322CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B-ghc9.6.3.a */,
|
||||
642BA82E2CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.3-ELfYrsBTXJJ5vBEIgQ1y2B.a */,
|
||||
642BA8322CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14-ghc9.6.3.a */,
|
||||
642BA82E2CEB3D4B005E9412 /* libHSsimplex-chat-6.2.0.1-3FFlorLJSLlCbWWiG2Vp14.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -1931,7 +1931,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -1980,7 +1980,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -2021,7 +2021,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
@@ -2041,7 +2041,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
@@ -2066,7 +2066,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
@@ -2103,7 +2103,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_CODE_COVERAGE = NO;
|
||||
@@ -2140,7 +2140,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -2191,7 +2191,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -2242,7 +2242,7 @@
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
@@ -2276,7 +2276,7 @@
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 249;
|
||||
CURRENT_PROJECT_VERSION = 247;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
|
||||
@@ -24,11 +24,11 @@ android.nonTransitiveRClass=true
|
||||
kotlin.mpp.androidSourceSetLayoutVersion=2
|
||||
kotlin.jvm.target=11
|
||||
|
||||
android.version_name=6.2-beta.3
|
||||
android.version_code=254
|
||||
android.version_name=6.2-beta.1
|
||||
android.version_code=252
|
||||
|
||||
desktop.version_name=6.2-beta.3
|
||||
desktop.version_code=78
|
||||
desktop.version_name=6.2-beta.1
|
||||
desktop.version_code=76
|
||||
|
||||
kotlin.version=1.9.23
|
||||
gradle.plugin.version=8.2.0
|
||||
|
||||
@@ -76,6 +76,7 @@ mkChatOpts BroadcastBotOpts {coreOptions} =
|
||||
ChatOpts
|
||||
{ coreOptions,
|
||||
deviceName = Nothing,
|
||||
userDisplayName = Nothing,
|
||||
chatCmd = "",
|
||||
chatCmdDelay = 3,
|
||||
chatCmdLog = CCLNone,
|
||||
|
||||
@@ -85,6 +85,7 @@ mkChatOpts DirectoryOpts {coreOptions} =
|
||||
ChatOpts
|
||||
{ coreOptions,
|
||||
deviceName = Nothing,
|
||||
userDisplayName = Nothing,
|
||||
chatCmd = "",
|
||||
chatCmdDelay = 3,
|
||||
chatCmdLog = CCLNone,
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
name: simplex-chat
|
||||
version: 6.2.0.3
|
||||
version: 6.2.0.1
|
||||
#synopsis:
|
||||
#description:
|
||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ cabal-version: 1.12
|
||||
-- see: https://github.com/sol/hpack
|
||||
|
||||
name: simplex-chat
|
||||
version: 6.2.0.3
|
||||
version: 6.2.0.1
|
||||
category: Web, System, Services, Cryptography
|
||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||
author: simplex.chat
|
||||
|
||||
+9
-9
@@ -1250,13 +1250,13 @@ processChatCommand' vr = \case
|
||||
when (size' > 0) $ copyChunks r w size'
|
||||
APIUserRead userId -> withUserId userId $ \user -> withFastStore' (`setUserChatsRead` user) >> ok user
|
||||
UserRead -> withUser $ \User {userId} -> processChatCommand $ APIUserRead userId
|
||||
APIChatRead chatRef@(ChatRef cType chatId) -> withUser $ \_ -> case cType of
|
||||
APIChatRead chatRef@(ChatRef cType chatId) fromToIds -> withUser $ \_ -> case cType of
|
||||
CTDirect -> do
|
||||
user <- withFastStore $ \db -> getUserByContactId db chatId
|
||||
ts <- liftIO getCurrentTime
|
||||
timedItems <- withFastStore' $ \db -> do
|
||||
timedItems <- getDirectUnreadTimedItems db user chatId
|
||||
updateDirectChatItemsRead db user chatId
|
||||
timedItems <- getDirectUnreadTimedItems db user chatId fromToIds
|
||||
updateDirectChatItemsRead db user chatId fromToIds
|
||||
setDirectChatItemsDeleteAt db user chatId timedItems ts
|
||||
forM_ timedItems $ \(itemId, deleteAt) -> startProximateTimedItemThread user (chatRef, itemId) deleteAt
|
||||
ok user
|
||||
@@ -1264,14 +1264,14 @@ processChatCommand' vr = \case
|
||||
user <- withFastStore $ \db -> getUserByGroupId db chatId
|
||||
ts <- liftIO getCurrentTime
|
||||
timedItems <- withFastStore' $ \db -> do
|
||||
timedItems <- getGroupUnreadTimedItems db user chatId
|
||||
updateGroupChatItemsRead db user chatId
|
||||
timedItems <- getGroupUnreadTimedItems db user chatId fromToIds
|
||||
updateGroupChatItemsRead db user chatId fromToIds
|
||||
setGroupChatItemsDeleteAt db user chatId timedItems ts
|
||||
forM_ timedItems $ \(itemId, deleteAt) -> startProximateTimedItemThread user (chatRef, itemId) deleteAt
|
||||
ok user
|
||||
CTLocal -> do
|
||||
user <- withFastStore $ \db -> getUserByNoteFolderId db chatId
|
||||
withFastStore' $ \db -> updateLocalChatItemsRead db user chatId
|
||||
withFastStore' $ \db -> updateLocalChatItemsRead db user chatId fromToIds
|
||||
ok user
|
||||
CTContactRequest -> pure $ chatCmdError Nothing "not supported"
|
||||
CTContactConnection -> pure $ chatCmdError Nothing "not supported"
|
||||
@@ -1471,7 +1471,7 @@ processChatCommand' vr = \case
|
||||
withCurrentCall contactId $ \user ct Call {chatItemId, callState} -> case callState of
|
||||
CallInvitationReceived {} -> do
|
||||
let aciContent = ACIContent SMDRcv $ CIRcvCall CISCallRejected 0
|
||||
withFastStore' $ \db -> setDirectChatItemRead db user contactId chatItemId
|
||||
withFastStore' $ \db -> updateDirectChatItemsRead db user contactId $ Just (chatItemId, chatItemId)
|
||||
timed_ <- contactCITimed ct
|
||||
updateDirectChatItemView user ct chatItemId aciContent False False timed_ Nothing
|
||||
forM_ (timed_ >>= timedDeleteAt') $
|
||||
@@ -1487,7 +1487,7 @@ processChatCommand' vr = \case
|
||||
callState' = CallOfferSent {localCallType = callType, peerCallType, localCallSession = rtcSession, sharedKey}
|
||||
aciContent = ACIContent SMDRcv $ CIRcvCall CISCallAccepted 0
|
||||
(SndMessage {msgId}, _) <- sendDirectContactMessage user ct (XCallOffer callId offer)
|
||||
withFastStore' $ \db -> setDirectChatItemRead db user contactId chatItemId
|
||||
withFastStore' $ \db -> updateDirectChatItemsRead db user contactId $ Just (chatItemId, chatItemId)
|
||||
updateDirectChatItemView user ct chatItemId aciContent False False Nothing $ Just msgId
|
||||
pure $ Just call {callState = callState'}
|
||||
_ -> throwChatError . CECallState $ callStateTag callState
|
||||
@@ -8277,7 +8277,7 @@ chatCommandP =
|
||||
"/_forward " *> (APIForwardChatItems <$> chatRefP <* A.space <*> chatRefP <*> _strP <*> sendMessageTTLP),
|
||||
"/_read user " *> (APIUserRead <$> A.decimal),
|
||||
"/read user" $> UserRead,
|
||||
"/_read chat " *> (APIChatRead <$> chatRefP),
|
||||
"/_read chat " *> (APIChatRead <$> chatRefP <*> optional (A.space *> ((,) <$> ("from=" *> A.decimal) <* A.space <*> ("to=" *> A.decimal)))),
|
||||
"/_read chat items " *> (APIChatItemsRead <$> chatRefP <*> _strP),
|
||||
"/_unread chat " *> (APIChatUnread <$> chatRefP <* A.space <*> onOffP),
|
||||
"/_delete " *> (APIDeleteChat <$> chatRefP <*> chatDeleteMode),
|
||||
|
||||
@@ -309,7 +309,7 @@ data ChatCommand
|
||||
| APIForwardChatItems {toChatRef :: ChatRef, fromChatRef :: ChatRef, chatItemIds :: NonEmpty ChatItemId, ttl :: Maybe Int}
|
||||
| APIUserRead UserId
|
||||
| UserRead
|
||||
| APIChatRead ChatRef
|
||||
| APIChatRead ChatRef (Maybe (ChatItemId, ChatItemId))
|
||||
| APIChatItemsRead ChatRef (NonEmpty ChatItemId)
|
||||
| APIChatUnread ChatRef Bool
|
||||
| APIDeleteChat ChatRef ChatDeleteMode -- currently delete mode settings are only applied to direct chats
|
||||
|
||||
+20
-15
@@ -23,31 +23,30 @@ import Simplex.Chat
|
||||
import Simplex.Chat.Controller
|
||||
import Simplex.Chat.Options (ChatOpts (..), CoreChatOpts (..))
|
||||
import Simplex.Chat.Store.Profiles
|
||||
import Simplex.Chat.Types
|
||||
import Simplex.Chat.Types (User (..), Profile (..), NewUser (..), LocalProfile (..))
|
||||
import Simplex.Chat.View (serializeChatResponse)
|
||||
import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore, withTransaction, MigrationConfirmation (..))
|
||||
import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore, withTransaction)
|
||||
import System.Exit (exitFailure)
|
||||
import System.IO (hFlush, stdout)
|
||||
import Text.Read (readMaybe)
|
||||
import UnliftIO.Async
|
||||
|
||||
simplexChatCore :: ChatConfig -> ChatOpts -> (User -> ChatController -> IO ()) -> IO ()
|
||||
simplexChatCore cfg@ChatConfig {confirmMigrations, testView} opts@ChatOpts {coreOptions = CoreChatOpts {dbFilePrefix, dbKey, logAgent, yesToUpMigrations}} chat =
|
||||
simplexChatCore cfg@ChatConfig {confirmMigrations, testView} opts@ChatOpts {coreOptions = CoreChatOpts {dbFilePrefix, dbKey, logAgent}} chat =
|
||||
case logAgent of
|
||||
Just level -> do
|
||||
setLogLevel level
|
||||
withGlobalLogging logCfg initRun
|
||||
_ -> initRun
|
||||
where
|
||||
initRun = createChatDatabase dbFilePrefix dbKey False confirm' >>= either exit run
|
||||
confirm' = if confirmMigrations == MCConsole && yesToUpMigrations then MCYesUp else confirmMigrations
|
||||
initRun = createChatDatabase dbFilePrefix dbKey False confirmMigrations >>= either exit run
|
||||
exit e = do
|
||||
putStrLn $ "Error opening database: " <> show e
|
||||
exitFailure
|
||||
run db@ChatDatabase {chatStore} = do
|
||||
u_ <- getSelectActiveUser chatStore
|
||||
u_ <- getSelectActiveUser chatStore opts
|
||||
cc <- newChatController db u_ cfg opts False
|
||||
u <- maybe (createActiveUser cc) pure u_
|
||||
u <- maybe (createActiveUser cc opts) pure u_
|
||||
unless testView $ putStrLn $ "Current user: " <> userStr u
|
||||
runSimplexChat opts u cc chat
|
||||
|
||||
@@ -65,12 +64,16 @@ sendChatCmdStr cc s = runReaderT (execChatCommand Nothing . encodeUtf8 $ T.pack
|
||||
sendChatCmd :: ChatController -> ChatCommand -> IO ChatResponse
|
||||
sendChatCmd cc cmd = runReaderT (execChatCommand' cmd) cc
|
||||
|
||||
getSelectActiveUser :: SQLiteStore -> IO (Maybe User)
|
||||
getSelectActiveUser st = do
|
||||
getSelectActiveUser :: SQLiteStore -> ChatOpts -> IO (Maybe User)
|
||||
getSelectActiveUser st ChatOpts {userDisplayName} = do
|
||||
users <- withTransaction st getUsers
|
||||
case find activeUser users of
|
||||
Just u -> pure $ Just u
|
||||
Nothing -> selectUser users
|
||||
case userDisplayName of
|
||||
Just name ->
|
||||
forM (find (\User {localDisplayName} -> localDisplayName == name) users) $ \u ->
|
||||
if activeUser u then pure u else withTransaction st (`setActiveUser` u)
|
||||
Nothing -> case find activeUser users of
|
||||
Just u -> pure $ Just u
|
||||
Nothing -> selectUser users
|
||||
where
|
||||
selectUser :: [User] -> IO (Maybe User)
|
||||
selectUser = \case
|
||||
@@ -91,8 +94,8 @@ getSelectActiveUser st = do
|
||||
let user = users !! (n - 1)
|
||||
in Just <$> withTransaction st (`setActiveUser` user)
|
||||
|
||||
createActiveUser :: ChatController -> IO User
|
||||
createActiveUser cc = do
|
||||
createActiveUser :: ChatController -> ChatOpts -> IO User
|
||||
createActiveUser cc ChatOpts {userDisplayName = name} = do
|
||||
putStrLn
|
||||
"No user profiles found, it will be created now.\n\
|
||||
\Please choose your display name.\n\
|
||||
@@ -101,7 +104,9 @@ createActiveUser cc = do
|
||||
loop
|
||||
where
|
||||
loop = do
|
||||
displayName <- T.pack <$> getWithPrompt "display name"
|
||||
displayName <- case name of
|
||||
Just n | not (T.null n) -> pure n
|
||||
_ -> T.pack <$> getWithPrompt "display name"
|
||||
let profile = Just Profile {displayName, fullName = "", image = Nothing, contactLink = Nothing, preferences = Nothing}
|
||||
execChatCommand' (CreateActiveUser NewUser {profile, pastTimestamp = False}) `runReaderT` cc >>= \case
|
||||
CRActiveUser user -> pure user
|
||||
|
||||
@@ -202,6 +202,7 @@ mobileChatOpts dbFilePrefix =
|
||||
yesToUpMigrations = False
|
||||
},
|
||||
deviceName = Nothing,
|
||||
userDisplayName = Nothing,
|
||||
chatCmd = "",
|
||||
chatCmdDelay = 3,
|
||||
chatCmdLog = CCLNone,
|
||||
|
||||
@@ -35,10 +35,12 @@ import Simplex.Messaging.Parsers (parseAll)
|
||||
import Simplex.Messaging.Protocol (ProtoServerWithAuth, ProtocolTypeI, SMPServerWithAuth, XFTPServerWithAuth)
|
||||
import Simplex.Messaging.Transport.Client (SocksProxyWithAuth (..), SocksAuth (..), defaultSocksProxyWithAuth)
|
||||
import System.FilePath (combine)
|
||||
import Simplex.Chat.Types (ContactName)
|
||||
|
||||
data ChatOpts = ChatOpts
|
||||
{ coreOptions :: CoreChatOpts,
|
||||
deviceName :: Maybe Text,
|
||||
userDisplayName :: Maybe ContactName,
|
||||
chatCmd :: String,
|
||||
chatCmdDelay :: Int,
|
||||
chatCmdLog :: ChatCmdLog,
|
||||
@@ -286,6 +288,13 @@ chatOptsP appDir defaultDbFileName = do
|
||||
<> metavar "DEVICE"
|
||||
<> help "Device name to use in connections with remote hosts and controller"
|
||||
)
|
||||
userDisplayName <-
|
||||
optional $
|
||||
strOption
|
||||
( long "user-display-name"
|
||||
<> metavar "DISPLAY_NAME"
|
||||
<> help "Create new or switch to existing user profile with this display name."
|
||||
)
|
||||
chatCmd <-
|
||||
strOption
|
||||
( long "execute"
|
||||
@@ -375,6 +384,7 @@ chatOptsP appDir defaultDbFileName = do
|
||||
pure
|
||||
ChatOpts
|
||||
{ coreOptions,
|
||||
userDisplayName,
|
||||
deviceName,
|
||||
chatCmd,
|
||||
chatCmdDelay,
|
||||
|
||||
@@ -73,11 +73,11 @@ import UnliftIO.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExis
|
||||
|
||||
-- when acting as host
|
||||
minRemoteCtrlVersion :: AppVersion
|
||||
minRemoteCtrlVersion = AppVersion [6, 2, 0, 3]
|
||||
minRemoteCtrlVersion = AppVersion [6, 2, 0, 1]
|
||||
|
||||
-- when acting as controller
|
||||
minRemoteHostVersion :: AppVersion
|
||||
minRemoteHostVersion = AppVersion [6, 2, 0, 3]
|
||||
minRemoteHostVersion = AppVersion [6, 2, 0, 1]
|
||||
|
||||
currentAppVersion :: AppVersion
|
||||
currentAppVersion = AppVersion SC.version
|
||||
|
||||
+119
-104
@@ -62,7 +62,6 @@ module Simplex.Chat.Store.Messages
|
||||
updateDirectChatItemsRead,
|
||||
getDirectUnreadTimedItems,
|
||||
updateDirectChatItemsReadList,
|
||||
setDirectChatItemRead,
|
||||
setDirectChatItemsDeleteAt,
|
||||
updateGroupChatItemsRead,
|
||||
getGroupUnreadTimedItems,
|
||||
@@ -1671,61 +1670,61 @@ toChatItemRef = \case
|
||||
(itemId, Nothing, Nothing, Just folderId) -> Right (ChatRef CTLocal folderId, itemId)
|
||||
(itemId, _, _, _) -> Left $ SEBadChatItem itemId Nothing
|
||||
|
||||
updateDirectChatItemsRead :: DB.Connection -> User -> ContactId -> IO ()
|
||||
updateDirectChatItemsRead db User {userId} contactId = do
|
||||
updateDirectChatItemsRead :: DB.Connection -> User -> ContactId -> Maybe (ChatItemId, ChatItemId) -> IO ()
|
||||
updateDirectChatItemsRead db User {userId} contactId itemsRange_ = do
|
||||
currentTs <- getCurrentTime
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND contact_id = ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, contactId, CISRcvNew)
|
||||
case itemsRange_ of
|
||||
Just (fromItemId, toItemId) ->
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND contact_id = ? AND chat_item_id >= ? AND chat_item_id <= ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, contactId, fromItemId, toItemId, CISRcvNew)
|
||||
_ ->
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND contact_id = ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, contactId, CISRcvNew)
|
||||
|
||||
getDirectUnreadTimedItems :: DB.Connection -> User -> ContactId -> IO [(ChatItemId, Int)]
|
||||
getDirectUnreadTimedItems db User {userId} contactId =
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND contact_id = ? AND item_status = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
|]
|
||||
(userId, contactId, CISRcvNew)
|
||||
getDirectUnreadTimedItems :: DB.Connection -> User -> ContactId -> Maybe (ChatItemId, ChatItemId) -> IO [(ChatItemId, Int)]
|
||||
getDirectUnreadTimedItems db User {userId} contactId itemsRange_ = case itemsRange_ of
|
||||
Just (fromItemId, toItemId) ->
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND contact_id = ?
|
||||
AND chat_item_id >= ? AND chat_item_id <= ?
|
||||
AND item_status = ?
|
||||
AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
AND (item_live IS NULL OR item_live = ?)
|
||||
|]
|
||||
(userId, contactId, fromItemId, toItemId, CISRcvNew, False)
|
||||
_ ->
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND contact_id = ? AND item_status = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
|]
|
||||
(userId, contactId, CISRcvNew)
|
||||
|
||||
updateDirectChatItemsReadList :: DB.Connection -> User -> ContactId -> NonEmpty ChatItemId -> IO [(ChatItemId, Int)]
|
||||
updateDirectChatItemsReadList db user@User {userId} contactId itemIds = do
|
||||
currentTs <- getCurrentTime
|
||||
catMaybes . L.toList <$> mapM (getUpdateDirectItem currentTs) itemIds
|
||||
updateDirectChatItemsReadList db user contactId itemIds = do
|
||||
catMaybes . L.toList <$> mapM getUpdateDirectItem itemIds
|
||||
where
|
||||
getUpdateDirectItem currentTs itemId = do
|
||||
ttl_ <- maybeFirstRow fromOnly getUnreadTimedItem
|
||||
setDirectChatItemRead_ db user contactId itemId currentTs
|
||||
pure $ (itemId,) <$> ttl_
|
||||
where
|
||||
getUnreadTimedItem =
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND contact_id = ? AND item_status = ? AND chat_item_id = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
|]
|
||||
(userId, contactId, CISRcvNew, itemId)
|
||||
|
||||
setDirectChatItemRead :: DB.Connection -> User -> ContactId -> ChatItemId -> IO ()
|
||||
setDirectChatItemRead db user contactId itemId =
|
||||
setDirectChatItemRead_ db user contactId itemId =<< getCurrentTime
|
||||
|
||||
setDirectChatItemRead_ :: DB.Connection -> User -> ContactId -> ChatItemId -> UTCTime -> IO ()
|
||||
setDirectChatItemRead_ db User {userId} contactId itemId currentTs =
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND contact_id = ? AND item_status = ? AND chat_item_id = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, contactId, CISRcvNew, itemId)
|
||||
getUpdateDirectItem chatItemId = do
|
||||
let itemsRange = Just (chatItemId, chatItemId)
|
||||
timedItem <- maybeFirstRow id $ getDirectUnreadTimedItems db user contactId itemsRange
|
||||
updateDirectChatItemsRead db user contactId itemsRange
|
||||
pure timedItem
|
||||
|
||||
setDirectChatItemsDeleteAt :: DB.Connection -> User -> ContactId -> [(ChatItemId, Int)] -> UTCTime -> IO [(ChatItemId, UTCTime)]
|
||||
setDirectChatItemsDeleteAt db User {userId} contactId itemIds currentTs = forM itemIds $ \(chatItemId, ttl) -> do
|
||||
@@ -1736,55 +1735,61 @@ setDirectChatItemsDeleteAt db User {userId} contactId itemIds currentTs = forM i
|
||||
(deleteAt, userId, contactId, chatItemId)
|
||||
pure (chatItemId, deleteAt)
|
||||
|
||||
updateGroupChatItemsRead :: DB.Connection -> User -> GroupId -> IO ()
|
||||
updateGroupChatItemsRead db User {userId} groupId = do
|
||||
updateGroupChatItemsRead :: DB.Connection -> User -> GroupId -> Maybe (ChatItemId, ChatItemId) -> IO ()
|
||||
updateGroupChatItemsRead db User {userId} groupId itemsRange_ = do
|
||||
currentTs <- getCurrentTime
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, groupId, CISRcvNew)
|
||||
case itemsRange_ of
|
||||
Just (fromItemId, toItemId) ->
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ? AND chat_item_id >= ? AND chat_item_id <= ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, groupId, fromItemId, toItemId, CISRcvNew)
|
||||
_ ->
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, groupId, CISRcvNew)
|
||||
|
||||
getGroupUnreadTimedItems :: DB.Connection -> User -> GroupId -> IO [(ChatItemId, Int)]
|
||||
getGroupUnreadTimedItems db User {userId} groupId =
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND group_id = ? AND item_status = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
|]
|
||||
(userId, groupId, CISRcvNew)
|
||||
getGroupUnreadTimedItems :: DB.Connection -> User -> GroupId -> Maybe (ChatItemId, ChatItemId) -> IO [(ChatItemId, Int)]
|
||||
getGroupUnreadTimedItems db User {userId} groupId itemsRange_ = case itemsRange_ of
|
||||
Just (fromItemId, toItemId) ->
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND group_id = ?
|
||||
AND chat_item_id >= ? AND chat_item_id <= ?
|
||||
AND item_status = ?
|
||||
AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
AND (item_live IS NULL OR item_live = ?)
|
||||
|]
|
||||
(userId, groupId, fromItemId, toItemId, CISRcvNew, False)
|
||||
_ ->
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND group_id = ? AND item_status = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
|]
|
||||
(userId, groupId, CISRcvNew)
|
||||
|
||||
updateGroupChatItemsReadList :: DB.Connection -> User -> GroupId -> NonEmpty ChatItemId -> IO [(ChatItemId, Int)]
|
||||
updateGroupChatItemsReadList db User {userId} groupId itemIds = do
|
||||
currentTs <- getCurrentTime
|
||||
catMaybes . L.toList <$> mapM (getUpdateGroupItem currentTs) itemIds
|
||||
updateGroupChatItemsReadList db user groupId itemIds = do
|
||||
catMaybes . L.toList <$> mapM getUpdateGroupItem itemIds
|
||||
where
|
||||
getUpdateGroupItem currentTs itemId = do
|
||||
ttl_ <- maybeFirstRow fromOnly getUnreadTimedItem
|
||||
setItemRead
|
||||
pure $ (itemId,) <$> ttl_
|
||||
where
|
||||
getUnreadTimedItem =
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT timed_ttl
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND group_id = ? AND item_status = ? AND chat_item_id = ? AND timed_ttl IS NOT NULL AND timed_delete_at IS NULL
|
||||
|]
|
||||
(userId, groupId, CISRcvNew, itemId)
|
||||
setItemRead =
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ? AND item_status = ? AND chat_item_id = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, groupId, CISRcvNew, itemId)
|
||||
getUpdateGroupItem chatItemId = do
|
||||
let itemsRange = Just (chatItemId, chatItemId)
|
||||
timedItem <- maybeFirstRow id $ getGroupUnreadTimedItems db user groupId itemsRange
|
||||
updateGroupChatItemsRead db user groupId itemsRange
|
||||
pure timedItem
|
||||
|
||||
setGroupChatItemsDeleteAt :: DB.Connection -> User -> GroupId -> [(ChatItemId, Int)] -> UTCTime -> IO [(ChatItemId, UTCTime)]
|
||||
setGroupChatItemsDeleteAt db User {userId} groupId itemIds currentTs = forM itemIds $ \(chatItemId, ttl) -> do
|
||||
@@ -1795,16 +1800,26 @@ setGroupChatItemsDeleteAt db User {userId} groupId itemIds currentTs = forM item
|
||||
(deleteAt, userId, groupId, chatItemId)
|
||||
pure (chatItemId, deleteAt)
|
||||
|
||||
updateLocalChatItemsRead :: DB.Connection -> User -> NoteFolderId -> IO ()
|
||||
updateLocalChatItemsRead db User {userId} noteFolderId = do
|
||||
updateLocalChatItemsRead :: DB.Connection -> User -> NoteFolderId -> Maybe (ChatItemId, ChatItemId) -> IO ()
|
||||
updateLocalChatItemsRead db User {userId} noteFolderId itemsRange_ = do
|
||||
currentTs <- getCurrentTime
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND note_folder_id = ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, noteFolderId, CISRcvNew)
|
||||
case itemsRange_ of
|
||||
Just (fromItemId, toItemId) ->
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND note_folder_id = ? AND chat_item_id >= ? AND chat_item_id <= ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, noteFolderId, fromItemId, toItemId, CISRcvNew)
|
||||
_ ->
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE chat_items SET item_status = ?, updated_at = ?
|
||||
WHERE user_id = ? AND note_folder_id = ? AND item_status = ?
|
||||
|]
|
||||
(CISRcvRead, currentTs, userId, noteFolderId, CISRcvNew)
|
||||
|
||||
type MaybeCIFIleRow = (Maybe Int64, Maybe String, Maybe Integer, Maybe FilePath, Maybe C.SbKey, Maybe C.CbNonce, Maybe ACIFileStatus, Maybe FileProtocol)
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
{-# LANGUAGE OverloadedLists #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
@@ -165,7 +164,7 @@ runTerminalOutput ct cc@ChatController {outputQ, showLiveItems, logFilePath} Cha
|
||||
(True, CISRcvNew) -> do
|
||||
let itemId = chatItemId' ci
|
||||
chatRef = chatInfoToRef chat
|
||||
void $ runReaderT (runExceptT $ processChatCommand (APIChatItemsRead chatRef [itemId])) cc
|
||||
void $ runReaderT (runExceptT $ processChatCommand (APIChatRead chatRef (Just (itemId, itemId)))) cc
|
||||
_ -> pure ()
|
||||
logResponse path s = withFile path AppendMode $ \h -> mapM_ (hPutStrLn h . unStyle) s
|
||||
getRemoteUser rhId =
|
||||
|
||||
@@ -74,6 +74,7 @@ testOpts =
|
||||
ChatOpts
|
||||
{ coreOptions = testCoreOpts,
|
||||
deviceName = Nothing,
|
||||
userDisplayName = Nothing,
|
||||
chatCmd = "",
|
||||
chatCmdDelay = 3,
|
||||
chatCmdLog = CCLNone,
|
||||
|
||||
@@ -217,6 +217,8 @@ testAddContact = versionTestMatrix2 runTestAddContact
|
||||
-- search
|
||||
alice #$> ("/_get chat @2 count=100 search=ello ther", chat, [(1, "hello there 🙂"), (0, "hello there")])
|
||||
-- read messages
|
||||
alice #$> ("/_read chat @2 from=1 to=100", id, "ok")
|
||||
bob #$> ("/_read chat @2 from=1 to=100", id, "ok")
|
||||
alice #$> ("/_read chat @2", id, "ok")
|
||||
bob #$> ("/_read chat @2", id, "ok")
|
||||
alice #$> ("/read user", id, "ok")
|
||||
|
||||
@@ -353,6 +353,9 @@ testGroupShared alice bob cath checkMessages directConnections = do
|
||||
bob #$> ("/_get chat #1 count=100", chat, groupFeatures <> [(0, "connected"), (0, "added cath (Catherine)"), (0, "connected"), (0, "hello"), (1, "hi there"), (0, "hey team")])
|
||||
cath @@@ [("@bob", "hey"), ("#team", "hey team"), ("@alice", "received invitation to join group team as admin")]
|
||||
cath #$> ("/_get chat #1 count=100", chat, groupFeatures <> [(0, "connected"), (0, "connected"), (0, "hello"), (0, "hi there"), (1, "hey team")])
|
||||
alice #$> ("/_read chat #1 from=1 to=100", id, "ok")
|
||||
bob #$> ("/_read chat #1 from=1 to=100", id, "ok")
|
||||
cath #$> ("/_read chat #1 from=1 to=100", id, "ok")
|
||||
alice #$> ("/_read chat #1", id, "ok")
|
||||
bob #$> ("/_read chat #1", id, "ok")
|
||||
cath #$> ("/_read chat #1", id, "ok")
|
||||
|
||||
@@ -41,7 +41,7 @@ testNotes tmp = withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
alice ##> "/? keep"
|
||||
alice <# "* keep in mind"
|
||||
|
||||
alice #$> ("/_read chat *1", id, "ok")
|
||||
alice #$> ("/_read chat *1 from=1 to=100", id, "ok")
|
||||
alice ##> "/_unread chat *1 on"
|
||||
alice <## "ok"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user