remove item&product confirmation dialog
Because there currently is no way to auto-refresh the lists it will appear as if nothing changed. Switching to a different tab and back again will update the list though
This commit is contained in:
parent
384fbb0573
commit
13c071b8ca
8 changed files with 872 additions and 611 deletions
|
@ -429,5 +429,12 @@
|
|||
"newItemQueryEmpty": "Type to show quick access buttons",
|
||||
"newItemQueryHint": "Type item or product name",
|
||||
"newItemQuickAccessPrefix": "Create:",
|
||||
"newItemQuickProduct": "product: {text}"
|
||||
"newItemQuickProduct": "product: {text}",
|
||||
"deleteItem": "Delete Item",
|
||||
"deleteItemConfirm": "Do you really want to remove the item named {item}",
|
||||
|
||||
"deleteProductTitle": "Delete Product",
|
||||
"deleteProductSubtitle": "Remove the product from list of known products",
|
||||
"deleteProduct": "Delete Product",
|
||||
"deleteProductConfirm": "DO you really want to remove the product named {product}"
|
||||
}
|
||||
|
|
|
@ -123,7 +123,12 @@ class _HomePageState extends State<HomePage> {
|
|||
)
|
||||
],
|
||||
),
|
||||
body: ListView.builder(
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 600),
|
||||
child: ListView.builder(
|
||||
itemCount: rooms.length,
|
||||
itemBuilder: (ctx, i) {
|
||||
final room = rooms[i];
|
||||
|
@ -134,27 +139,32 @@ class _HomePageState extends State<HomePage> {
|
|||
child: InkWell(
|
||||
onTap: () {
|
||||
// open room
|
||||
context.goNamed('room',
|
||||
params: {'server': room.serverTag, 'id': room.id});
|
||||
context.goNamed('room', params: {
|
||||
'server': room.serverTag,
|
||||
'id': room.id
|
||||
});
|
||||
},
|
||||
onLongPress: () {
|
||||
// open bottom sheet
|
||||
// NOTE: feature yet to be confirmed
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
|
||||
padding:
|
||||
const EdgeInsets.fromLTRB(10, 5, 5, 10),
|
||||
child: ListTile(
|
||||
title: Text(room.name),
|
||||
visualDensity: const VisualDensity(vertical: 3),
|
||||
visualDensity:
|
||||
const VisualDensity(vertical: 3),
|
||||
subtitle: Text(room.description),
|
||||
leading: AspectRatio(
|
||||
aspectRatio: 1 / 1,
|
||||
child: SvgPicture.asset("${room.icon?.img}"),
|
||||
child:
|
||||
SvgPicture.asset("${room.icon?.img}"),
|
||||
),
|
||||
hoverColor: Colors.transparent,
|
||||
))));
|
||||
},
|
||||
),
|
||||
)))),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
label: Text(AppLocalizations.of(context)!.addRoom),
|
||||
icon: const Icon(Icons.add),
|
||||
|
|
|
@ -138,7 +138,7 @@ class _EditItemPageState extends State<EditItemPage> {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 400),
|
||||
constraints: const BoxConstraints(maxWidth: 600),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
|
|
@ -33,6 +33,10 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 600),
|
||||
child: Column(children: [
|
||||
// room meta display
|
||||
...(widget.room != null)
|
||||
|
@ -65,7 +69,8 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
showSelectedIcon: true,
|
||||
multiSelectionEnabled: false,
|
||||
emptySelectionAllowed: false,
|
||||
segments: RoomVisibility.list().map((vis) {
|
||||
segments:
|
||||
RoomVisibility.list().map((vis) {
|
||||
return ButtonSegment<int>(
|
||||
value: vis.type,
|
||||
label: Text(vis.text(context)),
|
||||
|
@ -76,10 +81,14 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
// only show confirm dialog when user
|
||||
// is admin, owner or has CHANGE_ADMIN permission
|
||||
if (widget.info == null ||
|
||||
(!(widget.info?.isAdmin ?? false) &&
|
||||
!(widget.info?.isOwner ?? false) &&
|
||||
((widget.info?.permissions)! &
|
||||
RoomPermission.ota ==
|
||||
(!(widget.info?.isAdmin ??
|
||||
false) &&
|
||||
!(widget.info?.isOwner ??
|
||||
false) &&
|
||||
((widget.info
|
||||
?.permissions)! &
|
||||
RoomPermission
|
||||
.ota ==
|
||||
0))) {
|
||||
// action not permitted
|
||||
// NOTE: no error dialog should be shown
|
||||
|
@ -87,46 +96,65 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
return;
|
||||
}
|
||||
|
||||
final vis = RoomVisibility(vset.first);
|
||||
final vis =
|
||||
RoomVisibility(vset.first);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!
|
||||
title: Text(AppLocalizations
|
||||
.of(context)!
|
||||
.changeRoomVisibilityTitle),
|
||||
content: Text(
|
||||
AppLocalizations.of(context)!
|
||||
content: Text(AppLocalizations
|
||||
.of(context)!
|
||||
.changeRoomVisibilitySubtitle(
|
||||
vis.text(context))),
|
||||
vis.text(
|
||||
context))),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.cancel),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
final scaffMgr =
|
||||
ScaffoldMessenger.of(context);
|
||||
final nav = Navigator.of(context);
|
||||
final user = context.read<User>();
|
||||
ScaffoldMessenger
|
||||
.of(context);
|
||||
final nav =
|
||||
Navigator.of(
|
||||
context);
|
||||
final user = context
|
||||
.read<User>();
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
req: () => postWithCreadentials(
|
||||
path: 'setVisibility',
|
||||
target: user.server,
|
||||
doNetworkRequest(
|
||||
scaffMgr,
|
||||
req: () =>
|
||||
postWithCreadentials(
|
||||
path:
|
||||
'setVisibility',
|
||||
target: user
|
||||
.server,
|
||||
body: {
|
||||
'room': widget.room?.id,
|
||||
'room': widget
|
||||
.room
|
||||
?.id,
|
||||
'server': (widget
|
||||
.room?.serverTag)!,
|
||||
'visibility': vset.first
|
||||
.room
|
||||
?.serverTag)!,
|
||||
'visibility':
|
||||
vset.first
|
||||
},
|
||||
credentials: user),
|
||||
credentials:
|
||||
user),
|
||||
onOK: (_) {
|
||||
Room r = widget.room!;
|
||||
r.visibility = vis;
|
||||
Room r = widget
|
||||
.room!;
|
||||
r.visibility =
|
||||
vis;
|
||||
r.toDisk();
|
||||
},
|
||||
after: () {
|
||||
|
@ -134,13 +162,18 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
});
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.ok),
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.ok),
|
||||
)
|
||||
],
|
||||
));
|
||||
}),
|
||||
selected: {(widget.room?.visibility?.type)!},
|
||||
selectedIcon: Icon((widget.room?.visibility?.icon)!),
|
||||
selected: {
|
||||
(widget.room?.visibility?.type)!
|
||||
},
|
||||
selectedIcon: Icon(
|
||||
(widget.room?.visibility?.icon)!),
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
@ -161,10 +194,13 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
0)))
|
||||
? [
|
||||
ListTile(
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
trailing:
|
||||
const Icon(Icons.chevron_right),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.editRoomMetadata),
|
||||
subtitle: Text(AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)!
|
||||
.editRoomMetadata),
|
||||
subtitle: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.editRoomMetadataSubtitle),
|
||||
onTap: () {
|
||||
// show edit room screen
|
||||
|
@ -179,9 +215,10 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
// open members view
|
||||
ListTile(
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
title: Text(AppLocalizations.of(context)!.showRoomMembers),
|
||||
subtitle:
|
||||
Text(AppLocalizations.of(context)!.showRoomMembersSubtitle),
|
||||
title: Text(AppLocalizations.of(context)!
|
||||
.showRoomMembers),
|
||||
subtitle: Text(AppLocalizations.of(context)!
|
||||
.showRoomMembersSubtitle),
|
||||
onTap: () {
|
||||
// open member view screen
|
||||
context.goNamed('room-members', params: {
|
||||
|
@ -199,15 +236,20 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
0)))
|
||||
? [
|
||||
ListTile(
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
trailing:
|
||||
const Icon(Icons.chevron_right),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.editRoomPermissions),
|
||||
subtitle: Text(AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)!
|
||||
.editRoomPermissions),
|
||||
subtitle: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.editRoomPermissionsSubtitle),
|
||||
onTap: () {
|
||||
// show checkbox screen
|
||||
context.goNamed('room-permissions', params: {
|
||||
'server': (widget.room?.serverTag)!,
|
||||
context.goNamed('room-permissions',
|
||||
params: {
|
||||
'server':
|
||||
(widget.room?.serverTag)!,
|
||||
'id': (widget.room?.id)!
|
||||
});
|
||||
},
|
||||
|
@ -217,14 +259,18 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
...(widget.info != null &&
|
||||
((widget.info?.isAdmin ?? false) ||
|
||||
(widget.info?.isOwner ?? false) ||
|
||||
((widget.info?.permissions)! & RoomPermission.ota !=
|
||||
((widget.info?.permissions)! &
|
||||
RoomPermission.ota !=
|
||||
0)))
|
||||
? [
|
||||
ListTile(
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
title:
|
||||
Text(AppLocalizations.of(context)!.manageRoomOTA),
|
||||
subtitle: Text(AppLocalizations.of(context)!
|
||||
trailing:
|
||||
const Icon(Icons.chevron_right),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.manageRoomOTA),
|
||||
subtitle: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.manageRoomOTASubtitle),
|
||||
onTap: () {
|
||||
// show manage ota screen
|
||||
|
@ -235,14 +281,18 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
},
|
||||
),
|
||||
ListTile(
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
trailing:
|
||||
const Icon(Icons.chevron_right),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.manageRoomInvites),
|
||||
subtitle: Text(AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)!
|
||||
.manageRoomInvites),
|
||||
subtitle: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.manageRoomInvitesSubtitle),
|
||||
onTap: () {
|
||||
// show manage ota screen
|
||||
context.goNamed('room-invite', params: {
|
||||
context
|
||||
.goNamed('room-invite', params: {
|
||||
'server': (widget.room?.serverTag)!,
|
||||
'id': (widget.room?.id)!
|
||||
});
|
||||
|
@ -259,20 +309,30 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
padding: const EdgeInsets.all(8),
|
||||
child: FilledButton.tonal(
|
||||
child: Text(((widget.info?.isOwner)!)
|
||||
? AppLocalizations.of(context)!.deleteRoom
|
||||
: AppLocalizations.of(context)!.leaveRoom),
|
||||
? AppLocalizations.of(context)!
|
||||
.deleteRoom
|
||||
: AppLocalizations.of(context)!
|
||||
.leaveRoom),
|
||||
onPressed: () {
|
||||
// show confirm dialog
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: Text(((widget.info?.isOwner)!)
|
||||
? AppLocalizations.of(context)!.deleteRoom
|
||||
: AppLocalizations.of(context)!.leaveRoom),
|
||||
content: Text(((widget.info?.isOwner)!)
|
||||
? AppLocalizations.of(context)!
|
||||
title: Text(
|
||||
((widget.info?.isOwner)!)
|
||||
? AppLocalizations.of(
|
||||
context)!
|
||||
.deleteRoom
|
||||
: AppLocalizations.of(
|
||||
context)!
|
||||
.leaveRoom),
|
||||
content: Text(
|
||||
((widget.info?.isOwner)!)
|
||||
? AppLocalizations.of(
|
||||
context)!
|
||||
.deleteRoomConfirm
|
||||
: AppLocalizations.of(context)!
|
||||
: AppLocalizations.of(
|
||||
context)!
|
||||
.leaveRoomConfirm),
|
||||
actions: [
|
||||
TextButton(
|
||||
|
@ -281,47 +341,67 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
Navigator.of(ctx).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.cancel),
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.cancel),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
// send request
|
||||
final scaffMgr =
|
||||
ScaffoldMessenger.of(ctx);
|
||||
final nav = Navigator.of(ctx);
|
||||
final router = GoRouter.of(context);
|
||||
final user = context.read<User>();
|
||||
ScaffoldMessenger.of(
|
||||
ctx);
|
||||
final nav =
|
||||
Navigator.of(ctx);
|
||||
final router =
|
||||
GoRouter.of(context);
|
||||
final user =
|
||||
context.read<User>();
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
req: () => postWithCreadentials(
|
||||
path: ((widget.info?.isOwner)!)
|
||||
req: () =>
|
||||
postWithCreadentials(
|
||||
path: ((widget
|
||||
.info
|
||||
?.isOwner)!)
|
||||
? 'deleteRoom'
|
||||
: 'leaveRoom',
|
||||
target: user.server,
|
||||
target: user
|
||||
.server,
|
||||
body: {
|
||||
'room': widget.room?.id,
|
||||
'server':
|
||||
(widget.room?.serverTag)!,
|
||||
'room': widget
|
||||
.room
|
||||
?.id,
|
||||
'server': (widget
|
||||
.room
|
||||
?.serverTag)!,
|
||||
},
|
||||
credentials: user),
|
||||
credentials:
|
||||
user),
|
||||
onOK: (_) async {
|
||||
// try delete room from disk
|
||||
try {
|
||||
await widget.room?.removeDisk();
|
||||
await widget.room
|
||||
?.removeDisk();
|
||||
} catch (_) {}
|
||||
|
||||
// go back home
|
||||
router.pushReplacementNamed('home');
|
||||
router
|
||||
.pushReplacementNamed(
|
||||
'home');
|
||||
},
|
||||
after: () {
|
||||
// close popup
|
||||
nav.pop();
|
||||
});
|
||||
},
|
||||
child: Text(((widget.info?.isOwner)!)
|
||||
? AppLocalizations.of(context)!
|
||||
child: Text(((widget
|
||||
.info?.isOwner)!)
|
||||
? AppLocalizations.of(
|
||||
context)!
|
||||
.deleteRoomShort
|
||||
: AppLocalizations.of(context)!
|
||||
: AppLocalizations.of(
|
||||
context)!
|
||||
.leaveRoomShort),
|
||||
)
|
||||
],
|
||||
|
@ -330,6 +410,6 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
))
|
||||
]
|
||||
: [],
|
||||
])));
|
||||
])))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,12 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
.apply(displayColor: Theme.of(context).colorScheme.onSurface);
|
||||
|
||||
return Scaffold(
|
||||
body: ReorderableListView.builder(
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 600),
|
||||
child: ReorderableListView.builder(
|
||||
buildDefaultDragHandles: false,
|
||||
itemBuilder: (context, index) {
|
||||
final item = list[index];
|
||||
|
@ -75,7 +80,8 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
RoomPermission.editRoomContent !=
|
||||
0))
|
||||
? ReorderableDragStartListener(
|
||||
index: index, child: const Icon(Icons.drag_handle))
|
||||
index: index,
|
||||
child: const Icon(Icons.drag_handle))
|
||||
: null,
|
||||
title: Text(item.name),
|
||||
onTap: () {
|
||||
|
@ -99,20 +105,24 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.square_rounded,
|
||||
size: 48.0, color: item.color),
|
||||
Text(item.name, style: textTheme.titleLarge)
|
||||
Text(item.name,
|
||||
style: textTheme.titleLarge)
|
||||
],
|
||||
)),
|
||||
// edit category
|
||||
ListTile(
|
||||
leading: const Icon(Icons.edit),
|
||||
title: Text(AppLocalizations.of(context)!.editCategory),
|
||||
subtitle:
|
||||
Text(AppLocalizations.of(context)!.editCategoryLong),
|
||||
title: Text(AppLocalizations.of(context)!
|
||||
.editCategory),
|
||||
subtitle: Text(AppLocalizations.of(context)!
|
||||
.editCategoryLong),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () {
|
||||
// close the modal bottom sheet
|
||||
|
@ -131,9 +141,10 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
// delete category
|
||||
ListTile(
|
||||
leading: const Icon(Icons.delete),
|
||||
title: Text(AppLocalizations.of(context)!.deleteCategory),
|
||||
subtitle: Text(
|
||||
AppLocalizations.of(context)!.deleteCategoryLong),
|
||||
title: Text(AppLocalizations.of(context)!
|
||||
.deleteCategory),
|
||||
subtitle: Text(AppLocalizations.of(context)!
|
||||
.deleteCategoryLong),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () {
|
||||
// show popup
|
||||
|
@ -141,10 +152,13 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
icon: const Icon(Icons.delete),
|
||||
title: Text(AppLocalizations.of(context)!
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.deleteCategory),
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
.deleteCategoryConfirm(item.name)),
|
||||
content: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.deleteCategoryConfirm(
|
||||
item.name)),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
|
@ -152,30 +166,43 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
Navigator.of(ctx).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.cancel),
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.cancel),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
// send request
|
||||
final scaffMgr =
|
||||
ScaffoldMessenger.of(ctx);
|
||||
ScaffoldMessenger.of(
|
||||
ctx);
|
||||
// popup context
|
||||
final navInner = Navigator.of(ctx);
|
||||
final navInner =
|
||||
Navigator.of(ctx);
|
||||
// bottomsheet context
|
||||
final nav = Navigator.of(context);
|
||||
final user = context.read<User>();
|
||||
final nav =
|
||||
Navigator.of(context);
|
||||
final user =
|
||||
context.read<User>();
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
req: () => postWithCreadentials(
|
||||
path: 'deleteCategory',
|
||||
target: user.server,
|
||||
req: () =>
|
||||
postWithCreadentials(
|
||||
path:
|
||||
'deleteCategory',
|
||||
target:
|
||||
user.server,
|
||||
body: {
|
||||
'room': widget.room?.id,
|
||||
'server':
|
||||
widget.room?.serverTag,
|
||||
'listCatID': item.id
|
||||
'room': widget
|
||||
.room?.id,
|
||||
'server': widget
|
||||
.room
|
||||
?.serverTag,
|
||||
'listCatID':
|
||||
item.id
|
||||
},
|
||||
credentials: user),
|
||||
credentials:
|
||||
user),
|
||||
onOK: (_) async {
|
||||
// TODO: remove cached category
|
||||
fetchCategories();
|
||||
|
@ -187,7 +214,9 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
nav.pop();
|
||||
});
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
child: Text(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.deleteCategory),
|
||||
)
|
||||
],
|
||||
|
@ -205,7 +234,8 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
onReorder: (int oldIndex, int newIndex) {
|
||||
if (!((widget.info?.isAdmin ?? false) ||
|
||||
(widget.info?.isOwner ?? false) ||
|
||||
((widget.info?.permissions)! & RoomPermission.editRoomContent !=
|
||||
((widget.info?.permissions)! &
|
||||
RoomPermission.editRoomContent !=
|
||||
0))) {
|
||||
// user is not allowed to edit or delete categories
|
||||
return;
|
||||
|
@ -228,11 +258,12 @@ class _RoomCategoriesPageState extends State<RoomCategoriesPage> {
|
|||
body: {
|
||||
'room': widget.room?.id,
|
||||
'server': widget.room?.serverTag,
|
||||
'listCatIDs': list.map((item) => item.id).toList()
|
||||
'listCatIDs':
|
||||
list.map((item) => item.id).toList()
|
||||
}));
|
||||
});
|
||||
},
|
||||
),
|
||||
)))),
|
||||
floatingActionButton: (widget.info != null &&
|
||||
((widget.info?.isAdmin ?? false) ||
|
||||
(widget.info?.isOwner ?? false) ||
|
||||
|
|
|
@ -194,7 +194,12 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ListView(children: [
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 600),
|
||||
child: ListView(children: [
|
||||
LabeledDivider(AppLocalizations.of(context)!.shoppingList),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
|
@ -202,8 +207,8 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
|
|||
itemCount: list.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = list[index];
|
||||
final cat =
|
||||
categories[item.category] ?? RoomCategory.other(context);
|
||||
final cat = categories[item.category] ??
|
||||
RoomCategory.other(context);
|
||||
return ShoppingListItem(
|
||||
name: item.name,
|
||||
description: item.description,
|
||||
|
@ -253,8 +258,8 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
|
|||
physics: const ClampingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
final item = cart[index];
|
||||
final cat =
|
||||
categories[item.category] ?? RoomCategory.other(context);
|
||||
final cat = categories[item.category] ??
|
||||
RoomCategory.other(context);
|
||||
|
||||
return ShoppingListItem(
|
||||
name: item.name,
|
||||
|
@ -297,7 +302,7 @@ class _ShoppingListPageState extends State<ShoppingListPage> {
|
|||
});
|
||||
},
|
||||
)
|
||||
]),
|
||||
])))),
|
||||
floatingActionButton: (widget.info != null &&
|
||||
((widget.info?.isAdmin ?? false) ||
|
||||
(widget.info?.isOwner ?? false) ||
|
||||
|
@ -459,7 +464,60 @@ class ShoppingListItemInfo extends StatelessWidget {
|
|||
AppLocalizations.of(context)!.deleteItemSubtitle),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () {
|
||||
// TODO: show confirm dialog
|
||||
// show popup
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
icon: const Icon(Icons.delete),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.deleteItem),
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
.deleteItemConfirm(item.name)),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
// close popup
|
||||
Navigator.of(ctx).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.cancel),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
// send request
|
||||
final scaffMgr =
|
||||
ScaffoldMessenger.of(ctx);
|
||||
// popup context
|
||||
final navInner = Navigator.of(ctx);
|
||||
// bottomsheet context
|
||||
final nav = Navigator.of(context);
|
||||
final user = context.read<User>();
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
req: () => postWithCreadentials(
|
||||
path: 'deleteItem',
|
||||
target: user.server,
|
||||
body: {
|
||||
'room': room,
|
||||
'server': server,
|
||||
'listItemID': item.id
|
||||
},
|
||||
credentials: user),
|
||||
onOK: (_) async {
|
||||
// TODO: remove cached item
|
||||
},
|
||||
after: () {
|
||||
// close popup
|
||||
navInner.pop();
|
||||
// close modal bottom sheet
|
||||
nav.pop();
|
||||
});
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
.deleteItem),
|
||||
)
|
||||
],
|
||||
));
|
||||
}),
|
||||
]
|
||||
: [],
|
||||
|
|
|
@ -55,7 +55,12 @@ class _RoomProductsPageState extends State<RoomProductsPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ListView.builder(
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 600),
|
||||
child: ListView.builder(
|
||||
itemCount: products.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = products[index];
|
||||
|
@ -80,7 +85,7 @@ class _RoomProductsPageState extends State<RoomProductsPage> {
|
|||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
)))),
|
||||
floatingActionButton: (widget.info != null &&
|
||||
((widget.info?.isAdmin ?? false) ||
|
||||
(widget.info?.isOwner ?? false) ||
|
||||
|
|
|
@ -207,6 +207,76 @@ class _ViewProductPageState extends State<ViewProductPage> {
|
|||
},
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
),
|
||||
...(info != null &&
|
||||
((info?.isAdmin ?? false) ||
|
||||
(info?.isOwner ?? false) ||
|
||||
((info?.permissions)! & RoomPermission.editRoomContent !=
|
||||
0)))
|
||||
? [
|
||||
// delete product
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.deleteProductTitle),
|
||||
subtitle:
|
||||
Text(AppLocalizations.of(context)!.deleteProductSubtitle),
|
||||
onTap: () {
|
||||
// show popup
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
icon: const Icon(Icons.delete),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.deleteProduct),
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
.deleteProductConfirm(product?.name ?? "")),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
// close popup
|
||||
Navigator.of(ctx).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.cancel),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
// send request
|
||||
final scaffMgr = ScaffoldMessenger.of(ctx);
|
||||
// popup context
|
||||
final navInner = Navigator.of(ctx);
|
||||
// bottomsheet context
|
||||
final nav = Navigator.of(context);
|
||||
final user = context.read<User>();
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
req: () => postWithCreadentials(
|
||||
path: 'deleteProduct',
|
||||
target: user.server,
|
||||
body: {
|
||||
'room': widget.room,
|
||||
'server': widget.server,
|
||||
'listProdID': product?.id ?? ""
|
||||
},
|
||||
credentials: user),
|
||||
onOK: (_) async {
|
||||
// TODO: remove cached product
|
||||
},
|
||||
after: () {
|
||||
// close popup
|
||||
navInner.pop();
|
||||
// close modal bottom sheet
|
||||
nav.pop();
|
||||
});
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
.deleteProduct),
|
||||
)
|
||||
],
|
||||
));
|
||||
},
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
),
|
||||
]
|
||||
: []
|
||||
])),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue