//Possible actions/effects from cards // Nothing // useType of viewed definitions // SpanChoice of text in message from options // Call to server for additional/followup info import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../enum/span_choice_type.dart'; import '../enum/span_data_type.dart'; class SpanData { SpanData({ required this.message, required this.shortMessage, required this.choices, required this.offset, required this.length, required this.context, required this.fullText, required this.type, required this.rule, }); factory SpanData.fromJson(Map json) { final Iterable? choices = json['choices'] ?? json['replacements']; return SpanData( message: json['message'], shortMessage: json['shortMessage'] ?? json['short_message'], choices: choices ?.map( (e) => SpanChoice.fromJson(e as Map), ) .toList(), offset: json['offset'] as int, length: json['length'] as int, context: json['context'] != null ? Context.fromJson(json['context']) : null, fullText: json['sentence'] ?? json['full_text'] ?? json['fullText'] as String, type: SpanDataType.fromJson(json['type'] as Map), rule: json['rule'] != null ? Rule.fromJson(json['rule'] as Map) : null, ); } String? message; String? shortMessage; List? choices; int offset; int length; Context? context; String fullText; SpanDataType type; Rule? rule; Map toJson() => { 'message': message, 'short_message': shortMessage, 'choices': choices != null ? List.from(choices!.map((x) => x.toJson())) : null, 'offset': offset, 'length': length, 'context': context?.toJson(), 'full_text': fullText, 'type': type.toJson(), 'rule': rule?.toJson(), }; } class Context { Context({ required this.text, required this.offset, required this.length, }); factory Context.fromJson(Map json) { return Context( text: json['text'] as String, offset: json['offset'] as int, length: json['length'] as int, ); } /// full text of the message String text; int offset; int length; Map toJson() => { 'text': text, 'offset': offset, 'length': length, }; } class SpanChoice { SpanChoice({ required this.value, required this.type, this.feedback, this.selected = false, this.timestamp, }); factory SpanChoice.fromJson(Map json) { return SpanChoice( value: json['value'] as String, type: json['type'] != null ? SpanChoiceType.values.firstWhereOrNull( (element) => element.name == json['type'], ) ?? SpanChoiceType.bestCorrection : SpanChoiceType.bestCorrection, feedback: json['feedback'], selected: json['selected'] ?? false, timestamp: json['timestamp'] != null ? DateTime.parse(json['timestamp']) : null, ); } String value; SpanChoiceType type; bool selected; String? feedback; DateTime? timestamp; Map toJson() => { 'value': value, 'type': type.name, 'selected': selected, 'feedback': feedback, 'timestamp': timestamp?.toIso8601String(), }; String feedbackToDisplay(BuildContext context) { if (feedback == null) { return type.defaultFeedback(context); } return feedback!; } bool get isDistractor => type == SpanChoiceType.distractor; bool get isBestCorrection => type == SpanChoiceType.bestCorrection; Color get color => type.color; // override == operator and hashcode @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is SpanChoice && other.value == value && other.type.toString() == type.toString() && other.selected == selected && other.feedback == feedback && other.timestamp?.toIso8601String() == timestamp?.toIso8601String(); } @override int get hashCode { return Object.hashAll([ value.hashCode, type.toString().hashCode, selected.hashCode, feedback.hashCode, timestamp?.toIso8601String().hashCode, ]); } } class Rule { Rule({ required this.id, }); factory Rule.fromJson(Map json) => Rule( id: json['id'] as String, ); String id; Map toJson() => { 'id': id, }; } class SpanDataType { SpanDataType({ required this.typeName, }); factory SpanDataType.fromJson(Map json) { final String? type = json['typeName'] ?? json['type'] ?? json['type_name'] as String?; return SpanDataType( typeName: type != null ? SpanDataTypeEnum.values .firstWhereOrNull((element) => element.name == type) ?? SpanDataTypeEnum.correction : SpanDataTypeEnum.correction, ); } SpanDataTypeEnum typeName; Map toJson() => { 'type_name': typeName.name, }; }