diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 5c66f4c0a3..0b461e321c 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -90,7 +90,7 @@ "inlineCode": "Inline Code", "quote": "Quote Block" }, - "tooltip":{ + "tooltip": { "lightMode": "Switch to Light mode", "darkMode": "Switch to Dark mode" }, @@ -127,5 +127,16 @@ "instruction3": "Navigate to the following link in your web browser, and enter the above code:", "instruction4": "Press the button below when you've completed signup:" } + }, + "settings": { + "title": "Settings", + "menu": { + "appearance": "Appearance", + "language": "Language" + }, + "appearance": { + "lightLabel": "Light Mode", + "darkLabel": "Dark Mode" + } } } \ No newline at end of file diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart new file mode 100644 index 0000000000..2fee55cc33 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart @@ -0,0 +1,64 @@ +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:app_flowy/workspace/presentation/settings/widgets/settings_appearance_view.dart'; +import 'package:app_flowy/workspace/presentation/settings/widgets/settings_language_view.dart'; +import 'package:app_flowy/workspace/presentation/settings/widgets/settings_menu.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +class SettingsDialog extends StatefulWidget { + const SettingsDialog({Key? key}) : super(key: key); + + @override + State createState() => _SettingsDialogState(); +} + +class _SettingsDialogState extends State { + int _selectedViewIndex = 0; + + final List settingsViews = const [ + SettingsAppearanceView(), + SettingsLanguageView(), + ]; + + @override + Widget build(BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + title: Text( + LocaleKeys.settings_title.tr(), + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + content: ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 600, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: SettingsMenu( + changeSelectedIndex: (index) { + setState(() { + _selectedViewIndex = index; + }); + }, + currentIndex: _selectedViewIndex, + ), + ), + const VerticalDivider(), + const SizedBox(width: 10), + Expanded( + flex: 4, + child: settingsViews[_selectedViewIndex], + ) + ], + ), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart new file mode 100644 index 0000000000..6cfe8ed62d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart @@ -0,0 +1,50 @@ +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:app_flowy/workspace/presentation/theme/theme_model.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class SettingsAppearanceView extends StatelessWidget { + const SettingsAppearanceView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 15, + ), + Row( + children: [ + Text( + LocaleKeys.settings_appearance_lightLabel.tr(), + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + Switch( + value: theme.isDark, + onChanged: (val) { + context.read().swapTheme(); + }, + ), + Text( + LocaleKeys.settings_appearance_darkLabel.tr(), + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_language_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_language_view.dart new file mode 100644 index 0000000000..4681fcc2b8 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_language_view.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class SettingsLanguageView extends StatelessWidget { + const SettingsLanguageView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return const Center(child: Text('Work In Progress')); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart new file mode 100644 index 0000000000..241c337705 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart @@ -0,0 +1,40 @@ +import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:app_flowy/workspace/presentation/settings/widgets/settings_menu_element.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +class SettingsMenu extends StatelessWidget { + const SettingsMenu({ + Key? key, + required this.changeSelectedIndex, + required this.currentIndex, + }) : super(key: key); + + final Function changeSelectedIndex; + final int currentIndex; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SettingsMenuElement( + index: 0, + currentIndex: currentIndex, + label: LocaleKeys.settings_menu_appearance.tr(), + icon: Icons.brightness_4, + changeSelectedIndex: changeSelectedIndex, + ), + const SizedBox( + height: 10, + ), + SettingsMenuElement( + index: 1, + currentIndex: currentIndex, + label: LocaleKeys.settings_menu_language.tr(), + icon: Icons.translate, + changeSelectedIndex: changeSelectedIndex, + ), + ], + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu_element.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu_element.dart new file mode 100644 index 0000000000..80e5c16e42 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu_element.dart @@ -0,0 +1,50 @@ +import 'package:flowy_infra/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class SettingsMenuElement extends StatelessWidget { + const SettingsMenuElement({ + Key? key, + required this.index, + required this.label, + required this.icon, + required this.changeSelectedIndex, + required this.currentIndex, + }) : super(key: key); + + final int index; + final int currentIndex; + final String label; + final IconData icon; + final Function changeSelectedIndex; + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return ListTile( + leading: Icon( + icon, + size: 16, + color: index == currentIndex ? Colors.black : theme.textColor, + ), + onTap: () { + changeSelectedIndex(index); + }, + selected: index == currentIndex, + selectedColor: Colors.black, + selectedTileColor: theme.main2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + minLeadingWidth: 0, + title: Text( + label, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + overflow: TextOverflow.ellipsis, + ), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_user.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_user.dart index 29775a264b..38d760d51e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_user.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_user.dart @@ -1,15 +1,12 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart'; +import 'package:app_flowy/workspace/presentation/settings/settings_dialog.dart'; import 'package:flowy_infra/size.dart'; -import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:app_flowy/workspace/presentation/theme/theme_model.dart'; -import 'package:app_flowy/generated/locale_keys.g.dart'; class MenuUser extends StatelessWidget { final UserProfile user; @@ -17,7 +14,6 @@ class MenuUser extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = context.watch(); return BlocProvider( create: (context) => getIt(param1: user)..add(const MenuUserEvent.initial()), child: BlocBuilder( @@ -26,14 +22,12 @@ class MenuUser extends StatelessWidget { _renderAvatar(context), const HSpace(10), _renderUserName(context), - const HSpace(80), - (theme.isDark ? _renderLightMode(context) : _renderDarkMode(context)), - + const Spacer(), + _renderSettingsButton(context), //ToDo: when the user is allowed to create another workspace, //we get the below block back //_renderDropButton(context), ], - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, ), ), @@ -59,40 +53,28 @@ class MenuUser extends StatelessWidget { ); } - Widget _renderThemeToggle(BuildContext context) { - final theme = context.watch(); - return CircleAvatar( - backgroundColor: theme.surface, - child: IconButton( - icon: Icon(theme.isDark ? Icons.dark_mode : Icons.light_mode), - color: (theme.iconColor), - onPressed: () { - context.read().swapTheme(); - }), - ); - } - - Widget _renderDarkMode(BuildContext context) { - return Tooltip( - message: LocaleKeys.tooltip_darkMode.tr(), - child: _renderThemeToggle(context), - ); - } - - Widget _renderLightMode(BuildContext context) { - return Tooltip( - message: LocaleKeys.tooltip_lightMode.tr(), - child: _renderThemeToggle(context), - ); - } - Widget _renderUserName(BuildContext context) { String name = context.read().state.user.name; if (name.isEmpty) { name = context.read().state.user.email; } - return Flexible( - child: FlowyText(name, fontSize: 12), + return FlowyText(name, fontSize: 12); + } + + Widget _renderSettingsButton(BuildContext context) { + return Tooltip( + message: 'Open Settings', + child: IconButton( + onPressed: () { + showDialog( + context: context, + builder: (context) { + return const SettingsDialog(); + }, + ); + }, + icon: const Icon(Icons.settings), + ), ); } //ToDo: when the user is allowed to create another workspace, diff --git a/frontend/scripts/generate_language_files.cmd b/frontend/scripts/generate_language_files.cmd index a8e938aa08..8980093db6 100644 --- a/frontend/scripts/generate_language_files.cmd +++ b/frontend/scripts/generate_language_files.cmd @@ -1,4 +1,5 @@ echo 'Generating language files' cd app_flowy -flutter pub run easy_localization:generate -S assets/translations/ && flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations/ \ No newline at end of file +call flutter pub run easy_localization:generate -S assets/translations/ +call flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations/ -s en.json \ No newline at end of file diff --git a/frontend/scripts/generate_language_files.sh b/frontend/scripts/generate_language_files.sh index 6ef0b175f0..61215f1a64 100644 --- a/frontend/scripts/generate_language_files.sh +++ b/frontend/scripts/generate_language_files.sh @@ -3,4 +3,4 @@ echo 'Generating language files' cd app_flowy flutter pub run easy_localization:generate -S assets/translations/ -flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations +flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations -s en.json diff --git a/frontend/scripts/makefile/flutter.toml b/frontend/scripts/makefile/flutter.toml index bf7310eaea..b1cda1d69f 100644 --- a/frontend/scripts/makefile/flutter.toml +++ b/frontend/scripts/makefile/flutter.toml @@ -177,26 +177,24 @@ script_runner = "@shell" [tasks.generate_language_files] script_runner = "@shell" script = [ - ''' + """ cd app_flowy flutter clean flutter pub get flutter pub run easy_localization:generate -S assets/translations/ - flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations - ''' + flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations -s en.json + """ ] [tasks.generate_language_files.windows] script_runner = "@duckscript" script = [ - ''' - cd app_flowy + """ + cd ./app_flowy/ exec cmd.exe /c flutter clean exec cmd.exe /c flutter pub get exec cmd.exe /c flutter pub run easy_localization:generate -S assets/translations/ exec cmd.exe /c flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations - ''' + """ ] - -