|
1 | 1 | import 'dart:async'; |
2 | 2 |
|
3 | 3 | import 'package:appflowy_backend/dispatch/dispatch.dart'; |
4 | | -import 'package:appflowy_backend/log.dart'; |
5 | 4 | import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; |
| 5 | +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; |
6 | 6 | import 'package:appflowy_result/appflowy_result.dart'; |
7 | 7 | import 'package:bloc/bloc.dart'; |
8 | 8 | import 'package:freezed_annotation/freezed_annotation.dart'; |
9 | | - |
10 | | -import 'local_llm_listener.dart'; |
11 | | - |
12 | 9 | part 'local_ai_bloc.freezed.dart'; |
13 | 10 |
|
14 | | -class LocalAiPluginBloc extends Bloc<LocalAiPluginEvent, LocalAiPluginState> { |
15 | | - LocalAiPluginBloc() : super(const LoadingLocalAiPluginState()) { |
16 | | - on<LocalAiPluginEvent>(_handleEvent); |
17 | | - _startListening(); |
18 | | - _getLocalAiState(); |
19 | | - } |
20 | | - |
21 | | - final listener = LocalAIStateListener(); |
22 | | - |
23 | | - @override |
24 | | - Future<void> close() async { |
25 | | - await listener.stop(); |
26 | | - return super.close(); |
| 11 | +class LocalAIToggleBloc extends Bloc<LocalAIToggleEvent, LocalAIToggleState> { |
| 12 | + LocalAIToggleBloc() : super(const LocalAIToggleState()) { |
| 13 | + on<LocalAIToggleEvent>(_handleEvent); |
27 | 14 | } |
28 | 15 |
|
29 | 16 | Future<void> _handleEvent( |
30 | | - LocalAiPluginEvent event, |
31 | | - Emitter<LocalAiPluginState> emit, |
| 17 | + LocalAIToggleEvent event, |
| 18 | + Emitter<LocalAIToggleState> emit, |
32 | 19 | ) async { |
33 | 20 | await event.when( |
34 | | - didReceiveAiState: (aiState) { |
| 21 | + started: () async { |
| 22 | + final result = await AIEventGetLocalAIState().send(); |
| 23 | + _handleResult(emit, result); |
| 24 | + }, |
| 25 | + toggle: () async { |
35 | 26 | emit( |
36 | | - ReadyLocalAiPluginState( |
37 | | - isEnabled: aiState.enabled, |
38 | | - runningState: aiState.state, |
39 | | - lackOfResource: |
40 | | - aiState.hasLackOfResource() ? aiState.lackOfResource : null, |
| 27 | + state.copyWith( |
| 28 | + pageIndicator: const LocalAIToggleStateIndicator.loading(), |
41 | 29 | ), |
42 | 30 | ); |
43 | | - }, |
44 | | - didReceiveLackOfResources: (resources) { |
45 | | - if (state case final ReadyLocalAiPluginState readyState) { |
46 | | - emit( |
47 | | - ReadyLocalAiPluginState( |
48 | | - isEnabled: readyState.isEnabled, |
49 | | - runningState: readyState.runningState, |
50 | | - lackOfResource: resources, |
51 | | - ), |
52 | | - ); |
53 | | - } |
54 | | - }, |
55 | | - toggle: () async { |
56 | | - emit(LoadingLocalAiPluginState()); |
57 | | - await AIEventToggleLocalAI().send().fold( |
58 | | - (aiState) { |
59 | | - add(LocalAiPluginEvent.didReceiveAiState(aiState)); |
60 | | - }, |
61 | | - Log.error, |
| 31 | + unawaited( |
| 32 | + AIEventToggleLocalAI().send().then( |
| 33 | + (result) { |
| 34 | + if (!isClosed) { |
| 35 | + add(LocalAIToggleEvent.handleResult(result)); |
| 36 | + } |
| 37 | + }, |
| 38 | + ), |
62 | 39 | ); |
63 | 40 | }, |
64 | | - restart: () async { |
65 | | - emit(LoadingLocalAiPluginState()); |
66 | | - await AIEventRestartLocalAI().send(); |
| 41 | + handleResult: (result) { |
| 42 | + _handleResult(emit, result); |
67 | 43 | }, |
68 | 44 | ); |
69 | 45 | } |
70 | 46 |
|
71 | | - void _startListening() { |
72 | | - listener.start( |
73 | | - stateCallback: (pluginState) { |
74 | | - add(LocalAiPluginEvent.didReceiveAiState(pluginState)); |
75 | | - }, |
76 | | - resourceCallback: (data) { |
77 | | - add(LocalAiPluginEvent.didReceiveLackOfResources(data)); |
| 47 | + void _handleResult( |
| 48 | + Emitter<LocalAIToggleState> emit, |
| 49 | + FlowyResult<LocalAIPB, FlowyError> result, |
| 50 | + ) { |
| 51 | + result.fold( |
| 52 | + (localAI) { |
| 53 | + emit( |
| 54 | + state.copyWith( |
| 55 | + pageIndicator: |
| 56 | + LocalAIToggleStateIndicator.isEnabled(localAI.enabled), |
| 57 | + ), |
| 58 | + ); |
78 | 59 | }, |
79 | | - ); |
80 | | - } |
81 | | - |
82 | | - void _getLocalAiState() { |
83 | | - AIEventGetLocalAIState().send().fold( |
84 | | - (aiState) { |
85 | | - add(LocalAiPluginEvent.didReceiveAiState(aiState)); |
| 60 | + (err) { |
| 61 | + emit( |
| 62 | + state.copyWith( |
| 63 | + pageIndicator: LocalAIToggleStateIndicator.error(err), |
| 64 | + ), |
| 65 | + ); |
86 | 66 | }, |
87 | | - Log.error, |
88 | 67 | ); |
89 | 68 | } |
90 | 69 | } |
91 | 70 |
|
92 | 71 | @freezed |
93 | | -class LocalAiPluginEvent with _$LocalAiPluginEvent { |
94 | | - const factory LocalAiPluginEvent.didReceiveAiState(LocalAIPB aiState) = |
95 | | - _DidReceiveAiState; |
96 | | - const factory LocalAiPluginEvent.didReceiveLackOfResources( |
97 | | - LackOfAIResourcePB resources, |
98 | | - ) = _DidReceiveLackOfResources; |
99 | | - const factory LocalAiPluginEvent.toggle() = _Toggle; |
100 | | - const factory LocalAiPluginEvent.restart() = _Restart; |
101 | | -} |
102 | | - |
103 | | -sealed class LocalAiPluginState { |
104 | | - const LocalAiPluginState(); |
| 72 | +class LocalAIToggleEvent with _$LocalAIToggleEvent { |
| 73 | + const factory LocalAIToggleEvent.started() = _Started; |
| 74 | + const factory LocalAIToggleEvent.toggle() = _Toggle; |
| 75 | + const factory LocalAIToggleEvent.handleResult( |
| 76 | + FlowyResult<LocalAIPB, FlowyError> result, |
| 77 | + ) = _HandleResult; |
105 | 78 | } |
106 | 79 |
|
107 | | -class ReadyLocalAiPluginState extends LocalAiPluginState { |
108 | | - const ReadyLocalAiPluginState({ |
109 | | - required this.isEnabled, |
110 | | - required this.runningState, |
111 | | - required this.lackOfResource, |
112 | | - }); |
113 | | - |
114 | | - final bool isEnabled; |
115 | | - final RunningStatePB runningState; |
116 | | - final LackOfAIResourcePB? lackOfResource; |
| 80 | +@freezed |
| 81 | +class LocalAIToggleState with _$LocalAIToggleState { |
| 82 | + const factory LocalAIToggleState({ |
| 83 | + @Default(LocalAIToggleStateIndicator.loading()) |
| 84 | + LocalAIToggleStateIndicator pageIndicator, |
| 85 | + }) = _LocalAIToggleState; |
117 | 86 | } |
118 | 87 |
|
119 | | -class LoadingLocalAiPluginState extends LocalAiPluginState { |
120 | | - const LoadingLocalAiPluginState(); |
| 88 | +@freezed |
| 89 | +class LocalAIToggleStateIndicator with _$LocalAIToggleStateIndicator { |
| 90 | + // when start downloading the model |
| 91 | + const factory LocalAIToggleStateIndicator.error(FlowyError error) = _OnError; |
| 92 | + const factory LocalAIToggleStateIndicator.isEnabled(bool isEnabled) = _Ready; |
| 93 | + const factory LocalAIToggleStateIndicator.loading() = _Loading; |
121 | 94 | } |
0 commit comments