@@ -777,6 +777,25 @@ impl DashboardState {
777777 ActiveGuildScope :: Unset | ActiveGuildScope :: DirectMessages => BTreeMap :: new ( ) ,
778778 } ;
779779
780+ // Group joined threads by parent channel once. Looking them up per entry
781+ // avoids rescanning every channel for each row, which made sidebar
782+ // building O(N^2) and stuttered navigation on large guilds.
783+ let mut joined_threads_by_parent: BTreeMap < Id < ChannelMarker > , Vec < & ChannelState > > =
784+ BTreeMap :: new ( ) ;
785+ for channel in & channels {
786+ if channel. is_thread ( ) && channel. current_user_joined_thread {
787+ if let Some ( parent_id) = channel. parent_id {
788+ joined_threads_by_parent
789+ . entry ( parent_id)
790+ . or_default ( )
791+ . push ( * channel) ;
792+ }
793+ }
794+ }
795+ for threads in joined_threads_by_parent. values_mut ( ) {
796+ sort_thread_channels ( threads) ;
797+ }
798+
780799 let category_ids: HashSet < Id < ChannelMarker > > = channels
781800 . iter ( )
782801 . filter ( |channel| channel. is_category ( ) )
@@ -804,6 +823,7 @@ impl DashboardState {
804823 root,
805824 ChannelBranch :: None ,
806825 & voice_participants_by_channel,
826+ & joined_threads_by_parent,
807827 ) ;
808828 continue ;
809829 }
@@ -842,6 +862,7 @@ impl DashboardState {
842862 child,
843863 branch,
844864 & voice_participants_by_channel,
865+ & joined_threads_by_parent,
845866 ) ;
846867 }
847868 }
@@ -860,9 +881,12 @@ impl DashboardState {
860881 state : & ' a ChannelState ,
861882 branch : ChannelBranch ,
862883 voice_participants_by_channel : & BTreeMap < Id < ChannelMarker > , Vec < VoiceParticipantState > > ,
884+ joined_threads_by_parent : & BTreeMap < Id < ChannelMarker > , Vec < & ' a ChannelState > > ,
863885 ) {
864886 entries. push ( ChannelPaneEntry :: Channel { state, branch } ) ;
865- self . push_joined_thread_entries ( entries, state. id , branch) ;
887+ if let Some ( threads) = joined_threads_by_parent. get ( & state. id ) {
888+ Self :: push_joined_thread_entries ( entries, threads, branch) ;
889+ }
866890 if !state. is_voice ( ) {
867891 return ;
868892 }
@@ -878,23 +902,12 @@ impl DashboardState {
878902 }
879903
880904 fn push_joined_thread_entries < ' a > (
881- & ' a self ,
882905 entries : & mut Vec < ChannelPaneEntry < ' a > > ,
883- parent_id : Id < ChannelMarker > ,
906+ threads : & [ & ' a ChannelState ] ,
884907 parent_branch : ChannelBranch ,
885908 ) {
886- let mut threads: Vec < & ChannelState > = self
887- . channels ( )
888- . into_iter ( )
889- . filter ( |channel| {
890- channel. is_thread ( )
891- && channel. parent_id == Some ( parent_id)
892- && channel. current_user_joined_thread
893- } )
894- . collect ( ) ;
895- sort_thread_channels ( & mut threads) ;
896909 let last_child_index = threads. len ( ) . saturating_sub ( 1 ) ;
897- entries. extend ( threads. into_iter ( ) . enumerate ( ) . map ( |( index, state) | {
910+ entries. extend ( threads. iter ( ) . enumerate ( ) . map ( |( index, & state) | {
898911 let branch = if index == last_child_index {
899912 ChannelBranch :: Last
900913 } else {
0 commit comments