|
|
|
@@ -46,6 +46,7 @@ import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, listToMaybe, mapMayb
|
|
|
|
|
import Data.Text (Text)
|
|
|
|
|
import qualified Data.Text as T
|
|
|
|
|
import Data.Text.Encoding (decodeLatin1, encodeUtf8)
|
|
|
|
|
import Data.Time (NominalDiffTime, addUTCTime, defaultTimeLocale, formatTime)
|
|
|
|
|
import Data.Time.Clock (UTCTime, getCurrentTime, nominalDay)
|
|
|
|
|
import Data.Type.Equality
|
|
|
|
|
import qualified Data.UUID as UUID
|
|
|
|
@@ -117,12 +118,10 @@ import UnliftIO.IO (hClose)
|
|
|
|
|
import UnliftIO.STM
|
|
|
|
|
#if defined(dbPostgres)
|
|
|
|
|
import Data.Bifunctor (bimap, second)
|
|
|
|
|
import Data.Time (NominalDiffTime, addUTCTime)
|
|
|
|
|
import Simplex.Messaging.Agent.Client (SubInfo (..), getAgentQueuesInfo, getAgentWorkersDetails, getAgentWorkersSummary)
|
|
|
|
|
#else
|
|
|
|
|
import Data.Bifunctor (bimap, first, second)
|
|
|
|
|
import qualified Data.ByteArray as BA
|
|
|
|
|
import Data.Time (NominalDiffTime, addUTCTime, defaultTimeLocale, formatTime)
|
|
|
|
|
import qualified Database.SQLite.Simple as SQL
|
|
|
|
|
import Simplex.Chat.Archive
|
|
|
|
|
import Simplex.Messaging.Agent.Client (SubInfo (..), agentClientStore, getAgentQueuesInfo, getAgentWorkersDetails, getAgentWorkersSummary)
|
|
|
|
@@ -3547,13 +3546,13 @@ chatCommandP =
|
|
|
|
|
"/unmute " *> ((`SetShowMessages` MFAll) <$> chatNameP),
|
|
|
|
|
"/unmute mentions " *> ((`SetShowMessages` MFMentions) <$> chatNameP),
|
|
|
|
|
"/receipts " *> (SetSendReceipts <$> chatNameP <* " " <*> ((Just <$> onOffP) <|> ("default" $> Nothing))),
|
|
|
|
|
"/block #" *> (SetShowMemberMessages <$> displayName <* A.space <*> (char_ '@' *> displayName) <*> pure False),
|
|
|
|
|
"/unblock #" *> (SetShowMemberMessages <$> displayName <* A.space <*> (char_ '@' *> displayName) <*> pure True),
|
|
|
|
|
"/block #" *> (SetShowMemberMessages <$> displayNameP <* A.space <*> (char_ '@' *> displayNameP) <*> pure False),
|
|
|
|
|
"/unblock #" *> (SetShowMemberMessages <$> displayNameP <* A.space <*> (char_ '@' *> displayNameP) <*> pure True),
|
|
|
|
|
"/_create user " *> (CreateActiveUser <$> jsonP),
|
|
|
|
|
"/create user " *> (CreateActiveUser <$> newUserP),
|
|
|
|
|
"/users" $> ListUsers,
|
|
|
|
|
"/_user " *> (APISetActiveUser <$> A.decimal <*> optional (A.space *> jsonP)),
|
|
|
|
|
("/user " <|> "/u ") *> (SetActiveUser <$> displayName <*> optional (A.space *> pwdP)),
|
|
|
|
|
("/user " <|> "/u ") *> (SetActiveUser <$> displayNameP <*> optional (A.space *> pwdP)),
|
|
|
|
|
"/set receipts all " *> (SetAllContactReceipts <$> onOffP),
|
|
|
|
|
"/_set receipts contacts " *> (APISetUserContactReceipts <$> A.decimal <* A.space <*> receiptSettings),
|
|
|
|
|
"/set receipts contacts " *> (SetUserContactReceipts <$> receiptSettings),
|
|
|
|
@@ -3568,7 +3567,7 @@ chatCommandP =
|
|
|
|
|
"/mute user" $> MuteUser,
|
|
|
|
|
"/unmute user" $> UnmuteUser,
|
|
|
|
|
"/_delete user " *> (APIDeleteUser <$> A.decimal <* " del_smp=" <*> onOffP <*> optional (A.space *> jsonP)),
|
|
|
|
|
"/delete user " *> (DeleteUser <$> displayName <*> pure True <*> optional (A.space *> pwdP)),
|
|
|
|
|
"/delete user " *> (DeleteUser <$> displayNameP <*> pure True <*> optional (A.space *> pwdP)),
|
|
|
|
|
("/user" <|> "/u") $> ShowActiveUser,
|
|
|
|
|
"/_start " *> do
|
|
|
|
|
mainApp <- "main=" *> onOffP
|
|
|
|
@@ -3625,7 +3624,7 @@ chatCommandP =
|
|
|
|
|
"/_reorder tags " *> (APIReorderChatTags <$> strP),
|
|
|
|
|
"/_create *" *> (APICreateChatItems <$> A.decimal <*> (" json " *> jsonP <|> " text " *> composedMessagesTextP)),
|
|
|
|
|
"/_report #" *> (APIReportMessage <$> A.decimal <* A.space <*> A.decimal <*> (" reason=" *> strP) <*> (A.space *> textP <|> pure "")),
|
|
|
|
|
"/report #" *> (ReportMessage <$> displayName <*> optional (" @" *> displayName) <*> _strP <* A.space <*> msgTextP),
|
|
|
|
|
"/report #" *> (ReportMessage <$> displayNameP <*> optional (" @" *> displayNameP) <*> _strP <* A.space <*> msgTextP),
|
|
|
|
|
"/_update item " *> (APIUpdateChatItem <$> chatRefP <* A.space <*> A.decimal <*> liveMessageP <* A.space <*> msgContentP),
|
|
|
|
|
"/_delete item " *> (APIDeleteChatItem <$> chatRefP <*> _strP <*> _strP),
|
|
|
|
|
"/_delete member item #" *> (APIDeleteMemberChatItem <$> A.decimal <*> _strP),
|
|
|
|
@@ -3643,7 +3642,7 @@ chatCommandP =
|
|
|
|
|
"/_accept" *> (APIAcceptContact <$> incognitoOnOffP <* A.space <*> A.decimal),
|
|
|
|
|
"/_reject " *> (APIRejectContact <$> A.decimal),
|
|
|
|
|
"/_call invite @" *> (APISendCallInvitation <$> A.decimal <* A.space <*> jsonP),
|
|
|
|
|
"/call " *> char_ '@' *> (SendCallInvitation <$> displayName <*> pure defaultCallType),
|
|
|
|
|
"/call " *> char_ '@' *> (SendCallInvitation <$> displayNameP <*> pure defaultCallType),
|
|
|
|
|
"/_call reject @" *> (APIRejectCall <$> A.decimal),
|
|
|
|
|
"/_call offer @" *> (APISendCallOffer <$> A.decimal <* A.space <*> jsonP),
|
|
|
|
|
"/_call answer @" *> (APISendCallAnswer <$> A.decimal <* A.space <*> jsonP),
|
|
|
|
@@ -3704,37 +3703,37 @@ chatCommandP =
|
|
|
|
|
"/_info #" *> (APIGroupMemberInfo <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
"/_info #" *> (APIGroupInfo <$> A.decimal),
|
|
|
|
|
"/_info @" *> (APIContactInfo <$> A.decimal),
|
|
|
|
|
("/info #" <|> "/i #") *> (GroupMemberInfo <$> displayName <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
("/info #" <|> "/i #") *> (ShowGroupInfo <$> displayName),
|
|
|
|
|
("/info " <|> "/i ") *> char_ '@' *> (ContactInfo <$> displayName),
|
|
|
|
|
("/info #" <|> "/i #") *> (GroupMemberInfo <$> displayNameP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
("/info #" <|> "/i #") *> (ShowGroupInfo <$> displayNameP),
|
|
|
|
|
("/info " <|> "/i ") *> char_ '@' *> (ContactInfo <$> displayNameP),
|
|
|
|
|
"/_queue info #" *> (APIGroupMemberQueueInfo <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
"/_queue info @" *> (APIContactQueueInfo <$> A.decimal),
|
|
|
|
|
("/queue info #" <|> "/qi #") *> (GroupMemberQueueInfo <$> displayName <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
("/queue info " <|> "/qi ") *> char_ '@' *> (ContactQueueInfo <$> displayName),
|
|
|
|
|
("/queue info #" <|> "/qi #") *> (GroupMemberQueueInfo <$> displayNameP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
("/queue info " <|> "/qi ") *> char_ '@' *> (ContactQueueInfo <$> displayNameP),
|
|
|
|
|
"/_switch #" *> (APISwitchGroupMember <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
"/_switch @" *> (APISwitchContact <$> A.decimal),
|
|
|
|
|
"/_abort switch #" *> (APIAbortSwitchGroupMember <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
"/_abort switch @" *> (APIAbortSwitchContact <$> A.decimal),
|
|
|
|
|
"/_sync #" *> (APISyncGroupMemberRatchet <$> A.decimal <* A.space <*> A.decimal <*> (" force=on" $> True <|> pure False)),
|
|
|
|
|
"/_sync @" *> (APISyncContactRatchet <$> A.decimal <*> (" force=on" $> True <|> pure False)),
|
|
|
|
|
"/switch #" *> (SwitchGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
"/switch " *> char_ '@' *> (SwitchContact <$> displayName),
|
|
|
|
|
"/abort switch #" *> (AbortSwitchGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
"/abort switch " *> char_ '@' *> (AbortSwitchContact <$> displayName),
|
|
|
|
|
"/sync #" *> (SyncGroupMemberRatchet <$> displayName <* A.space <* char_ '@' <*> displayName <*> (" force=on" $> True <|> pure False)),
|
|
|
|
|
"/sync " *> char_ '@' *> (SyncContactRatchet <$> displayName <*> (" force=on" $> True <|> pure False)),
|
|
|
|
|
"/switch #" *> (SwitchGroupMember <$> displayNameP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
"/switch " *> char_ '@' *> (SwitchContact <$> displayNameP),
|
|
|
|
|
"/abort switch #" *> (AbortSwitchGroupMember <$> displayNameP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
"/abort switch " *> char_ '@' *> (AbortSwitchContact <$> displayNameP),
|
|
|
|
|
"/sync #" *> (SyncGroupMemberRatchet <$> displayNameP <* A.space <* char_ '@' <*> displayNameP <*> (" force=on" $> True <|> pure False)),
|
|
|
|
|
"/sync " *> char_ '@' *> (SyncContactRatchet <$> displayNameP <*> (" force=on" $> True <|> pure False)),
|
|
|
|
|
"/_get code @" *> (APIGetContactCode <$> A.decimal),
|
|
|
|
|
"/_get code #" *> (APIGetGroupMemberCode <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
"/_verify code @" *> (APIVerifyContact <$> A.decimal <*> optional (A.space *> verifyCodeP)),
|
|
|
|
|
"/_verify code #" *> (APIVerifyGroupMember <$> A.decimal <* A.space <*> A.decimal <*> optional (A.space *> verifyCodeP)),
|
|
|
|
|
"/_enable @" *> (APIEnableContact <$> A.decimal),
|
|
|
|
|
"/_enable #" *> (APIEnableGroupMember <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
"/code " *> char_ '@' *> (GetContactCode <$> displayName),
|
|
|
|
|
"/code #" *> (GetGroupMemberCode <$> displayName <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
"/verify " *> char_ '@' *> (VerifyContact <$> displayName <*> optional (A.space *> verifyCodeP)),
|
|
|
|
|
"/verify #" *> (VerifyGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName <*> optional (A.space *> verifyCodeP)),
|
|
|
|
|
"/enable " *> char_ '@' *> (EnableContact <$> displayName),
|
|
|
|
|
"/enable #" *> (EnableGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
"/code " *> char_ '@' *> (GetContactCode <$> displayNameP),
|
|
|
|
|
"/code #" *> (GetGroupMemberCode <$> displayNameP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
"/verify " *> char_ '@' *> (VerifyContact <$> displayNameP <*> optional (A.space *> verifyCodeP)),
|
|
|
|
|
"/verify #" *> (VerifyGroupMember <$> displayNameP <* A.space <* char_ '@' <*> displayNameP <*> optional (A.space *> verifyCodeP)),
|
|
|
|
|
"/enable " *> char_ '@' *> (EnableContact <$> displayNameP),
|
|
|
|
|
"/enable #" *> (EnableGroupMember <$> displayNameP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
("/help files" <|> "/help file" <|> "/hf") $> ChatHelp HSFiles,
|
|
|
|
|
("/help groups" <|> "/help group" <|> "/hg") $> ChatHelp HSGroups,
|
|
|
|
|
("/help contacts" <|> "/help contact" <|> "/hc") $> ChatHelp HSContacts,
|
|
|
|
@@ -3747,40 +3746,40 @@ chatCommandP =
|
|
|
|
|
("/help" <|> "/h") $> ChatHelp HSMain,
|
|
|
|
|
("/group" <|> "/g") *> (NewGroup <$> incognitoP <* A.space <* char_ '#' <*> groupProfile),
|
|
|
|
|
"/_group " *> (APINewGroup <$> A.decimal <*> incognitoOnOffP <* A.space <*> jsonP),
|
|
|
|
|
("/add " <|> "/a ") *> char_ '#' *> (AddMember <$> displayName <* A.space <* char_ '@' <*> displayName <*> (memberRole <|> pure GRMember)),
|
|
|
|
|
("/join " <|> "/j ") *> char_ '#' *> (JoinGroup <$> displayName <*> (" mute" $> MFNone <|> pure MFAll)),
|
|
|
|
|
("/member role " <|> "/mr ") *> char_ '#' *> (MemberRole <$> displayName <* A.space <* char_ '@' <*> displayName <*> memberRole),
|
|
|
|
|
"/block for all #" *> (BlockForAll <$> displayName <* A.space <*> (char_ '@' *> displayName) <*> pure True),
|
|
|
|
|
"/unblock for all #" *> (BlockForAll <$> displayName <* A.space <*> (char_ '@' *> displayName) <*> pure False),
|
|
|
|
|
("/remove " <|> "/rm ") *> char_ '#' *> (RemoveMember <$> displayName <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
("/leave " <|> "/l ") *> char_ '#' *> (LeaveGroup <$> displayName),
|
|
|
|
|
("/delete #" <|> "/d #") *> (DeleteGroup <$> displayName),
|
|
|
|
|
("/delete " <|> "/d ") *> char_ '@' *> (DeleteContact <$> displayName <*> chatDeleteMode),
|
|
|
|
|
("/add " <|> "/a ") *> char_ '#' *> (AddMember <$> displayNameP <* A.space <* char_ '@' <*> displayNameP <*> (memberRole <|> pure GRMember)),
|
|
|
|
|
("/join " <|> "/j ") *> char_ '#' *> (JoinGroup <$> displayNameP <*> (" mute" $> MFNone <|> pure MFAll)),
|
|
|
|
|
("/member role " <|> "/mr ") *> char_ '#' *> (MemberRole <$> displayNameP <* A.space <* char_ '@' <*> displayNameP <*> memberRole),
|
|
|
|
|
"/block for all #" *> (BlockForAll <$> displayNameP <* A.space <*> (char_ '@' *> displayNameP) <*> pure True),
|
|
|
|
|
"/unblock for all #" *> (BlockForAll <$> displayNameP <* A.space <*> (char_ '@' *> displayNameP) <*> pure False),
|
|
|
|
|
("/remove " <|> "/rm ") *> char_ '#' *> (RemoveMember <$> displayNameP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
("/leave " <|> "/l ") *> char_ '#' *> (LeaveGroup <$> displayNameP),
|
|
|
|
|
("/delete #" <|> "/d #") *> (DeleteGroup <$> displayNameP),
|
|
|
|
|
("/delete " <|> "/d ") *> char_ '@' *> (DeleteContact <$> displayNameP <*> chatDeleteMode),
|
|
|
|
|
"/clear *" $> ClearNoteFolder,
|
|
|
|
|
"/clear #" *> (ClearGroup <$> displayName),
|
|
|
|
|
"/clear " *> char_ '@' *> (ClearContact <$> displayName),
|
|
|
|
|
("/members " <|> "/ms ") *> char_ '#' *> (ListMembers <$> displayName),
|
|
|
|
|
"/clear #" *> (ClearGroup <$> displayNameP),
|
|
|
|
|
"/clear " *> char_ '@' *> (ClearContact <$> displayNameP),
|
|
|
|
|
("/members " <|> "/ms ") *> char_ '#' *> (ListMembers <$> displayNameP),
|
|
|
|
|
"/_groups" *> (APIListGroups <$> A.decimal <*> optional (" @" *> A.decimal) <*> optional (A.space *> stringP)),
|
|
|
|
|
("/groups" <|> "/gs") *> (ListGroups <$> optional (" @" *> displayName) <*> optional (A.space *> stringP)),
|
|
|
|
|
("/groups" <|> "/gs") *> (ListGroups <$> optional (" @" *> displayNameP) <*> optional (A.space *> stringP)),
|
|
|
|
|
"/_group_profile #" *> (APIUpdateGroupProfile <$> A.decimal <* A.space <*> jsonP),
|
|
|
|
|
("/group_profile " <|> "/gp ") *> char_ '#' *> (UpdateGroupNames <$> displayName <* A.space <*> groupProfile),
|
|
|
|
|
("/group_profile " <|> "/gp ") *> char_ '#' *> (ShowGroupProfile <$> displayName),
|
|
|
|
|
"/group_descr " *> char_ '#' *> (UpdateGroupDescription <$> displayName <*> optional (A.space *> msgTextP)),
|
|
|
|
|
"/set welcome " *> char_ '#' *> (UpdateGroupDescription <$> displayName <* A.space <*> (Just <$> msgTextP)),
|
|
|
|
|
"/delete welcome " *> char_ '#' *> (UpdateGroupDescription <$> displayName <*> pure Nothing),
|
|
|
|
|
"/show welcome " *> char_ '#' *> (ShowGroupDescription <$> displayName),
|
|
|
|
|
("/group_profile " <|> "/gp ") *> char_ '#' *> (UpdateGroupNames <$> displayNameP <* A.space <*> groupProfile),
|
|
|
|
|
("/group_profile " <|> "/gp ") *> char_ '#' *> (ShowGroupProfile <$> displayNameP),
|
|
|
|
|
"/group_descr " *> char_ '#' *> (UpdateGroupDescription <$> displayNameP <*> optional (A.space *> msgTextP)),
|
|
|
|
|
"/set welcome " *> char_ '#' *> (UpdateGroupDescription <$> displayNameP <* A.space <*> (Just <$> msgTextP)),
|
|
|
|
|
"/delete welcome " *> char_ '#' *> (UpdateGroupDescription <$> displayNameP <*> pure Nothing),
|
|
|
|
|
"/show welcome " *> char_ '#' *> (ShowGroupDescription <$> displayNameP),
|
|
|
|
|
"/_create link #" *> (APICreateGroupLink <$> A.decimal <*> (memberRole <|> pure GRMember)),
|
|
|
|
|
"/_set link role #" *> (APIGroupLinkMemberRole <$> A.decimal <*> memberRole),
|
|
|
|
|
"/_delete link #" *> (APIDeleteGroupLink <$> A.decimal),
|
|
|
|
|
"/_get link #" *> (APIGetGroupLink <$> A.decimal),
|
|
|
|
|
"/create link #" *> (CreateGroupLink <$> displayName <*> (memberRole <|> pure GRMember)),
|
|
|
|
|
"/set link role #" *> (GroupLinkMemberRole <$> displayName <*> memberRole),
|
|
|
|
|
"/delete link #" *> (DeleteGroupLink <$> displayName),
|
|
|
|
|
"/show link #" *> (ShowGroupLink <$> displayName),
|
|
|
|
|
"/create link #" *> (CreateGroupLink <$> displayNameP <*> (memberRole <|> pure GRMember)),
|
|
|
|
|
"/set link role #" *> (GroupLinkMemberRole <$> displayNameP <*> memberRole),
|
|
|
|
|
"/delete link #" *> (DeleteGroupLink <$> displayNameP),
|
|
|
|
|
"/show link #" *> (ShowGroupLink <$> displayNameP),
|
|
|
|
|
"/_create member contact #" *> (APICreateMemberContact <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
"/_invite member contact @" *> (APISendMemberContactInvitation <$> A.decimal <*> optional (A.space *> msgContentP)),
|
|
|
|
|
(">#" <|> "> #") *> (SendGroupMessageQuote <$> displayName <* A.space <*> pure Nothing <*> quotedMsg <*> msgTextP),
|
|
|
|
|
(">#" <|> "> #") *> (SendGroupMessageQuote <$> displayName <* A.space <* char_ '@' <*> (Just <$> displayName) <* A.space <*> quotedMsg <*> msgTextP),
|
|
|
|
|
(">#" <|> "> #") *> (SendGroupMessageQuote <$> displayNameP <* A.space <*> pure Nothing <*> quotedMsg <*> msgTextP),
|
|
|
|
|
(">#" <|> "> #") *> (SendGroupMessageQuote <$> displayNameP <* A.space <* char_ '@' <*> (Just <$> displayNameP) <* A.space <*> quotedMsg <*> msgTextP),
|
|
|
|
|
"/_contacts " *> (APIListContacts <$> A.decimal),
|
|
|
|
|
"/contacts" $> ListContacts,
|
|
|
|
|
"/_connect plan " *> (APIConnectPlan <$> A.decimal <* A.space <*> strP),
|
|
|
|
@@ -3790,18 +3789,18 @@ chatCommandP =
|
|
|
|
|
"/_set conn user :" *> (APIChangeConnectionUser <$> A.decimal <* A.space <*> A.decimal),
|
|
|
|
|
("/connect" <|> "/c") *> (Connect <$> incognitoP <* A.space <*> ((Just <$> strP) <|> A.takeTill isSpace $> Nothing)),
|
|
|
|
|
("/connect" <|> "/c") *> (AddContact <$> incognitoP),
|
|
|
|
|
ForwardMessage <$> chatNameP <* " <- @" <*> displayName <* A.space <*> msgTextP,
|
|
|
|
|
ForwardGroupMessage <$> chatNameP <* " <- #" <*> displayName <* A.space <* A.char '@' <*> (Just <$> displayName) <* A.space <*> msgTextP,
|
|
|
|
|
ForwardGroupMessage <$> chatNameP <* " <- #" <*> displayName <*> pure Nothing <* A.space <*> msgTextP,
|
|
|
|
|
ForwardMessage <$> chatNameP <* " <- @" <*> displayNameP <* A.space <*> msgTextP,
|
|
|
|
|
ForwardGroupMessage <$> chatNameP <* " <- #" <*> displayNameP <* A.space <* A.char '@' <*> (Just <$> displayNameP) <* A.space <*> msgTextP,
|
|
|
|
|
ForwardGroupMessage <$> chatNameP <* " <- #" <*> displayNameP <*> pure Nothing <* A.space <*> msgTextP,
|
|
|
|
|
ForwardLocalMessage <$> chatNameP <* " <- * " <*> msgTextP,
|
|
|
|
|
SendMessage <$> chatNameP <* A.space <*> msgTextP,
|
|
|
|
|
"/* " *> (SendMessage (ChatName CTLocal "") <$> msgTextP),
|
|
|
|
|
"@#" *> (SendMemberContactMessage <$> displayName <* A.space <* char_ '@' <*> displayName <* A.space <*> msgTextP),
|
|
|
|
|
"@#" *> (SendMemberContactMessage <$> displayNameP <* A.space <* char_ '@' <*> displayNameP <* A.space <*> msgTextP),
|
|
|
|
|
"/live " *> (SendLiveMessage <$> chatNameP <*> (A.space *> msgTextP <|> pure "")),
|
|
|
|
|
(">@" <|> "> @") *> sendMsgQuote (AMsgDirection SMDRcv),
|
|
|
|
|
(">>@" <|> ">> @") *> sendMsgQuote (AMsgDirection SMDSnd),
|
|
|
|
|
("\\ " <|> "\\") *> (DeleteMessage <$> chatNameP <* A.space <*> textP),
|
|
|
|
|
("\\\\ #" <|> "\\\\#") *> (DeleteMemberMessage <$> displayName <* A.space <* char_ '@' <*> displayName <* A.space <*> textP),
|
|
|
|
|
("\\\\ #" <|> "\\\\#") *> (DeleteMemberMessage <$> displayNameP <* A.space <* char_ '@' <*> displayNameP <* A.space <*> textP),
|
|
|
|
|
("! " <|> "!") *> (EditMessage <$> chatNameP <* A.space <*> (quotedMsg <|> pure "") <*> msgTextP),
|
|
|
|
|
ReactToMessage <$> (("+" $> True) <|> ("-" $> False)) <*> reactionP <* A.space <*> chatNameP' <* A.space <*> textP,
|
|
|
|
|
"/feed " *> (SendMessageBroadcast <$> msgTextP),
|
|
|
|
@@ -3833,8 +3832,8 @@ chatCommandP =
|
|
|
|
|
("/profile_address " <|> "/pa ") *> (SetProfileAddress <$> onOffP),
|
|
|
|
|
"/_auto_accept " *> (APIAddressAutoAccept <$> A.decimal <* A.space <*> autoAcceptP),
|
|
|
|
|
"/auto_accept " *> (AddressAutoAccept <$> autoAcceptP),
|
|
|
|
|
("/accept" <|> "/ac") *> (AcceptContact <$> incognitoP <* A.space <* char_ '@' <*> displayName),
|
|
|
|
|
("/reject " <|> "/rc ") *> char_ '@' *> (RejectContact <$> displayName),
|
|
|
|
|
("/accept" <|> "/ac") *> (AcceptContact <$> incognitoP <* A.space <* char_ '@' <*> displayNameP),
|
|
|
|
|
("/reject " <|> "/rc ") *> char_ '@' *> (RejectContact <$> displayNameP),
|
|
|
|
|
("/markdown" <|> "/m") $> ChatHelp HSMarkdown,
|
|
|
|
|
("/welcome" <|> "/w") $> Welcome,
|
|
|
|
|
"/set profile image " *> (UpdateProfileImage . Just . ImageData <$> imageP),
|
|
|
|
@@ -3842,22 +3841,22 @@ chatCommandP =
|
|
|
|
|
"/show profile image" $> ShowProfileImage,
|
|
|
|
|
("/profile " <|> "/p ") *> (uncurry UpdateProfile <$> profileNames),
|
|
|
|
|
("/profile" <|> "/p") $> ShowProfile,
|
|
|
|
|
"/set voice #" *> (SetGroupFeatureRole (AGFR SGFVoice) <$> displayName <*> _strP <*> optional memberRole),
|
|
|
|
|
"/set voice @" *> (SetContactFeature (ACF SCFVoice) <$> displayName <*> optional (A.space *> strP)),
|
|
|
|
|
"/set voice #" *> (SetGroupFeatureRole (AGFR SGFVoice) <$> displayNameP <*> _strP <*> optional memberRole),
|
|
|
|
|
"/set voice @" *> (SetContactFeature (ACF SCFVoice) <$> displayNameP <*> optional (A.space *> strP)),
|
|
|
|
|
"/set voice " *> (SetUserFeature (ACF SCFVoice) <$> strP),
|
|
|
|
|
"/set files #" *> (SetGroupFeatureRole (AGFR SGFFiles) <$> displayName <*> _strP <*> optional memberRole),
|
|
|
|
|
"/set history #" *> (SetGroupFeature (AGFNR SGFHistory) <$> displayName <*> (A.space *> strP)),
|
|
|
|
|
"/set reactions #" *> (SetGroupFeature (AGFNR SGFReactions) <$> displayName <*> (A.space *> strP)),
|
|
|
|
|
"/set calls @" *> (SetContactFeature (ACF SCFCalls) <$> displayName <*> optional (A.space *> strP)),
|
|
|
|
|
"/set files #" *> (SetGroupFeatureRole (AGFR SGFFiles) <$> displayNameP <*> _strP <*> optional memberRole),
|
|
|
|
|
"/set history #" *> (SetGroupFeature (AGFNR SGFHistory) <$> displayNameP <*> (A.space *> strP)),
|
|
|
|
|
"/set reactions #" *> (SetGroupFeature (AGFNR SGFReactions) <$> displayNameP <*> (A.space *> strP)),
|
|
|
|
|
"/set calls @" *> (SetContactFeature (ACF SCFCalls) <$> displayNameP <*> optional (A.space *> strP)),
|
|
|
|
|
"/set calls " *> (SetUserFeature (ACF SCFCalls) <$> strP),
|
|
|
|
|
"/set delete #" *> (SetGroupFeature (AGFNR SGFFullDelete) <$> displayName <*> (A.space *> strP)),
|
|
|
|
|
"/set delete @" *> (SetContactFeature (ACF SCFFullDelete) <$> displayName <*> optional (A.space *> strP)),
|
|
|
|
|
"/set delete #" *> (SetGroupFeature (AGFNR SGFFullDelete) <$> displayNameP <*> (A.space *> strP)),
|
|
|
|
|
"/set delete @" *> (SetContactFeature (ACF SCFFullDelete) <$> displayNameP <*> optional (A.space *> strP)),
|
|
|
|
|
"/set delete " *> (SetUserFeature (ACF SCFFullDelete) <$> strP),
|
|
|
|
|
"/set direct #" *> (SetGroupFeatureRole (AGFR SGFDirectMessages) <$> displayName <*> _strP <*> optional memberRole),
|
|
|
|
|
"/set disappear #" *> (SetGroupTimedMessages <$> displayName <*> (A.space *> timedTTLOnOffP)),
|
|
|
|
|
"/set disappear @" *> (SetContactTimedMessages <$> displayName <*> optional (A.space *> timedMessagesEnabledP)),
|
|
|
|
|
"/set direct #" *> (SetGroupFeatureRole (AGFR SGFDirectMessages) <$> displayNameP <*> _strP <*> optional memberRole),
|
|
|
|
|
"/set disappear #" *> (SetGroupTimedMessages <$> displayNameP <*> (A.space *> timedTTLOnOffP)),
|
|
|
|
|
"/set disappear @" *> (SetContactTimedMessages <$> displayNameP <*> optional (A.space *> timedMessagesEnabledP)),
|
|
|
|
|
"/set disappear " *> (SetUserTimedMessages <$> (("yes" $> True) <|> ("no" $> False))),
|
|
|
|
|
"/set links #" *> (SetGroupFeatureRole (AGFR SGFSimplexLinks) <$> displayName <*> _strP <*> optional memberRole),
|
|
|
|
|
"/set links #" *> (SetGroupFeatureRole (AGFR SGFSimplexLinks) <$> displayNameP <*> _strP <*> optional memberRole),
|
|
|
|
|
("/incognito" <* optional (A.space *> onOffP)) $> ChatHelp HSIncognito,
|
|
|
|
|
"/set device name " *> (SetLocalDeviceName <$> textP),
|
|
|
|
|
"/list remote hosts" $> ListRemoteHosts,
|
|
|
|
@@ -3919,14 +3918,7 @@ chatCommandP =
|
|
|
|
|
]
|
|
|
|
|
where
|
|
|
|
|
notifyP = " notify=" *> onOffP <|> pure True
|
|
|
|
|
displayName = safeDecodeUtf8 <$> (quoted "'" <|> takeNameTill isSpace)
|
|
|
|
|
where
|
|
|
|
|
takeNameTill p =
|
|
|
|
|
A.peekChar' >>= \c ->
|
|
|
|
|
if refChar c then A.takeTill p else fail "invalid first character in display name"
|
|
|
|
|
quoted cs = A.choice [A.char c *> takeNameTill (== c) <* A.char c | c <- cs]
|
|
|
|
|
refChar c = c > ' ' && c /= '#' && c /= '@'
|
|
|
|
|
sendMsgQuote msgDir = SendMessageQuote <$> displayName <* A.space <*> pure msgDir <*> quotedMsg <*> msgTextP
|
|
|
|
|
sendMsgQuote msgDir = SendMessageQuote <$> displayNameP <* A.space <*> pure msgDir <*> quotedMsg <*> msgTextP
|
|
|
|
|
quotedMsg = safeDecodeUtf8 <$> (A.char '(' *> A.takeTill (== ')') <* A.char ')') <* optional A.space
|
|
|
|
|
reactionP = MREmoji <$> (mrEmojiChar <$?> (toEmoji <$> A.anyChar))
|
|
|
|
|
toEmoji = \case
|
|
|
|
@@ -3948,7 +3940,7 @@ chatCommandP =
|
|
|
|
|
clearOverrides <- (" clear_overrides=" *> onOffP) <|> pure False
|
|
|
|
|
pure UserMsgReceiptSettings {enable, clearOverrides}
|
|
|
|
|
onOffP = ("on" $> True) <|> ("off" $> False)
|
|
|
|
|
profileNames = (,) <$> displayName <*> fullNameP
|
|
|
|
|
profileNames = (,) <$> displayNameP <*> fullNameP
|
|
|
|
|
newUserP = do
|
|
|
|
|
(cName, fullName) <- profileNames
|
|
|
|
|
let profile = Just Profile {displayName = cName, fullName, image = Nothing, contactLink = Nothing, preferences = Nothing}
|
|
|
|
@@ -3986,8 +3978,8 @@ chatCommandP =
|
|
|
|
|
chatNameP =
|
|
|
|
|
chatTypeP >>= \case
|
|
|
|
|
CTLocal -> pure $ ChatName CTLocal ""
|
|
|
|
|
ct -> ChatName ct <$> displayName
|
|
|
|
|
chatNameP' = ChatName <$> (chatTypeP <|> pure CTDirect) <*> displayName
|
|
|
|
|
ct -> ChatName ct <$> displayNameP
|
|
|
|
|
chatNameP' = ChatName <$> (chatTypeP <|> pure CTDirect) <*> displayNameP
|
|
|
|
|
chatRefP = ChatRef <$> chatTypeP <*> A.decimal
|
|
|
|
|
msgCountP = A.space *> A.decimal <|> pure 10
|
|
|
|
|
ciTTLDecimal = ("none" $> Nothing) <|> (Just <$> A.decimal)
|
|
|
|
@@ -4052,6 +4044,15 @@ chatCommandP =
|
|
|
|
|
text1P = safeDecodeUtf8 <$> A.takeTill (== ' ')
|
|
|
|
|
char_ = optional . A.char
|
|
|
|
|
|
|
|
|
|
displayNameP :: Parser Text
|
|
|
|
|
displayNameP = safeDecodeUtf8 <$> (quoted '\'' <|> takeNameTill (\c -> isSpace c || c == ','))
|
|
|
|
|
where
|
|
|
|
|
takeNameTill p =
|
|
|
|
|
A.peekChar' >>= \c ->
|
|
|
|
|
if refChar c then A.takeTill p else fail "invalid first character in display name"
|
|
|
|
|
quoted c = A.char c *> takeNameTill (== c) <* A.char c
|
|
|
|
|
refChar c = c > ' ' && c /= '#' && c /= '@'
|
|
|
|
|
|
|
|
|
|
mkValidName :: String -> String
|
|
|
|
|
mkValidName = reverse . dropWhile isSpace . fst3 . foldl' addChar ("", '\NUL', 0 :: Int)
|
|
|
|
|
where
|
|
|
|
|