diff --git a/lib/extensions/context_extensions.dart b/lib/extensions/context_extensions.dart index 8d334df0..69f97893 100644 --- a/lib/extensions/context_extensions.dart +++ b/lib/extensions/context_extensions.dart @@ -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; } diff --git a/lib/providers/ui_providers.dart b/lib/providers/ui_providers.dart index 0a6be441..e7d67038 100644 --- a/lib/providers/ui_providers.dart +++ b/lib/providers/ui_providers.dart @@ -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>( - (ref) => GlobalKey()); +final mobileScaffoldKeyStateProvider = StateProvider>( + (ref) => GlobalKey()); final leftDrawerStateProvider = StateProvider((ref) => false); final navRailIndexStateProvider = StateProvider((ref) => 0); final selectedIdEditStateProvider = StateProvider((ref) => null); diff --git a/lib/screens/envvar/environments_pane.dart b/lib/screens/envvar/environments_pane.dart index fa884b2b..075fb182 100644 --- a/lib/screens/envvar/environments_pane.dart +++ b/lib/screens/envvar/environments_pane.dart @@ -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), diff --git a/lib/screens/home_page/collection_pane.dart b/lib/screens/home_page/collection_pane.dart index 822af01c..66a3d93a 100644 --- a/lib/screens/home_page/collection_pane.dart +++ b/lib/screens/home_page/collection_pane.dart @@ -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: () { diff --git a/lib/screens/mobile/dashboard.dart b/lib/screens/mobile/dashboard.dart index 80ef32ce..805c37b9 100644 --- a/lib/screens/mobile/dashboard.dart +++ b/lib/screens/mobile/dashboard.dart @@ -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 { BuildContext context, ) { final railIdx = ref.watch(navRailIndexStateProvider); - final GlobalKey innerDrawerKey = - ref.watch(mobileDrawerKeyProvider); final isLeftDrawerOpen = ref.watch(leftDrawerStateProvider); + return AnnotatedRegion( value: FlexColorScheme.themedSystemNavigationBar( context, @@ -42,9 +37,8 @@ class _MobileDashboardState extends ConsumerState { children: [ PageBranch( pageIndex: railIdx, - innerDrawerKey: innerDrawerKey, ), - if (context.isCompactWindow) + if (context.isMediumWindow) AnimatedPositioned( bottom: isLeftDrawerOpen ? 0 @@ -62,28 +56,32 @@ class _MobileDashboardState extends ConsumerState { } } -class PageBranch extends StatelessWidget { +class PageBranch extends ConsumerWidget { const PageBranch({ super.key, required this.pageIndex, - required this.innerDrawerKey, }); final int pageIndex; - final GlobalKey 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, ); } } diff --git a/lib/screens/mobile/navbar.dart b/lib/screens/mobile/navbar.dart index e296efdd..47c16adc 100644 --- a/lib/screens/mobile/navbar.dart +++ b/lib/screens/mobile/navbar.dart @@ -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, diff --git a/lib/screens/mobile/requests_page.dart b/lib/screens/mobile/requests_page.dart index fb41b14d..6f36c144 100644 --- a/lib/screens/mobile/requests_page.dart +++ b/lib/screens/mobile/requests_page.dart @@ -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 innerDrawerKey; +class RequestsPage extends ConsumerWidget { + const RequestsPage({ + super.key, + required this.scaffoldKey, + }); - const RequestsPage({super.key, required this.innerDrawerKey}); + final GlobalKey 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); - }, - ), - 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), + Widget build(BuildContext context, WidgetRef ref) { + return TwoDrawerScaffold( + scaffoldKey: scaffoldKey, + title: const RequestTitle(), + 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 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(); }, ), ], diff --git a/lib/screens/mobile/response_drawer.dart b/lib/screens/mobile/response_drawer.dart index 40f0a9aa..e7295c27 100644 --- a/lib/screens/mobile/response_drawer.dart +++ b/lib/screens/mobile/response_drawer.dart @@ -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,31 +6,27 @@ 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( - appBar: AppBar( - backgroundColor: Theme.of(context).colorScheme.surface, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical(top: Radius.circular(8)), - ), - leading: IconButton( - icon: const Icon(Icons.arrow_back_rounded), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - scrolledUnderElevation: 0, - centerTitle: true, - title: const Text("Response"), + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.surface, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(8)), ), - body: Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.paddingOf(context).bottom, - ), - child: const ResponsePane(), + leading: IconButton( + icon: const Icon(Icons.arrow_back_rounded), + onPressed: () { + Navigator.of(context).pop(); + }, ), + scrolledUnderElevation: 0, + centerTitle: true, + title: const Text("Response"), + ), + body: Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.paddingOf(context).bottom, + ), + child: const ResponsePane(), ), ); } diff --git a/lib/screens/mobile/widgets/left_drawer.dart b/lib/screens/mobile/widgets/left_drawer.dart deleted file mode 100644 index d7f6973d..00000000 --- a/lib/screens/mobile/widgets/left_drawer.dart +++ /dev/null @@ -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, - ), - ), - ), - ); - } -} diff --git a/lib/screens/mobile/widgets/page_base.dart b/lib/screens/mobile/widgets/page_base.dart index 3116e2d7..b1bbb247 100644 --- a/lib/screens/mobile/widgets/page_base.dart +++ b/lib/screens/mobile/widgets/page_base.dart @@ -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,32 +14,28 @@ 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, - appBar: AppBar( - backgroundColor: Theme.of(context).colorScheme.background, - primary: true, - title: Text(title), - centerTitle: true, - ), - body: Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.paddingOf(context).bottom, - ), - child: scaffoldBody, + primary: true, + title: Text(title), + centerTitle: true, + scrolledUnderElevation: 0, + ), + body: Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.paddingOf(context).bottom, ), + 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, diff --git a/lib/widgets/splitviews.dart b/lib/widgets/splitviews.dart index f4a30e32..8145e6b7 100644 --- a/lib/widgets/splitviews.dart +++ b/lib/widgets/splitviews.dart @@ -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 { } } -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 innerDrawerKey; - final IDOffset offset; + final GlobalKey scaffoldKey; final Widget mainContent; - final Widget leftDrawerContent; + final Widget title; + final List? actions; + final Widget? leftDrawerContent; final Widget? rightDrawerContent; + final IconData? rightDrawerIcon; + final Widget? bottomNavigationBar; + final ValueChanged? onDrawerChanged; + final ValueChanged? onEndDrawerChanged; @override - Widget build(BuildContext context, WidgetRef ref) { - ValueNotifier dragPosition = useState(0.0); - ValueNotifier 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( - valueListenable: dragPosition, - builder: (context, value, child) { - return Container( - color: calculateBackgroundColor(value), - child: child, - ); - }, - child: ClipRRect( - borderRadius: const BorderRadius.only(topLeft: Radius.circular(8)), - child: SafeArea( - minimum: kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero, - bottom: false, - child: mainContent, + Widget build(BuildContext context) { + return Container( + 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(); + }, ), + 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, ), ); } diff --git a/pubspec.lock b/pubspec.lock index bd3a0f36..4e4b5ddb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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: diff --git a/pubspec.yaml b/pubspec.yaml index 3d092341..922f98df 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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