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:
Neginegiandwuke2022 authored and GitHub committed 2023-02-21 20:17:17 +08:00
1 parent dbc9c4c121
commit 5b69472ac8
20 files changed
+4390 -217

No files matched your search

Binary file not shown.
+1
View File
@@ -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",
-4
View File
@@ -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": "انتخاب فایل",
-2
View File
@@ -6,8 +6,6 @@
"cancel": "Отмена",
"selectAll": "Выбрать все",
"task": "Задачи",
"downloading": "downloading",
"downloaded": "downloaded",
"setting": "Настройки",
"create": "Создать задачу",
"downloadLink": "Ссылка для скачивание",
+1
View File
@@ -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)))),
],
));
}
+6 -11
View File
@@ -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': '基础',
+1 -1
View File
@@ -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';
+21 -14
View File
@@ -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
@@ -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);
}
},
);
}
}
+5 -8
View File
@@ -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