chore: highlight selected span during IGC (#2514)
This commit is contained in:
parent
6df7b25af2
commit
9015edb5c1
7 changed files with 59 additions and 6 deletions
|
|
@ -244,6 +244,7 @@ class IgcController {
|
|||
|
||||
choreographer.chatController.inputFocus.unfocus();
|
||||
OverlayUtil.showPositionedCard(
|
||||
overlayKey: "span_card_overlay_$firstMatchIndex",
|
||||
context: context,
|
||||
cardToShow: SpanCard(
|
||||
scm: SpanCardModel(
|
||||
|
|
@ -265,6 +266,7 @@ class IgcController {
|
|||
maxHeight: match.isITStart ? 260 : 350,
|
||||
maxWidth: 350,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
onDismiss: () => choreographer.setState(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import 'package:fluffychat/pangea/events/event_wrappers/pangea_representation_ev
|
|||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/representation_content_model.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
// import 'package:language_tool/language_tool.dart';
|
||||
|
||||
|
|
@ -358,6 +359,21 @@ class IGCTextData {
|
|||
);
|
||||
}
|
||||
|
||||
int? get _openMatchIndex {
|
||||
final RegExp pattern = RegExp(r'span_card_overlay_\d+');
|
||||
final String? matchingKeys =
|
||||
MatrixState.pAnyState.getMatchingOverlayKeys(pattern).firstOrNull;
|
||||
if (matchingKeys == null) return null;
|
||||
final int? index = int.tryParse(matchingKeys.split("_").last);
|
||||
if (index == null ||
|
||||
matches.length <= index ||
|
||||
matches[index].status != PangeaMatchStatus.open) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
//PTODO - handle multitoken spans
|
||||
/// Returns a list of [TextSpan]s used to display the text in the input field
|
||||
/// with the appropriate styling for each error match.
|
||||
|
|
@ -410,7 +426,11 @@ class IGCTextData {
|
|||
getSpanItem(
|
||||
start: match.match.offset,
|
||||
end: match.match.offset + match.match.length,
|
||||
style: match.textStyle(defaultStyle),
|
||||
style: match.textStyle(
|
||||
matchIndex,
|
||||
_openMatchIndex,
|
||||
defaultStyle,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -127,9 +127,26 @@ class PangeaMatch {
|
|||
}
|
||||
}
|
||||
|
||||
TextStyle textStyle(TextStyle? existingStyle) =>
|
||||
existingStyle?.merge(IGCTextData.underlineStyle(underlineColor)) ??
|
||||
IGCTextData.underlineStyle(underlineColor);
|
||||
TextStyle textStyle(
|
||||
int matchIndex,
|
||||
int? openMatchIndex,
|
||||
TextStyle? existingStyle,
|
||||
) {
|
||||
double opacityFactor = 1.0;
|
||||
if (openMatchIndex != null && openMatchIndex != matchIndex) {
|
||||
opacityFactor = 0.5;
|
||||
}
|
||||
|
||||
final int alpha = (255 * opacityFactor).round();
|
||||
return existingStyle?.merge(
|
||||
IGCTextData.underlineStyle(
|
||||
underlineColor.withAlpha(alpha),
|
||||
),
|
||||
) ??
|
||||
IGCTextData.underlineStyle(
|
||||
underlineColor.withAlpha(alpha),
|
||||
);
|
||||
}
|
||||
|
||||
PangeaMatch get copyWith => PangeaMatch.fromJson(toJson());
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ class PangeaTextController extends TextEditingController {
|
|||
|
||||
if (cardToShow != null) {
|
||||
OverlayUtil.showPositionedCard(
|
||||
overlayKey: matchIndex != -1 ? "span_card_overlay_$matchIndex" : null,
|
||||
context: context,
|
||||
maxHeight: matchIndex != -1 &&
|
||||
choreographer.igc.igcTextData!.matches[matchIndex].isITStart
|
||||
|
|
@ -128,6 +129,7 @@ class PangeaTextController extends TextEditingController {
|
|||
maxWidth: 350,
|
||||
cardToShow: cardToShow,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
onDismiss: () => choreographer.setState(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ class WordMatchContent extends StatelessWidget {
|
|||
botExpression: controller.error == null
|
||||
? controller.currentExpression
|
||||
: BotExpression.addled,
|
||||
onClose: () => controller.widget.scm.choreographer.setState(),
|
||||
),
|
||||
Scrollbar(
|
||||
controller: scrollController,
|
||||
|
|
|
|||
|
|
@ -107,6 +107,15 @@ class PangeaAnyState {
|
|||
bool isOverlayOpen(String overlayKey) {
|
||||
return entries.any((element) => element.key == overlayKey);
|
||||
}
|
||||
|
||||
List<String> getMatchingOverlayKeys(RegExp regex) {
|
||||
return entries
|
||||
.where((e) => e.key != null)
|
||||
.where((element) => regex.hasMatch(element.key!))
|
||||
.map((e) => e.key)
|
||||
.whereType<String>()
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
class LayerLinkAndKey {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class OverlayUtil {
|
|||
Color? borderColor,
|
||||
Color? backgroundColor,
|
||||
bool closePrevOverlay = true,
|
||||
Function? onDismiss,
|
||||
VoidCallback? onDismiss,
|
||||
OverlayPositionEnum position = OverlayPositionEnum.transform,
|
||||
Offset? offset,
|
||||
String? overlayKey,
|
||||
|
|
@ -117,6 +117,7 @@ class OverlayUtil {
|
|||
String? overlayKey,
|
||||
bool isScrollable = true,
|
||||
bool addBorder = true,
|
||||
VoidCallback? onDismiss,
|
||||
}) {
|
||||
try {
|
||||
final LayerLinkAndKey layerLinkAndKey =
|
||||
|
|
@ -192,6 +193,7 @@ class OverlayUtil {
|
|||
hasTopOverflow ? Alignment.bottomCenter : Alignment.topCenter,
|
||||
followerAnchor:
|
||||
hasTopOverflow ? Alignment.topCenter : Alignment.bottomCenter,
|
||||
onDismiss: onDismiss,
|
||||
);
|
||||
} catch (err, stack) {
|
||||
debugger(when: kDebugMode);
|
||||
|
|
@ -208,7 +210,7 @@ class OverlayUtil {
|
|||
|
||||
class TransparentBackdrop extends StatefulWidget {
|
||||
final Color? backgroundColor;
|
||||
final Function? onDismiss;
|
||||
final VoidCallback? onDismiss;
|
||||
final bool blurBackground;
|
||||
|
||||
const TransparentBackdrop({
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue