feat: promote linux native audio path
This commit is contained in:
@@ -226,6 +226,9 @@ class _BetaHomeState extends State<_BetaHome> with WidgetsBindingObserver {
|
||||
AndroidPermissionsService();
|
||||
final IosPermissionsService _iosPermissions = IosPermissionsService();
|
||||
final UiPreferencesService _uiPreferences = const UiPreferencesService();
|
||||
Map<String, ClientPlaybackPreference> _clientPlaybackPrefs = const {};
|
||||
final Map<BigInt, double> _appliedClientPlaybackVolumes = {};
|
||||
String _clientPlaybackPrefsHost = '';
|
||||
late final BackIntentService _backIntentService;
|
||||
int _modalRouteDepth = 0;
|
||||
|
||||
@@ -314,6 +317,105 @@ class _BetaHomeState extends State<_BetaHome> with WidgetsBindingObserver {
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Future<void> _ensureClientPlaybackPreferencesLoadedForCurrentHost() async {
|
||||
final host = _hostCtl.text.trim().toLowerCase();
|
||||
if (host.isEmpty) {
|
||||
_clientPlaybackPrefsHost = '';
|
||||
_clientPlaybackPrefs = const {};
|
||||
_appliedClientPlaybackVolumes.clear();
|
||||
return;
|
||||
}
|
||||
if (_clientPlaybackPrefsHost == host) return;
|
||||
_appliedClientPlaybackVolumes.clear();
|
||||
try {
|
||||
_clientPlaybackPrefs = await _uiPreferences
|
||||
.loadClientPlaybackPreferencesForServer(host);
|
||||
_clientPlaybackPrefsHost = host;
|
||||
} catch (_) {
|
||||
_clientPlaybackPrefsHost = host;
|
||||
_clientPlaybackPrefs = const {};
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _applyClientPlaybackPreferencesToSnapshot(
|
||||
rust.BridgeSnapshot snap,
|
||||
) async {
|
||||
await _ensureClientPlaybackPreferencesLoadedForCurrentHost();
|
||||
if (_clientPlaybackPrefs.isEmpty) return;
|
||||
for (final client in snap.clients) {
|
||||
if (client.id == snap.ownClientId ||
|
||||
client.isServerQuery ||
|
||||
client.uid.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
final pref = _clientPlaybackPrefs[client.uid];
|
||||
if (pref == null) continue;
|
||||
if (_appliedClientPlaybackVolumes[client.id] == pref.appliedVolume) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
await rust.setClientVolume(
|
||||
clientId: client.id,
|
||||
volume: pref.appliedVolume,
|
||||
);
|
||||
_appliedClientPlaybackVolumes[client.id] = pref.appliedVolume;
|
||||
} catch (_) {
|
||||
// Best-effort: queues may not exist yet for silent users.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setClientPlaybackPreference(
|
||||
rust.BridgeClient client,
|
||||
ClientPlaybackPreference preference,
|
||||
) async {
|
||||
if (client.id == _snapshot?.ownClientId ||
|
||||
client.isServerQuery ||
|
||||
client.uid.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final host = _hostCtl.text.trim().toLowerCase();
|
||||
if (host.isEmpty) return;
|
||||
|
||||
await _ensureClientPlaybackPreferencesLoadedForCurrentHost();
|
||||
final nextPrefs = Map<String, ClientPlaybackPreference>.from(
|
||||
_clientPlaybackPrefs,
|
||||
);
|
||||
if (preference.volume == 1.0 && !preference.muted) {
|
||||
nextPrefs.remove(client.uid);
|
||||
} else {
|
||||
nextPrefs[client.uid] = preference;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() => _clientPlaybackPrefs = nextPrefs);
|
||||
} else {
|
||||
_clientPlaybackPrefs = nextPrefs;
|
||||
}
|
||||
|
||||
try {
|
||||
await _uiPreferences.saveClientPlaybackPreference(
|
||||
serverHost: host,
|
||||
userUid: client.uid,
|
||||
volume: preference.volume,
|
||||
muted: preference.muted,
|
||||
);
|
||||
} catch (error) {
|
||||
_recordUiDiagnostic('save client playback preference', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await rust.setClientVolume(
|
||||
clientId: client.id,
|
||||
volume: preference.appliedVolume,
|
||||
);
|
||||
_appliedClientPlaybackVolumes[client.id] = preference.appliedVolume;
|
||||
} catch (error) {
|
||||
_recordUiDiagnostic('set client volume', error);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _requestRecordAudioOnStartup() async {
|
||||
try {
|
||||
if (Platform.isAndroid) {
|
||||
@@ -1482,6 +1584,7 @@ class _BetaHomeState extends State<_BetaHome> with WidgetsBindingObserver {
|
||||
|
||||
void _applySnapshot(rust.BridgeSnapshot snap) {
|
||||
_snapshot = snap;
|
||||
unawaited(_applyClientPlaybackPreferencesToSnapshot(snap));
|
||||
final own = ownClientSnapshotState(snap);
|
||||
if (own == null) return;
|
||||
_inputMuted = own.inputMuted;
|
||||
@@ -2013,6 +2116,9 @@ class _BetaHomeState extends State<_BetaHome> with WidgetsBindingObserver {
|
||||
onJoinChannel: (ch) => _onJoinChannel(ch),
|
||||
onJoinChannelWithPassword: (ch) =>
|
||||
_onJoinChannel(ch, askForPassword: true),
|
||||
clientPlaybackPreferences: _clientPlaybackPrefs,
|
||||
onClientPlaybackPreferenceChanged:
|
||||
_setClientPlaybackPreference,
|
||||
onTs3ServerLink: _onTs3ServerLink,
|
||||
);
|
||||
final ownClientState = _ownClientState;
|
||||
|
||||
Reference in New Issue
Block a user