import 'package:animated_theme_switcher/animated_theme_switcher.dart'; import 'package:async_tools/async_tools.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_translate/flutter_translate.dart'; import 'package:veilid_support/veilid_support.dart'; import 'init.dart'; import 'router/router.dart'; import 'settings/settings.dart'; import 'theme/theme.dart'; import 'tools/tools.dart'; import 'veilid_processor/veilid_processor.dart'; class ReloadThemeIntent extends Intent { const ReloadThemeIntent(); } class ChangeBrightnessIntent extends Intent { const ChangeBrightnessIntent(); } class ChangeColorIntent extends Intent { const ChangeColorIntent(); } class AttachDetachIntent extends Intent { const AttachDetachIntent(); } class DeveloperPageIntent extends Intent { const DeveloperPageIntent(); } class KeyboardShortcuts extends StatelessWidget { const KeyboardShortcuts({required this.child, super.key}); void reloadTheme(BuildContext context) { singleFuture(this, () async { log.info('Reloading theme'); await VeilidChatGlobalInit.loadAssetManifest(); final theme = PreferencesRepository.instance.value.themePreference.themeData(); if (context.mounted) { ThemeSwitcher.of(context).changeTheme(theme: theme); // Hack to reload translations final localizationDelegate = LocalizedApp.of(context).delegate; await LocalizationDelegate.create( fallbackLocale: localizationDelegate.fallbackLocale.toString(), supportedLocales: localizationDelegate.supportedLocales .map((x) => x.toString()) .toList()); } }); } void changeBrightness(BuildContext context) { singleFuture(this, () async { final prefs = PreferencesRepository.instance.value; final oldBrightness = prefs.themePreference.brightnessPreference; final newBrightness = BrightnessPreference.values[ (oldBrightness.index + 1) % BrightnessPreference.values.length]; log.info('Changing brightness to $newBrightness'); final newPrefs = prefs.copyWith( themePreference: prefs.themePreference .copyWith(brightnessPreference: newBrightness)); await PreferencesRepository.instance.set(newPrefs); if (context.mounted) { ThemeSwitcher.of(context) .changeTheme(theme: newPrefs.themePreference.themeData()); } }); } void changeColor(BuildContext context) { singleFuture(this, () async { final prefs = PreferencesRepository.instance.value; final oldColor = prefs.themePreference.colorPreference; final newColor = ColorPreference .values[(oldColor.index + 1) % ColorPreference.values.length]; log.info('Changing color to $newColor'); final newPrefs = prefs.copyWith( themePreference: prefs.themePreference.copyWith(colorPreference: newColor)); await PreferencesRepository.instance.set(newPrefs); if (context.mounted) { ThemeSwitcher.of(context) .changeTheme(theme: newPrefs.themePreference.themeData()); } }); } void _attachDetach(BuildContext context) { singleFuture(this, () async { if (ProcessorRepository.instance.processorConnectionState.isAttached) { log.info('Detaching'); await Veilid.instance.detach(); } else if (ProcessorRepository .instance.processorConnectionState.isDetached) { log.info('Attaching'); await Veilid.instance.attach(); } }); } void _developerPage(BuildContext context) { singleFuture(this, () async { final path = GoRouter.of(context).location(); if (path != '/developer') { await GoRouterHelper(context).push('/developer'); } }); } @override Widget build(BuildContext context) => ThemeSwitcher( builder: (context) => Shortcuts( shortcuts: const { SingleActivator( LogicalKeyboardKey.keyR, control: true, alt: true, ): ReloadThemeIntent(), SingleActivator( LogicalKeyboardKey.keyB, control: true, alt: true, ): ChangeBrightnessIntent(), SingleActivator( LogicalKeyboardKey.keyC, control: true, alt: true, ): ChangeColorIntent(), SingleActivator( LogicalKeyboardKey.keyA, control: true, alt: true, ): AttachDetachIntent(), SingleActivator( LogicalKeyboardKey.keyD, control: true, alt: true, ): DeveloperPageIntent(), }, child: Actions(actions: >{ ReloadThemeIntent: CallbackAction( onInvoke: (intent) => reloadTheme(context)), ChangeBrightnessIntent: CallbackAction( onInvoke: (intent) => changeBrightness(context)), ChangeColorIntent: CallbackAction( onInvoke: (intent) => changeColor(context)), AttachDetachIntent: CallbackAction( onInvoke: (intent) => _attachDetach(context)), DeveloperPageIntent: CallbackAction( onInvoke: (intent) => _developerPage(context)), }, child: Focus(autofocus: true, child: child)))); ///////////////////////////////////////////////////////// final Widget child; }