Merge branch 'main' into power-level-hotfix

This commit is contained in:
ggurdin 2024-06-12 14:40:07 -04:00 committed by GitHub
commit 8f557f7740
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 109 additions and 26 deletions

View file

@ -19,14 +19,37 @@ import '../../repo/tokens_repo.dart';
import '../../utils/error_handler.dart';
import '../../utils/overlay.dart';
class _SpanDetailsCacheItem {
SpanDetailsRepoReqAndRes data;
_SpanDetailsCacheItem({required this.data});
}
class IgcController {
Choreographer choreographer;
IGCTextData? igcTextData;
Object? igcError;
Completer<IGCTextData> igcCompleter = Completer();
final Map<int, _SpanDetailsCacheItem> _cache = {};
Timer? _cacheClearTimer;
IgcController(this.choreographer);
IgcController(this.choreographer) {
_initializeCacheClearing();
}
void _initializeCacheClearing() {
const duration = Duration(minutes: 2);
_cacheClearTimer = Timer.periodic(duration, (Timer t) => _clearCache());
}
void _clearCache() {
_cache.clear();
}
void dispose() {
_cacheClearTimer?.cancel();
}
Future<void> getIGCTextData({required bool tokensOnly}) async {
try {
@ -80,6 +103,14 @@ class IgcController {
igcTextData = igcTextDataResponse;
// After fetching igc data, pre-call span details for each match optimistically.
// This will make the loading of span details faster for the user
if (igcTextData?.matches.isNotEmpty ?? false) {
for (int i = 0; i < igcTextData!.matches.length; i++) {
getSpanDetails(i);
}
}
debugPrint("igc text ${igcTextData.toString()}");
} catch (err, stack) {
debugger(when: kDebugMode);
@ -99,18 +130,38 @@ class IgcController {
debugger(when: kDebugMode);
return;
}
final SpanData span = igcTextData!.matches[matchIndex].match;
final SpanDetailsRepoReqAndRes response = await SpanDataRepo.getSpanDetails(
await choreographer.accessToken,
request: SpanDetailsRepoReqAndRes(
userL1: choreographer.l1LangCode!,
userL2: choreographer.l2LangCode!,
enableIGC: choreographer.igcEnabled,
enableIT: choreographer.itEnabled,
span: span,
),
/// Retrieves the span data from the `igcTextData` matches at the specified `matchIndex`.
/// Creates a `SpanDetailsRepoReqAndRes` object with the retrieved span data and other parameters.
/// Generates a cache key based on the created `SpanDetailsRepoReqAndRes` object.
final SpanData span = igcTextData!.matches[matchIndex].match;
final req = SpanDetailsRepoReqAndRes(
userL1: choreographer.l1LangCode!,
userL2: choreographer.l2LangCode!,
enableIGC: choreographer.igcEnabled,
enableIT: choreographer.itEnabled,
span: span,
);
final int cacheKey = req.hashCode;
/// Retrieves the [SpanDetailsRepoReqAndRes] response from the cache if it exists,
/// otherwise makes an API call to get the response and stores it in the cache.
SpanDetailsRepoReqAndRes response;
if (_cache.containsKey(cacheKey)) {
response = _cache[cacheKey]!.data;
} else {
response = await SpanDataRepo.getSpanDetails(
await choreographer.accessToken,
request: SpanDetailsRepoReqAndRes(
userL1: choreographer.l1LangCode!,
userL2: choreographer.l2LangCode!,
enableIGC: choreographer.igcEnabled,
enableIT: choreographer.itEnabled,
span: span,
),
);
_cache[cacheKey] = _SpanDetailsCacheItem(data: response);
}
try {
igcTextData!.matches[matchIndex].match = response.span;

View file

@ -72,6 +72,24 @@ class SpanDetailsRepoReqAndRes {
enableIGC: json['enable_igc'] as bool,
span: SpanData.fromJson(json['span']),
);
/// Overrides the equality operator to compare two [SpanDetailsRepoReqAndRes] objects.
/// Returns true if the objects are identical or have the same property
/// values (based on the results of the toJson function), false otherwise.
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other is! SpanDetailsRepoReqAndRes) return false;
return toJson().toString() == other.toJson().toString();
}
/// Overrides the hashCode getter to generate a hash code for the [SpanDetailsRepoReqAndRes] object.
/// Used as keys in response cache in igc_controller.
@override
int get hashCode {
return toJson().toString().hashCode;
}
}
final spanDataRepomockSpan = SpanData(

View file

@ -59,6 +59,7 @@ class ToolbarDisplayController {
}
void showToolbar(BuildContext context, {MessageMode? mode}) {
bool toolbarUp = true;
if (highlighted) return;
if (controller.selectMode) {
controller.clearSelectedEvents();
@ -76,8 +77,22 @@ class ToolbarDisplayController {
if (targetRenderBox != null) {
final Size transformTargetSize = (targetRenderBox as RenderBox).size;
messageWidth = transformTargetSize.width;
final Offset targetOffset = (targetRenderBox).localToGlobal(Offset.zero);
final double screenHeight = MediaQuery.of(context).size.height;
toolbarUp = targetOffset.dy >= screenHeight / 2;
}
final Widget overlayMessage = OverlayMessage(
pangeaMessageEvent.event,
timeline: pangeaMessageEvent.timeline,
immersionMode: immersionMode,
ownMessage: pangeaMessageEvent.ownMessage,
toolbarController: this,
width: messageWidth,
nextEvent: nextEvent,
previousEvent: previousEvent,
);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Widget overlayEntry;
if (toolbar == null) return;
@ -88,18 +103,9 @@ class ToolbarDisplayController {
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: [
toolbar!,
toolbarUp ? toolbar! : overlayMessage,
const SizedBox(height: 6),
OverlayMessage(
pangeaMessageEvent.event,
timeline: pangeaMessageEvent.timeline,
immersionMode: immersionMode,
ownMessage: pangeaMessageEvent.ownMessage,
toolbarController: this,
width: messageWidth,
nextEvent: nextEvent,
previousEvent: previousEvent,
),
toolbarUp ? overlayMessage : toolbar!,
],
);
} catch (err) {
@ -113,11 +119,19 @@ class ToolbarDisplayController {
child: overlayEntry,
transformTargetId: targetId,
targetAnchor: pangeaMessageEvent.ownMessage
? Alignment.bottomRight
: Alignment.bottomLeft,
? toolbarUp
? Alignment.bottomRight
: Alignment.topRight
: toolbarUp
? Alignment.bottomLeft
: Alignment.topLeft,
followerAnchor: pangeaMessageEvent.ownMessage
? Alignment.bottomRight
: Alignment.bottomLeft,
? toolbarUp
? Alignment.bottomRight
: Alignment.topRight
: toolbarUp
? Alignment.bottomLeft
: Alignment.topLeft,
backgroundColor: const Color.fromRGBO(0, 0, 0, 1).withAlpha(100),
);