Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: desktop responsiveness #408

Merged
37 changes: 18 additions & 19 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:window_manager/window_manager.dart' hide WindowCaption;
import 'widgets/widgets.dart' show WindowCaption;
import 'providers/providers.dart';
import 'screens/screens.dart';
import 'extensions/extensions.dart';
import 'screens/screens.dart';
import 'consts.dart';

class App extends ConsumerStatefulWidget {
Expand Down Expand Up @@ -95,7 +95,7 @@ class _AppState extends ConsumerState<App> with WindowListener {

@override
Widget build(BuildContext context) {
return const Dashboard();
return context.isMediumWindow ? const MobileDashboard() : const Dashboard();
}
}

Expand Down Expand Up @@ -125,24 +125,23 @@ class DashApp extends ConsumerWidget {
visualDensity: VisualDensity.adaptivePlatformDensity,
),
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
home: kIsMobile
? context.isLargeWidth
? const Dashboard()
: const MobileDashboard()
: Stack(
children: [
kIsLinux ? const Dashboard() : const App(),
if (kIsWindows)
SizedBox(
height: 29,
child: WindowCaption(
backgroundColor: Colors.transparent,
brightness:
isDarkMode ? Brightness.dark : Brightness.light,
),
),
],
home: Stack(
children: [
!kIsLinux && !kIsMobile
? const App()
: context.isMediumWindow
? const MobileDashboard()
: const Dashboard(),
if (kIsWindows)
SizedBox(
height: 29,
child: WindowCaption(
backgroundColor: Colors.transparent,
brightness: isDarkMode ? Brightness.dark : Brightness.light,
),
),
],
),
);
}
}
16 changes: 14 additions & 2 deletions lib/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ final kColorLightDanger = Colors.red.withOpacity(0.9);
const kColorDarkDanger = Color(0xffcf6679);

const kWindowTitle = "API Dash";
const kMinWindowSize = Size(900, 600);
const kMinWindowSize = Size(320, 600);
const kMinInitialWindowWidth = 1200.0;
const kMinInitialWindowHeight = 800.0;
const kMinRequestEditorDetailsCardPaneSize = 300.0;
const kLargeMobileWidth = 600.0;
const kCompactWindowWidth = 600.0;
const kMediumWindowWidth = 840.0;
const kExpandedWindowWidth = 1200.0;
const kLargeWindowWidth = 1600.0;

const kColorSchemeSeed = Colors.blue;
final kFontFamily = GoogleFonts.openSans().fontFamily;
Expand Down Expand Up @@ -106,12 +109,21 @@ const kP8CollectionPane = EdgeInsets.only(
//right: 4.0,
// bottom: 8.0,
);
const kPt28 = EdgeInsets.only(
top: 28,
);
const kPt32 = EdgeInsets.only(
top: 32,
);
const kPb10 = EdgeInsets.only(
bottom: 10,
);
const kPb15 = EdgeInsets.only(
bottom: 15,
);
const kPb70 = EdgeInsets.only(
bottom: 70,
);
const kHSpacer4 = SizedBox(width: 4);
const kHSpacer5 = SizedBox(width: 5);
const kHSpacer10 = SizedBox(width: 10);
Expand Down
20 changes: 16 additions & 4 deletions lib/extensions/context_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@ import 'package:apidash/consts.dart';
import 'package:flutter/material.dart';

