From 273eaf21c168994eee761db8c53b93ad67d561a4 Mon Sep 17 00:00:00 2001 From: Edison Jwa Date: Wed, 20 May 2026 10:00:18 +0900 Subject: [PATCH] fix(android): add channel password join action --- apps/chanora_flutter/lib/main.dart | 52 ++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/apps/chanora_flutter/lib/main.dart b/apps/chanora_flutter/lib/main.dart index 6136de2..920e925 100644 --- a/apps/chanora_flutter/lib/main.dart +++ b/apps/chanora_flutter/lib/main.dart @@ -703,15 +703,17 @@ class _BetaHomeState extends State<_BetaHome> { } } - Future _onJoinChannel(rust.BridgeChannel ch) async { + Future _onJoinChannel( + rust.BridgeChannel ch, { + bool askForPassword = false, + }) async { if (!_canJoinVoiceChannel) return; if (_pendingVoiceChannelId != null) return; if (ch.id == _currentVoiceChannelId) return; final l10n = AppL10n.of(context); final messenger = ScaffoldMessenger.of(context); String? password; - // Heuristic: a channel name annotated with a lock prompts. - if (ch.name.contains('🔒') || ch.name.toLowerCase().contains('password')) { + if (askForPassword) { password = await _askChannelPassword(l10n); if (password == null) return; // cancelled } @@ -1414,7 +1416,9 @@ class _BetaHomeState extends State<_BetaHome> { pendingVoiceChannelId: _pendingVoiceChannelId, hasJoinPending: _pendingVoiceChannelId != null, canJoinVoiceChannel: _canJoinVoiceChannel, - onJoinChannel: _onJoinChannel, + onJoinChannel: (ch) => _onJoinChannel(ch), + onJoinChannelWithPassword: (ch) => + _onJoinChannel(ch, askForPassword: true), ); const voiceBarWidthWide = 320.0; if (constraints.maxWidth >= wideBreakpoint) { @@ -2057,6 +2061,7 @@ class _SnapshotView extends StatelessWidget { required this.hasJoinPending, required this.canJoinVoiceChannel, required this.onJoinChannel, + required this.onJoinChannelWithPassword, }); final rust.BridgeSnapshot snapshot; @@ -2065,6 +2070,7 @@ class _SnapshotView extends StatelessWidget { final bool hasJoinPending; final bool canJoinVoiceChannel; final ValueChanged onJoinChannel; + final ValueChanged onJoinChannelWithPassword; @override Widget build(BuildContext context) { @@ -2143,19 +2149,31 @@ class _SnapshotView extends StatelessWidget { subtitle: Text('id=${ch.id} parent=${ch.parent}'), trailing: ch.id == currentVoiceChannelId ? null - : IconButton( - icon: Icon( - ch.id == pendingVoiceChannelId - ? Icons.hourglass_top - : Icons.login, - ), - tooltip: ch.id == pendingVoiceChannelId - ? l10n.statusConnecting - : l10n.joinChannelAction, - onPressed: - hasJoinPending || ch.id == pendingVoiceChannelId - ? null - : () => onJoinChannel(ch), + : Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon(Icons.lock_outline), + tooltip: l10n.channelPasswordTitle, + onPressed: hasJoinPending + ? null + : () => onJoinChannelWithPassword(ch), + ), + IconButton( + icon: Icon( + ch.id == pendingVoiceChannelId + ? Icons.hourglass_top + : Icons.login, + ), + tooltip: ch.id == pendingVoiceChannelId + ? l10n.statusConnecting + : l10n.joinChannelAction, + onPressed: + hasJoinPending || ch.id == pendingVoiceChannelId + ? null + : () => onJoinChannel(ch), + ), + ], ), selected: ch.id == currentVoiceChannelId, onTap: