mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-10-11 08:03:17 +00:00
fix: backtick issue in French IME (#6408)
* fix: backtick doesn't format the text to code in french ime * test: add backtick test * fix: three backticks doesn't convert to code block in french ime * chore: remove cache for docker ci
This commit is contained in:
parent
1ffd653515
commit
1b0bb1d5ff
27
.github/workflows/docker_ci.yml
vendored
27
.github/workflows/docker_ci.yml
vendored
@ -23,13 +23,14 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
# cache the docker layers
|
# cache the docker layers
|
||||||
- name: Cache Docker layers
|
# don't cache anything temporarly, because it always triggers "no space left on device" error
|
||||||
uses: actions/cache@v3
|
# - name: Cache Docker layers
|
||||||
with:
|
# uses: actions/cache@v3
|
||||||
path: /tmp/.buildx-cache
|
# with:
|
||||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
# path: /tmp/.buildx-cache
|
||||||
restore-keys: |
|
# key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
${{ runner.os }}-buildx-
|
# restore-keys: |
|
||||||
|
# ${{ runner.os }}-buildx-
|
||||||
|
|
||||||
- name: Build the app
|
- name: Build the app
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
@ -37,10 +38,10 @@ jobs:
|
|||||||
context: .
|
context: .
|
||||||
file: ./frontend/scripts/docker-buildfiles/Dockerfile
|
file: ./frontend/scripts/docker-buildfiles/Dockerfile
|
||||||
push: false
|
push: false
|
||||||
cache-from: type=local,src=/tmp/.buildx-cache
|
# cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
# cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
|
|
||||||
- name: Move cache
|
# - name: Move cache
|
||||||
run: |
|
# run: |
|
||||||
rm -rf /tmp/.buildx-cache
|
# rm -rf /tmp/.buildx-cache
|
||||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
# mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
|
import '../../shared/util.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
group('customer:', () {
|
||||||
|
testWidgets('backtick issue - inline code', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
await tester.tapAnonymousSignInButton();
|
||||||
|
|
||||||
|
const pageName = 'backtick issue';
|
||||||
|
await tester.createNewPageWithNameUnderParent(name: pageName);
|
||||||
|
|
||||||
|
// focus on the editor
|
||||||
|
await tester.tap(find.byType(AppFlowyEditor));
|
||||||
|
// input backtick
|
||||||
|
const text = '`Hello` AppFlowy';
|
||||||
|
|
||||||
|
for (var i = 0; i < text.length; i++) {
|
||||||
|
await tester.ime.insertCharacter(text[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
final node = tester.editor.getNodeAtPath([0]);
|
||||||
|
expect(
|
||||||
|
node.delta?.toJson(),
|
||||||
|
equals([
|
||||||
|
{
|
||||||
|
"insert": "Hello",
|
||||||
|
"attributes": {"code": true},
|
||||||
|
},
|
||||||
|
{"insert": " AppFlowy"},
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('backtick issue - inline code', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
await tester.tapAnonymousSignInButton();
|
||||||
|
|
||||||
|
const pageName = 'backtick issue';
|
||||||
|
await tester.createNewPageWithNameUnderParent(name: pageName);
|
||||||
|
|
||||||
|
// focus on the editor
|
||||||
|
await tester.tap(find.byType(AppFlowyEditor));
|
||||||
|
// input backtick
|
||||||
|
const text = '```';
|
||||||
|
|
||||||
|
for (var i = 0; i < text.length; i++) {
|
||||||
|
await tester.ime.insertCharacter(text[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
final node = tester.editor.getNodeAtPath([0]);
|
||||||
|
expect(node.type, equals(CodeBlockKeys.type));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -270,9 +270,9 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
editorState.logConfiguration
|
editorState.logConfiguration
|
||||||
..level = AppFlowyEditorLogLevel.all
|
..level = AppFlowyEditorLogLevel.all
|
||||||
..handler = (log) {
|
..handler = (log) {
|
||||||
// if (enableDocumentInternalLog) {
|
if (enableDocumentInternalLog) {
|
||||||
Log.info(log);
|
Log.info(log);
|
||||||
// }
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +213,8 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
|
|
||||||
late final ViewInfoBloc viewInfoBloc = context.read<ViewInfoBloc>();
|
late final ViewInfoBloc viewInfoBloc = context.read<ViewInfoBloc>();
|
||||||
|
|
||||||
|
final editorKeyboardInterceptor = EditorKeyboardInterceptor();
|
||||||
|
|
||||||
Future<bool> showSlashMenu(editorState) async => customSlashCommand(
|
Future<bool> showSlashMenu(editorState) async => customSlashCommand(
|
||||||
slashMenuItems,
|
slashMenuItems,
|
||||||
shouldInsertSlash: false,
|
shouldInsertSlash: false,
|
||||||
@ -278,6 +280,10 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
if (widget.initialSelection != null) {
|
if (widget.initialSelection != null) {
|
||||||
widget.editorState.updateSelectionWithReason(widget.initialSelection);
|
widget.editorState.updateSelectionWithReason(widget.initialSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
widget.editorState.service.keyboardService?.registerInterceptor(
|
||||||
|
editorKeyboardInterceptor,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +308,9 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
widget.editorState.service.keyboardService?.unregisterInterceptor(
|
||||||
|
editorKeyboardInterceptor,
|
||||||
|
);
|
||||||
focusManager?.loseFocusNotifier.removeListener(_loseFocus);
|
focusManager?.loseFocusNotifier.removeListener(_loseFocus);
|
||||||
|
|
||||||
if (widget.useViewInfoBloc && !viewInfoBloc.isClosed) {
|
if (widget.useViewInfoBloc && !viewInfoBloc.isClosed) {
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class EditorKeyboardInterceptor extends AppFlowyKeyboardServiceInterceptor {
|
||||||
|
@override
|
||||||
|
Future<bool> interceptNonTextUpdate(
|
||||||
|
TextEditingDeltaNonTextUpdate nonTextUpdate,
|
||||||
|
EditorState editorState,
|
||||||
|
List<CharacterShortcutEvent> characterShortcutEvents,
|
||||||
|
) async {
|
||||||
|
return _checkIfBacktickPressed(
|
||||||
|
editorState,
|
||||||
|
nonTextUpdate,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the backtick pressed event should be handled
|
||||||
|
Future<bool> _checkIfBacktickPressed(
|
||||||
|
EditorState editorState,
|
||||||
|
TextEditingDeltaNonTextUpdate nonTextUpdate,
|
||||||
|
) async {
|
||||||
|
// if the composing range is not empty, it means the user is typing a text,
|
||||||
|
// so we don't need to handle the backtick pressed event
|
||||||
|
if (!nonTextUpdate.composing.isCollapsed ||
|
||||||
|
!nonTextUpdate.selection.isCollapsed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final selection = editorState.selection;
|
||||||
|
if (selection == null || !selection.isCollapsed) {
|
||||||
|
AppFlowyEditorLog.input.debug('selection is null or not collapsed');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final node = editorState.getNodesInSelection(selection).firstOrNull;
|
||||||
|
if (node == null) {
|
||||||
|
AppFlowyEditorLog.input.debug('node is null');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get last character of the node
|
||||||
|
final plainText = node.delta?.toPlainText();
|
||||||
|
// three backticks to code block
|
||||||
|
if (plainText != '```') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final transaction = editorState.transaction;
|
||||||
|
transaction.insertNode(
|
||||||
|
selection.end.path,
|
||||||
|
codeBlockNode(),
|
||||||
|
);
|
||||||
|
transaction.deleteNode(node);
|
||||||
|
transaction.afterSelection = Selection.collapsed(
|
||||||
|
Position(path: selection.start.path),
|
||||||
|
);
|
||||||
|
await editorState.apply(transaction);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ export 'image/mobile_image_toolbar_item.dart';
|
|||||||
export 'image/multi_image_block_component/multi_image_menu.dart';
|
export 'image/multi_image_block_component/multi_image_menu.dart';
|
||||||
export 'inline_math_equation/inline_math_equation.dart';
|
export 'inline_math_equation/inline_math_equation.dart';
|
||||||
export 'inline_math_equation/inline_math_equation_toolbar_item.dart';
|
export 'inline_math_equation/inline_math_equation_toolbar_item.dart';
|
||||||
|
export 'keyboard_interceptor/keyboard_interceptor.dart';
|
||||||
export 'link_preview/custom_link_preview.dart';
|
export 'link_preview/custom_link_preview.dart';
|
||||||
export 'link_preview/link_preview_cache.dart';
|
export 'link_preview/link_preview_cache.dart';
|
||||||
export 'link_preview/link_preview_menu.dart';
|
export 'link_preview/link_preview_menu.dart';
|
||||||
|
@ -53,8 +53,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "737681d"
|
ref: "6da7b4e"
|
||||||
resolved-ref: "737681dd97b501dd88c7c016c5c359f9ffff7d31"
|
resolved-ref: "6da7b4e5dc76dd6b9d4361c744359b04ddb5b983"
|
||||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||||
source: git
|
source: git
|
||||||
version: "3.3.0"
|
version: "3.3.0"
|
||||||
|
@ -177,7 +177,7 @@ dependency_overrides:
|
|||||||
appflowy_editor:
|
appflowy_editor:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||||
ref: "737681d"
|
ref: "6da7b4e"
|
||||||
|
|
||||||
appflowy_editor_plugins:
|
appflowy_editor_plugins:
|
||||||
git:
|
git:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user