extension MediaQueryExtension on BuildContext {
bool get isLargeWidth =>
MediaQuery.of(this).size.width > kMinWindowSize.width;
bool get isCompactWindow =>
MediaQuery.of(this).size.width < kCompactWindowWidth;

bool get isMobile =>
kIsMobile && MediaQuery.of(this).size.width < kMinWindowSize.width;
bool get isMediumWindow =>
MediaQuery.of(this).size.width < kMediumWindowWidth;

bool get isExpandedWindow =>
MediaQuery.of(this).size.width < kExpandedWindowWidth;

bool get isLargeWindow => MediaQuery.of(this).size.width < kLargeWindowWidth;

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;
}
8 changes: 4 additions & 4 deletions lib/providers/ui_providers.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
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);
final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
Expand Down
18 changes: 16 additions & 2 deletions lib/screens/dashboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ class Dashboard extends ConsumerWidget {
'Requests',
style: Theme.of(context).textTheme.labelSmall,
),
kVSpacer10,
IconButton(
isSelected: railIdx == 1,
onPressed: () {
ref.read(navRailIndexStateProvider.notifier).state = 1;
},
icon: const Icon(Icons.computer_outlined),
selectedIcon: const Icon(Icons.computer_rounded),
),
Text(
'Variables',
style: Theme.of(context).textTheme.labelSmall,
),
],
),
Expanded(
Expand All @@ -45,12 +58,12 @@ class Dashboard extends ConsumerWidget {
children: [
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: bottomButton(context, ref, railIdx, 1,
child: bottomButton(context, ref, railIdx, 2,
Icons.help, Icons.help_outline),
),
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: bottomButton(context, ref, railIdx, 2,
child: bottomButton(context, ref, railIdx, 3,
Icons.settings, Icons.settings_outlined),
),
],
Expand Down Expand Up @@ -81,6 +94,7 @@ class Dashboard extends ConsumerWidget {
index: railIdx,
children: const [
HomePage(),
SizedBox(),
IntroPage(),
SettingsPage(),
],
Expand Down
171 changes: 90 additions & 81 deletions lib/screens/home_page/collection_pane.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,91 +22,101 @@ class CollectionPane extends ConsumerWidget {
child: CircularProgressIndicator(),
);
}
return Padding(
padding: kIsMacOS ? kP24CollectionPane : kP8CollectionPane,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: kPe8,
child: Wrap(
alignment: WrapAlignment.spaceBetween,
children: [
TextButton.icon(
onPressed: (savingData || !hasUnsavedChanges)
? null
: () async {
overlayWidget.show(
widget:
const SavingOverlay(saveCompleted: false));
return Drawer(
shape: const ContinuousRectangleBorder(),
backgroundColor: Theme.of(context).colorScheme.surface,
surfaceTintColor: kColorTransparent,
child: Padding(
padding: (!context.isMediumWindow && kIsMacOS
? kP24CollectionPane
: kP8CollectionPane) +
(context.isMediumWindow ? kPb70 : EdgeInsets.zero),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: kPe8,
child: Wrap(
alignment: WrapAlignment.spaceBetween,
children: [
TextButton.icon(
onPressed: (savingData || !hasUnsavedChanges)
? null
: () async {
overlayWidget.show(
widget:
const SavingOverlay(saveCompleted: false));

await ref
.read(collectionStateNotifierProvider.notifier)
.saveData();
overlayWidget.hide();
overlayWidget.show(
widget: const SavingOverlay(saveCompleted: true));
await Future.delayed(const Duration(seconds: 1));
overlayWidget.hide();
},
icon: const Icon(
Icons.save,
size: 20,
),
label: const Text(
kLabelSave,
style: kTextStyleButton,
await ref
.read(collectionStateNotifierProvider.notifier)
.saveData();
overlayWidget.hide();
overlayWidget.show(
widget:
const SavingOverlay(saveCompleted: true));
await Future.delayed(const Duration(seconds: 1));
overlayWidget.hide();
},
icon: const Icon(
Icons.save,
size: 20,
),
label: const Text(
kLabelSave,
style: kTextStyleButton,
),
),
),
//const Spacer(),
ElevatedButton(
onPressed: () {
ref.read(collectionStateNotifierProvider.notifier).add();
},
child: const Text(
kLabelPlusNew,
style: kTextStyleButton,
//const Spacer(),
ElevatedButton(
onPressed: () {
ref.read(collectionStateNotifierProvider.notifier).add();
},
child: const Text(
kLabelPlusNew,
style: kTextStyleButton,
),
),
),
],
),
),
kVSpacer10,
Container(
margin: const EdgeInsets.only(right: 8),
decoration: BoxDecoration(
borderRadius: kBorderRadius8,
border: Border.all(
color: Theme.of(context).colorScheme.surfaceVariant,
],
),
),
child: Row(
children: [
kHSpacer5,
Icon(
Icons.filter_alt,
size: 18,
color: Theme.of(context).colorScheme.secondary,
kVSpacer10,
Container(
margin: const EdgeInsets.only(right: 8),
decoration: BoxDecoration(
borderRadius: kBorderRadius8,
border: Border.all(
color: Theme.of(context).colorScheme.surfaceVariant,
),
kHSpacer5,
Expanded(
child: RawTextField(
style: Theme.of(context).textTheme.bodyMedium,
hintText: "Filter by name or URL",
onChanged: (value) {
ref.read(searchQueryProvider.notifier).state =
value.toLowerCase();
},
),
child: Row(
children: [
kHSpacer5,
Icon(
Icons.filter_alt,
size: 18,
color: Theme.of(context).colorScheme.secondary,
),
),
],
kHSpacer5,
Expanded(
child: RawTextField(
style: Theme.of(context).textTheme.bodyMedium,
hintText: "Filter by name or URL",
onChanged: (value) {
ref.read(searchQueryProvider.notifier).state =
value.toLowerCase();
},
),
),
],
),
),
kVSpacer10,
const Expanded(
child: RequestList(),
),
),
kVSpacer10,
const Expanded(
child: RequestList(),
),
],
kVSpacer5
],
),
),
);
}
Expand Down Expand Up @@ -150,7 +160,7 @@ class _RequestListState extends ConsumerState<RequestList> {
radius: const Radius.circular(12),
child: filterQuery.isEmpty
? ReorderableListView.builder(
padding: context.isMobile
padding: context.isMediumWindow
? EdgeInsets.only(
bottom: MediaQuery.paddingOf(context).bottom,
right: 8,
Expand Down Expand Up @@ -198,7 +208,7 @@ class _RequestListState extends ConsumerState<RequestList> {
},
)
: ListView(
padding: kIsMobile
padding: context.isMediumWindow
? EdgeInsets.only(
bottom: MediaQuery.paddingOf(context).bottom,
right: 8,
Expand Down Expand Up @@ -240,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,
Expand All @@ -250,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: () {
Expand Down
Loading