@@ -321,7 +321,7 @@ public async Task<List<ChatViewBase>> getAllChats()
321321 {
322322 ChatViewBase cb = new ChatViewBase ( ) ;
323323 cb . chat = chat ;
324- cb . img64 = "" ; // chat.Photo == null ? "" : await getPhotoThumb(chat);
324+ cb . img64 = "" ; // Images loaded via /api/channel/image/{id} endpoint
325325 allChats . Add ( cb ) ;
326326 }
327327 return allChats ;
@@ -339,12 +339,104 @@ public async Task<List<ChatViewBase>> getAllSavedChats()
339339 {
340340 ChatViewBase cb = new ChatViewBase ( ) ;
341341 cb . chat = chat ;
342- cb . img64 = "" ; // chat.Photo == null ? "" : await getPhotoThumb(chat);
342+ cb . img64 = "" ; // Images loaded via /api/channel/image/{id} endpoint
343343 allChats . Add ( cb ) ;
344344 }
345345 return allChats ;
346346 }
347347
348+ /// <summary>
349+ /// Gets all chats organized by Telegram folders (dialog filters)
350+ /// </summary>
351+ public async Task < ChatsWithFolders > getChatsWithFolders ( )
352+ {
353+ var result = new ChatsWithFolders ( ) ;
354+
355+ if ( ! checkUserLogin ( ) ) return result ;
356+
357+ try
358+ {
359+ // Get all chats first
360+ var allChats = await getAllSavedChats ( ) ;
361+ var chatDict = allChats . ToDictionary ( c => c . chat . ID ) ;
362+ var chatsInFolders = new HashSet < long > ( ) ;
363+
364+ // Get dialog filters (folders)
365+ var dialogFilters = await client . Messages_GetDialogFilters ( ) ;
366+
367+ if ( dialogFilters ? . filters != null )
368+ {
369+ foreach ( var filter in dialogFilters . filters )
370+ {
371+ ChatFolderView folder = null ;
372+ InputPeer [ ] includePeers = null ;
373+
374+ // Handle regular folders (DialogFilter)
375+ if ( filter is DialogFilter df )
376+ {
377+ folder = new ChatFolderView
378+ {
379+ Id = df . id ,
380+ Title = df . title ? . text ?? df . title ? . ToString ( ) ?? "Folder" ,
381+ IconEmoji = df . emoticon ?? "📁"
382+ } ;
383+ includePeers = df . include_peers ;
384+ }
385+ // Handle shared folders (DialogFilterChatlist)
386+ else if ( filter is DialogFilterChatlist dfc )
387+ {
388+ folder = new ChatFolderView
389+ {
390+ Id = dfc . id ,
391+ Title = dfc . title ? . text ?? dfc . title ? . ToString ( ) ?? "Shared Folder" ,
392+ IconEmoji = dfc . emoticon ?? "🔗"
393+ } ;
394+ includePeers = dfc . include_peers ;
395+ }
396+
397+ if ( folder != null && includePeers != null )
398+ {
399+ foreach ( var peer in includePeers )
400+ {
401+ long peerId = peer switch
402+ {
403+ InputPeerChannel ipc => ipc . channel_id ,
404+ InputPeerChat ipchat => ipchat . chat_id ,
405+ InputPeerUser ipu => ipu . user_id ,
406+ _ => 0
407+ } ;
408+
409+ if ( peerId != 0 && chatDict . TryGetValue ( peerId , out var chatView ) )
410+ {
411+ folder . Chats . Add ( chatView ) ;
412+ chatsInFolders . Add ( peerId ) ;
413+ }
414+ }
415+
416+ // Only add folders that have chats
417+ if ( folder . Chats . Count > 0 )
418+ {
419+ result . Folders . Add ( folder ) ;
420+ }
421+ }
422+ }
423+ }
424+
425+ // Add ungrouped chats (not in any folder)
426+ result . UngroupedChats = allChats
427+ . Where ( c => ! chatsInFolders . Contains ( c . chat . ID ) )
428+ . ToList ( ) ;
429+ }
430+ catch ( Exception ex )
431+ {
432+ _logger . LogError ( ex , "Error getting chat folders" ) ;
433+ // Fallback: return all chats as ungrouped
434+ result . UngroupedChats = await getAllSavedChats ( ) ;
435+ }
436+
437+ return result ;
438+ }
439+
348440 public async Task < Message > uploadFile ( string chatId , Stream file , string fileName , string mimeType = null , UploadModel um = null , string caption = null )
349441 {
350442 _logger . LogInformation ( "Starting file upload - FileName: {FileName}, Size: {SizeMB:F2}MB, ChatId: {ChatId}" ,
@@ -677,6 +769,22 @@ public async Task<string> getPhotoThumb(ChatBase chat)
677769
678770 }
679771
772+ public async Task < byte [ ] ? > DownloadChannelPhoto ( long channelId )
773+ {
774+ if ( ! checkUserLogin ( ) || chats == null ) return null ;
775+
776+ if ( chats . chats . TryGetValue ( channelId , out var chat ) && chat . Photo != null )
777+ {
778+ using var ms = new MemoryStream ( ) ;
779+ // big=true for full resolution, miniThumb=false to avoid tiny thumbnail
780+ if ( await client . DownloadProfilePhotoAsync ( chat , ms , big : true , miniThumb : false ) != 0 )
781+ {
782+ return ms . ToArray ( ) ;
783+ }
784+ }
785+ return null ;
786+ }
787+
680788 public async Task < string > downloadPhotoThumb ( Photo thumb )
681789 {
682790 MemoryStream ms = new MemoryStream ( ) ;
0 commit comments