Skip to content

Commit b0c4f71

Browse files
committed
wip: desktop responsiveness
1 parent a49bcec commit b0c4f71

File tree

17 files changed

+299
-257
lines changed

17 files changed

+299
-257
lines changed

lib/app.dart

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import 'package:window_manager/window_manager.dart' hide WindowCaption;
66
import 'widgets/widgets.dart' show WindowCaption;
77
import 'providers/providers.dart';
88
import 'screens/screens.dart';
9-
import 'extensions/extensions.dart';
109
import 'consts.dart';
1110

1211
class App extends ConsumerStatefulWidget {
@@ -125,24 +124,23 @@ class DashApp extends ConsumerWidget {
125124
visualDensity: VisualDensity.adaptivePlatformDensity,
126125
),
127126
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
128-
home: kIsMobile
129-
? context.isLargeWidth
130-
? const Dashboard()
131-
: const MobileDashboard()
132-
: Stack(
133-
children: [
134-
kIsLinux ? const Dashboard() : const App(),
135-
if (kIsWindows)
136-
SizedBox(
137-
height: 29,
138-
child: WindowCaption(
139-
backgroundColor: Colors.transparent,
140-
brightness:
141-
isDarkMode ? Brightness.dark : Brightness.light,
142-
),
143-
),
144-
],
127+
home: Stack(
128+
children: [
129+
context.isMediumWindow
130+
? const MobileDashboard()
131+
: !kIsLinux && !kIsMobile
132+
? const App()
133+
: const Dashboard(),
134+
if (kIsWindows)
135+
SizedBox(
136+
height: 29,
137+
child: WindowCaption(
138+
backgroundColor: Colors.transparent,
139+
brightness: isDarkMode ? Brightness.dark : Brightness.light,
140+
),
145141
),
142+
],
143+
),
146144
);
147145
}
148146
}

lib/consts.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ final kColorLightDanger = Colors.red.withOpacity(0.9);
3535
const kColorDarkDanger = Color(0xffcf6679);
3636

3737
const kWindowTitle = "API Dash";
38-
const kMinWindowSize = Size(900, 600);
38+
const kMinWindowSize = Size(320, 640);
3939
const kMinInitialWindowWidth = 1200.0;
4040
const kMinInitialWindowHeight = 800.0;
4141
const kMinRequestEditorDetailsCardPaneSize = 300.0;
42-
const kLargeMobileWidth = 600.0;
42+
const kCompactWindowWidth = 600.0;
43+
const kMediumWindowWidth = 840.0;
44+
const kExpandedWindowWidth = 1200.0;
45+
const kLargeWindowWidth = 1600.0;
4346

4447
const kColorSchemeSeed = Colors.blue;
4548
final kFontFamily = GoogleFonts.openSans().fontFamily;
@@ -106,6 +109,8 @@ const kP8CollectionPane = EdgeInsets.only(
106109
//right: 4.0,
107110
// bottom: 8.0,
108111
);
112+
const kPt28 = EdgeInsets.only(top: 28);
113+
const kPt32 = EdgeInsets.only(top: 32);
109114
const kPb10 = EdgeInsets.only(
110115
bottom: 10,
111116
);

lib/extensions/context_extensions.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@ import 'package:apidash/consts.dart';
22
import 'package:flutter/material.dart';
33

44
extension MediaQueryExtension on BuildContext {
5-
bool get isLargeWidth =>
6-
MediaQuery.of(this).size.width > kMinWindowSize.width;
5+
bool get isCompactWindow =>
6+
MediaQuery.of(this).size.width < kCompactWindowWidth;
77

8-
bool get isMobile =>
9-
kIsMobile && MediaQuery.of(this).size.width < kMinWindowSize.width;
8+
bool get isMediumWindow =>
9+
MediaQuery.of(this).size.width < kMediumWindowWidth;
10+
11+
bool get isExpandedWindow =>
12+
MediaQuery.of(this).size.width < kExpandedWindowWidth;
13+
14+
bool get isLargeWindow => MediaQuery.of(this).size.width < kLargeWindowWidth;
15+
16+
bool get isExtraLargeWindow =>
17+
MediaQuery.of(this).size.width > kLargeWindowWidth;
1018
}

lib/screens/home_page/collection_pane.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class _RequestListState extends ConsumerState<RequestList> {
150150
radius: const Radius.circular(12),
151151
child: filterQuery.isEmpty
152152
? ReorderableListView.builder(
153-
padding: context.isMobile
153+
padding: context.isMediumWindow
154154
? EdgeInsets.only(
155155
bottom: MediaQuery.paddingOf(context).bottom,
156156
right: 8,
@@ -198,7 +198,7 @@ class _RequestListState extends ConsumerState<RequestList> {
198198
},
199199
)
200200
: ListView(
201-
padding: kIsMobile
201+
padding: context.isMediumWindow
202202
? EdgeInsets.only(
203203
bottom: MediaQuery.paddingOf(context).bottom,
204204
right: 8,

lib/screens/home_page/editor_pane/editor_request.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class RequestEditor extends StatelessWidget {
1212

1313
@override
1414
Widget build(BuildContext context) {
15-
return context.isMobile
15+
return context.isMediumWindow
1616
? const Padding(
1717
padding: kPb10,
1818
child: Column(

lib/screens/home_page/editor_pane/url_card.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ class EditorPaneRequestURLCard extends StatelessWidget {
2121
child: Padding(
2222
padding: EdgeInsets.symmetric(
2323
vertical: 5,
24-
horizontal: !context.isMobile ? 20 : 6,
24+
horizontal: !context.isMediumWindow ? 20 : 6,
2525
),
26-
child: context.isMobile
26+
child: context.isMediumWindow
2727
? const Row(
2828
children: [
2929
DropdownButtonHTTPMethod(),

lib/screens/mobile/dashboard.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ 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';
7-
import '../../providers/providers.dart';
7+
import 'package:apidash/extensions/extensions.dart';
8+
import 'package:apidash/providers/providers.dart';
89
import 'navbar.dart';
910
import 'widgets/left_drawer.dart';
1011
import 'requests_page.dart';
@@ -44,7 +45,6 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
4445
) {
4546
final GlobalKey<InnerDrawerState> innerDrawerKey =
4647
ref.watch(mobileDrawerKeyProvider);
47-
final isLargeMobile = MediaQuery.sizeOf(context).width > kLargeMobileWidth;
4848
return AnnotatedRegion<SystemUiOverlayStyle>(
4949
value: FlexColorScheme.themedSystemNavigationBar(
5050
context,
@@ -59,7 +59,7 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
5959
swipe: true,
6060
swipeChild: true,
6161
onTapClose: true,
62-
offset: isLargeMobile
62+
offset: !context.isCompactWindow
6363
? const IDOffset.only(left: 0.1, right: 1)
6464
: const IDOffset.only(left: 0.7, right: 1),
6565
boxShadow: [
@@ -72,8 +72,8 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
7272
colorTransitionChild: Colors.transparent,
7373
colorTransitionScaffold: Colors.transparent,
7474
rightAnimationType: InnerDrawerAnimation.linear,
75-
backgroundDecoration:
76-
BoxDecoration(color: Theme.of(context).colorScheme.surface),
75+
backgroundDecoration: BoxDecoration(
76+
color: Theme.of(context).colorScheme.onInverseSurface),
7777
onDragUpdate: (value, direction) {
7878
drawerDirection.value = direction;
7979
if (value > 0.98 && direction == InnerDrawerDirection.start) {
@@ -105,6 +105,7 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
105105
borderRadius:
106106
const BorderRadius.only(topLeft: Radius.circular(8)),
107107
child: SafeArea(
108+
minimum: kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero,
108109
bottom: false,
109110
child: RequestsPage(
110111
innerDrawerKey: innerDrawerKey,
@@ -113,7 +114,7 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
113114
),
114115
),
115116
),
116-
if (!isLargeMobile)
117+
if (context.isCompactWindow)
117118
AnimatedPositioned(
118119
bottom: isLeftDrawerOpen
119120
? 0

lib/screens/mobile/navbar.dart

Lines changed: 70 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import 'package:apidash/providers/ui_providers.dart';
2-
import 'package:apidash/screens/mobile/widgets/page_base.dart';
31
import 'package:flutter/material.dart';
42
import 'package:flutter_riverpod/flutter_riverpod.dart';
3+
import 'package:apidash/extensions/context_extensions.dart';
4+
import 'package:apidash/providers/ui_providers.dart';
5+
import 'package:apidash/screens/mobile/widgets/page_base.dart';
56
import '../settings_page.dart';
67
import '../intro_page.dart';
78

@@ -183,67 +184,76 @@ Widget customNavigationDestination(
183184
Function()? onTap,
184185
}) {
185186
bool isSelected = railIdx == buttonIdx;
186-
return Tooltip(
187-
message: label,
188-
triggerMode: TooltipTriggerMode.longPress,
189-
verticalOffset: 42,
190-
child: GestureDetector(
191-
behavior: HitTestBehavior.translucent,
192-
onTap: isSelected
193-
? null
194-
: () {
195-
if (!isNavigator) {
196-
ref.read(navRailIndexStateProvider.notifier).state = buttonIdx;
197-
}
198-
onTap?.call();
199-
},
200-
child: Column(
201-
mainAxisAlignment: MainAxisAlignment.center,
202-
children: [
203-
Ink(
204-
width: 65,
205-
height: 32,
206-
decoration: BoxDecoration(
207-
color: isSelected
208-
? Theme.of(context).colorScheme.secondaryContainer
209-
: Colors.transparent,
210-
borderRadius: BorderRadius.circular(30),
211-
),
212-
child: InkWell(
213-
borderRadius: BorderRadius.circular(30),
214-
onTap: isSelected
215-
? null
216-
: () {
217-
if (!isNavigator) {
218-
ref.read(navRailIndexStateProvider.notifier).state =
219-
buttonIdx;
220-
}
221-
onTap?.call();
222-
},
223-
child: Icon(
224-
isSelected ? selectedIcon : icon,
187+
return TooltipVisibility(
188+
visible: context.isCompactWindow,
189+
child: Tooltip(
190+
message: label,
191+
triggerMode: TooltipTriggerMode.longPress,
192+
verticalOffset: 42,
193+
child: GestureDetector(
194+
behavior: HitTestBehavior.translucent,
195+
onTap: isSelected
196+
? null
197+
: () {
198+
if (!isNavigator) {
199+
ref.read(navRailIndexStateProvider.notifier).state =
200+
buttonIdx;
201+
}
202+
onTap?.call();
203+
},
204+
child: Column(
205+
mainAxisAlignment: MainAxisAlignment.center,
206+
children: [
207+
Ink(
208+
width: 65,
209+
height: 32,
210+
decoration: BoxDecoration(
225211
color: isSelected
226-
? Theme.of(context).colorScheme.onSecondaryContainer
227-
: Theme.of(context).colorScheme.onSurface.withOpacity(0.65),
212+
? Theme.of(context).colorScheme.secondaryContainer
213+
: Colors.transparent,
214+
borderRadius: BorderRadius.circular(30),
215+
),
216+
child: InkWell(
217+
borderRadius: BorderRadius.circular(30),
218+
onTap: isSelected
219+
? null
220+
: () {
221+
if (!isNavigator) {
222+
ref.read(navRailIndexStateProvider.notifier).state =
223+
buttonIdx;
224+
}
225+
onTap?.call();
226+
},
227+
child: Icon(
228+
isSelected ? selectedIcon : icon,
229+
color: isSelected
230+
? Theme.of(context).colorScheme.onSecondaryContainer
231+
: Theme.of(context)
232+
.colorScheme
233+
.onSurface
234+
.withOpacity(0.65),
235+
),
228236
),
229237
),
230-
),
231-
showLabel ? const SizedBox(height: 4) : const SizedBox.shrink(),
232-
showLabel
233-
? Text(
234-
label,
235-
style: Theme.of(context).textTheme.labelSmall!.copyWith(
236-
fontWeight: FontWeight.w600,
237-
color: isSelected
238-
? Theme.of(context).colorScheme.onSecondaryContainer
239-
: Theme.of(context)
240-
.colorScheme
241-
.onSurface
242-
.withOpacity(0.65),
243-
),
244-
)
245-
: const SizedBox.shrink(),
246-
],
238+
showLabel ? const SizedBox(height: 4) : const SizedBox.shrink(),
239+
showLabel
240+
? Text(
241+
label,
242+
style: Theme.of(context).textTheme.labelSmall!.copyWith(
243+
fontWeight: FontWeight.w600,
244+
color: isSelected
245+
? Theme.of(context)
246+
.colorScheme
247+
.onSecondaryContainer
248+
: Theme.of(context)
249+
.colorScheme
250+
.onSurface
251+
.withOpacity(0.65),
252+
),
253+
)
254+
: const SizedBox.shrink(),
255+
],
256+
),
247257
),
248258
),
249259
);

lib/screens/mobile/response_drawer.dart

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,37 @@
11
import 'package:flutter/material.dart';
2+
import 'package:apidash/consts.dart';
23
import '../home_page/editor_pane/details_card/response_pane.dart';
34

45
class ResponseDrawer extends StatelessWidget {
56
const ResponseDrawer({super.key});
67

78
@override
89
Widget build(BuildContext context) {
9-
return Scaffold(
10-
appBar: AppBar(
11-
backgroundColor: Theme.of(context).colorScheme.surface,
12-
shape: const RoundedRectangleBorder(
13-
borderRadius: BorderRadius.vertical(top: Radius.circular(8)),
10+
return Container(
11+
padding: kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero,
12+
color: Theme.of(context).colorScheme.surface,
13+
child: Scaffold(
14+
appBar: AppBar(
15+
backgroundColor: Theme.of(context).colorScheme.surface,
16+
shape: const RoundedRectangleBorder(
17+
borderRadius: BorderRadius.vertical(top: Radius.circular(8)),
18+
),
19+
leading: IconButton(
20+
icon: const Icon(Icons.arrow_back_rounded),
21+
onPressed: () {
22+
Navigator.of(context).pop();
23+
},
24+
),
25+
scrolledUnderElevation: 0,
26+
centerTitle: true,
27+
title: const Text("Response"),
1428
),
15-
leading: IconButton(
16-
icon: const Icon(Icons.arrow_back_rounded),
17-
onPressed: () {
18-
Navigator.of(context).pop();
19-
},
29+
body: Padding(
30+
padding: EdgeInsets.only(
31+
bottom: MediaQuery.paddingOf(context).bottom,
32+
),
33+
child: const ResponsePane(),
2034
),
21-
scrolledUnderElevation: 0,
22-
centerTitle: true,
23-
title: const Text("Response"),
24-
),
25-
body: Padding(
26-
padding: EdgeInsets.only(
27-
bottom: MediaQuery.paddingOf(context).bottom,
28-
),
29-
child: const ResponsePane(),
3035
),
3136
);
3237
}

0 commit comments

Comments
 (0)