Skip to content

Commit ebf2f51

Browse files
committed
rework
1 parent 992ccdf commit ebf2f51

File tree

10 files changed

+145
-84
lines changed

10 files changed

+145
-84
lines changed

android/app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
1818
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
1919
<uses-permission android:name="android.permission.CAMERA" />
20+
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
21+
2022

2123
<application
2224
android:label="VPN Client"

assets/lang/ru.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"kazakhstan": "Казахстан",
99
"turkey": "Турция",
1010
"poland": "Польша",
11-
"fastest": "Самый быстрый",
11+
"fastest": "Быстрейший",
1212
"selected_server": "Выбранный сервер",
1313
"server_selection": "Выбор сервера",
1414
"all_servers": "Все серверы",

lib/main.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter/services.dart';
23
import 'package:provider/provider.dart';
3-
import 'package:vpn_client/pages/apps/apps_page.dart';
44
import 'dart:ui' as ui;
55
import 'package:vpn_client/pages/main/main_page.dart';
66
import 'package:vpn_client/pages/settings/setting_page.dart';
@@ -9,6 +9,7 @@ import 'package:vpn_client/theme_provider.dart';
99
import 'package:flutter_localizations/flutter_localizations.dart';
1010
import 'package:vpn_client/vpn_state.dart';
1111
import 'package:vpn_client/localization_service.dart';
12+
// import 'package:vpn_client/pages/apps/apps_page.dart';
1213

