diff --git a/gui/src/app.rs b/gui/src/app.rs index 0d8aa3f..7893b17 100644 --- a/gui/src/app.rs +++ b/gui/src/app.rs @@ -139,22 +139,15 @@ impl ChannelsState { pub fn update_channel_parents(&mut self) { // Zero out existing children - for (id, state) in self.channels.iter_mut() { - state.children = OrderSet::new(); + for state in self.channels.values_mut() { + state.children.clear(); } - let mut channels_updated: HashSet = HashSet::new(); - channels_updated.insert(0); // insert root channel - - let mut channels_to_parse: Vec<(ChannelId, ChannelId, i32)> = Vec::new(); + let mut to_sort: Vec<(ChannelId, Option, i32, String)> = Vec::new(); for (id, state) in self.channels.iter() { - // Skip root channel - if *id == 0 { - continue; - } - - // Ignore channels with no parent + // Hnadle channels with no parent (the root channel) let Some(parent_id) = state.parent else { + to_sort.push((*id, None, 0, state.name.clone())); continue; }; @@ -164,37 +157,42 @@ impl ChannelsState { continue; } - channels_to_parse.push((*id, parent_id, state.position)); + to_sort.push((*id, Some(parent_id), state.position, state.name.clone())); } - let mut channel_positions = HashMap::new(); - for (id, state) in self.channels.iter() { - channel_positions.insert(*id, state.position); - } + let pos_name: HashMap = self + .channels + .iter() + .map(|(&id, state)| (id, (state.position, state.name.clone()))) + .collect(); - while channels_updated.len() < channels_to_parse.len() { - for (id, parent_id, position) in &channels_to_parse { - if channels_updated.contains(&id) { - continue; - } - - // Skip channels whose parent we haven't seen yet - if !channels_updated.contains(&parent_id) { + let mut updated: HashSet = HashSet::new(); + + while updated.len() < to_sort.len() { + for &(id, ref parent_id, position, ref name) in &to_sort { + let Some(parent_id) = parent_id else { + updated.insert(id); + continue; + }; + + if updated.contains(&id) || !updated.contains(&parent_id) { continue; } + // Unwrap should never fail here since we pre filter let parent = self.channels.get_mut(&parent_id).unwrap(); - let mut after_index = 0; - for (index, child_id) in parent.children.iter().enumerate() { - after_index = index; - if channel_positions[child_id] > *position { - continue; + let mut insert_index = parent.children.len(); + for (i, &child) in parent.children.iter().enumerate() { + let (p, ref n) = pos_name[&child]; + if (position == p && name < n) || p > position { + insert_index = i; + break; } } - parent.children.insert_before(after_index, *id); - channels_updated.insert(*id); + parent.children.insert_before(insert_index, id); + updated.insert(id); } } }