2843 timeout on igc (#2846)
* chore: add timeout to tokenization call after message send * chore: add timeout to IGC * chore: add timeout to IT
This commit is contained in:
parent
3adac7f63c
commit
75f70c7fdb
11 changed files with 130 additions and 119 deletions
|
|
@ -400,7 +400,12 @@ class ChatView extends StatelessWidget {
|
|||
// #Pangea
|
||||
// Keep messages above minimum input bar height
|
||||
if (!controller.room.isAbandonedDMRoom)
|
||||
SizedBox(height: controller.inputBarHeight),
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: SizedBox(
|
||||
height: controller.inputBarHeight,
|
||||
),
|
||||
),
|
||||
// Pangea#
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ class ChatFloatingActionButtonState extends State<ChatFloatingActionButton> {
|
|||
child: const Icon(Icons.arrow_downward_outlined),
|
||||
);
|
||||
}
|
||||
if (widget.controller.choreographer.errorService.error != null) {
|
||||
if (widget.controller.choreographer.errorService.error != null &&
|
||||
!widget.controller.choreographer.itController.willOpen) {
|
||||
return ChoreographerHasErrorButton(
|
||||
widget.controller.choreographer.errorService.error!,
|
||||
widget.controller.choreographer,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
|
|
@ -22,17 +24,27 @@ class ChatInputBar extends StatefulWidget {
|
|||
}
|
||||
|
||||
class ChatInputBarState extends State<ChatInputBar> {
|
||||
void updateHeight() {
|
||||
final renderBox = context.findRenderObject() as RenderBox?;
|
||||
if (renderBox == null || !renderBox.hasSize) return;
|
||||
widget.controller.updateInputBarHeight(renderBox.size.height);
|
||||
Timer? _debounceTimer;
|
||||
|
||||
void _updateHeight() {
|
||||
_debounceTimer = Timer(const Duration(milliseconds: 100), () {
|
||||
final renderBox = context.findRenderObject() as RenderBox?;
|
||||
if (renderBox == null || !renderBox.hasSize) return;
|
||||
widget.controller.updateInputBarHeight(renderBox.size.height);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_debounceTimer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return NotificationListener(
|
||||
onNotification: (SizeChangedLayoutNotification notification) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => updateHeight());
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _updateHeight());
|
||||
return true;
|
||||
},
|
||||
child: SizeChangedLayoutNotifier(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import 'package:fluffychat/pangea/choreographer/enums/edit_type.dart';
|
|||
import 'package:fluffychat/pangea/choreographer/models/choreo_record.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/models/it_step.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/models/pangea_match_model.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/repo/language_detection_repo.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/utils/input_paste_listener.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/igc/pangea_text_controller.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/igc/paywall_card.dart';
|
||||
|
|
@ -21,7 +20,6 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
|
|||
import 'package:fluffychat/pangea/common/utils/any_state_holder.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/overlay.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/representation_content_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart';
|
||||
import 'package:fluffychat/pangea/events/repo/token_api_models.dart';
|
||||
|
|
@ -148,56 +146,57 @@ class Choreographer {
|
|||
)
|
||||
: null;
|
||||
|
||||
final detectionResp = await LanguageDetectionRepo.get(
|
||||
MatrixState.pangeaController.userController.accessToken,
|
||||
request: LanguageDetectionRequest(
|
||||
PangeaMessageTokens? tokensSent;
|
||||
PangeaRepresentation? originalSent;
|
||||
try {
|
||||
TokensResponseModel? res;
|
||||
if (l1LangCode != null && l2LangCode != null) {
|
||||
res = await pangeaController.messageData
|
||||
.getTokens(
|
||||
repEventId: null,
|
||||
room: chatController.room,
|
||||
req: TokensRequestModel(
|
||||
fullText: currentText,
|
||||
senderL1: l1LangCode!,
|
||||
senderL2: l2LangCode!,
|
||||
),
|
||||
)
|
||||
.timeout(const Duration(seconds: 10));
|
||||
}
|
||||
|
||||
originalSent = PangeaRepresentation(
|
||||
langCode: res?.detections.firstOrNull?.langCode ??
|
||||
LanguageKeys.unknownLanguage,
|
||||
text: currentText,
|
||||
senderl1: l1LangCode,
|
||||
senderl2: l2LangCode,
|
||||
),
|
||||
);
|
||||
final detections = detectionResp.detections;
|
||||
final detectedLanguage =
|
||||
detections.firstOrNull?.langCode ?? LanguageKeys.unknownLanguage;
|
||||
|
||||
final PangeaRepresentation originalSent = PangeaRepresentation(
|
||||
langCode: detectedLanguage,
|
||||
text: currentText,
|
||||
originalSent: true,
|
||||
originalWritten: originalWritten == null,
|
||||
);
|
||||
|
||||
List<PangeaToken>? res;
|
||||
if (l1LangCode != null && l2LangCode != null) {
|
||||
res = await pangeaController.messageData.getTokens(
|
||||
repEventId: null,
|
||||
room: chatController.room,
|
||||
req: TokensRequestModel(
|
||||
fullText: currentText,
|
||||
langCode: detectedLanguage,
|
||||
senderL1: l1LangCode!,
|
||||
senderL2: l2LangCode!,
|
||||
),
|
||||
originalSent: true,
|
||||
originalWritten: originalWritten == null,
|
||||
);
|
||||
|
||||
tokensSent = res != null
|
||||
? PangeaMessageTokens(
|
||||
tokens: res.tokens,
|
||||
detections: res.detections,
|
||||
)
|
||||
: null;
|
||||
} catch (e, s) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
"currentText": currentText,
|
||||
"l1LangCode": l1LangCode,
|
||||
"l2LangCode": l2LangCode,
|
||||
"choreoRecord": choreoRecord.toJson(),
|
||||
},
|
||||
);
|
||||
} finally {
|
||||
chatController.send(
|
||||
originalSent: originalSent,
|
||||
tokensSent: tokensSent,
|
||||
choreo: choreoRecord,
|
||||
);
|
||||
clear();
|
||||
}
|
||||
|
||||
final PangeaMessageTokens? tokensSent = res != null
|
||||
? PangeaMessageTokens(
|
||||
tokens: res,
|
||||
detections: detections,
|
||||
)
|
||||
: null;
|
||||
|
||||
chatController.send(
|
||||
// originalWritten: originalWritten,
|
||||
originalSent: originalSent,
|
||||
tokensSent: tokensSent,
|
||||
//TODO - save originalwritten tokens
|
||||
// choreo: applicableChoreo,
|
||||
choreo: choreoRecord,
|
||||
);
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
_resetDebounceTimer() {
|
||||
|
|
|
|||
|
|
@ -104,7 +104,9 @@ class IgcController {
|
|||
}
|
||||
|
||||
final IGCTextData igcTextDataResponse =
|
||||
await _igcTextDataCache[reqBody.hashCode]!.data;
|
||||
await _igcTextDataCache[reqBody.hashCode]!
|
||||
.data
|
||||
.timeout((const Duration(seconds: 10)));
|
||||
|
||||
// this will happen when the user changes the input while igc is fetching results
|
||||
if (igcTextDataResponse.originalInput != choreographer.currentText) {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class ITController {
|
|||
choreographer.setState();
|
||||
}
|
||||
|
||||
Duration get animationSpeed => const Duration(milliseconds: 500);
|
||||
Duration get animationSpeed => const Duration(milliseconds: 300);
|
||||
|
||||
Future<void> initializeIT(ITStartData itStartData) async {
|
||||
_willOpen = true;
|
||||
|
|
@ -136,7 +136,8 @@ class ITController {
|
|||
|
||||
// During first IT step, next step will not be set
|
||||
if (nextITStep == null) {
|
||||
final ITResponseModel res = await _customInputTranslation(currentText);
|
||||
final ITResponseModel res = await _customInputTranslation(currentText)
|
||||
.timeout(const Duration(seconds: 10));
|
||||
if (sourceText == null) return;
|
||||
|
||||
if (res.goldContinuances != null && res.goldContinuances!.isNotEmpty) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:fluffychat/pangea/choreographer/constants/choreo_constants.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/controllers/it_controller.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/it_bar_buttons.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/it_feedback_card.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
|
|
@ -206,12 +205,14 @@ class ITBarState extends State<ITBar> with SingleTickerProviderStateMixin {
|
|||
if (!itController.isEditingSourceText)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: itController.sourceText != null
|
||||
? Text(
|
||||
itController.sourceText!,
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
: const LinearProgressIndicator(),
|
||||
child: !itController.willOpen
|
||||
? const SizedBox()
|
||||
: itController.sourceText != null
|
||||
? Text(
|
||||
itController.sourceText!,
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
: const LinearProgressIndicator(),
|
||||
),
|
||||
const SizedBox(height: 8.0),
|
||||
Container(
|
||||
|
|
@ -391,10 +392,12 @@ class ITChoices extends StatelessWidget {
|
|||
return const SizedBox();
|
||||
}
|
||||
if (controller.currentITStep == null) {
|
||||
return CircularProgressIndicator(
|
||||
strokeWidth: 2.0,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
);
|
||||
return controller.willOpen
|
||||
? CircularProgressIndicator(
|
||||
strokeWidth: 2.0,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
)
|
||||
: const SizedBox();
|
||||
}
|
||||
return ChoicesArray(
|
||||
id: controller.currentITStep.hashCode.toString(),
|
||||
|
|
@ -438,23 +441,38 @@ class ITError extends StatelessWidget {
|
|||
final ErrorCopy errorCopy = ErrorCopy(context, error);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 300),
|
||||
child: Text(
|
||||
// Text(
|
||||
"${errorCopy.title}\n${errorCopy.body}",
|
||||
// Haga clic en su mensaje para ver los significados de las palabras.
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Icon(
|
||||
Icons.error_outline,
|
||||
size: 20,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
),
|
||||
TextSpan(text: " ${errorCopy.title} "),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
controller.closeIT();
|
||||
controller.choreographer.errorService.resetError();
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
ITRestartButton(controller: controller),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import '../controllers/it_controller.dart';
|
||||
|
||||
class ITRestartButton extends StatelessWidget {
|
||||
ITRestartButton({
|
||||
super.key,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
final ITController controller;
|
||||
final PangeaController pangeaController = MatrixState.pangeaController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconButton(
|
||||
onPressed: () async {
|
||||
controller.choreographer.errorService.resetError();
|
||||
controller.currentITStep = null;
|
||||
controller.choreographer.getLanguageHelp();
|
||||
},
|
||||
icon: const Icon(Icons.refresh_outlined),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
|
|||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
|
||||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/representation_content_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart';
|
||||
import 'package:fluffychat/pangea/events/repo/token_api_models.dart';
|
||||
|
|
@ -23,7 +22,7 @@ import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
|||
class MessageDataController extends BaseController {
|
||||
late PangeaController _pangeaController;
|
||||
|
||||
final Map<int, Future<List<PangeaToken>>> _tokensCache = {};
|
||||
final Map<int, Future<TokensResponseModel>> _tokensCache = {};
|
||||
final Map<int, Future<PangeaRepresentation>> _representationCache = {};
|
||||
late Timer _cacheTimer;
|
||||
|
||||
|
|
@ -54,7 +53,7 @@ class MessageDataController extends BaseController {
|
|||
|
||||
/// get tokens from the server
|
||||
/// if repEventId is not null, send the tokens to the room
|
||||
Future<List<PangeaToken>> _getTokens({
|
||||
Future<TokensResponseModel> _getTokens({
|
||||
required String? repEventId,
|
||||
required TokensRequestModel req,
|
||||
required Room? room,
|
||||
|
|
@ -83,13 +82,13 @@ class MessageDataController extends BaseController {
|
|||
);
|
||||
}
|
||||
|
||||
return res.tokens;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// get tokens from the server
|
||||
/// first check if the tokens are in the cache
|
||||
/// if repEventId is not null, send the tokens to the room
|
||||
Future<List<PangeaToken>> getTokens({
|
||||
Future<TokensResponseModel> getTokens({
|
||||
required String? repEventId,
|
||||
required TokensRequestModel req,
|
||||
required Room? room,
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ class RepresentationEvent {
|
|||
),
|
||||
);
|
||||
}
|
||||
final List<PangeaToken> res =
|
||||
final TokensResponseModel res =
|
||||
await MatrixState.pangeaController.messageData.getTokens(
|
||||
repEventId: _event?.eventId,
|
||||
room: _event?.room ?? parentMessageEvent.room,
|
||||
|
|
@ -180,7 +180,7 @@ class RepresentationEvent {
|
|||
),
|
||||
);
|
||||
|
||||
return res;
|
||||
return res.tokens;
|
||||
}
|
||||
|
||||
Future<void> sendTokensEvent(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:fluffychat/pangea/choreographer/models/language_detection_model.dart';
|
||||
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart';
|
||||
|
||||
class TokensRequestModel {
|
||||
/// the text to be tokenized
|
||||
|
|
@ -24,16 +25,16 @@ class TokensRequestModel {
|
|||
|
||||
TokensRequestModel({
|
||||
required this.fullText,
|
||||
required this.langCode,
|
||||
required this.senderL1,
|
||||
required this.senderL2,
|
||||
this.langCode,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
ModelKey.fullText: fullText,
|
||||
ModelKey.userL1: senderL1,
|
||||
ModelKey.userL2: senderL2,
|
||||
ModelKey.langCode: langCode,
|
||||
ModelKey.langCode: langCode ?? LanguageKeys.unknownLanguage,
|
||||
};
|
||||
|
||||
// override equals and hashcode
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue