file transfer search bar pop_menu show Windows drives

This commit is contained in:
csf 2022-10-18 23:56:36 +09:00
parent e23fa8c806
commit 0c976a6644
6 changed files with 251 additions and 168 deletions

View File

@ -107,7 +107,7 @@ class DraggableChatWindow extends StatelessWidget {
icon: IconFont.close,
onTap: chatModel.hideChatWindowOverlay,
isClose: true,
size: 32,
boxSize: 32,
))
],
),

View File

@ -6,6 +6,7 @@ import 'package:desktop_drop/desktop_drop.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/models/file_model.dart';
import 'package:get/get.dart';
import 'package:provider/provider.dart';
@ -455,7 +456,7 @@ class _FileManagerPageState extends State<FileManagerPage>
icon: const Icon(Icons.restart_alt_rounded)),
),
IconButton(
icon: const Icon(Icons.delete),
icon: const Icon(Icons.delete_forever_outlined),
splashRadius: 20,
onPressed: () {
model.jobTable.removeAt(index);
@ -742,31 +743,97 @@ class _FileManagerPageState extends State<FileManagerPage>
openDirectory(path, isLocal: isLocal);
});
breadCrumbScrollToEnd(isLocal);
final locationBarKey = GlobalKey(debugLabel: "locationBarKey");
return items.isEmpty
? Offstage()
: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
: Row(
key: locationBarKey,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: BreadCrumb(
items: items,
divider: Text("/").paddingSymmetric(horizontal: 4.0),
divider: Text("/",
style: TextStyle(color: Theme.of(context).hintColor))
.paddingSymmetric(horizontal: 2.0),
overflow: ScrollableOverflow(
controller: getBreadCrumbScrollController(isLocal)),
)),
DropdownButton<String>(
isDense: true,
underline: Offstage(),
items: [
// TODO: favourite
DropdownMenuItem(
child: Text('/'),
value: '/',
)
],
onChanged: (path) {
if (path is String && path.isNotEmpty) {
openDirectory(path, isLocal: isLocal);
ActionIcon(
message: "",
icon: Icons.arrow_drop_down,
onTap: () async {
final renderBox = locationBarKey.currentContext
?.findRenderObject() as RenderBox;
locationBarKey.currentContext?.size;
final size = renderBox.size;
final offset = renderBox.localToGlobal(Offset.zero);
final x = offset.dx;
final y = offset.dy + size.height + 1;
final peerPlatform = (await bind.sessionGetPlatform(
id: _ffi.id, isRemote: !isLocal))
.toLowerCase();
final List<MenuEntryBase> menuItems;
if (peerPlatform == "windows") {
menuItems = [];
final loadingTag =
_ffi.dialogManager.showLoading("Waiting");
try {
final fd =
await model.fetchDirectory("/", isLocal, false);
for (var entry in fd.entries) {
menuItems.add(MenuEntryButton(
childBuilder: (TextStyle? style) => Text(
entry.name,
style: style,
),
proc: () {
openDirectory(entry.name, isLocal: isLocal);
Get.back();
}));
menuItems.add(MenuEntryDivider());
}
})
} finally {
_ffi.dialogManager.dismissByTag(loadingTag);
}
} else {
menuItems = [
MenuEntryButton(
childBuilder: (TextStyle? style) => Text(
'/',
style: style,
),
proc: () {
openDirectory('/', isLocal: isLocal);
Get.back();
}),
MenuEntryDivider()
];
}
mod_menu.showMenu(
context: context,
position: RelativeRect.fromLTRB(x, y, x, y),
elevation: 4,
items: menuItems
.map((e) => e.build(
context,
MenuConfig(
commonColor:
CustomPopupMenuTheme.commonColor,
height: CustomPopupMenuTheme.height,
dividerHeight:
CustomPopupMenuTheme.dividerHeight,
boxWidth: size.width)))
.expand((i) => i)
.toList());
},
iconSize: 20,
)
]);
}

View File

