Skip to content

Commit abc3d79

Browse files
committed
handle removal for user peers only
1 parent 9ed44aa commit abc3d79

3 files changed

Lines changed: 79 additions & 35 deletions

File tree

lib/features/peers/peers_screen.dart

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class _PeersDataScreenState extends ConsumerState<_PeersDataScreen> {
9393

9494
@override
9595
Widget build(BuildContext context) {
96+
final peersNotifier = ref.read(peersProvider.notifier);
97+
final userPeers = peersNotifier.userPeers;
9698
final filtered = query.isEmpty
9799
? widget.peers
98100
: widget.peers
@@ -117,8 +119,7 @@ class _PeersDataScreenState extends ConsumerState<_PeersDataScreen> {
117119
Divider(
118120
height: 1,
119121
thickness: 1,
120-
color: Theme.of(context)
121-
.dividerColor, // You can use Theme.of(context).dividerColor for theme-aware color
122+
color: Theme.of(context).dividerColor,
122123
),
123124
]),
124125
currentIndex: 1,
@@ -142,10 +143,12 @@ class _PeersDataScreenState extends ConsumerState<_PeersDataScreen> {
142143
const SizedBox(height: AppSpacing.sm),
143144
itemBuilder: (_, index) {
144145
final p = filtered[index];
146+
final isUserPeer = userPeers.contains(p);
145147
return _PeerTile(
146148
ip: p,
147149
country: "Unknown",
148150
health: 0.8,
151+
isUserPeer: isUserPeer,
149152
);
150153
},
151154
),
@@ -262,12 +265,13 @@ class _PeerTile extends StatelessWidget {
262265
final String ip;
263266
final String country;
264267
final double health;
268+
final bool isUserPeer;
265269

266-
const _PeerTile({
267-
required this.ip,
268-
required this.country,
269-
required this.health,
270-
});
270+
const _PeerTile(
271+
{required this.ip,
272+
required this.country,
273+
required this.health,
274+
required this.isUserPeer});
271275

272276
@override
273277
Widget build(BuildContext context) {
@@ -315,9 +319,11 @@ class _PeerTile extends StatelessWidget {
315319
showDragHandle: true,
316320
builder: (_) => PeerDetailsSheet(
317321
country: country,
322+
ip: ip,
318323
city: "",
319324
latency: "",
320325
status: "",
326+
isUserPeer: isUserPeer,
321327
),
322328
);
323329
},
@@ -415,7 +421,9 @@ void _showAddPeerDialog(BuildContext context, WidgetRef ref) {
415421
title: const Text('Add Peer'),
416422
content: TextField(
417423
controller: controller,
418-
decoration: const InputDecoration(hintText: 'Enter peer IP'),
424+
decoration: const InputDecoration(
425+
hintText: 'Enter peer IP (e.g. 185.69.166.7)',
426+
),
419427
keyboardType: TextInputType.url,
420428
),
421429
actions: [
@@ -427,7 +435,10 @@ void _showAddPeerDialog(BuildContext context, WidgetRef ref) {
427435
onPressed: () async {
428436
final ip = controller.text.trim();
429437
if (ip.isNotEmpty) {
430-
await peersNotifier.addPeer(ip);
438+
final formattedPeer =
439+
ip.startsWith('tcp://') ? ip : 'tcp://$ip:9651';
440+
441+
await peersNotifier.addPeer(formattedPeer);
431442
}
432443
Navigator.of(context).pop();
433444
},

lib/features/peers/widgets/peer_details_sheet.dart

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,76 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_riverpod/flutter_riverpod.dart';
23
import '../../../app/theme/tokens.dart';
3-
import '../../../app/widgets/app_card.dart';
4+
import '../../../state/mycelium_providers.dart';
45

5-
class PeerDetailsSheet extends StatelessWidget {
6+
class PeerDetailsSheet extends ConsumerWidget {
7+
final String ip;
68
final String country;
79
final String city;
810
final String latency;
911
final String status;
12+
final bool isUserPeer;
1013

11-
const PeerDetailsSheet({super.key, required this.country, required this.city, required this.latency, required this.status});
14+
const PeerDetailsSheet(
15+
{super.key,
16+
required this.country,
17+
required this.city,
18+
required this.latency,
19+
required this.status,
20+
required this.ip,
21+
this.isUserPeer = false});
1222

1323
@override
14-
Widget build(BuildContext context) {
24+
Widget build(BuildContext context, WidgetRef ref) {
25+
final peersNotifier = ref.read(peersProvider.notifier);
1526
return Padding(
1627
padding: const EdgeInsets.all(AppSpacing.lg),
1728
child: Column(
1829
mainAxisSize: MainAxisSize.min,
1930
children: [
20-
Container(height: 4, width: 40, margin: const EdgeInsets.only(bottom: AppSpacing.lg), decoration: BoxDecoration(color: Theme.of(context).colorScheme.outline, borderRadius: BorderRadius.circular(2))),
31+
Container(
32+
height: 4,
33+
width: 40,
34+
margin: const EdgeInsets.only(bottom: AppSpacing.lg),
35+
decoration: BoxDecoration(
36+
color: Theme.of(context).colorScheme.outline,
37+
borderRadius: BorderRadius.circular(2))),
2138
Row(children: [
2239
const CircleAvatar(radius: 16, child: Text('US')),
2340
const SizedBox(width: AppSpacing.lg),
24-
Expanded(child: Text(country, style: Theme.of(context).textTheme.titleMedium, overflow: TextOverflow.ellipsis)),
41+
Expanded(
42+
child: Text(country,
43+
style: Theme.of(context).textTheme.titleMedium,
44+
overflow: TextOverflow.ellipsis)),
2545
const SizedBox(width: AppSpacing.lg),
2646
Text(latency, style: Theme.of(context).textTheme.labelMedium),
2747
]),
28-
const SizedBox(height: AppSpacing.xxl),
29-
AppCard(
30-
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
31-
Text('Health Check', style: Theme.of(context).textTheme.titleMedium),
32-
const SizedBox(height: AppSpacing.lg),
33-
Row(children: [
34-
_Kpi(title: 'Ping Status', value: 'Reachable'),
48+
const SizedBox(height: AppSpacing.lg),
49+
Row(
50+
children: [
51+
Expanded(
52+
child: OutlinedButton(
53+
onPressed: () {},
54+
child: const Text('Ping Test'),
55+
),
56+
),
57+
if (isUserPeer) ...[
3558
const SizedBox(width: AppSpacing.lg),
36-
_Kpi(title: 'Latency', value: latency),
37-
]),
38-
]),
59+
Expanded(
60+
child: FilledButton.tonal(
61+
onPressed: () async {
62+
await peersNotifier.removePeer(ip);
63+
if (context.mounted) {
64+
Navigator.of(context).pop();
65+
}
66+
},
67+
child: const Text('Remove Peer'),
68+
),
69+
),
70+
],
71+
],
3972
),
4073
const SizedBox(height: AppSpacing.lg),
41-
Row(children: [
42-
Expanded(child: OutlinedButton(onPressed: () {}, child: const Text('Ping Test'))),
43-
const SizedBox(width: AppSpacing.lg),
44-
Expanded(child: FilledButton.tonal(onPressed: () {}, child: const Text('Remove Peer'))),
45-
]),
46-
const SizedBox(height: AppSpacing.lg),
4774
],
4875
),
4976
);
@@ -59,7 +86,9 @@ class _Kpi extends StatelessWidget {
5986
Widget build(BuildContext context) {
6087
return Expanded(
6188
child: Container(
62-
decoration: BoxDecoration(color: Theme.of(context).colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(AppRadii.md)),
89+
decoration: BoxDecoration(
90+
color: Theme.of(context).colorScheme.surfaceContainerHighest,
91+
borderRadius: BorderRadius.circular(AppRadii.md)),
6392
padding: const EdgeInsets.all(AppSpacing.lg),
6493
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
6594
Text(title, style: Theme.of(context).textTheme.labelMedium),
@@ -70,5 +99,3 @@ class _Kpi extends StatelessWidget {
7099
);
71100
}
72101
}
73-
74-

lib/state/mycelium_providers.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@ class PeersNotifier extends StateNotifier<AsyncValue<List<String>>> {
2020
final PeersService _service;
2121
final PeersRepository _repo;
2222

23+
List<String> _userPeers = [];
24+
25+
List<String> get userPeers => _userPeers;
26+
2327
PeersNotifier(this._service, this._repo) : super(const AsyncLoading()) {
2428
_fetchPeers();
2529
}
2630

2731
Future<void> _fetchPeers() async {
2832
try {
29-
final userPeers = await _repo.loadPeers();
33+
_userPeers = await _repo.loadPeers();
3034
final fetchedPeers = await _service.fetchPeers();
3135

3236
final allPeers = {...userPeers, ...fetchedPeers}.toList();
@@ -38,6 +42,7 @@ class PeersNotifier extends StateNotifier<AsyncValue<List<String>>> {
3842

3943
Future<void> addPeer(String peer) async {
4044
await _repo.addPeer(peer);
45+
_userPeers.add(peer);
4146
final current = state.value ?? [];
4247
if (!current.contains(peer)) {
4348
state = AsyncData([...current, peer]);
@@ -46,6 +51,7 @@ class PeersNotifier extends StateNotifier<AsyncValue<List<String>>> {
4651

4752
Future<void> removePeer(String peer) async {
4853
await _repo.removePeer(peer);
54+
_userPeers.remove(peer);
4955
final current = state.value ?? [];
5056
state = AsyncData(current.where((p) => p != peer).toList());
5157
}

0 commit comments

Comments
 (0)