Skip to content

Commit

Permalink
fix: rect of the divider block is incorrect (#415)
Browse files Browse the repository at this point in the history
* fix: rect of the divider block is incorrect

* fix: only show the context menu when the gesture hit the selection area

* chore: change image upload widget UI

* fix: context menu test
  • Loading branch information
LucasXu0 authored Aug 25, 2023
1 parent 81186fa commit a9af2bb
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class _DividerBlockComponentWidgetState

@override
Rect getBlockRect() {
return getCursorRectInPosition(Position.invalid()) ?? Rect.zero;
return getRectsInSelection(Selection.invalid()).first;
}

@override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'dart:io';

import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:file_picker/file_picker.dart' as fp;
import 'package:flutter/material.dart';

import '../../util/file_picker/file_picker_impl.dart';
import 'package:file_picker/file_picker.dart' as fp;

enum ImageFromFileStatus {
notSelected,
Expand Down Expand Up @@ -47,7 +48,7 @@ void showImageMenu(
builder: (context) => UploadImageMenu(
backgroundColor: menuService.style.selectionMenuBackgroundColor,
headerColor: menuService.style.selectionMenuItemTextColor,
width: MediaQuery.of(context).size.width * 0.4,
width: MediaQuery.of(context).size.width * 0.3,
onSubmitted: insertImage,
onUpload: insertImage,
),
Expand Down Expand Up @@ -103,8 +104,8 @@ class _UploadImageMenuState extends State<UploadImageMenu> {
Widget build(BuildContext context) {
return Container(
width: widget.width,
height: 300,
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 10.0),
height: 240,
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 5.0),
decoration: BoxDecoration(
color: widget.backgroundColor,
boxShadow: [
Expand All @@ -123,7 +124,8 @@ class _UploadImageMenuState extends State<UploadImageMenu> {
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: 300,
width: 260,
height: 36,
child: TabBar(
tabs: const [
Tab(text: 'Upload Image'),
Expand Down Expand Up @@ -207,7 +209,7 @@ class _UploadImageMenuState extends State<UploadImageMenu> {
) {
return SizedBox(
width: 170,
height: 48,
height: 36,
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(const Color(0xFF00BCF0)),
Expand Down Expand Up @@ -296,7 +298,7 @@ class _UploadImageMenuState extends State<UploadImageMenu> {
}
},
child: Container(
height: 80,
height: 60,
margin: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
border: Border.all(color: const Color(0xff00BCF0)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,25 @@ class _DesktopSelectionServiceWidgetState
void _showContextMenu(TapDownDetails details) {
_clearContextMenu();

// only shows around the selection area.
if (selectionRects.isEmpty) {
return;
}

final isHitSelectionAreas = currentSelection.value?.isCollapsed == true ||
selectionRects.any((element) {
const threshold = 20;
final scaledArea = Rect.fromCenter(
center: element.center,
width: element.width + threshold,
height: element.height + threshold,
);
return scaledArea.contains(details.globalPosition);
});
if (!isHitSelectionAreas) {
return;
}

// For now, only support the text node.
if (!currentSelectedNodes.every((element) => element.delta != null)) {
return;
Expand Down
48 changes: 29 additions & 19 deletions test/service/context_menu_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:appflowy_editor/appflowy_editor.dart';

import '../infra/clipboard_test.dart';
import '../new/infra/testable_editor.dart';
Expand All @@ -26,9 +26,10 @@ void main() async {
});
});
group('context menu test', () {
void rightClick() {
void rightClickAt(Offset position) {
GestureBinding.instance.handlePointerEvent(
const PointerDownEvent(
PointerDownEvent(
position: position,
buttons: kSecondaryMouseButton,
),
);
Expand All @@ -39,22 +40,26 @@ void main() async {
}

testWidgets('context menu test', (tester) async {
final editor = tester.editor
..addParagraph(initialText: 'Welcome to AppFlowy');
const text = 'Welcome to AppFlowy';
final editor = tester.editor..addParagraph(initialText: text);
await editor.startTesting();
expect(find.byType(ContextMenu), findsNothing);
rightClick();
await editor.updateSelection(
Selection.single(path: [0], startOffset: 0, endOffset: text.length),
);
final position = tester.getCenter(find.text(text, findRichText: true));
rightClickAt(position);
await tester.pump();
expect(find.byType(ContextMenu), findsOneWidget);
await editor.dispose();
});

testWidgets('context menu cut test ', (tester) async {
final editor = tester.editor
..addParagraph(initialText: 'Welcome to AppFlowy');
const text = 'Welcome to AppFlowy';
final editor = tester.editor..addParagraph(initialText: text);
await editor.startTesting();
expect(
find.text('Welcome to AppFlowy', findRichText: true),
find.text(text, findRichText: true),
findsOneWidget,
);
await editor.updateSelection(
Expand All @@ -63,9 +68,10 @@ void main() async {
end: Position(path: [0], offset: 18),
),
);
final text =
final copiedText =
editor.editorState.getTextInSelection(editor.selection).join('/n');
rightClick();
final position = tester.getCenter(find.text(text, findRichText: true));
rightClickAt(position);
await tester.pump();
final cutButton = find.text('Cut');
expect(cutButton, findsOneWidget);
Expand All @@ -76,17 +82,18 @@ void main() async {
findsNothing,
);
final clipBoardData = await AppFlowyClipboard.getData();
expect(clipBoardData.text, text);
expect(clipBoardData.text, copiedText);
await editor.dispose();
});

testWidgets('context menu copy and paste test', (tester) async {
const text = 'Welcome to AppFlowy';
final editor = tester.editor
..addParagraph(initialText: 'Welcome to AppFlowy');
editor.addParagraph(initialText: 'Hello');
..addParagraph(initialText: text)
..addParagraph(initialText: 'Hello');
await editor.startTesting();
expect(
find.text('Welcome to AppFlowy', findRichText: true),
find.text(text, findRichText: true),
findsOneWidget,
);
await editor.updateSelection(
Expand All @@ -95,9 +102,10 @@ void main() async {
end: Position(path: [1], offset: 5),
),
);
final text =
final copiedText =
editor.editorState.getTextInSelection(editor.selection).join('/n');
rightClick();
final position = tester.getCenter(find.text('Hello', findRichText: true));
rightClickAt(position);
await tester.pump();
final copyButton = find.text('Copy');
expect(copyButton, findsOneWidget);
Expand All @@ -108,14 +116,16 @@ void main() async {
findsOneWidget,
);
final clipBoardData = await AppFlowyClipboard.getData();
expect(clipBoardData.text, text);
expect(clipBoardData.text, copiedText);
await editor.updateSelection(
Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: 7),
),
);
rightClick();
final newPosition =
tester.getTopLeft(find.text(text, findRichText: true));
rightClickAt(newPosition);
await tester.pump();
final pasteButton = find.text('Paste');
expect(pasteButton, findsOneWidget);
Expand Down

0 comments on commit a9af2bb

Please sign in to comment.