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.
fluffychat/lib/pangea/controllers/language_detection_controll...

169 lines
4.6 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:fluffychat/pangea/config/environment.dart';
import 'package:fluffychat/pangea/constants/language_constants.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/models/language_detection_model.dart';
import 'package:fluffychat/pangea/network/urls.dart';
import 'package:http/http.dart' as http;
import '../network/requests.dart';
class LanguageDetectionRequest {
/// The full text from which to detect the language.
String fullText;
/// The base language of the user, if known. Including this is much preferred
/// and should return better results; however, it is not absolutely necessary.
/// This property is nullable to allow for situations where the languages are not set
/// at the time of the request.
String? userL1;
/// The target language of the user. This is expected to be set for the request
/// but is nullable to handle edge cases where it might not be.
String? userL2;
LanguageDetectionRequest({
required this.fullText,
this.userL1 = "",
required this.userL2,
});
Map<String, dynamic> toJson() => {
'full_text': fullText,
'user_l1': userL1,
'user_l2': userL2,
};
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is LanguageDetectionRequest &&
other.fullText == fullText &&
other.userL1 == userL1 &&
other.userL2 == userL2;
}
@override
int get hashCode => fullText.hashCode ^ userL1.hashCode ^ userL2.hashCode;
}
class LanguageDetectionResponse {
List<LanguageDetection> detections;
String fullText;
LanguageDetectionResponse({
required this.detections,
required this.fullText,
});
factory LanguageDetectionResponse.fromJson(Map<String, dynamic> json) {
return LanguageDetectionResponse(
detections: List<LanguageDetection>.from(
json['detections'].map(
(e) => LanguageDetection.fromJson(e),
),
),
fullText: json['full_text'],
);
}
Map<String, dynamic> toJson() {
return {
'detections': detections,
'full_text': fullText,
};
}
LanguageDetection get _bestDetection {
detections.sort((a, b) => b.confidence.compareTo(a.confidence));
return detections.firstOrNull ?? unknownLanguageDetection;
}
LanguageDetection bestDetection({double? threshold}) =>
_bestDetection.confidence >=
(threshold ?? languageDetectionConfidenceThreshold)
? _bestDetection
: unknownLanguageDetection;
}
class _LanguageDetectionCacheItem {
Future<LanguageDetectionResponse> data;
_LanguageDetectionCacheItem({
required this.data,
});
}
class LanguageDetectionController {
static final Map<LanguageDetectionRequest, _LanguageDetectionCacheItem>
_cache = {};
late final PangeaController _pangeaController;
Timer? _cacheClearTimer;
LanguageDetectionController(PangeaController pangeaController) {
_pangeaController = pangeaController;
_initializeCacheClearing();
}
void _initializeCacheClearing() {
const duration = Duration(minutes: 15); // Adjust the duration as needed
_cacheClearTimer = Timer.periodic(duration, (Timer t) => _clearCache());
}
void _clearCache() {
_cache.clear();
}
void dispose() {
_cacheClearTimer?.cancel();
}
Future<LanguageDetectionResponse> detectLanguage(
String fullText,
String? userL2,
String? userL1,
) async {
final LanguageDetectionRequest params = LanguageDetectionRequest(
fullText: fullText,
userL1: userL1,
userL2: userL2,
);
return get(params);
}
Future<LanguageDetectionResponse> get(
LanguageDetectionRequest params,
) async {
if (_cache.containsKey(params)) {
return _cache[params]!.data;
} else {
final Future<LanguageDetectionResponse> response = _fetchResponse(
await _pangeaController.userController.accessToken,
params,
);
_cache[params] = _LanguageDetectionCacheItem(data: response);
return response;
}
}
static Future<LanguageDetectionResponse> _fetchResponse(
String accessToken,
LanguageDetectionRequest params,
) async {
final Requests request = Requests(
choreoApiKey: Environment.choreoApiKey,
accessToken: accessToken,
);
final http.Response res = await request.post(
url: PApiUrls.languageDetection,
body: params.toJson(),
);
final Map<String, dynamic> json = jsonDecode(res.body);
return LanguageDetectionResponse.fromJson(json);
}
}