Skip to content

Commit

Permalink
remade the orderable grid, added popup menu to allow deletion of item
Browse files Browse the repository at this point in the history
  • Loading branch information
namelessto committed Feb 22, 2024
1 parent d7793f4 commit 50785cc
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 144 deletions.
86 changes: 41 additions & 45 deletions lib/presentation/screens/misc/favorite_screen.dart
Original file line number Diff line number Diff line change
@@ -1,59 +1,55 @@
import 'package:context_menus/context_menus.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import '/analytics/analytics.dart';
import '/presentation/widgets/misc/orderable_grid.dart';
import '/utilities/favorite_state.dart';
import '/utilities/utils.dart';

class FavoriteScreen extends StatefulWidget {
const FavoriteScreen({super.key, required this.analyticsHelper});

class FavoriteScreen extends StatelessWidget {
FavoriteScreen({super.key, required this.analyticsHelper});
final AnalyticsHelper analyticsHelper;

@override
State<FavoriteScreen> createState() => _FavoriteScreenState();
}

class _FavoriteScreenState extends State<FavoriteScreen> {
final scrollController = ScrollController();
final PageController pageController = PageController();

@override
Widget build(BuildContext context) {
FavoriteState favoriteState =
Provider.of<FavoriteState>(context, listen: false);
List<String> categories =
List<String>.from(favoriteState.favoriteBox.keys.toList());
final generatedChildren = List.generate(
categories.length,
(index) => OrderableGrid(
gridKey: GlobalKey(),
favoriteItems: favoriteState.getListOfType(categories[index]),
typeName: categories[index],
analyticsHelper: widget.analyticsHelper,
scrollController: scrollController,
),
);
return Scaffold(
appBar: AppBar(
title: const Text('Favorites'),
actions: [
Consumer<FavoriteState>(
builder: (context, favoriteState, child) {
return IconButton(
onPressed: () {
favoriteState.toggleMultiSelect();
final constraintsValues = getPreset(MediaQuery.of(context).size);
return ContextMenuOverlay(
child: Scaffold(
appBar: AppBar(
title: const Text('Favorites'),
),
body: Consumer<FavoriteState>(
builder: (context, favoriteState, child) {
List<String> categories =
List<String>.from(favoriteState.favoriteBox.keys.toList());

return Scrollbar(
thumbVisibility: true,
thickness: 10,
scrollbarOrientation: ScrollbarOrientation.top,
radius: const Radius.circular(20),
controller: pageController,
child: PageView.builder(
itemCount: categories.length,
scrollDirection: Axis.horizontal,
controller: pageController,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(20),
child: OrderableGrid(
items: favoriteState.getListOfType(categories[index]),
categoryType: categories[index],
globalKeyGridView: GlobalKey(),
constraints: constraintsValues,
analyticsHelper: analyticsHelper,
),
);
},
icon: Icon(!favoriteState.isMultiSelectMode
? Icons.delete
: Icons.close),
);
},
),
],
),
body: ListView(
shrinkWrap: true,
controller: scrollController,
children: generatedChildren,
),
);
},
),
),
);
}
Expand Down
36 changes: 36 additions & 0 deletions lib/presentation/widgets/misc/draggable_pop_menu.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:context_menus/context_menus.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import '/hive/favorite_model.dart';
import '/utilities/favorite_state.dart';

class DraggablePopMenu extends StatelessWidget {
const DraggablePopMenu({
required this.items,
required this.selectedItem,
super.key,
});
final FavoriteModel selectedItem;
final List<FavoriteModel> items;

@override
Widget build(BuildContext context) {
return Consumer<FavoriteState>(
builder: (context, favoriteState, child) {
return GenericContextMenu(
buttonConfigs: [
ContextMenuButtonConfig(
"Remove from favorites",
icon: const Icon(Icons.delete),
onPressed: () {
favoriteState.toggleFavoriteFunc(
context, favoriteState, selectedItem);
items.removeWhere((item) => item.id == selectedItem.id);
},
),
],
);
},
);
}
}
4 changes: 0 additions & 4 deletions lib/presentation/widgets/misc/favorite_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ class FavoriteCard extends StatelessWidget {
return Consumer<FavoriteState>(
builder: (context, favoriteState, child) {
return InkWell(
onLongPress: () {
favoriteState.toggleFavoriteFunc(context, favoriteState, favItem);
favoriteItems.removeWhere((item) => item.id == favItem.id);
},
onTap: () {
if (!favoriteState.isMultiSelectMode) {
navigateToPage(
Expand Down
125 changes: 49 additions & 76 deletions lib/presentation/widgets/misc/orderable_grid.dart
Original file line number Diff line number Diff line change
@@ -1,104 +1,77 @@
import 'package:btd6wiki/hive/favorite_model.dart';
import 'package:btd6wiki/presentation/widgets/misc/favorite_card.dart';
import 'package:flutter_reorderable_grid_view/entities/order_update_entity.dart';
import 'package:flutter_reorderable_grid_view/widgets/widgets.dart';
import 'package:context_menus/context_menus.dart';
import 'package:reorderables/reorderables.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import '/hive/favorite_model.dart';
import '/analytics/analytics.dart';
import '/presentation/widgets/misc/favorite_card.dart';
import '/utilities/favorite_state.dart';
import '/utilities/constants.dart';
import '/utilities/strings.dart';
import '/utilities/utils.dart';

import 'draggable_pop_menu.dart';

class OrderableGrid extends StatefulWidget {
const OrderableGrid({
super.key,
required this.gridKey,
required this.typeName,
required this.favoriteItems,
required this.items,
required this.categoryType,
required this.globalKeyGridView,
required this.constraints,
required this.analyticsHelper,
required this.scrollController,
});

final GlobalKey gridKey;
final String typeName;
final List<dynamic> favoriteItems;
final List<FavoriteModel> items;
final AnalyticsHelper analyticsHelper;
final ScrollController scrollController;

final String categoryType;
final GlobalKey globalKeyGridView;
final Map<String, dynamic> constraints;

@override
State<OrderableGrid> createState() => _OrderableGridState();
}

class _OrderableGridState extends State<OrderableGrid> {
// @override
// void dispose() {
// // TODO: implement dispose
// widget.scrollController.detach();
// super.dispose();
// }
final ScrollController scrollController = ScrollController();

@override
Widget build(BuildContext context) {
final constraintsValues = getPreset(
MediaQuery.of(context).size,
List<Widget> orderedItems = List.generate(
widget.items.length,
(index) => SizedBox(
width: MediaQuery.of(context).size.width * 0.25,
height: MediaQuery.of(context).size.width * 0.25,
child: FavoriteCard(
favItem: widget.items[index],
favoriteItems: widget.items,
analyticsHelper: widget.analyticsHelper,
typeName: widget.categoryType,
constraintsValues: widget.constraints,
),
),
);
return Consumer<FavoriteState>(
builder: (context, favoriteState, child) {
List<Widget> generatedChildren = List.generate(
widget.favoriteItems.length,
(index) {
FavoriteModel favItem = widget.favoriteItems.elementAt(index);
return FavoriteCard(
key: Key(favItem.id),
favItem: favItem,
favoriteItems: widget.favoriteItems,
analyticsHelper: widget.analyticsHelper,
typeName: widget.typeName,
constraintsValues: constraintsValues);
return ReorderableWrap(
spacing: MediaQuery.of(context).size.width * 0.04,
runSpacing: MediaQuery.of(context).size.width * 0.04,
reorderAnimationDuration: const Duration(milliseconds: 0),
scrollAnimationDuration: const Duration(milliseconds: 100),
controller: scrollController,
padding: const EdgeInsets.all(12),
onNoReorder: (index) {
context.contextMenuOverlay.show(DraggablePopMenu(
items: widget.items,
selectedItem: widget.items[index],
));
},
onReorder: (oldIndex, newIndex) {
setState(() {
final favItem = widget.items.removeAt(oldIndex);
widget.items.insert(newIndex, favItem);
});
favoriteState.updateIndexes(widget.categoryType, widget.items);
},
children: orderedItems,
);
if (generatedChildren.isNotEmpty) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Text(
capitalizeEveryWord(widget.typeName),
style: bigTitleStyle,
),
ReorderableBuilder(
enableLongPress: false,
scrollController: ScrollController(),
onReorder: (List<OrderUpdateEntity> orderUpdateEntities) {
for (final orderUpdateEntity in orderUpdateEntities) {
final favItem = widget.favoriteItems
.removeAt(orderUpdateEntity.oldIndex);
widget.favoriteItems
.insert(orderUpdateEntity.newIndex, favItem);
}
favoriteState.updateIndexes(
widget.typeName, widget.favoriteItems);
},
builder: (children) {
return GridView(
key: widget.gridKey,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: constraintsValues[favItemCrossCount],
childAspectRatio: constraintsValues[favItemAspectRatio],
),
children: children,
);
},
children: generatedChildren,
),
],
),
);
}
return Container();
},
);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/utilities/favorite_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ class FavoriteState extends ChangeNotifier {
notifyListeners();
}

void toggleDrag() {
draggableMode = !draggableMode;
void toggleDrag(bool dragStatus) {
print('drag mode started as $draggableMode');
print('drag mode changing to $dragStatus');
draggableMode = dragStatus;
notifyListeners();
}

Expand Down
32 changes: 16 additions & 16 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.18.0"
context_menus:
dependency: "direct main"
description:
name: context_menus
sha256: "25313f2a17dc936f541f8012761648cb58d936c5d6f6bf7282f137a4b9dedddb"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
convert:
dependency: transitive
description:
Expand Down Expand Up @@ -233,14 +241,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.4"
equatable:
dependency: transitive
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async:
dependency: transitive
description:
Expand Down Expand Up @@ -342,14 +342,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
flutter_reorderable_grid_view:
dependency: "direct main"
description:
name: flutter_reorderable_grid_view
sha256: ac92a49a8411adfda40f75eff44d0958ee879b0f9d6776bb6154c74aa166aaf1
url: "https://pub.dev"
source: hosted
version: "4.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
Expand Down Expand Up @@ -664,6 +656,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.3"
reorderables:
dependency: "direct main"
description:
name: reorderables
sha256: "004a886e4878df1ee27321831c838bc1c976311f4ca6a74ce7d561e506540a77"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
shared_preferences:
dependency: transitive
description:
Expand Down
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ dependencies:
provider: ^6.1.1
hive: ^2.2.3
hive_flutter: ^1.1.0
flutter_reorderable_grid_view: ^4.0.0
reorderables: ^0.6.0
context_menus: ^1.0.2

dev_dependencies:
flutter_launcher_icons: ^0.13.1
Expand Down

0 comments on commit 50785cc

Please sign in to comment.