Improve inventory selection logic
This commit is contained in:
parent
5c61a89805
commit
f202ccdd75
3 changed files with 99 additions and 53 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue