Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
feat(dragAndDrop): add Drag and drop feature (#334)
Browse files Browse the repository at this point in the history
  • Loading branch information
PiotrFLEURY authored Oct 9, 2020
1 parent 2dfa03a commit ba1c4e8
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 240 deletions.
30 changes: 14 additions & 16 deletions lib/dao/wishlist_dao.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:MobileOne/data/owner_details.dart';
import 'package:MobileOne/data/wishlist_item.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

Expand Down Expand Up @@ -271,24 +272,13 @@ class WishlistDao {
}

Future<void> updateItemInList({
@required String itemUuid,
@required String name,
@required int count,
@required int typeIndex,
@required String imageLink,
@required String listUuid,
@required String imageName,
@required WishlistItem item,
}) async {
await FirebaseFirestore.instance.collection("items").doc(listUuid).update({
itemUuid: {
'label': name,
'quantity': count,
'unit': typeIndex,
'image': imageLink,
'isValidated': false,
'imageName': imageName,
}
});
await FirebaseFirestore.instance
.collection("items")
.doc(listUuid)
.update({item.uuid: item.toMap()});
}

Future<void> deleteItemInList({
Expand Down Expand Up @@ -461,4 +451,12 @@ class WishlistDao {
SetOptions(merge: true),
);
}

void updateItems(String listUuid, List<WishlistItem> items) async {
var data = Map.fromEntries(items.map((e) => MapEntry(e.uuid, e.toMap())));
await FirebaseFirestore.instance
.collection("items")
.doc(listUuid)
.update(data);
}
}
16 changes: 16 additions & 0 deletions lib/data/wishlist_item.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:collection';

class WishlistItem {
String uuid;
String imageUrl;
Expand All @@ -6,6 +8,7 @@ class WishlistItem {
int quantity;
int unit;
String imageName;
int order = 0;

WishlistItem();

Expand All @@ -17,6 +20,19 @@ class WishlistItem {
this.quantity = map["quantity"];
this.unit = map["unit"];
this.imageName = map["imageName"];
this.order = map["order"] ?? 0;
}

Map<String, dynamic> toMap() {
Map<String, dynamic> map = new HashMap<String, dynamic>();
map["image"] = this.imageUrl;
map["isValidated"] = this.isValidated;
map["label"] = this.label;
map["quantity"] = this.quantity;
map["unit"] = this.unit;
map["imageName"] = this.imageName;
map["order"] = this.order ?? 0;
return map;
}

bool hasImage() => imageUrl != null && imageUrl.isNotEmpty;
Expand Down
177 changes: 89 additions & 88 deletions lib/pages/openedListPage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import 'package:flutter_material_color_picker/flutter_material_color_picker.dart
import 'package:get_it/get_it.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:reorderables/reorderables.dart';
import '../localization/localization.dart';
import 'package:MobileOne/utility/colors.dart';

Expand Down Expand Up @@ -77,22 +78,24 @@ class OpenedListPageState extends State<OpenedListPage>
}
_myController.text = wishlist?.label ?? "";
return content(
wishlist, itemsListProvider.getItemList(_args.listUuid));
wishlist,
itemsListProvider.getItemList(_args.listUuid),
itemsListProvider);
});
},
),
);
}

Widget content(Wishlist wishlistHead, List<WishlistItem> items) {
Widget content(Wishlist wishlistHead, List<WishlistItem> items, provider) {
return SafeArea(
child: Scaffold(
backgroundColor: _colorsApp.colorTheme,
floatingActionButton: buildFloatingActionButton(wishlistHead),
body: CustomScrollView(
slivers: <Widget>[
buildAppBar(context, wishlistHead),
buildList(context, items, wishlistHead),
buildList(context, items, wishlistHead, provider),
],
),
),
Expand All @@ -117,92 +120,90 @@ class OpenedListPageState extends State<OpenedListPage>
);
}

Widget buildList(
BuildContext context, List<WishlistItem> items, Wishlist wishlistHead) {
return items == null
? SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Center(
child: Text(getString(context, "loading")),
),
childCount: 1,
))
: items.length > 0
? SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
child: Dismissible(
confirmDismiss: (DismissDirection direction) async {
if (direction == DismissDirection.endToStart) {
return await buildDeleteShowDialog(context);
} else {
await validateItem(
listUuid: wishlistHead.uuid,
item: items[index],
);
_analytics.sendAnalyticsEvent("check_item");
return false;
}
},
background: Padding(
padding: const EdgeInsets.only(top: 10.0, left: 10),
child: Container(
decoration: BoxDecoration(
color: GREEN,
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Icon(
Icons.check,
color: WHITE,
)),
),
),
),
secondaryBackground: Padding(
padding: const EdgeInsets.only(top: 10.0, right: 10),
child: Container(
decoration: BoxDecoration(
color: RED,
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
child: Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(
Icons.delete,
color: WHITE,
)),
),
),
),
key: UniqueKey(),
child: WidgetItem(
items[index], wishlistHead.uuid, items[index].uuid),
onDismissed: (direction) {
if (direction == DismissDirection.endToStart) {
deleteItemFromList(
listUuid: wishlistHead.uuid,
itemUuid: items[index].uuid,
imageName: items[index].imageName);
_analytics.sendAnalyticsEvent("delete_item");
}
}),
),
childCount: items.length,
),
)
: SliverToBoxAdapter(
child: emptyList(),
Widget buildList(BuildContext context, List<WishlistItem> items,
Wishlist wishlistHead, ItemsListProvider provider) {
var listItems = buildListItems(wishlistHead, items);
return listItems.length > 0
? ReorderableSliverList(
delegate: ReorderableSliverChildListDelegate(listItems),
onReorder: (int oldIndex, int newIndex) {
provider.onReorder(wishlistHead.uuid, oldIndex, newIndex);
},
)
: SliverToBoxAdapter(
child: emptyList(),
);
}

List<Widget> buildListItems(wishlistHead, List<WishlistItem> items) {
if (items == null) {
return List.generate(1, (index) => Text(getString(context, "loading")));
}
return List.generate(
items.length, (index) => buildListItem(wishlistHead, items, index));
}

Widget buildListItem(wishlistHead, items, index) {
return Container(
child: Dismissible(
confirmDismiss: (DismissDirection direction) async {
if (direction == DismissDirection.endToStart) {
return await buildDeleteShowDialog(context);
} else {
await validateItem(
listUuid: wishlistHead.uuid,
item: items[index],
);
_analytics.sendAnalyticsEvent("check_item");
return false;
}
},
background: Container(
decoration: BoxDecoration(
color: GREEN,
borderRadius: BorderRadius.all(
Radius.circular(0),
),
),
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(left: 24.0),
child: Icon(
Icons.check,
color: WHITE,
)),
),
),
secondaryBackground: Container(
decoration: BoxDecoration(
color: RED,
borderRadius: BorderRadius.all(
Radius.circular(0),
),
),
child: Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.only(right: 24.0),
child: Icon(
Icons.delete,
color: WHITE,
)),
),
),
key: UniqueKey(),
child: WidgetItem(items[index], wishlistHead.uuid, items[index].uuid),
onDismissed: (direction) {
if (direction == DismissDirection.endToStart) {
deleteItemFromList(
listUuid: wishlistHead.uuid,
itemUuid: items[index].uuid,
imageName: items[index].imageName);
_analytics.sendAnalyticsEvent("delete_item");
}
}),
);
}

