Error messages
This commit is contained in:
@@ -2,6 +2,7 @@ import 'package:briessenchecker/models/checklist.dart';
|
||||
import 'package:briessenchecker/pages/detail_checklist_page.dart';
|
||||
import 'package:briessenchecker/services/checklist_provider.dart';
|
||||
import 'package:briessenchecker/services/dbhelper.dart';
|
||||
import 'package:briessenchecker/services/scaffold_messenger.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
@@ -87,8 +88,12 @@ class _DashboardPageState extends State<DashboardPage> {
|
||||
}
|
||||
|
||||
void _onDeleteTapped() {
|
||||
DbHelper.deleteChecklistByid(
|
||||
checklists.elementAt(_selectedChecklistIndex!).id);
|
||||
final checklist = checklists.elementAt(_selectedChecklistIndex!);
|
||||
DbHelper.deleteChecklistByid(checklist.id);
|
||||
if (!DbHelper.isOwner(checklist.ownerId)) {
|
||||
Messenger.showError(
|
||||
context, 'Can\'t delete checklists that aren\'t yours');
|
||||
}
|
||||
setState(() {
|
||||
_selectedChecklistIndex = null;
|
||||
});
|
||||
|
||||
@@ -2,9 +2,11 @@ import 'package:briessenchecker/models/checklist.dart';
|
||||
import 'package:briessenchecker/models/listitem.dart';
|
||||
import 'package:briessenchecker/services/checklist_provider.dart';
|
||||
import 'package:briessenchecker/services/dbhelper.dart';
|
||||
import 'package:briessenchecker/widgets/item_detail_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../services/scaffold_messenger.dart';
|
||||
import '../widgets/item_list_tile.dart';
|
||||
|
||||
class DetailChecklistPage extends StatefulWidget {
|
||||
@@ -78,69 +80,21 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
||||
void _addItemTapped() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => _itemDetailDialog(context, null));
|
||||
builder: (context) => ItemDetailDialog(checklistId: _checklist!.id));
|
||||
}
|
||||
|
||||
void _itemTapped(int index) {
|
||||
_selectedItemId = _items.elementAt(index).id;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => _itemDetailDialog(context, index)).whenComplete(
|
||||
builder: (context) => ItemDetailDialog(
|
||||
checklistId: _checklist!.id,
|
||||
item: _items.elementAt(index),
|
||||
)).whenComplete(
|
||||
() => _selectedItemId = null,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _itemDetailDialog(BuildContext context, int? index) {
|
||||
TextEditingController titleCon = TextEditingController();
|
||||
TextEditingController descCon = TextEditingController();
|
||||
if (_selectedItemId != null) {
|
||||
final item = _items.elementAt(index!);
|
||||
titleCon.text = item.title;
|
||||
descCon.text = item.description;
|
||||
}
|
||||
return AlertDialog(
|
||||
title: const Text('additem'),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: titleCon,
|
||||
textInputAction: TextInputAction.next,
|
||||
decoration: const InputDecoration(
|
||||
label: Text('Title'),
|
||||
),
|
||||
),
|
||||
TextFormField(
|
||||
controller: descCon,
|
||||
onFieldSubmitted: (value) =>
|
||||
_itemSaved(titleCon.text, descCon.text),
|
||||
decoration: const InputDecoration(
|
||||
label: Text('Description'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
_itemSaved(titleCon.text, descCon.text);
|
||||
},
|
||||
child: const Text('save'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _itemSaved(String title, String description) {
|
||||
DbHelper.addOrUpdateItem(
|
||||
_checklistProvider.selectedChecklistId!,
|
||||
title,
|
||||
description,
|
||||
_selectedItemId,
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
Widget? _itemListBuilder(BuildContext context, int index) {
|
||||
Item item = _items.elementAt(index);
|
||||
return ItemListTile(
|
||||
@@ -170,8 +124,17 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
||||
|
||||
void _onDeleteItemsPressed() {
|
||||
List<int> itemIds = [];
|
||||
bool showErrorPrompt = false;
|
||||
for (final itemIndex in selectedItemIndexes) {
|
||||
itemIds.add(_items.elementAt(itemIndex).id!);
|
||||
if (!showErrorPrompt) {
|
||||
showErrorPrompt =
|
||||
!DbHelper.isOwner(_items.elementAt(itemIndex).ownerId) &&
|
||||
!DbHelper.isOwner(_checklist!.ownerId);
|
||||
}
|
||||
}
|
||||
if (showErrorPrompt) {
|
||||
Messenger.showError(context, 'Can\'t delete items that aren\'t yours.');
|
||||
}
|
||||
DbHelper.deleteItemsById(itemIds);
|
||||
setState(() {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:briessenchecker/services/checklist_provider.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -185,11 +187,15 @@ class DbHelper {
|
||||
}
|
||||
|
||||
static Future<void> deleteItemById(int id) async {
|
||||
await _client.from(itemsTableName).delete().eq('id', id);
|
||||
await _client.from(itemsTableName).delete().eq('id', id).onError(_onError);
|
||||
}
|
||||
|
||||
static Future<void> deleteItemsById(List<int> ids) async {
|
||||
await _client.from(itemsTableName).delete().in_('id', ids);
|
||||
await _client
|
||||
.from(itemsTableName)
|
||||
.delete()
|
||||
.in_('id', ids)
|
||||
.onError(_onError);
|
||||
}
|
||||
|
||||
static Future<void> deleteChecklistByid(int id) async {
|
||||
@@ -201,6 +207,12 @@ class DbHelper {
|
||||
static Stream<AuthState> get authChangeEventStream =>
|
||||
_client.auth.onAuthStateChange;
|
||||
|
||||
static bool isOwner(String id) {
|
||||
return _client.auth.currentSession!.user.id == id;
|
||||
}
|
||||
|
||||
static User? get currentUser => _client.auth.currentUser;
|
||||
|
||||
static Stream<List<Map<String, dynamic>>> get checklistChangeEventStream =>
|
||||
_client.from(checklistsTableName).stream(primaryKey: ['id']);
|
||||
|
||||
@@ -245,4 +257,8 @@ class DbHelper {
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
static FutureOr _onError(Object error, StackTrace stackTrace) {
|
||||
print(error);
|
||||
}
|
||||
}
|
||||
|
||||
15
lib/services/scaffold_messenger.dart
Normal file
15
lib/services/scaffold_messenger.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Messenger {
|
||||
static void showError(BuildContext context, String error) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.error,
|
||||
content: Text(
|
||||
error,
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.onError),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
77
lib/widgets/item_detail_dialog.dart
Normal file
77
lib/widgets/item_detail_dialog.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../models/listitem.dart';
|
||||
import '../services/dbhelper.dart';
|
||||
|
||||
class ItemDetailDialog extends StatelessWidget {
|
||||
const ItemDetailDialog({
|
||||
super.key,
|
||||
this.item,
|
||||
required this.checklistId,
|
||||
});
|
||||
final Item? item;
|
||||
final int checklistId;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TextEditingController titleCon = TextEditingController();
|
||||
final TextEditingController descCon = TextEditingController();
|
||||
bool isOwner = true;
|
||||
String dialogTitle = 'Add item';
|
||||
|
||||
if (item != null) {
|
||||
titleCon.text = item!.title;
|
||||
descCon.text = item!.description;
|
||||
isOwner = DbHelper.isOwner(item!.ownerId);
|
||||
isOwner ? dialogTitle = 'Edit Item' : dialogTitle = item!.title;
|
||||
}
|
||||
|
||||
return AlertDialog(
|
||||
title: Text(dialogTitle),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (isOwner)
|
||||
TextFormField(
|
||||
controller: titleCon,
|
||||
textInputAction: TextInputAction.next,
|
||||
decoration: const InputDecoration(
|
||||
label: Text('Title'),
|
||||
),
|
||||
),
|
||||
if (isOwner)
|
||||
TextFormField(
|
||||
controller: descCon,
|
||||
onFieldSubmitted: (value) {
|
||||
_itemSaved(titleCon.text, descCon.text);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
decoration: const InputDecoration(
|
||||
label: Text('Description'),
|
||||
),
|
||||
),
|
||||
if (!isOwner) Text(item!.description),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
_itemSaved(titleCon.text, descCon.text);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: const Text('save'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _itemSaved(String title, String description) {
|
||||
DbHelper.addOrUpdateItem(
|
||||
checklistId,
|
||||
title,
|
||||
description,
|
||||
item?.id,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user