Skip to content

Commit aa5fec6

Browse files
committed
fix: page navigation
1 parent f0175ff commit aa5fec6

File tree

12 files changed

+367
-138
lines changed

12 files changed

+367
-138
lines changed

lib/providers/ui_providers.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:inner_drawer/inner_drawer.dart';
44

55
final mobileDrawerKeyProvider = StateProvider<GlobalKey<InnerDrawerState>>(
66
(ref) => GlobalKey<InnerDrawerState>());
7+
final leftDrawerStateProvider = StateProvider<bool>((ref) => false);
78
final navRailIndexStateProvider = StateProvider<int>((ref) => 0);
89
final selectedIdEditStateProvider = StateProvider<String?>((ref) => null);
910
final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
@@ -29,4 +30,5 @@ final nameTextFieldFocusNodeProvider =
2930
return focusNode;
3031
});
3132

32-
final searchQueryProvider = StateProvider<String>((ref) => '');
33+
final collectionSearchQueryProvider = StateProvider<String>((ref) => '');
34+
final environmentSearchQueryProvider = StateProvider<String>((ref) => '');

lib/screens/dashboard.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ class Dashboard extends ConsumerWidget {
5858
children: [
5959
Padding(
6060
padding: const EdgeInsets.only(bottom: 16.0),
61+
child: bottomButton(context, ref, railIdx, 2,
6162
child: bottomButton(context, ref, railIdx, 2,
6263
Icons.help, Icons.help_outline),
6364
),
6465
Padding(
6566
padding: const EdgeInsets.only(bottom: 16.0),
67+
child: bottomButton(context, ref, railIdx, 3,
6668
child: bottomButton(context, ref, railIdx, 3,
6769
Icons.settings, Icons.settings_outlined),
6870
),
@@ -95,6 +97,7 @@ class Dashboard extends ConsumerWidget {
9597
children: const [
9698
HomePage(),
9799
SizedBox(),
100+
SizedBox(),
98101
IntroPage(),
99102
SettingsPage(),
100103
],

lib/screens/envvar/environment_page.dart

Whitespace-only changes.
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import 'package:apidash/consts.dart';
2+
import 'package:apidash/extensions/extensions.dart';
3+
import 'package:apidash/models/environment_model.dart';
4+
import 'package:apidash/providers/providers.dart';
5+
import 'package:flutter/material.dart';
6+
import 'package:hooks_riverpod/hooks_riverpod.dart';
7+
import 'package:flutter_hooks/flutter_hooks.dart';
8+
9+
class EnvironmentsPane extends ConsumerWidget {
10+
const EnvironmentsPane({
11+
super.key,
12+
});
13+
14+
@override
15+
Widget build(BuildContext context, WidgetRef ref) {
16+
return const SizedBox();
17+
}
18+
}
19+
20+
class EnvironmentsList extends HookConsumerWidget {
21+
const EnvironmentsList({
22+
super.key,
23+
});
24+
25+
@override
26+
Widget build(BuildContext context, WidgetRef ref) {
27+
final environmentSequence = ref.watch(environmentSequenceProvider);
28+
final environmentItems = ref.watch(environmentsStateNotifierProvider)!;
29+
final alwaysShowEnvironmentsPaneScrollbar = ref.watch(settingsProvider
30+
.select((value) => value.alwaysShowCollectionPaneScrollbar));
31+
final filterQuery = ref.watch(environmentSearchQueryProvider).trim();
32+
33+
ScrollController scrollController = useScrollController();
34+
return Scrollbar(
35+
controller: scrollController,
36+
thumbVisibility: alwaysShowEnvironmentsPaneScrollbar,
37+
radius: const Radius.circular(12),
38+
child: filterQuery.isEmpty
39+
? ReorderableListView.builder(
40+
padding: context.isMediumWindow
41+
? EdgeInsets.only(
42+
bottom: MediaQuery.paddingOf(context).bottom,
43+
right: 8,
44+
)
45+
: kPe8,
46+
scrollController: scrollController,
47+
buildDefaultDragHandles: false,
48+
itemCount: environmentSequence.length,
49+
onReorder: (int oldIndex, int newIndex) {
50+
if (oldIndex < newIndex) {
51+
newIndex -= 1;
52+
}
53+
if (oldIndex != newIndex) {
54+
ref
55+
.read(collectionStateNotifierProvider.notifier)
56+
.reorder(oldIndex, newIndex);
57+
}
58+
},
59+
itemBuilder: (context, index) {
60+
var id = environmentSequence[index];
61+
if (kIsMobile) {
62+
return ReorderableDelayedDragStartListener(
63+
key: ValueKey(id),
64+
index: index,
65+
child: Padding(
66+
padding: kP1,
67+
child: EnvironmentItem(
68+
id: id,
69+
environmentModel: environmentItems[id]!,
70+
),
71+
),
72+
);
73+
}
74+
return ReorderableDragStartListener(
75+
key: ValueKey(id),
76+
index: index,
77+
child: Padding(
78+
padding: kP1,
79+
child: EnvironmentItem(
80+
id: id,
81+
environmentModel: environmentItems[id]!,
82+
),
83+
),
84+
);
85+
},
86+
)
87+
: ListView(
88+
padding: context.isMediumWindow
89+
? EdgeInsets.only(
90+
bottom: MediaQuery.paddingOf(context).bottom,
91+
right: 8,
92+
)
93+
: kPe8,
94+
controller: scrollController,
95+
children: environmentSequence.map((id) {
96+
var item = environmentItems[id]!;
97+
if (item.name.toLowerCase().contains(filterQuery)) {
98+
return Padding(
99+
padding: kP1,
100+
child: EnvironmentItem(
101+
id: id,
102+
environmentModel: item,
103+
),
104+
);
105+
}
106+
return const SizedBox();
107+
}).toList(),
108+
),
109+
);
110+
}
111+
}
112+
113+
class EnvironmentItem extends ConsumerWidget {
114+
const EnvironmentItem({
115+
super.key,
116+
required this.id,
117+
required this.environmentModel,
118+
});
119+
120+
final String id;
121+
final EnvironmentModel environmentModel;
122+
123+
@override
124+
Widget build(BuildContext context, WidgetRef ref) {
125+
final selectedId = ref.watch(selectedEnvironmentIdProvider);
126+
127+
return Text(environmentModel.name);
128+
}
129+
}

lib/screens/home_page/collection_pane.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class CollectionPane extends ConsumerWidget {
9494
style: Theme.of(context).textTheme.bodyMedium,
9595
hintText: "Filter by name or URL",
9696
onChanged: (value) {
97-
ref.read(searchQueryProvider.notifier).state =
97+
ref.read(collectionSearchQueryProvider.notifier).state =
9898
value.toLowerCase();
9999
},
100100
),
@@ -142,7 +142,7 @@ class _RequestListState extends ConsumerState<RequestList> {
142142
final requestItems = ref.watch(collectionStateNotifierProvider)!;
143143
final alwaysShowCollectionPaneScrollbar = ref.watch(settingsProvider
144144
.select((value) => value.alwaysShowCollectionPaneScrollbar));
145-
final filterQuery = ref.watch(searchQueryProvider).trim();
145+
final filterQuery = ref.watch(collectionSearchQueryProvider).trim();
146146

147147
return Scrollbar(
148148
controller: controller,

lib/screens/mobile/dashboard.dart

Lines changed: 59 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import 'package:apidash/consts.dart';
1+
import 'package:apidash/widgets/splitviews.dart';
22
import 'package:flutter/material.dart';
33
import 'package:flutter/services.dart';
44
import 'package:flutter_riverpod/flutter_riverpod.dart';
55
import 'package:inner_drawer/inner_drawer.dart';
66
import 'package:flex_color_scheme/flex_color_scheme.dart';
77
import 'package:apidash/extensions/extensions.dart';
88
import 'package:apidash/providers/providers.dart';
9+
import '../intro_page.dart';
10+
import '../settings_page.dart';
911
import 'navbar.dart';
10-
import 'widgets/left_drawer.dart';
1112
import 'requests_page.dart';
1213
import 'response_drawer.dart';
1314
import '../home_page/collection_pane.dart';
15+
import 'widgets/page_base.dart';
1416

1517
class MobileDashboard extends ConsumerStatefulWidget {
1618
const MobileDashboard({super.key});
@@ -20,31 +22,14 @@ class MobileDashboard extends ConsumerStatefulWidget {
2022
}
2123

2224
class _MobileDashboardState extends ConsumerState<MobileDashboard> {
23-
late Color backgroundColor;
24-
bool isLeftDrawerOpen = false;
25-
ValueNotifier<double> dragPosition = ValueNotifier(0);
26-
ValueNotifier<InnerDrawerDirection?> drawerDirection =
27-
ValueNotifier(InnerDrawerDirection.start);
28-
29-
Color calculateBackgroundColor(double dragPosition) {
30-
Color start = Theme.of(context).colorScheme.surface;
31-
Color end = Theme.of(context).colorScheme.onInverseSurface;
32-
return dragPosition == 0 ? start : end;
33-
}
34-
35-
@override
36-
void dispose() {
37-
super.dispose();
38-
dragPosition.dispose();
39-
drawerDirection.dispose();
40-
}
41-
4225
@override
4326
Widget build(
4427
BuildContext context,
4528
) {
29+
final railIdx = ref.watch(navRailIndexStateProvider);
4630
final GlobalKey<InnerDrawerState> innerDrawerKey =
4731
ref.watch(mobileDrawerKeyProvider);
32+
final isLeftDrawerOpen = ref.watch(leftDrawerStateProvider);
4833
return AnnotatedRegion<SystemUiOverlayStyle>(
4934
value: FlexColorScheme.themedSystemNavigationBar(
5035
context,
@@ -54,65 +39,9 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
5439
child: Stack(
5540
alignment: AlignmentDirectional.bottomCenter,
5641
children: [
57-
InnerDrawer(
58-
key: innerDrawerKey,
59-
swipe: true,
60-
swipeChild: true,
61-
onTapClose: true,
62-
offset: !context.isCompactWindow
63-
? const IDOffset.only(left: 0.1, right: 1)
64-
: const IDOffset.only(left: 0.7, right: 1),
65-
boxShadow: [
66-
BoxShadow(
67-
offset: const Offset(1, 0),
68-
color: Theme.of(context).colorScheme.onInverseSurface,
69-
blurRadius: 0,
70-
),
71-
],
72-
colorTransitionChild: Colors.transparent,
73-
colorTransitionScaffold: Colors.transparent,
74-
rightAnimationType: InnerDrawerAnimation.linear,
75-
backgroundDecoration: BoxDecoration(
76-
color: Theme.of(context).colorScheme.onInverseSurface),
77-
onDragUpdate: (value, direction) {
78-
drawerDirection.value = direction;
79-
if (value > 0.98 && direction == InnerDrawerDirection.start) {
80-
dragPosition.value = 1;
81-
} else {
82-
dragPosition.value = 0;
83-
}
84-
},
85-
innerDrawerCallback: (isOpened) {
86-
if (drawerDirection.value == InnerDrawerDirection.start) {
87-
setState(() {
88-
isLeftDrawerOpen = isOpened;
89-
});
90-
}
91-
},
92-
leftChild: const LeftDrawer(
93-
drawerContent: CollectionPane(),
94-
),
95-
rightChild: const ResponseDrawer(),
96-
scaffold: ValueListenableBuilder<double>(
97-
valueListenable: dragPosition,
98-
builder: (context, value, child) {
99-
return Container(
100-
color: calculateBackgroundColor(value),
101-
child: child,
102-
);
103-
},
104-
child: ClipRRect(
105-
borderRadius:
106-
const BorderRadius.only(topLeft: Radius.circular(8)),
107-
child: SafeArea(
108-
minimum: kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero,
109-
bottom: false,
110-
child: RequestsPage(
111-
innerDrawerKey: innerDrawerKey,
112-
),
113-
),
114-
),
115-
),
42+
PageBranch(
43+
pageIndex: railIdx,
44+
innerDrawerKey: innerDrawerKey,
11645
),
11746
if (context.isCompactWindow)
11847
AnimatedPositioned(
@@ -131,3 +60,53 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
13160
);
13261
}
13362
}
63+
64+
class PageBranch extends StatelessWidget {
65+
const PageBranch({
66+
super.key,
67+
required this.pageIndex,
68+
required this.innerDrawerKey,
69+
});
70+
71+
final int pageIndex;
72+
final GlobalKey<InnerDrawerState> innerDrawerKey;
73+
74+
@override
75+
Widget build(BuildContext context) {
76+
switch (pageIndex) {
77+
case 1:
78+
return TwoDrawerSplitView(
79+
key: const ValueKey('env'),
80+
innerDrawerKey: innerDrawerKey,
81+
offset: !context.isCompactWindow
82+
? const IDOffset.only(left: 0.1)
83+
: const IDOffset.only(left: 0.7),
84+
leftDrawerContent: const SizedBox(),
85+
mainContent: const SizedBox(),
86+
);
87+
case 2:
88+
return const PageBase(
89+
title: 'About',
90+
scaffoldBody: IntroPage(),
91+
);
92+
case 3:
93+
return const PageBase(
94+
title: 'Settings',
95+
scaffoldBody: SettingsPage(),
96+
);
97+
default:
98+
return TwoDrawerSplitView(
99+
key: const ValueKey('home'),
100+
innerDrawerKey: innerDrawerKey,
101+
offset: !context.isCompactWindow
102+
? const IDOffset.only(left: 0.1, right: 1)
103+
: const IDOffset.only(left: 0.7, right: 1),
104+
leftDrawerContent: const CollectionPane(),
105+
rightDrawerContent: const ResponseDrawer(),
106+
mainContent: RequestsPage(
107+
innerDrawerKey: innerDrawerKey,
108+
),
109+
);
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)