refactor(app): remove unsupported server selector state #6
No files matched your search
@@ -1,11 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:revoltvpn/logic/app_colors.dart';
|
||||
import 'package:revoltvpn/logic/vpn_connection.dart';
|
||||
import 'package:revoltvpn/logic/session_timer.dart';
|
||||
import 'package:revoltvpn/logic/server_list.dart';
|
||||
import 'package:revoltvpn/components/online_dot.dart';
|
||||
import 'package:revoltvpn/screens/server_selector/selection_screen.dart';
|
||||
import 'package:revoltvpn/logic/app_colors.dart';
|
||||
import 'package:revoltvpn/logic/session_timer.dart';
|
||||
import 'package:revoltvpn/logic/vpn_connection.dart';
|
||||
|
||||
class StatusBar extends StatelessWidget {
|
||||
const StatusBar({super.key});
|
||||
@@ -26,37 +24,12 @@ class StatusBar extends StatelessWidget {
|
||||
? 'Connecting…'
|
||||
: (vpn.serverReachable ? 'Ready' : 'Offline'));
|
||||
|
||||
final server = context.watch<ServerList>().selected;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
PageRouteBuilder(
|
||||
transitionDuration: const Duration(milliseconds: 300),
|
||||
pageBuilder: (_, __, ___) => const SelectionScreen(),
|
||||
transitionsBuilder: (_, animation, __, child) {
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(1.0, 0.0),
|
||||
end: Offset.zero,
|
||||
).animate(
|
||||
CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: Curves.easeOut,
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
@@ -66,12 +39,16 @@ class StatusBar extends StatelessWidget {
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(server.flagAsset, width: 20, height: 20),
|
||||
Image.asset(
|
||||
'assets/finland_flag_256.png',
|
||||
width: 20,
|
||||
height: 20,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
const Expanded(
|
||||
child: Text(
|
||||
server.name,
|
||||
style: const TextStyle(
|
||||
'Helsinki, Finland',
|
||||
style: TextStyle(
|
||||
color: AppColors.accent,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 13,
|
||||
@@ -79,15 +56,9 @@ class StatusBar extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.chevron_right,
|
||||
color: AppColors.textDim,
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
padding:
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
// ── lib/logic/server_list.dart ──────────────────────────────────────────────
|
||||
// Server data model and ChangeNotifier — shared by StatusBar (shows current
|
||||
// server name/flag) and SelectionScreen (lets user pick a server).
|
||||
//
|
||||
// Each server is defined by its tunnel IP/port. Reality credentials (public
|
||||
// key, shortId) come from /session/status per session; only the transport
|
||||
// parameters live in AppConfig.
|
||||
//
|
||||
// When multi-server ships:
|
||||
// - _all becomes a fetched list (from /api/servers or bundled config)
|
||||
// - SelectionScreen shows multiple rows
|
||||
// - select() triggers a disconnect/reconnect cycle if the tunnel is active
|
||||
|
||||
class ServerInfo {
|
||||
final String id;
|
||||
final String name;
|
||||
final String flagAsset;
|
||||
final String ip;
|
||||
final int port;
|
||||
|
||||
const ServerInfo({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.flagAsset,
|
||||
required this.ip,
|
||||
required this.port,
|
||||
});
|
||||
}
|
||||
|
||||
class ServerList extends ChangeNotifier {
|
||||
static const _all = [
|
||||
ServerInfo(
|
||||
id: 'finland',
|
||||
name: 'Helsinki, Finland',
|
||||
flagAsset: 'assets/finland_flag_256.png',
|
||||
ip: '204.168.246.88',
|
||||
port: 443,
|
||||
),
|
||||
];
|
||||
|
||||
int _selectedIndex = 0;
|
||||
|
||||
List<ServerInfo> get all => _all;
|
||||
int get selectedIndex => _selectedIndex;
|
||||
ServerInfo get selected => _all[_selectedIndex];
|
||||
|
||||
// Loads persisted selection from SharedPreferences.
|
||||
// Fire-and-forget — UI starts with default, updates when prefs load.
|
||||
Future<void> init() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final saved = prefs.getInt('selected_server_index') ?? 0;
|
||||
if (saved >= 0 && saved < _all.length && saved != _selectedIndex) {
|
||||
_selectedIndex = saved;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// Switches to a different server. Persists the choice.
|
||||
Future<void> select(int index) async {
|
||||
if (index == _selectedIndex || index < 0 || index >= _all.length) return;
|
||||
_selectedIndex = index;
|
||||
notifyListeners();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setInt('selected_server_index', index);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import 'package:revoltvpn/logic/ad_manager.dart';
|
||||
import 'package:revoltvpn/logic/app_colors.dart';
|
||||
import 'package:revoltvpn/logic/connection_settings.dart';
|
||||
import 'package:revoltvpn/logic/haptic_settings.dart';
|
||||
import 'package:revoltvpn/logic/server_list.dart';
|
||||
import 'package:revoltvpn/logic/session_timer.dart';
|
||||
import 'package:revoltvpn/logic/vpn_connection.dart';
|
||||
import 'package:revoltvpn/screens/intro.dart';
|
||||
@@ -56,10 +55,6 @@ class ReVoltApp extends StatelessWidget {
|
||||
prev ?? SessionTimer(vpnConnection: vpn),
|
||||
),
|
||||
ChangeNotifierProvider(create: (_) => AdManager()),
|
||||
ChangeNotifierProvider(
|
||||
create: (_) => ServerList()..init(),
|
||||
lazy: false,
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
title: 'ReVolt VPN',
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:revoltvpn/logic/app_colors.dart';
|
||||
import 'package:revoltvpn/logic/server_list.dart';
|
||||
|
||||
// ── lib/screens/server_selector/selection_screen.dart ──────────────────────
|
||||
// Server picker — reads the server list from the ServerList provider.
|
||||
// Each row shows a flag + city name. Tapping a row persists the choice
|
||||
// and pops back. No latency measurement — the app runs inside a Reality
|
||||
// tunnel and must not emit separate probe traffic.
|
||||
|
||||
class SelectionScreen extends StatelessWidget {
|
||||
const SelectionScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serverList = context.watch<ServerList>();
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bgDeep,
|
||||
appBar: AppBar(
|
||||
backgroundColor: AppColors.bgSurface,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: AppColors.textWhite),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
title: const Text(
|
||||
'Select Server',
|
||||
style: TextStyle(
|
||||
color: AppColors.textWhite,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemCount: serverList.all.length,
|
||||
itemBuilder: (context, index) {
|
||||
final server = serverList.all[index];
|
||||
final isSelected = index == serverList.selectedIndex;
|
||||
|
||||
return ListTile(
|
||||
leading: Image.asset(server.flagAsset, width: 28, height: 28),
|
||||
title: Text(server.name,
|
||||
style: TextStyle(
|
||||
color: isSelected ? AppColors.accent : AppColors.textWhite,
|
||||
fontWeight: FontWeight.w600,
|
||||
)),
|
||||
trailing: isSelected
|
||||
? const Icon(Icons.check, color: AppColors.accent)
|
||||
: null,
|
||||
onTap: () {
|
||||
serverList.select(index);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user