Skip to content

Commit

Permalink
Change profile options modal
Browse files Browse the repository at this point in the history
  • Loading branch information
0xConsumer committed Jan 16, 2024
1 parent 46107f2 commit c182c46
Show file tree
Hide file tree
Showing 4 changed files with 325 additions and 92 deletions.
179 changes: 179 additions & 0 deletions lib/core/widget/adaptive_menu.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hiddify/utils/platform_utils.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';

typedef AdaptiveMenuBuilder = Widget Function(
BuildContext context,
void Function() toggleVisibility,
Widget? child,
);

class AdaptiveMenuItem<T> {
AdaptiveMenuItem({
required this.title,
this.icon,
this.onTap,
this.isSelected,
this.subItems,
});

final String title;
final IconData? icon;
final T Function()? onTap;
final bool? isSelected;
final List<AdaptiveMenuItem>? subItems;

(String, IconData?, T Function()?, bool?, List<AdaptiveMenuItem>?)
_equality() => (title, icon, onTap, isSelected, subItems);

@override
bool operator ==(covariant AdaptiveMenuItem other) {
if (identical(this, other)) return true;
return other._equality() == _equality();
}

@override
int get hashCode => _equality().hashCode;
}

class AdaptiveMenu extends HookConsumerWidget {
const AdaptiveMenu({
super.key,
required this.items,
required this.builder,
required this.child,
});

final Iterable<AdaptiveMenuItem> items;
final AdaptiveMenuBuilder builder;
final Widget? child;

@override
Widget build(BuildContext context, WidgetRef ref) {
if (PlatformUtils.isDesktop) {
List<Widget> buildMenuItems(Iterable<AdaptiveMenuItem> scopeItems) {
final menuItems = <Widget>[];
for (final item in scopeItems) {
if (item.subItems != null) {
final subItems = buildMenuItems(item.subItems!);
menuItems.add(
SubmenuButton(
menuChildren: subItems,
leadingIcon: item.icon != null ? Icon(item.icon) : null,
child: Text(item.title),
),
);
} else {
menuItems.add(
MenuItemButton(
leadingIcon: item.icon != null ? Icon(item.icon) : null,
onPressed: item.onTap,
child: Text(item.title),
),
);
}
}
return menuItems;
}

return MenuAnchor(
builder: (context, controller, child) => builder(
context,
() {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
child,
),
menuChildren: buildMenuItems(items),
child: child,
);
}

final pageIndexNotifier = useValueNotifier(0);
final nestedSheets = <SliverWoltModalSheetPage>[];
int pageIndex = 0;

void popSheets() {
if (context.mounted) {
Navigator.pop(context);
}
Future.delayed(const Duration(milliseconds: 200))
.then((_) => pageIndexNotifier.value = 0);
}

List<Widget> buildSheetItems(
Iterable<AdaptiveMenuItem> menuItems,
int index,
) {
final sheetItems = <Widget>[];
for (final item in menuItems) {
if (item.subItems != null) {
final subItems = buildSheetItems(item.subItems!, index + 1);
final subSheetIndex = ++pageIndex;
sheetItems.add(
ListTile(
title: Text(item.title),
leading: item.icon != null ? Icon(item.icon) : null,
trailing: const Icon(Icons.chevron_right),
onTap: () {
pageIndexNotifier.value = subSheetIndex;
},
),
);
nestedSheets.add(
SliverWoltModalSheetPage(
hasTopBarLayer: false,
isTopBarLayerAlwaysVisible: true,
topBarTitle: Text(item.title),
mainContentSlivers: [
SliverList.list(children: subItems),
],
),
);
} else {
sheetItems.add(
ListTile(
title: Text(item.title),
leading: item.icon != null ? Icon(item.icon) : null,
onTap: () async {
popSheets();
await item.onTap!();
},
),
);
}
}
return sheetItems;
}

return builder(
context,
() async {
await WoltModalSheet.show(
context: context,
pageIndexNotifier: pageIndexNotifier,
onModalDismissedWithDrag: popSheets,
onModalDismissedWithBarrierTap: popSheets,
useSafeArea: true,
showDragHandle: false,
pageListBuilder: (context) => [
SliverWoltModalSheetPage(
hasTopBarLayer: false,
mainContentSlivers: [
SliverList.list(children: buildSheetItems(items, 0)),
],
),
...nestedSheets,
],
);
},
child,
);
}
}
Loading

0 comments on commit c182c46

Please sign in to comment.