feat: check API port is in use (#524)

This commit is contained in:
Levi authored and GitHub committed 2024-05-07 19:19:57 +08:00
1 parent 53b3eea4fc
commit d2c70b077b
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;
});
}
}
}
+1
View File
@@ -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',
+1
View File
@@ -56,6 +56,7 @@ const zhCN = {
'apiToken': '接口令牌',
'notSet': '未设置',
'set': '已设置',
'portInUse': '端口[@port]已被占用,请更换端口',
'effectAfterRestart': '此配置项将在重启应用后生效',
'startAll': '全部开始',
'pauseAll': '全部暂停',
+1
View File
@@ -56,6 +56,7 @@ const zhTW = {
'apiToken': 'API令牌',
'notSet': '未設定',
'set': '已設定',
'portInUse': '端口[@port]已被占用,請更換端口',
'effectAfterRestart': '重啟後生效',
'startAll': '全部開始',
'pauseAll': '全部暫停',