fix: sidebar issues on Windows and Linux (#5431)

* fix: workspace icon overflow

* fix: notification button doesn't have same effect as settings button

* fix: open-sidebar button wasn't replaced in the Windows title bar

* fix: workspace name overflow on Linux

* fix: appflowy logo align issue
This commit is contained in:
Lucas.Xu 2024-05-29 22:05:20 +08:00 committed by GitHub
parent b8b7a10b33
commit 0bfe071caf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 127 additions and 81 deletions

View File

@ -3,12 +3,13 @@ import 'dart:io';
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/widget/flowy_tooltip.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class CocoaWindowChannel {
@ -102,13 +103,25 @@ class MoveWindowDetectorState extends State<MoveWindowDetector> {
return const SizedBox.shrink();
}
final color = Theme.of(context).isLightMode ? Colors.white : Colors.black;
final textSpan = TextSpan(
children: [
TextSpan(
text: '${LocaleKeys.sideBar_openSidebar.tr()}\n',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: color),
),
TextSpan(
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Theme.of(context).hintColor),
),
],
);
return FlowyTooltip(
richMessage: TextSpan(
children: [
TextSpan(text: '${LocaleKeys.sideBar_closeSidebar.tr()}\n'),
const TextSpan(text: 'Ctrl+\\'),
],
),
richMessage: textSpan,
child: FlowyIconButton(
hoverColor: Colors.transparent,
onPressed: () => context

View File

@ -3,6 +3,7 @@ import 'dart:io' show Platform;
import 'package:appflowy/core/frameless_window.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/home/home_setting_bloc.dart';
import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
@ -51,22 +52,23 @@ class SidebarTopMenu extends StatelessWidget {
? FlowySvgs.flowy_logo_dark_mode_xl
: FlowySvgs.flowy_logo_text_xl;
return FlowySvg(
svgData,
size: const Size(92, 17),
blendMode: null,
return Padding(
padding: const EdgeInsets.only(top: 12.0, left: 4),
child: FlowySvg(
svgData,
size: const Size(92, 17),
blendMode: null,
),
);
}
Widget _buildCollapseMenuButton(BuildContext context) {
final color = Theme.of(context).isLightMode ? Colors.white : Colors.black;
final textSpan = TextSpan(
children: [
TextSpan(
text: '${LocaleKeys.sideBar_closeSidebar.tr()}\n',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Colors.white),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: color),
),
TextSpan(
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',

View File

@ -38,7 +38,6 @@ class SidebarUser extends StatelessWidget {
const HSpace(10),
Expanded(child: _buildUserName(context, state)),
UserSettingButton(userProfile: state.userProfile),
const HSpace(4),
const NotificationButton(),
],
),

View File

@ -224,7 +224,7 @@ class _SidebarState extends State<_Sidebar> {
// user or workspace, setting
Container(
height: HomeSizes.workspaceSectionHeight,
padding: menuHorizontalInset,
padding: menuHorizontalInset - const EdgeInsets.only(right: 6),
child:
// if the workspaces are empty, show the user profile instead
userState.isCollabWorkspaceOn && userState.workspaces.isNotEmpty

View File

@ -44,7 +44,7 @@ class _WorkspaceIconState extends State<WorkspaceIcon> {
: Container(
alignment: Alignment.center,
width: widget.iconSize,
height: max(widget.iconSize, 26),
height: min(widget.iconSize, 26),
decoration: BoxDecoration(
color: ColorGenerator(widget.workspace.name).toColor(),
borderRadius: BorderRadius.circular(4),

View File

@ -128,7 +128,7 @@ class _WorkspaceMenuItemState extends State<WorkspaceMenuItem> {
// cause the popover dismiss intermediately when click the right icon.
// so using the stack to put the right icon on the flowy button.
return SizedBox(
height: 40,
height: 44,
child: MouseRegion(
onEnter: (_) => isHovered.value = true,
onExit: (_) => isHovered.value = false,
@ -250,7 +250,6 @@ class _WorkspaceInfo extends StatelessWidget {
overflow: TextOverflow.ellipsis,
withTooltip: true,
),
const VSpace(2.0),
// workspace members count
FlowyText.regular(
state.isLoading

View File

@ -49,9 +49,7 @@ class _SidebarWorkspaceState extends State<SidebarWorkspace> {
),
),
UserSettingButton(userProfile: widget.userProfile),
const HSpace(8),
const NotificationButton(),
const HSpace(4),
],
);
},
@ -201,12 +199,12 @@ class _SidebarSwitchWorkspaceButtonState
},
child: FlowyButton(
margin: EdgeInsets.zero,
text: Row(
children: [
const HSpace(6.0),
SizedBox(
width: 16.0,
child: WorkspaceIcon(
text: SizedBox(
height: 30,
child: Row(
children: [
const HSpace(6.0),
WorkspaceIcon(
workspace: widget.currentWorkspace,
iconSize: 16,
fontSize: 10,
@ -218,25 +216,25 @@ class _SidebarSwitchWorkspaceButtonState
),
),
),
),
const HSpace(10),
Flexible(
child: FlowyText.medium(
widget.currentWorkspace.name,
overflow: TextOverflow.ellipsis,
withTooltip: true,
const HSpace(10),
Flexible(
child: FlowyText.medium(
widget.currentWorkspace.name,
overflow: TextOverflow.ellipsis,
withTooltip: true,
),
),
),
const HSpace(4),
ValueListenableBuilder(
valueListenable: _isWorkSpaceMenuExpanded,
builder: (context, value, _) => FlowySvg(
value
? FlowySvgs.workspace_drop_down_menu_hide_s
: FlowySvgs.workspace_drop_down_menu_show_s,
const HSpace(4),
ValueListenableBuilder(
valueListenable: _isWorkSpaceMenuExpanded,
builder: (context, value, _) => FlowySvg(
value
? FlowySvgs.workspace_drop_down_menu_hide_s
: FlowySvgs.workspace_drop_down_menu_show_s,
),
),
),
],
],
),
),
),
);

View File

@ -422,6 +422,10 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
// icon
_buildViewIconButton(),
const HSpace(6),
// const SizedBox(
// width: 6.0,
// height: 1,
// ),
// title
Expanded(
child: FlowyText.regular(

View File

@ -1,17 +1,17 @@
import 'dart:io';
import 'package:appflowy_editor/appflowy_editor.dart';
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/home/home_setting_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
@ -65,23 +65,39 @@ class FlowyNavigation extends StatelessWidget {
buildWhen: (p, c) => p.isMenuCollapsed != c.isMenuCollapsed,
builder: (context, state) {
if (!PlatformExtension.isWindows && state.isMenuCollapsed) {
return RotationTransition(
turns: const AlwaysStoppedAnimation(180 / 360),
child: FlowyTooltip(
richMessage: sidebarTooltipTextSpan(
context,
LocaleKeys.sideBar_openSidebar.tr(),
final color =
Theme.of(context).isLightMode ? Colors.white : Colors.black;
final textSpan = TextSpan(
children: [
TextSpan(
text: '${LocaleKeys.sideBar_openSidebar.tr()}\n',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: color),
),
child: FlowyIconButton(
width: 24,
hoverColor: Colors.transparent,
onPressed: () => context
.read<HomeSettingBloc>()
.add(const HomeSettingEvent.collapseMenu()),
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
icon: FlowySvg(
FlowySvgs.hide_menu_m,
color: Theme.of(context).iconTheme.color,
TextSpan(
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Theme.of(context).hintColor),
),
],
);
return Padding(
padding: const EdgeInsets.only(right: 8.0),
child: RotationTransition(
turns: const AlwaysStoppedAnimation(180 / 360),
child: FlowyTooltip(
richMessage: textSpan,
child: FlowyIconButton(
width: 24,
onPressed: () => context
.read<HomeSettingBloc>()
.add(const HomeSettingEvent.collapseMenu()),
iconPadding: const EdgeInsets.all(2),
icon: const FlowySvg(FlowySvgs.hide_menu_s),
),
),
),

View File

@ -3,6 +3,7 @@ import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/reminder/reminder_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/notifications/notification_dialog.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
@ -27,17 +28,19 @@ class NotificationButton extends StatelessWidget {
child: BlocBuilder<ReminderBloc, ReminderState>(
builder: (context, state) => FlowyTooltip(
message: LocaleKeys.notificationHub_title.tr(),
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: AppFlowyPopover(
mutex: mutex,
direction: PopoverDirection.bottomWithLeftAligned,
constraints: const BoxConstraints(maxHeight: 500, maxWidth: 425),
windowPadding: EdgeInsets.zero,
margin: EdgeInsets.zero,
popupBuilder: (_) =>
NotificationDialog(views: views, mutex: mutex),
child: _buildNotificationIcon(context, state.hasUnreads),
child: AppFlowyPopover(
mutex: mutex,
direction: PopoverDirection.bottomWithLeftAligned,
constraints: const BoxConstraints(maxHeight: 500, maxWidth: 425),
windowPadding: EdgeInsets.zero,
margin: EdgeInsets.zero,
popupBuilder: (_) => NotificationDialog(views: views, mutex: mutex),
child: SizedBox.square(
dimension: HomeSizes.workspaceSectionHeight,
child: FlowyButton(
useIntrinsicWidth: true,
text: _buildNotificationIcon(context, state.hasUnreads),
),
),
),
),

View File

@ -167,6 +167,7 @@ class _ViewTitleState extends State<_ViewTitle> {
onPointerDown: (_) => context.read<TabsBloc>().openPlugin(widget.view),
child: FlowyButton(
useIntrinsicWidth: true,
margin: const EdgeInsets.symmetric(horizontal: 6.0),
onTap: () {},
text: _buildIconAndName(state),
),

View File

@ -2,6 +2,8 @@ import 'dart:io';
import 'package:flutter/material.dart';
const String _emojiFontFamily = 'noto color emoji';
class FlowyText extends StatelessWidget {
final String text;
final TextOverflow? overflow;
@ -119,13 +121,19 @@ class FlowyText extends StatelessWidget {
this.withTooltip = false,
this.strutStyle = const StrutStyle(forceStrutHeight: true),
}) : fontWeight = FontWeight.w400,
fontFamily = 'noto color emoji',
fontFamily = _emojiFontFamily,
fallbackFontFamily = null;
@override
Widget build(BuildContext context) {
Widget child;
double fontSize =
this.fontSize ?? Theme.of(context).textTheme.bodyMedium!.fontSize!;
if (Platform.isLinux && fontFamily == _emojiFontFamily) {
fontSize = fontSize * 0.8;
}
final textStyle = Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: fontSize,
fontWeight: fontWeight,

View File

@ -22,8 +22,13 @@ class FlowyTooltip extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isLightMode = Theme.of(context).brightness == Brightness.light;
return Tooltip(
margin: margin,
decoration: BoxDecoration(
color: isLightMode ? const Color(0xE5171717) : const Color(0xE5E5E5E5),
borderRadius: BorderRadius.circular(8.0),
),
waitDuration: _tooltipWaitDuration,
message: message,
richMessage: richMessage,

View File

@ -1,6 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 5L13 8L10 11" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
<rect x="3" y="5" width="4" height="1" rx="0.5" fill="#333333"/>
<rect x="3" y="7.5" width="6" height="1" rx="0.5" fill="#333333"/>
<rect x="3" y="10" width="4" height="1" rx="0.5" fill="#333333"/>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.75 14.25L15 9L9.75 3.75" stroke="#171717" stroke-width="1.2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.5625 14.25L8.8125 9L3.5625 3.75" stroke="#171717" stroke-width="1.2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 401 B