1package types 2 3import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 9 "github.com/keybase/client/go/chat/s3" 10 "github.com/keybase/client/go/libkb" 11 "github.com/keybase/client/go/protocol/chat1" 12 "github.com/keybase/client/go/protocol/gregor1" 13 "github.com/keybase/client/go/protocol/keybase1" 14 "github.com/keybase/client/go/protocol/stellar1" 15 context "golang.org/x/net/context" 16) 17 18const ( 19 ActionNewConversation = "newConversation" 20 ActionNewMessage = "newMessage" 21 ActionReadMessage = "readMessage" 22 ActionSetStatus = "setStatus" 23 ActionSetAppNotificationSettings = "setAppNotificationSettings" 24 ActionTeamType = "teamType" 25 ActionExpunge = "expunge" 26 27 PushActivity = "chat.activity" 28 PushTyping = "chat.typing" 29 PushMembershipUpdate = "chat.membershipUpdate" 30 PushTLFFinalize = "chat.tlffinalize" 31 PushTLFResolve = "chat.tlfresolve" 32 PushKBFSUpgrade = "chat.kbfsupgrade" 33 PushConvRetention = "chat.convretention" 34 PushTeamRetention = "chat.teamretention" 35 PushConvSettings = "chat.convsettings" 36 PushSubteamRename = "chat.subteamrename" 37 PushConversationsUpdate = "chat.conversationsupdate" 38 39 MapsDomain = "keybasemaps" 40) 41 42func NewAllCryptKeys() AllCryptKeys { 43 return make(AllCryptKeys) 44} 45 46type NameInfo struct { 47 ID chat1.TLFID 48 CanonicalName string 49 VerifiedMembers []gregor1.UID // may be empty if we couldn't satisfy the request 50} 51 52func NewNameInfo() *NameInfo { 53 return &NameInfo{} 54} 55 56type MembershipUpdateRes struct { 57 RoleUpdates []chat1.ConversationLocal 58 UserJoinedConvs []chat1.ConversationLocal 59 UserRemovedConvs []chat1.ConversationMember 60 UserResetConvs []chat1.ConversationMember 61 OthersJoinedConvs []chat1.ConversationMember 62 OthersRemovedConvs []chat1.ConversationMember 63 OthersResetConvs []chat1.ConversationMember 64} 65 66func (m MembershipUpdateRes) AllOtherUsers() (res []gregor1.UID) { 67 res = make([]gregor1.UID, 0, len(m.OthersResetConvs)+len(m.OthersJoinedConvs)+len(m.OthersRemovedConvs)) 68 for _, cm := range append(m.OthersResetConvs, append(m.OthersJoinedConvs, m.OthersRemovedConvs...)...) { 69 res = append(res, cm.Uid) 70 } 71 return res 72} 73 74type InboxSourceSearchEmptyMode int 75 76const ( 77 InboxSourceSearchEmptyModeUnread InboxSourceSearchEmptyMode = iota 78 InboxSourceSearchEmptyModeAll 79 InboxSourceSearchEmptyModeAllBySendCtime 80) 81 82type InboxSourceDataSourceTyp int 83 84const ( 85 InboxSourceDataSourceAll InboxSourceDataSourceTyp = iota 86 InboxSourceDataSourceRemoteOnly 87 InboxSourceDataSourceLocalOnly 88) 89 90type RemoteConversationMetadata struct { 91 Name string `codec:"n"` 92 TopicName string `codec:"t"` 93 Snippet string `codec:"s"` 94 SnippetDecoration chat1.SnippetDecoration `codec:"d"` 95 Headline string `codec:"h"` 96 HeadlineEmojis []chat1.HarvestedEmoji `codec:"e"` 97 WriterNames []string `codec:"w"` 98 FullNamesForSearch []*string `codec:"f"` 99 ResetParticipants []string `codec:"r"` 100} 101 102func (m RemoteConversationMetadata) DeepCopy() (res RemoteConversationMetadata) { 103 res.Name = m.Name 104 res.TopicName = m.TopicName 105 res.Snippet = m.Snippet 106 res.SnippetDecoration = m.SnippetDecoration 107 res.Headline = m.Headline 108 res.HeadlineEmojis = make([]chat1.HarvestedEmoji, len(m.HeadlineEmojis)) 109 copy(res.HeadlineEmojis, m.HeadlineEmojis) 110 res.WriterNames = make([]string, len(m.WriterNames)) 111 copy(res.WriterNames, m.WriterNames) 112 res.FullNamesForSearch = make([]*string, len(m.FullNamesForSearch)) 113 copy(res.FullNamesForSearch, m.FullNamesForSearch) 114 res.ResetParticipants = make([]string, len(m.ResetParticipants)) 115 copy(res.ResetParticipants, m.ResetParticipants) 116 return res 117} 118 119type RemoteConversation struct { 120 Conv chat1.Conversation `codec:"c"` 121 ConvIDStr chat1.ConvIDStr `codec:"i"` 122 LocalMetadata *RemoteConversationMetadata `codec:"l"` 123 LocalReadMsgID chat1.MessageID `codec:"r"` 124 LocalDraft *string `codec:"d"` 125 LocalMtime gregor1.Time `codec:"t"` 126} 127 128func NewEmptyRemoteConversation(convID chat1.ConversationID) RemoteConversation { 129 return RemoteConversation{ 130 Conv: chat1.Conversation{ 131 Metadata: chat1.ConversationMetadata{ 132 ConversationID: convID, 133 }, 134 }, 135 ConvIDStr: convID.ConvIDStr(), 136 } 137} 138 139func (rc RemoteConversation) DeepCopy() (res RemoteConversation) { 140 res.Conv = rc.Conv.DeepCopy() 141 res.ConvIDStr = rc.ConvIDStr 142 if rc.LocalMetadata != nil { 143 res.LocalMetadata = new(RemoteConversationMetadata) 144 *res.LocalMetadata = rc.LocalMetadata.DeepCopy() 145 } 146 res.LocalReadMsgID = rc.LocalReadMsgID 147 if rc.LocalDraft != nil { 148 res.LocalDraft = new(string) 149 *res.LocalDraft = *rc.LocalDraft 150 } 151 res.LocalMtime = rc.LocalMtime 152 return res 153} 154 155func (rc RemoteConversation) GetMtime() gregor1.Time { 156 res := rc.Conv.GetMtime() 157 if res > rc.LocalMtime { 158 return res 159 } 160 return rc.LocalMtime 161} 162 163func (rc RemoteConversation) GetReadMsgID() chat1.MessageID { 164 res := rc.Conv.ReaderInfo.ReadMsgid 165 if res > rc.LocalReadMsgID { 166 return res 167 } 168 return rc.LocalReadMsgID 169} 170 171func (rc RemoteConversation) GetConvID() chat1.ConversationID { 172 return rc.Conv.GetConvID() 173} 174 175func (rc RemoteConversation) GetVersion() chat1.ConversationVers { 176 return rc.Conv.Metadata.Version 177} 178 179func (rc RemoteConversation) GetMembersType() chat1.ConversationMembersType { 180 return rc.Conv.GetMembersType() 181} 182 183func (rc RemoteConversation) GetTeamType() chat1.TeamType { 184 return rc.Conv.GetTeamType() 185} 186 187func (rc RemoteConversation) CannotWrite() bool { 188 return rc.Conv.CannotWrite() 189} 190 191func (rc RemoteConversation) GetTopicName() string { 192 if rc.LocalMetadata != nil { 193 return rc.LocalMetadata.TopicName 194 } 195 return "" 196} 197 198func (rc RemoteConversation) GetMaxMessage(typ chat1.MessageType) (chat1.MessageSummary, error) { 199 return rc.Conv.GetMaxMessage(typ) 200} 201 202func (rc RemoteConversation) GetTopicType() chat1.TopicType { 203 return rc.Conv.GetTopicType() 204} 205 206func (rc RemoteConversation) IsLocallyRead() bool { 207 return rc.LocalReadMsgID >= rc.Conv.MaxVisibleMsgID() 208} 209 210func (rc RemoteConversation) MaxVisibleMsgID() chat1.MessageID { 211 return rc.Conv.MaxVisibleMsgID() 212} 213 214func (rc RemoteConversation) GetExpunge() *chat1.Expunge { 215 return rc.Conv.GetExpunge() 216} 217 218func (rc RemoteConversation) GetFinalizeInfo() *chat1.ConversationFinalizeInfo { 219 return rc.Conv.GetFinalizeInfo() 220} 221 222func (rc RemoteConversation) GetMaxDeletedUpTo() chat1.MessageID { 223 return rc.Conv.GetMaxDeletedUpTo() 224} 225 226func (rc RemoteConversation) IsPublic() bool { 227 return rc.Conv.IsPublic() 228} 229 230type UnboxMode int 231 232const ( 233 UnboxModeFull UnboxMode = iota 234 UnboxModeQuick 235) 236 237func (m UnboxMode) ShouldCache() bool { 238 switch m { 239 case UnboxModeFull: 240 return true 241 case UnboxModeQuick: 242 return false 243 } 244 return true 245} 246 247type Inbox struct { 248 Version chat1.InboxVers 249 ConvsUnverified []RemoteConversation 250 Convs []chat1.ConversationLocal 251} 252 253type InboxSyncRes struct { 254 FilteredConvs []RemoteConversation 255 TeamTypeChanged bool 256 MembersTypeChanged []chat1.ConversationID 257 Expunges []InboxSyncResExpunge 258 TopicNameChanged []chat1.ConversationID 259} 260 261type InboxSyncResExpunge struct { 262 ConvID chat1.ConversationID 263 Expunge chat1.Expunge 264} 265 266type ConvLoaderPriority int 267 268var ( 269 ConvLoaderPriorityHighest ConvLoaderPriority = 10 270 ConvLoaderPriorityHigh ConvLoaderPriority = 7 271 ConvLoaderPriorityMedium ConvLoaderPriority = 5 272 ConvLoaderPriorityLow ConvLoaderPriority = 3 273 ConvLoaderPriorityLowest ConvLoaderPriority 274) 275 276func (c ConvLoaderPriority) HigherThan(c2 ConvLoaderPriority) bool { 277 return int(c) > int(c2) 278} 279 280type ConvLoaderUniqueness int 281 282const ( 283 ConvLoaderUnique ConvLoaderUniqueness = iota 284 ConvLoaderGeneric 285) 286 287type ConvLoaderJob struct { 288 ConvID chat1.ConversationID 289 Pagination *chat1.Pagination 290 Priority ConvLoaderPriority 291 Uniqueness ConvLoaderUniqueness 292 PostLoadHook func(context.Context, chat1.ThreadView, ConvLoaderJob) 293} 294 295func (j ConvLoaderJob) HigherPriorityThan(j2 ConvLoaderJob) bool { 296 return j.Priority.HigherThan(j2.Priority) 297} 298 299func (j ConvLoaderJob) String() string { 300 return fmt.Sprintf("[convID: %s pagination: %s unique: %v]", j.ConvID, j.Pagination, j.Uniqueness) 301} 302 303func NewConvLoaderJob(convID chat1.ConversationID, pagination *chat1.Pagination, priority ConvLoaderPriority, 304 uniqueness ConvLoaderUniqueness, postLoadHook func(context.Context, chat1.ThreadView, ConvLoaderJob)) ConvLoaderJob { 305 return ConvLoaderJob{ 306 ConvID: convID, 307 Pagination: pagination, 308 Priority: priority, 309 Uniqueness: uniqueness, 310 PostLoadHook: postLoadHook, 311 } 312} 313 314type AsyncInboxResult struct { 315 Conv RemoteConversation 316 ConvLocal chat1.ConversationLocal 317 InboxRes *Inbox // set if we are returning the whole inbox 318} 319 320type ConversationLocalizerTyp int 321 322const ( 323 ConversationLocalizerBlocking ConversationLocalizerTyp = iota 324 ConversationLocalizerNonblocking 325) 326 327type AttachmentUploaderTaskStatus int 328 329const ( 330 AttachmentUploaderTaskStatusUploading AttachmentUploaderTaskStatus = iota 331 AttachmentUploaderTaskStatusSuccess 332 AttachmentUploaderTaskStatusFailed 333) 334 335type FlipSendStatus int 336 337const ( 338 FlipSendStatusInProgress FlipSendStatus = iota 339 FlipSendStatusSent 340 FlipSendStatusError 341) 342 343type AttachmentUploadResult struct { 344 Error *string 345 Object chat1.Asset 346 Preview *chat1.Asset 347 Metadata []byte 348} 349 350type BoxerEncryptionInfo struct { 351 Key CryptKey 352 SigningKeyPair libkb.NaclSigningKeyPair 353 EphemeralKey EphemeralCryptKey 354 PairwiseMACRecipients []keybase1.KID 355 Version chat1.MessageBoxedVersion 356} 357 358type SenderPrepareOptions struct { 359 SkipTopicNameState bool 360} 361 362type SenderPrepareResult struct { 363 Boxed chat1.MessageBoxed 364 EncryptionInfo BoxerEncryptionInfo 365 PendingAssetDeletes []chat1.Asset 366 DeleteFlipConv *chat1.ConversationID 367 AtMentions []gregor1.UID 368 ChannelMention chat1.ChannelMention 369 TopicNameState *chat1.TopicNameState 370 TopicNameStateConvs []chat1.ConversationID 371} 372 373type ParsedStellarPayment struct { 374 Username libkb.NormalizedUsername 375 Full string 376 Amount string 377 Currency string 378} 379 380func (p ParsedStellarPayment) ToMini() libkb.MiniChatPayment { 381 return libkb.MiniChatPayment{ 382 Username: p.Username, 383 Amount: p.Amount, 384 Currency: p.Currency, 385 } 386} 387 388type ParticipantResult struct { 389 Uids []gregor1.UID 390 Err error 391} 392 393type EmojiHarvestMode int 394 395const ( 396 EmojiHarvestModeNormal EmojiHarvestMode = iota 397 EmojiHarvestModeFast 398) 399 400type DummyAttachmentFetcher struct{} 401 402var _ AttachmentFetcher = (*DummyAttachmentFetcher)(nil) 403 404func (d DummyAttachmentFetcher) FetchAttachment(ctx context.Context, w io.Writer, 405 convID chat1.ConversationID, asset chat1.Asset, r func() chat1.RemoteInterface, signer s3.Signer, 406 progress ProgressReporter) error { 407 return nil 408} 409 410func (d DummyAttachmentFetcher) StreamAttachment(ctx context.Context, convID chat1.ConversationID, 411 asset chat1.Asset, ri func() chat1.RemoteInterface, signer s3.Signer) (io.ReadSeeker, error) { 412 return nil, nil 413} 414 415func (d DummyAttachmentFetcher) DeleteAssets(ctx context.Context, 416 convID chat1.ConversationID, assets []chat1.Asset, ri func() chat1.RemoteInterface, signer s3.Signer) (err error) { 417 return nil 418} 419 420func (d DummyAttachmentFetcher) PutUploadedAsset(ctx context.Context, filename string, asset chat1.Asset) error { 421 return nil 422} 423 424func (d DummyAttachmentFetcher) IsAssetLocal(ctx context.Context, asset chat1.Asset) (bool, error) { 425 return false, nil 426} 427func (d DummyAttachmentFetcher) OnDbNuke(mctx libkb.MetaContext) error { return nil } 428func (d DummyAttachmentFetcher) OnStart(mctx libkb.MetaContext) {} 429 430type DummyAttachmentHTTPSrv struct{} 431 432var _ AttachmentURLSrv = (*DummyAttachmentHTTPSrv)(nil) 433 434func (d DummyAttachmentHTTPSrv) GetURL(ctx context.Context, convID chat1.ConversationID, msgID chat1.MessageID, 435 preview, noAnim, isEmoji bool) string { 436 return "" 437} 438 439func (d DummyAttachmentHTTPSrv) GetPendingPreviewURL(ctx context.Context, outboxID chat1.OutboxID) string { 440 return "" 441} 442 443func (d DummyAttachmentHTTPSrv) GetUnfurlAssetURL(ctx context.Context, convID chat1.ConversationID, 444 asset chat1.Asset) string { 445 return "" 446} 447 448func (d DummyAttachmentHTTPSrv) GetAttachmentFetcher() AttachmentFetcher { 449 return DummyAttachmentFetcher{} 450} 451 452func (d DummyAttachmentHTTPSrv) GetGiphyURL(ctx context.Context, giphyURL string) string { 453 return "" 454} 455func (d DummyAttachmentHTTPSrv) GetGiphyGalleryURL(ctx context.Context, convID chat1.ConversationID, 456 tlfName string, results []chat1.GiphySearchResult) string { 457 return "" 458} 459func (d DummyAttachmentHTTPSrv) OnDbNuke(mctx libkb.MetaContext) error { return nil } 460 461type DummyStellarLoader struct{} 462 463var _ StellarLoader = (*DummyStellarLoader)(nil) 464 465func (d DummyStellarLoader) LoadPayment(ctx context.Context, convID chat1.ConversationID, msgID chat1.MessageID, senderUsername string, paymentID stellar1.PaymentID) *chat1.UIPaymentInfo { 466 return nil 467} 468 469func (d DummyStellarLoader) LoadRequest(ctx context.Context, convID chat1.ConversationID, msgID chat1.MessageID, senderUsername string, requestID stellar1.KeybaseRequestID) *chat1.UIRequestInfo { 470 return nil 471} 472 473type DummyEphemeralPurger struct{} 474 475var _ EphemeralPurger = (*DummyEphemeralPurger)(nil) 476 477func (d DummyEphemeralPurger) Start(ctx context.Context, uid gregor1.UID) {} 478func (d DummyEphemeralPurger) Stop(ctx context.Context) chan struct{} { 479 ch := make(chan struct{}) 480 close(ch) 481 return ch 482} 483func (d DummyEphemeralPurger) Queue(ctx context.Context, purgeInfo chat1.EphemeralPurgeInfo) error { 484 return nil 485} 486 487type DummyIndexer struct{} 488 489var _ Indexer = (*DummyIndexer)(nil) 490 491func (d DummyIndexer) Start(ctx context.Context, uid gregor1.UID) {} 492func (d DummyIndexer) Stop(ctx context.Context) chan struct{} { 493 ch := make(chan struct{}) 494 close(ch) 495 return ch 496} 497func (d DummyIndexer) Suspend(ctx context.Context) bool { 498 return false 499} 500func (d DummyIndexer) Resume(ctx context.Context) bool { 501 return false 502} 503func (d DummyIndexer) Search(ctx context.Context, query, origQuery string, 504 opts chat1.SearchOpts, hitUICh chan chat1.ChatSearchInboxHit, indexUICh chan chat1.ChatSearchIndexStatus) (*chat1.ChatSearchInboxResults, error) { 505 return nil, nil 506} 507func (d DummyIndexer) Add(ctx context.Context, convID chat1.ConversationID, msg []chat1.MessageUnboxed) error { 508 return nil 509} 510func (d DummyIndexer) Remove(ctx context.Context, convID chat1.ConversationID, msg []chat1.MessageUnboxed) error { 511 return nil 512} 513func (d DummyIndexer) SearchableConvs(ctx context.Context, convID *chat1.ConversationID) ([]RemoteConversation, error) { 514 return nil, nil 515} 516func (d DummyIndexer) IndexInbox(ctx context.Context) (map[chat1.ConvIDStr]chat1.ProfileSearchConvStats, error) { 517 return nil, nil 518} 519func (d DummyIndexer) IsBackgroundActive() bool { return false } 520func (d DummyIndexer) ClearCache() {} 521func (d DummyIndexer) OnLogout(mctx libkb.MetaContext) error { 522 return nil 523} 524func (d DummyIndexer) OnDbNuke(mctx libkb.MetaContext) error { 525 return nil 526} 527func (d DummyIndexer) FullyIndexed(ctx context.Context, convID chat1.ConversationID) (bool, error) { 528 return false, nil 529} 530func (d DummyIndexer) PercentIndexed(ctx context.Context, convID chat1.ConversationID) (int, error) { 531 return 0, nil 532} 533func (d DummyIndexer) Clear(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID) error { 534 return nil 535} 536 537type DummyNativeVideoHelper struct{} 538 539var _ NativeVideoHelper = (*DummyNativeVideoHelper)(nil) 540 541func (d DummyNativeVideoHelper) ThumbnailAndDuration(ctx context.Context, filename string) ([]byte, int, error) { 542 return nil, 0, nil 543} 544 545type UnfurlerTaskStatus int 546 547const ( 548 UnfurlerTaskStatusUnfurling UnfurlerTaskStatus = iota 549 UnfurlerTaskStatusSuccess 550 UnfurlerTaskStatusFailed 551 UnfurlerTaskStatusPermFailed 552) 553 554type DummyUnfurler struct{} 555 556var _ Unfurler = (*DummyUnfurler)(nil) 557 558func (d DummyUnfurler) UnfurlAndSend(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 559 msg chat1.MessageUnboxed) { 560} 561func (d DummyUnfurler) Prefetch(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, msgText string) int { 562 return 0 563} 564func (d DummyUnfurler) Status(ctx context.Context, outboxID chat1.OutboxID) (UnfurlerTaskStatus, *chat1.UnfurlResult, error) { 565 return UnfurlerTaskStatusFailed, nil, nil 566} 567func (d DummyUnfurler) Retry(ctx context.Context, outboxID chat1.OutboxID) {} 568func (d DummyUnfurler) Complete(ctx context.Context, outboxID chat1.OutboxID) {} 569 570func (d DummyUnfurler) GetSettings(ctx context.Context, uid gregor1.UID) (res chat1.UnfurlSettings, err error) { 571 return res, nil 572} 573 574func (d DummyUnfurler) WhitelistAdd(ctx context.Context, uid gregor1.UID, domain string) error { 575 return nil 576} 577 578func (d DummyUnfurler) WhitelistRemove(ctx context.Context, uid gregor1.UID, domain string) error { 579 return nil 580} 581 582func (d DummyUnfurler) WhitelistAddExemption(ctx context.Context, uid gregor1.UID, 583 exemption WhitelistExemption) { 584} 585 586func (d DummyUnfurler) SetMode(ctx context.Context, uid gregor1.UID, mode chat1.UnfurlMode) error { 587 return nil 588} 589 590func (d DummyUnfurler) SetSettings(ctx context.Context, uid gregor1.UID, settings chat1.UnfurlSettings) error { 591 return nil 592} 593 594type DummyStellarSender struct{} 595 596var _ StellarSender = (*DummyStellarSender)(nil) 597 598func (d DummyStellarSender) ParsePayments(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 599 body string, replyTo *chat1.MessageID) []ParsedStellarPayment { 600 return nil 601} 602 603func (d DummyStellarSender) DescribePayments(ctx context.Context, uid gregor1.UID, 604 convID chat1.ConversationID, payments []ParsedStellarPayment) (res chat1.UIChatPaymentSummary, toSend []ParsedStellarPayment, err error) { 605 return res, toSend, nil 606} 607 608func (d DummyStellarSender) SendPayments(ctx context.Context, convID chat1.ConversationID, payments []ParsedStellarPayment) ([]chat1.TextPayment, error) { 609 return nil, nil 610} 611 612func (d DummyStellarSender) DecorateWithPayments(ctx context.Context, body string, 613 payments []chat1.TextPayment) string { 614 return body 615} 616 617type DummyCoinFlipManager struct{} 618 619var _ CoinFlipManager = (*DummyCoinFlipManager)(nil) 620 621func (d DummyCoinFlipManager) Start(ctx context.Context, uid gregor1.UID) {} 622func (d DummyCoinFlipManager) Stop(ctx context.Context) chan struct{} { 623 ch := make(chan struct{}) 624 close(ch) 625 return ch 626} 627func (d DummyCoinFlipManager) StartFlip(ctx context.Context, uid gregor1.UID, hostConvID chat1.ConversationID, tlfName, text string, outboxID *chat1.OutboxID) error { 628 return nil 629} 630func (d DummyCoinFlipManager) MaybeInjectFlipMessage(ctx context.Context, boxedMsg chat1.MessageBoxed, 631 inboxVers chat1.InboxVers, uid gregor1.UID, convID chat1.ConversationID, topicType chat1.TopicType) bool { 632 return false 633} 634 635func (d DummyCoinFlipManager) LoadFlip(ctx context.Context, uid gregor1.UID, hostConvID chat1.ConversationID, 636 hostMsgID chat1.MessageID, flipConvID chat1.ConversationID, gameID chat1.FlipGameID) (chan chat1.UICoinFlipStatus, chan error) { 637 return nil, nil 638} 639 640func (d DummyCoinFlipManager) DescribeFlipText(ctx context.Context, text string) string { return "" } 641 642func (d DummyCoinFlipManager) HasActiveGames(ctx context.Context) bool { 643 return false 644} 645 646func (d DummyCoinFlipManager) IsFlipConversationCreated(ctx context.Context, outboxID chat1.OutboxID) (chat1.ConversationID, FlipSendStatus) { 647 return nil, FlipSendStatusError 648} 649 650type DummyTeamMentionLoader struct{} 651 652func (d DummyTeamMentionLoader) Start(ctx context.Context, uid gregor1.UID) {} 653func (d DummyTeamMentionLoader) Stop(ctx context.Context) chan struct{} { 654 ch := make(chan struct{}) 655 close(ch) 656 return ch 657} 658 659func (d DummyTeamMentionLoader) LoadTeamMention(ctx context.Context, uid gregor1.UID, 660 maybeMention chat1.MaybeMention, knownTeamMentions []chat1.KnownTeamMention, 661 forceRemote bool) error { 662 return nil 663} 664 665func (d DummyTeamMentionLoader) IsTeamMention(ctx context.Context, uid gregor1.UID, 666 maybeMention chat1.MaybeMention, knownTeamMentions []chat1.KnownTeamMention) bool { 667 return false 668} 669 670type DummyExternalAPIKeySource struct{} 671 672func (d DummyExternalAPIKeySource) GetKey(ctx context.Context, typ chat1.ExternalAPIKeyTyp) (res chat1.ExternalAPIKey, err error) { 673 switch typ { 674 case chat1.ExternalAPIKeyTyp_GIPHY: 675 return chat1.NewExternalAPIKeyWithGiphy(""), nil 676 case chat1.ExternalAPIKeyTyp_GOOGLEMAPS: 677 return chat1.NewExternalAPIKeyWithGooglemaps(""), nil 678 } 679 return res, errors.New("dummy doesnt know about key typ") 680} 681 682func (d DummyExternalAPIKeySource) GetAllKeys(ctx context.Context) (res []chat1.ExternalAPIKey, err error) { 683 return res, nil 684} 685 686type DummyBotCommandManager struct{} 687 688func (d DummyBotCommandManager) Advertise(ctx context.Context, alias *string, 689 ads []chat1.AdvertiseCommandsParam) error { 690 return nil 691} 692 693func (d DummyBotCommandManager) Clear(context.Context, *chat1.ClearBotCommandsFilter) error { 694 return nil 695} 696 697func (d DummyBotCommandManager) PublicCommandsConv(ctx context.Context, username string) (*chat1.ConversationID, error) { 698 return nil, nil 699} 700 701func (d DummyBotCommandManager) ListCommands(ctx context.Context, convID chat1.ConversationID) ([]chat1.UserBotCommandOutput, map[string]string, error) { 702 return nil, make(map[string]string), nil 703} 704 705func (d DummyBotCommandManager) UpdateCommands(ctx context.Context, convID chat1.ConversationID, 706 info *chat1.BotInfo) (chan error, error) { 707 ch := make(chan error, 1) 708 ch <- nil 709 return ch, nil 710} 711 712func (d DummyBotCommandManager) Start(ctx context.Context, uid gregor1.UID) {} 713func (d DummyBotCommandManager) Stop(ctx context.Context) chan struct{} { 714 ch := make(chan struct{}) 715 close(ch) 716 return ch 717} 718 719type DummyUIInboxLoader struct{} 720 721func (d DummyUIInboxLoader) Start(ctx context.Context, uid gregor1.UID) {} 722func (d DummyUIInboxLoader) Stop(ctx context.Context) chan struct{} { 723 ch := make(chan struct{}) 724 close(ch) 725 return ch 726} 727 728func (d DummyUIInboxLoader) LoadNonblock(ctx context.Context, query *chat1.GetInboxLocalQuery, 729 maxUnbox *int, skipUnverified bool) error { 730 return nil 731} 732 733func (d DummyUIInboxLoader) UpdateLayout(ctx context.Context, reselectMode chat1.InboxLayoutReselectMode, 734 reason string) { 735} 736 737func (d DummyUIInboxLoader) UpdateConvs(ctx context.Context, convIDs []chat1.ConversationID) error { 738 return nil 739} 740 741func (d DummyUIInboxLoader) UpdateLayoutFromNewMessage(ctx context.Context, conv RemoteConversation) { 742} 743 744func (d DummyUIInboxLoader) UpdateLayoutFromSubteamRename(ctx context.Context, convs []RemoteConversation) { 745} 746 747func (d DummyUIInboxLoader) UpdateLayoutFromSmallIncrease(ctx context.Context) {} 748func (d DummyUIInboxLoader) UpdateLayoutFromSmallReset(ctx context.Context) {} 749 750type DummyAttachmentUploader struct{} 751 752var _ AttachmentUploader = (*DummyAttachmentUploader)(nil) 753 754func (d DummyAttachmentUploader) Register(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 755 outboxID chat1.OutboxID, title, filename string, metadata []byte, 756 callerPreview *chat1.MakePreviewRes) (AttachmentUploaderResultCb, error) { 757 return nil, nil 758} 759func (d DummyAttachmentUploader) Status(ctx context.Context, outboxID chat1.OutboxID) (AttachmentUploaderTaskStatus, AttachmentUploadResult, error) { 760 return 0, AttachmentUploadResult{}, nil 761} 762func (d DummyAttachmentUploader) Retry(ctx context.Context, outboxID chat1.OutboxID) (AttachmentUploaderResultCb, error) { 763 return nil, nil 764} 765func (d DummyAttachmentUploader) Cancel(ctx context.Context, outboxID chat1.OutboxID) error { 766 return nil 767} 768func (d DummyAttachmentUploader) Complete(ctx context.Context, outboxID chat1.OutboxID) {} 769func (d DummyAttachmentUploader) GetUploadTempFile(ctx context.Context, outboxID chat1.OutboxID, filename string) (string, error) { 770 return "", nil 771} 772func (d DummyAttachmentUploader) GetUploadTempSink(ctx context.Context, filename string) (*os.File, chat1.OutboxID, error) { 773 return nil, nil, nil 774} 775func (d DummyAttachmentUploader) CancelUploadTempFile(ctx context.Context, outboxID chat1.OutboxID) error { 776 return nil 777} 778func (d DummyAttachmentUploader) OnDbNuke(mctx libkb.MetaContext) error { return nil } 779 780type DummyUIThreadLoader struct{} 781 782var _ UIThreadLoader = (*DummyUIThreadLoader)(nil) 783 784func (d DummyUIThreadLoader) LoadNonblock(ctx context.Context, chatUI libkb.ChatUI, uid gregor1.UID, 785 convID chat1.ConversationID, reason chat1.GetThreadReason, pgmode chat1.GetThreadNonblockPgMode, 786 cbmode chat1.GetThreadNonblockCbMode, knownRemote []string, 787 query *chat1.GetThreadQuery, uipagination *chat1.UIPagination) error { 788 return nil 789} 790 791func (d DummyUIThreadLoader) Load(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 792 reason chat1.GetThreadReason, knownRemotes []string, query *chat1.GetThreadQuery, 793 pagination *chat1.Pagination) (chat1.ThreadView, error) { 794 return chat1.ThreadView{}, nil 795} 796 797func (d DummyUIThreadLoader) IsOffline(ctx context.Context) bool { return true } 798func (d DummyUIThreadLoader) Connected(ctx context.Context) {} 799func (d DummyUIThreadLoader) Disconnected(ctx context.Context) {} 800 801type DummyParticipantSource struct{} 802 803var _ ParticipantSource = (*DummyParticipantSource)(nil) 804 805func (d DummyParticipantSource) Get(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 806 dataSource InboxSourceDataSourceTyp) ([]gregor1.UID, error) { 807 return nil, nil 808} 809func (d DummyParticipantSource) GetNonblock(ctx context.Context, uid gregor1.UID, 810 convID chat1.ConversationID, dataSource InboxSourceDataSourceTyp) chan ParticipantResult { 811 ch := make(chan ParticipantResult) 812 close(ch) 813 return ch 814} 815func (d DummyParticipantSource) GetWithNotifyNonblock(ctx context.Context, uid gregor1.UID, 816 convID chat1.ConversationID, dataSource InboxSourceDataSourceTyp) { 817} 818func (d DummyParticipantSource) GetParticipantsFromUids( 819 ctx context.Context, 820 uids []gregor1.UID, 821) ([]chat1.ConversationLocalParticipant, error) { 822 return nil, nil 823} 824 825type DummyEmojiSource struct{} 826 827var _ EmojiSource = (*DummyEmojiSource)(nil) 828 829func (DummyEmojiSource) Add(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 830 alias, filename string, allowOverwrite bool) (res chat1.EmojiRemoteSource, err error) { 831 return res, err 832} 833func (DummyEmojiSource) AddAlias(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 834 newAlias, existingAlias string) (res chat1.EmojiRemoteSource, err error) { 835 return res, err 836} 837func (DummyEmojiSource) Remove(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID, 838 alias string) error { 839 return nil 840} 841func (DummyEmojiSource) Get(ctx context.Context, uid gregor1.UID, convID *chat1.ConversationID, 842 opts chat1.EmojiFetchOpts) (chat1.UserEmojis, error) { 843 return chat1.UserEmojis{}, nil 844} 845func (DummyEmojiSource) Decorate(ctx context.Context, body string, uid gregor1.UID, 846 messageType chat1.MessageType, emojis []chat1.HarvestedEmoji) string { 847 return body 848} 849func (DummyEmojiSource) Harvest(ctx context.Context, body string, uid gregor1.UID, 850 convID chat1.ConversationID, mode EmojiHarvestMode) (res []chat1.HarvestedEmoji, err error) { 851 return res, err 852} 853func (DummyEmojiSource) IsStockEmoji(alias string) bool { return true } 854func (DummyEmojiSource) RemoteToLocalSource(ctx context.Context, uid gregor1.UID, 855 remote chat1.EmojiRemoteSource) (source chat1.EmojiLoadSource, noAnimSource chat1.EmojiLoadSource, err error) { 856 return source, noAnimSource, nil 857} 858func (DummyEmojiSource) ToggleAnimations(ctx context.Context, uid gregor1.UID, enabled bool) error { 859 return nil 860} 861func (DummyEmojiSource) IsValidSize(size int64) bool { 862 return false 863} 864 865type ClearOpts struct { 866 SendLocalAdminNotification bool 867 Reason string 868} 869 870type DummyEphemeralTracker struct{} 871 872var _ EphemeralTracker = (*DummyEphemeralTracker)(nil) 873 874func (d DummyEphemeralTracker) Start(ctx context.Context, uid gregor1.UID) {} 875func (d DummyEphemeralTracker) Stop(ctx context.Context) chan struct{} { 876 ch := make(chan struct{}) 877 close(ch) 878 return ch 879} 880func (d DummyEphemeralTracker) GetAllPurgeInfo(ctx context.Context, uid gregor1.UID) ([]chat1.EphemeralPurgeInfo, error) { 881 return nil, nil 882} 883func (d DummyEphemeralTracker) GetPurgeInfo(ctx context.Context, uid gregor1.UID, convID chat1.ConversationID) (chat1.EphemeralPurgeInfo, error) { 884 return chat1.EphemeralPurgeInfo{}, nil 885} 886func (d DummyEphemeralTracker) InactivatePurgeInfo(ctx context.Context, convID chat1.ConversationID, uid gregor1.UID) error { 887 return nil 888} 889func (d DummyEphemeralTracker) SetPurgeInfo(ctx context.Context, convID chat1.ConversationID, uid gregor1.UID, purgeInfo *chat1.EphemeralPurgeInfo) error { 890 return nil 891} 892func (d DummyEphemeralTracker) MaybeUpdatePurgeInfo(ctx context.Context, convID chat1.ConversationID, uid gregor1.UID, purgeInfo *chat1.EphemeralPurgeInfo) error { 893 return nil 894} 895func (d DummyEphemeralTracker) Clear(ctx context.Context, convID chat1.ConversationID, uid gregor1.UID) error { 896 return nil 897} 898func (d DummyEphemeralTracker) OnDbNuke(mctx libkb.MetaContext) error { return nil } 899func (d DummyEphemeralTracker) OnLogout(mctx libkb.MetaContext) error { return nil } 900 901type DummyCtxFactory struct{} 902 903var _ ContextFactory = (*DummyCtxFactory)(nil) 904 905func (d DummyCtxFactory) NewKeyFinder() KeyFinder { return nil } 906func (d DummyCtxFactory) NewUPAKFinder() UPAKFinder { return nil } 907