1407 bring back locking of tools (#1408)
* dev: clean up isActivityBasicallyEligible and shouldDoActivity defs * feat: bring back locking of tools and highlight words with meaning activities * fix: exclude tokens that are not relevant for meaning activities from proportionOfActivitiesCompleted computation * fix: show yellow if token meaning activity has been done but shouldDoActivity is true --------- Co-authored-by: ggurdin <ggurdin@gmail.com>
This commit is contained in:
parent
bbc791b314
commit
02050d3006
32 changed files with 223 additions and 112 deletions
|
|
@ -1,3 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pages/chat/chat.dart';
|
||||
|
|
@ -11,9 +16,6 @@ import 'package:fluffychat/utils/account_config.dart';
|
|||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
|
||||
class ChatEventList extends StatelessWidget {
|
||||
final ChatController controller;
|
||||
|
|
|
|||
|
|
@ -154,8 +154,13 @@ class Message extends StatelessWidget {
|
|||
previousEvent!.senderId == event.senderId &&
|
||||
previousEvent!.originServerTs.sameEnvironment(event.originServerTs);
|
||||
|
||||
final textColor =
|
||||
ownMessage ? theme.colorScheme.onPrimary : theme.colorScheme.onSurface;
|
||||
final textColor = ownMessage
|
||||
?
|
||||
// #Pangea
|
||||
// theme.colorScheme.onPrimary
|
||||
ThemeData.dark().colorScheme.onPrimary
|
||||
// Pangea#
|
||||
: theme.colorScheme.onSurface;
|
||||
final rowMainAxisAlignment =
|
||||
ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start;
|
||||
|
||||
|
|
@ -189,7 +194,13 @@ class Message extends StatelessWidget {
|
|||
if (ownMessage) {
|
||||
color = displayEvent.status.isError
|
||||
? Colors.redAccent
|
||||
: theme.colorScheme.primary;
|
||||
// #Pangea
|
||||
// : ThemeData.dark().colorScheme.primary;
|
||||
: Color.alphaBlend(
|
||||
Colors.white.withAlpha(180),
|
||||
ThemeData.dark().colorScheme.primary,
|
||||
);
|
||||
// Pangea#
|
||||
}
|
||||
|
||||
final resetAnimateIn = this.resetAnimateIn;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/controllers/it_controller.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/it_bar_buttons.dart';
|
||||
|
|
@ -14,9 +17,6 @@ import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'
|
|||
import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/widgets/animations/gain_points.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../controllers/it_feedback_controller.dart';
|
||||
import '../../models/it_response_model.dart';
|
||||
import '../../utils/overlay.dart';
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_show_popup.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../widgets/common/bot_face_svg.dart';
|
||||
import '../controllers/choreographer.dart';
|
||||
import '../controllers/it_controller.dart';
|
||||
|
|
|
|||
|
|
@ -220,6 +220,8 @@ IconData getIconForMorphFeature(String feature) {
|
|||
return Icons.check_circle_outline;
|
||||
case 'prepcase':
|
||||
return Icons.location_on_outlined;
|
||||
case 'conjtype':
|
||||
return Icons.compare_arrows;
|
||||
default:
|
||||
debugger(when: kDebugMode);
|
||||
return Icons.help_outline;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@ import 'dart:async';
|
|||
import 'dart:developer';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/bot_mode.dart';
|
||||
import 'package:fluffychat/pangea/constants/class_default_values.dart';
|
||||
import 'package:fluffychat/pangea/constants/pangea_event_types.dart';
|
||||
|
|
@ -26,10 +31,6 @@ import 'package:fluffychat/pangea/models/bot_options_model.dart';
|
|||
import 'package:fluffychat/pangea/utils/bot_name.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import '../../config/app_config.dart';
|
||||
import '../utils/firebase_analytics.dart';
|
||||
import '../utils/p_store.dart';
|
||||
|
|
|
|||
|
|
@ -81,23 +81,34 @@ extension MessageModeExtension on MessageMode {
|
|||
}
|
||||
|
||||
bool isUnlocked(
|
||||
int index,
|
||||
int numActivitiesCompleted,
|
||||
double proportionOfActivitiesCompleted,
|
||||
bool totallyDone,
|
||||
) =>
|
||||
numActivitiesCompleted >= index || totallyDone;
|
||||
) {
|
||||
if (totallyDone) return true;
|
||||
|
||||
switch (this) {
|
||||
case MessageMode.translation:
|
||||
return proportionOfActivitiesCompleted >= 1;
|
||||
case MessageMode.textToSpeech:
|
||||
return proportionOfActivitiesCompleted >= 0.5;
|
||||
case MessageMode.speechToText:
|
||||
case MessageMode.practiceActivity:
|
||||
case MessageMode.wordZoom:
|
||||
case MessageMode.noneSelected:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool get showButton => this != MessageMode.practiceActivity;
|
||||
|
||||
Color iconButtonColor(
|
||||
BuildContext context,
|
||||
int index,
|
||||
MessageMode currentMode,
|
||||
int numActivitiesCompleted,
|
||||
double proportionOfActivitiesUnlocked,
|
||||
bool totallyDone,
|
||||
) {
|
||||
//locked
|
||||
if (!isUnlocked(index, numActivitiesCompleted, totallyDone)) {
|
||||
if (!isUnlocked(proportionOfActivitiesUnlocked, totallyDone)) {
|
||||
return barAndLockedButtonColor(context);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,18 @@ import 'dart:async';
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:html_unescape/html_unescape.dart';
|
||||
import 'package:matrix/matrix.dart' as matrix;
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix/src/utils/markdown.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/bot_mode.dart';
|
||||
import 'package:fluffychat/pangea/constants/class_code_constants.dart';
|
||||
import 'package:fluffychat/pangea/constants/class_default_values.dart';
|
||||
|
|
@ -21,15 +31,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:html_unescape/html_unescape.dart';
|
||||
import 'package:matrix/matrix.dart' as matrix;
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix/src/utils/markdown.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import '../../../config/app_config.dart';
|
||||
import '../../constants/pangea_event_types.dart';
|
||||
import '../../models/choreo_record.dart';
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
enum InstructionsEnum {
|
||||
itInstructions,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class InstructionsInlineTooltip extends StatefulWidget {
|
||||
final InstructionsEnum instructionsEnum;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_toggle.dart';
|
||||
import 'package:fluffychat/pangea/utils/bot_style.dart';
|
||||
|
|
@ -5,8 +9,6 @@ import 'package:fluffychat/pangea/utils/overlay.dart';
|
|||
import 'package:fluffychat/pangea/widgets/common/bot_face_svg.dart';
|
||||
import 'package:fluffychat/pangea/widgets/igc/card_header.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
/// Instruction Card gives users tips on
|
||||
/// how to use Pangea Chat's features
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
/// User can toggle on to prevent Instruction Card
|
||||
/// from appearing in future sessions
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:sentry_flutter/sentry_flutter.dart';
|
|||
|
||||
import 'package:fluffychat/pangea/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/controllers/text_to_speech_controller.dart';
|
||||
import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/enum/audio_encoding_enum.dart';
|
||||
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_representation_event.dart';
|
||||
import 'package:fluffychat/pangea/matrix_event_wrappers/practice_activity_event.dart';
|
||||
|
|
@ -560,9 +561,43 @@ class PangeaMessageEvent {
|
|||
// return practiceActivities.any((activity) => !(activity.isComplete));
|
||||
// }
|
||||
|
||||
int get numberOfActivitiesCompleted {
|
||||
return MatrixState.pangeaController.activityRecordController
|
||||
.getCompletedActivityCount(eventId);
|
||||
/// value from 0 to 1 indicating the proportion of activities completed
|
||||
double get proportionOfActivitiesCompleted {
|
||||
if (messageDisplayRepresentation == null ||
|
||||
messageDisplayRepresentation?.tokens == null) {
|
||||
return 1;
|
||||
}
|
||||
final int total = messageDisplayRepresentation!.tokens!
|
||||
.where(
|
||||
(token) =>
|
||||
token.isActivityBasicallyEligible(ActivityTypeEnum.wordMeaning),
|
||||
)
|
||||
.length;
|
||||
|
||||
final int toDo = messageDisplayRepresentation!.tokens!
|
||||
.where(
|
||||
(token) =>
|
||||
token.didActivitySuccessfully(ActivityTypeEnum.wordMeaning),
|
||||
)
|
||||
.length;
|
||||
|
||||
final double proportion =
|
||||
(total - toDo) / messageDisplayRepresentation!.tokens!.length;
|
||||
|
||||
if (proportion < 0) {
|
||||
debugger(when: kDebugMode);
|
||||
ErrorHandler.logError(
|
||||
m: "proportion of activities completed is less than 0",
|
||||
data: {
|
||||
"proportion": proportion,
|
||||
"total": total,
|
||||
"toDo": toDo,
|
||||
"tokens": messageDisplayRepresentation!.tokens,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return proportion;
|
||||
}
|
||||
|
||||
String? get l2Code =>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
import 'dart:developer';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/language_constants.dart';
|
||||
import 'package:fluffychat/pangea/constants/pangea_event_types.dart';
|
||||
import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
|
||||
|
|
@ -16,9 +20,6 @@ import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_repo.dart';
|
|||
import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import '../constants/model_keys.dart';
|
||||
import 'lemma.dart';
|
||||
|
||||
|
|
@ -210,7 +211,10 @@ class PangeaToken {
|
|||
);
|
||||
}
|
||||
|
||||
bool _isActivityBasicallyEligible(ActivityTypeEnum a) {
|
||||
bool isActivityBasicallyEligible(ActivityTypeEnum a) {
|
||||
if (!lemma.saveVocab) {
|
||||
return false;
|
||||
}
|
||||
switch (a) {
|
||||
case ActivityTypeEnum.wordMeaning:
|
||||
return canBeDefined;
|
||||
|
|
@ -258,7 +262,7 @@ class PangeaToken {
|
|||
// }
|
||||
// }
|
||||
|
||||
bool _didActivitySuccessfully(
|
||||
bool didActivitySuccessfully(
|
||||
ActivityTypeEnum a, [
|
||||
String? morphFeature,
|
||||
String? morphTag,
|
||||
|
|
@ -308,7 +312,7 @@ class PangeaToken {
|
|||
return false;
|
||||
}
|
||||
case ActivityTypeEnum.wordFocusListening:
|
||||
return !_didActivitySuccessfully(a) || daysSinceLastUseByType(a) > 30;
|
||||
return !didActivitySuccessfully(a) || daysSinceLastUseByType(a) > 30;
|
||||
case ActivityTypeEnum.hiddenWordListening:
|
||||
return daysSinceLastUseByType(a) > 7;
|
||||
case ActivityTypeEnum.lemmaId:
|
||||
|
|
@ -402,8 +406,7 @@ class PangeaToken {
|
|||
required String? feature,
|
||||
required String? tag,
|
||||
}) {
|
||||
return lemma.saveVocab &&
|
||||
_isActivityBasicallyEligible(a) &&
|
||||
return isActivityBasicallyEligible(a) &&
|
||||
_isActivityProbablyLevelAppropriate(a, feature, tag);
|
||||
}
|
||||
|
||||
|
|
@ -428,13 +431,13 @@ class PangeaToken {
|
|||
.getConstructUses(
|
||||
ConstructIdentifier(
|
||||
lemma: lemma.text,
|
||||
type: ConstructTypeEnum.morph,
|
||||
type: ConstructTypeEnum.vocab,
|
||||
category: pos,
|
||||
),
|
||||
) ??
|
||||
ConstructUses(
|
||||
lemma: lemma.text,
|
||||
constructType: ConstructTypeEnum.morph,
|
||||
constructType: ConstructTypeEnum.vocab,
|
||||
category: pos,
|
||||
uses: [],
|
||||
);
|
||||
|
|
@ -604,10 +607,10 @@ class PangeaToken {
|
|||
}
|
||||
|
||||
String get xpEmoji {
|
||||
if (xp < 30) {
|
||||
if (vocabConstruct.points < 30) {
|
||||
// bean emoji
|
||||
return "🫛";
|
||||
} else if (xp < 100) {
|
||||
} else if (vocabConstruct.points < 100) {
|
||||
// sprout emoji
|
||||
return "🌱";
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/enum/activity_display_instructions_enum.dart';
|
||||
import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/enum/analytics/morph_categories_enum.dart';
|
||||
|
|
@ -8,10 +14,6 @@ import 'package:fluffychat/pangea/enum/construct_type_enum.dart';
|
|||
import 'package:fluffychat/pangea/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/models/practice_activities.dart/multiple_choice_activity_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class ConstructIdentifier {
|
||||
final String lemma;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instruction_settings.dart';
|
||||
import 'package:fluffychat/pangea/models/space_model.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'language_model.dart';
|
||||
|
||||
/// The user's settings learning settings.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/models/content_feedback.dart';
|
||||
import 'package:fluffychat/pangea/network/urls.dart';
|
||||
import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart';
|
||||
import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_response.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../config/environment.dart';
|
||||
import '../../network/requests.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/enum/construct_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/models/practice_activities.dart/message_activity_request.dart';
|
||||
|
|
@ -5,8 +9,6 @@ import 'package:fluffychat/pangea/models/practice_activities.dart/multiple_choic
|
|||
import 'package:fluffychat/pangea/models/practice_activities.dart/practice_activity_model.dart';
|
||||
import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_repo.dart';
|
||||
import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class WordMeaningActivityGenerator {
|
||||
Future<MessageActivityResponse> get(
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ class MessageTextUtil {
|
|||
start: globalIndex,
|
||||
end: startIndex,
|
||||
hideContent: false,
|
||||
highlight:
|
||||
(isSelected?.call(token) ?? false) && !hasHiddenContent,
|
||||
selected: (isSelected?.call(token) ?? false) && !hasHiddenContent,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -58,7 +57,7 @@ class MessageTextUtil {
|
|||
end: endIndex,
|
||||
token: token,
|
||||
hideContent: hideContent,
|
||||
highlight: (isSelected?.call(token) ?? false) &&
|
||||
selected: (isSelected?.call(token) ?? false) &&
|
||||
!hideContent &&
|
||||
!hasHiddenContent,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
int get activitiesLeftToComplete => messageAnalyticsEntry?.numActivities ?? 0;
|
||||
|
||||
bool get isPracticeComplete =>
|
||||
activitiesLeftToComplete <= 0 || !messageInUserL2;
|
||||
(pangeaMessageEvent?.proportionOfActivitiesCompleted ?? 1) >= 1 ||
|
||||
!messageInUserL2;
|
||||
|
||||
/// Decides whether an _initialSelectedToken should be used
|
||||
/// for a first practice activity on the word meaning
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart';
|
||||
|
|
@ -10,12 +17,6 @@ import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator
|
|||
import 'package:fluffychat/pangea/widgets/common/icon_number_widget.dart';
|
||||
import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
import '../../utils/bot_style.dart';
|
||||
|
||||
class MessageSpeechToTextCard extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ import 'package:flutter/material.dart';
|
|||
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/controllers/message_analytics_controller.dart';
|
||||
import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/message_text_util.dart';
|
||||
|
|
@ -69,7 +71,7 @@ class MessageTokenText extends StatelessWidget {
|
|||
class TokenPosition {
|
||||
final int start;
|
||||
final int end;
|
||||
final bool highlight;
|
||||
final bool selected;
|
||||
final bool hideContent;
|
||||
final PangeaToken? token;
|
||||
|
||||
|
|
@ -77,7 +79,7 @@ class TokenPosition {
|
|||
required this.start,
|
||||
required this.end,
|
||||
required this.hideContent,
|
||||
required this.highlight,
|
||||
required this.selected,
|
||||
this.token,
|
||||
});
|
||||
}
|
||||
|
|
@ -176,6 +178,19 @@ class MessageTextWidget extends StatelessWidget {
|
|||
text: TextSpan(
|
||||
children:
|
||||
tokenPositions.mapIndexed((int i, TokenPosition tokenPosition) {
|
||||
final shouldDo = tokenPosition.token?.shouldDoActivity(
|
||||
a: ActivityTypeEnum.wordMeaning,
|
||||
feature: null,
|
||||
tag: null,
|
||||
) ??
|
||||
false;
|
||||
|
||||
final didMeaningActivity =
|
||||
tokenPosition.token?.didActivitySuccessfully(
|
||||
ActivityTypeEnum.wordMeaning,
|
||||
) ??
|
||||
true;
|
||||
|
||||
final substring = messageCharacters
|
||||
.skip(tokenPosition.start)
|
||||
.take(tokenPosition.end - tokenPosition.start)
|
||||
|
|
@ -199,11 +214,13 @@ class MessageTextWidget extends StatelessWidget {
|
|||
text: substring,
|
||||
style: style.merge(
|
||||
TextStyle(
|
||||
backgroundColor: tokenPosition.highlight
|
||||
? Theme.of(context).brightness == Brightness.light
|
||||
? Colors.black.withAlpha(100)
|
||||
: Colors.white.withAlpha(100)
|
||||
: Colors.transparent,
|
||||
backgroundColor: tokenPosition.selected
|
||||
? AppConfig.primaryColor.withAlpha(80)
|
||||
: (isSelected != null && shouldDo)
|
||||
? !didMeaningActivity
|
||||
? AppConfig.success.withAlpha(60)
|
||||
: AppConfig.gold.withAlpha(60)
|
||||
: Colors.transparent,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ class ToolbarButtons extends StatelessWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
int? get activitiesCompleted =>
|
||||
overlayController.pangeaMessageEvent?.numberOfActivitiesCompleted;
|
||||
double? get proportionOfActivitiesCompleted =>
|
||||
overlayController.pangeaMessageEvent?.proportionOfActivitiesCompleted;
|
||||
|
||||
List<MessageMode> get modes => MessageMode.values
|
||||
.where((mode) => mode.shouldShowAsToolbarButton(event))
|
||||
|
|
@ -62,7 +62,7 @@ class ToolbarButtons extends StatelessWidget {
|
|||
height: 12,
|
||||
width: overlayController.isPracticeComplete
|
||||
? width
|
||||
: min(width, (width / 2) * activitiesCompleted!),
|
||||
: min(width, width * proportionOfActivitiesCompleted!),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
color: AppConfig.success,
|
||||
|
|
@ -76,15 +76,13 @@ class ToolbarButtons extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: modes.mapIndexed((index, mode) {
|
||||
final enabled = mode.isUnlocked(
|
||||
index,
|
||||
activitiesCompleted!,
|
||||
proportionOfActivitiesCompleted!,
|
||||
overlayController.isPracticeComplete,
|
||||
);
|
||||
final color = mode.iconButtonColor(
|
||||
context,
|
||||
index,
|
||||
overlayController.toolbarMode,
|
||||
activitiesCompleted!,
|
||||
proportionOfActivitiesCompleted!,
|
||||
overlayController.isPracticeComplete,
|
||||
);
|
||||
return mode.showButton
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart';
|
||||
|
|
@ -9,7 +11,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|||
import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart';
|
||||
import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MessageTranslationCard extends StatefulWidget {
|
||||
final PangeaMessageEvent messageEvent;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,10 @@ class OverlayMessage extends StatelessWidget {
|
|||
if (ownMessage) {
|
||||
color = displayEvent.status.isError
|
||||
? Colors.redAccent
|
||||
: theme.colorScheme.primary;
|
||||
: Color.alphaBlend(
|
||||
Colors.white.withAlpha(180),
|
||||
ThemeData.dark().colorScheme.primary,
|
||||
);
|
||||
}
|
||||
|
||||
final noBubble = {
|
||||
|
|
@ -96,8 +99,9 @@ class OverlayMessage extends StatelessWidget {
|
|||
MessageTypes.Audio,
|
||||
}.contains(event.messageType);
|
||||
|
||||
final textColor =
|
||||
ownMessage ? theme.colorScheme.onPrimary : theme.colorScheme.onSurface;
|
||||
final textColor = ownMessage
|
||||
? ThemeData.dark().colorScheme.onPrimary
|
||||
: theme.colorScheme.onSurface;
|
||||
|
||||
return Material(
|
||||
color: color,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_tts/flutter_tts.dart' as flutter_tts;
|
||||
import 'package:matrix/matrix_api_lite/utils/logs.dart';
|
||||
import 'package:text_to_speech/text_to_speech.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/controllers/user_controller.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_show_popup.dart';
|
||||
|
|
@ -8,11 +15,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|||
import 'package:fluffychat/pangea/widgets/chat/missing_voice_button.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_tts/flutter_tts.dart' as flutter_tts;
|
||||
import 'package:matrix/matrix_api_lite/utils/logs.dart';
|
||||
import 'package:text_to_speech/text_to_speech.dart';
|
||||
|
||||
class TtsController {
|
||||
String? get targetLanguage =>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import 'dart:developer';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pages/chat/chat.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
|
|
@ -11,10 +16,6 @@ import 'package:fluffychat/pangea/models/representation_content_model.dart';
|
|||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_toolbar_selection_area.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import '../../models/pangea_match_model.dart';
|
||||
|
||||
class PangeaRichText extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class StarAnimationWidget extends StatefulWidget {
|
||||
const StarAnimationWidget({super.key});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/controllers/message_analytics_controller.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/controllers/put_analytics_controller.dart';
|
||||
|
|
@ -22,8 +26,6 @@ import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart';
|
|||
import 'package:fluffychat/pangea/widgets/practice_activity/multiple_choice_activity.dart';
|
||||
import 'package:fluffychat/pangea/widgets/word_zoom/word_zoom_widget.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// The wrapper for practice activity content.
|
||||
/// Handles the activities associated with a message,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/choreographer/widgets/text_loading_shimmer.dart';
|
||||
import 'package:fluffychat/pangea/constants/language_constants.dart';
|
||||
|
|
@ -7,9 +12,6 @@ import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_repo.dart';
|
|||
import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart';
|
||||
import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_response.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class LemmaMeaningWidget extends StatefulWidget {
|
||||
final String lemma;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
// stateful widget that displays morphological label and a shimmer effect while the text is loading
|
||||
// takes a token and morphological feature as input
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/constants/morph_categories_and_labels.dart';
|
||||
import 'package:fluffychat/pangea/enum/analytics/morph_categories_enum.dart';
|
||||
|
|
@ -12,8 +16,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|||
import 'package:fluffychat/pangea/utils/grammar/get_grammar_copy.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class MorphologicalCenterWidget extends StatefulWidget {
|
||||
final PangeaToken token;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/controllers/message_analytics_controller.dart';
|
||||
import 'package:fluffychat/pangea/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
|
||||
|
|
@ -8,8 +11,6 @@ import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_ca
|
|||
import 'package:fluffychat/pangea/widgets/word_zoom/lemma_meaning_widget.dart';
|
||||
import 'package:fluffychat/pangea/widgets/word_zoom/morphs/morphological_center_widget.dart';
|
||||
import 'package:fluffychat/pangea/widgets/word_zoom/word_zoom_widget.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WordZoomCenterWidget extends StatelessWidget {
|
||||
final WordZoomSelection? selectionType;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue