@@ -70,7 +70,21 @@ func (s *Syncer) liveChannelList(ctx context.Context, guildID string) ([]*discor
7070 for _ , channel := range channels {
7171 allChannels [channel .ID ] = channel
7272 }
73- if err := s .appendThreadCatalog (ctx , allChannels , threadParentIDs (channels )); err != nil {
73+ var storedRows []store.ChannelRow
74+ if s .store != nil {
75+ rows , err := s .store .Channels (ctx , guildID )
76+ if err != nil {
77+ return nil , err
78+ }
79+ storedRows = rows
80+ mergeStoredThreadChannels (allChannels , rows )
81+ }
82+ parentIDs := fullSyncThreadParentIDs (channels , storedRows )
83+ if len (storedThreadParentIDs (storedRows )) == 0 {
84+ if err := s .appendThreadCatalog (ctx , allChannels , parentIDs ); err != nil {
85+ return nil , err
86+ }
87+ } else if err := s .appendActiveThreadCatalog (ctx , allChannels , parentIDs ); err != nil {
7488 return nil , err
7589 }
7690 return mapsToSlice (allChannels ), nil
@@ -82,11 +96,8 @@ func (s *Syncer) appendThreadCatalog(ctx context.Context, allChannels map[string
8296 if ! isThreadParent (channel ) {
8397 continue
8498 }
85- active , err := s .client .ThreadsActive (ctx , channel .ID )
86- if err == nil {
87- for _ , thread := range active {
88- allChannels [thread .ID ] = thread
89- }
99+ if err := s .appendActiveThreads (ctx , allChannels , channel .ID ); err != nil {
100+ return err
90101 }
91102 for _ , private := range []bool {false , true } {
92103 archived , err := s .client .ThreadsArchived (ctx , channel .ID , private )
@@ -102,6 +113,30 @@ func (s *Syncer) appendThreadCatalog(ctx context.Context, allChannels map[string
102113 return nil
103114}
104115
116+ func (s * Syncer ) appendActiveThreadCatalog (ctx context.Context , allChannels map [string ]* discordgo.Channel , parents []string ) error {
117+ for _ , parentID := range uniqueIDs (parents ) {
118+ channel := allChannels [parentID ]
119+ if ! isThreadParent (channel ) {
120+ continue
121+ }
122+ if err := s .appendActiveThreads (ctx , allChannels , channel .ID ); err != nil {
123+ return err
124+ }
125+ }
126+ return nil
127+ }
128+
129+ func (s * Syncer ) appendActiveThreads (ctx context.Context , allChannels map [string ]* discordgo.Channel , channelID string ) error {
130+ active , err := s .client .ThreadsActive (ctx , channelID )
131+ if err != nil {
132+ return err
133+ }
134+ for _ , thread := range active {
135+ allChannels [thread .ID ] = thread
136+ }
137+ return nil
138+ }
139+
105140func mapsToSlice (in map [string ]* discordgo.Channel ) []* discordgo.Channel {
106141 out := make ([]* discordgo.Channel , 0 , len (in ))
107142 for _ , channel := range in {
@@ -111,6 +146,18 @@ func mapsToSlice(in map[string]*discordgo.Channel) []*discordgo.Channel {
111146 return out
112147}
113148
149+ func mergeStoredThreadChannels (allChannels map [string ]* discordgo.Channel , rows []store.ChannelRow ) {
150+ for _ , row := range rows {
151+ if ! strings .HasPrefix (row .Kind , "thread_" ) {
152+ continue
153+ }
154+ if _ , ok := allChannels [row .ID ]; ok {
155+ continue
156+ }
157+ allChannels [row .ID ] = channelFromRow (row )
158+ }
159+ }
160+
114161func selectStoredChannels (rows []store.ChannelRow , requested map [string ]struct {}) map [string ]* discordgo.Channel {
115162 if len (rows ) == 0 || len (requested ) == 0 {
116163 return nil
@@ -120,30 +167,34 @@ func selectStoredChannels(rows []store.ChannelRow, requested map[string]struct{}
120167 if _ , ok := requested [row .ID ]; ! ok {
121168 continue
122169 }
123- channelType := channelTypeFromKind (row .Kind )
124- var threadMeta * discordgo.ThreadMetadata
125- if strings .HasPrefix (row .Kind , "thread_" ) {
126- threadMeta = & discordgo.ThreadMetadata {
127- Archived : row .IsArchived ,
128- Locked : row .IsLocked ,
129- ArchiveTimestamp : row .ArchiveTimestamp ,
130- }
131- }
132- out [row .ID ] = & discordgo.Channel {
133- ID : row .ID ,
134- GuildID : row .GuildID ,
135- ParentID : row .ParentID ,
136- Name : row .Name ,
137- Topic : row .Topic ,
138- Position : row .Position ,
139- NSFW : row .IsNSFW ,
140- Type : channelType ,
141- ThreadMetadata : threadMeta ,
142- }
170+ out [row .ID ] = channelFromRow (row )
143171 }
144172 return out
145173}
146174
175+ func channelFromRow (row store.ChannelRow ) * discordgo.Channel {
176+ channelType := channelTypeFromKind (row .Kind )
177+ var threadMeta * discordgo.ThreadMetadata
178+ if strings .HasPrefix (row .Kind , "thread_" ) {
179+ threadMeta = & discordgo.ThreadMetadata {
180+ Archived : row .IsArchived ,
181+ Locked : row .IsLocked ,
182+ ArchiveTimestamp : row .ArchiveTimestamp ,
183+ }
184+ }
185+ return & discordgo.Channel {
186+ ID : row .ID ,
187+ GuildID : row .GuildID ,
188+ ParentID : row .ParentID ,
189+ Name : row .Name ,
190+ Topic : row .Topic ,
191+ Position : row .Position ,
192+ NSFW : row .IsNSFW ,
193+ Type : channelType ,
194+ ThreadMetadata : threadMeta ,
195+ }
196+ }
197+
147198func canUseStoredTargets (storedByID map [string ]* discordgo.Channel , requested map [string ]struct {}) bool {
148199 if len (requested ) == 0 || len (storedByID ) != len (requested ) {
149200 return false
@@ -232,6 +283,41 @@ func threadParentIDs(channels []*discordgo.Channel) []string {
232283 return parents
233284}
234285
286+ func fullSyncThreadParentIDs (topLevel []* discordgo.Channel , storedRows []store.ChannelRow ) []string {
287+ storedParents := storedThreadParentIDs (storedRows )
288+ if len (storedParents ) == 0 {
289+ return threadParentIDs (topLevel )
290+ }
291+ parents := make ([]string , 0 , len (topLevel ))
292+ for _ , channel := range topLevel {
293+ if channel == nil {
294+ continue
295+ }
296+ if channel .Type == discordgo .ChannelTypeGuildForum {
297+ parents = append (parents , channel .ID )
298+ continue
299+ }
300+ if _ , ok := storedParents [channel .ID ]; ok && isThreadParent (channel ) {
301+ parents = append (parents , channel .ID )
302+ }
303+ }
304+ return uniqueIDs (parents )
305+ }
306+
307+ func storedThreadParentIDs (rows []store.ChannelRow ) map [string ]struct {} {
308+ if len (rows ) == 0 {
309+ return nil
310+ }
311+ parents := make (map [string ]struct {})
312+ for _ , row := range rows {
313+ if ! strings .HasPrefix (row .Kind , "thread_" ) || row .ParentID == "" {
314+ continue
315+ }
316+ parents [row .ParentID ] = struct {}{}
317+ }
318+ return parents
319+ }
320+
235321func uniqueIDs (ids []string ) []string {
236322 set := make (map [string ]struct {}, len (ids ))
237323 out := make ([]string , 0 , len (ids ))
0 commit comments