You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
7.4 KiB
Dart
279 lines
7.4 KiB
Dart
import 'package:collection/collection.dart';
|
|
import 'package:fluffychat/pangea/controllers/base_controller.dart';
|
|
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
|
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
|
import 'package:fluffychat/pangea/models/message_data_models.dart';
|
|
import 'package:fluffychat/pangea/repo/tokens_repo.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:matrix/matrix.dart';
|
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
|
|
|
import '../constants/pangea_event_types.dart';
|
|
import '../enum/use_type.dart';
|
|
import '../models/choreo_record.dart';
|
|
import '../repo/full_text_translation_repo.dart';
|
|
import '../utils/error_handler.dart';
|
|
|
|
class MessageDataController extends BaseController {
|
|
late PangeaController _pangeaController;
|
|
|
|
final List<CacheItem> _cache = [];
|
|
final List<RepresentationCacheItem> _representationCache = [];
|
|
|
|
MessageDataController(PangeaController pangeaController) {
|
|
_pangeaController = pangeaController;
|
|
}
|
|
|
|
CacheItem? getItem(String parentId, String type, String langCode) =>
|
|
_cache.firstWhereOrNull(
|
|
(e) =>
|
|
e.parentId == parentId && e.type == type && e.langCode == langCode,
|
|
);
|
|
|
|
RepresentationCacheItem? getRepresentationCacheItem(
|
|
String parentId,
|
|
String langCode,
|
|
) =>
|
|
_representationCache.firstWhereOrNull(
|
|
(e) => e.parentId == parentId && e.langCode == langCode,
|
|
);
|
|
|
|
Future<PangeaMessageTokens?> _getTokens(
|
|
TokensRequestModel req,
|
|
) async {
|
|
final accessToken = await _pangeaController.userController.accessToken;
|
|
|
|
final TokensResponseModel igcTextData =
|
|
await TokensRepo.tokenize(accessToken, req);
|
|
|
|
return PangeaMessageTokens(tokens: igcTextData.tokens);
|
|
}
|
|
|
|
Future<Event?> _getTokenEvent({
|
|
required BuildContext context,
|
|
required String repEventId,
|
|
required TokensRequestModel req,
|
|
required Room room,
|
|
}) async {
|
|
try {
|
|
final PangeaMessageTokens? pangeaMessageTokens = await _getTokens(
|
|
req,
|
|
);
|
|
if (pangeaMessageTokens == null) return null;
|
|
|
|
final Event? tokensEvent = await room.sendPangeaEvent(
|
|
content: pangeaMessageTokens.toJson(),
|
|
parentEventId: repEventId,
|
|
type: PangeaEventTypes.tokens,
|
|
);
|
|
|
|
return tokensEvent;
|
|
} catch (err, stack) {
|
|
Sentry.addBreadcrumb(
|
|
Breadcrumb(
|
|
message: "err in _getTokenEvent with repEventId $repEventId",
|
|
),
|
|
);
|
|
Sentry.addBreadcrumb(
|
|
Breadcrumb.fromJson({"req": req.toJson()}),
|
|
);
|
|
Sentry.addBreadcrumb(
|
|
Breadcrumb.fromJson({"room": room.toJson()}),
|
|
);
|
|
ErrorHandler.logError(e: err, s: stack);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<Event?> getTokenEvent({
|
|
required BuildContext context,
|
|
required String repEventId,
|
|
required TokensRequestModel req,
|
|
required Room room,
|
|
}) async {
|
|
final CacheItem? item =
|
|
getItem(repEventId, PangeaEventTypes.tokens, req.userL2);
|
|
if (item != null) return item.data;
|
|
|
|
_cache.add(
|
|
CacheItem(
|
|
repEventId,
|
|
PangeaEventTypes.tokens,
|
|
req.userL2,
|
|
_getTokenEvent(
|
|
context: context,
|
|
repEventId: repEventId,
|
|
req: req,
|
|
room: room,
|
|
),
|
|
),
|
|
);
|
|
|
|
return _cache.last.data;
|
|
}
|
|
|
|
/////// translation ////////
|
|
|
|
/// make representation (originalSent and originalWritten always false)
|
|
Future<Event?> _sendRepresentationMatrixEvent({
|
|
required PangeaRepresentation representation,
|
|
required String messageEventId,
|
|
required Room room,
|
|
}) async {
|
|
try {
|
|
final Event? repEvent = await room.sendPangeaEvent(
|
|
content: representation.toJson(),
|
|
parentEventId: messageEventId,
|
|
type: PangeaEventTypes.representation,
|
|
);
|
|
|
|
return repEvent;
|
|
} catch (err, stack) {
|
|
Sentry.addBreadcrumb(
|
|
Breadcrumb(
|
|
message:
|
|
"err in _sendRepresentationMatrixEvent with messageEventId $messageEventId",
|
|
),
|
|
);
|
|
Sentry.addBreadcrumb(
|
|
Breadcrumb.fromJson({"room": room.toJson()}),
|
|
);
|
|
ErrorHandler.logError(e: err, s: stack);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<PangeaRepresentation?> getPangeaRepresentation({
|
|
required String text,
|
|
required String? source,
|
|
required String target,
|
|
required Room room,
|
|
}) async {
|
|
final RepresentationCacheItem? item =
|
|
getRepresentationCacheItem(text, target);
|
|
if (item != null) return item.data;
|
|
|
|
_representationCache.add(
|
|
RepresentationCacheItem(
|
|
text,
|
|
target,
|
|
_getPangeaRepresentation(
|
|
text: text,
|
|
source: source,
|
|
target: target,
|
|
room: room,
|
|
),
|
|
),
|
|
);
|
|
|
|
return _representationCache.last.data;
|
|
}
|
|
|
|
Future<PangeaRepresentation?> _getPangeaRepresentation({
|
|
required String text,
|
|
required String? source,
|
|
required String target,
|
|
required Room room,
|
|
}) async {
|
|
final req = FullTextTranslationRequestModel(
|
|
text: text,
|
|
tgtLang: target,
|
|
srcLang: source,
|
|
userL2:
|
|
_pangeaController.languageController.activeL2Code(roomID: room.id)!,
|
|
userL1:
|
|
_pangeaController.languageController.activeL1Code(roomID: room.id)!,
|
|
);
|
|
|
|
try {
|
|
final FullTextTranslationResponseModel res =
|
|
await FullTextTranslationRepo.translate(
|
|
accessToken: await _pangeaController.userController.accessToken,
|
|
request: req,
|
|
);
|
|
|
|
return PangeaRepresentation(
|
|
langCode: req.tgtLang,
|
|
text: res.bestTranslation,
|
|
originalSent: false,
|
|
originalWritten: false,
|
|
);
|
|
} catch (err, stack) {
|
|
ErrorHandler.logError(e: err, s: stack);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// make representation (originalSent and originalWritten always false)
|
|
Future<Event?> sendRepresentationMatrixEvent({
|
|
required PangeaRepresentation representation,
|
|
required String messageEventId,
|
|
required Room room,
|
|
required String target,
|
|
}) async {
|
|
final CacheItem? item =
|
|
getItem(messageEventId, PangeaEventTypes.representation, target);
|
|
if (item != null) return item.data;
|
|
|
|
_cache.add(
|
|
CacheItem(
|
|
messageEventId,
|
|
PangeaEventTypes.representation,
|
|
target,
|
|
_sendRepresentationMatrixEvent(
|
|
messageEventId: messageEventId,
|
|
room: room,
|
|
representation: representation,
|
|
),
|
|
),
|
|
);
|
|
|
|
return _cache.last.data;
|
|
}
|
|
}
|
|
|
|
class MessageDataQueueItem {
|
|
String transactionId;
|
|
|
|
List<RepTokensAndRecord> repTokensAndRecords;
|
|
|
|
UseType useType;
|
|
|
|
MessageDataQueueItem(
|
|
this.transactionId,
|
|
this.repTokensAndRecords,
|
|
this.useType,
|
|
// required this.recentMessageRecord,
|
|
);
|
|
}
|
|
|
|
class RepTokensAndRecord {
|
|
PangeaRepresentation representation;
|
|
ChoreoRecord? choreoRecord;
|
|
PangeaMessageTokens? tokens;
|
|
RepTokensAndRecord(this.representation, this.choreoRecord, this.tokens);
|
|
|
|
Map<String, dynamic> toJson() => {
|
|
"rep": representation.toJson(),
|
|
"choreoRecord": choreoRecord?.toJson(),
|
|
"tokens": tokens?.toJson(),
|
|
};
|
|
}
|
|
|
|
class CacheItem {
|
|
String parentId;
|
|
String langCode;
|
|
String type;
|
|
Future<Event?> data;
|
|
|
|
CacheItem(this.parentId, this.type, this.langCode, this.data);
|
|
}
|
|
|
|
class RepresentationCacheItem {
|
|
String parentId;
|
|
String langCode;
|
|
Future<PangeaRepresentation?> data;
|
|
|
|
RepresentationCacheItem(this.parentId, this.langCode, this.data);
|
|
}
|