mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-09-02 05:14:05 +00:00
feat: update workspace icon style on desktop (#6452)
* feat: update workspace icon style on desktop * fix: unable to insert two referenced link at the same doc
This commit is contained in:
parent
cb2b933a90
commit
5de716b19d
@ -60,6 +60,57 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('insert multiple referenced boards', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
await tester.tapAnonymousSignInButton();
|
||||||
|
|
||||||
|
// create a new grid
|
||||||
|
final id = uuid();
|
||||||
|
final name = '${ViewLayoutPB.Board.name}_$id';
|
||||||
|
await tester.createNewPageWithNameUnderParent(
|
||||||
|
name: name,
|
||||||
|
layout: ViewLayoutPB.Board,
|
||||||
|
openAfterCreated: false,
|
||||||
|
);
|
||||||
|
// create a new document
|
||||||
|
await tester.createNewPageWithNameUnderParent(
|
||||||
|
name: 'insert_a_reference_${ViewLayoutPB.Board.name}',
|
||||||
|
);
|
||||||
|
// tap the first line of the document
|
||||||
|
await tester.editor.tapLineOfEditorAt(0);
|
||||||
|
// insert a referenced view
|
||||||
|
await tester.editor.showSlashMenu();
|
||||||
|
await tester.editor.tapSlashMenuItemWithName(
|
||||||
|
ViewLayoutPB.Board.slashMenuLinkedName,
|
||||||
|
);
|
||||||
|
final referencedDatabase1 = find.descendant(
|
||||||
|
of: find.byType(InlineActionsHandler),
|
||||||
|
matching: find.findTextInFlowyText(name),
|
||||||
|
);
|
||||||
|
expect(referencedDatabase1, findsOneWidget);
|
||||||
|
await tester.tapButton(referencedDatabase1);
|
||||||
|
|
||||||
|
await tester.editor.tapLineOfEditorAt(1);
|
||||||
|
await tester.editor.showSlashMenu();
|
||||||
|
await tester.editor.tapSlashMenuItemWithName(
|
||||||
|
ViewLayoutPB.Board.slashMenuLinkedName,
|
||||||
|
);
|
||||||
|
final referencedDatabase2 = find.descendant(
|
||||||
|
of: find.byType(InlineActionsHandler),
|
||||||
|
matching: find.findTextInFlowyText(name),
|
||||||
|
);
|
||||||
|
expect(referencedDatabase2, findsOneWidget);
|
||||||
|
await tester.tapButton(referencedDatabase2);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byType(AppFlowyEditor),
|
||||||
|
matching: find.byType(DesktopBoardPage),
|
||||||
|
),
|
||||||
|
findsNWidgets(2),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('insert a referenced calendar', (tester) async {
|
testWidgets('insert a referenced calendar', (tester) async {
|
||||||
await tester.initializeAppFlowy();
|
await tester.initializeAppFlowy();
|
||||||
await tester.tapAnonymousSignInButton();
|
await tester.tapAnonymousSignInButton();
|
||||||
|
@ -121,7 +121,7 @@ class _MobileWorkspace extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
WorkspaceIconV2(
|
WorkspaceIcon(
|
||||||
workspace: currentWorkspace,
|
workspace: currentWorkspace,
|
||||||
iconSize: 36,
|
iconSize: 36,
|
||||||
fontSize: 18.0,
|
fontSize: 18.0,
|
||||||
|
@ -272,7 +272,7 @@ class _WorkspaceMenuItemIcon extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
child: WorkspaceIconV2(
|
child: WorkspaceIcon(
|
||||||
enableEdit: false,
|
enableEdit: false,
|
||||||
iconSize: 36,
|
iconSize: 36,
|
||||||
emojiSize: 24.0,
|
emojiSize: 24.0,
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/inline_actions/handlers/inline_page_reference.dart';
|
import 'package:appflowy/plugins/inline_actions/handlers/inline_page_reference.dart';
|
||||||
import 'package:appflowy/plugins/inline_actions/inline_actions_menu.dart';
|
import 'package:appflowy/plugins/inline_actions/inline_actions_menu.dart';
|
||||||
@ -8,6 +6,7 @@ import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
InlineActionsMenuService? _actionsMenuService;
|
InlineActionsMenuService? _actionsMenuService;
|
||||||
Future<void> showLinkToPageMenu(
|
Future<void> showLinkToPageMenu(
|
||||||
@ -15,6 +14,8 @@ Future<void> showLinkToPageMenu(
|
|||||||
SelectionMenuService menuService,
|
SelectionMenuService menuService,
|
||||||
ViewLayoutPB pageType,
|
ViewLayoutPB pageType,
|
||||||
) async {
|
) async {
|
||||||
|
keepEditorFocusNotifier.increase();
|
||||||
|
|
||||||
menuService.dismiss();
|
menuService.dismiss();
|
||||||
_actionsMenuService?.dismiss();
|
_actionsMenuService?.dismiss();
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ Future<void> showLinkToPageMenu(
|
|||||||
context: rootContext,
|
context: rootContext,
|
||||||
handlers: [
|
handlers: [
|
||||||
InlinePageReferenceService(
|
InlinePageReferenceService(
|
||||||
currentViewId: "",
|
currentViewId: '',
|
||||||
viewLayout: pageType,
|
viewLayout: pageType,
|
||||||
customTitle: titleFromPageType(pageType),
|
customTitle: titleFromPageType(pageType),
|
||||||
insertPage: pageType != ViewLayoutPB.Document,
|
insertPage: pageType != ViewLayoutPB.Document,
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/plugins/inline_actions/inline_actions_result.dart';
|
import 'package:appflowy/plugins/inline_actions/inline_actions_result.dart';
|
||||||
import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart';
|
import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart';
|
||||||
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
|
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
abstract class InlineActionsMenuService {
|
abstract class InlineActionsMenuService {
|
||||||
InlineActionsMenuStyle get style;
|
InlineActionsMenuStyle get style;
|
||||||
@ -40,6 +39,7 @@ class InlineActionsMenu extends InlineActionsMenuService {
|
|||||||
if (_menuEntry != null) {
|
if (_menuEntry != null) {
|
||||||
editorState.service.keyboardService?.enable();
|
editorState.service.keyboardService?.enable();
|
||||||
editorState.service.scrollService?.enable();
|
editorState.service.scrollService?.enable();
|
||||||
|
keepEditorFocusNotifier.decrease();
|
||||||
}
|
}
|
||||||
|
|
||||||
_menuEntry?.remove();
|
_menuEntry?.remove();
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
|
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
|
||||||
import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
|
import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
|
||||||
@ -24,96 +22,6 @@ class WorkspaceIcon extends StatefulWidget {
|
|||||||
this.emojiSize,
|
this.emojiSize,
|
||||||
this.alignment,
|
this.alignment,
|
||||||
required this.figmaLineHeight,
|
required this.figmaLineHeight,
|
||||||
});
|
|
||||||
|
|
||||||
final UserWorkspacePB workspace;
|
|
||||||
final double iconSize;
|
|
||||||
final bool enableEdit;
|
|
||||||
final double fontSize;
|
|
||||||
final double? emojiSize;
|
|
||||||
final void Function(EmojiPickerResult) onSelected;
|
|
||||||
final double borderRadius;
|
|
||||||
final Alignment? alignment;
|
|
||||||
final double figmaLineHeight;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<WorkspaceIcon> createState() => _WorkspaceIconState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _WorkspaceIconState extends State<WorkspaceIcon> {
|
|
||||||
final controller = PopoverController();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Widget child = widget.workspace.icon.isNotEmpty
|
|
||||||
? Container(
|
|
||||||
width: widget.iconSize,
|
|
||||||
alignment: widget.alignment ?? Alignment.center,
|
|
||||||
child: FlowyText.emoji(
|
|
||||||
widget.workspace.icon,
|
|
||||||
fontSize: widget.emojiSize ?? widget.iconSize,
|
|
||||||
figmaLineHeight: widget.figmaLineHeight,
|
|
||||||
optimizeEmojiAlign: true,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Container(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
width: widget.iconSize,
|
|
||||||
height: min(widget.iconSize, 24),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: ColorGenerator(widget.workspace.name).toColor(),
|
|
||||||
borderRadius: BorderRadius.circular(widget.borderRadius),
|
|
||||||
border: Border.all(
|
|
||||||
color: const Color(0xa1717171),
|
|
||||||
width: 0.5,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: FlowyText.semibold(
|
|
||||||
widget.workspace.name.isEmpty
|
|
||||||
? ''
|
|
||||||
: widget.workspace.name.substring(0, 1),
|
|
||||||
fontSize: widget.fontSize,
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (widget.enableEdit) {
|
|
||||||
child = AppFlowyPopover(
|
|
||||||
offset: const Offset(0, 8),
|
|
||||||
controller: controller,
|
|
||||||
direction: PopoverDirection.bottomWithLeftAligned,
|
|
||||||
constraints: BoxConstraints.loose(const Size(364, 356)),
|
|
||||||
clickHandler: PopoverClickHandler.gestureDetector,
|
|
||||||
margin: const EdgeInsets.all(0),
|
|
||||||
popupBuilder: (_) => FlowyIconEmojiPicker(
|
|
||||||
onSelectedEmoji: (result) {
|
|
||||||
widget.onSelected(result);
|
|
||||||
controller.close();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
child: MouseRegion(
|
|
||||||
cursor: SystemMouseCursors.click,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The v2 supports the built-in color set
|
|
||||||
class WorkspaceIconV2 extends StatefulWidget {
|
|
||||||
const WorkspaceIconV2({
|
|
||||||
super.key,
|
|
||||||
required this.workspace,
|
|
||||||
required this.enableEdit,
|
|
||||||
required this.iconSize,
|
|
||||||
required this.fontSize,
|
|
||||||
required this.onSelected,
|
|
||||||
this.borderRadius = 4,
|
|
||||||
this.emojiSize,
|
|
||||||
this.alignment,
|
|
||||||
required this.figmaLineHeight,
|
|
||||||
this.showBorder = true,
|
this.showBorder = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -129,10 +37,10 @@ class WorkspaceIconV2 extends StatefulWidget {
|
|||||||
final bool showBorder;
|
final bool showBorder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<WorkspaceIconV2> createState() => _WorkspaceIconV2State();
|
State<WorkspaceIcon> createState() => _WorkspaceIconState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WorkspaceIconV2State extends State<WorkspaceIconV2> {
|
class _WorkspaceIconState extends State<WorkspaceIcon> {
|
||||||
final controller = PopoverController();
|
final controller = PopoverController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -178,7 +86,7 @@ class _WorkspaceIconV2State extends State<WorkspaceIconV2> {
|
|||||||
|
|
||||||
Widget _buildEditableIcon(Widget child) {
|
Widget _buildEditableIcon(Widget child) {
|
||||||
if (UniversalPlatform.isDesktopOrWeb) {
|
if (UniversalPlatform.isDesktopOrWeb) {
|
||||||
AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
offset: const Offset(0, 8),
|
offset: const Offset(0, 8),
|
||||||
controller: controller,
|
controller: controller,
|
||||||
direction: PopoverDirection.bottomWithLeftAligned,
|
direction: PopoverDirection.bottomWithLeftAligned,
|
||||||
|
@ -153,31 +153,22 @@ class _WorkspaceMenuItemState extends State<WorkspaceMenuItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildLeftIcon(BuildContext context) {
|
Widget _buildLeftIcon(BuildContext context) {
|
||||||
return Container(
|
return FlowyTooltip(
|
||||||
width: 32.0,
|
message: LocaleKeys.document_plugins_cover_changeIcon.tr(),
|
||||||
height: 32.0,
|
child: WorkspaceIcon(
|
||||||
decoration: BoxDecoration(
|
workspace: widget.workspace,
|
||||||
borderRadius: BorderRadius.circular(8),
|
iconSize: 36,
|
||||||
border: Border.all(
|
emojiSize: 24.0,
|
||||||
color: const Color(0x01717171).withOpacity(0.12),
|
fontSize: 18.0,
|
||||||
width: 0.8,
|
figmaLineHeight: 26.0,
|
||||||
),
|
borderRadius: 12.0,
|
||||||
),
|
enableEdit: true,
|
||||||
child: FlowyTooltip(
|
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
||||||
message: LocaleKeys.document_plugins_cover_changeIcon.tr(),
|
UserWorkspaceEvent.updateWorkspaceIcon(
|
||||||
child: WorkspaceIcon(
|
widget.workspace.workspaceId,
|
||||||
workspace: widget.workspace,
|
result.emoji,
|
||||||
iconSize: 22,
|
|
||||||
fontSize: 16,
|
|
||||||
figmaLineHeight: 32.0,
|
|
||||||
enableEdit: true,
|
|
||||||
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
|
||||||
UserWorkspaceEvent.updateWorkspaceIcon(
|
|
||||||
widget.workspace.workspaceId,
|
|
||||||
result.emoji,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -321,8 +312,10 @@ class _CreateWorkspaceButton extends StatelessWidget {
|
|||||||
text: Row(
|
text: Row(
|
||||||
children: [
|
children: [
|
||||||
_buildLeftIcon(context),
|
_buildLeftIcon(context),
|
||||||
const HSpace(10.0),
|
const HSpace(8.0),
|
||||||
FlowyText.regular(LocaleKeys.workspace_create.tr()),
|
FlowyText.regular(
|
||||||
|
LocaleKeys.workspace_create.tr(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -331,11 +324,11 @@ class _CreateWorkspaceButton extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildLeftIcon(BuildContext context) {
|
Widget _buildLeftIcon(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
width: 32.0,
|
width: 36.0,
|
||||||
height: 32.0,
|
height: 36.0,
|
||||||
padding: const EdgeInsets.all(7.0),
|
padding: const EdgeInsets.all(7.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: const Color(0x01717171).withOpacity(0.12),
|
color: const Color(0x01717171).withOpacity(0.12),
|
||||||
width: 0.8,
|
width: 0.8,
|
||||||
|
@ -273,12 +273,13 @@ class _SideBarSwitchWorkspaceButtonChild extends StatelessWidget {
|
|||||||
const HSpace(4.0),
|
const HSpace(4.0),
|
||||||
WorkspaceIcon(
|
WorkspaceIcon(
|
||||||
workspace: currentWorkspace,
|
workspace: currentWorkspace,
|
||||||
iconSize: 24,
|
iconSize: 26,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
emojiSize: 18,
|
emojiSize: 20,
|
||||||
enableEdit: false,
|
enableEdit: false,
|
||||||
borderRadius: 8.0,
|
borderRadius: 8.0,
|
||||||
figmaLineHeight: 21.0,
|
figmaLineHeight: 18.0,
|
||||||
|
showBorder: false,
|
||||||
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
||||||
UserWorkspaceEvent.updateWorkspaceIcon(
|
UserWorkspaceEvent.updateWorkspaceIcon(
|
||||||
currentWorkspace.workspaceId,
|
currentWorkspace.workspaceId,
|
||||||
@ -286,7 +287,7 @@ class _SideBarSwitchWorkspaceButtonChild extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const HSpace(8),
|
const HSpace(6),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: FlowyText.medium(
|
child: FlowyText.medium(
|
||||||
currentWorkspace.name,
|
currentWorkspace.name,
|
||||||
|
@ -345,20 +345,18 @@ class _WorkspaceIconSetting extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
return SizedBox(
|
||||||
height: 64,
|
height: 64,
|
||||||
width: 64,
|
width: 64,
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border.all(color: Theme.of(context).colorScheme.outline),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(1),
|
padding: const EdgeInsets.all(1),
|
||||||
child: WorkspaceIcon(
|
child: WorkspaceIcon(
|
||||||
workspace: workspace!,
|
workspace: workspace!,
|
||||||
iconSize: workspace!.icon.isNotEmpty == true ? 46 : 20,
|
iconSize: 36,
|
||||||
fontSize: 16.0,
|
emojiSize: 24.0,
|
||||||
figmaLineHeight: 46,
|
fontSize: 24.0,
|
||||||
|
figmaLineHeight: 26.0,
|
||||||
|
borderRadius: 18.0,
|
||||||
enableEdit: true,
|
enableEdit: true,
|
||||||
onSelected: (r) => context
|
onSelected: (r) => context
|
||||||
.read<WorkspaceSettingsBloc>()
|
.read<WorkspaceSettingsBloc>()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user