@ -99,12 +99,14 @@ class MenuConfig {
final double height;
final double dividerHeight;
final double? boxWidth;
final Color commonColor;
const MenuConfig(
{required this.commonColor,
this.height = kMinInteractiveDimension,
this.dividerHeight = 16.0});
this.dividerHeight = 16.0,
this.boxWidth});
}
abstract class MenuEntryBase<T> {
@ -190,12 +192,14 @@ class MenuEntryRadios<T> extends MenuEntryBase<T> {
return mod_menu.PopupMenuItem(
padding: EdgeInsets.zero,
height: conf.height,
child: Container(
width: conf.boxWidth,
child: TextButton(
child: Container(
padding: padding,
alignment: AlignmentDirectional.centerStart,
constraints:
BoxConstraints(minHeight: conf.height, maxHeight: conf.height),
constraints: BoxConstraints(
minHeight: conf.height, maxHeight: conf.height),
child: Row(
children: [
Text(
@ -232,7 +236,7 @@ class MenuEntryRadios<T> extends MenuEntryBase<T> {
}
setOption(opt.value);
},
),
)),
);
}
@ -285,12 +289,14 @@ class MenuEntrySubRadios<T> extends MenuEntryBase<T> {
return mod_menu.PopupMenuItem(
padding: EdgeInsets.zero,
height: conf.height,
child: Container(
width: conf.boxWidth,
child: TextButton(
child: Container(
padding: padding,
alignment: AlignmentDirectional.centerStart,
constraints:
BoxConstraints(minHeight: conf.height, maxHeight: conf.height),
constraints: BoxConstraints(
minHeight: conf.height, maxHeight: conf.height),
child: Row(
children: [
Text(
@ -326,7 +332,7 @@ class MenuEntrySubRadios<T> extends MenuEntryBase<T> {
}
setOption(opt.value);
},
),
)),
);
}
@ -401,6 +407,8 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
mod_menu.PopupMenuItem(
padding: EdgeInsets.zero,
height: conf.height,
child: Container(
width: conf.boxWidth,
child: TextButton(
child: Container(
padding: padding,
@ -449,7 +457,7 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
}
setOption(!curOption.value);
},
),
)),
)
];
}
@ -606,7 +614,9 @@ class MenuEntryButton<T> extends MenuEntryBase<T> {
fontSize: MenuConfig.fontSize,
fontWeight: FontWeight.normal);
super.enabled ??= true.obs;
return Obx(() => TextButton(
return Obx(() => Container(
width: conf.boxWidth,
child: TextButton(
onPressed: super.enabled!.value
? () {
if (super.dismissOnClicked && Navigator.canPop(context)) {
@ -623,7 +633,7 @@ class MenuEntryButton<T> extends MenuEntryBase<T> {
child: childBuilder(
super.enabled!.value ? enabledStyle : disabledStyle),
),
));
)));
}
@override

View File

@ -811,14 +811,16 @@ class ActionIcon extends StatelessWidget {
final IconData icon;
final Function() onTap;
final bool isClose;
final double? size;
final double iconSize;
final double boxSize;
const ActionIcon(
{Key? key,
required this.message,
required this.icon,
required this.onTap,
required this.isClose,
this.size})
this.isClose = false,
this.iconSize = _kActionIconSize,
this.boxSize = _kTabBarHeight - 1})
: super(key: key);
@override
@ -834,14 +836,14 @@ class ActionIcon extends StatelessWidget {
onHover: (value) => hover.value = value,
onTap: onTap,
child: SizedBox(
height: size ?? (_kTabBarHeight - 1),
width: size ?? (_kTabBarHeight - 1),
height: boxSize,
width: boxSize,
child: Icon(
icon,
color: hover.value && isClose
? Colors.white
: MyTheme.tabbar(context).unSelectedIconColor,
size: _kActionIconSize,
size: iconSize,
),
),
),

View File

@ -402,6 +402,10 @@ class FileModel extends ChangeNotifier {
}
}
Future<FileDirectory> fetchDirectory(path, isLocal, showHidden) async {
return await _fileFetcher.fetchDirectory(path, isLocal, showHidden);
}
void pushHistory(bool isLocal) {
final history = isLocal ? localHistory : remoteHistory;
final currPath = isLocal ? currentLocalDir.path : currentRemoteDir.path;