From 13107b63e92071becdd98b375c03cf64c03e4a57 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Sat, 15 Jun 2024 09:03:09 +0800 Subject: [PATCH] feat: improve upgrade space toast (#5543) * fix: divider color * feat: improve upgrade space toast --- .../home/favorite_folder/favorite_space.dart | 6 +- .../home/recent_folder/recent_space.dart | 2 +- .../mobile_bottom_navigation_bar.dart | 6 +- .../application/sidebar/space/space_bloc.dart | 2 +- .../home/menu/sidebar/sidebar.dart | 31 ++-- .../menu/sidebar/space/space_migration.dart | 169 ++++++++++++++++++ .../flowy_icons/16x/space_arrow_right.svg | 3 + .../resources/flowy_icons/16x/upgrade.svg | 14 ++ .../flowy_icons/16x/upgrade_close.svg | 5 + frontend/resources/translations/en.json | 6 +- 10 files changed, 217 insertions(+), 27 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_migration.dart create mode 100644 frontend/resources/flowy_icons/16x/space_arrow_right.svg create mode 100644 frontend/resources/flowy_icons/16x/upgrade.svg create mode 100644 frontend/resources/flowy_icons/16x/upgrade_close.svg diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/favorite_space.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/favorite_space.dart index 86d445a3f51dc..105ebdfc9cf96 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/favorite_space.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/favorite_space.dart @@ -1,6 +1,7 @@ import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/home/shared/empty_placeholder.dart'; import 'package:appflowy/mobile/presentation/home/shared/mobile_view_card.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/user/prelude.dart'; @@ -92,6 +93,9 @@ class _FavoriteViews extends StatelessWidget { @override Widget build(BuildContext context) { + final borderColor = Theme.of(context).isLightMode + ? const Color(0xFFE9E9EC) + : const Color(0x1AFFFFFF); return Scrollbar( child: ListView.separated( key: const PageStorageKey('favorite_views_page_storage_key'), @@ -108,7 +112,7 @@ class _FavoriteViews extends StatelessWidget { decoration: BoxDecoration( border: Border( bottom: BorderSide( - color: Theme.of(context).dividerColor, + color: borderColor, width: 0.5, ), ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart index 5fa3b6e27f740..5d313a3533c87 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart @@ -65,7 +65,7 @@ class _RecentViews extends StatelessWidget { @override Widget build(BuildContext context) { final borderColor = Theme.of(context).isLightMode - ? const Color(0x00e2e2e4) + ? const Color(0xFFE9E9EC) : const Color(0x1AFFFFFF); return SlidableAutoCloseBehavior( child: Scrollbar( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart b/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart index 600d65ad13b37..d50369e5f962f 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart @@ -52,15 +52,15 @@ class MobileBottomNavigationBar extends StatelessWidget { final isLightMode = Theme.of(context).isLightMode; final backgroundColor = isLightMode ? Colors.white.withOpacity(0.95) - : const Color(0x0023262b).withOpacity(0.95); + : const Color(0xFF23262B).withOpacity(0.95); return Scaffold( body: navigationShell, extendBody: true, bottomNavigationBar: ClipRRect( child: BackdropFilter( filter: ImageFilter.blur( - sigmaX: 2, - sigmaY: 2, + sigmaX: 3, + sigmaY: 3, ), child: DecoratedBox( decoration: BoxDecoration( diff --git a/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart index 911ea4ab55e0d..337ec43881604 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart @@ -82,7 +82,7 @@ class SpaceBloc extends Bloc { ); if (shouldShowUpgradeDialog) { - add(const SpaceEvent.migrate()); + // add(const SpaceEvent.migrate()); } }, create: (name, icon, iconColor, permission) async { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 9aa353fb6ce00..7fe35dd88c854 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -23,6 +23,7 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/header/sidebar import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_new_page_button.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/sidebar_space.dart'; +import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_migration.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart' @@ -304,8 +305,6 @@ class _SidebarState extends State<_Sidebar> { _renderFolderOrSpace(menuHorizontalInset), - _renderUpgradeSpaceButton(menuHorizontalInset), - // trash Padding( padding: menuHorizontalInset + @@ -313,6 +312,8 @@ class _SidebarState extends State<_Sidebar> { child: const Divider(height: 0.5, color: Color(0x141F2329)), ), const VSpace(8), + _renderUpgradeSpaceButton(menuHorizontalInset), + const VSpace(8), Padding( padding: menuHorizontalInset + const EdgeInsets.symmetric(horizontal: 4.0), @@ -368,24 +369,14 @@ class _SidebarState extends State<_Sidebar> { return !spaceState.shouldShowUpgradeDialog || !workspaceState.isCollabWorkspaceOn ? const SizedBox.shrink() - : Container( - height: 40, - padding: menuHorizontalInset, - child: FlowyButton( - onTap: () { - context.read().add(const SpaceEvent.migrate()); - }, - leftIcon: const Icon( - Icons.upgrade_rounded, - color: Colors.red, - ), - leftIconSize: const Size.square(20), - iconPadding: 12.0, - text: FlowyText.regular( - LocaleKeys.space_enableSpacesForYourWorkspace.tr(), - overflow: TextOverflow.ellipsis, - ), - ), + : Padding( + padding: menuHorizontalInset + + const EdgeInsets.only( + left: 4.0, + right: 4.0, + top: 8.0, + ), + child: const SpaceMigration(), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_migration.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_migration.dart new file mode 100644 index 0000000000000..603b69537807c --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_migration.dart @@ -0,0 +1,169 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/application/sidebar/space/space_bloc.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'; + +class SpaceMigration extends StatefulWidget { + const SpaceMigration({super.key}); + + @override + State createState() => _SpaceMigrationState(); +} + +class _SpaceMigrationState extends State { + bool _isExpanded = false; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(12), + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + color: const Color(0x66F5EAFF), + shape: RoundedRectangleBorder( + side: const BorderSide( + strokeAlign: BorderSide.strokeAlignOutside, + color: Color(0x339327FF), + ), + borderRadius: BorderRadius.circular(10), + ), + ), + child: _isExpanded + ? _buildExpandedMigrationContent() + : _buildCollapsedMigrationContent(), + ); + } + + Widget _buildExpandedMigrationContent() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _MigrationTitle( + onClose: () => setState(() => _isExpanded = false), + ), + const VSpace(6.0), + Opacity( + opacity: 0.7, + child: FlowyText.regular( + LocaleKeys.space_upgradeSpaceDescription.tr(), + maxLines: null, + fontSize: 13.0, + lineHeight: 1.3, + ), + ), + const VSpace(12.0), + _ExpandedUpgradeButton( + onUpgrade: () => + context.read().add(const SpaceEvent.migrate()), + ), + ], + ); + } + + Widget _buildCollapsedMigrationContent() { + const linearGradient = LinearGradient( + begin: Alignment.bottomLeft, + end: Alignment.bottomRight, + colors: [ + Color(0xFF8032FF), + Color(0xFFEF35FF), + ], + stops: [ + 0.1545, + 0.8225, + ], + ); + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => setState(() => _isExpanded = true), + child: Row( + children: [ + const FlowySvg( + FlowySvgs.upgrade_s, + blendMode: null, + ), + const HSpace(8.0), + Expanded( + child: ShaderMask( + shaderCallback: (Rect bounds) => + linearGradient.createShader(bounds), + blendMode: BlendMode.srcIn, + child: FlowyText( + LocaleKeys.space_upgradeYourSpace.tr(), + ), + ), + ), + const FlowySvg( + FlowySvgs.space_arrow_right_s, + blendMode: null, + ), + ], + ), + ); + } +} + +class _MigrationTitle extends StatelessWidget { + const _MigrationTitle({required this.onClose}); + + final VoidCallback? onClose; + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const FlowySvg( + FlowySvgs.upgrade_s, + blendMode: null, + ), + const HSpace(8.0), + Expanded( + child: FlowyText( + LocaleKeys.space_upgradeSpaceTitle.tr(), + maxLines: 3, + lineHeight: 1.2, + ), + ), + GestureDetector( + onTap: onClose, + child: const Padding( + padding: EdgeInsets.only(top: 3.0), + child: FlowySvg(FlowySvgs.upgrade_close_s), + ), + ), + ], + ); + } +} + +class _ExpandedUpgradeButton extends StatelessWidget { + const _ExpandedUpgradeButton({required this.onUpgrade}); + + final VoidCallback? onUpgrade; + + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: onUpgrade, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), + decoration: ShapeDecoration( + color: const Color(0xFFA44AFD), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(9)), + ), + child: FlowyText( + LocaleKeys.space_upgrade.tr(), + color: Colors.white, + fontSize: 12.0, + strutStyle: const StrutStyle(forceStrutHeight: true), + ), + ), + ); + } +} diff --git a/frontend/resources/flowy_icons/16x/space_arrow_right.svg b/frontend/resources/flowy_icons/16x/space_arrow_right.svg new file mode 100644 index 0000000000000..6b9e66285ed09 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/space_arrow_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/16x/upgrade.svg b/frontend/resources/flowy_icons/16x/upgrade.svg new file mode 100644 index 0000000000000..0790946477078 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/upgrade.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/frontend/resources/flowy_icons/16x/upgrade_close.svg b/frontend/resources/flowy_icons/16x/upgrade_close.svg new file mode 100644 index 0000000000000..3275378614f0d --- /dev/null +++ b/frontend/resources/flowy_icons/16x/upgrade_close.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index b8a1ad7c0c318..4e510c25aa480 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -1914,6 +1914,10 @@ "unableToDeleteSpaceNotCreatedByYou": "Cannot delete a space created by others", "enableSpacesForYourWorkspace": "Enable spaces for your workspace", "title": "Spaces", - "defaultSpaceName": "General" + "defaultSpaceName": "General", + "upgradeSpaceTitle": "Enable Spaces for your workspace", + "upgradeSpaceDescription": "Create multiple public and private spaces to better organize your work.", + "upgrade": "Upgrade", + "upgradeYourSpace": "Upgrade your space" } } \ No newline at end of file