|
|
@ -1,3 +1,4 @@ |
|
|
|
|
|
|
|
import 'dart:async'; |
|
|
|
import 'dart:convert'; |
|
|
|
import 'dart:convert'; |
|
|
|
import 'dart:io'; |
|
|
|
import 'dart:io'; |
|
|
|
|
|
|
|
|
|
|
@ -29,6 +30,8 @@ class TextEditorState extends State<TextEditor> with AutomaticKeepAliveClientMix |
|
|
|
final TextEditingController _textController = TextEditingController(); |
|
|
|
final TextEditingController _textController = TextEditingController(); |
|
|
|
final FocusNode _focusNode = FocusNode(); |
|
|
|
final FocusNode _focusNode = FocusNode(); |
|
|
|
bool _isLoading = false; |
|
|
|
bool _isLoading = false; |
|
|
|
|
|
|
|
String _lastSyncedText = ''; |
|
|
|
|
|
|
|
Timer? _debounceTimer; |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
bool get wantKeepAlive => true; |
|
|
|
bool get wantKeepAlive => true; |
|
|
@ -36,26 +39,38 @@ class TextEditorState extends State<TextEditor> with AutomaticKeepAliveClientMix |
|
|
|
@override |
|
|
|
@override |
|
|
|
void initState() { |
|
|
|
void initState() { |
|
|
|
super.initState(); |
|
|
|
super.initState(); |
|
|
|
_textController.text = widget.initialContent ?? ''; |
|
|
|
_lastSyncedText = widget.initialContent ?? ''; |
|
|
|
|
|
|
|
_textController.text = _lastSyncedText; |
|
|
|
_textController.addListener(_handleTextChanged); |
|
|
|
_textController.addListener(_handleTextChanged); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
void _handleTextChanged() { |
|
|
|
void didUpdateWidget(TextEditor oldWidget) { |
|
|
|
if (_debounceTimer?.isActive ?? false) { |
|
|
|
super.didUpdateWidget(oldWidget); |
|
|
|
_debounceTimer?.cancel(); |
|
|
|
if (oldWidget.initialContent != widget.initialContent) { |
|
|
|
|
|
|
|
_textController.text = widget.initialContent ?? ''; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_debounceTimer = Timer(const Duration(milliseconds: 300), () { |
|
|
|
|
|
|
|
final currentText = _textController.text; |
|
|
|
|
|
|
|
if (widget.onContentChanged != null && currentText != _lastSyncedText) { |
|
|
|
|
|
|
|
_lastSyncedText = currentText; |
|
|
|
|
|
|
|
widget.onContentChanged!(currentText); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void _handleTextChanged() { |
|
|
|
@override |
|
|
|
if (widget.onContentChanged != null) { |
|
|
|
void didUpdateWidget(TextEditor oldWidget) { |
|
|
|
widget.onContentChanged!(_textController.text); |
|
|
|
super.didUpdateWidget(oldWidget); |
|
|
|
|
|
|
|
final newText = widget.initialContent ?? ''; |
|
|
|
|
|
|
|
if (newText != _textController.text && newText != _lastSyncedText) { |
|
|
|
|
|
|
|
_lastSyncedText = newText; |
|
|
|
|
|
|
|
_textController.text = newText; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
void dispose() { |
|
|
|
void dispose() { |
|
|
|
|
|
|
|
_debounceTimer?.cancel(); |
|
|
|
_textController.removeListener(_handleTextChanged); |
|
|
|
_textController.removeListener(_handleTextChanged); |
|
|
|
_textController.dispose(); |
|
|
|
_textController.dispose(); |
|
|
|
_focusNode.dispose(); |
|
|
|
_focusNode.dispose(); |
|
|
|