From 0fcc119c9a0c4fc35b7b7f7a532217e1326c94a4 Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:25:34 -0500 Subject: [PATCH] improved logging for acceptReplacement index error (#1245) * improved logging for acceptReplacement index error * replace flutter_html package with fork with fix for safari regex * better logging for cast error in PracticeActivityModel.fromJson --- lib/pages/chat/events/html_message.dart | 6 ++- lib/pangea/models/igc_text_data_model.dart | 51 +++++++++++++++---- .../practice_activity_model.dart | 12 ++++- .../widgets/igc/pangea_text_controller.dart | 13 +++-- pubspec.lock | 33 ++---------- pubspec.yaml | 11 +++- 6 files changed, 77 insertions(+), 49 deletions(-) diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index 3ebf6dfae..73876ab55 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_highlighter/flutter_highlighter.dart'; import 'package:flutter_highlighter/themes/shades-of-purple.dart'; import 'package:flutter_html/flutter_html.dart'; -import 'package:flutter_html_table/flutter_html_table.dart'; +// import 'package:flutter_html_table/flutter_html_table.dart'; import 'package:flutter_math_fork/flutter_math.dart'; import 'package:html/dom.dart' as dom; import 'package:linkify/linkify.dart'; @@ -167,7 +167,9 @@ class HtmlMessage extends StatelessWidget { MatrixMathExtension( style: TextStyle(fontSize: fontSize, color: textColor), ), - const TableHtmlExtension(), + // #Pangea + // const TableHtmlExtension(), + // Pangea# SpoilerExtension(textColor: textColor), const ImageExtension(), FontColorExtension(), diff --git a/lib/pangea/models/igc_text_data_model.dart b/lib/pangea/models/igc_text_data_model.dart index b2e05d0b0..d6a8ac999 100644 --- a/lib/pangea/models/igc_text_data_model.dart +++ b/lib/pangea/models/igc_text_data_model.dart @@ -139,16 +139,41 @@ class IGCTextData { replacement.value, ); + int startIndex; + int endIndex; + // replace the tokens that are part of the match // with the tokens in the replacement // start is inclusive - final startIndex = tokenIndexByOffset(pangeaMatch.match.offset); - // end is exclusive, hence the +1 - // use pangeaMatch.matchContent.trim().length instead of pangeaMatch.match.length since pangeaMatch.match.length may include leading/trailing spaces - final endIndex = tokenIndexByOffset( - pangeaMatch.match.offset + pangeaMatch.matchContent.trim().length, - ) + - 1; + try { + startIndex = tokenIndexByOffset(pangeaMatch.match.offset); + // end is exclusive, hence the +1 + // use pangeaMatch.matchContent.trim().length instead of pangeaMatch.match.length since pangeaMatch.match.length may include leading/trailing spaces + endIndex = tokenIndexByOffset( + pangeaMatch.match.offset + pangeaMatch.matchContent.trim().length, + ) + + 1; + } catch (err, s) { + matches.removeAt(matchIndex); + + for (final match in matches) { + match.match.fullText = originalInput; + if (match.match.offset > pangeaMatch.match.offset) { + match.match.offset += + replacement.value.length - pangeaMatch.match.length; + } + } + ErrorHandler.logError( + e: err, + s: s, + data: { + "cursorOffset": pangeaMatch.match.offset, + "match": pangeaMatch.match.toJson(), + "tokens": tokens.map((e) => e.toJson()).toString(), + }, + ); + return; + } // for all tokens after the replacement, update their offsets for (int i = endIndex; i < tokens.length; i++) { @@ -199,9 +224,15 @@ class IGCTextData { } } - int tokenIndexByOffset(int cursorOffset) => tokens.indexWhere( - (token) => token.start <= cursorOffset && cursorOffset <= token.end, - ); + int tokenIndexByOffset(int cursorOffset) { + final tokenIndex = tokens.indexWhere( + (token) => token.start <= cursorOffset && cursorOffset <= token.end, + ); + if (tokenIndex < 0) { + throw "No token found for cursor offset"; + } + return tokenIndex; + } List matchIndicesByOffset(int offset) { final List matchesForOffset = []; diff --git a/lib/pangea/models/practice_activities.dart/practice_activity_model.dart b/lib/pangea/models/practice_activities.dart/practice_activity_model.dart index a6bbb4b65..ae1644afe 100644 --- a/lib/pangea/models/practice_activities.dart/practice_activity_model.dart +++ b/lib/pangea/models/practice_activities.dart/practice_activity_model.dart @@ -253,9 +253,17 @@ class PracticeActivityModel { throw ("lang_code is not a string in PracticeActivityModel.fromJson"); } + final targetConstructsEntry = + json['tgt_constructs'] ?? json['target_constructs']; + if (targetConstructsEntry is! List) { + Sentry.addBreadcrumb( + Breadcrumb(data: {"json": json}), + ); + throw ("tgt_constructs is not a list in PracticeActivityModel.fromJson"); + } + return PracticeActivityModel( - tgtConstructs: ((json['tgt_constructs'] ?? json['target_constructs']) - as List) + tgtConstructs: targetConstructsEntry .map((e) => ConstructIdentifier.fromJson(e as Map)) .toList(), langCode: json['lang_code'] as String, diff --git a/lib/pangea/widgets/igc/pangea_text_controller.dart b/lib/pangea/widgets/igc/pangea_text_controller.dart index a8ad07d71..15258667d 100644 --- a/lib/pangea/widgets/igc/pangea_text_controller.dart +++ b/lib/pangea/widgets/igc/pangea_text_controller.dart @@ -77,11 +77,14 @@ class PangeaTextController extends TextEditingController { return; } - final int tokenIndex = choreographer.igc.igcTextData!.tokenIndexByOffset( - selection.baseOffset, - ); - - if (tokenIndex == -1) return; + int tokenIndex; + try { + tokenIndex = choreographer.igc.igcTextData!.tokenIndexByOffset( + selection.baseOffset, + ); + } catch (_) { + return; + } final int matchIndex = choreographer.igc.igcTextData!.getTopMatchIndexForOffset( diff --git a/pubspec.lock b/pubspec.lock index b7ee77fba..de1e51f4a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -693,18 +693,11 @@ packages: flutter_html: dependency: "direct main" description: - name: flutter_html - sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee" - url: "https://pub.dev" - source: hosted - version: "3.0.0-beta.2" - flutter_html_table: - dependency: "direct main" - description: - name: flutter_html_table - sha256: e20c72d67ea2512e7b4949f6f7dd13d004e773b0f82c586a21f895e6bd90383c - url: "https://pub.dev" - source: hosted + path: "." + ref: master + resolved-ref: e07b904d70a98d678882ac5c4c2da896a67a688c + url: "https://github.com/SherpaMiguel/flutter_html" + source: git version: "3.0.0-beta.2" flutter_keyboard_visibility: dependency: transitive @@ -754,14 +747,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" - flutter_layout_grid: - dependency: transitive - description: - name: flutter_layout_grid - sha256: "88b4f8484a0874962e27c47733ad256aeb26acc694a9f029edbef771d301885a" - url: "https://pub.dev" - source: hosted - version: "2.0.7" flutter_linkify: dependency: "direct main" description: @@ -1941,14 +1926,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - quiver: - dependency: transitive - description: - name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 - url: "https://pub.dev" - source: hosted - version: "3.2.1" random_string: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 6a922745b..dadde5725 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,8 +41,15 @@ dependencies: flutter_cache_manager: ^3.4.1 flutter_foreground_task: ^6.1.3 flutter_highlighter: ^0.1.1 - flutter_html: ^3.0.0-beta.2 - flutter_html_table: ^3.0.0-beta.2 + # #Pangea + # Fix for https://github.com/Sub6Resources/flutter_html/issues/1314 + # flutter_html: ^3.0.0-beta.2 + flutter_html: + git: + url: https://github.com/SherpaMiguel/flutter_html + ref: master + # flutter_html_table: ^3.0.0-beta.2 + # Pangea# flutter_linkify: ^6.0.0 flutter_local_notifications: ^17.2.3 flutter_localizations: