diff --git a/example/lib/components/peer_widget.dart b/example/lib/components/peer_widget.dart index 07c6f56..b476a16 100644 --- a/example/lib/components/peer_widget.dart +++ b/example/lib/components/peer_widget.dart @@ -7,21 +7,30 @@ class PeerWidget extends StatelessWidget { required this.device, required this.isIosBrowser, required this.onConnect, + required this.communicationChannelState, }); final NearbyDevice device; final bool isIosBrowser; final ValueChanged onConnect; + final CommunicationChannelState communicationChannelState; @override Widget build(BuildContext context) { + final connectedStateCaption = communicationChannelState.isLoading + ? 'Wait for connection' + : 'Tap to chat'; + final status = - device.status.isConnected ? 'Tap to chat' : device.status.name; + device.status.isConnected ? connectedStateCaption : device.status.name; + + final canTap = !communicationChannelState.isLoading; + return ListTile( title: Text( '${isIosBrowser ? 'Found device' : 'Pending invitation'} | ${device.info.displayName} | $status', ), - onTap: () => onConnect(device), + onTap: canTap ? () => onConnect(device) : null, tileColor: Colors.blueAccent, textColor: Colors.white, ); diff --git a/example/lib/main.dart b/example/lib/main.dart index 3be8b25..e4846d1 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -57,10 +57,11 @@ class AppBody extends StatefulWidget { class _AppBodyState extends State { /// Our service - final _nearbyService = NearbyService.getInstance( + late final _nearbyService = NearbyService.getInstance( /// Define log level here logLevel: NearbyServiceLogLevel.debug, - ); + )..communicationChannelState.addListener(() => setState(() {})); + AppState _state = AppState.idle; /// Browser OR Advertiser for IOS @@ -116,6 +117,7 @@ class _AppBodyState extends State { device: e, isIosBrowser: _isIosBrowser, onConnect: _connect, + communicationChannelState: _communicationChannelState, ), ), ], @@ -155,6 +157,10 @@ class _AppBodyState extends State { return Container(); } + CommunicationChannelState get _communicationChannelState { + return _nearbyService.communicationChannelState.value; + } + Future _initialize() async { await _nearbyService.initialize(); } @@ -199,30 +205,42 @@ class _AppBodyState extends State { // double connection may be unnecessary final result = await _nearbyService.connect(device); if (result || device.status.isConnected) { - _connectionCheckTimer = Timer.periodic( - const Duration(seconds: 3), - (_) { - NearbyDevice? selectedDevice; - try { - selectedDevice = _peers.firstWhere( - (element) => element.info.id == device.info.id, - ); - } finally {} - - if (selectedDevice.status.isConnected) { - try { - _startCommunicationChannel(device); - } finally { - _connectionCheckTimer?.cancel(); - _connectionCheckTimer = null; - } - } - }, - ); + final channelStarting = _tryCommunicate(device); + if (!channelStarting) { + _connectionCheckTimer = Timer.periodic( + const Duration(seconds: 3), + (_) => _tryCommunicate(device), + ); + } } } + bool _tryCommunicate(NearbyDevice device) { + NearbyDevice? selectedDevice; + + try { + selectedDevice = _peers.firstWhere( + (element) => element.info.id == device.info.id, + ); + } catch (_) { + return false; + } + + if (selectedDevice.status.isConnected) { + try { + _startCommunicationChannel(device); + } finally { + _connectionCheckTimer?.cancel(); + _connectionCheckTimer = null; + } + return true; + } + return false; + } + void _startCommunicationChannel(NearbyDevice device) { + if (!_communicationChannelState.isNotConnected) return; + _nearbyService.startCommunicationChannel( NearbyCommunicationChannelData( device.info.id, @@ -260,6 +278,7 @@ class _AppBodyState extends State { await _nearbyService.stopDiscovery(); await _peersSubscription?.cancel(); setState(() { + _peers = []; _state = AppState.idle; }); } diff --git a/example/lib/utils/app_snack_bar.dart b/example/lib/utils/app_snack_bar.dart index ca2822f..bcbe7ed 100644 --- a/example/lib/utils/app_snack_bar.dart +++ b/example/lib/utils/app_snack_bar.dart @@ -24,6 +24,7 @@ class AppSnackBar { SnackBar( content: content, action: action, + duration: Duration(seconds: action != null ? 10 : 2), ), ); return messenger.closed.then((value) => null);