Preserve Flutter mirror-os codebase
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:mirror_ui/mirror_ui.dart';
|
||||
import '../providers/connection_provider.dart';
|
||||
|
||||
class ConnectScreen extends ConsumerStatefulWidget {
|
||||
const ConnectScreen({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<ConnectScreen> createState() => _ConnectScreenState();
|
||||
}
|
||||
|
||||
class _ConnectScreenState extends ConsumerState<ConnectScreen> {
|
||||
final _hostController = TextEditingController();
|
||||
bool _loaded = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadSavedHost();
|
||||
}
|
||||
|
||||
Future<void> _loadSavedHost() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final saved = prefs.getString('mirror_host') ?? 'mirror.local';
|
||||
_hostController.text = saved;
|
||||
setState(() => _loaded = true);
|
||||
// Auto-connect only if not manually disconnected
|
||||
final connection = ref.read(connectionProvider);
|
||||
if (!connection.manualDisconnect && saved.isNotEmpty && saved != 'mirror.local') {
|
||||
_connect();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _saveHost(String host) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('mirror_host', host);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_hostController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final connection = ref.watch(connectionProvider);
|
||||
|
||||
if (!_loaded) {
|
||||
return const Scaffold(body: Center(child: CircularProgressIndicator()));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Spacer(),
|
||||
Icon(
|
||||
Icons.cast_connected,
|
||||
size: 64,
|
||||
color: MirrorTheme.accent,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
'Mirror OS',
|
||||
style: Theme.of(context).textTheme.headlineLarge,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Connect to your mirror',
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
TextField(
|
||||
controller: _hostController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Mirror address',
|
||||
hintText: 'mirror.local or 192.168.x.x',
|
||||
filled: true,
|
||||
fillColor: MirrorTheme.surface,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
prefixIcon: const Icon(Icons.wifi),
|
||||
),
|
||||
keyboardType: TextInputType.url,
|
||||
onSubmitted: (_) => _connect(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
onPressed: connection.connecting ? null : _connect,
|
||||
style: FilledButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: connection.connecting
|
||||
? const SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Text('Connect'),
|
||||
),
|
||||
if (connection.error != null) ...[
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
connection.error!,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: MirrorTheme.danger,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
const Spacer(),
|
||||
Text(
|
||||
'Make sure your phone is on the same\nWiFi network as the mirror',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _connect() {
|
||||
final host = _hostController.text.trim();
|
||||
if (host.isNotEmpty) {
|
||||
_saveHost(host);
|
||||
ref.read(connectionProvider.notifier).connect(host);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user