mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-05 16:15:43 +00:00
fix: style, performance ,loading bug (#90)
* refactor project in get-cli standard * use local trackers when github is not connectable upgrade stylish_bottom_bar to 1.0.0 responsive view for home_view treeview for file_list_vie fluent ui integrating * improve responsive view. treeView add light theme.fix overflow bugs * responsive view,treeView,file select downloaded and downloading pages file extension icons fix some minor bugs * use local trackers when github is not connectable upgrade stylish_bottom_bar to 1.0.0 responsive view for home_view treeview for file_list_vie fluent ui integrating * improve responsive view. treeView add light theme.fix overflow bugs * bottom bar index fix * refactor project in get-cli standard * fix:locale fix * fix: task list stack progress style fix: translation fix: tree view fix: confirm button loading remove: stylish_bottom_bar(dark mode not supported) * fix: task list stack progress style fix: translation fix: tree view fix: confirm button loading remove: stylish_bottom_bar(dark mode not supported) --------- Co-authored-by: wuke2022 <[email protected]>
This commit is contained in:
1 parent
dbc9c4c121
commit
5b69472ac8
20 files changed
+4390
-217
No files matched your search
Binary file not shown.
@@ -15,6 +15,7 @@
|
||||
"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",
|
||||
"basic": "Basic",
|
||||
|
||||
@@ -6,14 +6,10 @@
|
||||
"cancel": "انصراف",
|
||||
"selectAll": "انتخاب همه",
|
||||
"task": "کار",
|
||||
"downloading": "downloading",
|
||||
"downloaded": "downloaded",
|
||||
"setting": "تنظیمات",
|
||||
"create": "ایجاد کار",
|
||||
"downloadLink": "لینک دانلود",
|
||||
"downloadLinkValid": "لطفا لینک دانلود را وارد کنید",
|
||||
"downloadLinkHit": "Please enter the download link, HTTP/HTTPS/MAGNET supported@append",
|
||||
"downloadLinkHitDesktop": ", or drag the torrent file here directly",
|
||||
"download": "دانلود",
|
||||
"noStoragePermission": "مجوز ذخیره سازی مورد نیاز است",
|
||||
"selectFile": "انتخاب فایل",
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
"cancel": "Отмена",
|
||||
"selectAll": "Выбрать все",
|
||||
"task": "Задачи",
|
||||
"downloading": "downloading",
|
||||
"downloaded": "downloaded",
|
||||
"setting": "Настройки",
|
||||
"create": "Создать задачу",
|
||||
"downloadLink": "Ссылка для скачивание",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"downloadLinkHit": "请输入下载链接,支持 HTTP/HTTPS/MAGNET@append",
|
||||
"downloadLinkHitDesktop": ",也可以直接拖拽种子文件到此处",
|
||||
"download": "下载",
|
||||
"noFileSelected": "请至少选择一个文件下载",
|
||||
"noStoragePermission": "需要开启存储权限",
|
||||
"selectFile": "选择文件",
|
||||
"basic": "基础",
|
||||
|
||||
@@ -10,7 +10,7 @@ import '../../../../api/api.dart';
|
||||
import '../../../../api/model/downloader_config.dart';
|
||||
import '../../../../core/common/start_config.dart';
|
||||
import '../../../../generated/locales.g.dart';
|
||||
import '../../../../i18n/localeManager.dart';
|
||||
import '../../../../util/localeManager.dart';
|
||||
import '../../../../util/log_util.dart';
|
||||
import '../../../../util/util.dart';
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../../generated/locales.g.dart';
|
||||
import '../../../../i18n/localeManager.dart';
|
||||
import '../../../../theme/theme.dart';
|
||||
import '../../../../util/localeManager.dart';
|
||||
import '../../../routes/app_pages.dart';
|
||||
import '../controllers/app_controller.dart';
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@ import 'package:get/get.dart';
|
||||
|
||||
class CreateController extends GetxController {
|
||||
final files = [].obs;
|
||||
final RxList selectedIndexs = [].obs;
|
||||
final RxList selectedIndexes = [].obs;
|
||||
}
|
||||
@@ -70,18 +70,18 @@ class CreateView extends GetView<CreateController> {
|
||||
child: RoundedLoadingButton(
|
||||
color: Get.theme.colorScheme.secondary,
|
||||
onPressed: () async {
|
||||
if (_resolveFormKey.currentState!.validate()) {
|
||||
try {
|
||||
_confirmController.start();
|
||||
try {
|
||||
if (_resolveFormKey.currentState!.validate()) {
|
||||
final rr = await resolve(Request(
|
||||
url: _urlController.text,
|
||||
));
|
||||
await _showResolveDialog(rr);
|
||||
} catch (e) {
|
||||
Get.snackbar('error'.tr, e.toString());
|
||||
} finally {
|
||||
_confirmController.reset();
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar('error'.tr, e.toString());
|
||||
} finally {
|
||||
_confirmController.reset();
|
||||
}
|
||||
},
|
||||
controller: _confirmController,
|
||||
@@ -106,12 +106,11 @@ class CreateView extends GetView<CreateController> {
|
||||
Future<void> _showResolveDialog(ResolveResult rr) async {
|
||||
controller.files.value = rr.res.files;
|
||||
final appController = Get.find<AppController>();
|
||||
final setting = appController.downloaderConfig.value;
|
||||
|
||||
final createFormKey = GlobalKey<FormState>();
|
||||
final pathController = TextEditingController(text: setting.downloadDir);
|
||||
final pathController = TextEditingController(
|
||||
text: appController.downloaderConfig.value.downloadDir);
|
||||
final downloadController = RoundedLoadingButtonController();
|
||||
|
||||
return showDialog<void>(
|
||||
context: Get.context!,
|
||||
barrierDismissible: false,
|
||||
@@ -163,40 +162,47 @@ class CreateView extends GetView<CreateController> {
|
||||
height: Get.theme.buttonTheme.height,
|
||||
),
|
||||
child: RoundedLoadingButton(
|
||||
color: Get.theme.colorScheme.secondary,
|
||||
onPressed: () async {
|
||||
try {
|
||||
if (createFormKey.currentState!.validate()) {
|
||||
color: Get.theme.colorScheme.secondary,
|
||||
duration: const Duration(milliseconds: 100),
|
||||
onPressed: () async {
|
||||
try {
|
||||
downloadController.start();
|
||||
if (controller.selectedIndexes.isEmpty) {
|
||||
Get.snackbar('tip'.tr, 'noFileSelected'.tr);
|
||||
return;
|
||||
}
|
||||
if (createFormKey.currentState!.validate()) {
|
||||
// if (Util.isAndroid()) {
|
||||
// if (!await Permission.storage.request().isGranted) {
|
||||
// Get.snackbar('error'.tr,
|
||||
// 'noStoragePermission'.tr);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (Util.isAndroid()) {
|
||||
// if (!await Permission.storage.request().isGranted) {
|
||||
// Get.snackbar('error'.tr,
|
||||
// 'noStoragePermission'.tr);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
await createTask(CreateTask(
|
||||
rid: rr.id,
|
||||
opts: Options(
|
||||
name: '',
|
||||
path: pathController.text,
|
||||
selectFiles:
|
||||
controller.selectedIndexs.cast<int>())));
|
||||
Get.back();
|
||||
Get.rootDelegate.offNamed(Routes.DOWNLOADING);
|
||||
await createTask(CreateTask(
|
||||
rid: rr.id,
|
||||
opts: Options(
|
||||
name: '',
|
||||
path: pathController.text,
|
||||
selectFiles: controller.selectedIndexes
|
||||
.cast<int>())));
|
||||
Get.rootDelegate.offNamed(Routes.DOWNLOADING);
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar('error'.tr, e.toString());
|
||||
rethrow;
|
||||
} finally {
|
||||
downloadController.reset();
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar('error'.tr, e.toString());
|
||||
rethrow;
|
||||
} finally {
|
||||
downloadController.reset();
|
||||
}
|
||||
},
|
||||
controller: downloadController,
|
||||
child: Text('download'.tr),
|
||||
),
|
||||
},
|
||||
controller: downloadController,
|
||||
child: Text(
|
||||
'download'.tr,
|
||||
// style: controller.selectedIndexes.isEmpty
|
||||
// ? Get.textTheme.disabled
|
||||
// : Get.textTheme.titleSmall
|
||||
)),
|
||||
),
|
||||
],
|
||||
));
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:stylish_bottom_bar/model/bar_items.dart';
|
||||
import 'package:stylish_bottom_bar/stylish_bottom_bar.dart';
|
||||
|
||||
import '../../../routes/app_pages.dart';
|
||||
import '../../../views/views/responsive_builder.dart';
|
||||
@@ -77,29 +75,23 @@ class HomeView extends GetView<HomeController> {
|
||||
))
|
||||
]),
|
||||
bottomNavigationBar: ResponsiveBuilder.isNarrow(context)
|
||||
? StylishBottomBar(
|
||||
option: AnimatedBarOptions(
|
||||
iconSize: 32,
|
||||
barAnimation: BarAnimation.blink,
|
||||
iconStyle: IconStyle.Default,
|
||||
opacity: 0.3,
|
||||
),
|
||||
items: [
|
||||
BottomBarItem(
|
||||
icon: const Icon(Icons.format_align_left_outlined),
|
||||
selectedColor: Get.theme.primaryColor,
|
||||
title: Text('downloading'.tr)),
|
||||
BottomBarItem(
|
||||
icon: const Icon(Icons.format_align_justify_outlined),
|
||||
selectedColor: Get.theme.primaryColor,
|
||||
title: Text('downloaded'.tr)),
|
||||
BottomBarItem(
|
||||
icon: const Icon(Icons.settings),
|
||||
selectedColor: Get.theme.primaryColor,
|
||||
title: Text('setting'.tr)),
|
||||
? BottomNavigationBar(
|
||||
items: <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.format_align_left_outlined),
|
||||
label: 'downloading'.tr,
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.format_align_justify_outlined),
|
||||
label: 'downloaded'.tr,
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.settings),
|
||||
label: 'setting'.tr,
|
||||
),
|
||||
],
|
||||
// hasNotch: true,
|
||||
currentIndex: controller.currentIndex.value,
|
||||
// selectedItemColor: Get.theme.highlightColor,
|
||||
onTap: (index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
@@ -117,6 +109,46 @@ class HomeView extends GetView<HomeController> {
|
||||
}
|
||||
},
|
||||
)
|
||||
// StylishBottomBar(
|
||||
// option: AnimatedBarOptions(
|
||||
// iconSize: 32,
|
||||
// barAnimation: BarAnimation.blink,
|
||||
// iconStyle: IconStyle.Default,
|
||||
// opacity: 0.3,
|
||||
// ),
|
||||
// items: [
|
||||
// BottomBarItem(
|
||||
// icon: const Icon(Icons.format_align_left_outlined),
|
||||
// selectedColor: Get.theme.primaryColor,
|
||||
// title: Text('downloading'.tr)),
|
||||
// BottomBarItem(
|
||||
// icon: const Icon(Icons.format_align_justify_outlined),
|
||||
// selectedColor: Get.theme.primaryColor,
|
||||
// title: Text('downloaded'.tr)),
|
||||
// BottomBarItem(
|
||||
// icon: const Icon(Icons.settings),
|
||||
// selectedColor: Get.theme.primaryColor,
|
||||
// title: Text('setting'.tr)),
|
||||
// ],
|
||||
// // hasNotch: true,
|
||||
// currentIndex: controller.currentIndex.value,
|
||||
// onTap: (index) {
|
||||
// switch (index) {
|
||||
// case 0:
|
||||
// delegate.toNamed(Routes.DOWNLOADING);
|
||||
// controller.currentIndex.value = 0;
|
||||
// break;
|
||||
// case 1:
|
||||
// delegate.toNamed(Routes.DOWNLOADED);
|
||||
// controller.currentIndex.value = 1;
|
||||
// break;
|
||||
// case 2:
|
||||
// delegate.toNamed(Routes.SETTING);
|
||||
// controller.currentIndex.value = 2;
|
||||
// break;
|
||||
// }
|
||||
// },
|
||||
// )
|
||||
: const SizedBox.shrink(),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:intl/intl.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../../../generated/locales.g.dart';
|
||||
import '../../../../i18n/localeManager.dart';
|
||||
import '../../../../util/localeManager.dart';
|
||||
import '../../../../util/package_info.dart';
|
||||
import '../../../../util/util.dart';
|
||||
import '../../../views/views/check_list_view.dart';
|
||||
|
||||
@@ -6,6 +6,8 @@ import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../../api/api.dart';
|
||||
import '../../../api/model/task.dart';
|
||||
import '../../../util/file_icon.dart';
|
||||
import '../../../util/icons.dart';
|
||||
import '../../../util/util.dart';
|
||||
import '../../routes/app_pages.dart';
|
||||
|
||||
@@ -171,25 +173,36 @@ class BuildTaskListView extends GetView {
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Stack(children: [
|
||||
!isDone()
|
||||
? Opacity(
|
||||
opacity: 0.6,
|
||||
child: LinearProgressIndicator(
|
||||
backgroundColor: Colors.transparent,
|
||||
color: pickColor(),
|
||||
minHeight: 66,
|
||||
value: getProgress(),
|
||||
),
|
||||
)
|
||||
? Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: Opacity(
|
||||
opacity: 0.6,
|
||||
child: LinearProgressIndicator(
|
||||
backgroundColor: Colors.transparent,
|
||||
color: pickColor(),
|
||||
// minHeight: 76,
|
||||
value: getProgress(),
|
||||
),
|
||||
))
|
||||
: const SizedBox.shrink(),
|
||||
ListTile(
|
||||
// isThreeLine: true,
|
||||
title: Text(task.meta.res.name,
|
||||
maxLines: 2, overflow: TextOverflow.ellipsis),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Get.textTheme.titleSmall),
|
||||
subtitle: Text(
|
||||
"${isDone() ? "" : "${Util.fmtByte(task.progress.downloaded)} / "}${Util.fmtByte(task.size)}",
|
||||
style: context.textTheme.bodyLarge
|
||||
?.copyWith(color: Get.theme.disabledColor),
|
||||
),
|
||||
leading: const Icon(Icons.insert_drive_file),
|
||||
leading: task.meta.res.name.lastIndexOf('.') == -1
|
||||
? const Icon(FaIcons.file)
|
||||
: Icon(FaIcons.allIcons[findIcon(task.meta.res.name)]),
|
||||
|
||||
trailing: SizedBox(
|
||||
width: 180,
|
||||
child: Row(
|
||||
@@ -203,7 +216,7 @@ class BuildTaskListView extends GetView {
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
])
|
||||
]));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:get/get.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../../../util/file_icon.dart';
|
||||
import '../../../util/icons.dart';
|
||||
import '../../../util/util.dart';
|
||||
import '../../modules/app/controllers/app_controller.dart';
|
||||
import '../../modules/create/controllers/create_controller.dart';
|
||||
@@ -15,16 +16,50 @@ class FileListView extends GetView {
|
||||
final parentController = Get.find<CreateController>();
|
||||
final appController = Get.find<AppController>();
|
||||
|
||||
late final List fileInfos;
|
||||
|
||||
List findChildFileIdsRecursive(children) {
|
||||
List res = [];
|
||||
for (var i in children) {
|
||||
if (fileInfos[i]['type'] == 'folder') {
|
||||
findChildFileIdsRecursive(fileInfos[i]['children']);
|
||||
} else {
|
||||
res.add(i);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
List<fluent.TreeViewItem> buildTreeViewItemsRecursive(
|
||||
List fileInfos, int level, List<fluent.TreeViewItem> treeViewItems) {
|
||||
int level, List<fluent.TreeViewItem> treeViewItems) {
|
||||
List children = fileInfos.where((e) => e['level'] == level).toList();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
Map fileInfo = children[i];
|
||||
if (fileInfo['size'] == null) {
|
||||
if (fileInfo['type'] == 'folder') {
|
||||
// folder
|
||||
treeViewItems.add(fluent.TreeViewItem(
|
||||
// expanded: false, bug on init
|
||||
leading: const Icon(Icons.folder_open),
|
||||
// value: fileInfo['id'],
|
||||
onInvoked: (item, reason) async {
|
||||
debugPrint('onItemInvoked(reason=$reason): $item');
|
||||
if (reason.toString() ==
|
||||
'TreeViewItemInvokeReason.selectionToggle') {
|
||||
List childrenIds =
|
||||
findChildFileIdsRecursive(fileInfo['children']);
|
||||
if (item.selected == true) {
|
||||
parentController.selectedIndexes
|
||||
.addAll(findChildFileIdsRecursive(childrenIds));
|
||||
} else {
|
||||
parentController.selectedIndexes
|
||||
.removeWhere((index) => childrenIds.contains(index));
|
||||
}
|
||||
}
|
||||
},
|
||||
leading:
|
||||
// parentController.openedFolders.contains(fileInfo['id'])
|
||||
// ? const Icon(FaIcons.folder)
|
||||
// : const Icon(FaIcons.folder_open),
|
||||
const Icon(FaIcons.folder),
|
||||
content: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
@@ -33,26 +68,35 @@ class FileListView extends GetView {
|
||||
// style: context.textTheme.titleSmall,
|
||||
)),
|
||||
]),
|
||||
// onExpandToggle: (Fluent.TreeViewItem item, bool getsExpanded) {
|
||||
//TODO
|
||||
// item.expanded = getsExpanded;
|
||||
// onExpandToggle: (fluent.TreeViewItem item, bool getExpanded) async {
|
||||
// getExpanded
|
||||
// ? parentController.openedFolders.add(item.value)
|
||||
// : parentController.openedFolders.remove(item.value);
|
||||
// },
|
||||
children: buildTreeViewItemsRecursive(
|
||||
fileInfos.where((e) => e['level'] > level).toList(),
|
||||
level + 1, [])));
|
||||
// fileInfos.where((e) => e['level'] > level).toList(),
|
||||
level + 1,
|
||||
[])));
|
||||
} else {
|
||||
// file
|
||||
if (fileInfo['selected']) {
|
||||
parentController.selectedIndexs.add(fileInfo['fileId']);
|
||||
}
|
||||
// if (fileInfo['selected']) {
|
||||
// parentController.selectedIndexs.add(fileInfo['fileId']);
|
||||
// }
|
||||
treeViewItems.add(fluent.TreeViewItem(
|
||||
value: fileInfo['fileId'],
|
||||
selected: fileInfo['selected'],
|
||||
onInvoked: (item, reason) async => {
|
||||
debugPrint('onItemInvoked(reason=$reason): $item'),
|
||||
reason.toString() == 'TreeViewItemInvokeReason.selectionToggle'
|
||||
? item.selected == false
|
||||
? parentController.selectedIndexes.remove(item.value)
|
||||
: parentController.selectedIndexes.add(item.value)
|
||||
: null
|
||||
},
|
||||
collapsable: false,
|
||||
leading: fileInfo['name'].lastIndexOf('.') == -1
|
||||
? const Icon(fluent.FluentIcons.document)
|
||||
: Icon(fluent.FluentIcons.allIcons[findIcon(fileInfo['name']
|
||||
.substring(fileInfo['name'].lastIndexOf('.') + 1))]),
|
||||
? const Icon(FaIcons.file)
|
||||
: Icon(FaIcons.allIcons[findIcon(fileInfo['name'])]),
|
||||
content: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
@@ -74,25 +118,27 @@ class FileListView extends GetView {
|
||||
return treeViewItems;
|
||||
}
|
||||
|
||||
List<fluent.TreeViewItem> get items {
|
||||
List fileInfos = [];
|
||||
List<fluent.TreeViewItem> items(files) {
|
||||
List infos = [];
|
||||
int idNext = 0;
|
||||
List selectedIndexs = [];
|
||||
// List openedFolders = [];
|
||||
//make fileInfos list
|
||||
for (var i = 0; i < parentController.files.length; i++) {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
//parentId -1 means path root
|
||||
int parentId = -1;
|
||||
List folders = path.split(parentController.files[i].path);
|
||||
List folders = path.split(files[i].path);
|
||||
for (var folder in folders) {
|
||||
int indexInfileInfos = fileInfos.lastIndexWhere((fileInfo) =>
|
||||
int indexInfileInfos = infos.lastIndexWhere((fileInfo) =>
|
||||
fileInfo['name'] == folder && fileInfo['parentId'] == parentId);
|
||||
//TODO calculate folder size
|
||||
if (indexInfileInfos != -1) {
|
||||
// folder exists
|
||||
parentId = fileInfos[indexInfileInfos]['id'];
|
||||
parentId = infos[indexInfileInfos]['id'];
|
||||
} else {
|
||||
// parent not exist
|
||||
// create one and add index to parent's children
|
||||
fileInfos.add({
|
||||
infos.add({
|
||||
'id': idNext,
|
||||
'type': 'folder',
|
||||
'name': folder,
|
||||
@@ -101,41 +147,47 @@ class FileListView extends GetView {
|
||||
'children': [],
|
||||
});
|
||||
if (parentId != -1) {
|
||||
fileInfos[parentId]['children'].add(idNext);
|
||||
infos[parentId]['children'].add(idNext);
|
||||
}
|
||||
// openedFolders.add(idNext);
|
||||
parentId = idNext;
|
||||
idNext++;
|
||||
}
|
||||
}
|
||||
//add one file, add index to parent
|
||||
fileInfos.add({
|
||||
infos.add({
|
||||
'id': idNext,
|
||||
'type': 'file',
|
||||
'fileId': i,
|
||||
'level': folders.length,
|
||||
'name': parentController.files[i].name,
|
||||
'size': parentController.files[i].size,
|
||||
'name': files[i].name,
|
||||
'size': files[i].size,
|
||||
'parentId': parentId,
|
||||
//TODO add unselected logic
|
||||
'selected': true
|
||||
});
|
||||
selectedIndexs.add(idNext);
|
||||
if (parentId != -1) {
|
||||
fileInfos[parentId]['children'].add(idNext);
|
||||
infos[parentId]['children'].add(idNext);
|
||||
}
|
||||
idNext++;
|
||||
}
|
||||
List<fluent.TreeViewItem> treeItems =
|
||||
buildTreeViewItemsRecursive(fileInfos, 0, []);
|
||||
fileInfos = infos;
|
||||
parentController.selectedIndexes.value = selectedIndexs;
|
||||
// parentController.openedFolders.value = openedFolders;
|
||||
List<fluent.TreeViewItem> treeItems = buildTreeViewItemsRecursive(0, []);
|
||||
return treeItems;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appController = Get.find<AppController>();
|
||||
final files = parentController.files;
|
||||
return fluent.FluentTheme(
|
||||
data: appController.downloaderConfig.value.extra.themeMode == 'dark'
|
||||
? fluent.ThemeData(brightness: Brightness.dark)
|
||||
: fluent.ThemeData(brightness: Brightness.light),
|
||||
data:
|
||||
Get.find<AppController>().downloaderConfig.value.extra.themeMode ==
|
||||
'dark'
|
||||
? fluent.ThemeData(brightness: Brightness.dark)
|
||||
: fluent.ThemeData(brightness: Brightness.light),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -151,24 +203,19 @@ class FileListView extends GetView {
|
||||
border: Border.all(color: Colors.grey, width: 1),
|
||||
borderRadius: BorderRadius.circular(5)),
|
||||
child: fluent.TreeView(
|
||||
//changes all when folder selector is changed
|
||||
onSelectionChanged: (selectedItems) async => {
|
||||
parentController.selectedIndexs.value =
|
||||
selectedItems.map((j) => j.value).toList()
|
||||
// for (var i = 0; i < parentController.files.length; i++)
|
||||
// {
|
||||
// selectedItems
|
||||
// .map((j) => j.value)
|
||||
// .toList()
|
||||
// .contains(i)
|
||||
// ? values[i] = true
|
||||
// : values[i] = false
|
||||
// }
|
||||
},
|
||||
// shrinkWrap: false,
|
||||
// addRepaintBoundaries: false,
|
||||
// usePrototypeItem: true,
|
||||
// onItemInvoked: (item, reason) async => {},
|
||||
onSecondaryTap: (item, details) async {
|
||||
debugPrint(
|
||||
'onSecondaryTap $item at ${details.globalPosition}');
|
||||
},
|
||||
// onSelectionChanged: (selectedItems) async => {},
|
||||
narrowSpacing: true,
|
||||
scrollPrimary: true,
|
||||
// scrollPrimary: true,
|
||||
selectionMode: fluent.TreeViewSelectionMode.multiple,
|
||||
items: items))),
|
||||
items: items(files)))),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ class LocaleKeys {
|
||||
static const downloadLinkHit = 'downloadLinkHit';
|
||||
static const downloadLinkHitDesktop = 'downloadLinkHitDesktop';
|
||||
static const download = 'download';
|
||||
static const noFileSelected = 'noFileSelected';
|
||||
static const noStoragePermission = 'noStoragePermission';
|
||||
static const selectFile = 'selectFile';
|
||||
static const basic = 'basic';
|
||||
@@ -63,7 +64,6 @@ class LocaleKeys {
|
||||
static const deleteTask = 'deleteTask';
|
||||
static const deleteTaskTip = 'deleteTaskTip';
|
||||
static const delete = 'delete';
|
||||
static const title = 'title';
|
||||
}
|
||||
|
||||
class Locales {
|
||||
@@ -85,6 +85,7 @@ class Locales {
|
||||
'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',
|
||||
'basic': 'Basic',
|
||||
@@ -129,15 +130,10 @@ class Locales {
|
||||
'cancel': 'انصراف',
|
||||
'selectAll': 'انتخاب همه',
|
||||
'task': 'کار',
|
||||
'downloading': 'downloading',
|
||||
'downloaded': 'downloaded',
|
||||
'setting': 'تنظیمات',
|
||||
'title': 'ایجاد کار',
|
||||
'create': 'ایجاد کار',
|
||||
'downloadLink': 'لینک دانلود',
|
||||
'downloadLinkValid': 'لطفا لینک دانلود را وارد کنید',
|
||||
'downloadLinkHit':
|
||||
'Please enter the download link, HTTP/HTTPS/MAGNET supported@append',
|
||||
'downloadLinkHitDesktop': ', or drag the torrent file here directly',
|
||||
'download': 'دانلود',
|
||||
'noStoragePermission': 'مجوز ذخیره سازی مورد نیاز است',
|
||||
'selectFile': 'انتخاب فایل',
|
||||
@@ -183,10 +179,8 @@ class Locales {
|
||||
'cancel': 'Отмена',
|
||||
'selectAll': 'Выбрать все',
|
||||
'task': 'Задачи',
|
||||
'downloading': 'downloading',
|
||||
'downloaded': 'downloaded',
|
||||
'setting': 'Настройки',
|
||||
'title': 'Создать задачу',
|
||||
'create': 'Создать задачу',
|
||||
'downloadLink': 'Ссылка для скачивание',
|
||||
'downloadLinkValid': 'Пожалуйста, введите ссылку для скачивания',
|
||||
'downloadLinkHit':
|
||||
@@ -240,12 +234,13 @@ class Locales {
|
||||
'downloading': '下载中',
|
||||
'downloaded': '已完成',
|
||||
'setting': '设置',
|
||||
'title': '创建任务',
|
||||
'create': '创建任务',
|
||||
'downloadLink': '下载链接',
|
||||
'downloadLinkValid': '请输入下载链接',
|
||||
'downloadLinkHit': '请输入下载链接,支持 HTTP/HTTPS/MAGNET@append',
|
||||
'downloadLinkHitDesktop': ',也可以直接拖拽种子文件到此处',
|
||||
'download': '下载',
|
||||
'noFileSelected': '请至少选择一个文件下载',
|
||||
'noStoragePermission': '需要开启存储权限',
|
||||
'selectFile': '选择文件',
|
||||
'basic': '基础',
|
||||
|
||||
@@ -7,7 +7,7 @@ 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/localeManager.dart';
|
||||
import 'util/localeManager.dart';
|
||||
import 'util/log_util.dart';
|
||||
import 'util/mac_secure_util.dart';
|
||||
import 'util/package_info.dart';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
findIcon(String ext) {
|
||||
String res = 'document';
|
||||
findIcon(String filename) {
|
||||
String res = 'file';
|
||||
String ext = filename.substring(filename.lastIndexOf('.') + 1);
|
||||
for (var iconMap in iconMaps) {
|
||||
if (iconMap['extensions'].contains(ext)) {
|
||||
res = iconMap['thumbnail'];
|
||||
@@ -57,7 +58,7 @@ const List iconMaps = [
|
||||
'3gp'
|
||||
],
|
||||
'type': 'Video',
|
||||
'thumbnail': 'my_movies_t_v'
|
||||
'thumbnail': 'file_video'
|
||||
},
|
||||
{
|
||||
'extensions': [
|
||||
@@ -73,7 +74,7 @@ const List iconMaps = [
|
||||
'.wma'
|
||||
],
|
||||
'type': 'Audio',
|
||||
'thumbnail': 'music_in_collection_fill'
|
||||
'thumbnail': 'file_audio'
|
||||
},
|
||||
//compressed
|
||||
{
|
||||
@@ -97,23 +98,29 @@ const List iconMaps = [
|
||||
'dockerignore'
|
||||
],
|
||||
'type': 'Archive',
|
||||
'thumbnail': 'package'
|
||||
'thumbnail': 'file_archive'
|
||||
},
|
||||
//office relative
|
||||
{
|
||||
'extensions': ['pdf'],
|
||||
'type': 'Portable Document Format',
|
||||
'thumbnail': 'pdf'
|
||||
'thumbnail': 'file_pdf'
|
||||
},
|
||||
{
|
||||
'extensions': ['txt', 'doc', 'docb', 'docm', 'dot', 'dotm', 'docx', 'rtf'],
|
||||
'type': 'Word Document',
|
||||
'thumbnail': 'text_document_edit'
|
||||
'extensions': ['txt', 'docb', 'rtf'],
|
||||
'type': 'Document',
|
||||
'thumbnail': 'doc_text'
|
||||
},
|
||||
{
|
||||
'extensions': ['doc', 'docm', 'dot', 'dotm', 'docx'],
|
||||
'type': 'Word Document',
|
||||
'thumbnail': 'file_word'
|
||||
},
|
||||
|
||||
{
|
||||
'extensions': ['xlsx', 'xls', 'xlsb', 'xls', 'ods', 'fods', 'csv'],
|
||||
'type': 'Excel Document',
|
||||
'thumbnail': 'excel_document'
|
||||
'thumbnail': 'file_excel'
|
||||
},
|
||||
{
|
||||
'extensions': [
|
||||
@@ -129,13 +136,13 @@ const List iconMaps = [
|
||||
'pptx'
|
||||
],
|
||||
'type': 'Powerpoint Document',
|
||||
'thumbnail': 'power_point_document'
|
||||
'thumbnail': 'file_powerpoint'
|
||||
},
|
||||
//other
|
||||
{
|
||||
'extensions': ['lnk'],
|
||||
'type': 'Shortcut',
|
||||
'thumbnail': 'file_symlink'
|
||||
'thumbnail': 'link_ext'
|
||||
},
|
||||
{
|
||||
'extensions': [
|
||||
@@ -155,12 +162,12 @@ const List iconMaps = [
|
||||
'cfg'
|
||||
],
|
||||
'type': 'Settings',
|
||||
'thumbnail': 'text_document_settings'
|
||||
'thumbnail': 'cog_alt'
|
||||
},
|
||||
{
|
||||
'extensions': ['html', 'htm', 'xhtml', 'html_vm'],
|
||||
'type': 'html',
|
||||
'thumbnail': 'file_h_t_m_l'
|
||||
'thumbnail': 'html5'
|
||||
},
|
||||
//code relative
|
||||
// {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File renamed without changes.
@@ -1,50 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ResponsiveBuilder extends StatelessWidget {
|
||||
const ResponsiveBuilder({
|
||||
required this.narrowBuilder,
|
||||
required this.mediumBuilder,
|
||||
required this.wideBuilder,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget Function(
|
||||
BuildContext context,
|
||||
BoxConstraints constraints,
|
||||
) narrowBuilder;
|
||||
|
||||
final Widget Function(
|
||||
BuildContext context,
|
||||
BoxConstraints constraints,
|
||||
) mediumBuilder;
|
||||
|
||||
final Widget Function(
|
||||
BuildContext context,
|
||||
BoxConstraints constraints,
|
||||
) wideBuilder;
|
||||
|
||||
static bool isNarrow(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width < 768;
|
||||
|
||||
static bool isMedium(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width < 992 &&
|
||||
MediaQuery.of(context).size.width >= 768;
|
||||
|
||||
static bool isWide(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width >= 992;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
if (constraints.maxWidth >= 992) {
|
||||
return wideBuilder(context, constraints);
|
||||
} else if (constraints.maxWidth >= 768) {
|
||||
return mediumBuilder(context, constraints);
|
||||
} else {
|
||||
return narrowBuilder(context, constraints);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -30,13 +30,12 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
sdk: flutter
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.2
|
||||
get: ^4.6.5
|
||||
stylish_bottom_bar: ^1.0.0
|
||||
lottie: ^1.4.2
|
||||
styled_widget: ^0.4.0+3
|
||||
context_menus: ^1.0.2
|
||||
@@ -98,12 +97,10 @@ flutter:
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
fonts:
|
||||
- family: FontAwesome
|
||||
fonts:
|
||||
- asset: assets/fonts/FontAwesome.ttf
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
|
||||
Reference in new issue
Block a user