Export AI Scribe code from controller to a mixin

Avoid adding too much code in the controller
This commit is contained in:
Théo Poizat
2025-12-11 11:31:25 +01:00
committed by Dat H. Pham
parent 4d0880b8be
commit 77a56ae9b7
4 changed files with 93 additions and 76 deletions
@@ -0,0 +1,84 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:scribe/scribe.dart';
import 'package:scribe/scribe/ai/presentation/widgets/ai_scribe.dart';
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/mixins/text_selection_mixin.dart';
mixin AIScribeInComposerMixin {
final editorTextSelection = Rxn<EditorTextSelection>();
final GlobalKey aiScribeButtonKey = GlobalKey();
RichTextWebController? get richTextWebController;
RichTextMobileTabletController? get richTextMobileTabletController;
ImagePaths get imagePaths;
GenerateAITextInteractor get generateAITextInteractor;
Future<String> getTextOnlyContentInEditor();
void insertTextInEditor(String text) {
final htmlContent = text.replaceAll('\n', '<br>');
if (PlatformInfo.isWeb) {
richTextWebController?.editorController.insertHtml(htmlContent);
} else {
richTextMobileTabletController?.htmlEditorApi?.insertHtml(htmlContent);
}
}
void showAIScribeMenuForFullText(BuildContext context) async {
final fullText = await getTextOnlyContentInEditor();
final RenderBox? renderBox = aiScribeButtonKey.currentContext?.findRenderObject() as RenderBox?;
Offset? buttonPosition;
if (renderBox != null) {
buttonPosition = renderBox.localToGlobal(Offset.zero);
}
if (!context.mounted) return;
showAIScribeDialog(
context: context,
imagePaths: imagePaths,
content: fullText,
onInsertText: insertTextInEditor,
interactor: generateAITextInteractor,
buttonPosition: buttonPosition,
);
}
void showAIScribeMenuForSelectedText(BuildContext context, {Offset? buttonPosition}) {
final selection = editorTextSelection.value?.selectedText;
if (selection == null || selection.isEmpty) {
return;
}
showAIScribeDialog(
context: context,
imagePaths: imagePaths,
content: selection,
onInsertText: insertTextInEditor,
interactor: generateAITextInteractor,
buttonPosition: buttonPosition,
);
}
void handleTextSelection(TextSelectionData? textSelectionData) {
if (textSelectionData != null && textSelectionData.hasSelection) {
editorTextSelection.value = EditorTextSelection(
selectedText: textSelectionData.selectedText,
coordinates: textSelectionData.coordinates != null
? Offset(
textSelectionData.coordinates!.x,
textSelectionData.coordinates!.y,
)
: null,
);
} else {
editorTextSelection.value = null;
}
}
}