fix: some mobile search UI issues (#7845)

* fix: some mobile search UI issues

* fix: some icon colors

* fix: show 'Add Link' while creating a link on mobile

* fix: add tapping event for mobile embed link

* fix: bookmark can not open the non-http link

* fix: improve the behavior of links on mobile

* fix: switch workspace will refresh the reminders

* chore: remove unused import

* fix: test error
This commit is contained in:
Morn 2025-04-29 12:52:28 +08:00 committed by GitHub
parent 63aa5112ba
commit d28987d16d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 223 additions and 174 deletions

View File

@ -53,6 +53,7 @@ class _MobileBottomSheetEditLinkWidgetState
ViewPB? currentView; ViewPB? currentView;
bool showErrorText = false; bool showErrorText = false;
bool showRemoveLink = false; bool showRemoveLink = false;
String title = LocaleKeys.editor_editLink.tr();
AppFlowyThemeData get theme => AppFlowyTheme.of(context); AppFlowyThemeData get theme => AppFlowyTheme.of(context);
@ -73,6 +74,7 @@ class _MobileBottomSheetEditLinkWidgetState
)..searchRecentViews(); )..searchRecentViews();
if (linkInfo.link.isEmpty) { if (linkInfo.link.isEmpty) {
isShowingSearchResult = true; isShowingSearchResult = true;
title = LocaleKeys.toolbar_addLink.tr();
} else { } else {
showRemoveLink = true; showRemoveLink = true;
textFocusNode.requestFocus(); textFocusNode.requestFocus();
@ -104,7 +106,7 @@ class _MobileBottomSheetEditLinkWidgetState
child: Column( child: Column(
children: [ children: [
BottomSheetHeader( BottomSheetHeader(
title: LocaleKeys.editor_editLink.tr(), title: title,
onClose: () => context.pop(), onClose: () => context.pop(),
confirmButton: FlowyTextButton( confirmButton: FlowyTextButton(
LocaleKeys.button_done.tr(), LocaleKeys.button_done.tr(),

View File

@ -1,9 +1,11 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart'; import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart';
import 'package:appflowy/workspace/application/command_palette/search_result_ext.dart'; import 'package:appflowy/workspace/application/command_palette/search_result_ext.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-search/result.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-search/result.pb.dart';
import 'package:appflowy_ui/appflowy_ui.dart'; import 'package:appflowy_ui/appflowy_ui.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -20,12 +22,18 @@ class MobileSearchResultCell extends StatelessWidget {
final theme = AppFlowyTheme.of(context), final theme = AppFlowyTheme.of(context),
textColor = theme.textColorScheme.primary; textColor = theme.textColorScheme.primary;
final commandPaletteState = context.read<CommandPaletteBloc>().state; final commandPaletteState = context.read<CommandPaletteBloc>().state;
final displayName = item.displayName.isEmpty
? LocaleKeys.menuAppHeader_defaultNewPageName.tr()
: item.displayName;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
buildIcon(theme), SizedBox.square(
dimension: 24,
child: Center(child: buildIcon(theme)),
),
HSpace(12), HSpace(12),
Flexible( Flexible(
child: Column( child: Column(
@ -35,7 +43,7 @@ class MobileSearchResultCell extends StatelessWidget {
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
text: buildHighLightSpan( text: buildHighLightSpan(
content: item.displayName, content: displayName,
normal: theme.textStyle.heading4.standard(color: textColor), normal: theme.textStyle.heading4.standard(color: textColor),
highlight: theme.textStyle.heading4 highlight: theme.textStyle.heading4
.standard(color: textColor) .standard(color: textColor)
@ -45,7 +53,7 @@ class MobileSearchResultCell extends StatelessWidget {
), ),
), ),
buildPath(commandPaletteState, theme), buildPath(commandPaletteState, theme),
buildSummary(theme), ...buildSummary(theme),
], ],
), ),
), ),
@ -84,11 +92,11 @@ class MobileSearchResultCell extends StatelessWidget {
); );
} }
Widget buildSummary(AppFlowyThemeData theme) { List<Widget> buildSummary(AppFlowyThemeData theme) {
if (item.content.isEmpty) { if (item.content.isEmpty) return [];
return const SizedBox.shrink(); return [
} VSpace(theme.spacing.m),
return RichText( RichText(
maxLines: 3, maxLines: 3,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
text: buildHighLightSpan( text: buildHighLightSpan(
@ -101,7 +109,8 @@ class MobileSearchResultCell extends StatelessWidget {
backgroundColor: theme.fillColorScheme.themeSelect, backgroundColor: theme.fillColorScheme.themeSelect,
), ),
), ),
); ),
];
} }
TextSpan buildHighLightSpan({ TextSpan buildHighLightSpan({

View File

@ -55,7 +55,7 @@ class _MobileSearchTextfieldState extends State<MobileSearchTextfield> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = AppFlowyTheme.of(context); final theme = AppFlowyTheme.of(context);
return SizedBox( return SizedBox(
height: 40, height: 42,
child: ValueListenableBuilder( child: ValueListenableBuilder(
valueListenable: controller, valueListenable: controller,
builder: (context, _, __) { builder: (context, _, __) {
@ -84,14 +84,19 @@ class _MobileSearchTextfieldState extends State<MobileSearchTextfield> {
if (!hasFocus || !hasText) return SizedBox.shrink(); if (!hasFocus || !hasText) return SizedBox.shrink();
return GestureDetector( return GestureDetector(
onTap: () => focusNode.unfocus(), onTap: () => focusNode.unfocus(),
child: Padding( behavior: HitTestBehavior.opaque,
child: Container(
height: 42,
padding: EdgeInsets.only(left: 8), padding: EdgeInsets.only(left: 8),
child: Align(
alignment: Alignment.centerLeft,
child: Text( child: Text(
LocaleKeys.button_cancel.tr(), LocaleKeys.button_cancel.tr(),
style: theme.textStyle.body style: theme.textStyle.body
.standard(color: theme.textColorScheme.action), .standard(color: theme.textColorScheme.action),
), ),
), ),
),
); );
}, },
), ),

View File

@ -2,6 +2,7 @@ import 'dart:math';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_ui/appflowy_ui.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -328,6 +329,7 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
} }
Widget _buildNoResultsWidget(BuildContext context) { Widget _buildNoResultsWidget(BuildContext context) {
final theme = AppFlowyTheme.of(context);
return DecoratedBox( return DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).cardColor, color: Theme.of(context).cardColor,
@ -350,7 +352,10 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
child: Center( child: Center(
child: Text( child: Text(
LocaleKeys.inlineActions_noResults.tr(), LocaleKeys.inlineActions_noResults.tr(),
style: TextStyle(fontSize: 18.0, color: Color(0x801F2225)), style: TextStyle(
fontSize: 18.0,
color: theme.textColorScheme.primary,
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),

View File

@ -12,6 +12,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:universal_platform/universal_platform.dart';
import 'link_embed_menu.dart'; import 'link_embed_menu.dart';
@ -156,7 +157,9 @@ class LinkEmbedBlockComponentState
child: ValueListenableBuilder<bool>( child: ValueListenableBuilder<bool>(
valueListenable: showActionsNotifier, valueListenable: showActionsNotifier,
builder: (context, showActions, child) { builder: (context, showActions, child) {
if (!showActions) return SizedBox.shrink(); if (!showActions || UniversalPlatform.isMobile) {
return SizedBox.shrink();
}
return LinkEmbedMenu( return LinkEmbedMenu(
editorState: context.read<EditorState>(), editorState: context.read<EditorState>(),
node: node, node: node,
@ -189,14 +192,22 @@ class LinkEmbedBlockComponentState
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: !UniversalPlatform.isMobile
? null
: () =>
afLaunchUrlString(url, addingHttpSchemeWhenFailed: true),
child: ClipRRect( child: ClipRRect(
borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), borderRadius:
const BorderRadius.vertical(top: Radius.circular(16)),
child: FlowyNetworkImage( child: FlowyNetworkImage(
url: linkInfo.imageUrl ?? '', url: linkInfo.imageUrl ?? '',
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
), ),
), ),
), ),
),
MouseRegion( MouseRegion(
cursor: SystemMouseCursors.click, cursor: SystemMouseCursors.click,
child: GestureDetector( child: GestureDetector(
@ -258,7 +269,13 @@ class LinkEmbedBlockComponentState
child: CircularProgressIndicator.adaptive(), child: CircularProgressIndicator.adaptive(),
), ),
) )
: Center( : GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: !UniversalPlatform.isMobile
? null
: () =>
afLaunchUrlString(url, addingHttpSchemeWhenFailed: true),
child: Center(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -299,6 +316,7 @@ class LinkEmbedBlockComponentState
), ),
], ],
), ),
),
); );
} }

View File

@ -122,7 +122,8 @@ class CustomLinkPreviewWidget extends StatelessWidget {
return MouseRegion( return MouseRegion(
cursor: SystemMouseCursors.click, cursor: SystemMouseCursors.click,
child: GestureDetector( child: GestureDetector(
onTap: () => afLaunchUrlString(url), behavior: HitTestBehavior.opaque,
onTap: () => afLaunchUrlString(url, addingHttpSchemeWhenFailed: true),
child: child, child: child,
), ),
); );
@ -133,7 +134,8 @@ class CustomLinkPreviewWidget extends StatelessWidget {
editorState: context.read<EditorState>(), editorState: context.read<EditorState>(),
extendActionWidgets: _buildExtendActionWidgets(context), extendActionWidgets: _buildExtendActionWidgets(context),
child: GestureDetector( child: GestureDetector(
onTap: () => afLaunchUrlString(url), behavior: HitTestBehavior.opaque,
onTap: () => afLaunchUrlString(url, addingHttpSchemeWhenFailed: true),
child: child, child: child,
), ),
); );

View File

@ -4,6 +4,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/link_previ
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:universal_platform/universal_platform.dart';
import 'custom_link_preview.dart'; import 'custom_link_preview.dart';
import 'default_selectable_mixin.dart'; import 'default_selectable_mixin.dart';
@ -148,7 +149,7 @@ class CustomLinkPreviewBlockComponentState
child = Stack( child = Stack(
children: [ children: [
child, child,
if (showActions) if (showActions && UniversalPlatform.isDesktopOrWeb)
Positioned( Positioned(
top: 12, top: 12,
right: 12, right: 12,

View File

@ -13,6 +13,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:universal_platform/universal_platform.dart';
import 'mention_link_error_preview.dart'; import 'mention_link_error_preview.dart';
import 'mention_link_preview.dart'; import 'mention_link_preview.dart';
@ -91,6 +92,10 @@ class _MentionLinkBlockState extends State<MentionLinkBlock> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final child = buildIconWithTitle(context);
if (UniversalPlatform.isMobile) return child;
return AppFlowyPopover( return AppFlowyPopover(
key: ValueKey(showAtBottom), key: ValueKey(showAtBottom),
controller: previewController, controller: previewController,
@ -143,7 +148,12 @@ class _MentionLinkBlockState extends State<MentionLinkBlock> {
onRemoveLink: removeLink, onRemoveLink: removeLink,
onOpenLink: openLink, onOpenLink: openLink,
), ),
child: buildIconWithTitle(context), child: MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: onEnter,
onExit: onExit,
child: child,
),
); );
} }
@ -151,17 +161,12 @@ class _MentionLinkBlockState extends State<MentionLinkBlock> {
final theme = AppFlowyTheme.of(context); final theme = AppFlowyTheme.of(context);
final siteName = linkInfo.siteName, linkTitle = linkInfo.title ?? url; final siteName = linkInfo.siteName, linkTitle = linkInfo.title ?? url;
return MouseRegion( return GestureDetector(
cursor: SystemMouseCursors.click,
onEnter: onEnter,
onExit: onExit,
child: GestureDetector(
onTap: () async { onTap: () async {
await afLaunchUrlString(url, addingHttpSchemeWhenFailed: true); await afLaunchUrlString(url, addingHttpSchemeWhenFailed: true);
}, },
child: FlowyHoverContainer( child: FlowyHoverContainer(
style: style: HoverStyle(hoverColor: Theme.of(context).colorScheme.secondary),
HoverStyle(hoverColor: Theme.of(context).colorScheme.secondary),
applyStyle: isHovering, applyStyle: isHovering,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -196,7 +201,6 @@ class _MentionLinkBlockState extends State<MentionLinkBlock> {
], ],
), ),
), ),
),
); );
} }

View File

@ -37,7 +37,6 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
_listener = AppLifecycleListener( _listener = AppLifecycleListener(
onResume: () { onResume: () {
if (!isClosed) { if (!isClosed) {
add(const ReminderEvent.refresh());
add(const ReminderEvent.resetTimer()); add(const ReminderEvent.resetTimer());
} }
}, },
@ -437,15 +436,11 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
Future<bool> checkReminderAvailable( Future<bool> checkReminderAvailable(
ReminderPB reminder, ReminderPB reminder,
Set<String> reminderIds, { Set<String> reminderIds,
Set<String>? removedIds, ) async {
}) async {
/// blockId is null means no node /// blockId is null means no node
final blockId = reminder.meta[ReminderMetaKeys.blockId]; final blockId = reminder.meta[ReminderMetaKeys.blockId];
if (blockId == null) { if (blockId == null) return false;
removedIds?.add(reminder.id);
return false;
}
/// check if schedule time is comming /// check if schedule time is comming
final scheduledAt = reminder.scheduledAt.toDateTime(); final scheduledAt = reminder.scheduledAt.toDateTime();
@ -457,19 +452,13 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
final viewId = reminder.objectId; final viewId = reminder.objectId;
final view = final view =
await ViewBackendService.getView(viewId).fold((s) => s, (_) => null); await ViewBackendService.getView(viewId).fold((s) => s, (_) => null);
if (view == null) { if (view == null) return false;
removedIds?.add(reminder.id);
return false;
}
/// check if document is not null /// check if document is not null
final document = await DocumentService() final document = await DocumentService()
.openDocument(documentId: viewId) .openDocument(documentId: viewId)
.fold((s) => s.toDocument(), (_) => null); .fold((s) => s.toDocument(), (_) => null);
if (document == null) { if (document == null) return false;
removedIds?.add(reminder.id);
return false;
}
Node? searchById(Node current, String id) { Node? searchById(Node current, String id) {
if (current.id == id) { if (current.id == id) {
return current; return current;
@ -488,10 +477,7 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
/// check if node is not null /// check if node is not null
final node = searchById(document.root, blockId); final node = searchById(document.root, blockId);
if (node == null) { if (node == null) return false;
removedIds?.add(reminder.id);
return false;
}
final textInserts = node.delta?.whereType<TextInsert>(); final textInserts = node.delta?.whereType<TextInsert>();
if (textInserts == null) return false; if (textInserts == null) return false;
for (final text in textInserts) { for (final text in textInserts) {
@ -502,8 +488,6 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
return true; return true;
} }
} }
removedIds?.add(reminder.id);
return false; return false;
} }
@ -512,19 +496,11 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
) async { ) async {
final List<ReminderPB> availableReminders = []; final List<ReminderPB> availableReminders = [];
final reminderIds = reminders.map((e) => e.id).toSet(); final reminderIds = reminders.map((e) => e.id).toSet();
final removedIds = <String>{};
for (final r in reminders) { for (final r in reminders) {
if (await checkReminderAvailable( if (await checkReminderAvailable(r, reminderIds)) {
r,
reminderIds,
removedIds: removedIds,
)) {
availableReminders.add(r); availableReminders.add(r);
} }
} }
for (final id in removedIds) {
add(ReminderEvent.remove(reminderId: id));
}
return availableReminders; return availableReminders;
} }
} }

View File

@ -1,5 +1,7 @@
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/shared/feature_flags.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
import 'package:appflowy/user/application/user_listener.dart'; import 'package:appflowy/user/application/user_listener.dart';
import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy/user/application/user_service.dart';
import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/log.dart';
@ -285,6 +287,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
), ),
), ),
); );
getIt<ReminderBloc>().add(ReminderEvent.started());
}, },
renameWorkspace: (workspaceId, name) async { renameWorkspace: (workspaceId, name) async {
final result = final result =

View File

@ -276,7 +276,7 @@ class DesktopHomeScreen extends StatelessWidget {
.animatedPanelX( .animatedPanelX(
closeX: -layout.notificationPanelWidth, closeX: -layout.notificationPanelWidth,
isClosed: !layout.showNotificationPanel, isClosed: !layout.showNotificationPanel,
curve: Curves.easeInOut, curve: Curves.easeOutQuad,
duration: layout.animDuration.inMilliseconds * 0.001, duration: layout.animDuration.inMilliseconds * 0.001,
) )
.positioned( .positioned(

View File

@ -6,6 +6,7 @@ import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
import 'package:appflowy_ui/appflowy_ui.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/hover.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/flowy_tooltip.dart';
@ -83,6 +84,7 @@ class SidebarTopMenu extends StatelessWidget {
), ),
], ],
); );
final theme = AppFlowyTheme.of(context);
return ValueListenableBuilder( return ValueListenableBuilder(
valueListenable: isSidebarOnHover, valueListenable: isSidebarOnHover,
@ -97,10 +99,12 @@ class SidebarTopMenu extends StatelessWidget {
onPointerDown: (_) => onPointerDown: (_) =>
context.read<HomeSettingBloc>().collapseMenu(), context.read<HomeSettingBloc>().collapseMenu(),
child: FlowyHover( child: FlowyHover(
child: Container( child: SizedBox(
width: 24, width: 24,
padding: const EdgeInsets.all(4), child: FlowySvg(
child: const FlowySvg(FlowySvgs.hide_menu_s), FlowySvgs.double_back_arrow_m,
color: theme.iconColorScheme.secondary,
),
), ),
), ),
), ),

View File

@ -4,6 +4,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_stack.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart';
import 'package:appflowy_ui/appflowy_ui.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart';
@ -81,6 +82,7 @@ class FlowyNavigation extends StatelessWidget {
), ),
], ],
); );
final theme = AppFlowyTheme.of(context);
return Padding( return Padding(
padding: const EdgeInsets.only(right: 8.0), padding: const EdgeInsets.only(right: 8.0),
child: SizedBox( child: SizedBox(
@ -101,8 +103,10 @@ class FlowyNavigation extends StatelessWidget {
child: FlowyIconButton( child: FlowyIconButton(
width: 24, width: 24,
onPressed: () {}, onPressed: () {},
iconPadding: const EdgeInsets.all(4), icon: FlowySvg(
icon: const FlowySvg(FlowySvgs.hide_menu_s), FlowySvgs.double_back_arrow_m,
color: theme.iconColorScheme.secondary,
),
), ),
), ),
), ),

View File

@ -99,8 +99,9 @@ class _NotificationPanelState extends State<NotificationPanel>
Widget buildTitle({ Widget buildTitle({
required BuildContext context, required BuildContext context,
required VoidCallback onHide, required VoidCallback onHide,
}) => }) {
Container( final theme = AppFlowyTheme.of(context);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
height: 24, height: 24,
child: Row( child: Row(
@ -112,19 +113,23 @@ class _NotificationPanelState extends State<NotificationPanel>
), ),
Spacer(), Spacer(),
FlowyIconButton( FlowyIconButton(
icon: FlowySvg(FlowySvgs.hide_menu_s),
width: 24, width: 24,
icon: FlowySvg(
FlowySvgs.double_back_arrow_m,
color: theme.iconColorScheme.secondary,
),
richTooltipText: colappsedButtonTooltip(context), richTooltipText: colappsedButtonTooltip(context),
onPressed: onHide, onPressed: onHide,
iconPadding: const EdgeInsets.all(4),
), ),
HSpace(8), HSpace(8),
buildMoreActionButton(context), buildMoreActionButton(context),
], ],
), ),
); );
}
Widget buildMoreActionButton(BuildContext context) { Widget buildMoreActionButton(BuildContext context) {
final theme = AppFlowyTheme.of(context);
return AppFlowyPopover( return AppFlowyPopover(
constraints: BoxConstraints.loose(const Size(240, 78)), constraints: BoxConstraints.loose(const Size(240, 78)),
offset: const Offset(-24, 24), offset: const Offset(-24, 24),
@ -134,13 +139,15 @@ class _NotificationPanelState extends State<NotificationPanel>
onClose: () => keepEditorFocusNotifier.decrease(), onClose: () => keepEditorFocusNotifier.decrease(),
popupBuilder: (_) => buildMoreActions(), popupBuilder: (_) => buildMoreActions(),
child: FlowyIconButton( child: FlowyIconButton(
icon: FlowySvg(FlowySvgs.three_dots_s),
width: 24, width: 24,
icon: FlowySvg(
FlowySvgs.three_dots_m,
color: theme.iconColorScheme.secondary,
),
onPressed: () { onPressed: () {
keepEditorFocusNotifier.increase(); keepEditorFocusNotifier.increase();
moreActionController.show(); moreActionController.show();
}, },
iconPadding: const EdgeInsets.all(4),
), ),
); );
} }

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.25 6.75L6 12L11.25 17.25" stroke="#171717" stroke-width="1.2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.4375 6.75L12.1875 12L17.4375 17.25" stroke="#171717" stroke-width="1.2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.325 12.0004C8.325 12.746 7.72058 13.3504 6.975 13.3504C6.22942 13.3504 5.625 12.746 5.625 12.0004C5.625 11.2548 6.22942 10.6504 6.975 10.6504C7.72058 10.6504 8.325 11.2548 8.325 12.0004Z" fill="#171717"/>
<path d="M13.3499 12.0004C13.3499 12.746 12.7455 13.3504 11.9999 13.3504C11.2543 13.3504 10.6499 12.746 10.6499 12.0004C10.6499 11.2548 11.2543 10.6504 11.9999 10.6504C12.7455 10.6504 13.3499 11.2548 13.3499 12.0004Z" fill="#171717"/>
<path d="M18.375 12.0004C18.375 12.746 17.7706 13.3504 17.025 13.3504C16.2795 13.3504 15.675 12.746 15.675 12.0004C15.675 11.2548 16.2795 10.6504 17.025 10.6504C17.7706 10.6504 18.375 11.2548 18.375 12.0004Z" fill="#171717"/>
</svg>

After

Width:  |  Height:  |  Size: 781 B