This commit is contained in:
2026-02-27 21:12:56 +08:00
commit a878084cbb
233 changed files with 22988 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../controller/peers_controller.dart';
import '../widgets/peer_card.dart';
import '../../../shared/widgets/empty_state.dart';
class PeersPage extends ConsumerWidget {
const PeersPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final peersAsync = ref.watch(peersControllerProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Peers Discovery'),
actions: [
IconButton(
tooltip: '刷新',
onPressed: () =>
ref.read(peersControllerProvider.notifier).refresh(),
icon: const Icon(Icons.refresh_rounded),
),
],
),
body: peersAsync.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (error, _) => AppEmptyState(
icon: Icons.cloud_off_rounded,
title: '发现失败',
message: error.toString(),
action: FilledButton.icon(
onPressed: () =>
ref.read(peersControllerProvider.notifier).refresh(),
icon: const Icon(Icons.refresh_rounded),
label: const Text('重试'),
),
),
data: (peers) {
if (peers.isEmpty) {
return AppEmptyState(
icon: Icons.wifi_tethering,
title: '扫描中',
message: '请确认局域网连接和防火墙配置。',
);
}
final width = MediaQuery.sizeOf(context).width;
final columns = width >= 1320
? 4
: width >= 1100
? 3
: width >= 720
? 2
: 1;
return GridView.builder(
padding: const EdgeInsets.all(16),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: columns,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: 1.36,
),
itemCount: peers.length,
itemBuilder: (context, index) => PeerCard(peer: peers[index]),
);
},
),
);
}
}