diff --git a/lib/config/theme_data.dart b/lib/config/theme_data.dart index 688f13c..7046d03 100644 --- a/lib/config/theme_data.dart +++ b/lib/config/theme_data.dart @@ -12,6 +12,7 @@ class LightThemeConfig { colorScheme: _colorScheme, fontFamily: 'Dana-FA', textTheme: _textTheme, + cardColor: _colorScheme.surface, ); static final TextTheme _textTheme = const TextTheme( @@ -84,6 +85,7 @@ class DarkThemeConfig { iconTheme: const IconThemeData( color: text, ), + cardColor: _colorScheme.surface, ); static final TextTheme _textTheme = const TextTheme( diff --git a/lib/main.dart b/lib/main.dart index 87129d8..ba606ac 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,6 +10,8 @@ void main() { runApp(const Didvan()); } +final GlobalKey navigatorKey = GlobalKey(); + class Didvan extends StatelessWidget { const Didvan({Key? key}) : super(key: key); @override @@ -25,6 +27,7 @@ class Didvan extends StatelessWidget { ], child: Consumer( builder: (context, themeProvider, child) => MaterialApp( + navigatorKey: navigatorKey, debugShowCheckedModeBanner: false, title: 'Didvan', theme: LightThemeConfig.themeData, diff --git a/lib/models/enums.dart b/lib/models/enums.dart index e10ad91..247826c 100644 --- a/lib/models/enums.dart +++ b/lib/models/enums.dart @@ -3,3 +3,8 @@ enum AppState { busy, failed, } + +enum ButtonStyleMode { + primary, + flat, +} diff --git a/lib/models/view/action_sheet_data.dart b/lib/models/view/action_sheet_data.dart new file mode 100644 index 0000000..e7faf8a --- /dev/null +++ b/lib/models/view/action_sheet_data.dart @@ -0,0 +1,25 @@ +import 'package:flutter/cupertino.dart'; + +class ActionSheetData { + final Widget content; + final String? confrimTitle; + final String? dismissTitle; + final VoidCallback? onConfirmed; + final VoidCallback? onDismissed; + final String title; + final IconData? titleIcon; + final Color? titleColor; + final bool hasDismissButton; + + ActionSheetData({ + required this.content, + required this.title, + this.confrimTitle, + this.onConfirmed, + this.titleColor, + this.hasDismissButton = true, + this.titleIcon, + this.dismissTitle, + this.onDismissed, + }); +} diff --git a/lib/pages/home/profile/settings/settings.dart b/lib/pages/home/profile/settings/settings.dart index c73bf6b..27a65fa 100644 --- a/lib/pages/home/profile/settings/settings.dart +++ b/lib/pages/home/profile/settings/settings.dart @@ -1,11 +1,15 @@ +import 'package:day_night_time_picker/lib/constants.dart'; import 'package:day_night_time_picker/lib/daynight_timepicker.dart'; import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/assets.dart'; +import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/pages/home/profile/settings/settings_state.dart'; import 'package:didvan/pages/home/profile/widgets/menu_item.dart'; import 'package:didvan/providers/theme_provider.dart'; +import 'package:didvan/utils/actions_sheet.dart'; import 'package:didvan/widgets/didvan/card.dart'; import 'package:didvan/widgets/didvan/divider.dart'; import 'package:didvan/widgets/didvan/scaffold.dart'; @@ -75,15 +79,78 @@ class Settings extends StatelessWidget { ); } - Future _pickTimeRange(context) async { + Future _pickTimeRange(BuildContext context) async { + ActionSheetUtils.showBottomSheet( + data: ActionSheetData( + content: Row( + children: [ + const SizedBox(width: 8), + Expanded(child: _timeFieldBuilder(context, 0)), + const SizedBox(width: 8), + const DidvanText('-'), + const SizedBox(width: 8), + Expanded(child: _timeFieldBuilder(context, 1)), + const SizedBox(width: 8), + ], + ), + title: 'زمان دریافت اعلان', + titleIcon: DidvanIcons.notification_regular, + ), + ); + } + + Widget _timeFieldBuilder(BuildContext context, int index) { final SettingsState state = context.read(); - Navigator.of(context).push( + return ChangeNotifierProvider.value( + value: state, + child: StatefulBuilder( + builder: (context, setState) => GestureDetector( + onTap: () async { + await _openTimePicker(context, index); + setState(() {}); + }, + child: Container( + alignment: Alignment.center, + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.splash, + borderRadius: DesignConfig.mediumBorderRadius, + border: Border.all( + color: Theme.of(context).colorScheme.border, + ), + ), + child: DidvanText(state.notificationTimeRange[index]), + ), + ), + ), + ); + } + + Future _openTimePicker(BuildContext context, int index) async { + final SettingsState state = context.read(); + await Navigator.of(context).push( showPicker( + okText: 'تایید', + cancelText: 'بازگشت', + accentColor: Theme.of(context).colorScheme.primary, + okCancelStyle: Theme.of(context).textTheme.bodyText2!, + unselectedColor: Theme.of(context).colorScheme.text, + blurredBackground: true, + hourLabel: 'ساعت', + minuteLabel: 'دقیقه', + is24HrFormat: true, + iosStylePicker: true, + minuteInterval: MinuteInterval.FIFTEEN, context: context, value: const TimeOfDay(hour: 0, minute: 0), + themeData: Theme.of(context), onChange: (time) { - String hour = time.toString().split(':')[0]; - state.notificationTimeRange = []; + state.notificationTimeRange = state.notificationTimeRange + ..replaceRange( + index, + index + 1, + ['${time.hour}:${time.minute}'], + ); }, ), ); diff --git a/lib/pages/splash/splash.dart b/lib/pages/splash/splash.dart index cced112..2f97304 100644 --- a/lib/pages/splash/splash.dart +++ b/lib/pages/splash/splash.dart @@ -1,7 +1,9 @@ import 'package:didvan/config/design_config.dart'; +import 'package:didvan/main.dart'; import 'package:didvan/providers/theme_provider.dart'; import 'package:didvan/routes/routes.dart'; import 'package:didvan/services/app_initalizer.dart'; +import 'package:didvan/utils/actions_sheet.dart'; import 'package:didvan/widgets/logos/didvan_horizontal_logo.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -24,6 +26,7 @@ class _SplashState extends State { } Future _initialize() async { + ActionSheetUtils.context = navigatorKey.currentContext!; await AppInitializer.setupServices(); final ThemeMode themeMode = await AppInitializer.initilizeSettings(); context.read().themeMode = themeMode; diff --git a/lib/utils/actions_sheet.dart b/lib/utils/actions_sheet.dart index ee324d4..0bf6f92 100644 --- a/lib/utils/actions_sheet.dart +++ b/lib/utils/actions_sheet.dart @@ -1,5 +1,12 @@ import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; +import 'package:didvan/main.dart'; +import 'package:didvan/models/enums.dart'; +import 'package:didvan/models/view/action_sheet_data.dart'; +import 'package:didvan/widgets/didvan/button.dart'; +import 'package:didvan/widgets/didvan/card.dart'; +import 'package:didvan/widgets/didvan/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:rive/rive.dart'; @@ -29,4 +36,73 @@ class ActionSheetUtils { child: child, ); } + + static Future showBottomSheet({required ActionSheetData data}) async { + await showModalBottomSheet( + context: context, + builder: (context) => Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: const BorderRadius.vertical( + top: Radius.circular( + 10, + ), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Container( + height: 3, + width: 50, + color: Theme.of(context).colorScheme.hint, + ), + ), + const SizedBox(height: 8), + Row( + children: [ + if (data.titleIcon != null) + Icon( + data.titleIcon, + color: + data.titleColor ?? Theme.of(context).colorScheme.title, + ), + if (data.titleIcon != null) const SizedBox(width: 8), + DidvanText( + data.title, + style: Theme.of(context).textTheme.subtitle1, + color: data.titleColor ?? Theme.of(context).colorScheme.title, + ) + ], + ), + const SizedBox(height: 28), + data.content, + const SizedBox(height: 28), + Row( + children: [ + if (data.hasDismissButton) + Expanded( + child: DidvanButton( + title: data.dismissTitle ?? 'بازگشت', + style: ButtonStyleMode.flat, + ), + ), + const SizedBox(width: 20), + Expanded( + child: DidvanButton( + style: ButtonStyleMode.primary, + onPressed: () {}, + title: data.confrimTitle ?? 'تایید', + ), + ), + ], + ), + ], + ), + ), + ); + } } diff --git a/lib/widgets/didvan/button.dart b/lib/widgets/didvan/button.dart index fe90593..dff6d73 100644 --- a/lib/widgets/didvan/button.dart +++ b/lib/widgets/didvan/button.dart @@ -1,11 +1,18 @@ import 'package:didvan/config/design_config.dart'; +import 'package:didvan/models/enums.dart'; import 'package:didvan/widgets/didvan/text.dart'; import 'package:flutter/material.dart'; class DidvanButton extends StatelessWidget { final VoidCallback? onPressed; final String? title; - const DidvanButton({Key? key, this.onPressed, this.title}) : super(key: key); + final ButtonStyleMode style; + const DidvanButton({ + Key? key, + this.onPressed, + this.title, + this.style = ButtonStyleMode.primary, + }) : super(key: key); @override Widget build(BuildContext context) {