fix(tvos): dismiss overlays with back
This commit is contained in:
@@ -836,6 +836,9 @@ class _MainAppState extends State<MainApp> with WidgetsBindingObserver {
|
||||
...WidgetsApp.defaultShortcuts,
|
||||
const SingleActivator(LogicalKeyboardKey.select): const ActivateIntent(),
|
||||
const SingleActivator(LogicalKeyboardKey.gameButtonA): const ActivateIntent(),
|
||||
const SingleActivator(LogicalKeyboardKey.goBack): const DismissIntent(),
|
||||
const SingleActivator(LogicalKeyboardKey.browserBack): const DismissIntent(),
|
||||
const SingleActivator(LogicalKeyboardKey.gameButtonB): const DismissIntent(),
|
||||
},
|
||||
builder: (context, child) => ScaffoldMessenger(
|
||||
key: rootScaffoldMessengerKey,
|
||||
|
||||
@@ -893,6 +893,10 @@ class _MainScreenState extends State<MainScreen> with RouteAware, WindowListener
|
||||
bool _suppressBackAfterPop = false;
|
||||
|
||||
KeyEventResult _handleBackKey(KeyEvent event) {
|
||||
if (ModalRoute.of(context)?.isCurrent != true) {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
if (_suppressBackAfterPop && event.logicalKey.isBackKey) {
|
||||
if (event is KeyUpEvent) _suppressBackAfterPop = false;
|
||||
return KeyEventResult.handled;
|
||||
|
||||
@@ -9,6 +9,7 @@ import '../../profiles/plex_home_service.dart';
|
||||
import '../../profiles/profile_connection_registry.dart';
|
||||
import '../../providers/companion_remote_provider.dart';
|
||||
import '../../focus/focusable_button.dart';
|
||||
import '../../focus/key_event_utils.dart';
|
||||
import '../../utils/app_logger.dart';
|
||||
|
||||
class RemoteSessionDialog extends StatefulWidget {
|
||||
@@ -99,109 +100,113 @@ class _RemoteSessionDialogState extends State<RemoteSessionDialog> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<CompanionRemoteProvider>(
|
||||
builder: (context, provider, child) {
|
||||
if (_isStarting) {
|
||||
return Dialog(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(32.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const CircularProgressIndicator(),
|
||||
const SizedBox(height: 16),
|
||||
Text(t.companionRemote.session.startingServer, style: Theme.of(context).textTheme.titleMedium),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (_errorMessage != null) {
|
||||
return AlertDialog(
|
||||
title: Text(t.common.error),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(t.companionRemote.session.failedToCreate),
|
||||
const SizedBox(height: 8),
|
||||
Text(_errorMessage!, style: const TextStyle(fontFamily: 'monospace')),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(onPressed: () => Navigator.of(context).pop(), child: Text(t.common.close)),
|
||||
TextButton(onPressed: _ensureServerRunning, child: Text(t.common.retry)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return Dialog(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 500),
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.phone_android, size: 32),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(t.companionRemote.title, style: Theme.of(context).textTheme.headlineSmall),
|
||||
const SizedBox(height: 4),
|
||||
_buildStatusLine(context, provider),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(icon: const Icon(Icons.close), onPressed: () => Navigator.of(context).pop()),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Server status card
|
||||
_buildServerStatus(context, provider),
|
||||
|
||||
// Connected device info
|
||||
if (provider.connectedDevice != null) ...[
|
||||
return Focus(
|
||||
autofocus: true,
|
||||
onKeyEvent: (node, event) => handleBackKeyNavigation(context, event),
|
||||
child: Consumer<CompanionRemoteProvider>(
|
||||
builder: (context, provider, child) {
|
||||
if (_isStarting) {
|
||||
return Dialog(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(32.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const CircularProgressIndicator(),
|
||||
const SizedBox(height: 16),
|
||||
_buildConnectedDevice(context, provider),
|
||||
Text(t.companionRemote.session.startingServer, style: Theme.of(context).textTheme.titleMedium),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const SizedBox(height: 24),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton.icon(
|
||||
onPressed: _toggleServer,
|
||||
icon: Icon(provider.isHostServerRunning ? Icons.stop : Icons.play_arrow),
|
||||
label: Text(
|
||||
provider.isHostServerRunning
|
||||
? t.companionRemote.session.stopServer
|
||||
: t.companionRemote.session.startServer,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
FocusableButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: FilledButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: Text(t.companionRemote.session.minimize),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (_errorMessage != null) {
|
||||
return AlertDialog(
|
||||
title: Text(t.common.error),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(t.companionRemote.session.failedToCreate),
|
||||
const SizedBox(height: 8),
|
||||
Text(_errorMessage!, style: const TextStyle(fontFamily: 'monospace')),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(onPressed: () => Navigator.of(context).pop(), child: Text(t.common.close)),
|
||||
TextButton(onPressed: _ensureServerRunning, child: Text(t.common.retry)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return Dialog(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 500),
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.phone_android, size: 32),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(t.companionRemote.title, style: Theme.of(context).textTheme.headlineSmall),
|
||||
const SizedBox(height: 4),
|
||||
_buildStatusLine(context, provider),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(icon: const Icon(Icons.close), onPressed: () => Navigator.of(context).pop()),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Server status card
|
||||
_buildServerStatus(context, provider),
|
||||
|
||||
// Connected device info
|
||||
if (provider.connectedDevice != null) ...[
|
||||
const SizedBox(height: 16),
|
||||
_buildConnectedDevice(context, provider),
|
||||
],
|
||||
|
||||
const SizedBox(height: 24),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton.icon(
|
||||
onPressed: _toggleServer,
|
||||
icon: Icon(provider.isHostServerRunning ? Icons.stop : Icons.play_arrow),
|
||||
label: Text(
|
||||
provider.isHostServerRunning
|
||||
? t.companionRemote.session.stopServer
|
||||
: t.companionRemote.session.startServer,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
FocusableButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: FilledButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: Text(t.companionRemote.session.minimize),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user