second draft
This commit is contained in:
@@ -20,6 +20,8 @@ class ListsPage extends StatefulWidget {
|
||||
class _ListsPageState extends State<ListsPage> {
|
||||
late Future<List<Liste>> _listsFuture;
|
||||
StreamSubscription? _listsSubscription;
|
||||
Map<String, String> _layoutNameById = {};
|
||||
bool _layoutsLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -39,6 +41,25 @@ class _ListsPageState extends State<ListsPage> {
|
||||
void _loadLists() {
|
||||
_listsFuture = apiService.getLists();
|
||||
setState(() {});
|
||||
_refreshLayoutCache();
|
||||
}
|
||||
|
||||
Future<void> _refreshLayoutCache() async {
|
||||
if (!mounted) return;
|
||||
setState(() => _layoutsLoading = true);
|
||||
try {
|
||||
final layouts = await apiService.getStoreLayouts();
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_layoutNameById = {
|
||||
for (final layout in layouts) layout.id: layout.name,
|
||||
};
|
||||
_layoutsLoading = false;
|
||||
});
|
||||
} catch (_) {
|
||||
if (!mounted) return;
|
||||
setState(() => _layoutsLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showListMenu(Liste list) async {
|
||||
@@ -46,6 +67,13 @@ class _ListsPageState extends State<ListsPage> {
|
||||
context: context,
|
||||
builder: (c) => Wrap(
|
||||
children: <Widget>[
|
||||
if (list.owner == apiService.userId)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.store_mall_directory_outlined),
|
||||
title: const Text('Layout zuordnen'),
|
||||
onTap: () => Navigator.pop(c, 'layout'),
|
||||
),
|
||||
if (list.owner == apiService.userId) const Divider(height: 0),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.edit),
|
||||
title: const Text('Umbenennen'),
|
||||
@@ -62,11 +90,107 @@ class _ListsPageState extends State<ListsPage> {
|
||||
|
||||
if (result == 'edit') {
|
||||
_editList(list);
|
||||
} else if (result == 'layout') {
|
||||
_assignLayout(list);
|
||||
} else if (result == 'delete') {
|
||||
_deleteList(list);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _assignLayout(Liste list) async {
|
||||
if (list.owner != apiService.userId) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Nur Besitzer können Layouts zuordnen.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<StoreLayout> layouts = [];
|
||||
try {
|
||||
layouts = await apiService.getStoreLayouts();
|
||||
if (!mounted) return;
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Layouts konnten nicht geladen werden: $e')),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const String noLayoutOption = '__no_layout__';
|
||||
final String? currentId = list.layoutId;
|
||||
|
||||
final String? selection = await showModalBottomSheet<String>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SafeArea(
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.close),
|
||||
title: const Text('Kein Layout zuordnen'),
|
||||
trailing: currentId == null
|
||||
? const Icon(Icons.check, size: 20)
|
||||
: null,
|
||||
onTap: () => Navigator.pop(context, noLayoutOption),
|
||||
),
|
||||
if (layouts.isNotEmpty) const Divider(height: 0),
|
||||
if (layouts.isEmpty)
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Text('Keine Layouts verfügbar.'),
|
||||
),
|
||||
...layouts.map((layout) {
|
||||
return ListTile(
|
||||
leading: Icon(
|
||||
layout.owner == apiService.userId
|
||||
? Icons.store_mall_directory
|
||||
: Icons.share,
|
||||
),
|
||||
title: Text(layout.name),
|
||||
subtitle: layout.address != null && layout.address!.isNotEmpty
|
||||
? Text(layout.address!)
|
||||
: null,
|
||||
trailing: currentId == layout.id
|
||||
? const Icon(Icons.check, size: 20)
|
||||
: null,
|
||||
onTap: () => Navigator.pop(context, layout.id),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
if (selection == null) return;
|
||||
|
||||
final String? newLayoutId = selection == noLayoutOption ? null : selection;
|
||||
if (newLayoutId == currentId) return;
|
||||
|
||||
try {
|
||||
await apiService.updateList(
|
||||
list.id,
|
||||
layoutId: newLayoutId,
|
||||
clearLayout: newLayoutId == null,
|
||||
);
|
||||
list.layoutId = newLayoutId;
|
||||
_loadLists();
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Layout konnte nicht gespeichert werden: $e')),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _editList(Liste list) async {
|
||||
final TextEditingController titleCtl = TextEditingController(
|
||||
text: list.title,
|
||||
@@ -243,10 +367,39 @@ class _ListsPageState extends State<ListsPage> {
|
||||
itemCount: lists.length,
|
||||
itemBuilder: (c, i) {
|
||||
final l = lists[i];
|
||||
final String? layoutName = l.layoutId != null
|
||||
? _layoutNameById[l.layoutId!]
|
||||
: null;
|
||||
final String? subtitle = layoutName != null
|
||||
? 'Layout: $layoutName'
|
||||
: l.layoutId != null
|
||||
? (_layoutsLoading
|
||||
? 'Layout wird geladen...'
|
||||
: 'Layout-ID: ${l.layoutId}')
|
||||
: null;
|
||||
Widget? trailing;
|
||||
if (l.owner == apiService.userId) {
|
||||
trailing = IconButton(
|
||||
tooltip: l.layoutId != null
|
||||
? 'Layout wechseln'
|
||||
: 'Layout zuordnen',
|
||||
icon: Icon(
|
||||
l.layoutId != null
|
||||
? Icons.store_mall_directory
|
||||
: Icons.store_mall_directory_outlined,
|
||||
),
|
||||
onPressed: () => _assignLayout(l),
|
||||
);
|
||||
} else if (l.layoutId != null) {
|
||||
trailing = const Icon(Icons.store_mall_directory_outlined);
|
||||
}
|
||||
|
||||
return ListTile(
|
||||
title: Text(l.title),
|
||||
subtitle: subtitle != null ? Text(subtitle) : null,
|
||||
onTap: () => _openList(l),
|
||||
onLongPress: () => _showListMenu(l),
|
||||
trailing: trailing,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user