From bc3cda6ddac45cfbda403a99d4a4c0aab37886f7 Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Mon, 13 Jan 2025 15:50:46 -0500 Subject: [PATCH] feat: added ignored span cache to prevent showing match again after ignoring it (#1432) --- .../controllers/choreographer.dart | 1 + .../controllers/igc_controller.dart | 55 +++++++++++++++++-- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/lib/pangea/choreographer/controllers/choreographer.dart b/lib/pangea/choreographer/controllers/choreographer.dart index 1525b25a0..7b2797395 100644 --- a/lib/pangea/choreographer/controllers/choreographer.dart +++ b/lib/pangea/choreographer/controllers/choreographer.dart @@ -439,6 +439,7 @@ class Choreographer { throw Exception("Cannot find the ignored match in igcTextData"); } + igc.onIgnoreMatch(igc.igcTextData!.matches[matchIndex]); igc.igcTextData!.matches[matchIndex].status = PangeaMatchStatus.ignored; choreoRecord.addRecord( _textController.text, diff --git a/lib/pangea/choreographer/controllers/igc_controller.dart b/lib/pangea/choreographer/controllers/igc_controller.dart index a98a2d358..8f4eabd13 100644 --- a/lib/pangea/choreographer/controllers/igc_controller.dart +++ b/lib/pangea/choreographer/controllers/igc_controller.dart @@ -24,6 +24,26 @@ class _IGCTextDataCacheItem { _IGCTextDataCacheItem({required this.data}); } +class _IgnoredMatchCacheItem { + PangeaMatch match; + + String get spanText => match.match.fullText.substring( + match.match.offset, + match.match.offset + match.match.length, + ); + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + return other is _IgnoredMatchCacheItem && other.spanText == spanText; + } + + @override + int get hashCode => spanText.hashCode; + + _IgnoredMatchCacheItem({required this.match}); +} + class IgcController { Choreographer choreographer; IGCTextData? igcTextData; @@ -34,7 +54,9 @@ class IgcController { // cache for IGC data and prev message final Map _igcTextDataCache = {}; - Timer? _igcCacheClearTimer; + final Map _ignoredMatchCache = {}; + + Timer? _cacheClearTimer; IgcController(this.choreographer) { spanDataController = SpanDataController(choreographer); @@ -42,9 +64,11 @@ class IgcController { } void _initializeCacheClearing() { - const duration = Duration(minutes: 1); - _igcCacheClearTimer = - Timer.periodic(duration, (Timer t) => _igcTextDataCache.clear()); + const duration = Duration(minutes: 2); + _cacheClearTimer = Timer.periodic(duration, (Timer t) { + _igcTextDataCache.clear(); + _ignoredMatchCache.clear(); + }); } Future getIGCTextData({ @@ -68,7 +92,7 @@ class IgcController { prevMessages: prevMessages(), ); - if (_igcCacheClearTimer == null || !_igcCacheClearTimer!.isActive) { + if (_cacheClearTimer == null || !_cacheClearTimer!.isActive) { _initializeCacheClearing(); } @@ -102,6 +126,17 @@ class IgcController { igcTextData = igcTextDataResponse; + final List filteredMatches = List.from(igcTextData!.matches); + for (final PangeaMatch match in igcTextData!.matches) { + final _IgnoredMatchCacheItem cacheEntry = + _IgnoredMatchCacheItem(match: match); + + if (_ignoredMatchCache.containsKey(cacheEntry.hashCode)) { + filteredMatches.remove(match); + } + } + igcTextData!.matches = filteredMatches; + // TODO - for each new match, // check if existing igcTextData has one and only one match with the same error text and correction // if so, keep the original match and discard the new one @@ -138,6 +173,13 @@ class IgcController { } } + void onIgnoreMatch(PangeaMatch match) { + final cacheEntry = _IgnoredMatchCacheItem(match: match); + if (!_ignoredMatchCache.containsKey(cacheEntry.hashCode)) { + _ignoredMatchCache[cacheEntry.hashCode] = cacheEntry; + } + } + void showFirstMatch(BuildContext context) { if (igcTextData == null || igcTextData!.matches.isEmpty) { debugger(when: kDebugMode); @@ -252,6 +294,7 @@ class IgcController { dispose() { clear(); _igcTextDataCache.clear(); - _igcCacheClearTimer?.cancel(); + _ignoredMatchCache.clear(); + _cacheClearTimer?.cancel(); } }