Commit code. Update time: 2023-06-25
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:sail/adapters/leaf_ffi/config.dart';
|
||||
import 'package:sail/channels/Platform.dart';
|
||||
import 'package:sail/channels/vpn_manager.dart';
|
||||
import 'package:sail/constant/app_colors.dart';
|
||||
import 'package:sail/constant/app_strings.dart';
|
||||
import 'package:sail/models/base_model.dart';
|
||||
import 'package:sail/models/server_model.dart';
|
||||
import 'package:sail/models/user_model.dart';
|
||||
import 'package:sail/utils/common_util.dart';
|
||||
|
||||
class AppModel extends BaseModel {
|
||||
VpnManager vpnManager = VpnManager();
|
||||
VpnStatus vpnStatus = VpnStatus.disconnected;
|
||||
bool isOn = false;
|
||||
bool isconnectordisconnct = false;
|
||||
DateTime? connectedDate;
|
||||
PageController pageController = PageController(initialPage: 0);
|
||||
String appTitle = AppStrings.appName;
|
||||
Config config = Config();
|
||||
ThemeData themeData = ThemeData(
|
||||
primarySwatch: AppColors.themeColor,
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
);
|
||||
|
||||
AppModel() {
|
||||
General general = General(
|
||||
loglevel: 'info',
|
||||
logoutput: '{{leafLogFile}}',
|
||||
dnsServer: ['223.5.5.5', '114.114.114.114'],
|
||||
tunFd: '{{tunFd}}',
|
||||
routingDomainResolve: true);
|
||||
|
||||
List<Rule> rules = [];
|
||||
// rules.add(Rule(typeField: 'EXTERNAL', target: 'Direct', filter: 'site:cn'));
|
||||
rules.add(Rule(typeField: 'FINAL', target: 'Direct'));
|
||||
|
||||
config.general = general;
|
||||
config.rules = rules;
|
||||
}
|
||||
|
||||
final Map _tabMap = {
|
||||
0: '主页',
|
||||
1: '套餐',
|
||||
2: '节点',
|
||||
3: '我的',
|
||||
};
|
||||
|
||||
void jumpToPage(int page) {
|
||||
// pageController.jumpToPage(page);
|
||||
appTitle = _tabMap[page];
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void getStatus() async {
|
||||
vpnStatus = await vpnManager.getStatus();
|
||||
|
||||
if (vpnStatus == VpnStatus.connected) {
|
||||
isOn = true;
|
||||
|
||||
getConnectedDate();
|
||||
notifyListeners();
|
||||
} else if (vpnStatus == VpnStatus.disconnected) {
|
||||
isOn = false;
|
||||
notifyListeners();
|
||||
} else {
|
||||
isconnectordisconnct = true;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void getConnectedDate() async {
|
||||
if (Platform.isAndroid || Platform.isMacOS) {
|
||||
} else {
|
||||
var date = await vpnManager.getConnectedDate();
|
||||
//print("date: $date");
|
||||
connectedDate = date;
|
||||
}
|
||||
}
|
||||
|
||||
void togglePowerButton() async {
|
||||
if (vpnStatus == VpnStatus.connecting) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Connecting, please wait...",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIosWeb: 2,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vpnStatus == VpnStatus.disconnecting) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Disconnecting, please wait...",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIosWeb: 2,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vpnStatus == VpnStatus.connected) {
|
||||
vpnStatus = VpnStatus.disconnecting;
|
||||
}
|
||||
|
||||
if (vpnStatus == VpnStatus.disconnected) {
|
||||
vpnStatus = VpnStatus.connecting;
|
||||
}
|
||||
|
||||
await vpnManager.toggle();
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void getTunnelLog() async {
|
||||
if (Platform.isIOS) {
|
||||
var log = await vpnManager.getTunnelLog();
|
||||
print("log: $log");
|
||||
}
|
||||
}
|
||||
|
||||
void getTunnelConfiguration() async {
|
||||
if (Platform.isIOS) {
|
||||
var conf = await vpnManager.getTunnelConfiguration();
|
||||
print("config: $conf");
|
||||
}
|
||||
}
|
||||
|
||||
void setConfigProxies(UserModel userModel, ServerModel serverModel) async {
|
||||
List<Proxy> proxies = [];
|
||||
List<ProxyGroup> proxyGroups = [];
|
||||
List<String> actors = [];
|
||||
|
||||
for (var server in serverModel.serverEntityList) {
|
||||
Proxy proxy = Proxy(
|
||||
tag: server.name,
|
||||
protocol: server.type,
|
||||
address: server.host,
|
||||
port: server.port,
|
||||
encryptMethod: server.cipher,
|
||||
password: userModel.userEntity!.uuid);
|
||||
proxies.add(proxy);
|
||||
actors.add(server.name);
|
||||
}
|
||||
|
||||
if (actors.isNotEmpty) {
|
||||
proxyGroups.add(ProxyGroup(
|
||||
tag: "UrlTest",
|
||||
protocol: 'url-test',
|
||||
actors: actors,
|
||||
checkInterval: 600));
|
||||
|
||||
config.rules?.last.target = "UrlTest";
|
||||
}
|
||||
|
||||
config.proxies = proxies;
|
||||
config.proxyGroups = proxyGroups;
|
||||
|
||||
//print("-----------------config-----------------");
|
||||
//print(config);
|
||||
//print("-----------------config-----------------");
|
||||
|
||||
vpnManager.setTunnelConfiguration(config.toString());
|
||||
}
|
||||
|
||||
void setConfigRule(String tag) async {
|
||||
// var proxy = config.proxies?.where((proxies) => proxies.tag == tag);
|
||||
//
|
||||
// if (proxy == null || proxy.isEmpty) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// config.rules?.last.target = tag;
|
||||
//
|
||||
// //print("-----------------config-----------------");
|
||||
// print(config);
|
||||
// //print("-----------------config-----------------");
|
||||
//
|
||||
// vpnManager.setTunnelConfiguration(config.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sail/models/page_state.dart';
|
||||
import 'package:sail/utils/common_util.dart';
|
||||
|
||||
class BaseModel extends ChangeNotifier {
|
||||
PageState pageState = PageState.loading;
|
||||
bool _isDispose = false;
|
||||
late String errorMessage;
|
||||
|
||||
bool get isDispose => _isDispose;
|
||||
|
||||
@override
|
||||
void notifyListeners() {
|
||||
//print("view model notifyListeners");
|
||||
if (!_isDispose) {
|
||||
super.notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void errorNotify(String error) {
|
||||
pageState = PageState.error;
|
||||
errorMessage = error;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_isDispose = true;
|
||||
//print("view model dispose");
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'package:sail/models/base_model.dart';
|
||||
import 'package:sail/models/user_model.dart';
|
||||
import 'package:sail/service/user_service.dart';
|
||||
|
||||
class LoginModel extends BaseModel {
|
||||
final UserService _userService = UserService();
|
||||
final UserModel _userModel;
|
||||
|
||||
LoginModel(this._userModel);
|
||||
|
||||
// 登陆方法
|
||||
login(String? account, String? passWord) async {
|
||||
var parameters = {'email': account, 'password': passWord};
|
||||
|
||||
return _userService.login(parameters)?.then((loginEntity) async {
|
||||
_userModel.setToken(loginEntity);
|
||||
|
||||
return _userService.info();
|
||||
}).then((userEntity) {
|
||||
_userModel.setUserInfo(userEntity);
|
||||
notifyListeners();
|
||||
|
||||
return userEntity;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
enum PageState {
|
||||
loading, //加载中
|
||||
hasData, //有数据
|
||||
empty, //无数据
|
||||
error, //加载失败
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:sail/entity/plan_entity.dart';
|
||||
import 'package:sail/models/base_model.dart';
|
||||
import 'package:sail/service/plan_service.dart';
|
||||
|
||||
class PlanModel extends BaseModel {
|
||||
final PlanService _planService = PlanService();
|
||||
|
||||
List<PlanEntity> _planEntityList = [];
|
||||
|
||||
List<PlanEntity> get planEntityList => _planEntityList;
|
||||
|
||||
// 获取套餐列表
|
||||
void fetchPlanList() async {
|
||||
try {
|
||||
// bool xxx = await platform.invokeMethod("getStatus");
|
||||
// result = xxx ? 1 : 0;
|
||||
_planEntityList = (await _planService.plan())!;
|
||||
|
||||
notifyListeners();
|
||||
} on Exception catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_icmp_ping/flutter_icmp_ping.dart';
|
||||
import 'package:sail/constant/app_strings.dart';
|
||||
import 'package:sail/entity/server_entity.dart';
|
||||
import 'package:sail/models/base_model.dart';
|
||||
import 'package:sail/service/server_service.dart';
|
||||
import 'package:sail/utils/shared_preferences_util.dart';
|
||||
import 'package:sail/utils/common_util.dart';
|
||||
|
||||
enum PingType { ping, tcp }
|
||||
|
||||
class ServerModel extends BaseModel {
|
||||
List<ServerEntity> _serverEntityList = [];
|
||||
ServerEntity? _selectServerEntity;
|
||||
int _selectServerIndex = 0;
|
||||
|
||||
final ServerService _serverService = ServerService();
|
||||
|
||||
List<ServerEntity> get serverEntityList => _serverEntityList;
|
||||
|
||||
ServerEntity? get selectServerEntity => _selectServerEntity;
|
||||
|
||||
int get selectServerIndex => _selectServerIndex;
|
||||
|
||||
getServerList({bool forceRefresh = false}) async {
|
||||
bool result = false;
|
||||
|
||||
List<dynamic> data = await SharedPreferencesUtil.getInstance()
|
||||
?.getList(AppStrings.serverNode) ??
|
||||
[];
|
||||
List<dynamic> newData =
|
||||
List.from(data.map((e) => Map<String, dynamic>.from(jsonDecode(e))));
|
||||
|
||||
if (newData.isEmpty || forceRefresh) {
|
||||
setServerEntityList(await _serverService.server());
|
||||
} else {
|
||||
_serverEntityList = serverEntityFromList(newData);
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
|
||||
result = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void pingAll() async {
|
||||
for (int i = 0; i < _serverEntityList.length; i++) {
|
||||
var duration = const Duration(milliseconds: 300);
|
||||
await Future.delayed(duration);
|
||||
ping(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ping(int index, {PingType type = PingType.tcp}) {
|
||||
ServerEntity serverEntity = _serverEntityList[index];
|
||||
String host = serverEntity.host;
|
||||
int serverPort = serverEntity.port;
|
||||
|
||||
//print("host=$host");
|
||||
//print("serverPort=$serverPort");
|
||||
|
||||
switch (type) {
|
||||
case PingType.ping:
|
||||
try {
|
||||
final ping =
|
||||
Ping(host, count: 1, timeout: 1.0, interval: 1.0, ipv6: false);
|
||||
ping.stream.listen((event) {
|
||||
print(event);
|
||||
if (event.error != null) {
|
||||
var duration = const Duration(minutes: 1);
|
||||
_serverEntityList[index].ping = duration;
|
||||
} else if (event.response != null) {
|
||||
_serverEntityList[index].ping = event.response?.time;
|
||||
}
|
||||
notifyListeners();
|
||||
|
||||
ping.stop();
|
||||
});
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
break;
|
||||
case PingType.tcp:
|
||||
Stopwatch stopwatch = Stopwatch()..start();
|
||||
|
||||
Socket.connect(host, serverPort, timeout: const Duration(seconds: 3))
|
||||
.then((socket) {
|
||||
socket.destroy();
|
||||
var duration = stopwatch.elapsed;
|
||||
_serverEntityList[index].ping = duration;
|
||||
|
||||
notifyListeners();
|
||||
|
||||
return duration;
|
||||
}).catchError((error) {
|
||||
var duration = const Duration(minutes: 1);
|
||||
_serverEntityList[index].ping = duration;
|
||||
|
||||
throw error;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw Error();
|
||||
}
|
||||
}
|
||||
|
||||
getSelectServer() async {
|
||||
Map<String, dynamic> data = await SharedPreferencesUtil.getInstance()
|
||||
?.getMap(AppStrings.selectServer) ??
|
||||
<String, dynamic>{};
|
||||
int index = int.parse(await SharedPreferencesUtil.getInstance()
|
||||
?.getString(AppStrings.selectServerIndex) ??
|
||||
'0');
|
||||
|
||||
if (data.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
_selectServerEntity = ServerEntity.fromMap(data);
|
||||
_selectServerIndex = index;
|
||||
|
||||
notifyListeners();
|
||||
|
||||
return _selectServerEntity;
|
||||
}
|
||||
|
||||
setServerEntityList(List<ServerEntity> serverEntityList) {
|
||||
_serverEntityList = serverEntityList;
|
||||
|
||||
_saveServerEntityList();
|
||||
}
|
||||
|
||||
setSelectServerEntity(ServerEntity selectServerEntity) {
|
||||
_selectServerEntity = selectServerEntity;
|
||||
|
||||
_saveSelectServerEntity();
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
setSelectServerIndex(int index) {
|
||||
_selectServerIndex = index;
|
||||
|
||||
_saveSelectServerIndex();
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
_saveServerEntityList() async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
await sharedPreferencesUtil?.setList(
|
||||
AppStrings.serverNode, _serverEntityList);
|
||||
}
|
||||
|
||||
_saveSelectServerEntity() async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
await sharedPreferencesUtil?.setMap(
|
||||
AppStrings.selectServer, _selectServerEntity!.toMap());
|
||||
}
|
||||
|
||||
_saveSelectServerIndex() async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
await sharedPreferencesUtil?.setString(
|
||||
AppStrings.selectServerIndex, _selectServerIndex.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import 'package:sail/constant/app_strings.dart';
|
||||
import 'package:sail/entity/login_entity.dart';
|
||||
import 'package:sail/entity/user_entity.dart';
|
||||
import 'package:sail/models/base_model.dart';
|
||||
import 'package:sail/utils/navigator_util.dart';
|
||||
import 'package:sail/utils/shared_preferences_util.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class UserModel extends BaseModel {
|
||||
String? _token;
|
||||
String? _authData;
|
||||
UserEntity? _userEntity;
|
||||
bool _isLogin = false;
|
||||
|
||||
String? get token => _token;
|
||||
String? get authData => _authData;
|
||||
UserEntity? get userEntity => _userEntity;
|
||||
bool get isLogin => _isLogin;
|
||||
String? _isonceLogin;
|
||||
|
||||
Future<void> checkHasLogin(context, Function callback) async {
|
||||
if (!isLogin) {
|
||||
NavigatorUtil.goLogin(context);
|
||||
} else {
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
|
||||
refreshData() async {
|
||||
String token = await SharedPreferencesUtil.getInstance()
|
||||
?.getString(AppStrings.token) ??
|
||||
'';
|
||||
String authData = await SharedPreferencesUtil.getInstance()
|
||||
?.getString(AppStrings.authData) ??
|
||||
'';
|
||||
|
||||
if (token != null &&
|
||||
token.isNotEmpty &&
|
||||
authData != null &&
|
||||
authData.isNotEmpty) {
|
||||
_isLogin = true;
|
||||
_token = token;
|
||||
_authData = authData;
|
||||
|
||||
Map<String, dynamic> userEntityMap =
|
||||
await SharedPreferencesUtil.getInstance()
|
||||
?.getMap(AppStrings.userInfo) ??
|
||||
<String, dynamic>{};
|
||||
_userEntity = UserEntity.fromMap(userEntityMap);
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
logout() {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
sharedPreferencesUtil?.clear();
|
||||
|
||||
refreshData();
|
||||
}
|
||||
|
||||
_saveOnceUserUse() async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
_isonceLogin = "1";
|
||||
await sharedPreferencesUtil?.setString("diyicidakaiapp", "1");
|
||||
}
|
||||
|
||||
getOnceUse() async {
|
||||
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
|
||||
return sharedPreferences.getString("diyicidakaiapp");
|
||||
// String? value = await sharedPreferencesUtil?.getString("diyicidakaiapp");
|
||||
|
||||
// if (value != null && value != "") {
|
||||
// return value;
|
||||
// } else {
|
||||
// return "0";
|
||||
// }
|
||||
}
|
||||
|
||||
_saveUserToken(LoginEntity loginEntity) async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
await sharedPreferencesUtil?.setString(AppStrings.token, loginEntity.token);
|
||||
}
|
||||
|
||||
_setUserAuthData(LoginEntity loginEntity) async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
await sharedPreferencesUtil?.setString(
|
||||
AppStrings.authData, loginEntity.authData);
|
||||
}
|
||||
|
||||
_saveUserInfo() async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
await sharedPreferencesUtil?.setMap(
|
||||
AppStrings.userInfo, _userEntity?.toMap());
|
||||
}
|
||||
|
||||
setToken(LoginEntity loginEntity) {
|
||||
_token = loginEntity.token;
|
||||
_authData = loginEntity.authData;
|
||||
_isLogin = true;
|
||||
|
||||
_saveUserToken(loginEntity);
|
||||
_setUserAuthData(loginEntity);
|
||||
}
|
||||
|
||||
setUserInfo(UserEntity? userEntity) {
|
||||
_userEntity = userEntity;
|
||||
|
||||
_saveUserInfo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import 'package:sail/constant/app_strings.dart';
|
||||
import 'package:sail/entity/user_subscribe_entity.dart';
|
||||
import 'package:sail/models/base_model.dart';
|
||||
import 'package:sail/service/user_service.dart';
|
||||
import 'package:sail/utils/shared_preferences_util.dart';
|
||||
|
||||
class UserSubscribeModel extends BaseModel {
|
||||
UserSubscribeEntity? _userSubscribeEntity;
|
||||
|
||||
final UserService _userService = UserService();
|
||||
|
||||
UserSubscribeEntity? get userSubscribeEntity => _userSubscribeEntity;
|
||||
|
||||
Future<bool> getUserSubscribe({bool forceRefresh = false}) async {
|
||||
bool result = false;
|
||||
|
||||
// Map<String, dynamic>? data = await SharedPreferencesUtil.getInstance() ?.getMap(AppStrings.userSubscribe);
|
||||
Map<String, dynamic>? data;
|
||||
if (data == null || data.isEmpty || forceRefresh) {
|
||||
setUserSubscribeEntity(await _userService.userSubscribe());
|
||||
} else {
|
||||
_userSubscribeEntity = UserSubscribeEntity.fromMap(data);
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
|
||||
result = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
setUserSubscribeEntity(UserSubscribeEntity? userSubscribeEntity) {
|
||||
_userSubscribeEntity = userSubscribeEntity;
|
||||
|
||||
_saveUserSubscribe();
|
||||
}
|
||||
|
||||
_saveUserSubscribe() async {
|
||||
SharedPreferencesUtil? sharedPreferencesUtil =
|
||||
SharedPreferencesUtil.getInstance();
|
||||
|
||||
await sharedPreferencesUtil?.setMap(
|
||||
AppStrings.userSubscribe, _userSubscribeEntity?.toMap());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user