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)));
return childDir;
},
);
).onError((error, stackTrace) {
return dir;
});
}
notifyListeners();
}

View file

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

View file

@ -3,20 +3,29 @@ import 'package:contacts_plus_plus/widgets/formatted_text.dart';
import 'package:flutter/material.dart';
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 Function() onPressed;
final Function()? onTap;
final Function()? onLongPress;
final bool selected;
@override
Widget build(BuildContext context) {
return OutlinedButton.icon(
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,
alignment: Alignment.centerLeft,
),
onPressed: onPressed,
onLongPress: onLongPress,
onPressed: onTap,
icon: record.recordType == RecordType.directory ? const Icon(Icons.folder) : const Icon(Icons.link),
label: FormattedText(
record.formattedName,