feat: make file manager draggable

This commit is contained in:
Kingtous
2023-02-24 14:15:54 +08:00
parent ca991ff39f
commit c3c4505132
4 changed files with 168 additions and 58 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:flutter_hbb/desktop/widgets/dragable_divider.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:flutter/gestures.dart';
@@ -78,6 +79,10 @@ class _FileManagerPageState extends State<FileManagerPage>
final _keyboardNodeRemote = FocusNode(debugLabel: "keyboardNodeRemote");
final _listSearchBufferLocal = TimeoutStringBuffer();
final _listSearchBufferRemote = TimeoutStringBuffer();
final _nameColWidthLocal = kDesktopFileTransferNameColWidth.obs;
final _modifiedColWidthLocal = kDesktopFileTransferModifiedColWidth.obs;
final _nameColWidthRemote = kDesktopFileTransferNameColWidth.obs;
final _modifiedColWidthRemote = kDesktopFileTransferModifiedColWidth.obs;
/// [_lastClickTime], [_lastClickEntry] help to handle double click
int _lastClickTime =
@@ -297,11 +302,12 @@ class _FileManagerPageState extends State<FileManagerPage>
}
var searchResult = entries
.skip(skipCount)
.where((element) => element.name.startsWith(buffer));
.where((element) => element.name.toLowerCase().startsWith(buffer));
if (searchResult.isEmpty) {
// cannot find next, lets restart search from head
debugPrint("restart search from head");
searchResult =
entries.where((element) => element.name.startsWith(buffer));
entries.where((element) => element.name.toLowerCase().startsWith(buffer));
}
if (searchResult.isEmpty) {
setState(() {
@@ -316,7 +322,7 @@ class _FileManagerPageState extends State<FileManagerPage>
debugPrint("searching for $buffer");
final selectedEntries = getSelectedItems(isLocal);
final searchResult =
entries.where((element) => element.name.startsWith(buffer));
entries.where((element) => element.name.toLowerCase().startsWith(buffer));
selectedEntries.clear();
if (searchResult.isEmpty) {
setState(() {
@@ -362,37 +368,41 @@ class _FileManagerPageState extends State<FileManagerPage>
child: Row(
children: [
GestureDetector(
child: Container(
width: kDesktopFileTransferNameColWidth,
child: Tooltip(
waitDuration:
Duration(milliseconds: 500),
message: entry.name,
child: Row(children: [
entry.isDrive
? Image(
image: iconHardDrive,
fit: BoxFit.scaleDown,
color: Theme.of(context)
.iconTheme
.color
?.withOpacity(0.7))
.paddingAll(4)
: SvgPicture.asset(
entry.isFile
? "assets/file.svg"
: "assets/folder.svg",
color: Theme.of(context)
.tabBarTheme
.labelColor,
),
Expanded(
child: Text(
entry.name.nonBreaking,
overflow:
TextOverflow.ellipsis))
]),
)),
child: Obx(
() => Container(
width: isLocal
? _nameColWidthLocal.value
: _nameColWidthRemote.value,
child: Tooltip(
waitDuration:
Duration(milliseconds: 500),
message: entry.name,
child: Row(children: [
entry.isDrive
? Image(
image: iconHardDrive,
fit: BoxFit.scaleDown,
color: Theme.of(context)
.iconTheme
.color
?.withOpacity(0.7))
.paddingAll(4)
: SvgPicture.asset(
entry.isFile
? "assets/file.svg"
: "assets/folder.svg",
color: Theme.of(context)
.tabBarTheme
.labelColor,
),
Expanded(
child: Text(
entry.name.nonBreaking,
overflow:
TextOverflow.ellipsis))
]),
)),
),
onTap: () {
final items = getSelectedItems(isLocal);
// handle double click
@@ -406,24 +416,35 @@ class _FileManagerPageState extends State<FileManagerPage>
items, filteredEntries, entry, isLocal);
},
),
SizedBox(
width: 2.0,
),
GestureDetector(
child: SizedBox(
width: kDesktopFileTransferModifiedColWidth,
child: Tooltip(
waitDuration:
Duration(milliseconds: 500),
message: lastModifiedStr,
child: Text(
lastModifiedStr,
style: TextStyle(
fontSize: 12,
color: MyTheme.darkGray,
),
)),
child: Obx(
() => SizedBox(
width: isLocal
? _modifiedColWidthLocal.value
: _modifiedColWidthRemote.value,
child: Tooltip(
waitDuration:
Duration(milliseconds: 500),
message: lastModifiedStr,
child: Text(
lastModifiedStr,
style: TextStyle(
fontSize: 12,
color: MyTheme.darkGray,
),
)),
),
),
),
// Divider from header.
SizedBox(
width: 100,
width: 2.0,
),
Expanded(
// width: 100,
child: GestureDetector(
child: Tooltip(
waitDuration: Duration(milliseconds: 500),
@@ -1362,6 +1383,7 @@ class _FileManagerPageState extends State<FileManagerPage>
Text(
name,
style: headerTextStyle,
overflow: TextOverflow.ellipsis,
).marginSymmetric(horizontal: 4),
ascending.value != null
? Icon(
@@ -1383,16 +1405,48 @@ class _FileManagerPageState extends State<FileManagerPage>
}
Widget _buildFileBrowserHeader(BuildContext context, bool isLocal) {
return Row(
children: [
headerItemFunc(kDesktopFileTransferNameColWidth, SortBy.name,
translate("Name"), isLocal),
headerItemFunc(kDesktopFileTransferModifiedColWidth, SortBy.modified,
translate("Modified"), isLocal),
Expanded(
child:
headerItemFunc(null, SortBy.size, translate("Size"), isLocal))
],
final nameColWidth = isLocal ? _nameColWidthLocal : _nameColWidthRemote;
final modifiedColWidth =
isLocal ? _modifiedColWidthLocal : _modifiedColWidthRemote;
final padding = EdgeInsets.all(1.0);
return SizedBox(
height: kDesktopFileTransferHeaderHeight,
child: Row(
children: [
Obx(
() => headerItemFunc(
nameColWidth.value, SortBy.name, translate("Name"), isLocal),
),
DraggableDivider(
axis: Axis.vertical,
onPointerMove: (dx) {
nameColWidth.value += dx;
nameColWidth.value = min(
kDesktopFileTransferMaximumWidth,
max(kDesktopFileTransferMinimumWidth,
nameColWidth.value));
},
padding: padding,
),
Obx(
() => headerItemFunc(modifiedColWidth.value, SortBy.modified,
translate("Modified"), isLocal),
),
DraggableDivider(
axis: Axis.vertical,
onPointerMove: (dx) {
modifiedColWidth.value += dx;
modifiedColWidth.value = min(
kDesktopFileTransferMaximumWidth,
max(kDesktopFileTransferMinimumWidth,
modifiedColWidth.value));
},
padding: padding),
Expanded(
child:
headerItemFunc(null, SortBy.size, translate("Size"), isLocal))
],
),
);
}
}