diff --git a/lib/app.dart b/lib/app.dart index ac6f708b..4d51a553 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -140,7 +140,7 @@ class DashApp extends ConsumerWidget { ? const App() : context.isMediumWindow ? const MobileDashboard() - : const Dashboard(), + : const DesktopDashboard(), if (kIsWindows) SizedBox( height: 29, diff --git a/lib/common/utils.dart b/lib/common/utils.dart index 8eaf2b2c..cf61ce22 100644 --- a/lib/common/utils.dart +++ b/lib/common/utils.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:apidash/providers/providers.dart'; import 'package:apidash/utils/utils.dart'; import 'package:apidash/widgets/widgets.dart'; @@ -18,3 +20,14 @@ Future saveCollection( sm.hideCurrentSnackBar(); sm.showSnackBar(getSnackBar(message, small: false)); } + +Future saveData(BuildContext context, WidgetRef ref) async { + final overlayWidget = OverlayWidgetTemplate(context: context); + overlayWidget.show(widget: const SavingOverlay(saveCompleted: false)); + await ref.read(collectionStateNotifierProvider.notifier).saveData(); + await ref.read(environmentsStateNotifierProvider.notifier).saveEnvironments(); + overlayWidget.hide(); + overlayWidget.show(widget: const SavingOverlay(saveCompleted: true)); + await Future.delayed(const Duration(seconds: 1)); + overlayWidget.hide(); +} diff --git a/lib/screens/common_widgets/sidebar_save_button.dart b/lib/screens/common_widgets/sidebar_save_button.dart index 46390ac4..6084651f 100644 --- a/lib/screens/common_widgets/sidebar_save_button.dart +++ b/lib/screens/common_widgets/sidebar_save_button.dart @@ -3,34 +3,20 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:apidash/consts.dart'; import 'package:apidash/providers/providers.dart'; -import 'package:apidash/widgets/widgets.dart'; +import '../../common/utils.dart'; class SaveButton extends ConsumerWidget { const SaveButton({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { - final overlayWidget = OverlayWidgetTemplate(context: context); final savingData = ref.watch(saveDataStateProvider); final hasUnsavedChanges = ref.watch(hasUnsavedChangesProvider); return TextButton.icon( onPressed: (savingData || !hasUnsavedChanges) ? null : () async { - overlayWidget.show( - widget: const SavingOverlay(saveCompleted: false)); - - await ref - .read(collectionStateNotifierProvider.notifier) - .saveData(); - await ref - .read(environmentsStateNotifierProvider.notifier) - .saveEnvironments(); - overlayWidget.hide(); - overlayWidget.show( - widget: const SavingOverlay(saveCompleted: true)); - await Future.delayed(const Duration(seconds: 1)); - overlayWidget.hide(); + await saveData(context, ref); }, icon: const Icon( Icons.save, diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index d71b3008..698b3fd9 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -1,127 +1,155 @@ import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:apidash/providers/providers.dart'; import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/consts.dart'; +import '../common/utils.dart'; import 'common_widgets/common_widgets.dart'; import 'envvar/environment_page.dart'; import 'home_page/home_page.dart'; import 'history/history_page.dart'; import 'settings_page.dart'; +class SaveIntent extends Intent { + const SaveIntent(); +} + +class DesktopDashboard extends ConsumerWidget { + const DesktopDashboard({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return const Dashboard(); + } +} + class Dashboard extends ConsumerWidget { const Dashboard({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final railIdx = ref.watch(navRailIndexStateProvider); - return Scaffold( - body: SafeArea( - child: Row( - children: [ - Column( - children: [ - SizedBox( - height: kIsMacOS ? 32.0 : 16.0, - width: 64, - ), - Column( - mainAxisSize: MainAxisSize.min, - children: [ - IconButton( - isSelected: railIdx == 0, - onPressed: () { - ref.read(navRailIndexStateProvider.notifier).state = 0; - }, - icon: const Icon(Icons.auto_awesome_mosaic_outlined), - selectedIcon: const Icon(Icons.auto_awesome_mosaic), - ), - Text( - 'Requests', - style: Theme.of(context).textTheme.labelSmall, - ), - kVSpacer10, - IconButton( - isSelected: railIdx == 1, - onPressed: () { - ref.read(navRailIndexStateProvider.notifier).state = 1; - }, - icon: const Icon(Icons.laptop_windows_outlined), - selectedIcon: const Icon(Icons.laptop_windows), - ), - Text( - 'Variables', - style: Theme.of(context).textTheme.labelSmall, - ), - kVSpacer10, - IconButton( - isSelected: railIdx == 2, - onPressed: () { - ref.read(navRailIndexStateProvider.notifier).state = 2; - }, - icon: const Icon(Icons.history_outlined), - selectedIcon: const Icon(Icons.history_rounded), - ), - Text( - 'History', - style: Theme.of(context).textTheme.labelSmall, - ), - ], - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.end, + return Shortcuts( + shortcuts: { + LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyS): const SaveIntent(), + }, + child: Actions( + actions: { + SaveIntent : CallbackAction(onInvoke: (intent) => saveData(context, ref)) + }, + child: FocusScope( + autofocus: true, + child: Scaffold( + body: SafeArea( + child: Row( + children: [ + Column( children: [ - Padding( - padding: const EdgeInsets.only(bottom: 16.0), - child: NavbarButton( - railIdx: railIdx, - selectedIcon: Icons.help, - icon: Icons.help_outline, - label: 'About', - showLabel: false, - isCompact: true, - onTap: () { - showAboutAppDialog(context); - }, - ), + SizedBox( + height: kIsMacOS ? 32.0 : 16.0, + width: 64, + ), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + isSelected: railIdx == 0, + onPressed: () { + ref.read(navRailIndexStateProvider.notifier).state = 0; + }, + icon: const Icon(Icons.auto_awesome_mosaic_outlined), + selectedIcon: const Icon(Icons.auto_awesome_mosaic), + ), + Text( + 'Requests', + style: Theme.of(context).textTheme.labelSmall, + ), + kVSpacer10, + IconButton( + isSelected: railIdx == 1, + onPressed: () { + ref.read(navRailIndexStateProvider.notifier).state = 1; + }, + icon: const Icon(Icons.laptop_windows_outlined), + selectedIcon: const Icon(Icons.laptop_windows), + ), + Text( + 'Variables', + style: Theme.of(context).textTheme.labelSmall, + ), + kVSpacer10, + IconButton( + isSelected: railIdx == 2, + onPressed: () { + ref.read(navRailIndexStateProvider.notifier).state = 2; + }, + icon: const Icon(Icons.history_outlined), + selectedIcon: const Icon(Icons.history_rounded), + ), + Text( + 'History', + style: Theme.of(context).textTheme.labelSmall, + ), + ], ), - Padding( - padding: const EdgeInsets.only(bottom: 16.0), - child: NavbarButton( - railIdx: railIdx, - buttonIdx: 3, - selectedIcon: Icons.settings, - icon: Icons.settings_outlined, - label: 'Settings', - showLabel: false, - isCompact: true, + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: NavbarButton( + railIdx: railIdx, + selectedIcon: Icons.help, + icon: Icons.help_outline, + label: 'About', + showLabel: false, + isCompact: true, + onTap: () { + showAboutAppDialog(context); + }, + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: NavbarButton( + railIdx: railIdx, + buttonIdx: 3, + selectedIcon: Icons.settings, + icon: Icons.settings_outlined, + label: 'Settings', + showLabel: false, + isCompact: true, + ), + ), + ], ), ), ], ), - ), - ], - ), - VerticalDivider( - thickness: 1, - width: 1, - color: Theme.of(context).colorScheme.surfaceContainerHighest, - ), - Expanded( - child: IndexedStack( - alignment: AlignmentDirectional.topCenter, - index: railIdx, - children: const [ - HomePage(), - EnvironmentPage(), - HistoryPage(), - SettingsPage(), + VerticalDivider( + thickness: 1, + width: 1, + color: Theme.of(context).colorScheme.surfaceContainerHighest, + ), + Expanded( + child: IndexedStack( + alignment: AlignmentDirectional.topCenter, + index: railIdx, + children: const [ + HomePage(), + EnvironmentPage(), + HistoryPage(), + SettingsPage(), + ], + ), + ) ], ), - ) - ], + ), + ), ), ), );