Adds an end-to-end auto-reconnect path so a brief network outage no longer leaves the client wedged in a half-dead state. The flow has three layers, each motivated by a real failure mode observed on the Moto G live test: * `chanora_protocol::DisconnectReason` (`UserRequested` / `StreamEnded` / `Error(String)`) is reported on a `oneshot` when the per-connection task exits, so the supervisor can tell user intent apart from a real loss. * `chanora_core` spawns a supervisor task per `ChanoraSession`. It listens for the loss notifier AND runs a watchdog that issues `snapshot()` probes every 5s with a 4s timeout — three consecutive misses synthesise a `DisconnectReason::Error(...)` and trigger the reconnect path. The watchdog catches the "ghost connected" case where tsclientlib silently resets internal state but the event stream never errors. Backoff schedule: 1s, 2s, 5s, 15s, 30s, 60s (capped). On success the supervisor swaps the dead `ProtocolClient` for the new one in place and, if audio was running, restarts the audio engine bound to the new `voice_in`/`voice_out` channels. * `SessionEvent` (Connected / Lost / Reconnecting / Disconnected / AudioStarted / AudioStopped) is broadcast on a 64-slot channel. `chanora_bridge` re-exports it as `BridgeEvent` and exposes `events_stream(StreamSink)`; the Flutter side subscribes from `initState` and renders a reconnect banner with attempt count and delay. New `SnapshotProbe` exposes a clone-friendly snapshot path so the watchdog can probe without holding `&self` across awaits. Localization adds `statusReconnecting` and `statusConnectionLost` keys to `app_en.arb` and `app_zh.arb`. Verified on Moto G Stylus 5G (Android 14) against cn.teamspeak.app: killed Wi-Fi + cellular for ~70 s; watchdog declared loss at three misses, supervisor walked the backoff schedule, and the UI reconnected automatically once the radios came back. Snapshot tree re-rendered without user action.
531 lines
16 KiB
Dart
531 lines
16 KiB
Dart
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
// coverage:ignore-file
|
|
// ignore_for_file: type=lint
|
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
|
|
|
part of 'lib.dart';
|
|
|
|
// **************************************************************************
|
|
// FreezedGenerator
|
|
// **************************************************************************
|
|
|
|
// dart format off
|
|
T _$identity<T>(T value) => value;
|
|
/// @nodoc
|
|
mixin _$BridgeError {
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError);
|
|
}
|
|
|
|
|
|
@override
|
|
int get hashCode => runtimeType.hashCode;
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BridgeError()';
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
class $BridgeErrorCopyWith<$Res> {
|
|
$BridgeErrorCopyWith(BridgeError _, $Res Function(BridgeError) __);
|
|
}
|
|
|
|
|
|
/// Adds pattern-matching-related methods to [BridgeError].
|
|
extension BridgeErrorPatterns on BridgeError {
|
|
/// A variant of `map` that fallback to returning `orElse`.
|
|
///
|
|
/// It is equivalent to doing:
|
|
/// ```dart
|
|
/// switch (sealedClass) {
|
|
/// case final Subclass value:
|
|
/// return ...;
|
|
/// case _:
|
|
/// return orElse();
|
|
/// }
|
|
/// ```
|
|
|
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( BridgeError_InvalidCommand value)? invalidCommand,TResult Function( BridgeError_DnsFailed value)? dnsFailed,TResult Function( BridgeError_Connection value)? connection,TResult Function( BridgeError_NotConnected value)? notConnected,TResult Function( BridgeError_AlreadyConnected value)? alreadyConnected,TResult Function( BridgeError_Unmapped value)? unmapped,required TResult orElse(),}){
|
|
final _that = this;
|
|
switch (_that) {
|
|
case BridgeError_InvalidCommand() when invalidCommand != null:
|
|
return invalidCommand(_that);case BridgeError_DnsFailed() when dnsFailed != null:
|
|
return dnsFailed(_that);case BridgeError_Connection() when connection != null:
|
|
return connection(_that);case BridgeError_NotConnected() when notConnected != null:
|
|
return notConnected(_that);case BridgeError_AlreadyConnected() when alreadyConnected != null:
|
|
return alreadyConnected(_that);case BridgeError_Unmapped() when unmapped != null:
|
|
return unmapped(_that);case _:
|
|
return orElse();
|
|
|
|
}
|
|
}
|
|
/// A `switch`-like method, using callbacks.
|
|
///
|
|
/// Callbacks receives the raw object, upcasted.
|
|
/// It is equivalent to doing:
|
|
/// ```dart
|
|
/// switch (sealedClass) {
|
|
/// case final Subclass value:
|
|
/// return ...;
|
|
/// case final Subclass2 value:
|
|
/// return ...;
|
|
/// }
|
|
/// ```
|
|
|
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( BridgeError_InvalidCommand value) invalidCommand,required TResult Function( BridgeError_DnsFailed value) dnsFailed,required TResult Function( BridgeError_Connection value) connection,required TResult Function( BridgeError_NotConnected value) notConnected,required TResult Function( BridgeError_AlreadyConnected value) alreadyConnected,required TResult Function( BridgeError_Unmapped value) unmapped,}){
|
|
final _that = this;
|
|
switch (_that) {
|
|
case BridgeError_InvalidCommand():
|
|
return invalidCommand(_that);case BridgeError_DnsFailed():
|
|
return dnsFailed(_that);case BridgeError_Connection():
|
|
return connection(_that);case BridgeError_NotConnected():
|
|
return notConnected(_that);case BridgeError_AlreadyConnected():
|
|
return alreadyConnected(_that);case BridgeError_Unmapped():
|
|
return unmapped(_that);}
|
|
}
|
|
/// A variant of `map` that fallback to returning `null`.
|
|
///
|
|
/// It is equivalent to doing:
|
|
/// ```dart
|
|
/// switch (sealedClass) {
|
|
/// case final Subclass value:
|
|
/// return ...;
|
|
/// case _:
|
|
/// return null;
|
|
/// }
|
|
/// ```
|
|
|
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( BridgeError_InvalidCommand value)? invalidCommand,TResult? Function( BridgeError_DnsFailed value)? dnsFailed,TResult? Function( BridgeError_Connection value)? connection,TResult? Function( BridgeError_NotConnected value)? notConnected,TResult? Function( BridgeError_AlreadyConnected value)? alreadyConnected,TResult? Function( BridgeError_Unmapped value)? unmapped,}){
|
|
final _that = this;
|
|
switch (_that) {
|
|
case BridgeError_InvalidCommand() when invalidCommand != null:
|
|
return invalidCommand(_that);case BridgeError_DnsFailed() when dnsFailed != null:
|
|
return dnsFailed(_that);case BridgeError_Connection() when connection != null:
|
|
return connection(_that);case BridgeError_NotConnected() when notConnected != null:
|
|
return notConnected(_that);case BridgeError_AlreadyConnected() when alreadyConnected != null:
|
|
return alreadyConnected(_that);case BridgeError_Unmapped() when unmapped != null:
|
|
return unmapped(_that);case _:
|
|
return null;
|
|
|
|
}
|
|
}
|
|
/// A variant of `when` that fallback to an `orElse` callback.
|
|
///
|
|
/// It is equivalent to doing:
|
|
/// ```dart
|
|
/// switch (sealedClass) {
|
|
/// case Subclass(:final field):
|
|
/// return ...;
|
|
/// case _:
|
|
/// return orElse();
|
|
/// }
|
|
/// ```
|
|
|
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String field0)? invalidCommand,TResult Function( String host, String reason)? dnsFailed,TResult Function( String field0)? connection,TResult Function()? notConnected,TResult Function()? alreadyConnected,TResult Function( String field0)? unmapped,required TResult orElse(),}) {final _that = this;
|
|
switch (_that) {
|
|
case BridgeError_InvalidCommand() when invalidCommand != null:
|
|
return invalidCommand(_that.field0);case BridgeError_DnsFailed() when dnsFailed != null:
|
|
return dnsFailed(_that.host,_that.reason);case BridgeError_Connection() when connection != null:
|
|
return connection(_that.field0);case BridgeError_NotConnected() when notConnected != null:
|
|
return notConnected();case BridgeError_AlreadyConnected() when alreadyConnected != null:
|
|
return alreadyConnected();case BridgeError_Unmapped() when unmapped != null:
|
|
return unmapped(_that.field0);case _:
|
|
return orElse();
|
|
|
|
}
|
|
}
|
|
/// A `switch`-like method, using callbacks.
|
|
///
|
|
/// As opposed to `map`, this offers destructuring.
|
|
/// It is equivalent to doing:
|
|
/// ```dart
|
|
/// switch (sealedClass) {
|
|
/// case Subclass(:final field):
|
|
/// return ...;
|
|
/// case Subclass2(:final field2):
|
|
/// return ...;
|
|
/// }
|
|
/// ```
|
|
|
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String field0) invalidCommand,required TResult Function( String host, String reason) dnsFailed,required TResult Function( String field0) connection,required TResult Function() notConnected,required TResult Function() alreadyConnected,required TResult Function( String field0) unmapped,}) {final _that = this;
|
|
switch (_that) {
|
|
case BridgeError_InvalidCommand():
|
|
return invalidCommand(_that.field0);case BridgeError_DnsFailed():
|
|
return dnsFailed(_that.host,_that.reason);case BridgeError_Connection():
|
|
return connection(_that.field0);case BridgeError_NotConnected():
|
|
return notConnected();case BridgeError_AlreadyConnected():
|
|
return alreadyConnected();case BridgeError_Unmapped():
|
|
return unmapped(_that.field0);}
|
|
}
|
|
/// A variant of `when` that fallback to returning `null`
|
|
///
|
|
/// It is equivalent to doing:
|
|
/// ```dart
|
|
/// switch (sealedClass) {
|
|
/// case Subclass(:final field):
|
|
/// return ...;
|
|
/// case _:
|
|
/// return null;
|
|
/// }
|
|
/// ```
|
|
|
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String field0)? invalidCommand,TResult? Function( String host, String reason)? dnsFailed,TResult? Function( String field0)? connection,TResult? Function()? notConnected,TResult? Function()? alreadyConnected,TResult? Function( String field0)? unmapped,}) {final _that = this;
|
|
switch (_that) {
|
|
case BridgeError_InvalidCommand() when invalidCommand != null:
|
|
return invalidCommand(_that.field0);case BridgeError_DnsFailed() when dnsFailed != null:
|
|
return dnsFailed(_that.host,_that.reason);case BridgeError_Connection() when connection != null:
|
|
return connection(_that.field0);case BridgeError_NotConnected() when notConnected != null:
|
|
return notConnected();case BridgeError_AlreadyConnected() when alreadyConnected != null:
|
|
return alreadyConnected();case BridgeError_Unmapped() when unmapped != null:
|
|
return unmapped(_that.field0);case _:
|
|
return null;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
|
|
|
|
class BridgeError_InvalidCommand extends BridgeError {
|
|
const BridgeError_InvalidCommand(this.field0): super._();
|
|
|
|
|
|
final String field0;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
@pragma('vm:prefer-inline')
|
|
$BridgeError_InvalidCommandCopyWith<BridgeError_InvalidCommand> get copyWith => _$BridgeError_InvalidCommandCopyWithImpl<BridgeError_InvalidCommand>(this, _$identity);
|
|
|
|
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError_InvalidCommand&&(identical(other.field0, field0) || other.field0 == field0));
|
|
}
|
|
|
|
|
|
@override
|
|
int get hashCode => Object.hash(runtimeType,field0);
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BridgeError.invalidCommand(field0: $field0)';
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
abstract mixin class $BridgeError_InvalidCommandCopyWith<$Res> implements $BridgeErrorCopyWith<$Res> {
|
|
factory $BridgeError_InvalidCommandCopyWith(BridgeError_InvalidCommand value, $Res Function(BridgeError_InvalidCommand) _then) = _$BridgeError_InvalidCommandCopyWithImpl;
|
|
@useResult
|
|
$Res call({
|
|
String field0
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
/// @nodoc
|
|
class _$BridgeError_InvalidCommandCopyWithImpl<$Res>
|
|
implements $BridgeError_InvalidCommandCopyWith<$Res> {
|
|
_$BridgeError_InvalidCommandCopyWithImpl(this._self, this._then);
|
|
|
|
final BridgeError_InvalidCommand _self;
|
|
final $Res Function(BridgeError_InvalidCommand) _then;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@pragma('vm:prefer-inline') $Res call({Object? field0 = null,}) {
|
|
return _then(BridgeError_InvalidCommand(
|
|
null == field0 ? _self.field0 : field0 // ignore: cast_nullable_to_non_nullable
|
|
as String,
|
|
));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
|
|
|
|
class BridgeError_DnsFailed extends BridgeError {
|
|
const BridgeError_DnsFailed({required this.host, required this.reason}): super._();
|
|
|
|
|
|
/// The hostname (or `host:port`) the caller submitted.
|
|
final String host;
|
|
/// Reason from the platform resolver.
|
|
final String reason;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
@pragma('vm:prefer-inline')
|
|
$BridgeError_DnsFailedCopyWith<BridgeError_DnsFailed> get copyWith => _$BridgeError_DnsFailedCopyWithImpl<BridgeError_DnsFailed>(this, _$identity);
|
|
|
|
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError_DnsFailed&&(identical(other.host, host) || other.host == host)&&(identical(other.reason, reason) || other.reason == reason));
|
|
}
|
|
|
|
|
|
@override
|
|
int get hashCode => Object.hash(runtimeType,host,reason);
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BridgeError.dnsFailed(host: $host, reason: $reason)';
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
abstract mixin class $BridgeError_DnsFailedCopyWith<$Res> implements $BridgeErrorCopyWith<$Res> {
|
|
factory $BridgeError_DnsFailedCopyWith(BridgeError_DnsFailed value, $Res Function(BridgeError_DnsFailed) _then) = _$BridgeError_DnsFailedCopyWithImpl;
|
|
@useResult
|
|
$Res call({
|
|
String host, String reason
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
/// @nodoc
|
|
class _$BridgeError_DnsFailedCopyWithImpl<$Res>
|
|
implements $BridgeError_DnsFailedCopyWith<$Res> {
|
|
_$BridgeError_DnsFailedCopyWithImpl(this._self, this._then);
|
|
|
|
final BridgeError_DnsFailed _self;
|
|
final $Res Function(BridgeError_DnsFailed) _then;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@pragma('vm:prefer-inline') $Res call({Object? host = null,Object? reason = null,}) {
|
|
return _then(BridgeError_DnsFailed(
|
|
host: null == host ? _self.host : host // ignore: cast_nullable_to_non_nullable
|
|
as String,reason: null == reason ? _self.reason : reason // ignore: cast_nullable_to_non_nullable
|
|
as String,
|
|
));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
|
|
|
|
class BridgeError_Connection extends BridgeError {
|
|
const BridgeError_Connection(this.field0): super._();
|
|
|
|
|
|
final String field0;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
@pragma('vm:prefer-inline')
|
|
$BridgeError_ConnectionCopyWith<BridgeError_Connection> get copyWith => _$BridgeError_ConnectionCopyWithImpl<BridgeError_Connection>(this, _$identity);
|
|
|
|
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError_Connection&&(identical(other.field0, field0) || other.field0 == field0));
|
|
}
|
|
|
|
|
|
@override
|
|
int get hashCode => Object.hash(runtimeType,field0);
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BridgeError.connection(field0: $field0)';
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
abstract mixin class $BridgeError_ConnectionCopyWith<$Res> implements $BridgeErrorCopyWith<$Res> {
|
|
factory $BridgeError_ConnectionCopyWith(BridgeError_Connection value, $Res Function(BridgeError_Connection) _then) = _$BridgeError_ConnectionCopyWithImpl;
|
|
@useResult
|
|
$Res call({
|
|
String field0
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
/// @nodoc
|
|
class _$BridgeError_ConnectionCopyWithImpl<$Res>
|
|
implements $BridgeError_ConnectionCopyWith<$Res> {
|
|
_$BridgeError_ConnectionCopyWithImpl(this._self, this._then);
|
|
|
|
final BridgeError_Connection _self;
|
|
final $Res Function(BridgeError_Connection) _then;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@pragma('vm:prefer-inline') $Res call({Object? field0 = null,}) {
|
|
return _then(BridgeError_Connection(
|
|
null == field0 ? _self.field0 : field0 // ignore: cast_nullable_to_non_nullable
|
|
as String,
|
|
));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
|
|
|
|
class BridgeError_NotConnected extends BridgeError {
|
|
const BridgeError_NotConnected(): super._();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError_NotConnected);
|
|
}
|
|
|
|
|
|
@override
|
|
int get hashCode => runtimeType.hashCode;
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BridgeError.notConnected()';
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @nodoc
|
|
|
|
|
|
class BridgeError_AlreadyConnected extends BridgeError {
|
|
const BridgeError_AlreadyConnected(): super._();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError_AlreadyConnected);
|
|
}
|
|
|
|
|
|
@override
|
|
int get hashCode => runtimeType.hashCode;
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BridgeError.alreadyConnected()';
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @nodoc
|
|
|
|
|
|
class BridgeError_Unmapped extends BridgeError {
|
|
const BridgeError_Unmapped(this.field0): super._();
|
|
|
|
|
|
final String field0;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
@pragma('vm:prefer-inline')
|
|
$BridgeError_UnmappedCopyWith<BridgeError_Unmapped> get copyWith => _$BridgeError_UnmappedCopyWithImpl<BridgeError_Unmapped>(this, _$identity);
|
|
|
|
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError_Unmapped&&(identical(other.field0, field0) || other.field0 == field0));
|
|
}
|
|
|
|
|
|
@override
|
|
int get hashCode => Object.hash(runtimeType,field0);
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BridgeError.unmapped(field0: $field0)';
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// @nodoc
|
|
abstract mixin class $BridgeError_UnmappedCopyWith<$Res> implements $BridgeErrorCopyWith<$Res> {
|
|
factory $BridgeError_UnmappedCopyWith(BridgeError_Unmapped value, $Res Function(BridgeError_Unmapped) _then) = _$BridgeError_UnmappedCopyWithImpl;
|
|
@useResult
|
|
$Res call({
|
|
String field0
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
/// @nodoc
|
|
class _$BridgeError_UnmappedCopyWithImpl<$Res>
|
|
implements $BridgeError_UnmappedCopyWith<$Res> {
|
|
_$BridgeError_UnmappedCopyWithImpl(this._self, this._then);
|
|
|
|
final BridgeError_Unmapped _self;
|
|
final $Res Function(BridgeError_Unmapped) _then;
|
|
|
|
/// Create a copy of BridgeError
|
|
/// with the given fields replaced by the non-null parameter values.
|
|
@pragma('vm:prefer-inline') $Res call({Object? field0 = null,}) {
|
|
return _then(BridgeError_Unmapped(
|
|
null == field0 ? _self.field0 : field0 // ignore: cast_nullable_to_non_nullable
|
|
as String,
|
|
));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// dart format on
|