diff --git a/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart b/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart index 958910dd80..570c482fb5 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart @@ -1,5 +1,5 @@ import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart'; -import 'package:flutter/material.dart'; +import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -17,25 +17,25 @@ void main() { await tester.openSettingsPage(SettingsPage.notifications); await tester.pumpAndSettle(); - final switchFinder = find.byType(Switch).first; + final toggleFinder = find.byType(Toggle).first; // Defaults to enabled - Switch switchWidget = tester.widget(switchFinder); - expect(switchWidget.value, true); + Toggle toggleWidget = tester.widget(toggleFinder); + expect(toggleWidget.value, true); // Disable - await tester.tap(switchFinder); + await tester.tap(toggleFinder); await tester.pumpAndSettle(); - switchWidget = tester.widget(switchFinder); - expect(switchWidget.value, false); + toggleWidget = tester.widget(toggleFinder); + expect(toggleWidget.value, false); // Enable again - await tester.tap(switchFinder); + await tester.tap(toggleFinder); await tester.pumpAndSettle(); - switchWidget = tester.widget(switchFinder); - expect(switchWidget.value, true); + toggleWidget = tester.widget(toggleFinder); + expect(toggleWidget.value, true); }); }); } diff --git a/frontend/appflowy_flutter/lib/core/frameless_window.dart b/frontend/appflowy_flutter/lib/core/frameless_window.dart index c322da97aa..799c90f5b7 100644 --- a/frontend/appflowy_flutter/lib/core/frameless_window.dart +++ b/frontend/appflowy_flutter/lib/core/frameless_window.dart @@ -1,15 +1,16 @@ import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/shared/window_title_bar.dart'; import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CocoaWindowChannel { @@ -122,15 +123,21 @@ class MoveWindowDetectorState extends State { return FlowyTooltip( richMessage: textSpan, - child: FlowyIconButton( - hoverColor: Colors.transparent, - onPressed: () => context + child: Listener( + behavior: HitTestBehavior.translucent, + onPointerDown: (_) => context .read() .add(const HomeSettingEvent.collapseMenu()), - iconPadding: const EdgeInsets.all(4.0), - icon: context.read().state.isMenuCollapsed - ? const FlowySvg(FlowySvgs.show_menu_s) - : const FlowySvg(FlowySvgs.hide_menu_m), + child: FlowyHover( + child: Container( + width: 24, + padding: const EdgeInsets.all(4), + child: const RotatedBox( + quarterTurns: 2, + child: FlowySvg(FlowySvgs.hide_menu_s), + ), + ), + ), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/toolbar/calendar_layout_setting.dart b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/toolbar/calendar_layout_setting.dart index 3ec5e7c34f..e081a2fbb3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/toolbar/calendar_layout_setting.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/toolbar/calendar_layout_setting.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/application/database_controller.dart'; @@ -5,12 +7,10 @@ import 'package:appflowy/plugins/database/application/setting/property_bloc.dart import 'package:appflowy/plugins/database/calendar/application/calendar_setting_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.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'; /// Widget that displays a list of settings that alters the appearance of the @@ -325,7 +325,6 @@ Widget _toggleItem({ Toggle( value: value, onChanged: (value) => onToggle(!value), - style: ToggleStyle.big, padding: EdgeInsets.zero, ), ], diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_editor.dart index 445966afe8..c3d950afae 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/field_editor.dart @@ -1,5 +1,7 @@ import 'dart:typed_data'; +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/application/field/field_controller.dart'; @@ -11,12 +13,10 @@ import 'package:appflowy/plugins/database/grid/presentation/widgets/common/type_ import 'package:appflowy/util/field_type_extension.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.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 'field_type_list.dart'; @@ -258,7 +258,6 @@ enum FieldAction { onChanged: (_) => context .read() .add(const FieldEditorEvent.toggleWrapCellContent()), - style: ToggleStyle.big, padding: EdgeInsets.zero, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart index 4c7dc73ae2..0040444bb4 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart @@ -1,12 +1,12 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; class DateFormatButton extends StatelessWidget { const DateFormatButton({ @@ -248,7 +248,6 @@ class IncludeTimeButton extends StatelessWidget { Toggle( value: value, onChanged: onChanged, - style: ToggleStyle.big, padding: EdgeInsets.zero, ), ], diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/group/database_group.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/group/database_group.dart index 532effbd87..ee021d59d3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/group/database_group.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/group/database_group.dart @@ -9,7 +9,6 @@ import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/common/type_option_separator.dart'; import 'package:appflowy/util/field_type_extension.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -74,7 +73,6 @@ class DatabaseGroupList extends StatelessWidget { value: !state.layoutSettings.hideUngroupedColumn, onChanged: (value) => _updateLayoutSettings(state.layoutSettings, value), - style: ToggleStyle.big, padding: EdgeInsets.zero, ), ], diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_manage_data_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_manage_data_view.dart index bde6c5bf31..d99227ec87 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_manage_data_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_manage_data_view.dart @@ -22,7 +22,6 @@ import 'package:appflowy/workspace/presentation/settings/widgets/files/settings_ import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; -import 'package:dotted_border/dotted_border.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/file_picker/file_picker_service.dart'; import 'package:flowy_infra/theme_extension.dart'; @@ -288,65 +287,22 @@ class _ImportDataFieldState extends State<_ImportDataField> { (_) => _showToast(LocaleKeys.settings_menu_importFailed.tr()), ), builder: (context, state) { - return DottedBorder( - radius: const Radius.circular(8), - dashPattern: const [2, 2], - borderType: BorderType.RRect, - color: Theme.of(context).colorScheme.primary, - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - children: [ - // When dragging files are enabled - // FlowyText.regular('Drag file here or'), - // const VSpace(8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - height: 42, - child: FlowyTextButton( - LocaleKeys.settings_manageDataPage_importData_action - .tr(), - padding: const EdgeInsets.symmetric( - horizontal: 24, - vertical: 12, - ), - fontWeight: FontWeight.w600, - radius: BorderRadius.circular(12), - fillColor: Theme.of(context).colorScheme.primary, - hoverColor: const Color(0xFF005483), - fontHoverColor: Colors.white, - onPressed: () async { - final path = await getIt() - .getDirectoryPath(); - if (path == null || !context.mounted) { - return; - } + return SingleSettingAction( + label: + LocaleKeys.settings_manageDataPage_importData_description.tr(), + labelMaxLines: 2, + buttonLabel: + LocaleKeys.settings_manageDataPage_importData_action.tr(), + onPressed: () async { + final path = await getIt().getDirectoryPath(); + if (path == null || !context.mounted) { + return; + } - context.read().add( - SettingFileImportEvent - .importAppFlowyDataFolder( - path, - ), - ); - }, - ), - ), - ], - ), - const VSpace(8), - FlowyText.regular( - LocaleKeys.settings_manageDataPage_importData_description - .tr(), - // 'Supported filetypes:\nCSV, Notion, Text, and Markdown', - maxLines: 3, - lineHeight: 1.5, - textAlign: TextAlign.center, - ), - ], - ), - ), + context + .read() + .add(SettingFileImportEvent.importAppFlowyDataFolder(path)); + }, ); }, ), @@ -496,7 +452,7 @@ class _DataPathActions extends StatelessWidget { label: LocaleKeys.settings_manageDataPage_dataStorage_actions_open.tr(), icon: const FlowySvg(FlowySvgs.folder_m, size: Size.square(20)), - onPressed: () => afLaunchUrlString('file://$currentPath'), + onPressed: () => afLaunchUrl(Uri.file(currentPath)), ), ], ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart index f642a92b51..a094c0db39 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/settings/plan/settings_plan_bloc.dart'; import 'package:appflowy/workspace/application/settings/plan/workspace_subscription_ext.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_alert_dialog.dart'; @@ -44,6 +45,8 @@ class _SettingsPlanComparisonDialogState @override Widget build(BuildContext context) { + final isLM = Theme.of(context).isLightMode; + return BlocListener( listener: (context, state) { final readyState = state.mapOrNull(ready: (state) => state); @@ -64,15 +67,11 @@ class _SettingsPlanComparisonDialogState ), ), ), - title: - LocaleKeys.settings_comparePlanDialog_paymentSuccess_title.tr( - args: [readyState.subscription.label], - ), + title: LocaleKeys.settings_comparePlanDialog_paymentSuccess_title + .tr(args: [readyState.subscription.label]), subtitle: LocaleKeys .settings_comparePlanDialog_paymentSuccess_description - .tr( - args: [readyState.subscription.label], - ), + .tr(args: [readyState.subscription.label]), hideCancelButton: true, confirm: Navigator.of(context).pop, confirmLabel: LocaleKeys.button_close.tr(), @@ -96,6 +95,7 @@ class _SettingsPlanComparisonDialogState FlowyText.semibold( LocaleKeys.settings_comparePlanDialog_title.tr(), fontSize: 24, + color: AFThemeExtension.of(context).strongText, ), const Spacer(), GestureDetector( @@ -108,13 +108,14 @@ class _SettingsPlanComparisonDialogState child: FlowySvg( FlowySvgs.m_close_m, size: const Size.square(20), - color: Theme.of(context).colorScheme.outline, + color: AFThemeExtension.of(context).strongText, ), ), ), ], ), ), + const VSpace(16), Flexible( child: SingleChildScrollView( controller: horizontalController, @@ -140,7 +141,7 @@ class _SettingsPlanComparisonDialogState mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - const VSpace(26), + const VSpace(30), SizedBox( height: 100, child: FlowyText.semibold( @@ -149,7 +150,9 @@ class _SettingsPlanComparisonDialogState .tr(), fontSize: 24, maxLines: 2, - color: const Color(0xFF5C3699), + color: isLM + ? const Color(0xFF5C3699) + : const Color(0xFFE8E0FF), ), ), const SizedBox(height: 64), @@ -281,17 +284,18 @@ class _PlanTable extends StatelessWidget { @override Widget build(BuildContext context) { final highlightPlan = !isCurrent && !canDowngrade && canUpgrade; + final isLM = Theme.of(context).isLightMode; return Container( - width: 210, + width: 215, decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), gradient: !highlightPlan ? null - : const LinearGradient( + : LinearGradient( colors: [ - Color(0xFF251D37), - Color(0xFF7547C0), + isLM ? const Color(0xFF251D37) : const Color(0xFF7459AD), + isLM ? const Color(0xFF7547C0) : const Color(0xFFDDC8FF), ], ), ), @@ -311,6 +315,7 @@ class _PlanTable extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ if (isCurrent) const _CurrentBadge(), + const VSpace(4), _Heading( title: title, description: description, @@ -376,14 +381,16 @@ class _CurrentBadge extends StatelessWidget { height: 22, width: 72, decoration: BoxDecoration( - color: const Color(0xFF4F3F5F), + color: Theme.of(context).isLightMode + ? const Color(0xFF4F3F5F) + : const Color(0xFFE8E0FF), borderRadius: BorderRadius.circular(4), ), child: Center( child: FlowyText.medium( LocaleKeys.settings_comparePlanDialog_current.tr(), fontSize: 12, - color: Colors.white, + color: Theme.of(context).isLightMode ? Colors.white : Colors.black, ), ), ); @@ -417,22 +424,28 @@ class _ComparisonCell extends StatelessWidget { ), ), child: Row( - mainAxisSize: MainAxisSize.min, children: [ if (icon != null) ...[ - FlowySvg(icon!), + FlowySvg( + icon!, + color: AFThemeExtension.of(context).strongText, + ), ] else ...[ Expanded( child: FlowyText.medium( label, lineHeight: 1.2, + color: AFThemeExtension.of(context).strongText, ), ), ], if (tooltip != null) FlowyTooltip( message: tooltip, - child: const FlowySvg(FlowySvgs.information_s), + child: FlowySvg( + FlowySvgs.information_s, + color: AFThemeExtension.of(context).strongText, + ), ), ], ), @@ -457,9 +470,8 @@ class _ActionButton extends StatelessWidget { @override Widget build(BuildContext context) { - final isLM = Theme.of(context).brightness == Brightness.light; + final isLM = Theme.of(context).isLightMode; - final gradientBorder = useGradientBorder && isLM; return SizedBox( height: 56, child: Row( @@ -475,25 +487,17 @@ class _ActionButton extends StatelessWidget { child: _drawGradientBorder( isLM: isLM, child: Container( - height: gradientBorder ? 36 : 40, - width: gradientBorder ? 148 : 152, + height: 36, + width: 148, decoration: BoxDecoration( color: useGradientBorder ? Theme.of(context).cardColor : Colors.transparent, - border: Border.all( - color: gradientBorder - ? Colors.transparent - : AFThemeExtension.of(context).textColor, - ), - borderRadius: - BorderRadius.circular(gradientBorder ? 14 : 16), + border: Border.all(color: Colors.transparent), + borderRadius: BorderRadius.circular(14), ), child: Center( - child: _drawText( - label, - isLM, - ), + child: _drawText(label, isLM), ), ), ), @@ -511,6 +515,7 @@ class _ActionButton extends StatelessWidget { fontSize: 14, lineHeight: 1.2, fontWeight: useGradientBorder ? FontWeight.w600 : FontWeight.w500, + color: const Color(0xFFC49BEC), ); if (!useGradientBorder || !isLM) { @@ -532,19 +537,15 @@ class _ActionButton extends StatelessWidget { } Widget _drawGradientBorder({required bool isLM, required Widget child}) { - if (!useGradientBorder || !isLM) { - return child; - } - return Container( padding: const EdgeInsets.all(2), decoration: BoxDecoration( - gradient: const LinearGradient( - transform: GradientRotation(-1.2), - stops: [0.4, 1], + gradient: LinearGradient( + transform: const GradientRotation(-1.2), + stops: const [0.4, 1], colors: [ - Color(0xFF251D37), - Color(0xFF7547C0), + isLM ? const Color(0xFF251D37) : const Color(0xFF7459AD), + isLM ? const Color(0xFF7547C0) : const Color(0xFFDDC8FF), ], ), borderRadius: BorderRadius.circular(16), @@ -582,7 +583,9 @@ class _Heading extends StatelessWidget { fontSize: 24, color: isPrimary ? AFThemeExtension.of(context).strongText - : const Color(0xFF5C3699), + : Theme.of(context).isLightMode + ? const Color(0xFF5C3699) + : const Color(0xFFC49BEC), ), if (description != null && description!.isNotEmpty) ...[ const VSpace(4), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart index 9aa84d2e67..5373196a2c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/util/int64_extension.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; import 'package:appflowy/workspace/application/settings/date_time/date_format_ext.dart'; import 'package:appflowy/workspace/application/settings/plan/settings_plan_bloc.dart'; @@ -12,7 +13,6 @@ import 'package:appflowy/workspace/presentation/settings/pages/settings_plan_com import 'package:appflowy/workspace/presentation/settings/shared/flowy_gradient_button.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -62,19 +62,17 @@ class SettingsPlanView extends StatelessWidget { return ErrorWidget.withDetails(message: 'Something went wrong!'); }, - ready: (state) { - return SettingsBody( - autoSeparate: false, - title: LocaleKeys.settings_planPage_title.tr(), - children: [ - _PlanUsageSummary( - usage: state.workspaceUsage, - subscription: state.subscription, - ), - _CurrentPlanBox(subscription: state.subscription), - ], - ); - }, + ready: (state) => SettingsBody( + autoSeparate: false, + title: LocaleKeys.settings_planPage_title.tr(), + children: [ + _PlanUsageSummary( + usage: state.workspaceUsage, + subscription: state.subscription, + ), + _CurrentPlanBox(subscription: state.subscription), + ], + ), ); }, ), @@ -266,13 +264,16 @@ class _ProConItem extends StatelessWidget { @override Widget build(BuildContext context) { return Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( - height: 24, - width: 24, + width: 18, child: FlowySvg( - isPro ? FlowySvgs.check_m : FlowySvgs.close_s, - color: isPro ? null : const Color(0xFF900000), + isPro ? FlowySvgs.check_m : FlowySvgs.close_error_s, + size: const Size.square(18), + color: isPro + ? AFThemeExtension.of(context).strongText + : const Color(0xFF900000), ), ), const HSpace(4), @@ -415,7 +416,7 @@ class _ToggleMoreState extends State<_ToggleMore> { @override Widget build(BuildContext context) { - final isLM = Brightness.light == Theme.of(context).brightness; + final isLM = Theme.of(context).isLightMode; final primaryColor = isLM ? const Color(0xFF653E8C) : const Color(0xFFE8E2EE); final secondaryColor = @@ -426,7 +427,6 @@ class _ToggleMoreState extends State<_ToggleMore> { Toggle( value: toggleValue, padding: EdgeInsets.zero, - style: ToggleStyle.big, onChanged: (_) { setState(() => toggleValue = !toggleValue); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart index 74ccac5558..5cce796f8d 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart @@ -31,7 +31,6 @@ import 'package:appflowy/workspace/presentation/settings/shared/settings_radio_s import 'package:appflowy/workspace/presentation/settings/shared/single_setting_action.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/theme_upload/theme_upload_view.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -417,7 +416,6 @@ class EnableRTLItemsSwitcher extends StatelessWidget { ), const HSpace(16), Toggle( - style: ToggleStyle.big, value: context .watch() .state @@ -564,7 +562,6 @@ class _TimeFormatSwitcher extends StatelessWidget { ), const HSpace(16), Toggle( - style: ToggleStyle.big, value: context.watch().state.timeFormat == UserTimeFormatPB.TwentyFourHour, onChanged: (value) => 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 index 17f1582c90..04bc501c6b 100644 --- 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 @@ -1,9 +1,10 @@ +import 'package:flutter/material.dart'; + 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({ @@ -17,7 +18,7 @@ class RestartButton extends StatelessWidget { @override Widget build(BuildContext context) { - final List children = [_buildRestartButton()]; + final List children = [_buildRestartButton(context)]; if (showRestartHint) { children.add( Padding( @@ -33,25 +34,43 @@ class RestartButton extends StatelessWidget { return Column(children: children); } - Widget _buildRestartButton() { + Widget _buildRestartButton(BuildContext context) { if (PlatformExtension.isDesktopOrWeb) { return Row( children: [ - FlowyButton( - isSelected: true, - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric( - horizontal: 30, - vertical: 10, + SizedBox( + height: 42, + child: FlowyTextButton( + LocaleKeys.settings_manageDataPage_dataStorage_actions_change + .tr(), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + fontWeight: FontWeight.w600, + radius: BorderRadius.circular(12), + fillColor: Theme.of(context).colorScheme.primary, + hoverColor: const Color(0xFF005483), + fontHoverColor: Colors.white, + onPressed: onClick, ), - text: FlowyText( - LocaleKeys.settings_menu_restartApp.tr(), - ), - onTap: onClick, ), - const Spacer(), ], ); + // 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(), 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 1d8795411d..8716c8ca89 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 @@ -10,7 +10,6 @@ import 'package:appflowy/workspace/application/settings/appflowy_cloud_urls_bloc import 'package:appflowy/workspace/presentation/settings/widgets/_restart_app_button.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart'; @@ -317,7 +316,6 @@ class AppFlowyCloudEnableSync extends StatelessWidget { FlowyText.medium(LocaleKeys.settings_menu_enableSync.tr()), const Spacer(), Toggle( - style: ToggleStyle.big, value: state.setting.enableSync, onChanged: (value) => context .read() 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 10e69be87a..7191e2cc9d 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 @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/env/cloud_env.dart'; import 'package:appflowy/env/env.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; @@ -6,16 +8,16 @@ 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/shared/af_dropdown_menu_entry.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart'; +import 'package:appflowy/workspace/presentation/settings/shared/settings_dropdown.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/setting_local_cloud.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.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/theme_extension.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'; @@ -41,6 +43,7 @@ class SettingCloud extends StatelessWidget { builder: (context, state) { return SettingsBody( title: LocaleKeys.settings_menu_cloudSettings.tr(), + autoSeparate: false, children: [ if (Env.enableCustomCloud) Row( @@ -50,11 +53,13 @@ class SettingCloud extends StatelessWidget { LocaleKeys.settings_menu_cloudServerType.tr(), ), ), - CloudTypeSwitcher( - cloudType: state.cloudType, - onSelected: (type) => context - .read() - .add(CloudSettingEvent.updateCloudType(type)), + Flexible( + child: CloudTypeSwitcher( + cloudType: state.cloudType, + onSelected: (type) => context + .read() + .add(CloudSettingEvent.updateCloudType(type)), + ), ), ], ), @@ -74,21 +79,13 @@ class SettingCloud extends StatelessWidget { Widget _viewFromCloudType(AuthenticatorType cloudType) { switch (cloudType) { case AuthenticatorType.local: - return SettingLocalCloud( - restartAppFlowy: restartAppFlowy, - ); + return SettingLocalCloud(restartAppFlowy: restartAppFlowy); case AuthenticatorType.supabase: - return SettingSupabaseCloudView( - restartAppFlowy: restartAppFlowy, - ); + return SettingSupabaseCloudView(restartAppFlowy: restartAppFlowy); case AuthenticatorType.appflowyCloud: - return AppFlowyCloudViewSetting( - restartAppFlowy: restartAppFlowy, - ); + return AppFlowyCloudViewSetting(restartAppFlowy: restartAppFlowy); case AuthenticatorType.appflowyCloudSelfHost: - return CustomAppFlowyCloudView( - restartAppFlowy: restartAppFlowy, - ); + return CustomAppFlowyCloudView(restartAppFlowy: restartAppFlowy); case AuthenticatorType.appflowyCloudDevelop: return AppFlowyCloudViewSetting( serverURL: "http://localhost", @@ -122,63 +119,57 @@ class CloudTypeSwitcher extends StatelessWidget { return 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: AFThemeExtension.of(context).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, - ); + ? SettingsDropdown( + selectedOption: cloudType, + onChanged: (type) { + if (type != cloudType) { + NavigatorAlertDialog( + title: LocaleKeys.settings_menu_changeServerTip.tr(), + confirm: () async { + onSelected(type); + }, + hideCancelButton: true, + ).show(context); + } }, + options: values + .map( + (type) => buildDropdownMenuEntry( + context, + value: type, + label: titleFromCloudType(type), + ), + ) + .toList(), ) : FlowyButton( - text: FlowyText( - titleFromCloudType(cloudType), - ), + text: FlowyText(titleFromCloudType(cloudType)), useIntrinsicWidth: true, rightIcon: const Icon( Icons.chevron_right, ), - onTap: () { - showMobileBottomSheet( - context, - showHeader: true, - showDragHandle: true, - showDivider: false, - title: LocaleKeys.settings_menu_cloudServerType.tr(), - builder: (context) { - return 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(), - ); - }, - ); - }, + onTap: () => showMobileBottomSheet( + context, + showHeader: true, + showDragHandle: true, + showDivider: false, + title: LocaleKeys.settings_menu_cloudServerType.tr(), + builder: (context) => 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/settings_notifications_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_notifications_view.dart index f7dcb63507..bdeb288ec6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_notifications_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_notifications_view.dart @@ -4,6 +4,7 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart'; import 'package:appflowy/workspace/presentation/settings/shared/setting_list_tile.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart'; +import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -23,10 +24,8 @@ class SettingsNotificationsView extends StatelessWidget { hint: LocaleKeys.settings_notifications_enableNotifications_hint .tr(), trailing: [ - Switch( + Toggle( value: state.isNotificationsEnabled, - splashRadius: 0, - activeColor: Theme.of(context).colorScheme.primary, onChanged: (value) => context .read() .toggleNotificationsEnabled(), @@ -40,10 +39,8 @@ class SettingsNotificationsView extends StatelessWidget { hint: LocaleKeys.settings_notifications_showNotificationsIcon_hint .tr(), trailing: [ - Switch( + Toggle( value: state.isShowNotificationsIconEnabled, - splashRadius: 0, - activeColor: Theme.of(context).colorScheme.primary, onChanged: (_) => context .read() .toogleShowNotificationIconEnabled(), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/end_time_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/end_time_button.dart index 6f60257929..0dddca0464 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/end_time_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/end_time_button.dart @@ -1,12 +1,12 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter/material.dart'; class EndTimeButton extends StatelessWidget { const EndTimeButton({ @@ -38,7 +38,6 @@ class EndTimeButton extends StatelessWidget { Toggle( value: isRange, onChanged: onChanged, - style: ToggleStyle.big, padding: EdgeInsets.zero, ), ], diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/toggle/toggle.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/toggle/toggle.dart index c788eaeea3..4bdeb2521b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/toggle/toggle.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/toggle/toggle.dart @@ -1,13 +1,40 @@ -import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; -import 'package:flowy_infra/theme_extension.dart'; import 'package:flutter/material.dart'; +import 'package:flowy_infra/theme_extension.dart'; + +class ToggleStyle { + const ToggleStyle({ + required this.height, + required this.width, + required this.thumbRadius, + }); + + const ToggleStyle.big() + : height = 16, + width = 27, + thumbRadius = 14; + + const ToggleStyle.small() + : height = 10, + width = 16, + thumbRadius = 8; + + const ToggleStyle.mobile() + : height = 24, + width = 42, + thumbRadius = 18; + + final double height; + final double width; + final double thumbRadius; +} + class Toggle extends StatelessWidget { const Toggle({ super.key, required this.value, required this.onChanged, - required this.style, + this.style = const ToggleStyle.big(), this.thumbColor, this.activeBackgroundColor, this.inactiveBackgroundColor, @@ -26,7 +53,8 @@ class Toggle extends StatelessWidget { Widget build(BuildContext context) { final backgroundColor = value ? activeBackgroundColor ?? Theme.of(context).colorScheme.primary - : activeBackgroundColor ?? AFThemeExtension.of(context).toggleOffFill; + : inactiveBackgroundColor ?? + AFThemeExtension.of(context).toggleButtonBGColor; return GestureDetector( onTap: () => onChanged(value), child: Padding( @@ -49,7 +77,7 @@ class Toggle extends StatelessWidget { height: style.thumbRadius, width: style.thumbRadius, decoration: BoxDecoration( - color: thumbColor ?? Theme.of(context).colorScheme.onPrimary, + color: thumbColor ?? Colors.white, borderRadius: BorderRadius.circular(style.thumbRadius / 2), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/toggle/toggle_style.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/toggle/toggle_style.dart deleted file mode 100644 index d11bb5e40e..0000000000 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/toggle/toggle_style.dart +++ /dev/null @@ -1,20 +0,0 @@ -class ToggleStyle { - ToggleStyle({ - required this.height, - required this.width, - required this.thumbRadius, - }); - - final double height; - final double width; - final double thumbRadius; - - static ToggleStyle get big => - ToggleStyle(height: 16, width: 27, thumbRadius: 14); - - static ToggleStyle get small => - ToggleStyle(height: 10, width: 16, thumbRadius: 8); - - static ToggleStyle get mobile => - ToggleStyle(height: 24, width: 42, thumbRadius: 18); -} diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart index e87fbbc424..94c59302f1 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart @@ -126,7 +126,7 @@ class DefaultColorScheme extends FlowyColorScheme { questionBubbleBG: _darkShader3, progressBarBGColor: _darkShader3, toolbarColor: _darkInput, - toggleButtonBGColor: _darkShader1, + toggleButtonBGColor: const Color(0xFF828282), calendarWeekendBGColor: _darkShader1, gridRowCountColor: _darkShader5, ); diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart index e99ee90f56..eb32f60f61 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -1,11 +1,12 @@ import 'dart:io'; +import 'package:flutter/material.dart'; + import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/ignore_parent_gesture.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter/material.dart'; class FlowyButton extends StatelessWidget { final Widget text; @@ -195,7 +196,11 @@ class FlowyTextButton extends StatelessWidget { children.add(heading!); children.add(const HSpace(8)); } - children.add(Text(text, overflow: overflow, textAlign: TextAlign.center)); + children.add(Text( + text, + overflow: overflow, + textAlign: TextAlign.center, + )); Widget child = Row( crossAxisAlignment: CrossAxisAlignment.center, @@ -230,6 +235,7 @@ class FlowyTextButton extends StatelessWidget { fontSize: fontSize, decoration: decoration, fontFamily: fontFamily, + height: 1.1, ), ), backgroundColor: WidgetStateProperty.resolveWith( diff --git a/frontend/resources/flowy_icons/16x/close_error.svg b/frontend/resources/flowy_icons/16x/close_error.svg new file mode 100644 index 0000000000..6e1321a6ec --- /dev/null +++ b/frontend/resources/flowy_icons/16x/close_error.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 50067fbf6c..985e17eee8 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -478,8 +478,8 @@ "importData": { "title": "Import data", "tooltip": "Import data from @:appName backups/data folders", - "description": "Copy data from an external @:appName data folder and import it into the current @:appName data folder", - "action": "Browse folder" + "description": "Copy data from an external @:appName data folder", + "action": "Browse file" }, "encryption": { "title": "Encryption", @@ -494,7 +494,7 @@ }, "cache": { "title": "Clear cache", - "description": "If you encounter issues with images not loading or fonts not displaying correctly, try clearing your cache. This action will not remove your user data.", + "description": "Clear app cache, this can help resolve issues like images or fonts not loading. This will not affect your data.", "dialog": { "title": "Are you sure?", "description": "Clearing the cache will cause images and fonts to be re-downloaded on load. This action will not remove or modify your data.",