Merge pull request #4874 from pangeachat/more-practice-tweaks
More practice tweaks
This commit is contained in:
commit
6ec7e9ff59
6 changed files with 93 additions and 46 deletions
|
|
@ -14,6 +14,7 @@ import 'package:fluffychat/pages/chat/chat.dart';
|
|||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/layout/reading_assistance_mode_enum.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/message_practice/message_practice_mode_enum.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/message_practice/token_practice_button.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/message_selection_overlay.dart';
|
||||
import 'package:fluffychat/pangea/toolbar/reading_assistance/token_emoji_button.dart';
|
||||
|
|
@ -513,6 +514,26 @@ class HtmlMessage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (renderer.showCenterStyling &&
|
||||
token != null &&
|
||||
overlayController != null)
|
||||
ListenableBuilder(
|
||||
listenable: overlayController!.practiceController,
|
||||
builder: (context, _) => AnimatedSize(
|
||||
duration: const Duration(
|
||||
milliseconds: AppConfig.overlayAnimationDuration,
|
||||
),
|
||||
curve: Curves.easeOut,
|
||||
child: SizedBox(
|
||||
height: overlayController!
|
||||
.practiceController.practiceMode !=
|
||||
MessagePracticeMode.noneSelected
|
||||
? 16.0
|
||||
: 0.0,
|
||||
width: tokenWidth,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
// ),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class PutAnalyticsController {
|
|||
String? targetId,
|
||||
}) {
|
||||
final level = _pangeaController.getAnalytics.constructListModel.level;
|
||||
_addLocalMessage(eventId, constructs).then(
|
||||
_addLocalMessage(eventId, List.from(constructs)).then(
|
||||
(_) => _sendAnalytics(level, targetId, constructs),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,28 +395,6 @@ class MessageSelectionPositionerState extends State<MessageSelectionPositioner>
|
|||
alignment:
|
||||
ownMessage ? Alignment.centerRight : Alignment.centerLeft,
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: ListenableBuilder(
|
||||
listenable: widget.overlayController.practiceController,
|
||||
builder: (context, _) {
|
||||
final instruction = widget.overlayController
|
||||
.practiceController.practiceMode.instruction;
|
||||
if (instruction != null) {
|
||||
return InstructionsInlineTooltip(
|
||||
instructionsEnum: widget.overlayController
|
||||
.practiceController.practiceMode.instruction!,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
animate: false,
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox();
|
||||
},
|
||||
),
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: _startedTransition,
|
||||
builder: (context, started, __) {
|
||||
|
|
@ -458,6 +436,36 @@ class MessageSelectionPositionerState extends State<MessageSelectionPositioner>
|
|||
selectedToken: widget.overlayController.selectedToken,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: switch (MediaQuery.heightOf(context)) {
|
||||
< 700 => 0,
|
||||
> 900 => 160,
|
||||
_ => 80,
|
||||
},
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: ListenableBuilder(
|
||||
listenable:
|
||||
widget.overlayController.practiceController,
|
||||
builder: (context, _) {
|
||||
final instruction = widget.overlayController
|
||||
.practiceController.practiceMode.instruction;
|
||||
if (instruction != null) {
|
||||
return InstructionsInlineTooltip(
|
||||
instructionsEnum: widget
|
||||
.overlayController
|
||||
.practiceController
|
||||
.practiceMode
|
||||
.instruction!,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
animate: false,
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -54,6 +54,30 @@ class PracticeController with ChangeNotifier {
|
|||
practiceSelection?.activities(activityType).every((a) => a.isComplete) ==
|
||||
true;
|
||||
|
||||
bool isPracticeButtonEmpty(PangeaToken token) {
|
||||
final target = practiceTargetForToken(token);
|
||||
|
||||
if (MessagePracticeMode.wordEmoji == practiceMode) {
|
||||
if (token.vocabConstructID.userSetEmoji.firstOrNull != null) {
|
||||
return false;
|
||||
}
|
||||
// Keep open even when completed to show emoji
|
||||
return target == null;
|
||||
}
|
||||
|
||||
if (MessagePracticeMode.wordMorph == practiceMode) {
|
||||
// Keep open even when completed to show morph icon
|
||||
return target == null;
|
||||
}
|
||||
|
||||
return target == null ||
|
||||
target.isCompleteByToken(
|
||||
token,
|
||||
_activity?.morphFeature,
|
||||
) ==
|
||||
true;
|
||||
}
|
||||
|
||||
Future<Result<PracticeActivityModel>> fetchActivityModel(
|
||||
PracticeTarget target,
|
||||
) async {
|
||||
|
|
|
|||
|
|
@ -176,11 +176,10 @@ class _ReadingAssistanceBarContent extends StatelessWidget {
|
|||
}
|
||||
|
||||
if (target == null) {
|
||||
return Center(
|
||||
child: Text(
|
||||
L10n.of(context).selectForGrammar,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
textAlign: TextAlign.center,
|
||||
return const Center(
|
||||
child: Icon(
|
||||
Symbols.fitness_center,
|
||||
size: 60.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,20 +55,7 @@ class TokenPracticeButton extends StatelessWidget {
|
|||
true;
|
||||
}
|
||||
|
||||
bool get _isEmpty {
|
||||
final mode = controller.practiceMode;
|
||||
if (MessagePracticeMode.wordEmoji == mode &&
|
||||
token.vocabConstructID.userSetEmoji.firstOrNull != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return _activity == null ||
|
||||
(isActivityCompleteOrNullForToken &&
|
||||
![MessagePracticeMode.wordEmoji, MessagePracticeMode.wordMorph]
|
||||
.contains(mode)) ||
|
||||
(MessagePracticeMode.wordMorph == mode &&
|
||||
_activity?.morphFeature == null);
|
||||
}
|
||||
bool get _isEmpty => controller.isPracticeButtonEmpty(token);
|
||||
|
||||
bool get _isSelected =>
|
||||
controller.selectedMorph?.token == token &&
|
||||
|
|
@ -98,6 +85,7 @@ class TokenPracticeButton extends StatelessWidget {
|
|||
child = _MorphMatchButton(
|
||||
active: _isSelected,
|
||||
textColor: textColor,
|
||||
width: tokenButtonHeight,
|
||||
onTap: () => controller.onSelectMorph(
|
||||
MorphSelection(
|
||||
token,
|
||||
|
|
@ -123,8 +111,14 @@ class TokenPracticeButton extends StatelessWidget {
|
|||
curve: Curves.easeOut,
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: _isEmpty
|
||||
? const SizedBox(height: 0)
|
||||
: SizedBox(height: tokenButtonHeight, child: child),
|
||||
? const SizedBox()
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: 16.0),
|
||||
SizedBox(height: tokenButtonHeight, child: child),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
@ -198,10 +192,12 @@ class _MorphMatchButton extends StatelessWidget {
|
|||
final bool active;
|
||||
final Color textColor;
|
||||
final bool shimmer;
|
||||
final double width;
|
||||
|
||||
const _MorphMatchButton({
|
||||
required this.active,
|
||||
required this.textColor,
|
||||
required this.width,
|
||||
this.shimmer = false,
|
||||
this.onTap,
|
||||
});
|
||||
|
|
@ -218,7 +214,7 @@ class _MorphMatchButton extends StatelessWidget {
|
|||
child: ShimmerBackground(
|
||||
enabled: shimmer,
|
||||
child: SizedBox(
|
||||
width: 24.0,
|
||||
width: width,
|
||||
child: Center(
|
||||
child: Opacity(
|
||||
opacity: active ? 1.0 : 0.6,
|
||||
|
|
@ -282,7 +278,6 @@ class _NoActivityContentButton extends StatelessWidget {
|
|||
context: context,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 24.0,
|
||||
child: Center(
|
||||
child: MorphIcon(
|
||||
morphFeature: morphFeature,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue