mirror of
https://github.com/foss42/apidash.git
synced 2025-05-29 12:59:58 +08:00
fix: page navigation
This commit is contained in:
@ -4,6 +4,7 @@ import 'package:inner_drawer/inner_drawer.dart';
|
||||
|
||||
final mobileDrawerKeyProvider = StateProvider<GlobalKey<InnerDrawerState>>(
|
||||
(ref) => GlobalKey<InnerDrawerState>());
|
||||
final leftDrawerStateProvider = StateProvider<bool>((ref) => false);
|
||||
final navRailIndexStateProvider = StateProvider<int>((ref) => 0);
|
||||
final selectedIdEditStateProvider = StateProvider<String?>((ref) => null);
|
||||
final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
|
||||
@ -29,4 +30,5 @@ final nameTextFieldFocusNodeProvider =
|
||||
return focusNode;
|
||||
});
|
||||
|
||||
final searchQueryProvider = StateProvider<String>((ref) => '');
|
||||
final collectionSearchQueryProvider = StateProvider<String>((ref) => '');
|
||||
final environmentSearchQueryProvider = StateProvider<String>((ref) => '');
|
||||
|
@ -58,11 +58,13 @@ class Dashboard extends ConsumerWidget {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16.0),
|
||||
child: bottomButton(context, ref, railIdx, 2,
|
||||
child: bottomButton(context, ref, railIdx, 2,
|
||||
Icons.help, Icons.help_outline),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16.0),
|
||||
child: bottomButton(context, ref, railIdx, 3,
|
||||
child: bottomButton(context, ref, railIdx, 3,
|
||||
Icons.settings, Icons.settings_outlined),
|
||||
),
|
||||
@ -95,6 +97,7 @@ class Dashboard extends ConsumerWidget {
|
||||
children: const [
|
||||
HomePage(),
|
||||
SizedBox(),
|
||||
SizedBox(),
|
||||
IntroPage(),
|
||||
SettingsPage(),
|
||||
],
|
||||
|
0
lib/screens/envvar/environment_page.dart
Normal file
0
lib/screens/envvar/environment_page.dart
Normal file
129
lib/screens/envvar/environments_pane.dart
Normal file
129
lib/screens/envvar/environments_pane.dart
Normal file
@ -0,0 +1,129 @@
|
||||
import 'package:apidash/consts.dart';
|
||||
import 'package:apidash/extensions/extensions.dart';
|
||||
import 'package:apidash/models/environment_model.dart';
|
||||
import 'package:apidash/providers/providers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
|
||||
class EnvironmentsPane extends ConsumerWidget {
|
||||
const EnvironmentsPane({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return const SizedBox();
|
||||
}
|
||||
}
|
||||
|
||||
class EnvironmentsList extends HookConsumerWidget {
|
||||
const EnvironmentsList({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final environmentSequence = ref.watch(environmentSequenceProvider);
|
||||
final environmentItems = ref.watch(environmentsStateNotifierProvider)!;
|
||||
final alwaysShowEnvironmentsPaneScrollbar = ref.watch(settingsProvider
|
||||
.select((value) => value.alwaysShowCollectionPaneScrollbar));
|
||||
final filterQuery = ref.watch(environmentSearchQueryProvider).trim();
|
||||
|
||||
ScrollController scrollController = useScrollController();
|
||||
return Scrollbar(
|
||||
controller: scrollController,
|
||||
thumbVisibility: alwaysShowEnvironmentsPaneScrollbar,
|
||||
radius: const Radius.circular(12),
|
||||
child: filterQuery.isEmpty
|
||||
? ReorderableListView.builder(
|
||||
padding: context.isMediumWindow
|
||||
? EdgeInsets.only(
|
||||
bottom: MediaQuery.paddingOf(context).bottom,
|
||||
right: 8,
|
||||
)
|
||||
: kPe8,
|
||||
scrollController: scrollController,
|
||||
buildDefaultDragHandles: false,
|
||||
itemCount: environmentSequence.length,
|
||||
onReorder: (int oldIndex, int newIndex) {
|
||||
if (oldIndex < newIndex) {
|
||||
newIndex -= 1;
|
||||
}
|
||||
if (oldIndex != newIndex) {
|
||||
ref
|
||||
.read(collectionStateNotifierProvider.notifier)
|
||||
.reorder(oldIndex, newIndex);
|
||||
}
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
var id = environmentSequence[index];
|
||||
if (kIsMobile) {
|
||||
return ReorderableDelayedDragStartListener(
|
||||
key: ValueKey(id),
|
||||
index: index,
|
||||
child: Padding(
|
||||
padding: kP1,
|
||||
child: EnvironmentItem(
|
||||
id: id,
|
||||
environmentModel: environmentItems[id]!,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return ReorderableDragStartListener(
|
||||
key: ValueKey(id),
|
||||
index: index,
|
||||
child: Padding(
|
||||
padding: kP1,
|
||||
child: EnvironmentItem(
|
||||
id: id,
|
||||
environmentModel: environmentItems[id]!,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
: ListView(
|
||||
padding: context.isMediumWindow
|
||||
? EdgeInsets.only(
|
||||
bottom: MediaQuery.paddingOf(context).bottom,
|
||||
right: 8,
|
||||
)
|
||||
: kPe8,
|
||||
controller: scrollController,
|
||||
children: environmentSequence.map((id) {
|
||||
var item = environmentItems[id]!;
|
||||
if (item.name.toLowerCase().contains(filterQuery)) {
|
||||
return Padding(
|
||||
padding: kP1,
|
||||
child: EnvironmentItem(
|
||||
id: id,
|
||||
environmentModel: item,
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EnvironmentItem extends ConsumerWidget {
|
||||
const EnvironmentItem({
|
||||
super.key,
|
||||
required this.id,
|
||||
required this.environmentModel,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final EnvironmentModel environmentModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedId = ref.watch(selectedEnvironmentIdProvider);
|
||||
|
||||
return Text(environmentModel.name);
|
||||
}
|
||||
}
|
@ -94,7 +94,7 @@ class CollectionPane extends ConsumerWidget {
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
hintText: "Filter by name or URL",
|
||||
onChanged: (value) {
|
||||
ref.read(searchQueryProvider.notifier).state =
|
||||
ref.read(collectionSearchQueryProvider.notifier).state =
|
||||
value.toLowerCase();
|
||||
},
|
||||
),
|
||||
@ -142,7 +142,7 @@ class _RequestListState extends ConsumerState<RequestList> {
|
||||
final requestItems = ref.watch(collectionStateNotifierProvider)!;
|
||||
final alwaysShowCollectionPaneScrollbar = ref.watch(settingsProvider
|
||||
.select((value) => value.alwaysShowCollectionPaneScrollbar));
|
||||
final filterQuery = ref.watch(searchQueryProvider).trim();
|
||||
final filterQuery = ref.watch(collectionSearchQueryProvider).trim();
|
||||
|
||||
return Scrollbar(
|
||||
controller: controller,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:apidash/consts.dart';
|
||||
import 'package:apidash/widgets/splitviews.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@ -6,11 +6,13 @@ 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';
|
||||
import '../intro_page.dart';
|
||||
import '../settings_page.dart';
|
||||
import 'navbar.dart';
|
||||
import 'widgets/left_drawer.dart';
|
||||
import 'requests_page.dart';
|
||||
import 'response_drawer.dart';
|
||||
import '../home_page/collection_pane.dart';
|
||||
import 'widgets/page_base.dart';
|
||||
|
||||
class MobileDashboard extends ConsumerStatefulWidget {
|
||||
const MobileDashboard({super.key});
|
||||
@ -20,31 +22,14 @@ class MobileDashboard extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _MobileDashboardState extends ConsumerState<MobileDashboard> {
|
||||
late Color backgroundColor;
|
||||
bool isLeftDrawerOpen = false;
|
||||
ValueNotifier<double> dragPosition = ValueNotifier(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;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
dragPosition.dispose();
|
||||
drawerDirection.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
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,
|
||||
@ -54,65 +39,9 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
|
||||
child: Stack(
|
||||
alignment: AlignmentDirectional.bottomCenter,
|
||||
children: [
|
||||
InnerDrawer(
|
||||
key: innerDrawerKey,
|
||||
swipe: true,
|
||||
swipeChild: true,
|
||||
onTapClose: true,
|
||||
offset: !context.isCompactWindow
|
||||
? const IDOffset.only(left: 0.1, right: 1)
|
||||
: const IDOffset.only(left: 0.7, right: 1),
|
||||
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) {
|
||||
setState(() {
|
||||
isLeftDrawerOpen = isOpened;
|
||||
});
|
||||
}
|
||||
},
|
||||
leftChild: const LeftDrawer(
|
||||
drawerContent: CollectionPane(),
|
||||
),
|
||||
rightChild: const ResponseDrawer(),
|
||||
scaffold: ValueListenableBuilder<double>(
|
||||
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: RequestsPage(
|
||||
innerDrawerKey: innerDrawerKey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
PageBranch(
|
||||
pageIndex: railIdx,
|
||||
innerDrawerKey: innerDrawerKey,
|
||||
),
|
||||
if (context.isCompactWindow)
|
||||
AnimatedPositioned(
|
||||
@ -131,3 +60,53 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PageBranch extends StatelessWidget {
|
||||
const PageBranch({
|
||||
super.key,
|
||||
required this.pageIndex,
|
||||
required this.innerDrawerKey,
|
||||
});
|
||||
|
||||
final int pageIndex;
|
||||
final GlobalKey<InnerDrawerState> innerDrawerKey;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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 SizedBox(),
|
||||
mainContent: const SizedBox(),
|
||||
);
|
||||
case 2:
|
||||
return const PageBase(
|
||||
title: 'About',
|
||||
scaffoldBody: IntroPage(),
|
||||
);
|
||||
case 3:
|
||||
return const PageBase(
|
||||
title: 'Settings',
|
||||
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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:apidash/extensions/context_extensions.dart';
|
||||
import 'package:apidash/providers/ui_providers.dart';
|
||||
import 'package:apidash/screens/mobile/widgets/page_base.dart';
|
||||
import '../settings_page.dart';
|
||||
import '../intro_page.dart';
|
||||
|
||||
class BottomNavBar extends ConsumerWidget {
|
||||
const BottomNavBar({super.key});
|
||||
@ -48,30 +45,26 @@ class BottomNavBar extends ConsumerWidget {
|
||||
'Variables'),
|
||||
),
|
||||
Expanded(
|
||||
child: customNavigationDestination(context, ref, railIdx, 2,
|
||||
Icons.help, Icons.help_outline, 'About',
|
||||
isNavigator: true, onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const PageBase(
|
||||
title: 'About',
|
||||
scaffoldBody: IntroPage(),
|
||||
)),
|
||||
);
|
||||
}),
|
||||
child: customNavigationDestination(
|
||||
context,
|
||||
ref,
|
||||
railIdx,
|
||||
2,
|
||||
Icons.help,
|
||||
Icons.help_outline,
|
||||
'About',
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: customNavigationDestination(context, ref, railIdx, 3,
|
||||
Icons.settings, Icons.settings_outlined, 'Settings',
|
||||
isNavigator: true, onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const PageBase(
|
||||
title: 'Settings',
|
||||
scaffoldBody: SettingsPage(),
|
||||
)),
|
||||
);
|
||||
}),
|
||||
child: customNavigationDestination(
|
||||
context,
|
||||
ref,
|
||||
railIdx,
|
||||
3,
|
||||
Icons.settings,
|
||||
Icons.settings_outlined,
|
||||
'Settings',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -131,17 +124,6 @@ class NavRail extends ConsumerWidget {
|
||||
Icons.help,
|
||||
Icons.help_outline,
|
||||
'About',
|
||||
isNavigator: true,
|
||||
showLabel: false,
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const PageBase(
|
||||
title: 'About',
|
||||
scaffoldBody: IntroPage(),
|
||||
)),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
customNavigationDestination(
|
||||
@ -152,17 +134,6 @@ class NavRail extends ConsumerWidget {
|
||||
Icons.settings,
|
||||
Icons.settings_outlined,
|
||||
'Settings',
|
||||
isNavigator: true,
|
||||
showLabel: false,
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const PageBase(
|
||||
title: 'Settings',
|
||||
scaffoldBody: SettingsPage(),
|
||||
)),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -179,7 +150,6 @@ Widget customNavigationDestination(
|
||||
IconData selectedIcon,
|
||||
IconData icon,
|
||||
String label, {
|
||||
bool isNavigator = false,
|
||||
bool showLabel = true,
|
||||
Function()? onTap,
|
||||
}) {
|
||||
@ -195,9 +165,9 @@ Widget customNavigationDestination(
|
||||
onTap: isSelected
|
||||
? null
|
||||
: () {
|
||||
if (!isNavigator) {
|
||||
ref.read(navRailIndexStateProvider.notifier).state =
|
||||
buttonIdx;
|
||||
ref.read(navRailIndexStateProvider.notifier).state = buttonIdx;
|
||||
if (railIdx > 1 && buttonIdx <= 1) {
|
||||
ref.read(leftDrawerStateProvider.notifier).state = false;
|
||||
}
|
||||
onTap?.call();
|
||||
},
|
||||
@ -218,9 +188,11 @@ Widget customNavigationDestination(
|
||||
onTap: isSelected
|
||||
? null
|
||||
: () {
|
||||
if (!isNavigator) {
|
||||
ref.read(navRailIndexStateProvider.notifier).state =
|
||||
buttonIdx;
|
||||
ref.read(navRailIndexStateProvider.notifier).state =
|
||||
buttonIdx;
|
||||
if (railIdx > 1 && buttonIdx <= 1) {
|
||||
ref.read(leftDrawerStateProvider.notifier).state =
|
||||
false;
|
||||
}
|
||||
onTap?.call();
|
||||
},
|
||||
|
@ -16,7 +16,8 @@ class PageBase extends ConsumerWidget {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero,
|
||||
padding: const EdgeInsets.only(bottom: 70) +
|
||||
(kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero),
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
|
@ -152,3 +152,41 @@ class RequestDetailsCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SidebarEnvironmentCard extends StatelessWidget {
|
||||
const SidebarEnvironmentCard({
|
||||
super.key,
|
||||
required this.id,
|
||||
this.isGlobal = false,
|
||||
this.isSelected = false,
|
||||
this.isActive = false,
|
||||
this.name,
|
||||
this.editRequestId,
|
||||
this.onTap,
|
||||
this.onDoubleTap,
|
||||
this.onSecondaryTap,
|
||||
this.onChangedNameEditor,
|
||||
this.focusNode,
|
||||
this.onTapOutsideNameEditor,
|
||||
this.onMenuSelected,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final bool isGlobal;
|
||||
final bool isSelected;
|
||||
final bool isActive;
|
||||
final String? name;
|
||||
final String? editRequestId;
|
||||
final void Function()? onTap;
|
||||
final void Function()? onDoubleTap;
|
||||
final void Function()? onSecondaryTap;
|
||||
final Function(String)? onChangedNameEditor;
|
||||
final FocusNode? focusNode;
|
||||
final Function()? onTapOutsideNameEditor;
|
||||
final Function(RequestItemMenuOption)? onMenuSelected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const SizedBox();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
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/consts.dart';
|
||||
import 'package:apidash/providers/ui_providers.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
|
||||
class DashboardSplitView extends StatefulWidget {
|
||||
const DashboardSplitView({
|
||||
@ -110,3 +115,85 @@ class _EqualSplitViewState extends State<EqualSplitView> {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class TwoDrawerSplitView extends HookConsumerWidget {
|
||||
const TwoDrawerSplitView({
|
||||
super.key,
|
||||
required this.innerDrawerKey,
|
||||
required this.offset,
|
||||
required this.mainContent,
|
||||
required this.leftDrawerContent,
|
||||
this.rightDrawerContent,
|
||||
});
|
||||
|
||||
final GlobalKey<InnerDrawerState> innerDrawerKey;
|
||||
final IDOffset offset;
|
||||
final Widget mainContent;
|
||||
final Widget leftDrawerContent;
|
||||
final Widget? rightDrawerContent;
|
||||
|
||||
@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) {
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
16
pubspec.lock
16
pubspec.lock
@ -390,6 +390,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_hooks:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_hooks
|
||||
sha256: cde36b12f7188c85286fba9b38cc5a902e7279f36dd676967106c041dc9dde70
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.20.5"
|
||||
flutter_keyboard_visibility:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -576,6 +584,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
hooks_riverpod:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: hooks_riverpod
|
||||
sha256: "45b2030a18bcd6dbd680c2c91bc3b33e3fe7c323e3acb5ecec93a613e2fbaa8a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.1"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -61,6 +61,8 @@ dependencies:
|
||||
flex_color_scheme: ^7.3.1
|
||||
data_table_2: ^2.5.11
|
||||
file_selector: ^1.0.3
|
||||
hooks_riverpod: ^2.5.1
|
||||
flutter_hooks: ^0.20.5
|
||||
|
||||
dependency_overrides:
|
||||
web: ^0.5.0
|
||||
|
Reference in New Issue
Block a user