Skip to content

Commit c36ccc3

Browse files
committed
feat: [improvements] integrate logging library in AppFlowyEditor
1 parent a0753ce commit c36ccc3

File tree

16 files changed

+322
-39
lines changed

16 files changed

+322
-39
lines changed

frontend/app_flowy/packages/appflowy_editor/example/lib/main.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,13 @@ class _MyHomePageState extends State<MyHomePage> {
9797
builder: (context, snapshot) {
9898
if (snapshot.hasData) {
9999
final data = Map<String, Object>.from(json.decode(snapshot.data!));
100-
return _buildAppFlowyEditor(EditorState(
101-
document: StateTree.fromJson(data),
102-
));
100+
final editorState = EditorState(document: StateTree.fromJson(data));
101+
editorState.logConfiguration
102+
..level = LogLevel.all
103+
..handler = (message) {
104+
debugPrint(message);
105+
};
106+
return _buildAppFlowyEditor(editorState);
103107
} else {
104108
return const Center(
105109
child: CircularProgressIndicator(),

frontend/app_flowy/packages/appflowy_editor/lib/appflowy_editor.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/// AppFlowyEditor library
22
library appflowy_editor;
33

4+
export 'src/infra/log.dart';
45
export 'src/document/node.dart';
56
export 'src/document/path.dart';
67
export 'src/document/position.dart';

frontend/app_flowy/packages/appflowy_editor/lib/src/editor_state.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:async';
2+
import 'package:appflowy_editor/src/infra/log.dart';
23
import 'package:appflowy_editor/src/service/service.dart';
34
import 'package:flutter/material.dart';
45

@@ -48,10 +49,15 @@ class EditorState {
4849
// Service reference.
4950
final service = FlowyService();
5051

52+
/// Configures log output parameters,
53+
/// such as log level and log output callbacks,
54+
/// with this variable.
55+
LogConfiguration get logConfiguration => LogConfiguration();
56+
5157
final UndoManager undoManager = UndoManager();
5258
Selection? _cursorSelection;
5359

54-
/// TODO: only for testing.
60+
// TODO: only for testing.
5561
bool disableSealTimer = false;
5662

5763
Selection? get cursorSelection {
@@ -120,7 +126,7 @@ class EditorState {
120126
_debouncedSealHistoryItemTimer =
121127
Timer(const Duration(milliseconds: 1000), () {
122128
if (undoManager.undoStack.isNonEmpty) {
123-
debugPrint('Seal history item');
129+
Log.editor.debug('Seal history item');
124130
final last = undoManager.undoStack.last;
125131
last.seal();
126132
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import 'package:logging/logging.dart';
2+
3+
enum LogLevel {
4+
off,
5+
error,
6+
warn,
7+
info,
8+
debug,
9+
all,
10+
}
11+
12+
typedef LogHandler = void Function(String message);
13+
14+
class LogConfiguration {
15+
LogConfiguration._() {
16+
Logger.root.onRecord.listen((record) {
17+
if (handler != null) {
18+
handler!(
19+
'[${record.level.toLogLevel().name}][${record.loggerName}]: ${record.time}: ${record.message}');
20+
}
21+
});
22+
}
23+
24+
factory LogConfiguration() => _logConfiguration;
25+
26+
static final LogConfiguration _logConfiguration = LogConfiguration._();
27+
28+
LogHandler? handler;
29+
30+
LogLevel _level = LogLevel.off;
31+
32+
LogLevel get level => _level;
33+
set level(LogLevel level) {
34+
_level = level;
35+
Logger.root.level = level.toLevel();
36+
}
37+
}
38+
39+
class Log {
40+
Log._({
41+
required this.name,
42+
}) : _logger = Logger(name);
43+
44+
final String name;
45+
late final Logger _logger;
46+
47+
static Log editor = Log._(name: 'editor');
48+
static Log selection = Log._(name: 'selection');
49+
static Log keyboard = Log._(name: 'keyboard');
50+
static Log input = Log._(name: 'input');
51+
static Log scroll = Log._(name: 'scroll');
52+
static Log ui = Log._(name: 'ui');
53+
54+
void error(String message) => _logger.severe(message);
55+
void warn(String message) => _logger.warning(message);
56+
void info(String message) => _logger.info(message);
57+
void debug(String message) => _logger.fine(message);
58+
}
59+
60+
extension on LogLevel {
61+
Level toLevel() {
62+
switch (this) {
63+
case LogLevel.off:
64+
return Level.OFF;
65+
case LogLevel.error:
66+
return Level.SEVERE;
67+
case LogLevel.warn:
68+
return Level.WARNING;
69+
case LogLevel.info:
70+
return Level.INFO;
71+
case LogLevel.debug:
72+
return Level.FINE;
73+
case LogLevel.all:
74+
return Level.ALL;
75+
}
76+
}
77+
78+
String get name {
79+
switch (this) {
80+
case LogLevel.off:
81+
return 'OFF';
82+
case LogLevel.error:
83+
return 'ERROR';
84+
case LogLevel.warn:
85+
return 'WARN';
86+
case LogLevel.info:
87+
return 'INFO';
88+
case LogLevel.debug:
89+
return 'DEBUG';
90+
case LogLevel.all:
91+
return 'ALL';
92+
}
93+
}
94+
}
95+
96+
extension on Level {
97+
LogLevel toLogLevel() {
98+
if (this == Level.SEVERE) {
99+
return LogLevel.error;
100+
} else if (this == Level.WARNING) {
101+
return LogLevel.warn;
102+
} else if (this == Level.INFO) {
103+
return LogLevel.info;
104+
} else if (this == Level.FINE) {
105+
return LogLevel.debug;
106+
}
107+
return LogLevel.off;
108+
}
109+
}

frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/checkbox_text.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
8383
name: check ? 'check' : 'uncheck',
8484
),
8585
onTap: () {
86-
debugPrint('[Checkbox] onTap...');
8786
TransactionBuilder(widget.editorState)
8887
..updateNode(widget.textNode, {
8988
StyleKey.checkbox: !check,

frontend/app_flowy/packages/appflowy_editor/lib/src/service/input_service.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:appflowy_editor/src/infra/log.dart';
12
import 'package:flutter/material.dart';
23
import 'package:flutter/services.dart';
34

@@ -243,7 +244,8 @@ class _AppFlowyInputState extends State<AppFlowyInput>
243244

244245
@override
245246
void updateEditingValueWithDeltas(List<TextEditingDelta> textEditingDeltas) {
246-
debugPrint(textEditingDeltas.map((delta) => delta.toString()).toString());
247+
Log.input
248+
.debug(textEditingDeltas.map((delta) => delta.toString()).toString());
247249

248250
apply(textEditingDeltas);
249251
}

frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:appflowy_editor/appflowy_editor.dart';
22
import 'package:appflowy_editor/src/infra/html_converter.dart';
33
import 'package:appflowy_editor/src/document/node_iterator.dart';
4+
import 'package:appflowy_editor/src/infra/log.dart';
45
import 'package:flutter/material.dart';
56
import 'package:flutter/services.dart';
67
import 'package:rich_clipboard/rich_clipboard.dart';
@@ -19,10 +20,10 @@ _handleCopy(EditorState editorState) async {
1920
startOffset: selection.start.offset,
2021
endOffset: selection.end.offset)
2122
.toHTMLString();
22-
debugPrint('copy html: $htmlString');
23+
Log.keyboard.debug('copy html: $htmlString');
2324
RichClipboard.setData(RichClipboardData(html: htmlString));
2425
} else {
25-
debugPrint("unimplemented: copy non-text");
26+
Log.keyboard.debug('unimplemented: copy non-text');
2627
}
2728
return;
2829
}
@@ -37,7 +38,7 @@ _handleCopy(EditorState editorState) async {
3738
startOffset: selection.start.offset,
3839
endOffset: selection.end.offset)
3940
.toHTMLString();
40-
debugPrint('copy html: $copyString');
41+
Log.keyboard.debug('copy html: $copyString');
4142
RichClipboard.setData(RichClipboardData(html: copyString));
4243
}
4344

@@ -54,7 +55,7 @@ _pasteHTML(EditorState editorState, String html) {
5455
return;
5556
}
5657

57-
debugPrint('paste html: $html');
58+
Log.keyboard.debug('paste html: $html');
5859
final nodes = HTMLToNodesConverter(html).toNodes();
5960

6061
if (nodes.isEmpty) {
@@ -250,7 +251,6 @@ _handlePastePlainText(EditorState editorState, String plainText) {
250251
/// 1. copy the selected content
251252
/// 2. delete selected content
252253
_handleCut(EditorState editorState) {
253-
debugPrint('cut');
254254
_handleCopy(editorState);
255255
_deleteSelectedContent(editorState);
256256
}

frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/delete_text_handler.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ KeyEventResult _handleDelete(EditorState editorState, RawKeyEvent event) {
9797
if (textNodes.length == 1) {
9898
final textNode = textNodes.first;
9999
if (selection.start.offset >= textNode.delta.length) {
100-
debugPrint("merge next line");
101100
final nextNode = textNode.next;
102101
if (nextNode == null) {
103102
return KeyEventResult.ignored;

frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/slash_handler.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'dart:math';
33
import 'package:appflowy_editor/src/document/node.dart';
44
import 'package:appflowy_editor/src/editor_state.dart';
55
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
6+
import 'package:appflowy_editor/src/infra/log.dart';
67
import 'package:appflowy_editor/src/operation/transaction_builder.dart';
78
import 'package:appflowy_editor/src/render/rich_text/rich_text_style.dart';
89
import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
@@ -50,12 +51,6 @@ final List<PopupListItem> _popupListItems = [
5051
icon: _popupListIcon('bullets'),
5152
handler: (editorState) => insertBulletedListAfterSelection(editorState),
5253
),
53-
// PopupListItem(
54-
// text: 'Numbered list',
55-
// keywords: ['numbered list'],
56-
// icon: _popupListIcon('number'),
57-
// handler: (editorState) => debugPrint('Not implement yet!'),
58-
// ),
5954
PopupListItem(
6055
text: 'To-do List',
6156
keywords: ['checkbox', 'todo'],
@@ -293,7 +288,7 @@ class _PopupListWidgetState extends State<PopupListWidget> {
293288
}
294289

295290
KeyEventResult _onKey(FocusNode node, RawKeyEvent event) {
296-
debugPrint('slash on key $event');
291+
Log.keyboard.debug('slash command, on key $event');
297292
if (event is! RawKeyDownEvent) {
298293
return KeyEventResult.ignored;
299294
}

frontend/app_flowy/packages/appflowy_editor/lib/src/service/keyboard_service.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:appflowy_editor/appflowy_editor.dart';
2+
import 'package:appflowy_editor/src/infra/log.dart';
23
import 'package:flutter/services.dart';
34

45
import 'package:flutter/material.dart';
@@ -94,15 +95,13 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
9495

9596
@override
9697
KeyEventResult onKey(RawKeyEvent event) {
97-
debugPrint('on keyboard event $event');
98+
Log.keyboard.debug('on keyboard event $event');
9899

99100
if (event is! RawKeyDownEvent) {
100101
return KeyEventResult.ignored;
101102
}
102103

103104
for (final handler in widget.handlers) {
104-
// debugPrint('handle keyboard event $event by $handler');
105-
106105
KeyEventResult result = handler(widget.editorState, event);
107106

108107
switch (result) {
@@ -119,7 +118,7 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
119118
}
120119

121120
void _onFocusChange(bool value) {
122-
debugPrint('[KeyBoard Service] focus change $value');
121+
Log.keyboard.debug('on keyboard event focus change $value');
123122
}
124123

125124
KeyEventResult _onKey(FocusNode node, RawKeyEvent event) {

0 commit comments

Comments
 (0)