void openColorPicker(Widget content, String wishlistUuid) {
Expand Down
5 changes: 5 additions & 0 deletions lib/providers/itemsList_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,9 @@ class ItemsListProvider with ChangeNotifier {
fireUpdate() {
notifyListeners();
}

void onReorder(String listUuid, int oldIndex, int newIndex) {
wishlistService.reorder(listUuid, oldIndex, newIndex);
notifyListeners();
}
}
67 changes: 40 additions & 27 deletions lib/services/wishlist_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,18 @@ class WishlistService {
List<WishlistItem> sortItemsInList(List<WishlistItem> itemList) {
if (itemList != null) {
itemList.sort((a, b) {
if (a.isValidated == b.isValidated) {
if (a.label != null && b.label != null) {
return a.label.toLowerCase().compareTo(b.label.toLowerCase());
}
return 0;
} else if (a.isValidated) {
return 1;
} else {
return -1;
if (a.isValidated != b.isValidated) {
return a.isValidated ? 1 : -1;
}

if (a.order != b.order) {
return a.order.compareTo(b.order);
}

String aLabel = a.label?.toLowerCase() ?? "";
String bLabel = b.label?.toLowerCase() ?? "";

return aLabel.compareTo(bLabel);
});
}

Expand Down Expand Up @@ -208,22 +210,15 @@ class WishlistService {
@required String listUuid,
@required String imageName,
}) async {
WishlistItem oldItem =
WishlistItem editedItem =
_itemlists[listUuid].where((element) => element.uuid == itemUuid).first;
oldItem.imageName = imageName;
oldItem.imageUrl = imageLink;
oldItem.isValidated = false;
oldItem.label = name;
oldItem.quantity = count;
oldItem.unit = typeIndex;
await dao.updateItemInList(
itemUuid: itemUuid,
name: name,
count: count,
typeIndex: typeIndex,
imageLink: imageLink,
listUuid: listUuid,
imageName: imageName);
editedItem.imageName = imageName;
editedItem.imageUrl = imageLink;
editedItem.isValidated = false;
editedItem.label = name;
editedItem.quantity = count;
editedItem.unit = typeIndex;
await dao.updateItemInList(listUuid: listUuid, item: editedItem);
await fetchItemList(listUuid);
}

Expand All @@ -245,9 +240,13 @@ class WishlistService {
@required String itemUuid,
@required bool isValidated,
}) async {
dao.validateItem(
listUuid: listUuid, itemUuid: itemUuid, isValidated: isValidated);
await fetchItemList(listUuid);
_itemlists[listUuid]
.firstWhere((element) => element.uuid == itemUuid)
?.isValidated = isValidated;
dao
.validateItem(
listUuid: listUuid, itemUuid: itemUuid, isValidated: isValidated)
.then((value) => fetchItemList(listUuid));
}

List<dynamic> filterLists(String filterText) {
Expand Down Expand Up @@ -334,4 +333,18 @@ class WishlistService {
.where((element) => element.categoryId == categoryId)
.toList();
}

void reorder(String listUuid, int oldIndex, int newIndex) {
var items = _itemlists[listUuid];
items.insert(newIndex, items.removeAt(oldIndex));
items
.asMap()
.map((key, value) {
return MapEntry(key, value.order = key);
})
.values
.forEach((element) {
dao.updateItems(listUuid, items);
});
}
}
Loading

0 comments on commit ba1c4e8

Please sign in to comment.