selectedItems use obs state

This commit is contained in:
csf 2023-03-09 19:55:38 +09:00
parent 5ae3d33f3c
commit f5d0275bf3
2 changed files with 101 additions and 107 deletions

View File

@ -15,7 +15,6 @@ import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/models/file_model.dart'; import 'package:flutter_hbb/models/file_model.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:provider/provider.dart';
import 'package:wakelock/wakelock.dart'; import 'package:wakelock/wakelock.dart';
import '../../consts.dart'; import '../../consts.dart';
@ -701,10 +700,11 @@ class _FileManagerViewState extends State<FileManagerView> {
color: Theme.of(context).cardColor, color: Theme.of(context).cardColor,
hoverColor: Theme.of(context).hoverColor, hoverColor: Theme.of(context).hoverColor,
), ),
MenuButton( Obx(() => MenuButton(
onPressed: selectedItems.valid() onPressed: SelectedItems.valid(selectedItems.items)
? () async { ? () async {
await (controller.removeAction(selectedItems)); await (controller
.removeAction(selectedItems));
selectedItems.clear(); selectedItems.clear();
} }
: null, : null,
@ -714,23 +714,24 @@ class _FileManagerViewState extends State<FileManagerView> {
), ),
color: Theme.of(context).cardColor, color: Theme.of(context).cardColor,
hoverColor: Theme.of(context).hoverColor, hoverColor: Theme.of(context).hoverColor,
), )),
menu(isLocal: isLocal), menu(isLocal: isLocal),
], ],
), ),
), ),
ElevatedButton.icon( Obx(() => ElevatedButton.icon(
style: ButtonStyle( style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(isLocal padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
isLocal
? EdgeInsets.only(left: 10) ? EdgeInsets.only(left: 10)
: EdgeInsets.only(right: 10)), : EdgeInsets.only(right: 10)),
backgroundColor: MaterialStateProperty.all( backgroundColor: MaterialStateProperty.all(
selectedItems.length == 0 selectedItems.items.isEmpty
? MyTheme.accent80 ? MyTheme.accent80
: MyTheme.accent, : MyTheme.accent,
), ),
), ),
onPressed: selectedItems.valid() onPressed: SelectedItems.valid(selectedItems.items)
? () { ? () {
final otherSideData = final otherSideData =
controller.getOtherSideDirectoryData(); controller.getOtherSideDirectoryData();
@ -743,8 +744,9 @@ class _FileManagerViewState extends State<FileManagerView> {
translate('Send'), translate('Send'),
textAlign: TextAlign.right, textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
color: selectedItems.length == 0 color: selectedItems.items.isEmpty
? Theme.of(context).brightness == Brightness.light ? Theme.of(context).brightness ==
Brightness.light
? MyTheme.grayBg ? MyTheme.grayBg
: MyTheme.darkGray : MyTheme.darkGray
: Colors.white, : Colors.white,
@ -754,8 +756,9 @@ class _FileManagerViewState extends State<FileManagerView> {
quarterTurns: 2, quarterTurns: 2,
child: SvgPicture.asset( child: SvgPicture.asset(
"assets/arrow.svg", "assets/arrow.svg",
color: selectedItems.length == 0 color: selectedItems.items.isEmpty
? Theme.of(context).brightness == Brightness.light ? Theme.of(context).brightness ==
Brightness.light
? MyTheme.grayBg ? MyTheme.grayBg
: MyTheme.darkGray : MyTheme.darkGray
: Colors.white, : Colors.white,
@ -765,8 +768,9 @@ class _FileManagerViewState extends State<FileManagerView> {
label: isLocal label: isLocal
? SvgPicture.asset( ? SvgPicture.asset(
"assets/arrow.svg", "assets/arrow.svg",
color: selectedItems.length == 0 color: selectedItems.items.isEmpty
? Theme.of(context).brightness == Brightness.light ? Theme.of(context).brightness ==
Brightness.light
? MyTheme.grayBg ? MyTheme.grayBg
: MyTheme.darkGray : MyTheme.darkGray
: Colors.white, : Colors.white,
@ -774,14 +778,15 @@ class _FileManagerViewState extends State<FileManagerView> {
: Text( : Text(
translate('Receive'), translate('Receive'),
style: TextStyle( style: TextStyle(
color: selectedItems.length == 0 color: selectedItems.items.isEmpty
? Theme.of(context).brightness == Brightness.light ? Theme.of(context).brightness ==
Brightness.light
? MyTheme.grayBg ? MyTheme.grayBg
: MyTheme.darkGray : MyTheme.darkGray
: Colors.white, : Colors.white,
), ),
), ),
), )),
], ],
).marginOnly(top: 8.0) ).marginOnly(top: 8.0)
], ],
@ -814,7 +819,7 @@ class _FileManagerViewState extends State<FileManagerView> {
MenuEntryButton( MenuEntryButton(
childBuilder: (style) => childBuilder: (style) =>
Text(translate("Unselect All"), style: style), Text(translate("Unselect All"), style: style),
proc: () => setState(() => selectedItems.clear()), proc: () => selectedItems.clear(),
padding: kDesktopMenuPadding, padding: kDesktopMenuPadding,
dismissOnClicked: true) dismissOnClicked: true)
]; ];
@ -864,7 +869,7 @@ class _FileManagerViewState extends State<FileManagerView> {
onNext: (buffer) { onNext: (buffer) {
debugPrint("searching next for $buffer"); debugPrint("searching next for $buffer");
assert(buffer.length == 1); assert(buffer.length == 1);
assert(selectedItems.length <= 1); assert(selectedItems.items.length <= 1);
var skipCount = 0; var skipCount = 0;
if (selectedItems.items.isNotEmpty) { if (selectedItems.items.isNotEmpty) {
final index = entries.indexOf(selectedItems.items.first); final index = entries.indexOf(selectedItems.items.first);
@ -883,7 +888,7 @@ class _FileManagerViewState extends State<FileManagerView> {
(element) => element.name.toLowerCase().startsWith(buffer)); (element) => element.name.toLowerCase().startsWith(buffer));
} }
if (searchResult.isEmpty) { if (searchResult.isEmpty) {
setState(() => selectedItems.clear()); selectedItems.clear();
return; return;
} }
_jumpToEntry(isLocal, searchResult.first, scrollController, _jumpToEntry(isLocal, searchResult.first, scrollController,
@ -896,7 +901,7 @@ class _FileManagerViewState extends State<FileManagerView> {
.where((element) => element.name.toLowerCase().startsWith(buffer)); .where((element) => element.name.toLowerCase().startsWith(buffer));
selectedEntries.clear(); selectedEntries.clear();
if (searchResult.isEmpty) { if (searchResult.isEmpty) {
setState(() => selectedItems.clear()); selectedItems.clear();
return; return;
} }
_jumpToEntry(isLocal, searchResult.first, scrollController, _jumpToEntry(isLocal, searchResult.first, scrollController,
@ -915,12 +920,11 @@ class _FileManagerViewState extends State<FileManagerView> {
final lastModifiedStr = entry.isDrive final lastModifiedStr = entry.isDrive
? " " ? " "
: "${entry.lastModified().toString().replaceAll(".000", "")} "; : "${entry.lastModified().toString().replaceAll(".000", "")} ";
final isSelected = selectedItems.contains(entry);
return Padding( return Padding(
padding: EdgeInsets.symmetric(vertical: 1), padding: EdgeInsets.symmetric(vertical: 1),
child: Container( child: Obx(() => Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected color: selectedItems.items.contains(entry)
? Theme.of(context).hoverColor ? Theme.of(context).hoverColor
: Theme.of(context).cardColor, : Theme.of(context).cardColor,
borderRadius: BorderRadius.all( borderRadius: BorderRadius.all(
@ -1025,7 +1029,7 @@ class _FileManagerViewState extends State<FileManagerView> {
), ),
), ),
], ],
)), ))),
); );
}).toList(growable: false); }).toList(growable: false);
@ -1077,10 +1081,8 @@ class _FileManagerViewState extends State<FileManagerView> {
entries.indexOf(searchResult.first) * rowHeight), entries.indexOf(searchResult.first) * rowHeight),
scrollController.position.maxScrollExtent); scrollController.position.maxScrollExtent);
scrollController.jumpTo(offset); scrollController.jumpTo(offset);
setState(() {
selectedEntries.add(searchResult.first); selectedEntries.add(searchResult.first);
debugPrint("focused on ${searchResult.first.name}"); debugPrint("focused on ${searchResult.first.name}");
});
} }
void _onSelectedChanged(SelectedItems selectedItems, List<Entry> entries, void _onSelectedChanged(SelectedItems selectedItems, List<Entry> entries,
@ -1090,7 +1092,7 @@ class _FileManagerViewState extends State<FileManagerView> {
final isShiftDown = final isShiftDown =
RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftLeft); RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftLeft);
if (isCtrlDown) { if (isCtrlDown) {
if (selectedItems.contains(entry)) { if (selectedItems.items.contains(entry)) {
selectedItems.remove(entry); selectedItems.remove(entry);
} else { } else {
selectedItems.add(entry); selectedItems.add(entry);

View File

@ -1052,40 +1052,32 @@ class DirectoryOptions {
class SelectedItems { class SelectedItems {
final bool isLocal; final bool isLocal;
final List<Entry> _items = []; final items = RxList<Entry>.empty(growable: true);
List<Entry> get items => _items;
int get length => _items.length;
SelectedItems({required this.isLocal}); SelectedItems({required this.isLocal});
void add(Entry e) { void add(Entry e) {
if (e.isDrive) return; if (e.isDrive) return;
if (!_items.contains(e)) { if (!items.contains(e)) {
_items.add(e); items.add(e);
} }
} }
bool contains(Entry e) {
return _items.contains(e);
}
void remove(Entry e) { void remove(Entry e) {
_items.remove(e); items.remove(e);
} }
void clear() { void clear() {
_items.clear(); items.clear();
} }
void selectAll(List<Entry> entries) { void selectAll(List<Entry> entries) {
_items.clear(); items.clear();
_items.addAll(entries); items.addAll(entries);
} }
bool valid() { static bool valid(RxList<Entry> items) {
if (length > 0) { if (items.isNotEmpty) {
// exclude DirDrive type // exclude DirDrive type
return items.any((item) => !item.isDrive); return items.any((item) => !item.isDrive);
} }