mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-07 00:50:27 +00:00
feat: check API port is in use (#524)
This commit is contained in:
5 files changed
+56
-8
No files matched your search
@@ -274,7 +274,9 @@ class AppController extends GetxController with WindowListener, TrayListener {
|
||||
}
|
||||
|
||||
Future<void> _toCreate(Uri uri) async {
|
||||
final path = (uri.scheme == "magnet" || uri.scheme == "http" || uri.scheme == "https")
|
||||
final path = (uri.scheme == "magnet" ||
|
||||
uri.scheme == "http" ||
|
||||
uri.scheme == "https")
|
||||
? uri.toString()
|
||||
: (await toFile(uri.toString())).path;
|
||||
await Get.rootDelegate.offAndToNamed(Routes.CREATE, arguments: path);
|
||||
@@ -305,15 +307,16 @@ class AppController extends GetxController with WindowListener, TrayListener {
|
||||
return _defaultStartConfig!;
|
||||
}
|
||||
|
||||
Future<void> loadStartConfig() async {
|
||||
Future<StartConfig> loadStartConfig() async {
|
||||
final defaultCfg = await _initDefaultStartConfig();
|
||||
final saveCfg = Database.instance.getStartConfig();
|
||||
startConfig.value.network = saveCfg?.network ?? defaultCfg.network;
|
||||
startConfig.value.address = saveCfg?.address ?? defaultCfg.address;
|
||||
startConfig.value.apiToken = saveCfg?.apiToken ?? defaultCfg.apiToken;
|
||||
return startConfig.value;
|
||||
}
|
||||
|
||||
Future<void> loadDownloaderConfig() async {
|
||||
Future<DownloaderConfig> loadDownloaderConfig() async {
|
||||
try {
|
||||
downloaderConfig.value = await getConfig();
|
||||
} catch (e) {
|
||||
@@ -321,6 +324,7 @@ class AppController extends GetxController with WindowListener, TrayListener {
|
||||
downloaderConfig.value = DownloaderConfig();
|
||||
}
|
||||
await _initDownloaderConfig();
|
||||
return downloaderConfig.value;
|
||||
}
|
||||
|
||||
Future<void> trackerUpdate() async {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:badges/badges.dart' as badges;
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -8,6 +9,7 @@ import 'package:intl/intl.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../../../api/model/downloader_config.dart';
|
||||
import '../../../../database/database.dart';
|
||||
import '../../../../i18n/message.dart';
|
||||
import '../../../../util/input_formatter.dart';
|
||||
import '../../../../util/locale_manager.dart';
|
||||
@@ -34,13 +36,22 @@ class SettingView extends GetView<SettingController> {
|
||||
final startCfg = appController.startConfig;
|
||||
|
||||
Timer? timer;
|
||||
debounceSave({bool needRestart = false}) {
|
||||
var completer = Completer<void>();
|
||||
Future<bool> debounceSave(
|
||||
{Future<String> Function()? check, bool needRestart = false}) {
|
||||
var completer = Completer<bool>();
|
||||
timer?.cancel();
|
||||
timer = Timer(const Duration(milliseconds: 1000), () {
|
||||
timer = Timer(const Duration(milliseconds: 1000), () async {
|
||||
if (check != null) {
|
||||
final checkResult = await check();
|
||||
if (checkResult.isNotEmpty) {
|
||||
showErrorMessage(checkResult);
|
||||
completer.complete(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
appController
|
||||
.saveConfig()
|
||||
.then(completer.complete)
|
||||
.then((_) => completer.complete(true))
|
||||
.onError(completer.completeError);
|
||||
if (needRestart) {
|
||||
showMessage('tip'.tr, 'effectAfterRestart'.tr);
|
||||
@@ -639,11 +650,41 @@ class SettingView extends GetView<SettingController> {
|
||||
final ipController = TextEditingController(text: ip);
|
||||
final portController = TextEditingController(text: port);
|
||||
updateAddress() async {
|
||||
if (ipController.text.isEmpty || portController.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final newAddress = '${ipController.text}:${portController.text}';
|
||||
if (newAddress != startCfg.value.address) {
|
||||
startCfg.value.address = newAddress;
|
||||
|
||||
await debounceSave(needRestart: true);
|
||||
final saved = await debounceSave(
|
||||
check: () async {
|
||||
// Check if address already in use
|
||||
final configIp = ipController.text;
|
||||
final configPort = int.parse(portController.text);
|
||||
if (configPort == 0) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
final socket = await Socket.connect(configIp, configPort,
|
||||
timeout: const Duration(seconds: 3));
|
||||
socket.close();
|
||||
return 'portInUse'
|
||||
.trParams({'port': configPort.toString()});
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
needRestart: true);
|
||||
|
||||
// If save failed, restore the old address
|
||||
if (!saved) {
|
||||
final oldAddress =
|
||||
(await appController.loadStartConfig()).address;
|
||||
startCfg.update((val) async {
|
||||
val!.address = oldAddress;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ const enUS = {
|
||||
'apiToken': 'API Token',
|
||||
'notSet': 'NS',
|
||||
'set': 'SET',
|
||||
'portInUse': 'Port [@port] is in use, please change the port',
|
||||
'effectAfterRestart': 'Effect after restart',
|
||||
'startAll': 'Start All',
|
||||
'pauseAll': 'Pause All',
|
||||
|
||||
@@ -56,6 +56,7 @@ const zhCN = {
|
||||
'apiToken': '接口令牌',
|
||||
'notSet': '未设置',
|
||||
'set': '已设置',
|
||||
'portInUse': '端口[@port]已被占用,请更换端口',
|
||||
'effectAfterRestart': '此配置项将在重启应用后生效',
|
||||
'startAll': '全部开始',
|
||||
'pauseAll': '全部暂停',
|
||||
|
||||
@@ -56,6 +56,7 @@ const zhTW = {
|
||||
'apiToken': 'API令牌',
|
||||
'notSet': '未設定',
|
||||
'set': '已設定',
|
||||
'portInUse': '端口[@port]已被占用,請更換端口',
|
||||
'effectAfterRestart': '重啟後生效',
|
||||
'startAll': '全部開始',
|
||||
'pauseAll': '全部暫停',
|
||||
|
||||
Reference in new issue
Block a user