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