diff --git a/lib/features/composer/presentation/composer_bindings.dart b/lib/features/composer/presentation/composer_bindings.dart index 27cc6b6ad..8647672ee 100644 --- a/lib/features/composer/presentation/composer_bindings.dart +++ b/lib/features/composer/presentation/composer_bindings.dart @@ -74,6 +74,7 @@ import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; import 'package:tmail_ui_user/main/utils/ios_sharing_manager.dart'; import 'package:uuid/uuid.dart'; +import 'package:scribe/scribe/ai/domain/usecases/generate_ai_text_interactor.dart'; class ComposerBindings extends BaseBindings { @@ -338,6 +339,7 @@ class ComposerBindings extends BaseBindings { Get.find(tag: composerId), Get.find(tag: composerId), Get.find(tag: composerId), + Get.find(), composerId: composerId, composerArgs: composerArguments, ), tag: composerId); diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index bd1a0f810..7d6036e6c 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -180,6 +180,7 @@ class ComposerController extends BaseController final String? composerId; final ComposerArguments? composerArgs; final SaveTemplateEmailInteractor _saveTemplateEmailInteractor; + final GenerateAITextInteractor _generateAITextInteractor; GetAllAutoCompleteInteractor? _getAllAutoCompleteInteractor; GetAutoCompleteInteractor? _getAutoCompleteInteractor; @@ -287,6 +288,7 @@ class ComposerController extends BaseController this.printEmailInteractor, this._composerRepository, this._saveTemplateEmailInteractor, + this._generateAITextInteractor, { this.composerId, this.composerArgs, @@ -920,6 +922,7 @@ class ComposerController extends BaseController imagePaths: imagePaths, content: fullText, onInsertText: insertTextInEditor, + interactor: _generateAITextInteractor, buttonPosition: buttonPosition, ); } @@ -935,6 +938,7 @@ class ComposerController extends BaseController imagePaths: imagePaths, content: selection, onInsertText: insertTextInEditor, + interactor: _generateAITextInteractor, buttonPosition: buttonPosition, ); } diff --git a/scribe/lib/scribe/ai/presentation/bindings/ai_scribe_bindings.dart b/scribe/lib/scribe/ai/presentation/bindings/ai_scribe_bindings.dart new file mode 100644 index 000000000..90c0ea233 --- /dev/null +++ b/scribe/lib/scribe/ai/presentation/bindings/ai_scribe_bindings.dart @@ -0,0 +1,44 @@ +import 'package:dio/dio.dart'; +import 'package:get/get.dart'; +import 'package:scribe/scribe/ai/data/datasource/ai_datasource.dart'; +import 'package:scribe/scribe/ai/data/datasource_impl/ai_datasource_impl.dart'; +import 'package:scribe/scribe/ai/data/repository/ai_repository_impl.dart'; +import 'package:scribe/scribe/ai/domain/repository/ai_scribe_repository.dart'; +import 'package:scribe/scribe/ai/domain/usecases/generate_ai_text_interactor.dart'; + +class AIScribeBindings extends Bindings { + @override + void dependencies() { + _bindingsDataSourceImpl(); + _bindingsDataSource(); + _bindingsRepositoryImpl(); + _bindingsRepository(); + _bindingsInteractor(); + } + + void _bindingsDataSourceImpl() { + Get.lazyPut(() => AIDataSourceImpl( + dio: Dio(), // Dedicated Dio instance without authorization interceptors + )); + } + + void _bindingsDataSource() { + Get.lazyPut(() => Get.find()); + } + + void _bindingsRepositoryImpl() { + Get.lazyPut(() => AIScribeRepositoryImpl( + Get.find(), + )); + } + + void _bindingsRepository() { + Get.lazyPut(() => Get.find()); + } + + void _bindingsInteractor() { + Get.lazyPut(() => GenerateAITextInteractor( + Get.find(), + )); + } +} diff --git a/scribe/lib/scribe/ai/presentation/widgets/ai_scribe.dart b/scribe/lib/scribe/ai/presentation/widgets/ai_scribe.dart index a732d1301..f517d568f 100644 --- a/scribe/lib/scribe/ai/presentation/widgets/ai_scribe.dart +++ b/scribe/lib/scribe/ai/presentation/widgets/ai_scribe.dart @@ -1,10 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:dio/dio.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/utils/app_logger.dart'; -import 'package:scribe/scribe/ai/data/datasource_impl/ai_datasource_impl.dart'; -import 'package:scribe/scribe/ai/data/repository/ai_repository_impl.dart'; import 'package:scribe/scribe/ai/domain/state/generate_ai_text_state.dart'; import 'package:scribe/scribe/ai/domain/usecases/generate_ai_text_interactor.dart'; import 'package:scribe/scribe/ai/presentation/model/ai_action.dart'; @@ -21,6 +18,7 @@ Future showAIScribeDialog({ required ImagePaths imagePaths, required String content, required AIScribeResultCallback onInsertText, + required GenerateAITextInteractor interactor, List? availableCategories, Offset? buttonPosition, }) async { @@ -109,7 +107,7 @@ Future showAIScribeDialog({ context: context, barrierDismissible: true, builder: (context) { - final suggestionFuture = _executeAIRequest(selectedAction, content); + final suggestionFuture = _executeAIRequest(interactor, selectedAction, content); final title = selectedAction.getLabel(context); final modalContent = AIScribeSuggestion( @@ -194,14 +192,10 @@ Future showAIScribeDialog({ } Future _executeAIRequest( + GenerateAITextInteractor interactor, AIAction action, String content, ) async { - final dio = Dio(); - final dataSource = AIDataSourceImpl(dio: dio); - final repository = AIScribeRepositoryImpl(dataSource); - final interactor = GenerateAITextInteractor(repository); - final result = await interactor.execute(action, content); return result.fold( diff --git a/scribe/pubspec.lock b/scribe/pubspec.lock index 4f62c1a5e..c7b31e06f 100644 --- a/scribe/pubspec.lock +++ b/scribe/pubspec.lock @@ -581,7 +581,7 @@ packages: source: hosted version: "4.0.0" get: - dependency: transitive + dependency: "direct main" description: name: get sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e diff --git a/scribe/pubspec.yaml b/scribe/pubspec.yaml index 3e62f1652..96d128a8b 100644 --- a/scribe/pubspec.yaml +++ b/scribe/pubspec.yaml @@ -24,6 +24,8 @@ dependencies: flutter_dotenv: 5.0.2 + get: 4.6.6 + pointer_interceptor: 0.10.1+2 intl: 0.20.2 diff --git a/test/features/composer/presentation/composer_controller_test.dart b/test/features/composer/presentation/composer_controller_test.dart index 5f1355f50..6965b366b 100644 --- a/test/features/composer/presentation/composer_controller_test.dart +++ b/test/features/composer/presentation/composer_controller_test.dart @@ -68,6 +68,7 @@ import 'package:tmail_ui_user/main/utils/app_config.dart'; import 'package:tmail_ui_user/main/utils/toast_manager.dart'; import 'package:tmail_ui_user/main/utils/twake_app_manager.dart'; import 'package:uuid/uuid.dart'; +import 'package:scribe/scribe/ai/domain/usecases/generate_ai_text_interactor.dart'; import '../../../fixtures/account_fixtures.dart'; import '../../../fixtures/session_fixtures.dart'; @@ -178,6 +179,7 @@ class MockMailboxDashBoardController extends Mock implements MailboxDashBoardCon MockSpec(), MockSpec(), MockSpec(), + MockSpec(), // Additional Getx dependencies mock specs MockSpec(fallbackGenerators: fallbackGenerators), @@ -223,6 +225,7 @@ void main() { late MockPrintEmailInteractor mockPrintEmailInteractor; late MockComposerRepository mockComposerRepository; late MockSaveTemplateEmailInteractor mockSaveTemplateEmailInteractor; + late MockGenerateAITextInteractor mockGenerateAITextInteractor; // Declaration Getx dependencies final mockMailboxDashBoardController = MockMailboxDashBoardController(); @@ -293,6 +296,7 @@ void main() { mockPrintEmailInteractor = MockPrintEmailInteractor(); mockComposerRepository = MockComposerRepository(); mockSaveTemplateEmailInteractor = MockSaveTemplateEmailInteractor(); + mockGenerateAITextInteractor = MockGenerateAITextInteractor(); composerController = ComposerController( mockLocalFilePickerInteractor, @@ -310,6 +314,7 @@ void main() { mockPrintEmailInteractor, mockComposerRepository, mockSaveTemplateEmailInteractor, + mockGenerateAITextInteractor, ); mockHtmlEditorApi = MockHtmlEditorApi();