chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
196
internal/compat/tdesktop/dialogs.go
Normal file
196
internal/compat/tdesktop/dialogs.go
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
package tdesktop
|
||||
|
||||
import "telesrv/internal/domain"
|
||||
|
||||
// ShouldMergePinnedIntoInitialDialogs reports whether a TDesktop main-list
|
||||
// messages.getDialogs request should carry pinned/archive rows inline.
|
||||
//
|
||||
// TDesktop starts the main list with getDialogs(exclude_pinned=true) and loads
|
||||
// pinned rows through getPinnedDialogs in parallel. If the exclude_pinned result
|
||||
// is rendered first, the first visible list temporarily lacks pinned/archive
|
||||
// rows. Keep the workaround scoped to the first main-folder page with no hash so
|
||||
// pagination and cache probes retain normal Telegram semantics.
|
||||
func ShouldMergePinnedIntoInitialDialogs(filter domain.DialogFilter) bool {
|
||||
if !filter.ExcludePinned || filter.Hash != 0 {
|
||||
return false
|
||||
}
|
||||
if filter.HasFolderID && filter.FolderID != domain.DialogMainFolderID {
|
||||
return false
|
||||
}
|
||||
if filter.OffsetID != 0 || filter.OffsetDate != 0 || filter.HasOffsetPeer {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MergeInitialDialogsWithPinned prepends the pinned getPinnedDialogs view to an
|
||||
// initial getDialogs(exclude_pinned=true) main-list response. The returned list
|
||||
// remains a normal messages.dialogs/messages.dialogsSlice projection; only the
|
||||
// first response carries extra pinned/archive rows for TDesktop startup.
|
||||
func MergeInitialDialogsWithPinned(main, pinned domain.DialogList) domain.DialogList {
|
||||
if pinned.ArchiveSummary == nil && len(pinned.Dialogs) == 0 {
|
||||
return main
|
||||
}
|
||||
out := main
|
||||
out.ArchiveSummary = pinned.ArchiveSummary
|
||||
out.Dialogs = mergeDialogsByPeer(pinned.Dialogs, main.Dialogs)
|
||||
out.Messages = mergePrivateMessages(pinned.Messages, main.Messages)
|
||||
out.ChannelMessages = mergeChannelMessages(pinned.ChannelMessages, main.ChannelMessages)
|
||||
out.Users = mergeUsersByID(pinned.Users, main.Users)
|
||||
out.Channels = mergeChannelsByID(pinned.Channels, main.Channels)
|
||||
pinnedEntries := len(pinned.Dialogs)
|
||||
if pinned.ArchiveSummary != nil {
|
||||
pinnedEntries++
|
||||
}
|
||||
mainCount := main.Count
|
||||
if mainCount == 0 {
|
||||
mainCount = len(main.Dialogs)
|
||||
}
|
||||
out.Count = mainCount + pinnedEntries
|
||||
out.Hash = 0
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeDialogsByPeer(first, second []domain.Dialog) []domain.Dialog {
|
||||
out := make([]domain.Dialog, 0, len(first)+len(second))
|
||||
seen := make(map[domain.Peer]struct{}, len(first)+len(second))
|
||||
for _, d := range first {
|
||||
if d.Peer.ID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[d.Peer]; ok {
|
||||
continue
|
||||
}
|
||||
seen[d.Peer] = struct{}{}
|
||||
out = append(out, d)
|
||||
}
|
||||
for _, d := range second {
|
||||
if d.Peer.ID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[d.Peer]; ok {
|
||||
continue
|
||||
}
|
||||
seen[d.Peer] = struct{}{}
|
||||
out = append(out, d)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
type privateMessageKey struct {
|
||||
peer domain.Peer
|
||||
id int
|
||||
}
|
||||
|
||||
func mergePrivateMessages(first, second []domain.Message) []domain.Message {
|
||||
out := make([]domain.Message, 0, len(first)+len(second))
|
||||
seen := make(map[privateMessageKey]struct{}, len(first)+len(second))
|
||||
for _, msg := range first {
|
||||
key := privateMessageKey{peer: msg.Peer, id: msg.ID}
|
||||
if key.peer.ID == 0 || key.id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
out = append(out, msg)
|
||||
}
|
||||
for _, msg := range second {
|
||||
key := privateMessageKey{peer: msg.Peer, id: msg.ID}
|
||||
if key.peer.ID == 0 || key.id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
out = append(out, msg)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
type channelMessageKey struct {
|
||||
channelID int64
|
||||
id int
|
||||
}
|
||||
|
||||
func mergeChannelMessages(first, second []domain.ChannelMessage) []domain.ChannelMessage {
|
||||
out := make([]domain.ChannelMessage, 0, len(first)+len(second))
|
||||
seen := make(map[channelMessageKey]struct{}, len(first)+len(second))
|
||||
for _, msg := range first {
|
||||
key := channelMessageKey{channelID: msg.ChannelID, id: msg.ID}
|
||||
if key.channelID == 0 || key.id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
out = append(out, msg)
|
||||
}
|
||||
for _, msg := range second {
|
||||
key := channelMessageKey{channelID: msg.ChannelID, id: msg.ID}
|
||||
if key.channelID == 0 || key.id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
out = append(out, msg)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeUsersByID(first, second []domain.User) []domain.User {
|
||||
out := make([]domain.User, 0, len(first)+len(second))
|
||||
seen := make(map[int64]struct{}, len(first)+len(second))
|
||||
for _, user := range first {
|
||||
if user.ID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[user.ID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[user.ID] = struct{}{}
|
||||
out = append(out, user)
|
||||
}
|
||||
for _, user := range second {
|
||||
if user.ID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[user.ID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[user.ID] = struct{}{}
|
||||
out = append(out, user)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeChannelsByID(first, second []domain.Channel) []domain.Channel {
|
||||
out := make([]domain.Channel, 0, len(first)+len(second))
|
||||
seen := make(map[int64]struct{}, len(first)+len(second))
|
||||
for _, channel := range first {
|
||||
if channel.ID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[channel.ID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[channel.ID] = struct{}{}
|
||||
out = append(out, channel)
|
||||
}
|
||||
for _, channel := range second {
|
||||
if channel.ID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[channel.ID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[channel.ID] = struct{}{}
|
||||
out = append(out, channel)
|
||||
}
|
||||
return out
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue