Files
chanora/apps/chanora_flutter/lib
EdisonJwa 5c413ba199 fix(protocol): sort channels by TS3 linked-list order, not by numeric value
The TeamSpeak 3 protocol's per-channel `order` field is NOT a
numeric rank — it stores the ChannelId of the channel that should
appear immediately before this one within the same parent. The
previous chanora_protocol::adapter::build_snapshot sorted by
`order.0` as if it were a sequence number, producing
stable-but-arbitrary output that did not match TS3 client display
order. Surfaced on the Windows verification round as 'channel
sort in not correct'.

Replace the numeric sort with a linked-list walk per parent
followed by a root-first depth-first emission so the bridge
consumer receives a pre-ordered tree:

  fn sort_channels_tree(&[&Channel]) -> Vec<&Channel>
  fn sort_channels_tree_by<T>(&[&T], extract) -> Vec<&T>
  fn emit_subtree<T>(by_parent, root_id, out, extract)

Defensive behaviour:
  * Per-parent cycle guard so a malformed snapshot can't infinite-loop.
  * Channels whose predecessor pointer is unreachable from
    order=0 are appended at the end of their parent bucket sorted
    by id (channel never silently disappears from the UI).
  * Channels whose `parent` is not present anywhere in the tree
    are appended at the very end sorted by id (orphan defence).

Unit tests cover the four shapes that broke real users:
  * Single-parent linked list out of HashMap iteration order
  * Disconnected predecessor (leftover-bucket fallback)
  * Two-level tree (depth-first subtree emission)
  * Two-channel cycle (no infinite loop, both channels emitted)

Also removes the now-redundant Dart-side numeric sort in
_SnapshotView.build(); Flutter trusts the pre-ordered server
list and would otherwise re-introduce the bug.

Verified on Linux: cargo test --workspace 59/0/3 (was 55 + 4 new
adapter tests), flutter analyze clean.
2026-05-15 20:38:51 +08:00
..