mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 12:53:18 +00:00
remove statuses core
This commit is contained in:
1 parent
c7b46d8dd7
commit
a76e09f633
12 files changed
+12
-62
No files matched your search
@@ -178,8 +178,8 @@
|
||||
64C3B0212A0D359700E19930 /* CustomTimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */; };
|
||||
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829982D54AEED006B9E89 /* libgmp.a */; };
|
||||
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829992D54AEEE006B9E89 /* libffi.a */; };
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH-ghc9.6.3.a */; };
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH.a */; };
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC-ghc9.6.3.a */; };
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC.a */; };
|
||||
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299C2D54AEEE006B9E89 /* libgmpxx.a */; };
|
||||
64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */; };
|
||||
64D0C2C229FA57AB00B38D5F /* UserAddressLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */; };
|
||||
@@ -545,8 +545,8 @@
|
||||
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTimePicker.swift; sourceTree = "<group>"; };
|
||||
64C829982D54AEED006B9E89 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
64C829992D54AEEE006B9E89 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH.a"; sourceTree = "<group>"; };
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC.a"; sourceTree = "<group>"; };
|
||||
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
64D0C2BF29F9688300B38D5F /* UserAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressView.swift; sourceTree = "<group>"; };
|
||||
64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressLearnMore.swift; sourceTree = "<group>"; };
|
||||
@@ -708,8 +708,8 @@
|
||||
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */,
|
||||
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */,
|
||||
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */,
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH-ghc9.6.3.a in Frameworks */,
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH.a in Frameworks */,
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC-ghc9.6.3.a in Frameworks */,
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC.a in Frameworks */,
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -795,8 +795,8 @@
|
||||
64C829992D54AEEE006B9E89 /* libffi.a */,
|
||||
64C829982D54AEED006B9E89 /* libgmp.a */,
|
||||
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */,
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH-ghc9.6.3.a */,
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.4.6.0-1uYs2FKSnCtGti4vmlXmvH.a */,
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC-ghc9.6.3.a */,
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.2-6qgCrd2M1igHbyytG3wCNC.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
||||
@@ -349,7 +349,6 @@ undocumentedCommands =
|
||||
"APIGetContactCode",
|
||||
"APIGetGroupMemberCode",
|
||||
"APIGetNetworkConfig",
|
||||
"APIGetNetworkStatuses",
|
||||
"APIGetNtfConns",
|
||||
"APIGetNtfToken",
|
||||
"APIGetReactionMembers",
|
||||
|
||||
@@ -167,7 +167,6 @@ undocumentedResponses =
|
||||
"CRMemberSupportChatDeleted",
|
||||
"CRMemberSupportChats",
|
||||
"CRNetworkConfig",
|
||||
"CRNetworkStatuses",
|
||||
"CRNewMemberContact",
|
||||
"CRNewMemberContactSentInv",
|
||||
"CRMemberContactAccepted",
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/simplex-chat/simplexmq.git
|
||||
tag: 4a827b99e59ef63c018a6cdf47ca7e7faba4d356
|
||||
tag: 220456f0168ae25a7e8add018c36346854d8ae2b
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"https://github.com/simplex-chat/simplexmq.git"."4a827b99e59ef63c018a6cdf47ca7e7faba4d356" = "15vdg9s7k7w2pb6qg3vs30ixflr5rxljhhi4cxpic8vvc41mnjfi";
|
||||
"https://github.com/simplex-chat/simplexmq.git"."220456f0168ae25a7e8add018c36346854d8ae2b" = "0msdllbfjz702g8la9vcw4i5lz44w5iagwf3bnpim2g2jyw1ymsd";
|
||||
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
|
||||
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
|
||||
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
|
||||
|
||||
@@ -149,7 +149,6 @@ newChatController
|
||||
eventSeq <- newTVarIO 0
|
||||
inputQ <- newTBQueueIO tbqSize
|
||||
outputQ <- newTBQueueIO tbqSize
|
||||
connNetworkStatuses <- TM.emptyIO
|
||||
subscriptionMode <- newTVarIO SMSubscribe
|
||||
chatLock <- newEmptyTMVarIO
|
||||
entityLocks <- TM.emptyIO
|
||||
@@ -191,7 +190,6 @@ newChatController
|
||||
eventSeq,
|
||||
inputQ,
|
||||
outputQ,
|
||||
connNetworkStatuses,
|
||||
subscriptionMode,
|
||||
chatLock,
|
||||
entityLocks,
|
||||
|
||||
@@ -231,7 +231,6 @@ data ChatController = ChatController
|
||||
eventSeq :: TVar Int,
|
||||
inputQ :: TBQueue String,
|
||||
outputQ :: TBQueue (Maybe RemoteHostId, Either ChatError ChatEvent),
|
||||
connNetworkStatuses :: TMap AgentConnId NetworkStatus,
|
||||
subscriptionMode :: TVar SubscriptionMode,
|
||||
chatLock :: Lock,
|
||||
entityLocks :: TMap ChatLockEntity Lock,
|
||||
@@ -354,7 +353,6 @@ data ChatCommand
|
||||
| APIEndCall ContactId
|
||||
| APIGetCallInvitations
|
||||
| APICallStatus ContactId WebRTCCallStatus
|
||||
| APIGetNetworkStatuses
|
||||
| APIUpdateProfile {userId :: UserId, profile :: Profile}
|
||||
| APISetContactPrefs {contactId :: ContactId, preferences :: Preferences}
|
||||
| APISetContactAlias {contactId :: ContactId, localAlias :: LocalAlias}
|
||||
@@ -729,7 +727,6 @@ data ChatResponse
|
||||
| CRGroupAliasUpdated {user :: User, toGroup :: GroupInfo}
|
||||
| CRConnectionAliasUpdated {user :: User, toConnection :: PendingContactConnection}
|
||||
| CRContactPrefsUpdated {user :: User, fromContact :: Contact, toContact :: Contact}
|
||||
| CRNetworkStatuses {user_ :: Maybe User, networkStatuses :: [ConnNetworkStatus]}
|
||||
| CRJoinedGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||
| CRMemberAccepted {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||
| CRMemberSupportChatRead {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
|
||||
@@ -1472,10 +1469,6 @@ chatModifyVar' :: (ChatController -> TVar a) -> (a -> a) -> CM' ()
|
||||
chatModifyVar' f newValue = asks f >>= atomically . (`modifyTVar'` newValue)
|
||||
{-# INLINE chatModifyVar' #-}
|
||||
|
||||
setContactNetworkStatus :: Contact -> NetworkStatus -> CM' ()
|
||||
setContactNetworkStatus Contact {activeConn = Nothing} _ = pure ()
|
||||
setContactNetworkStatus Contact {activeConn = Just Connection {agentConnId}} status = chatModifyVar' connNetworkStatuses $ M.insert agentConnId status
|
||||
|
||||
onChatError :: CM a -> CM b -> CM a
|
||||
a `onChatError` onErr = a `catchAllErrors` \e -> onErr >> throwError e
|
||||
{-# INLINE onChatError #-}
|
||||
|
||||
@@ -1368,8 +1368,6 @@ processChatCommand vr nm = \case
|
||||
user <- getUserByContactId db contactId
|
||||
contact <- getContact db vr user contactId
|
||||
pure RcvCallInvitation {user, contact, callType = peerCallType, sharedKey, callUUID, callTs}
|
||||
APIGetNetworkStatuses -> withUser $ \_ ->
|
||||
CRNetworkStatuses Nothing . map (uncurry ConnNetworkStatus) . M.toList <$> chatReadVar connNetworkStatuses
|
||||
APICallStatus contactId receivedStatus ->
|
||||
withCurrentCall contactId $ \user ct call ->
|
||||
updateCallItemStatus user ct call receivedStatus Nothing $> Just call
|
||||
@@ -2681,7 +2679,6 @@ processChatCommand vr nm = \case
|
||||
ct <- withFastStore' $ \db -> createMemberContact db user connId cReq g m mConn subMode
|
||||
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
|
||||
-- TODO not sure it is correct to set connections status here?
|
||||
lift $ setContactNetworkStatus ct NSConnected
|
||||
pure $ CRNewMemberContact user ct g m
|
||||
_ -> throwChatError CEGroupMemberNotActive
|
||||
APISendMemberContactInvitation contactId msgContent_ -> withUser $ \user -> do
|
||||
@@ -4392,7 +4389,6 @@ chatCommandP =
|
||||
"/_call end @" *> (APIEndCall <$> A.decimal),
|
||||
"/_call status @" *> (APICallStatus <$> A.decimal <* A.space <*> strP),
|
||||
"/_call get" $> APIGetCallInvitations,
|
||||
"/_network_statuses" $> APIGetNetworkStatuses,
|
||||
"/_profile " *> (APIUpdateProfile <$> A.decimal <* A.space <*> jsonP),
|
||||
"/_set alias @" *> (APISetContactAlias <$> A.decimal <*> (A.space *> textP <|> pure "")),
|
||||
"/_set alias #" *> (APISetGroupAlias <$> A.decimal <*> (A.space *> textP <|> pure "")),
|
||||
|
||||
@@ -139,11 +139,8 @@ processAgentMessageNoConn = \case
|
||||
where
|
||||
hostEvent :: ChatEvent -> CM ()
|
||||
hostEvent = whenM (asks $ hostEvents . config) . toView
|
||||
serverEvent srv nsStatus conns = do
|
||||
chatModifyVar connNetworkStatuses $ \m -> foldl' (\m' cId -> M.insert cId nsStatus m') m connIds
|
||||
toView $ CEvtNetworkStatus srv nsStatus connIds
|
||||
where
|
||||
connIds = map AgentConnId conns
|
||||
serverEvent :: SMPServer -> NetworkStatus -> [ConnId] -> CM ()
|
||||
serverEvent srv nsStatus conns = toView $ CEvtNetworkStatus srv nsStatus $ map AgentConnId conns
|
||||
errsEvent :: [(ConnId, AgentErrorType)] -> CM ()
|
||||
errsEvent = toView . CEvtChatErrors . map (\(cId, e) -> ChatErrorAgent e (AgentConnId cId) Nothing)
|
||||
|
||||
@@ -559,7 +556,6 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
ct' = ct {activeConn = Just conn'} :: Contact
|
||||
-- [incognito] print incognito profile used for this contact
|
||||
incognitoProfile <- forM customUserProfileId $ \profileId -> withStore (\db -> getProfileById db userId profileId)
|
||||
lift $ setContactNetworkStatus ct' NSConnected
|
||||
toView $ CEvtContactConnected user ct' (fmap fromLocalProfile incognitoProfile)
|
||||
let createE2EItem = createInternalChatItem user (CDDirectRcv ct') (CIRcvDirectE2EEInfo $ E2EInfo $ Just pqEnc) Nothing
|
||||
-- TODO [short links] get contact request by contactRequestId, check encryption (UserContactRequest.pqSupport)?
|
||||
@@ -640,7 +636,6 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
-- [async agent commands] continuation on receiving JOINED
|
||||
when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData ->
|
||||
when (directOrUsed ct && sqSecured) $ do
|
||||
lift $ setContactNetworkStatus ct NSConnected
|
||||
toView $ CEvtContactSndReady user ct
|
||||
when (connChatVersion >= batchSend2Version) $ forM_ viaUserContactLink $ \userContactLinkId -> do
|
||||
(ucl, _) <- withStore $ \db -> getUserContactLinkById db userId userContactLinkId
|
||||
@@ -1455,7 +1450,6 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
notifyMemberConnected gInfo m ct_ = do
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
memberConnectedChatItem gInfo' scopeInfo m'
|
||||
lift $ mapM_ (`setContactNetworkStatus` NSConnected) ct_
|
||||
toView $ CEvtConnectedToGroupMember user gInfo' m' ct_
|
||||
|
||||
probeMatchingMembers :: Contact -> IncognitoEnabled -> CM ()
|
||||
|
||||
@@ -1803,12 +1803,6 @@ netStatusStr = \case
|
||||
NSDisconnected -> "disconnected"
|
||||
NSError e -> "error: " <> e
|
||||
|
||||
data ConnNetworkStatus = ConnNetworkStatus
|
||||
{ agentConnId :: AgentConnId,
|
||||
networkStatus :: NetworkStatus
|
||||
}
|
||||
deriving (Show)
|
||||
|
||||
type CommandId = Int64
|
||||
|
||||
aCorrId :: CommandId -> ACorrId
|
||||
@@ -2000,8 +1994,6 @@ $(JQ.deriveJSON defaultJSON ''SecurityCode)
|
||||
|
||||
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "NS") ''NetworkStatus)
|
||||
|
||||
$(JQ.deriveJSON defaultJSON ''ConnNetworkStatus)
|
||||
|
||||
$(JQ.deriveJSON defaultJSON ''Connection)
|
||||
|
||||
$(JQ.deriveJSON defaultJSON ''PendingContactConnection)
|
||||
|
||||
@@ -232,7 +232,6 @@ chatResponseToView hu cfg@ChatConfig {logLevel, showReactions, testView} liveIte
|
||||
CRRcvStandaloneFileCreated u ft -> ttyUser u $ receivingFileStandalone "started" ft
|
||||
CRSndStandaloneFileCreated u ft -> ttyUser u $ uploadingFileStandalone "started" ft
|
||||
CRStandaloneFileInfo info_ -> maybe ["no file information in URI"] (\j -> [viewJSON j]) info_
|
||||
CRNetworkStatuses u statuses -> if testView then ttyUser' u $ viewNetworkStatuses statuses else []
|
||||
CRJoinedGroupMember u g m -> ttyUser u $ viewJoinedGroupMember g m
|
||||
CRMemberAccepted u g m -> ttyUser u $ viewMemberAccepted g m
|
||||
CRMemberSupportChatRead u g m -> ttyUser u $ viewSupportChatRead g m
|
||||
@@ -1174,12 +1173,6 @@ viewDirectMessagesProhibited :: MsgDirection -> Contact -> [StyledString]
|
||||
viewDirectMessagesProhibited MDSnd c = ["direct messages to indirect contact " <> ttyContact' c <> " are prohibited"]
|
||||
viewDirectMessagesProhibited MDRcv c = ["received prohibited direct message from indirect contact " <> ttyContact' c <> " (discarded)"]
|
||||
|
||||
viewNetworkStatuses :: [ConnNetworkStatus] -> [StyledString]
|
||||
viewNetworkStatuses = map viewStatuses . L.groupBy ((==) `on` netStatus) . sortOn netStatus
|
||||
where
|
||||
netStatus ConnNetworkStatus {networkStatus} = networkStatus
|
||||
viewStatuses ss@(s :| _) = plain $ show (L.length ss) <> " connections " <> netStatusStr (netStatus s)
|
||||
|
||||
viewUserJoinedGroup :: GroupInfo -> [StyledString]
|
||||
viewUserJoinedGroup g@GroupInfo {membership} =
|
||||
case incognitoMembershipProfile g of
|
||||
|
||||
@@ -180,8 +180,6 @@ chatDirectTests = do
|
||||
testReqVRange vr11 supportedChatVRange
|
||||
testReqVRange vr11 vr11
|
||||
it "update peer version range on received messages" testUpdatePeerChatVRange
|
||||
describe "network statuses" $ do
|
||||
it "should get network statuses" testGetNetworkStatuses
|
||||
where
|
||||
testInvVRange vr1 vr2 = it (vRangeStr vr1 <> " - " <> vRangeStr vr2) $ testConnInvChatVRange vr1 vr2
|
||||
testReqVRange vr1 vr2 = it (vRangeStr vr1 <> " - " <> vRangeStr vr2) $ testConnReqChatVRange vr1 vr2
|
||||
@@ -3324,18 +3322,6 @@ testUpdatePeerChatVRange ps =
|
||||
where
|
||||
cfg11 = testCfg {chatVRange = vr11} :: ChatConfig
|
||||
|
||||
testGetNetworkStatuses :: HasCallStack => TestParams -> IO ()
|
||||
testGetNetworkStatuses ps = do
|
||||
withNewTestChat ps "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChat ps "bob" bobProfile $ \bob -> do
|
||||
connectUsers alice bob
|
||||
alice ##> "/_network_statuses"
|
||||
alice <## "1 connections subscribed"
|
||||
withTestChat ps "alice" $ \alice ->
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
|
||||
vr11 :: VersionRangeChat
|
||||
vr11 = mkVersionRange (VersionChat 1) (VersionChat 1)
|
||||
|
||||
|
||||
Reference in new issue
Block a user