fix: migrate to native drawer

This commit is contained in:
DenserMeerkat
2024-06-13 00:46:22 +05:30
parent 605afefd9f
commit 09639cdf13
13 changed files with 150 additions and 328 deletions

View File

@ -15,4 +15,8 @@ extension MediaQueryExtension on BuildContext {
bool get isExtraLargeWindow =>
MediaQuery.of(this).size.width > kLargeWindowWidth;
double get width => MediaQuery.of(this).size.width;
double get height => MediaQuery.of(this).size.height;
}

View File

@ -1,9 +1,8 @@
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:inner_drawer/inner_drawer.dart';
final mobileDrawerKeyProvider = StateProvider<GlobalKey<InnerDrawerState>>(
(ref) => GlobalKey<InnerDrawerState>());
final mobileScaffoldKeyStateProvider = StateProvider<GlobalKey<ScaffoldState>>(
(ref) => GlobalKey<ScaffoldState>());
final leftDrawerStateProvider = StateProvider<bool>((ref) => false);
final navRailIndexStateProvider = StateProvider<int>((ref) => 0);
final selectedIdEditStateProvider = StateProvider<String?>((ref) => null);

View File

@ -153,7 +153,6 @@ class EnvironmentItem extends ConsumerWidget {
final selectedId = ref.watch(selectedEnvironmentIdStateProvider);
final activeEnvironmentId = ref.watch(activeEnvironmentIdStateProvider);
final editRequestId = ref.watch(selectedIdEditStateProvider);
final mobileDrawerKey = ref.watch(mobileDrawerKeyProvider);
return SidebarEnvironmentCard(
id: id,
@ -166,7 +165,7 @@ class EnvironmentItem extends ConsumerWidget {
ref.read(activeEnvironmentIdStateProvider.notifier).state = id;
},
onTap: () {
mobileDrawerKey.currentState?.close();
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
ref.read(selectedEnvironmentIdStateProvider.notifier).state = id;
},
focusNode: ref.watch(nameTextFieldFocusNodeProvider),

View File

@ -250,7 +250,6 @@ class RequestItem extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final selectedId = ref.watch(selectedIdStateProvider);
final editRequestId = ref.watch(selectedIdEditStateProvider);
final mobileDrawerKey = ref.watch(mobileDrawerKeyProvider);
return SidebarRequestCard(
id: id,
@ -260,7 +259,7 @@ class RequestItem extends ConsumerWidget {
selectedId: selectedId,
editRequestId: editRequestId,
onTap: () {
mobileDrawerKey.currentState?.close();
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
ref.read(selectedIdStateProvider.notifier).state = id;
},
// onDoubleTap: () {

View File

@ -1,9 +1,7 @@
import 'package:apidash/screens/envvar/environments_pane.dart';
import 'package:apidash/widgets/splitviews.dart';
import 'package:apidash/consts.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:inner_drawer/inner_drawer.dart';
import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/providers/providers.dart';
@ -11,8 +9,6 @@ import '../intro_page.dart';
import '../settings_page.dart';
import 'navbar.dart';
import 'requests_page.dart';
import 'response_drawer.dart';
import '../home_page/collection_pane.dart';
import 'widgets/page_base.dart';
class MobileDashboard extends ConsumerStatefulWidget {
@ -28,9 +24,8 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
BuildContext context,
) {
final railIdx = ref.watch(navRailIndexStateProvider);
final GlobalKey<InnerDrawerState> innerDrawerKey =
ref.watch(mobileDrawerKeyProvider);
final isLeftDrawerOpen = ref.watch(leftDrawerStateProvider);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: FlexColorScheme.themedSystemNavigationBar(
context,
@ -42,9 +37,8 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
children: [
PageBranch(
pageIndex: railIdx,
innerDrawerKey: innerDrawerKey,
),
if (context.isCompactWindow)
if (context.isMediumWindow)
AnimatedPositioned(
bottom: isLeftDrawerOpen
? 0
@ -62,28 +56,32 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
}
}
class PageBranch extends StatelessWidget {
class PageBranch extends ConsumerWidget {
const PageBranch({
super.key,
required this.pageIndex,
required this.innerDrawerKey,
});
final int pageIndex;
final GlobalKey<InnerDrawerState> innerDrawerKey;
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
final scaffoldKey = ref.watch(mobileScaffoldKeyStateProvider);
switch (pageIndex) {
case 1:
return TwoDrawerSplitView(
key: const ValueKey('env'),
innerDrawerKey: innerDrawerKey,
offset: !context.isCompactWindow
? const IDOffset.only(left: 0.1)
: const IDOffset.only(left: 0.7),
leftDrawerContent: const EnvironmentsPane(),
mainContent: const SizedBox(),
// Temporary Environment Page
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: const Text('Environments'),
),
onDrawerChanged: (isOpened) {
ref.read(leftDrawerStateProvider.notifier).state = isOpened;
},
drawer: const Drawer(
surfaceTintColor: kColorTransparent,
shape: ContinuousRectangleBorder(),
),
body: const SizedBox(),
);
case 2:
return const PageBase(
@ -96,17 +94,8 @@ class PageBranch extends StatelessWidget {
scaffoldBody: SettingsPage(),
);
default:
return TwoDrawerSplitView(
key: const ValueKey('home'),
innerDrawerKey: innerDrawerKey,
offset: !context.isCompactWindow
? const IDOffset.only(left: 0.1, right: 1)
: const IDOffset.only(left: 0.7, right: 1),
leftDrawerContent: const CollectionPane(),
rightDrawerContent: const ResponseDrawer(),
mainContent: RequestsPage(
innerDrawerKey: innerDrawerKey,
),
return RequestsPage(
scaffoldKey: scaffoldKey,
);
}
}

View File

@ -75,76 +75,6 @@ class BottomNavBar extends ConsumerWidget {
}
}
class NavRail extends ConsumerWidget {
const NavRail({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final railIdx = ref.watch(navRailIndexStateProvider);
return Material(
type: MaterialType.transparency,
child: Ink(
width: 70,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
border: Border(
right: BorderSide(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 1,
),
),
),
child: Column(
children: [
customNavigationDestination(
context,
ref,
railIdx,
0,
Icons.dashboard,
Icons.dashboard_outlined,
'Requests',
),
const SizedBox(height: 16),
customNavigationDestination(
context,
ref,
railIdx,
1,
Icons.laptop_windows,
Icons.laptop_windows_outlined,
'Variables',
),
const Expanded(child: SizedBox()),
customNavigationDestination(
context,
ref,
railIdx,
2,
Icons.help,
Icons.help_outline,
'About',
showLabel: false,
),
const SizedBox(height: 24),
customNavigationDestination(
context,
ref,
railIdx,
3,
Icons.settings,
Icons.settings_outlined,
'Settings',
showLabel: false,
),
],
),
),
);
}
}
Widget customNavigationDestination(
BuildContext context,
WidgetRef ref,

View File

@ -1,58 +1,36 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:inner_drawer/inner_drawer.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/utils/http_utils.dart';
import 'package:apidash/consts.dart';
import 'package:apidash/widgets/widgets.dart';
import '../home_page/collection_pane.dart';
import '../home_page/editor_pane/editor_request.dart';
import '../home_page/editor_pane/editor_pane.dart';
import '../home_page/editor_pane/url_card.dart';
import '../home_page/editor_pane/details_card/code_pane.dart';
import 'response_drawer.dart';
import 'widgets/page_base.dart';
class RequestsPage extends StatelessWidget {
final GlobalKey<InnerDrawerState> innerDrawerKey;
class RequestsPage extends ConsumerWidget {
const RequestsPage({
super.key,
required this.scaffoldKey,
});
const RequestsPage({super.key, required this.innerDrawerKey});
final GlobalKey<ScaffoldState> scaffoldKey;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.surface,
scrolledUnderElevation: 0,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(8)),
),
leading: IconButton(
icon: const Icon(Icons.format_list_bulleted_rounded),
onPressed: () {
innerDrawerKey.currentState!
.open(direction: InnerDrawerDirection.start);
},
),
Widget build(BuildContext context, WidgetRef ref) {
return TwoDrawerScaffold(
scaffoldKey: scaffoldKey,
title: const RequestTitle(),
titleSpacing: 0,
actions: [
IconButton(
icon: Icon(
Icons.quickreply_outlined,
color: Theme.of(context).colorScheme.onBackground,
),
onPressed: () {
innerDrawerKey.currentState!
.open(direction: InnerDrawerDirection.end);
},
),
],
),
body: Container(
color: Theme.of(context).colorScheme.surface,
child: const RequestEditorPane(),
),
bottomNavigationBar: RequestPageBottombar(innerDrawerKey: innerDrawerKey),
leftDrawerContent: const CollectionPane(),
rightDrawerContent: const ResponseDrawer(),
mainContent: const RequestEditorPane(),
bottomNavigationBar: const RequestPageBottombar(),
onDrawerChanged: (value) =>
ref.read(leftDrawerStateProvider.notifier).state = value,
);
}
}
@ -118,16 +96,13 @@ class RequestTitle extends ConsumerWidget {
}
}
class RequestPageBottombar extends StatelessWidget {
class RequestPageBottombar extends ConsumerWidget {
const RequestPageBottombar({
super.key,
required this.innerDrawerKey,
});
final GlobalKey<InnerDrawerState> innerDrawerKey;
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
return Container(
height: 60 + MediaQuery.paddingOf(context).bottom,
width: MediaQuery.sizeOf(context).width,
@ -168,8 +143,10 @@ class RequestPageBottombar extends StatelessWidget {
),
SendButton(
onTap: () {
innerDrawerKey.currentState!
.open(direction: InnerDrawerDirection.end);
ref
.read(mobileScaffoldKeyStateProvider)
.currentState!
.openEndDrawer();
},
),
],

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:apidash/consts.dart';
import '../home_page/editor_pane/details_card/response_pane.dart';
class ResponseDrawer extends StatelessWidget {
@ -7,10 +6,7 @@ class ResponseDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero,
color: Theme.of(context).colorScheme.surface,
child: Scaffold(
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.surface,
shape: const RoundedRectangleBorder(
@ -32,7 +28,6 @@ class ResponseDrawer extends StatelessWidget {
),
child: const ResponsePane(),
),
),
);
}
}

View File

@ -1,46 +0,0 @@
import 'package:apidash/consts.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/screens/mobile/navbar.dart';
import 'package:flutter/material.dart';
class LeftDrawer extends StatelessWidget {
final Widget drawerContent;
const LeftDrawer({super.key, required this.drawerContent});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: MediaQuery.paddingOf(context).top) +
(kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero),
color: Theme.of(context).colorScheme.onInverseSurface,
child: Drawer(
backgroundColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
child: Padding(
padding: const EdgeInsets.only(right: 16),
child: Container(
padding: EdgeInsets.only(
left: MediaQuery.paddingOf(context).left,
bottom: !context.isCompactWindow
? MediaQuery.paddingOf(context).bottom
: 70 + MediaQuery.paddingOf(context).bottom),
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius:
const BorderRadius.only(topRight: Radius.circular(8)),
),
child: !context.isCompactWindow
? Row(
children: [
const NavRail(),
Expanded(child: drawerContent),
],
)
: drawerContent,
),
),
),
);
}
}

View File

@ -4,7 +4,6 @@ import 'package:apidash/consts.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/window_caption.dart';
import '../navbar.dart';
class PageBase extends ConsumerWidget {
final String title;
@ -15,19 +14,14 @@ class PageBase extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final isDarkMode =
ref.watch(settingsProvider.select((value) => value.isDark));
final scaffold = Container(
padding: (context.isCompactWindow
? const EdgeInsets.only(bottom: 70)
: EdgeInsets.zero) +
(kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero),
color: Theme.of(context).colorScheme.surface,
child: Scaffold(
final scaffold = Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.background,
primary: true,
title: Text(title),
centerTitle: true,
scrolledUnderElevation: 0,
),
body: Padding(
padding: EdgeInsets.only(
@ -35,12 +29,13 @@ class PageBase extends ConsumerWidget {
),
child: scaffoldBody,
),
),
);
return Stack(
children: [
Container(
padding: (context.isMediumWindow ? kPb70 : EdgeInsets.zero) +
padding: (context.isMediumWindow
? const EdgeInsets.only(bottom: 70)
: EdgeInsets.zero) +
(kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero),
color: Theme.of(context).colorScheme.surface,
child: scaffold,

View File

@ -1,11 +1,7 @@
import 'package:apidash/screens/mobile/widgets/left_drawer.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:inner_drawer/inner_drawer.dart';
import 'package:multi_split_view/multi_split_view.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/consts.dart';
import 'package:apidash/providers/ui_providers.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class DashboardSplitView extends StatefulWidget {
const DashboardSplitView({
@ -116,83 +112,77 @@ class _EqualSplitViewState extends State<EqualSplitView> {
}
}
class TwoDrawerSplitView extends HookConsumerWidget {
const TwoDrawerSplitView({
class TwoDrawerScaffold extends StatelessWidget {
const TwoDrawerScaffold({
super.key,
required this.innerDrawerKey,
required this.offset,
required this.scaffoldKey,
required this.mainContent,
required this.leftDrawerContent,
required this.title,
this.actions,
this.leftDrawerContent,
this.rightDrawerContent,
this.rightDrawerIcon,
this.bottomNavigationBar,
this.onDrawerChanged,
this.onEndDrawerChanged,
});
final GlobalKey<InnerDrawerState> innerDrawerKey;
final IDOffset offset;
final GlobalKey<ScaffoldState> scaffoldKey;
final Widget mainContent;
final Widget leftDrawerContent;
final Widget title;
final List<Widget>? actions;
final Widget? leftDrawerContent;
final Widget? rightDrawerContent;
final IconData? rightDrawerIcon;
final Widget? bottomNavigationBar;
final ValueChanged<bool>? onDrawerChanged;
final ValueChanged<bool>? onEndDrawerChanged;
@override
Widget build(BuildContext context, WidgetRef ref) {
ValueNotifier<double> dragPosition = useState(0.0);
ValueNotifier<InnerDrawerDirection?> drawerDirection =
ValueNotifier(InnerDrawerDirection.start);
Color calculateBackgroundColor(double dragPosition) {
Color start = Theme.of(context).colorScheme.surface;
Color end = Theme.of(context).colorScheme.onInverseSurface;
return dragPosition == 0 ? start : end;
}
return InnerDrawer(
key: innerDrawerKey,
swipe: true,
swipeChild: true,
onTapClose: true,
offset: offset,
boxShadow: [
BoxShadow(
offset: const Offset(1, 0),
color: Theme.of(context).colorScheme.onInverseSurface,
blurRadius: 0,
),
],
colorTransitionChild: Colors.transparent,
colorTransitionScaffold: Colors.transparent,
rightAnimationType: InnerDrawerAnimation.linear,
backgroundDecoration:
BoxDecoration(color: Theme.of(context).colorScheme.onInverseSurface),
onDragUpdate: (value, direction) {
drawerDirection.value = direction;
if (value > 0.98 && direction == InnerDrawerDirection.start) {
dragPosition.value = 1;
} else {
dragPosition.value = 0;
}
},
innerDrawerCallback: (isOpened) {
if (drawerDirection.value == InnerDrawerDirection.start) {
ref.read(leftDrawerStateProvider.notifier).state = isOpened;
}
},
leftChild: LeftDrawer(drawerContent: leftDrawerContent),
rightChild: rightDrawerContent,
scaffold: ValueListenableBuilder<double>(
valueListenable: dragPosition,
builder: (context, value, child) {
Widget build(BuildContext context) {
return Container(
color: calculateBackgroundColor(value),
child: child,
);
padding: (kIsWindows || kIsMacOS) ? kPt28 : EdgeInsets.zero,
color: Theme.of(context).colorScheme.surface,
child: Scaffold(
key: scaffoldKey,
backgroundColor: Theme.of(context).colorScheme.surface,
onDrawerChanged: onDrawerChanged,
onEndDrawerChanged: onEndDrawerChanged,
drawerEdgeDragWidth: context.width,
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.surface,
scrolledUnderElevation: 0,
shape: const ContinuousRectangleBorder(),
leading: IconButton(
icon: const Icon(Icons.format_list_bulleted_rounded),
onPressed: () {
scaffoldKey.currentState!.openDrawer();
},
child: ClipRRect(
borderRadius: const BorderRadius.only(topLeft: Radius.circular(8)),
child: SafeArea(
minimum: kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero,
bottom: false,
child: mainContent,
),
title: title,
titleSpacing: 0,
actions: [
...actions ?? [],
(rightDrawerContent != null
? Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
icon: Icon(
rightDrawerIcon ?? Icons.arrow_forward,
color: Theme.of(context).colorScheme.onBackground,
),
onPressed: () {
scaffoldKey.currentState!.openEndDrawer();
},
),
)
: const SizedBox.shrink()),
],
),
drawer: leftDrawerContent,
endDrawer: rightDrawerContent,
body: mainContent,
bottomNavigationBar: bottomNavigationBar,
),
);
}

View File

@ -640,14 +640,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.2.0"
inner_drawer:
dependency: "direct main"
description:
name: inner_drawer
sha256: "19df8813ccb6aa1b6db76f2f976c93befbbae67452d019f5267209b15deb0772"
url: "https://pub.dev"
source: hosted
version: "1.0.0+1"
io:
dependency: transitive
description:

View File

@ -57,7 +57,6 @@ dependencies:
dart_style: ^2.3.6
json_text_field: ^1.1.0
csv: ^6.0.0
inner_drawer: ^1.0.0+1
flex_color_scheme: ^7.3.1
data_table_2: ^2.5.11
file_selector: ^1.0.3