feat: support proxy (#284)

This commit is contained in:
Levi authored and GitHub committed 2023-12-02 18:36:52 +08:00
1 parent ef97528114
commit 16b7a3d5b3
45 files changed
+1017 -1124

No files matched your search

-77
View File
@@ -1,77 +0,0 @@
{
"label": "English",
"error": "Error",
"tip": "Tip",
"confirm": "Confirm",
"cancel": "Cancel",
"selectAll": "Select All",
"task": "Tasks",
"downloading": "downloading",
"downloaded": "downloaded",
"setting": "Settings",
"donate": "Donate",
"exit": "Exit",
"create": "Create Task",
"directDownload": "Direct Download",
"advancedOptions": "Advanced Options",
"downloadLink": "Download Link",
"downloadLinkValid": "Please enter the download link",
"downloadLinkHit": "Please enter the download link, HTTP/HTTPS/MAGNET supported@append",
"downloadLinkHitDesktop": ", or drag the torrent file here directly",
"download": "Download",
"noFileSelected": "Please select at least one file to continue.",
"noStoragePermission": "Storage permission required",
"selectFile": "Select File",
"rename": "Rename",
"basic": "Basic",
"advanced": "Advanced",
"general": "General",
"downloadDir": "Download Directory",
"downloadDirValid": "Please select the download directory",
"connections": "Connections",
"maxRunning": "Max Running Tasks",
"items": "@count items",
"subscribeTracker": "Subscribe Tracker",
"subscribeFail": "Subscribe failed, please check network or try again later",
"update": "Update",
"updateDaily": "Update daily",
"lastUpdate": "Last update: @time",
"addTracker": "Add Tracker",
"addTrackerHit": "Please enter the tracker server url, one per line",
"ui": "UI",
"theme": "Theme",
"themeSystem": "System",
"themeLight": "Light",
"themeDark": "Dark",
"locale": "Language",
"about": "About",
"homepage": "Homepage",
"version": "Version",
"protocol": "Protocol",
"port": "Port",
"apiToken": "API Token",
"notSet": "NS",
"set": "SET",
"effectAfterRestart": "Effect after restart",
"startAll": "Start All",
"pauseAll": "Pause All",
"deleteTask": "Delete Task",
"deleteTaskTip": "Keep downloaded files",
"delete": "Delete",
"newVersionTitle": "Discover new version @version",
"newVersionUpdate": "Update Now",
"newVersionLater": "Later",
"extensions": "Extensions",
"extensionInstallUrl": "Install URL",
"extensionInstallSuccess": "Installed successfully",
"extensionUpdateSuccess": "Updated successfully",
"extensionDelete": "Delete Extension",
"extensionAlreadyLatest": "It's already the latest version",
"extensionFind": "Find Extensions",
"extensionDevelop": "Develop Extensions",
"history": "History",
"clearHistory": "Clear History",
"noHistoryFound": "No History Found",
"serviceTitle": "Download Service",
"serviceText": "Running"
}
-58
View File
@@ -1,58 +0,0 @@
{
"label": "فارسی",
"error": "اررور",
"tip": "Tip",
"confirm": "تایید",
"cancel": "انصراف",
"selectAll": "انتخاب همه",
"task": "کار",
"setting": "تنظیمات",
"donate": "کمک مالی",
"exit": "خروج",
"create": "ایجاد کار",
"downloading": "دانلود کردن",
"downloaded": "دانلود شدن",
"downloadLink": "لینک دانلود",
"downloadLinkValid": "لطفا لینک دانلود را وارد کنید",
"download": "دانلود",
"noFileSelected": "لطفا حداقل یک فایل را جهت دانلود انتخاب کنید.",
"noStoragePermission": "مجوز ذخیره سازی مورد نیاز است",
"selectFile": "انتخاب فایل",
"basic": "پایه",
"advanced": "پیشرفته",
"general": "عمومی",
"downloadDir": "دایرکتوری دانلود",
"downloadDirValid": "لطفا دایرکتوری دانلود را انتخاب کنید",
"connections": "اتصالات",
"items": "@count آیتم ها",
"subscribeTracker": "Subscribe Tracker",
"subscribeFail": "Subscribe failed, please check network or try again later",
"update": "بروزرسانی",
"updateDaily": "بروزرسانی روزانه",
"lastUpdate": "Last update: @time",
"addTracker": "Add Tracker",
"addTrackerHit": "Please enter the tracker server url, one per line",
"ui": "رابط کاربری",
"theme": "پوسته",
"themeSystem": "سیستم",
"themeLight": "روشن",
"themeDark": "تاریک",
"locale": "Language",
"about": "درباره ی",
"homepage": "صفحه اصلی",
"version": "نسخه",
"protocol": "پروتکل",
"port": "پورت",
"apiToken": "API توکن",
"notSet": "NS",
"set": "SET",
"effectAfterRestart": "Effect after restart",
"startAll": "شروع همه",
"pauseAll": "توقف همه",
"deleteTask": "پاک کردن کار",
"deleteTaskTip": "فایل های دانلود شده را نگه دارد",
"delete": "پاک کردن",
"newVersionTitle": "@version عنوان: کشف نسخه جدید",
"newVersionUpdate": "بروزرسانی",
"newVersionLater": "بعداً"
}
-61
View File
@@ -1,61 +0,0 @@
{
"label": "日本語",
"error": "エラー",
"tip": "ヒント",
"confirm": "確認",
"cancel": "キャンセル",
"selectAll": "すべてを選択",
"task": "タスク",
"downloading": "ダウンロード中",
"downloaded": "ダウンロード済",
"setting": "セッティング",
"donate": "寄付する",
"exit": "終了",
"create": "タスクを作成",
"downloadLink": "ダウンロードリンク",
"downloadLinkValid": "ダウンロードリンクを入力してください",
"downloadLinkHit": "ダウンロード リンクを入力してください、HTTP/HTTPS/MAGNET support@append",
"downloadLinkHitDesktop": "または、torrent ファイルを直接ここにドラッグします",
"download": "ダウンロード",
"noFileSelected": "続行するには少なくとも 1 つのファイルを選択してください。",
"noStoragePermission": "ストレージのパーミッションが必要",
"selectFile": "ファイルを選択",
"basic": "ベーシック",
"advanced": "アドバンスド",
"general": "ジェネラル",
"downloadDir": "ディレクトリのダウンロード",
"downloadDirValid": "ダウンロードディレクトリを選択してください",
"connections": "接続",
"maxRunning": "最大実行タスク",
"items": "@count アイテム",
"subscribeTracker": "トラッカーを購読",
"subscribeFail": "登録に失敗しました。ネットワークを確認するか、後でもう一度お試しください",
"update": "アップデート",
"updateDaily": "毎日アップデート",
"lastUpdate": "最終アップデート: @time",
"addTracker": "トラッカーを追加",
"addTrackerHit": "トラッカーサーバーの URL を 1 行に 1 つずつ入力してください",
"ui": "UI",
"theme": "テーマ",
"themeSystem": "システム",
"themeLight": "ライト",
"themeDark": "ダーク",
"locale": "言語",
"about": "概要",
"homepage": "ホームページ",
"version": "バージョン",
"protocol": "プロトコル",
"port": "ポート",
"apiToken": "API トークン",
"notSet": "未設置",
"set": "設置",
"effectAfterRestart": "再起動後の効果",
"startAll": "すべてを開始",
"pauseAll": "すべてを一時停止",
"deleteTask": "タスクを削除",
"deleteTaskTip": "ダウンロードしたファイルを保持",
"delete": "削除",
"newVersionTitle": "新しいバージョン @version を発見する",
"newVersionUpdate": "アップデート",
"newVersionLater": "後で"
}
-73
View File
@@ -1,73 +0,0 @@
{
"label": "Русский(Россия)",
"error": "Ошибка",
"tip": "Подсказка",
"confirm": "Подтвердить",
"cancel": "Отмена",
"selectAll": "Выбрать все",
"task": "Задачи",
"downloading": "Загрузка",
"downloaded": "Загружено",
"setting": "Настройки",
"donate": "Пожертвовать",
"exit": "Выход",
"create": "Создать задачу",
"advancedOptions": "Расширенные опции",
"downloadLink": "Ссылка на скачивание",
"downloadLinkValid": "Пожалуйста, введите ссылку для скачивания",
"downloadLinkHit": "Пожалуйста, введите ссылку для скачивания, HTTP/HTTPS/MAGNET поддерживаются@append",
"downloadLinkHitDesktop": ", или перетащите сюда торрент-файл",
"download": "Скачать",
"noFileSelected": "Файл не выбран",
"noStoragePermission": "Требуется доступ к хранилищу",
"selectFile": "Выбрать файл",
"rename": "Переименовать",
"basic": "Основные параметры",
"advanced": "Расширенные",
"general": "Общие",
"downloadDir": "Папка загрузки",
"downloadDirValid": "Пожалуйста, выберите папку для загрузки",
"connections": "Соединений",
"maxRunning": "Максимальное количество активных задач",
"items": "@подсчет элементов",
"subscribeTracker": "Подпись трекера",
"subscribeFail": "Подписка не удалась, пожалуйста, проверьте сеть или повторите попытку позже",
"update": "Обновить",
"updateDaily": "Обновлять ежедневно",
"lastUpdate": "Последнее обновление: @время",
"addTracker": "Добавить трекер",
"addTrackerHit": "Пожалуйста, введите url трекера, по одному в строке",
"ui": "UI",
"theme": "Тема",
"themeSystem": "Системная",
"themeLight": "Светлая",
"themeDark": "Темная",
"locale": "Язык",
"about": "О приложении",
"homepage": "Домашняя страница",
"version": "Версия",
"protocol": "Протокол",
"port": "Порт",
"apiToken": "API Токен",
"notSet": "Не установлено",
"set": "Установлено",
"effectAfterRestart": "Эффект после перезагрузки",
"startAll": "Запустить все",
"pauseAll": "Приостановить все",
"deleteTask": "Удалить задачу",
"deleteTaskTip": "Сохранить загруженные файлы",
"delete": "Удалить",
"newVersionTitle": "Обнаружена новая версия @version",
"newVersionUpdate": "Обновить",
"newVersionLater": "позже",
"extensions": "Расширения",
"extensionInstallSuccess": "Установка завершена",
"extensionUpdateSuccess": "Обновление завершено",
"extensionDelete": "Удалить расширение",
"extensionAlreadyLatest": "Это последняя версия",
"extensionFind": "Найти расширения",
"extensionDevelop": "Разработка расширений",
"history": "История",
"clearHistory": "Очистить историю",
"noHistoryFound": "История не найдена"
}
-77
View File
@@ -1,77 +0,0 @@
{
"label": "中文(简体)",
"error": "错误",
"tip": "提示",
"confirm": "确认",
"cancel": "取消",
"selectAll": "全选",
"task": "任务",
"downloading": "下载中",
"downloaded": "已完成",
"setting": "设置",
"donate": "打赏",
"exit": "退出",
"create": "创建任务",
"directDownload": "直接下载",
"advancedOptions": "高级选项",
"downloadLink": "下载链接",
"downloadLinkValid": "请输入下载链接",
"downloadLinkHit": "请输入下载链接,支持 HTTP/HTTPS/MAGNET@append",
"downloadLinkHitDesktop": ",也可以直接拖拽种子文件到此处",
"download": "下载",
"noFileSelected": "请至少选择一个文件下载",
"noStoragePermission": "需要开启存储权限",
"selectFile": "选择文件",
"rename": "重命名",
"basic": "基础",
"advanced": "高级",
"general": "通用",
"downloadDir": "下载目录",
"downloadDirValid": "请选择下载目录",
"connections": "连接数",
"maxRunning": "最大下载数",
"items": "@count 项",
"subscribeTracker": "订阅 Tracker",
"subscribeFail": "订阅失败,请检查网络或稍后重试",
"update": "更新",
"updateDaily": "每天自动更新",
"lastUpdate": "上次更新:@time",
"addTracker": "添加 Tracker",
"addTrackerHit": "请输入 tracker 服务器地址,每行一条",
"ui": "界面",
"theme": "主题",
"themeSystem": "跟随系统",
"themeLight": "明亮主题",
"themeDark": "暗黑主题",
"locale": "语言",
"about": "关于",
"homepage": "主页",
"version": "版本",
"protocol": "通讯协议",
"port": "端口",
"apiToken": "接口令牌",
"notSet": "未设置",
"set": "已设置",
"effectAfterRestart": "此配置项将在重启应用后生效",
"startAll": "全部开始",
"pauseAll": "全部暂停",
"deleteTask": "删除任务",
"deleteTaskTip": "保留已下载的文件",
"delete": "删除",
"newVersionTitle": "发现新版本 @version",
"newVersionUpdate": "立即更新",
"newVersionLater": "稍后再说",
"extensions": "扩展",
"extensionInstallUrl": "安装链接",
"extensionInstallSuccess": "安装成功",
"extensionUpdateSuccess": "更新成功",
"extensionDelete": "删除扩展",
"extensionAlreadyLatest": "已经是最新版本",
"extensionFind": "获取扩展",
"extensionDevelop": "开发扩展",
"history": "历史记录",
"clearHistory": "清空历史记录",
"noHistoryFound": "暂无历史记录",
"serviceTitle": "下载服务",
"serviceText": "运行中"
}
-77
View File
@@ -1,77 +0,0 @@
{
"label": "中文 (繁體) ",
"error": "錯誤",
"tip": "提示",
"confirm": "確定",
"cancel": "取消",
"selectAll": "全選",
"task": "任務",
"downloading": "下載中",
"downloaded": "已完成",
"setting": "設定",
"donate": "斗內",
"exit": "離開",
"create": "新增任務",
"directDownload": "直接下載",
"advancedOptions": "進階選項",
"downloadLink": "下載鏈接",
"downloadLinkValid": "請輸入下載鏈接",
"downloadLinkHit": "請輸入下載鏈接,支援 HTTP/HTTPS/MAGNET@append",
"downloadLinkHitDesktop": ",也可以通過拖拽Torrent文件至此以新增任務",
"download": "下載",
"noFileSelected": "沒有選取的文件",
"noStoragePermission": "沒有存儲權限",
"selectFile": "選擇文件",
"rename": "重命名",
"basic": "基礎",
"advanced": "進階",
"general": "通用設定",
"downloadDir": "下載目録",
"downloadDirValid": "請選擇下載目録",
"connections": "同時連接數",
"maxRunning": "最大同時下載數",
"items": "@count 項",
"subscribeTracker": "已訂閲的追蹤者列表",
"subscribeFail": "訂閲失敗",
"update": "更新",
"updateDaily": "每天自動更新",
"lastUpdate": "上次更新時間: @time",
"addTracker": "增加新的追蹤者",
"addTrackerHit": "請輸入追蹤者服務器地址,每行一條",
"ui": "介面",
"theme": "佈景主題",
"themeSystem": "跟隨系統",
"themeLight": "亮色主題",
"themeDark": "深色主題",
"locale": "語言",
"about": "關於",
"homepage": "訪問主頁",
"version": "版本資訊",
"protocol": "端口設定",
"port": "端口",
"apiToken": "接口秘鑰",
"notSet": "未設定",
"set": "已設定",
"effectAfterRestart": "重啟後生效",
"startAll": "全部開始",
"pauseAll": "全部暫停",
"deleteTask": "刪除任務",
"deleteTaskTip": "保留已經下載的文件",
"delete": "刪除",
"newVersionTitle": "發現新版本 @version",
"newVersionUpdate": "立刻更新",
"newVersionLater": "稍後更新",
"extensions": "外掛程序",
"extensionInstallUrl": "安裝URL",
"extensionInstallSuccess": "安裝成功",
"extensionUpdateSuccess": "更新完成",
"extensionDelete": "解除安裝",
"extensionAlreadyLatest": "已是最新版本",
"extensionFind": "取得外掛",
"extensionDevelop": "開發外掛",
"history": "歷史記錄",
"clearHistory": "清空記錄",
"noHistoryFound": "還沒有記錄",
"serviceTitle": "下載服務",
"serviceText": "執行中"
}
@@ -8,6 +8,7 @@ class DownloaderConfig {
int maxRunning = 0;
ProtocolConfig protocolConfig = ProtocolConfig();
ExtraConfig extra = ExtraConfig();
ProxyConfig proxy = ProxyConfig();
DownloaderConfig();
@@ -66,6 +67,22 @@ class ExtraConfig {
Map<String, dynamic> toJson() => _$ExtraConfigToJson(this);
}
@JsonSerializable()
class ProxyConfig {
bool enable = false;
String scheme = '';
String host = '';
String usr = '';
String pwd = '';
ProxyConfig();
factory ProxyConfig.fromJson(Map<String, dynamic> json) =>
_$ProxyConfigFromJson(json);
Map<String, dynamic> toJson() => _$ProxyConfigToJson(this);
}
@JsonSerializable()
class ExtraConfigBt {
List<String> trackerSubscribeUrls = [];
@@ -12,7 +12,8 @@ DownloaderConfig _$DownloaderConfigFromJson(Map<String, dynamic> json) =>
..maxRunning = json['maxRunning'] as int
..protocolConfig = ProtocolConfig.fromJson(
json['protocolConfig'] as Map<String, dynamic>?)
..extra = ExtraConfig.fromJson(json['extra'] as Map<String, dynamic>?);
..extra = ExtraConfig.fromJson(json['extra'] as Map<String, dynamic>?)
..proxy = ProxyConfig.fromJson(json['proxy'] as Map<String, dynamic>);
Map<String, dynamic> _$DownloaderConfigToJson(DownloaderConfig instance) =>
<String, dynamic>{
@@ -20,6 +21,7 @@ Map<String, dynamic> _$DownloaderConfigToJson(DownloaderConfig instance) =>
'maxRunning': instance.maxRunning,
'protocolConfig': instance.protocolConfig.toJson(),
'extra': instance.extra.toJson(),
'proxy': instance.proxy.toJson(),
};
ProtocolConfig _$ProtocolConfigFromJson(Map<String, dynamic> json) =>
@@ -65,6 +67,22 @@ Map<String, dynamic> _$ExtraConfigToJson(ExtraConfig instance) =>
'bt': instance.bt.toJson(),
};
ProxyConfig _$ProxyConfigFromJson(Map<String, dynamic> json) => ProxyConfig()
..enable = json['enable'] as bool
..scheme = json['scheme'] as String
..host = json['host'] as String
..usr = json['usr'] as String
..pwd = json['pwd'] as String;
Map<String, dynamic> _$ProxyConfigToJson(ProxyConfig instance) =>
<String, dynamic>{
'enable': instance.enable,
'scheme': instance.scheme,
'host': instance.host,
'usr': instance.usr,
'pwd': instance.pwd,
};
ExtraConfigBt _$ExtraConfigBtFromJson(Map<String, dynamic> json) =>
ExtraConfigBt()
..trackerSubscribeUrls = (json['trackerSubscribeUrls'] as List<dynamic>)
@@ -16,7 +16,7 @@ import 'package:window_manager/window_manager.dart';
import '../../../../api/api.dart';
import '../../../../api/model/downloader_config.dart';
import '../../../../core/common/start_config.dart';
import '../../../../generated/locales.g.dart';
import '../../../../i18n/message.dart';
import '../../../../util/locale_manager.dart';
import '../../../../util/log_util.dart';
import '../../../../util/package_info.dart';
@@ -185,9 +185,7 @@ class AppController extends GetxController with WindowListener, TrayListener {
MenuItem(
label: 'donate'.tr,
onClick: (menuItem) => {
launchUrl(
Uri.parse(
"https://github.com/GopeedLab/gopeed/blob/main/.donate/index.md#donate"),
launchUrl(Uri.parse("https://docs.gopeed.com/donate.html"),
mode: LaunchMode.externalApplication)
},
),
@@ -376,7 +374,7 @@ class AppController extends GetxController with WindowListener, TrayListener {
}
if (extra.locale.isEmpty) {
final systemLocale = getLocaleKey(PlatformDispatcher.instance.locale);
extra.locale = AppTranslation.translations.containsKey(systemLocale)
extra.locale = messages.keys.containsKey(systemLocale)
? systemLocale
: getLocaleKey(fallbackLocale);
}
@@ -384,6 +382,10 @@ class AppController extends GetxController with WindowListener, TrayListener {
// default select all tracker subscribe urls
extra.bt.trackerSubscribeUrls.addAll(allTrackerSubscribeUrls);
}
final proxy = config.proxy;
if (proxy.scheme.isEmpty) {
proxy.scheme = 'http';
}
if (config.downloadDir.isEmpty) {
if (Util.isDesktop()) {
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart';
import '../../../../generated/locales.g.dart';
import '../../../../i18n/message.dart';
import '../../../../theme/theme.dart';
import '../../../../util/locale_manager.dart';
import '../../../routes/app_pages.dart';
@@ -20,8 +20,7 @@ class AppView extends GetView<AppController> {
theme: GopeedTheme.light,
darkTheme: GopeedTheme.dark,
themeMode: ThemeMode.values.byName(config.extra.themeMode),
// translations: messages,
translationsKeys: AppTranslation.translations,
translations: messages,
locale: toLocale(config.extra.locale),
fallbackLocale: fallbackLocale,
localizationsDelegates: const [
@@ -29,8 +28,7 @@ class AppView extends GetView<AppController> {
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales:
AppTranslation.translations.keys.map((e) => toLocale(e)).toList(),
supportedLocales: messages.keys.keys.map((e) => toLocale(e)).toList(),
getPages: AppPages.routes,
);
}
@@ -208,20 +208,15 @@ class ExtensionView extends GetView<ExtensionController> {
? IconButton(
onPressed: () {
launchUrl(
Uri.parse(extension.homepage),
mode: LaunchMode
.externalApplication);
Uri.parse(extension.homepage));
},
icon: const Icon(Icons.home))
: null,
extension.repository?.url.isNotEmpty == true
? IconButton(
onPressed: () {
launchUrl(
Uri.parse(
extension.repository!.url),
mode: LaunchMode
.externalApplication);
launchUrl(Uri.parse(
extension.repository!.url));
},
icon: const Icon(Icons.code))
: null,
@@ -7,7 +7,7 @@ import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../../generated/locales.g.dart';
import '../../../../i18n/message.dart';
import '../../../../util/input_formatter.dart';
import '../../../../util/locale_manager.dart';
import '../../../../util/message.dart';
@@ -272,8 +272,7 @@ class SettingView extends GetView<SettingController> {
));
final buildLocale = _buildConfigItem(
'locale',
() => AppTranslation
.translations[downloaderCfg.value.extra.locale]!['label']!,
() => messages.keys[downloaderCfg.value.extra.locale]!['label']!,
(Key key) => DropdownButton<String>(
key: key,
value: downloaderCfg.value.extra.locale,
@@ -287,23 +286,26 @@ class SettingView extends GetView<SettingController> {
await debounceSave();
},
items: AppTranslation.translations.keys
items: messages.keys.keys
.map((e) => DropdownMenuItem<String>(
value: e,
child: Text(AppTranslation.translations[e]!['label']!),
child: Text(messages.keys[e]!['label']!),
))
.toList(),
));
// about config items start
buildHomepage() => ListTile(
title: Text('homepage'.tr),
subtitle: const Text('https://github.com/GopeedLab/gopeed'),
onTap: () {
launchUrl(Uri.parse('https://github.com/GopeedLab/gopeed'),
mode: LaunchMode.externalApplication);
},
);
buildHomepage() {
const homePage = 'https://gopeed.com';
return ListTile(
title: Text('homepage'.tr),
subtitle: const Text(homePage),
onTap: () {
launchUrl(Uri.parse(homePage), mode: LaunchMode.externalApplication);
},
);
}
buildVersion() {
bool isNewVersion(String current, String latest) {
if (latest == "") {
@@ -363,7 +365,167 @@ class SettingView extends GetView<SettingController> {
);
}
// advanced config items start
// advanced config proxy items start
final buildProxy = _buildConfigItem(
'proxy',
() => downloaderCfg.value.proxy.enable
? '${downloaderCfg.value.proxy.scheme}://${downloaderCfg.value.proxy.host}'
: 'notSet'.tr,
(Key key) {
final proxy = downloaderCfg.value.proxy;
final switcher = Switch(
value: proxy.enable,
onChanged: (bool value) async {
if (value != proxy.enable) {
downloaderCfg.update((val) {
val!.proxy.enable = value;
});
await debounceSave();
}
},
);
final items = <Widget>[
SizedBox(
width: 150,
child: DropdownButtonFormField<String>(
value: proxy.scheme,
onChanged: (value) async {
if (value != null && value != proxy.scheme) {
proxy.scheme = value;
await debounceSave();
}
},
items: const [
DropdownMenuItem<String>(
value: 'http',
child: Text('HTTP'),
),
DropdownMenuItem<String>(
value: 'https',
child: Text('HTTPS'),
),
DropdownMenuItem<String>(
value: 'socks5',
child: Text('SOCKS5'),
),
],
),
)
];
final arr = proxy.host.split(':');
var ip = '';
var port = '';
if (arr.length > 1) {
ip = arr[0];
port = arr[1];
}
final ipController = TextEditingController(text: ip);
final portController = TextEditingController(text: port);
updateAddress() async {
final newAddress = '${ipController.text}:${portController.text}';
if (newAddress != startCfg.value.address) {
proxy.host = newAddress;
await debounceSave();
}
}
ipController.addListener(updateAddress);
portController.addListener(updateAddress);
items.addAll([
const Padding(padding: EdgeInsets.only(left: 20)),
SizedBox(
width: 150,
child: TextFormField(
controller: ipController,
decoration: const InputDecoration(
labelText: 'IP',
contentPadding: EdgeInsets.all(0.0),
),
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[0-9.]')),
],
),
),
const Padding(padding: EdgeInsets.only(left: 10)),
SizedBox(
width: 150,
child: TextFormField(
controller: portController,
decoration: InputDecoration(
labelText: 'port'.tr,
contentPadding: const EdgeInsets.all(0.0),
),
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
NumericalRangeFormatter(min: 0, max: 65535),
],
),
),
]);
final usrController = TextEditingController(text: proxy.usr);
final pwdController = TextEditingController(text: proxy.pwd);
final auth = [
SizedBox(
width: 150,
child: TextFormField(
controller: usrController,
decoration: InputDecoration(
labelText: 'username'.tr,
contentPadding: const EdgeInsets.all(0.0),
),
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[0-9.]')),
],
),
),
const Padding(padding: EdgeInsets.only(left: 10)),
SizedBox(
width: 150,
child: TextFormField(
controller: pwdController,
decoration: InputDecoration(
labelText: 'password'.tr,
contentPadding: const EdgeInsets.all(0.0),
),
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
NumericalRangeFormatter(min: 0, max: 65535),
],
),
),
];
return Form(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _addPadding([
switcher,
Row(
children: items,
),
Row(
children: auth,
),
]),
),
);
},
);
// advanced config API items start
final buildApiProtocol = _buildConfigItem(
'protocol',
() => startCfg.value.network == 'tcp'
@@ -424,7 +586,7 @@ class SettingView extends GetView<SettingController> {
items.addAll([
const Padding(padding: EdgeInsets.only(left: 20)),
SizedBox(
width: 200,
width: 150,
child: TextFormField(
controller: ipController,
decoration: const InputDecoration(
@@ -439,7 +601,7 @@ class SettingView extends GetView<SettingController> {
),
const Padding(padding: EdgeInsets.only(left: 10)),
SizedBox(
width: 200,
width: 150,
child: TextFormField(
controller: portController,
decoration: InputDecoration(
@@ -553,21 +715,42 @@ class SettingView extends GetView<SettingController> {
]),
),
),
Column(
children: [
// Column(
// children: [
// Card(
// child: Column(
// children: [
// ..._addDivider([
// buildApiProtocol(),
// Util.isDesktop() && startCfg.value.network == 'tcp'
// ? buildApiToken()
// : null,
// ]),
// ],
// )),
// ],
// ),
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _addPadding([
Text('network'.tr),
Card(
child: Column(
children: [
..._addDivider([
buildApiProtocol(),
Util.isDesktop() && startCfg.value.network == 'tcp'
? buildApiToken()
: null,
]),
],
children: _addDivider([buildProxy()]),
)),
],
),
const Text('API'),
Card(
child: Column(
children: _addDivider([
buildApiProtocol(),
Util.isDesktop() && startCfg.value.network == 'tcp'
? buildApiToken()
: null,
]),
)),
]),
))
],
).paddingOnly(left: 16, right: 16, top: 16, bottom: 16)),
),
File diff suppressed because it is too large. Load diff
+84
View File
@@ -0,0 +1,84 @@
const enUS = {
'en_US': {
'label': 'English',
'error': 'Error',
'tip': 'Tip',
'confirm': 'Confirm',
'cancel': 'Cancel',
'selectAll': 'Select All',
'task': 'Tasks',
'downloading': 'downloading',
'downloaded': 'downloaded',
'setting': 'Settings',
'donate': 'Donate',
'exit': 'Exit',
'create': 'Create Task',
'directDownload': 'Direct Download',
'advancedOptions': 'Advanced Options',
'downloadLink': 'Download Link',
'downloadLinkValid': 'Please enter the download link',
'downloadLinkHit':
'Please enter the download link, HTTP/HTTPS/MAGNET supported@append',
'downloadLinkHitDesktop': ', or drag the torrent file here directly',
'download': 'Download',
'noFileSelected': 'Please select at least one file to continue.',
'noStoragePermission': 'Storage permission required',
'selectFile': 'Select File',
'rename': 'Rename',
'basic': 'Basic',
'advanced': 'Advanced',
'general': 'General',
'downloadDir': 'Download Directory',
'downloadDirValid': 'Please select the download directory',
'connections': 'Connections',
'maxRunning': 'Max Running Tasks',
'items': '@count items',
'subscribeTracker': 'Subscribe Tracker',
'subscribeFail':
'Subscribe failed, please check network or try again later',
'update': 'Update',
'updateDaily': 'Update daily',
'lastUpdate': 'Last update: @time',
'addTracker': 'Add Tracker',
'addTrackerHit': 'Please enter the tracker server url, one per line',
'ui': 'UI',
'theme': 'Theme',
'themeSystem': 'System',
'themeLight': 'Light',
'themeDark': 'Dark',
'locale': 'Language',
'about': 'About',
'homepage': 'Homepage',
'version': 'Version',
'protocol': 'Protocol',
'port': 'Port',
'apiToken': 'API Token',
'notSet': 'NS',
'set': 'SET',
'effectAfterRestart': 'Effect after restart',
'startAll': 'Start All',
'pauseAll': 'Pause All',
'deleteTask': 'Delete Task',
'deleteTaskTip': 'Keep downloaded files',
'delete': 'Delete',
'newVersionTitle': 'Discover new version @version',
'newVersionUpdate': 'Update Now',
'newVersionLater': 'Later',
'extensions': 'Extensions',
'extensionInstallUrl': 'Install URL',
'extensionInstallSuccess': 'Installed successfully',
'extensionUpdateSuccess': 'Updated successfully',
'extensionDelete': 'Delete Extension',
'extensionAlreadyLatest': 'It\'s already the latest version',
'extensionFind': 'Find Extensions',
'extensionDevelop': 'Develop Extensions',
'history': 'History',
'clearHistory': 'Clear History',
'noHistoryFound': 'No History Found',
'serviceTitle': 'Download Service',
'serviceText': 'Running',
'proxy': 'Proxy',
'username': 'Username',
'password': 'Password',
},
};
+61
View File
@@ -0,0 +1,61 @@
const faIR = {
"fa_IR": {
'label': 'فارسی',
'error': 'اررور',
'tip': 'Tip',
'confirm': 'تایید',
'cancel': 'انصراف',
'selectAll': 'انتخاب همه',
'task': 'کار',
'setting': 'تنظیمات',
'donate': 'کمک مالی',
'exit': 'خروج',
'create': 'ایجاد کار',
'downloading': 'دانلود کردن',
'downloaded': 'دانلود شدن',
'downloadLink': 'لینک دانلود',
'downloadLinkValid': 'لطفا لینک دانلود را وارد کنید',
'download': 'دانلود',
'noFileSelected': 'لطفا حداقل یک فایل را جهت دانلود انتخاب کنید.',
'noStoragePermission': 'مجوز ذخیره سازی مورد نیاز است',
'selectFile': 'انتخاب فایل',
'basic': 'پایه',
'advanced': 'پیشرفته',
'general': 'عمومی',
'downloadDir': 'دایرکتوری دانلود',
'downloadDirValid': 'لطفا دایرکتوری دانلود را انتخاب کنید',
'connections': 'اتصالات',
'items': '@count آیتم ها',
'subscribeTracker': 'Subscribe Tracker',
'subscribeFail':
'Subscribe failed, please check network or try again later',
'update': 'بروزرسانی',
'updateDaily': 'بروزرسانی روزانه',
'lastUpdate': 'Last update: @time',
'addTracker': 'Add Tracker',
'addTrackerHit': 'Please enter the tracker server url, one per line',
'ui': 'رابط کاربری',
'theme': 'پوسته',
'themeSystem': 'سیستم',
'themeLight': 'روشن',
'themeDark': 'تاریک',
'locale': 'Language',
'about': 'درباره ی',
'homepage': 'صفحه اصلی',
'version': 'نسخه',
'protocol': 'پروتکل',
'port': 'پورت',
'apiToken': 'API توکن',
'notSet': 'NS',
'set': 'SET',
'effectAfterRestart': 'Effect after restart',
'startAll': 'شروع همه',
'pauseAll': 'توقف همه',
'deleteTask': 'پاک کردن کار',
'deleteTaskTip': 'فایل های دانلود شده را نگه دارد',
'delete': 'پاک کردن',
'newVersionTitle': '@version عنوان: کشف نسخه جدید',
'newVersionUpdate': 'بروزرسانی',
'newVersionLater': 'بعداً',
}
};
+63
View File
@@ -0,0 +1,63 @@
const jaJP = {
"ja_JP": {
'label': '日本語',
'error': 'エラー',
'tip': 'ヒント',
'confirm': '確認',
'cancel': 'キャンセル',
'selectAll': 'すべてを選択',
'task': 'タスク',
'downloading': 'ダウンロード中',
'downloaded': 'ダウンロード済',
'setting': 'セッティング',
'donate': '寄付する',
'exit': '終了',
'create': 'タスクを作成',
'downloadLink': 'ダウンロードリンク',
'downloadLinkValid': 'ダウンロードリンクを入力してください',
'downloadLinkHit': 'ダウンロード リンクを入力してください、HTTP/HTTPS/MAGNET support@append',
'downloadLinkHitDesktop': 'または、torrent ファイルを直接ここにドラッグします',
'download': 'ダウンロード',
'noFileSelected': '続行するには少なくとも 1 つのファイルを選択してください。',
'noStoragePermission': 'ストレージのパーミッションが必要',
'selectFile': 'ファイルを選択',
'basic': 'ベーシック',
'advanced': 'アドバンスド',
'general': 'ジェネラル',
'downloadDir': 'ディレクトリのダウンロード',
'downloadDirValid': 'ダウンロードディレクトリを選択してください',
'connections': '接続',
'maxRunning': '最大実行タスク',
'items': '@count アイテム',
'subscribeTracker': 'トラッカーを購読',
'subscribeFail': '登録に失敗しました。ネットワークを確認するか、後でもう一度お試しください',
'update': 'アップデート',
'updateDaily': '毎日アップデート',
'lastUpdate': '最終アップデート: @time',
'addTracker': 'トラッカーを追加',
'addTrackerHit': 'トラッカーサーバーの URL を 1 行に 1 つずつ入力してください',
'ui': 'UI',
'theme': 'テーマ',
'themeSystem': 'システム',
'themeLight': 'ライト',
'themeDark': 'ダーク',
'locale': '言語',
'about': '概要',
'homepage': 'ホームページ',
'version': 'バージョン',
'protocol': 'プロトコル',
'port': 'ポート',
'apiToken': 'API トークン',
'notSet': '未設置',
'set': '設置',
'effectAfterRestart': '再起動後の効果',
'startAll': 'すべてを開始',
'pauseAll': 'すべてを一時停止',
'deleteTask': 'タスクを削除',
'deleteTaskTip': 'ダウンロードしたファイルを保持',
'delete': '削除',
'newVersionTitle': '新しいバージョン @version を発見する',
'newVersionUpdate': 'アップデート',
'newVersionLater': '後で',
}
};
+77
View File
@@ -0,0 +1,77 @@
const ruRU = {
'ru_RU': {
'label': 'Русский(Россия)',
'error': 'Ошибка',
'tip': 'Подсказка',
'confirm': 'Подтвердить',
'cancel': 'Отмена',
'selectAll': 'Выбрать все',
'task': 'Задачи',
'downloading': 'Загрузка',
'downloaded': 'Загружено',
'setting': 'Настройки',
'donate': 'Пожертвовать',
'exit': 'Выход',
'create': 'Создать задачу',
'advancedOptions': 'Расширенные опции',
'downloadLink': 'Ссылка на скачивание',
'downloadLinkValid': 'Пожалуйста, введите ссылку для скачивания',
'downloadLinkHit':
'Пожалуйста, введите ссылку для скачивания, HTTP/HTTPS/MAGNET поддерживаются@append',
'downloadLinkHitDesktop': ', или перетащите сюда торрент-файл',
'download': 'Скачать',
'noFileSelected': 'Файл не выбран',
'noStoragePermission': 'Требуется доступ к хранилищу',
'selectFile': 'Выбрать файл',
'rename': 'Переименовать',
'basic': 'Основные параметры',
'advanced': 'Расширенные',
'general': 'Общие',
'downloadDir': 'Папка загрузки',
'downloadDirValid': 'Пожалуйста, выберите папку для загрузки',
'connections': 'Соединений',
'maxRunning': 'Максимальное количество активных задач',
'items': '@подсчет элементов',
'subscribeTracker': 'Подпись трекера',
'subscribeFail':
'Подписка не удалась, пожалуйста, проверьте сеть или повторите попытку позже',
'update': 'Обновить',
'updateDaily': 'Обновлять ежедневно',
'lastUpdate': 'Последнее обновление: @время',
'addTracker': 'Добавить трекер',
'addTrackerHit': 'Пожалуйста, введите url трекера, по одному в строке',
'ui': 'UI',
'theme': 'Тема',
'themeSystem': 'Системная',
'themeLight': 'Светлая',
'themeDark': 'Темная',
'locale': 'Язык',
'about': 'О приложении',
'homepage': 'Домашняя страница',
'version': 'Версия',
'protocol': 'Протокол',
'port': 'Порт',
'apiToken': 'API Токен',
'notSet': 'Не установлено',
'set': 'Установлено',
'effectAfterRestart': 'Эффект после перезагрузки',
'startAll': 'Запустить все',
'pauseAll': 'Приостановить все',
'deleteTask': 'Удалить задачу',
'deleteTaskTip': 'Сохранить загруженные файлы',
'delete': 'Удалить',
'newVersionTitle': 'Обнаружена новая версия @version',
'newVersionUpdate': 'Обновить',
'newVersionLater': 'позже',
'extensions': 'Расширения',
'extensionInstallSuccess': 'Установка завершена',
'extensionUpdateSuccess': 'Обновление завершено',
'extensionDelete': 'Удалить расширение',
'extensionAlreadyLatest': 'Это последняя версия',
'extensionFind': 'Найти расширения',
'extensionDevelop': 'Разработка расширений',
'history': 'История',
'clearHistory': 'Очистить историю',
'noHistoryFound': 'История не найдена',
}
};
+82
View File
@@ -0,0 +1,82 @@
const zhCN = {
'zh_CN': {
'label': '中文(简体)',
'error': '错误',
'tip': '提示',
'confirm': '确认',
'cancel': '取消',
'selectAll': '全选',
'task': '任务',
'downloading': '下载中',
'downloaded': '已完成',
'setting': '设置',
'donate': '打赏',
'exit': '退出',
'create': '创建任务',
'directDownload': '直接下载',
'advancedOptions': '高级选项',
'downloadLink': '下载链接',
'downloadLinkValid': '请输入下载链接',
'downloadLinkHit': '请输入下载链接,支持 HTTP/HTTPS/MAGNET@append',
'downloadLinkHitDesktop': ',也可以直接拖拽种子文件到此处',
'download': '下载',
'noFileSelected': '请至少选择一个文件下载',
'noStoragePermission': '需要开启存储权限',
'selectFile': '选择文件',
'rename': '重命名',
'basic': '基础',
'advanced': '高级',
'general': '通用',
'downloadDir': '下载目录',
'downloadDirValid': '请选择下载目录',
'connections': '连接数',
'maxRunning': '最大下载数',
'items': '@count 项',
'subscribeTracker': '订阅 Tracker',
'subscribeFail': '订阅失败,请检查网络或稍后重试',
'update': '更新',
'updateDaily': '每天自动更新',
'lastUpdate': '上次更新:@time',
'addTracker': '添加 Tracker',
'addTrackerHit': '请输入 tracker 服务器地址,每行一条',
'ui': '界面',
'theme': '主题',
'themeSystem': '跟随系统',
'themeLight': '明亮主题',
'themeDark': '暗黑主题',
'locale': '语言',
'about': '关于',
'homepage': '主页',
'version': '版本',
'protocol': '通讯协议',
'port': '端口',
'apiToken': '接口令牌',
'notSet': '未设置',
'set': '已设置',
'effectAfterRestart': '此配置项将在重启应用后生效',
'startAll': '全部开始',
'pauseAll': '全部暂停',
'deleteTask': '删除任务',
'deleteTaskTip': '保留已下载的文件',
'delete': '删除',
'newVersionTitle': '发现新版本 @version',
'newVersionUpdate': '立即更新',
'newVersionLater': '稍后再说',
'extensions': '扩展',
'extensionInstallUrl': '安装链接',
'extensionInstallSuccess': '安装成功',
'extensionUpdateSuccess': '更新成功',
'extensionDelete': '删除扩展',
'extensionAlreadyLatest': '已经是最新版本',
'extensionFind': '获取扩展',
'extensionDevelop': '开发扩展',
'history': '历史记录',
'clearHistory': '清空历史记录',
'noHistoryFound': '暂无历史记录',
'serviceTitle': '下载服务',
'serviceText': '运行中',
'proxy': '代理',
'username': '用户名',
'password': '密码'
}
};
+79
View File
@@ -0,0 +1,79 @@
const zhTW = {
"zh_TW": {
'label': '中文 (繁體) ',
'error': '錯誤',
'tip': '提示',
'confirm': '確定',
'cancel': '取消',
'selectAll': '全選',
'task': '任務',
'downloading': '下載中',
'downloaded': '已完成',
'setting': '設定',
'donate': '斗內',
'exit': '離開',
'create': '新增任務',
'directDownload': '直接下載',
'advancedOptions': '進階選項',
'downloadLink': '下載鏈接',
'downloadLinkValid': '請輸入下載鏈接',
'downloadLinkHit': '請輸入下載鏈接,支援 HTTP/HTTPS/MAGNET@append',
'downloadLinkHitDesktop': ',也可以通過拖拽Torrent文件至此以新增任務',
'download': '下載',
'noFileSelected': '沒有選取的文件',
'noStoragePermission': '沒有存儲權限',
'selectFile': '選擇文件',
'rename': '重命名',
'basic': '基礎',
'advanced': '進階',
'general': '通用設定',
'downloadDir': '下載目録',
'downloadDirValid': '請選擇下載目録',
'connections': '同時連接數',
'maxRunning': '最大同時下載數',
'items': '@count 項',
'subscribeTracker': '已訂閲的追蹤者列表',
'subscribeFail': '訂閲失敗',
'update': '更新',
'updateDaily': '每天自動更新',
'lastUpdate': '上次更新時間: @time',
'addTracker': '增加新的追蹤者',
'addTrackerHit': '請輸入追蹤者服務器地址,每行一條',
'ui': '介面',
'theme': '佈景主題',
'themeSystem': '跟隨系統',
'themeLight': '亮色主題',
'themeDark': '深色主題',
'locale': '語言',
'about': '關於',
'homepage': '訪問主頁',
'version': '版本資訊',
'protocol': '端口設定',
'port': '端口',
'apiToken': '接口秘鑰',
'notSet': '未設定',
'set': '已設定',
'effectAfterRestart': '重啟後生效',
'startAll': '全部開始',
'pauseAll': '全部暫停',
'deleteTask': '刪除任務',
'deleteTaskTip': '保留已經下載的文件',
'delete': '刪除',
'newVersionTitle': '發現新版本 @version',
'newVersionUpdate': '立刻更新',
'newVersionLater': '稍後更新',
'extensions': '外掛程序',
'extensionInstallUrl': '安裝URL',
'extensionInstallSuccess': '安裝成功',
'extensionUpdateSuccess': '更新完成',
'extensionDelete': '解除安裝',
'extensionAlreadyLatest': '已是最新版本',
'extensionFind': '取得外掛',
'extensionDevelop': '開發外掛',
'history': '歷史記錄',
'clearHistory': '清空記錄',
'noHistoryFound': '還沒有記錄',
'serviceTitle': '下載服務',
'serviceText': '執行中',
}
};
+23
View File
@@ -0,0 +1,23 @@
import 'package:get/get.dart';
import 'package:gopeed/i18n/langs/fa_ir.dart';
import 'package:gopeed/i18n/langs/ja_jp.dart';
import 'package:gopeed/i18n/langs/zh_tw.dart';
import 'langs/en_us.dart';
import 'langs/ru_ru.dart';
import 'langs/zh_cn.dart';
final messages = _Messages();
class _Messages extends Translations {
// just include available locales here
@override
Map<String, Map<String, String>> get keys => {
...zhCN,
...enUS,
...ruRU,
...zhTW,
...faIR,
...jaJP,
};
}
+5 -7
View File
@@ -7,7 +7,7 @@ import 'api/api.dart' as api;
import 'app/modules/app/controllers/app_controller.dart';
import 'app/modules/app/views/app_view.dart';
import 'core/libgopeed_boot.dart';
import 'generated/locales.g.dart';
import 'i18n/message.dart';
import 'util/locale_manager.dart';
import 'util/log_util.dart';
import 'util/mac_secure_util.dart';
@@ -72,12 +72,10 @@ Future<void> onStart() async {
// if is debug mode, check language message is complete,change debug locale to your comfortable language if you want
if (kDebugMode) {
final mainLang = getLocaleKey(debugLocale);
final fullMessages = AppTranslation.translations[mainLang];
AppTranslation.translations.keys
.where((e) => e != mainLang)
.forEach((lang) {
final langMessages = AppTranslation.translations[lang];
final debugLang = getLocaleKey(debugLocale);
final fullMessages = messages.keys[debugLang];
messages.keys.keys.where((e) => e != debugLang).forEach((lang) {
final langMessages = messages.keys[lang];
if (langMessages == null) {
logger.w("missing language: $lang");
return;