1314
import 'design/colors.dart';
1415
import 'nav_bar.dart';
@@ -20,6 +21,10 @@ void main() async {
2021
ui.PlatformDispatcher.instance.locale; // <-- Get the system locale
2122
await LocalizationService.load(userLocale);
2223

24+
await SystemChrome.setPreferredOrientations([
25+
DeviceOrientation.portraitUp,
26+
DeviceOrientation.portraitDown,
27+
]);
2328
runApp(
2429
MultiProvider(
2530
providers: [
@@ -80,17 +85,17 @@ class MainScreen extends StatefulWidget {
8085
}
8186

8287
class _MainScreenState extends State<MainScreen> {
83-
int _currentIndex = 2;
88+
int _currentIndex = 1;
8489
late List<Widget> _pages;
8590

8691
@override
8792
void initState() {
8893
super.initState();
8994
_pages = [
90-
const AppsPage(),
95+
// const AppsPage(),
9196
ServersPage(onNavBarTap: _handleNavBarTap),
9297
const MainPage(),
93-
const PlaceholderPage(text: 'Speed Page'),
98+
// const PlaceholderPage(text: 'Speed Page'),
9499
SettingPage(onNavBarTap: _handleNavBarTap),
95100
];
96101
}

lib/nav_bar.dart

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class NavBar extends StatefulWidget {
55
final int initialIndex;
66
final Function(int) onItemTapped;
77

8-
const NavBar({super.key, this.initialIndex = 2, required this.onItemTapped});
8+
const NavBar({super.key, this.initialIndex = 0, required this.onItemTapped});
99

1010
@override
1111
State<NavBar> createState() => NavBarState();
@@ -14,19 +14,11 @@ class NavBar extends StatefulWidget {
1414
class NavBarState extends State<NavBar> {
1515
late int _selectedIndex;
1616

17-
final List<Widget> _inactiveIcons = [
18-
appIcon,
19-
serverIcon,
20-
homeIcon,
21-
speedIcon,
22-
settingsIcon,
23-
];
17+
final List<Widget> _inactiveIcons = [serverIcon, homeIcon, settingsIcon];
2418

2519
final List<Widget> _activeIcons = [
26-
activeAppIcon,
2720
activeServerIcon,
2821
activeHomeIcon,
29-
speedIcon,
3022
activeSettingsIcon,
3123
];
3224

@@ -36,6 +28,16 @@ class NavBarState extends State<NavBar> {
3628
_selectedIndex = widget.initialIndex;
3729
}
3830

31+
@override
32+
void didUpdateWidget(covariant NavBar oldWidget) {
33+
super.didUpdateWidget(oldWidget);
34+
if (widget.initialIndex != oldWidget.initialIndex) {
35+
setState(() {
36+
_selectedIndex = widget.initialIndex;
37+
});
38+
}
39+
}
40+
3941
void _onItemTapped(int index) {
4042
setState(() {
4143
_selectedIndex = index;
@@ -49,22 +51,20 @@ class NavBarState extends State<NavBar> {
4951
alignment: Alignment.center,
5052
width: MediaQuery.of(context).size.width,
5153
height: 60,
52-
margin: const EdgeInsets.only(bottom: 30),
53-
padding: const EdgeInsets.symmetric(horizontal: 30),
54+
margin: const EdgeInsets.only(bottom: 35),
55+
padding: const EdgeInsets.symmetric(horizontal: 50),
5456
decoration: BoxDecoration(color: Theme.of(context).colorScheme.surface),
5557
child: Row(
58+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
5659
children: List.generate(_inactiveIcons.length, (index) {
5760
bool isActive = _selectedIndex == index;
5861
return GestureDetector(
5962
onTap: () => _onItemTapped(index),
60-
child: SizedBox(
61-
width: (MediaQuery.of(context).size.width - 60) / 5,
62-
child: AnimatedContainer(
63-
duration: const Duration(milliseconds: 200),
64-
curve: Curves.easeInOut,
65-
padding: const EdgeInsets.all(8),
66-
child: isActive ? _activeIcons[index] : _inactiveIcons[index],
67-
),
63+
child: AnimatedContainer(
64+
duration: const Duration(milliseconds: 200),
65+
curve: Curves.easeInOut,
66+
padding: const EdgeInsets.all(3),
67+
child: isActive ? _activeIcons[index] : _inactiveIcons[index],
6868
),
6969
);
7070
}),

lib/pages/main/main_page.dart

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,15 @@ class MainPageState extends State<MainPage> {
6565
elevation: 0,
6666
),
6767
body: SafeArea(
68-
child: Column(
69-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
70-
children: [
71-
const StatBar(),
72-
const MainBtn(),
73-
LocationWidget(selectedServer: _selectedServer),
74-
],
68+
child: SingleChildScrollView(
69+
child: Column(
70+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
71+
children: [
72+
const StatBar(),
73+
const MainBtn(),
74+
LocationWidget(selectedServer: _selectedServer),
75+
],
76+
),
7577
),
7678
),
7779
);

lib/pages/servers/servers_list_item.dart

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,16 @@ class ServerListItem extends StatelessWidget {
4141
borderRadius: BorderRadius.circular(10),
4242
boxShadow: [
4343
BoxShadow(
44-
color: Colors.grey.withValues(alpha: 0.2),
44+
color: Colors.grey.withAlpha(51),
4545
blurRadius: 10,
4646
offset: const Offset(0, 1),
4747
),
4848
],
4949
),
5050
child: Padding(
51-
padding: const EdgeInsets.all(0),
51+
padding: const EdgeInsets.symmetric(
52+
horizontal: 12,
53+
), // add some padding
5254
child: Row(
5355
mainAxisAlignment: MainAxisAlignment.spaceBetween,
5456
children: [
@@ -57,29 +59,34 @@ class ServerListItem extends StatelessWidget {
5759
if (icon != null)
5860
SvgPicture.asset(icon!, width: 52, height: 52),
5961
if (icon == null) const SizedBox(width: 16),
62+
const SizedBox(width: 8), // spacing between icon and text
6063
Container(
6164
alignment: Alignment.center,
6265
height: 52,
63-
child: Text(
64-
text,
65-
style: const TextStyle(fontSize: 16, color: Colors.black),
66+
child: Flexible(
67+
// Let text flexibly use remaining space
68+
child: Text(
69+
text,
70+
overflow: TextOverflow.ellipsis,
71+
style: const TextStyle(
72+
fontSize: 14,
73+
color: Colors.black,
74+
),
75+
),
6676
),
6777
),
6878
],
6979
),
70-
Container(
71-
alignment: Alignment.center,
72-
height: 52,
73-
child: Row(
74-
children: [
75-
Text(
76-
int.tryParse(ping) != null ? '$ping ms' : ping,
77-
style: const TextStyle(fontSize: 14, color: Colors.grey),
78-
),
79-
if (ping.isNotEmpty)
80-
Image.asset(pingImage, width: 52, height: 52),
81-
],
82-
),
80+
Row(
81+
children: [
82+
Text(
83+
int.tryParse(ping) != null ? '$ping ms' : ping,
84+
overflow: TextOverflow.ellipsis,
85+
style: const TextStyle(fontSize: 14, color: Colors.grey),
86+
),
87+
if (ping.isNotEmpty)
88+
Image.asset(pingImage, width: 52, height: 52),
89+
],
8390
),
8491
],
8592
),

lib/pages/settings/setting_page.dart

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import 'package:flutter/material.dart';
2+
import 'package:shared_preferences/shared_preferences.dart'; // Add this import
23
import 'package:vpn_client/localization_service.dart';
34
import 'setting_info_card.dart';
45
import 'support_service_card.dart';
6+
import 'package:vpn_client/utility/clean_scroll.dart';
57
import 'action_button.dart';
68
import 'reset_settings_dialog.dart';
79
import 'snackbar_utils.dart';
@@ -22,6 +24,32 @@ class _SettingPageState extends State<SettingPage> {
2224
String _supportStatus = '1 me/vnp_client_support';
2325
String _userId = '2485926342';
2426

27+
@override
28+
void initState() {
29+
super.initState();
30+
_loadSettings(); // Load saved state on page start
31+
}
32+
33+
Future<void> _loadSettings() async {
34+
final prefs = await SharedPreferences.getInstance();
35+
setState(() {
36+
_isConnected = prefs.getBool('isConnected') ?? true;
37+
_connectionStatus =
38+
prefs.getString('connectionStatus') ?? '1 me/vnp_client_bot';
39+
_supportStatus =
40+
prefs.getString('supportStatus') ?? '1 me/vnp_client_support';
41+
_userId = prefs.getString('userId') ?? '2485926342';
42+
});
43+
}
44+
45+
Future<void> _saveSettings() async {
46+
final prefs = await SharedPreferences.getInstance();
47+
await prefs.setBool('isConnected', _isConnected);
48+
await prefs.setString('connectionStatus', _connectionStatus);
49+
await prefs.setString('supportStatus', _supportStatus);
50+
await prefs.setString('userId', _userId);
51+
}
52+
2553
@override
2654
Widget build(BuildContext context) {
2755
return Scaffold(
@@ -40,38 +68,37 @@ class _SettingPageState extends State<SettingPage> {
4068
centerTitle: true,
4169
leading: const SizedBox(),
4270
),
43-
body: Padding(
44-
padding: const EdgeInsets.symmetric(horizontal: 16.0),
45-
child: Column(
46-
crossAxisAlignment: CrossAxisAlignment.start,
47-
children: [
48-
const SizedBox(height: 20),
49-
50-
SettingInfoCard(
51-
isConnected: _isConnected,
52-
connectionStatus: _connectionStatus,
53-
supportStatus: _supportStatus,
54-
userId: _userId,
55-
),
56-
57-
const SizedBox(height: 20),
58-
59-
SupportServiceCard(
60-
onTap: () {
61-
// Handle support service tap
62-
},
63-
),
64-
65-
const SizedBox(height: 30),
66-
67-
Center(
68-
child: ActionButton(
71+
body: ScrollConfiguration(
72+
behavior: NoGlowScrollBehavior(),
73+
child: SingleChildScrollView(
74+
physics: const ClampingScrollPhysics(),
75+
padding: const EdgeInsets.symmetric(horizontal: 16.0),
76+
child: Column(
77+
crossAxisAlignment: CrossAxisAlignment.start,
78+
children: [
79+
const SizedBox(height: 20),
80+
SettingInfoCard(
6981
isConnected: _isConnected,
70-
onResetPressed: _showResetDialog,
71-
onConnectPressed: _connectToBot,
82+
connectionStatus: _connectionStatus,
83+
supportStatus: _supportStatus,
84+
userId: _userId,
85+
),
86+
const SizedBox(height: 20),
87+
SupportServiceCard(
88+
onTap: () {
89+
_connectToBot();
90+
},
91+
),
92+
const SizedBox(height: 30),
93+
Center(
94+
child: ActionButton(
95+
isConnected: _isConnected,
96+
onResetPressed: _showResetDialog,
97+
onConnectPressed: _connectToBot,
98+
),
7299
),
73-
),
74-
],
100+
],
101+
),
75102
),
76103
),
77104
);
@@ -89,14 +116,17 @@ class _SettingPageState extends State<SettingPage> {
89116
}
90117
}
91118

92-
void _resetSettings() {
119+
void _resetSettings() async {
93120
setState(() {
94121
_isConnected = false;
95122
_connectionStatus = '';
96123
_supportStatus = '';
97124
_userId = '';
98125
});
99126

127+
await _saveSettings(); // Save updated state persistently
128+
129+
if (!mounted) return;
100130
SnackbarUtils.showResetSuccessSnackbar(context);
101131
}
102132

lib/pages/settings/url_launcher_utils.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import 'package:url_launcher/url_launcher.dart';
22

33
class UrlLauncherUtils {
44
static Future<bool> launchTelegramBot() async {
5-
const botUrl = 'https://t.me/vnp_client_bot';
5+
const botUrl = 'tg://resolve?domain=VPNclient_support';
66

77
if (await canLaunchUrl(Uri.parse(botUrl))) {
88
await launchUrl(Uri.parse(botUrl), mode: LaunchMode.externalApplication);

lib/search_dialog.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class _SearchDialogState extends State<SearchDialog> {
158158
LocalizationService.to('done'),
159159
textAlign: TextAlign.center,
160160
style: TextStyle(
161-
color: Colors.blue,
161+
color: Colors.orange,
162162
fontSize: 16,
163163
),
164164
),
@@ -177,7 +177,7 @@ class _SearchDialogState extends State<SearchDialog> {
177177
LocalizationService.to('cancel'),
178178
textAlign: TextAlign.center,
179179
style: TextStyle(
180-
color: Colors.blue,
180+
color: Colors.orange,
181181
fontSize: 16,
182182
),
183183
),

0 commit comments

Comments
 (0)