Files
chanora/Cargo.toml
Edison Jwa 808324f374 feat: event-driven UI updates for instant channel switching (#15)
* chore: regenerate Cargo.lock after rebase

* fix(ui): add 1s cool-down to prevent double-tap channel join

voiceJoin returns instantly (fire-and-forget protocol), so the
pending-join guard clears before a second tap lands. The cool-down
prevents the rapid channel oscillation and ClientIsFlooding (524)
that results from double-tapping.

* fix(ui): handle ChannelAlreadyIn as success, ClientIsFlooding with backoff

- ChannelAlreadyIn (0x0302): treat as silent success, update UI state
- ClientIsFlooding (0x020c): show localized snackbar, extend cooldown 5s
- Add l10n strings for flooding error (en + zh)

* fix(proto): use Windows TS3 client version for broadest compatibility

Matches Qint's default (Windows_3_X_X__1). Avoids server-side
behavioral differences with TS5 version strings.

* fix(proto): patch tsproto-types to handle short P-256 coordinates

BigInt::to_bytes_be() strips leading zeros, causing WrongPublicKeyLength
when a server's ephemeral key coordinate starts with 0x00. Patch from
EdisonJwa/tsclientlib fix/p256-short-coordinate-pad branch left-pads
coordinates to the P-256 field size instead of rejecting them.

* refactor(core): stop watchdog from emitting SnapshotChanged

The watchdog now serves only as a liveness probe (miss counting for
reconnection). UI updates are handled entirely by the event-driven
delta path (ProtocolDelta → SessionEvent → BridgeEvent → Flutter).

Removes signature tracking and SnapshotChanged emission from the
supervisor loop. The initial snapshot is still fetched via the
Connected event handler in Flutter.

* refactor(ui): remove channel-join cooldown guard

With event-driven deltas the UI updates instantly on channel moves,
so the 1-second cooldown is no longer needed. Double-taps are handled
by the server (ChannelAlreadyIn → success) and the pending-channel-id
guard prevents overlapping requests.

Also removes the _lastJoinCompletedAt field entirely.

* fix(core): reattach event forwarders after reconnect

The reconnect path swapped in a new ProtocolClient but never took
chat_rx, activity_rx, or delta_rx from it. After the first reconnect,
the event-driven UI pipeline was dead.

Fix by extracting spawn_event_forwarders() helper called on both
initial connect and reconnect. Also replaces lossy try_recv+sleep
polling with proper recv().await for push-based delivery.

* feat(protocol): enrich delta schema with all snapshot-visible fields

ClientJoined now carries input_muted, output_muted, is_server_query,
talk_power, talk_power_granted. ChannelAdded/ChannelUpdated now carry
has_password and needed_talk_power. ClientUpdated also carries
is_server_query, talk_power, talk_power_granted.

This prevents local snapshot drift where fabricated defaults could
hide password requirements, talk-power restrictions, or client type.

* refactor: remove dead SnapshotChanged variant end-to-end

SnapshotChanged is no longer emitted since the watchdog was refactored
to liveness-only. Removes the variant from SessionEvent, BridgeEvent,
and the Flutter switch statement. FRB bindings regenerated.

* fix(ci): regenerate license inventory and fix iOS submodule fetch

- Regenerate docs/security/license-inventory.md to match current lockfile
- Remove submodules: true from checkout (causes hard fail on private submodule)
- Add explicit git submodule update --init --depth=1 with || true fallback
- Check silero-coreml/Package.swift instead of directory existence
2026-06-03 18:20:33 +09:00

85 lines
3.6 KiB
TOML

# Chanora — top-level Cargo workspace.
#
# Layout authority: DEC-022 in
# docs/governance/product-decision-register.md, which adopts the
# README's sketch as canonical:
#
# apps/chanora_flutter/ — Flutter application (separate toolchain)
# core/chanora_core/ — top-level Rust API + orchestration
# crates/chanora_protocol/ — tsclientlib isolation
# crates/chanora_resolver/ — TeamSpeak address resolution
# crates/chanora_state/ — snapshot, deltas, reducers
# crates/chanora_audio/ — capture, DSP, Opus, jitter, mixer
# crates/chanora_storage/ — bookmarks, settings, identity refs
# crates/chanora_diagnostics/ — logs, redaction, export
# crates/chanora_prefetch — server-resolution prefetch cache/policy
# crates/chanora_bridge/ — Flutter/Rust typed DTOs + glue
#
# The Flutter app is not part of this Cargo workspace; it is owned by
# Gradle / Xcode / Flutter tooling under apps/chanora_flutter/.
#
# Proof-of-concept spikes are archived separately in the private
# chanoraapp/chanora-poc repository. Promotion of PoC findings into
# product code happens crate-by-crate with explicit audit-trail commits.
[workspace]
resolver = "2"
members = [
"core/chanora_core",
"crates/chanora_protocol",
"crates/chanora_state",
"crates/chanora_audio",
"crates/chanora_storage",
"crates/chanora_diagnostics",
"crates/chanora_prefetch",
"crates/chanora_bridge",
"crates/chanora_resolver",
]
exclude = [
"apps/chanora_flutter",
]
[workspace.package]
version = "0.2.0-beta.1"
edition = "2021"
rust-version = "1.95"
authors = ["The Chanora Project Contributors"]
license = "MIT OR Apache-2.0" # DEC-020
repository = "https://github.com/anomalyco/opencode"
publish = false # not on crates.io
readme = "README.md"
# Shared dependency pinnings. Members refer to these via
# `package.dependencies.<x>.workspace = true` so versions stay aligned.
[workspace.dependencies]
thiserror = "2"
tracing = "0.1"
serde = { version = "1", features = ["derive"] }
# DEC-032 exit step: override the `cmake` crate with the fork carrying
# cmake-rs PR #257 (https://github.com/rust-lang/cmake-rs/pull/257).
# The patch forwards `ANDROID_ABI` and `ANDROID_PLATFORM` environment
# variables (set per-invocation by cargo-ndk >= 4.x and reinforced by
# our SDD-118 item 5 cleanEnv map) to the child `cmake` invocation as
# `-D` variables, so audiopus_sys's libopus CMake build picks up the
# correct per-ABI target on multi-ABI Android builds. Without it the
# child cmake falls through to the NDK toolchain file's default and
# armeabi-v7a / x86_64 fail to compile.
#
# Pinned by exact commit SHA (the `android-build` branch tip on
# pr2502/cmake-rs as of 2026-05-18) so the patch is reproducible.
# Re-evaluate and remove once PR #257 merges and a fresh `cmake`
# release lands on crates.io (current upstream is 0.7.2).
# Patch tsproto-types to left-pad P-256 coordinates that are shorter than
# 32 bytes. BigInt::to_bytes_be() strips leading zero bytes; when a
# coordinate happens to start with 0x00 (~0.8 % probability per coordinate)
# the upstream code rejects it with WrongPublicKeyLength, breaking the
# init-server handshake. The fix zero-pads to the field size instead.
# Fork: https://github.com/EdisonJwa/tsclientlib/tree/fix/p256-short-coordinate-pad
[patch."https://github.com/ReSpeak/tsclientlib.git"]
tsproto-types = { git = "https://github.com/EdisonJwa/tsclientlib.git", branch = "fix/p256-short-coordinate-pad" }
[patch.crates-io]
cmake = { git = "https://github.com/pr2502/cmake-rs", rev = "bdad5edc569d82151922c5c6c4685b1563f12aa1" }