decide whether to show points gain animation based on the origin of the point update

pull/1476/head
ggurdin 1 year ago
parent 35e3bbc3fe
commit 7f844ff1a2
No known key found for this signature in database
GPG Key ID: A01CB41737CBB478

@ -691,6 +691,7 @@ class ChatController extends State<ChatPageWithRoom>
metadata: metadata,
)),
],
origin: AnalyticsUpdateOrigin.sendMessage,
),
);
}

@ -9,6 +9,7 @@ import 'package:fluffychat/pages/chat/pinned_events.dart';
import 'package:fluffychat/pages/chat/reply_display.dart';
import 'package:fluffychat/pangea/choreographer/widgets/it_bar.dart';
import 'package:fluffychat/pangea/choreographer/widgets/start_igc_button.dart';
import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/widgets/animations/gain_points.dart';
import 'package:fluffychat/pangea/widgets/chat/chat_floating_action_button.dart';
@ -454,6 +455,8 @@ class ChatView extends StatelessWidget {
gainColor: Theme.of(context)
.colorScheme
.onPrimary,
origin: AnalyticsUpdateOrigin
.sendMessage,
),
const SizedBox(width: 100),
ChatFloatingActionButton(

@ -3,6 +3,7 @@ import 'dart:developer';
import 'package:fluffychat/pangea/choreographer/controllers/error_service.dart';
import 'package:fluffychat/pangea/constants/choreo_constants.dart';
import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart';
import 'package:fluffychat/pangea/enum/construct_use_type_enum.dart';
import 'package:fluffychat/pangea/models/pangea_token_model.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
@ -315,6 +316,7 @@ class ITController {
ignoredTokens ?? [],
choreographer.roomId,
ConstructUseTypeEnum.ignIt,
AnalyticsUpdateOrigin.it,
);
Future.delayed(

@ -7,6 +7,7 @@ import 'package:fluffychat/pangea/choreographer/widgets/it_bar_buttons.dart';
import 'package:fluffychat/pangea/choreographer/widgets/it_feedback_card.dart';
import 'package:fluffychat/pangea/choreographer/widgets/translation_finished_flow.dart';
import 'package:fluffychat/pangea/constants/choreo_constants.dart';
import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart';
import 'package:fluffychat/pangea/enum/construct_use_type_enum.dart';
import 'package:fluffychat/pangea/enum/instructions_enum.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
@ -80,7 +81,9 @@ class ITBarState extends State<ITBar> {
children: [
const Positioned(
top: 60,
child: PointsGainedAnimation(),
child: PointsGainedAnimation(
origin: AnalyticsUpdateOrigin.it,
),
),
SingleChildScrollView(
child: Column(
@ -372,6 +375,7 @@ class ITChoices extends StatelessWidget {
continuance.level > 1
? ConstructUseTypeEnum.incIt
: ConstructUseTypeEnum.corIt,
AnalyticsUpdateOrigin.it,
);
}
controller.currentITStep!.continuances[index].wasClicked = true;

@ -23,8 +23,8 @@ class GetAnalyticsController {
late PangeaController _pangeaController;
final List<AnalyticsCacheEntry> _cache = [];
StreamSubscription<AnalyticsUpdate>? _analyticsUpdateSubscription;
CachedStreamController<List<OneConstructUse>> analyticsStream =
CachedStreamController<List<OneConstructUse>>();
CachedStreamController<AnalyticsStreamUpdate> analyticsStream =
CachedStreamController<AnalyticsStreamUpdate>();
/// The previous XP points of the user, before the last update.
/// Used for animating analytics updates.
@ -83,7 +83,7 @@ class GetAnalyticsController {
_analyticsUpdateSubscription?.cancel();
_analyticsUpdateSubscription = null;
_cache.clear();
analyticsStream.add([]);
analyticsStream.add(AnalyticsStreamUpdate(constructs: []));
prevXP = null;
}
@ -92,24 +92,30 @@ class GetAnalyticsController {
if (analyticsUpdate.type == AnalyticsUpdateType.server) {
await getConstructs(forceUpdate: true);
}
updateAnalyticsStream();
updateAnalyticsStream(origin: analyticsUpdate.origin);
}
void updateAnalyticsStream() {
void updateAnalyticsStream({AnalyticsUpdateOrigin? origin}) {
// if there are no construct uses, or if the last update in this
// stream has the same length as this update, don't update the stream
if (allConstructUses.isEmpty ||
allConstructUses.length == analyticsStream.value?.length) {
allConstructUses.length == analyticsStream.value?.constructs.length) {
return;
}
// set the previous XP to the currentXP
if (analyticsStream.value != null && analyticsStream.value!.isNotEmpty) {
prevXP = calcXP(analyticsStream.value!);
if (analyticsStream.value != null &&
analyticsStream.value!.constructs.isNotEmpty) {
prevXP = calcXP(analyticsStream.value!.constructs);
}
// finally, add to the stream
analyticsStream.add(allConstructUses);
analyticsStream.add(
AnalyticsStreamUpdate(
constructs: allConstructUses,
origin: origin,
),
);
}
/// Calculates the user's xpPoints for their current L2,
@ -347,3 +353,13 @@ class AnalyticsCacheEntry {
return _createdAt.isBefore(lastEventUpdated);
}
}
class AnalyticsStreamUpdate {
final List<OneConstructUse> constructs;
final AnalyticsUpdateOrigin? origin;
AnalyticsStreamUpdate({
required this.constructs,
this.origin,
});
}

@ -125,7 +125,7 @@ class MyAnalyticsController extends BaseController<AnalyticsStream> {
_addLocalMessage(eventID, filtered).then(
(_) {
_clearDraftUses(roomID);
_decideWhetherToUpdateAnalyticsRoom(level);
_decideWhetherToUpdateAnalyticsRoom(level, data.origin);
},
);
});
@ -135,6 +135,7 @@ class MyAnalyticsController extends BaseController<AnalyticsStream> {
List<PangeaToken> tokens,
String roomID,
ConstructUseTypeEnum useType,
AnalyticsUpdateOrigin origin,
) {
final metadata = ConstructUseMetaData(
roomId: roomID,
@ -178,7 +179,7 @@ class MyAnalyticsController extends BaseController<AnalyticsStream> {
final level = _pangeaController.analytics.level;
_addLocalMessage('draft$roomID', uses).then(
(_) => _decideWhetherToUpdateAnalyticsRoom(level),
(_) => _decideWhetherToUpdateAnalyticsRoom(level, origin),
);
}
@ -218,7 +219,10 @@ class MyAnalyticsController extends BaseController<AnalyticsStream> {
/// If the addition brought the total number of messages in the cache
/// to the max, or if the addition triggered a level-up, update the analytics.
/// Otherwise, add a local update to the alert stream.
void _decideWhetherToUpdateAnalyticsRoom(int prevLevel) {
void _decideWhetherToUpdateAnalyticsRoom(
int prevLevel,
AnalyticsUpdateOrigin? origin,
) {
// cancel the last timer that was set on message event and
// reset it to fire after _minutesBeforeUpdate minutes
_updateTimer?.cancel();
@ -238,7 +242,7 @@ class MyAnalyticsController extends BaseController<AnalyticsStream> {
newLevel > prevLevel
? sendLocalAnalyticsToAnalyticsRoom()
: analyticsUpdateStream.add(
AnalyticsUpdate(AnalyticsUpdateType.local),
AnalyticsUpdate(AnalyticsUpdateType.local, origin: origin),
);
}
@ -345,6 +349,7 @@ class MyAnalyticsController extends BaseController<AnalyticsStream> {
class AnalyticsStream {
final String eventId;
final String roomId;
final AnalyticsUpdateOrigin? origin;
final List<OneConstructUse> constructs;
@ -352,12 +357,21 @@ class AnalyticsStream {
required this.eventId,
required this.roomId,
required this.constructs,
this.origin,
});
}
enum AnalyticsUpdateOrigin {
it,
igc,
sendMessage,
practiceActivity,
}
class AnalyticsUpdate {
final AnalyticsUpdateType type;
final AnalyticsUpdateOrigin? origin;
final bool isLogout;
AnalyticsUpdate(this.type, {this.isLogout = false});
AnalyticsUpdate(this.type, {this.isLogout = false, this.origin});
}

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:fluffychat/pangea/models/analytics/constructs_model.dart';
import 'package:fluffychat/pangea/controllers/get_analytics_controller.dart';
import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart';
import 'package:fluffychat/pangea/utils/bot_style.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
@ -8,8 +9,11 @@ import 'package:flutter/material.dart';
class PointsGainedAnimation extends StatefulWidget {
final Color? gainColor;
final Color? loseColor;
final AnalyticsUpdateOrigin origin;
const PointsGainedAnimation({
super.key,
required this.origin,
this.gainColor,
this.loseColor = Colors.red,
});
@ -69,7 +73,8 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
super.dispose();
}
void _showPointsGained(List<OneConstructUse> constructs) {
void _showPointsGained(AnalyticsStreamUpdate update) {
if (update.origin != widget.origin) return;
setState(() => _addedPoints = (_currentXP ?? 0) - (_prevXP ?? 0));
if (_prevXP != _currentXP) {
_controller.reset();

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pangea/controllers/get_analytics_controller.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/enum/construct_type_enum.dart';
import 'package:fluffychat/pangea/enum/progress_indicators_enum.dart';
@ -37,7 +38,7 @@ class LearningProgressIndicatorsState
/// A stream subscription to listen for updates to
/// the analytics data, either locally or from events
StreamSubscription<List<OneConstructUse>>? _analyticsUpdateSubscription;
StreamSubscription<AnalyticsStreamUpdate>? _analyticsUpdateSubscription;
/// Vocabulary constructs model
ConstructListModel? words;
@ -65,11 +66,11 @@ class LearningProgressIndicatorsState
void initState() {
super.initState();
updateAnalyticsData(
_pangeaController.analytics.analyticsStream.value ?? [],
_pangeaController.analytics.analyticsStream.value?.constructs ?? [],
);
_analyticsUpdateSubscription = _pangeaController
.analytics.analyticsStream.stream
.listen(updateAnalyticsData);
.listen((update) => updateAnalyticsData(update.constructs));
}
@override

@ -1,6 +1,7 @@
import 'dart:developer';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart';
import 'package:fluffychat/pangea/enum/construct_use_type_enum.dart';
import 'package:fluffychat/pangea/enum/span_data_type.dart';
import 'package:fluffychat/pangea/models/pangea_token_model.dart';
@ -130,6 +131,7 @@ class SpanCardState extends State<SpanCard> {
selectedChoice!.isBestCorrection
? ConstructUseTypeEnum.corIGC
: ConstructUseTypeEnum.incIGC,
AnalyticsUpdateOrigin.igc,
);
}
@ -160,6 +162,7 @@ class SpanCardState extends State<SpanCard> {
ignoredTokens ?? [],
widget.roomId,
ConstructUseTypeEnum.ignIGC,
AnalyticsUpdateOrigin.igc,
);
}
@ -226,7 +229,9 @@ class WordMatchContent extends StatelessWidget {
children: [
const Positioned(
top: 40,
child: PointsGainedAnimation(),
child: PointsGainedAnimation(
origin: AnalyticsUpdateOrigin.igc,
),
),
Column(
children: [

@ -81,6 +81,7 @@ class MultipleChoiceActivityState extends State<MultipleChoiceActivity> {
widget.practiceCardController.currentActivity!,
widget.practiceCardController.metadata,
),
origin: AnalyticsUpdateOrigin.practiceActivity,
),
);

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:developer';
import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
@ -335,7 +336,9 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
children: [
// Main content
const Positioned(
child: PointsGainedAnimation(),
child: PointsGainedAnimation(
origin: AnalyticsUpdateOrigin.practiceActivity,
),
),
if (activityWidget != null)
Padding(

@ -29,7 +29,9 @@ class TargetTokensController {
_targetTokens = await _initialize(context, pangeaMessageEvent);
await updateTokensWithConstructs(
MatrixState.pangeaController.analytics.analyticsStream.value ?? [],
MatrixState
.pangeaController.analytics.analyticsStream.value?.constructs ??
[],
context,
pangeaMessageEvent,
);
@ -58,9 +60,8 @@ class TargetTokensController {
return _targetTokens = [];
}
return _targetTokens = tokens
.map((token) => token.emptyTokenWithXP)
.toList();
return _targetTokens =
tokens.map((token) => token.emptyTokenWithXP).toList();
}
Future<void> updateTokensWithConstructs(
@ -76,9 +77,8 @@ class TargetTokensController {
_targetTokens ??= await _initialize(context, pangeaMessageEvent);
for (final token in _targetTokens!) {
// we don't need to do this for tokens that don't have saveVocab set to true
if (!token.token.lemma.saveVocab){
if (!token.token.lemma.saveVocab) {
continue;
}

@ -79,6 +79,7 @@ class WordFocusListeningActivityState
widget.practiceCardController.currentActivity!,
widget.practiceCardController.metadata,
),
origin: AnalyticsUpdateOrigin.practiceActivity,
),
);
setState(() {

Loading…
Cancel
Save