diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/_restart_app_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/_restart_app_button.dart new file mode 100644 index 0000000000..6119d233db --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/_restart_app_button.dart @@ -0,0 +1,43 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/sign_in_or_logout_button.dart'; +import 'package:appflowy_editor/appflowy_editor.dart' show PlatformExtension; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; + +class RestartButton extends StatelessWidget { + const RestartButton({ + super.key, + required this.onClick, + }); + + final VoidCallback onClick; + + @override + Widget build(BuildContext context) { + if (PlatformExtension.isDesktopOrWeb) { + return Row( + children: [ + FlowyButton( + isSelected: true, + useIntrinsicWidth: true, + margin: const EdgeInsets.symmetric( + horizontal: 30, + vertical: 10, + ), + text: FlowyText( + LocaleKeys.settings_menu_restartApp.tr(), + ), + onTap: onClick, + ), + const Spacer(), + ], + ); + } else { + return MobileSignInOrLogoutButton( + labelText: LocaleKeys.settings_menu_restartApp.tr(), + onPressed: onClick, + ); + } + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart index 0fc308fae3..b80ff6a24b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart @@ -3,6 +3,7 @@ import 'package:appflowy/env/env.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/settings/appflowy_cloud_setting_bloc.dart'; import 'package:appflowy/workspace/application/settings/appflowy_cloud_urls_bloc.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/_restart_app_button.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; @@ -59,7 +60,7 @@ class AppFlowyCloudViewSetting extends StatelessWidget { child: Column( children: [ const AppFlowyCloudEnableSync(), - const VSpace(40), + const VSpace(12), RestartButton( onClick: () async { NavigatorAlertDialog( @@ -173,7 +174,7 @@ class AppFlowyCloudURLs extends StatelessWidget { ); }, ), - const VSpace(20), + const VSpace(8), RestartButton( onClick: () async { NavigatorAlertDialog( @@ -317,12 +318,13 @@ class AppFlowyCloudEnableSync extends StatelessWidget { children: [ FlowyText.medium(LocaleKeys.settings_menu_enableSync.tr()), const Spacer(), - Switch( + Switch.adaptive( onChanged: (bool value) { context.read().add( AppFlowyCloudSettingEvent.enableSync(value), ); }, + activeColor: Theme.of(context).colorScheme.primary, value: state.setting.enableSync, ), ], @@ -331,24 +333,3 @@ class AppFlowyCloudEnableSync extends StatelessWidget { ); } } - -class RestartButton extends StatelessWidget { - final VoidCallback onClick; - const RestartButton({required this.onClick, super.key}); - - @override - Widget build(BuildContext context) { - return FlowyButton( - isSelected: true, - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric( - horizontal: 30, - vertical: 10, - ), - text: FlowyText( - LocaleKeys.settings_menu_restartApp.tr(), - ), - onTap: onClick, - ); - } -} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_cloud.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_cloud.dart index 27d9bd5349..aca974e01c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_cloud.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_cloud.dart @@ -2,14 +2,19 @@ import 'package:appflowy/env/cloud_env.dart'; import 'package:appflowy/env/env.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; +import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/settings/cloud_setting_bloc.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/setting_local_cloud.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; import 'setting_appflowy_cloud.dart'; import 'setting_supabase_cloud.dart'; @@ -56,6 +61,7 @@ class SettingCloud extends StatelessWidget { ), ], ), + const VSpace(8), _viewFromCloudType(state.cloudType), ], ); @@ -74,7 +80,9 @@ class SettingCloud extends StatelessWidget { Widget _viewFromCloudType(AuthenticatorType cloudType) { switch (cloudType) { case AuthenticatorType.local: - return SettingLocalCloud(didResetServerUrl: didResetServerUrl); + return SettingLocalCloud( + didResetServerUrl: didResetServerUrl, + ); case AuthenticatorType.supabase: return SettingSupabaseCloudView( didResetServerUrl: didResetServerUrl, @@ -108,39 +116,79 @@ class CloudTypeSwitcher extends StatelessWidget { @override Widget build(BuildContext context) { - return AppFlowyPopover( - direction: PopoverDirection.bottomWithRightAligned, - child: FlowyTextButton( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 6), - titleFromCloudType(cloudType), - fontColor: Theme.of(context).colorScheme.onBackground, - fillColor: Colors.transparent, - onPressed: () {}, - ), - popupBuilder: (BuildContext context) { - final isDevelopMode = integrationMode().isDevelop; - // Only show the appflowyCloudDevelop in develop mode - final values = AuthenticatorType.values - .where( - (element) => - isDevelopMode || - element != AuthenticatorType.appflowyCloudDevelop, - ) - .toList(); - - return ListView.builder( - shrinkWrap: true, - itemBuilder: (context, index) { - return CloudTypeItem( - cloudType: values[index], - currentCloudtype: cloudType, - onSelected: onSelected, - ); - }, - itemCount: values.length, - ); - }, - ); + final isDevelopMode = integrationMode().isDevelop; + // Only show the appflowyCloudDevelop in develop mode + final values = AuthenticatorType.values + .where( + (element) => + isDevelopMode || + element != AuthenticatorType.appflowyCloudDevelop, + ) + .toList(); + return PlatformExtension.isDesktopOrWeb + ? AppFlowyPopover( + direction: PopoverDirection.bottomWithRightAligned, + child: FlowyTextButton( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 6), + titleFromCloudType(cloudType), + fontColor: Theme.of(context).colorScheme.onBackground, + fillColor: Colors.transparent, + onPressed: () {}, + ), + popupBuilder: (BuildContext context) { + return ListView.builder( + shrinkWrap: true, + itemBuilder: (context, index) { + return CloudTypeItem( + cloudType: values[index], + currentCloudtype: cloudType, + onSelected: onSelected, + ); + }, + itemCount: values.length, + ); + }, + ) + : FlowyButton( + text: FlowyText( + titleFromCloudType(cloudType), + ), + useIntrinsicWidth: true, + rightIcon: const Icon( + Icons.chevron_right, + ), + onTap: () { + showMobileBottomSheet( + context, + showHeader: true, + showDragHandle: true, + showDivider: false, + showCloseButton: false, + title: LocaleKeys.settings_menu_cloudServerType.tr(), + padding: const EdgeInsets.fromLTRB(0, 8, 0, 48), + builder: (context) { + return Padding( + padding: const EdgeInsets.only(top: 10), + child: Column( + children: values + .mapIndexed( + (i, e) => FlowyOptionTile.checkbox( + text: titleFromCloudType(values[i]), + isSelected: cloudType == values[i], + onTap: () { + onSelected(e); + context.pop(); + }, + showBottomBorder: i == values.length - 1, + ), + ) + .toList(), + ), + ); + }, + ); + }, + ); } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_local_cloud.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_local_cloud.dart index edd8c470aa..bdfbc85f5a 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_local_cloud.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_local_cloud.dart @@ -1,9 +1,8 @@ import 'package:appflowy/env/cloud_env.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/_restart_app_button.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; class SettingLocalCloud extends StatelessWidget { @@ -15,32 +14,20 @@ class SettingLocalCloud extends StatelessWidget { @override Widget build(BuildContext context) { - return Row( - children: [ - FlowyButton( - isSelected: true, - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric( - horizontal: 30, - vertical: 10, - ), - text: FlowyText( - LocaleKeys.settings_menu_restartApp.tr(), - ), - onTap: () { - NavigatorAlertDialog( - title: LocaleKeys.settings_menu_restartAppTip.tr(), - confirm: () async { - await setAuthenticatorType( - AuthenticatorType.local, - ); - didResetServerUrl(); - }, - ).show(context); - }, - ), - const Spacer(), - ], + return RestartButton( + onClick: () => onPressed(context), ); } + + void onPressed(BuildContext context) { + NavigatorAlertDialog( + title: LocaleKeys.settings_menu_restartAppTip.tr(), + confirm: () async { + await setAuthenticatorType( + AuthenticatorType.local, + ); + didResetServerUrl(); + }, + ).show(context); + } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart index c1808bc17c..ebb9d73dbe 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart @@ -3,6 +3,7 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/settings/supabase_cloud_setting_bloc.dart'; import 'package:appflowy/workspace/application/settings/supabase_cloud_urls_bloc.dart'; import 'package:appflowy/workspace/presentation/home/toast.dart'; +import 'package:appflowy/workspace/presentation/settings/widgets/_restart_app_button.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; @@ -118,24 +119,8 @@ class SupabaseCloudURLs extends StatelessWidget { error: state.anonKeyError.fold(() => null, (a) => a), ), const VSpace(20), - FlowyButton( - isSelected: true, - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric( - horizontal: 30, - vertical: 10, - ), - text: FlowyText( - LocaleKeys.settings_menu_restartApp.tr(), - ), - onTap: () { - NavigatorAlertDialog( - title: LocaleKeys.settings_menu_restartAppTip.tr(), - confirm: () => context - .read() - .add(const SupabaseCloudURLsEvent.confirmUpdate()), - ).show(context); - }, + RestartButton( + onClick: () => _restartApp, ), ], ); @@ -144,6 +129,15 @@ class SupabaseCloudURLs extends StatelessWidget { ), ); } + + void _restartApp(BuildContext context) { + NavigatorAlertDialog( + title: LocaleKeys.settings_menu_restartAppTip.tr(), + confirm: () => context + .read() + .add(const SupabaseCloudURLsEvent.confirmUpdate()), + ).show(context); + } } class EnableEncrypt extends StatelessWidget { @@ -167,7 +161,8 @@ class EnableEncrypt extends StatelessWidget { const Spacer(), indicator, const HSpace(3), - Switch( + Switch.adaptive( + activeColor: Theme.of(context).colorScheme.primary, onChanged: state.setting.enableEncrypt ? null : (bool value) { @@ -235,7 +230,8 @@ class SupabaseEnableSync extends StatelessWidget { children: [ FlowyText.medium(LocaleKeys.settings_menu_enableSync.tr()), const Spacer(), - Switch( + Switch.adaptive( + activeColor: Theme.of(context).colorScheme.primary, onChanged: (bool value) { context.read().add( SupabaseCloudSettingEvent.enableSync(value),