Improve inventory selection logic

This commit is contained in:
Nutcake 2023-06-17 19:28:23 +02:00
parent 5c61a89805
commit f202ccdd75
3 changed files with 99 additions and 53 deletions

View file

@ -82,7 +82,9 @@ class InventoryClient extends ChangeNotifier {
childDir.children.addAll(records.map((record) => NeosDirectory.fromRecord(record: record, parent: childDir))); childDir.children.addAll(records.map((record) => NeosDirectory.fromRecord(record: record, parent: childDir)));
return childDir; return childDir;
}, },
); ).onError((error, stackTrace) {
return dir;
});
} }
notifyListeners(); notifyListeners();
} }

View file

@ -132,20 +132,42 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
mainAxisSpacing: 8), mainAxisSpacing: 8),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final record = paths[index]; final record = paths[index];
return PathInventoryTile( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 3.0),
child: PathInventoryTile(
record: record, record: record,
onPressed: () { selected: _selectedIds.contains(record.id),
onTap: _selectedIds.isEmpty
? () {
iClient.navigateTo(record); iClient.navigateTo(record);
}
: () {
setState(() {
if (_selectedIds.contains(record.id)) {
_selectedIds.remove(record.id);
} else {
_selectedIds.add(record.id);
}
});
}, },
onLongPress: () {
setState(() {
if (_selectedIds.contains(record.id)) {
_selectedIds.remove(record.id);
} else {
_selectedIds.add(record.id);
}
});
},
),
); );
}, },
), ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
Padding( GridView.builder(
padding: const EdgeInsets.symmetric(horizontal: 8.0), padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: GridView.builder(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: objects.length, itemCount: objects.length,
@ -160,18 +182,28 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
return ObjectInventoryTile( return ObjectInventoryTile(
record: record, record: record,
selected: _selectedIds.contains(record.id), selected: _selectedIds.contains(record.id),
onTap: () async { onTap: _selectedIds.isEmpty
? () async {
await Navigator.push( await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => PhotoView( builder: (context) => PhotoView(
minScale: PhotoViewComputedScale.contained, minScale: PhotoViewComputedScale.contained,
imageProvider: imageProvider: CachedNetworkImageProvider(
CachedNetworkImageProvider(Aux.neosDbToHttp(record.thumbnailUri)), Aux.neosDbToHttp(record.thumbnailUri)),
heroAttributes: PhotoViewHeroAttributes(tag: record.id), heroAttributes: PhotoViewHeroAttributes(tag: record.id),
), ),
), ),
); );
}
: () async {
setState(() {
if (_selectedIds.contains(record.id)) {
_selectedIds.remove(record.id);
} else {
_selectedIds.add(record.id);
}
});
}, },
onLongPress: () async { onLongPress: () async {
setState(() { setState(() {
@ -185,25 +217,28 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
); );
}, },
), ),
),
], ],
), ),
Align( Align(
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: const Duration(milliseconds: 250), duration: const Duration(milliseconds: 250),
child: snapshot.connectionState == ConnectionState.waiting ? const LinearProgressIndicator() : null, child: snapshot.connectionState == ConnectionState.waiting
? const LinearProgressIndicator()
: null,
), ),
), ),
Align( Align(
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: const Duration(milliseconds: 250), duration: const Duration(milliseconds: 250),
child: snapshot.connectionState == ConnectionState.waiting ? Container( child: snapshot.connectionState == ConnectionState.waiting
? Container(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
color: Colors.black38, color: Colors.black38,
) : null, )
: null,
), ),
) )
], ],

View file

@ -3,20 +3,29 @@ import 'package:contacts_plus_plus/widgets/formatted_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class PathInventoryTile extends StatelessWidget { class PathInventoryTile extends StatelessWidget {
const PathInventoryTile({required this.record, required this.onPressed, super.key}); const PathInventoryTile({required this.record, this.selected = false, this.onTap, this.onLongPress, super.key});
final Record record; final Record record;
final Function() onPressed; final Function()? onTap;
final Function()? onLongPress;
final bool selected;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OutlinedButton.icon( return OutlinedButton.icon(
style: TextButton.styleFrom( style: TextButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
side: BorderSide(
color: selected ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.outline,
width: 1,
),
foregroundColor: Theme.of(context).colorScheme.onSecondaryContainer, foregroundColor: Theme.of(context).colorScheme.onSecondaryContainer,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
), ),
onPressed: onPressed, onLongPress: onLongPress,
onPressed: onTap,
icon: record.recordType == RecordType.directory ? const Icon(Icons.folder) : const Icon(Icons.link), icon: record.recordType == RecordType.directory ? const Icon(Icons.folder) : const Icon(Icons.link),
label: FormattedText( label: FormattedText(
record.formattedName, record.formattedName,