Merge pull request #728 from pangeachat/popup-dimensions
make popup dimensions dynamic
This commit is contained in:
commit
db2ad031eb
20 changed files with 291 additions and 305 deletions
|
|
@ -4114,14 +4114,14 @@
|
|||
"placeholders": {}
|
||||
},
|
||||
"addChatToSpaceDesc": "Adding a chat to a space will make the chat appear within the space for students and give them access.",
|
||||
"addSpaceToSpaceDesc": "Adding a sub space to space will make the sub space appear in the main space''s chat list.",
|
||||
"addSpaceToSpaceDesc": "Adding a sub space to space will make the sub space appear in the main space's chat list.",
|
||||
"spaceAnalytics": "Space Analytics",
|
||||
"changeAnalyticsLanguage": "Change Analytics Language",
|
||||
"suggestToSpace": "Suggest this space",
|
||||
"suggestToSpaceDesc": "Suggested sub spaces will appear in their main space''s chat list",
|
||||
"suggestToSpaceDesc": "Suggested sub spaces will appear in their main space's chat list",
|
||||
"practice": "Practice",
|
||||
"noLanguagesSet": "No languages set",
|
||||
"noActivitiesFound": "That''s enough on this for now! Come back later for more.",
|
||||
"noActivitiesFound": "That's enough on this for now! Come back later for more.",
|
||||
"hintTitle": "Hint:",
|
||||
"speechToTextBody": "See how well you did by looking at your Accuracy and Words Per Minute scores",
|
||||
"previous": "Previous",
|
||||
|
|
@ -4225,14 +4225,14 @@
|
|||
"discoverHomeservers": "Discover homeservers",
|
||||
"whatIsAHomeserver": "What is a homeserver?",
|
||||
"homeserverDescription": "All your data is stored on the homeserver, just like an email provider. You can choose which homeserver you want to use, while you can still communicate with everyone. Learn more at at https://matrix.org.",
|
||||
"doesNotSeemToBeAValidHomeserver": "Doesn''t seem to be a compatible homeserver. Wrong URL?",
|
||||
"doesNotSeemToBeAValidHomeserver": "Doesn't seem to be a compatible homeserver. Wrong URL?",
|
||||
"grammar": "Grammar",
|
||||
"contactHasBeenInvitedToTheChat": "Contact has been invited to the chat",
|
||||
"inviteChat": "📨 Invite chat",
|
||||
"chatName": "Chat name",
|
||||
"reportContentIssueTitle": "Report content issue",
|
||||
"feedback": "Optional feedback",
|
||||
"reportContentIssueDescription": "Uh oh! AI can faciliate personalized learning experiences but... also hallucinates. Please provide any feedback you have and we''ll try again.",
|
||||
"reportContentIssueDescription": "Uh oh! AI can faciliate personalized learning experiences but... also hallucinates. Please provide any feedback you have and we'll try again.",
|
||||
"clickTheWordAgainToDeselect": "Click the selected word to deselect it.",
|
||||
"l2SupportNa": "Not Available",
|
||||
"l2SupportAlpha": "Alpha",
|
||||
|
|
@ -4355,7 +4355,7 @@
|
|||
"grammarCopyNumber": "Number",
|
||||
"grammarCopyConjType": "Conjunction Type",
|
||||
"grammarCopyPolarity": "Polarity",
|
||||
"grammarCopyNumberPsor": "Possessor''s Number",
|
||||
"grammarCopyNumberPsor": "Possessor's Number",
|
||||
"grammarCopyCase": "Case",
|
||||
"grammarCopyDefinite": "Definiteness",
|
||||
"grammarCopyNumForm": "Numeral Form",
|
||||
|
|
|
|||
|
|
@ -439,64 +439,61 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
// ],
|
||||
// ),
|
||||
// const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
for (var i = 0; i < AudioPlayerWidget.wavesCount; i++)
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final double barOpacity = currentPosition > i ? 1 : 0.5;
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
onTapDown: (_) {
|
||||
audioPlayer?.seek(
|
||||
Duration(
|
||||
milliseconds:
|
||||
(maxPosition / AudioPlayerWidget.wavesCount)
|
||||
.round() *
|
||||
i,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 0.5,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: widget.color.withOpacity(barOpacity),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
height: 32 * (waveform[i] / 1024),
|
||||
),
|
||||
],
|
||||
Row(
|
||||
children: [
|
||||
for (var i = 0; i < AudioPlayerWidget.wavesCount; i++)
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final double barOpacity = currentPosition > i ? 1 : 0.5;
|
||||
return GestureDetector(
|
||||
onTapDown: (_) {
|
||||
audioPlayer?.seek(
|
||||
Duration(
|
||||
milliseconds:
|
||||
(maxPosition / AudioPlayerWidget.wavesCount)
|
||||
.round() *
|
||||
i,
|
||||
),
|
||||
),
|
||||
);
|
||||
// return Container(
|
||||
// height: 32,
|
||||
// width: 2,
|
||||
// alignment: Alignment.center,
|
||||
// child: Opacity(
|
||||
// opacity: barOpacity,
|
||||
// child: Container(
|
||||
// margin: const EdgeInsets.symmetric(
|
||||
// horizontal: 1,
|
||||
// ),
|
||||
// decoration: BoxDecoration(
|
||||
// color: widget.color,
|
||||
// borderRadius: BorderRadius.circular(2),
|
||||
// ),
|
||||
// height: 32 * (waveform[i] / 1024),
|
||||
// width: 2,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 0.5,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: widget.color.withOpacity(barOpacity),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
height: 32 * (waveform[i] / 1024),
|
||||
width: 1.5,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
// return Container(
|
||||
// height: 32,
|
||||
// width: 2,
|
||||
// alignment: Alignment.center,
|
||||
// child: Opacity(
|
||||
// opacity: barOpacity,
|
||||
// child: Container(
|
||||
// margin: const EdgeInsets.symmetric(
|
||||
// horizontal: 1,
|
||||
// ),
|
||||
// decoration: BoxDecoration(
|
||||
// color: widget.color,
|
||||
// borderRadius: BorderRadius.circular(2),
|
||||
// ),
|
||||
// height: 32 * (waveform[i] / 1024),
|
||||
// width: 2,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
// SizedBox(
|
||||
|
|
|
|||
|
|
@ -74,8 +74,11 @@ class Choreographer {
|
|||
CanSendStatus.showPaywall) {
|
||||
OverlayUtil.showPositionedCard(
|
||||
context: context,
|
||||
cardToShow: const PaywallCard(),
|
||||
cardSize: const Size(325, 325),
|
||||
cardToShow: PaywallCard(
|
||||
chatController: chatController,
|
||||
),
|
||||
maxHeight: 325,
|
||||
maxWidth: 325,
|
||||
transformTargetId: inputTransformTargetKey,
|
||||
);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -125,7 +125,8 @@ class IgcController {
|
|||
),
|
||||
roomId: choreographer.roomId,
|
||||
),
|
||||
cardSize: match.isITStart ? const Size(350, 260) : const Size(350, 350),
|
||||
maxHeight: match.isITStart ? 260 : 350,
|
||||
maxWidth: 350,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -341,7 +341,8 @@ class ITChoices extends StatelessWidget {
|
|||
),
|
||||
choiceFeedback: choiceFeedback,
|
||||
),
|
||||
cardSize: const Size(300, 300),
|
||||
maxHeight: 300,
|
||||
maxWidth: 300,
|
||||
borderColor: borderColor,
|
||||
transformTargetId: controller.choreographer.itBarTransformTargetKey,
|
||||
backDropToDismiss: false,
|
||||
|
|
|
|||
|
|
@ -106,21 +106,18 @@ class InstructionsController {
|
|||
onClose: () => {_instructionsClosed[key.toString()] = true},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
key.body(context),
|
||||
style: botStyle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
key.body(context),
|
||||
style: botStyle,
|
||||
),
|
||||
),
|
||||
if (showToggle) InstructionsToggle(instructionsKey: key),
|
||||
],
|
||||
),
|
||||
cardSize: const Size(300.0, 300.0),
|
||||
maxHeight: 300,
|
||||
maxWidth: 300,
|
||||
transformTargetId: transformTargetKey,
|
||||
closePrevOverlay: false,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ class OverlayUtil {
|
|||
required String transformTargetId,
|
||||
double? width,
|
||||
double? height,
|
||||
Offset? offset,
|
||||
backDropToDismiss = true,
|
||||
blurBackground = false,
|
||||
Color? borderColor,
|
||||
|
|
@ -86,8 +85,9 @@ class OverlayUtil {
|
|||
static showPositionedCard({
|
||||
required BuildContext context,
|
||||
required Widget cardToShow,
|
||||
required Size cardSize,
|
||||
required String transformTargetId,
|
||||
required double maxHeight,
|
||||
required double maxWidth,
|
||||
backDropToDismiss = true,
|
||||
Color? borderColor,
|
||||
bool closePrevOverlay = true,
|
||||
|
|
@ -107,14 +107,14 @@ class OverlayUtil {
|
|||
child: OverlayContainer(
|
||||
cardToShow: cardToShow,
|
||||
borderColor: borderColor,
|
||||
maxHeight: maxHeight,
|
||||
maxWidth: maxWidth,
|
||||
),
|
||||
);
|
||||
|
||||
showOverlay(
|
||||
context: context,
|
||||
child: child,
|
||||
width: cardSize.width,
|
||||
height: cardSize.height,
|
||||
transformTargetId: transformTargetId,
|
||||
backDropToDismiss: backDropToDismiss,
|
||||
borderColor: borderColor,
|
||||
|
|
|
|||
|
|
@ -187,26 +187,32 @@ class MessageAudioCardState extends State<MessageAudioCard> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
constraints: const BoxConstraints(minHeight: minCardHeight),
|
||||
alignment: Alignment.center,
|
||||
child: _isLoading
|
||||
? const ToolbarContentLoadingIndicator()
|
||||
: audioFile != null
|
||||
? Column(
|
||||
children: [
|
||||
AudioPlayerWidget(
|
||||
null,
|
||||
matrixFile: audioFile,
|
||||
sectionStartMS: sectionStartMS,
|
||||
sectionEndMS: sectionEndMS,
|
||||
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
tts.missingVoiceButton ?? const SizedBox(),
|
||||
],
|
||||
)
|
||||
: const CardErrorWidget(),
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
constraints: const BoxConstraints(minHeight: minCardHeight),
|
||||
alignment: Alignment.center,
|
||||
child: _isLoading
|
||||
? const ToolbarContentLoadingIndicator()
|
||||
: audioFile != null
|
||||
? Column(
|
||||
children: [
|
||||
AudioPlayerWidget(
|
||||
null,
|
||||
matrixFile: audioFile,
|
||||
sectionStartMS: sectionStartMS,
|
||||
sectionEndMS: sectionEndMS,
|
||||
color:
|
||||
Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
tts.missingVoiceButton,
|
||||
],
|
||||
)
|
||||
: const CardErrorWidget(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,26 +378,21 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
widget.chatController.room.membership == Membership.join;
|
||||
|
||||
// the default spacing between the side of the screen and the message bubble
|
||||
final double messageMargin =
|
||||
pangeaMessageEvent.ownMessage ? Avatar.defaultSize + 16 : 8;
|
||||
|
||||
// the actual spacing between the side of the screen and
|
||||
// the message bubble, accounts for wide screen
|
||||
double extraChatSpace = FluffyThemes.isColumnMode(context)
|
||||
? ((screenWidth -
|
||||
(FluffyThemes.columnWidth * 3.5) -
|
||||
FluffyThemes.navRailWidth) /
|
||||
2) +
|
||||
messageMargin
|
||||
: messageMargin;
|
||||
|
||||
if (extraChatSpace < messageMargin) {
|
||||
extraChatSpace = messageMargin;
|
||||
const double messageMargin = Avatar.defaultSize + 16 + 8;
|
||||
final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0;
|
||||
final chatViewWidth = screenWidth -
|
||||
(FluffyThemes.isColumnMode(context)
|
||||
? (FluffyThemes.columnWidth + FluffyThemes.navRailWidth)
|
||||
: 0);
|
||||
const totalMaxWidth = (FluffyThemes.columnWidth * 2.5) - messageMargin;
|
||||
double maxWidth = chatViewWidth - (2 * horizontalPadding) - messageMargin;
|
||||
if (maxWidth > totalMaxWidth) {
|
||||
maxWidth = totalMaxWidth;
|
||||
}
|
||||
|
||||
final overlayMessage = Container(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 2.5,
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: maxWidth,
|
||||
),
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
|
|
@ -446,21 +441,20 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
|
|||
),
|
||||
);
|
||||
|
||||
final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0;
|
||||
final columnOffset = FluffyThemes.isColumnMode(context)
|
||||
? FluffyThemes.columnWidth + FluffyThemes.navRailWidth
|
||||
: 0;
|
||||
|
||||
final double leftPadding = widget._pangeaMessageEvent.ownMessage
|
||||
? extraChatSpace
|
||||
final double? leftPadding = widget._pangeaMessageEvent.ownMessage
|
||||
? null
|
||||
: messageOffset!.dx - horizontalPadding - columnOffset;
|
||||
|
||||
final double rightPadding = widget._pangeaMessageEvent.ownMessage
|
||||
final double? rightPadding = widget._pangeaMessageEvent.ownMessage
|
||||
? screenWidth -
|
||||
messageOffset!.dx -
|
||||
messageSize!.width -
|
||||
horizontalPadding
|
||||
: extraChatSpace;
|
||||
: null;
|
||||
|
||||
final positionedOverlayMessage = _overlayPositionAnimation == null
|
||||
? Positioned(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dar
|
|||
import 'package:fluffychat/pangea/models/speech_to_text_models.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/utils/inline_tooltip.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart';
|
||||
import 'package:fluffychat/pangea/widgets/common/icon_number_widget.dart';
|
||||
import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart';
|
||||
|
|
@ -154,16 +153,11 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
|
|||
return CardErrorWidget(error: error);
|
||||
}
|
||||
|
||||
final int words = speechToTextResponse!.transcript.sttTokens.length;
|
||||
final int accuracy = speechToTextResponse!.transcript.confidence;
|
||||
final int total = words * accuracy;
|
||||
|
||||
//TODO: find better icons
|
||||
return Container(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
constraints: const BoxConstraints(minHeight: minCardHeight),
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
RichText(
|
||||
|
|
@ -171,19 +165,15 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// IconNumberWidget(
|
||||
// icon: Icons.abc,
|
||||
// number: (selectedToken == null ? words : 1).toString(),
|
||||
// toolTip: L10n.of(context)!.words,
|
||||
// ),
|
||||
IconNumberWidget(
|
||||
icon: Symbols.target,
|
||||
number:
|
||||
"${selectedToken?.confidence ?? speechToTextResponse!.transcript.confidence}%",
|
||||
toolTip: L10n.of(context)!.accuracy,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
IconNumberWidget(
|
||||
icon: Icons.speed,
|
||||
number: wordsPerMinuteString != null
|
||||
|
|
|
|||
|
|
@ -101,41 +101,25 @@ class MessageToolbar extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
key: MatrixState.pAnyState
|
||||
.layerLinkAndKey('${pangeaMessageEvent.eventId}-toolbar')
|
||||
.key,
|
||||
type: MaterialType.transparency,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardColor,
|
||||
border: Border.all(
|
||||
width: 2,
|
||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.5),
|
||||
),
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
),
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: AppConfig.toolbarMaxHeight,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: toolbarContent,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardColor,
|
||||
border: Border.all(
|
||||
width: 2,
|
||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.5),
|
||||
),
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
),
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: AppConfig.toolbarMaxHeight,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: toolbarContent,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import 'package:fluffychat/pangea/repo/full_text_translation_repo.dart';
|
|||
import 'package:fluffychat/pangea/utils/bot_style.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/utils/inline_tooltip.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_toolbar.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';
|
||||
|
|
@ -134,36 +133,41 @@ class MessageTranslationCardState extends State<MessageTranslationCard> {
|
|||
return const CardErrorWidget();
|
||||
}
|
||||
|
||||
return Container(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
constraints: const BoxConstraints(minHeight: minCardHeight),
|
||||
alignment: Alignment.center,
|
||||
child: _fetchingTranslation
|
||||
? const ToolbarContentLoadingIndicator()
|
||||
: Column(
|
||||
children: [
|
||||
widget.selection != null
|
||||
? Text(
|
||||
selectionTranslation!,
|
||||
style: BotStyle.text(context),
|
||||
)
|
||||
: Text(
|
||||
repEvent!.text,
|
||||
style: BotStyle.text(context),
|
||||
),
|
||||
if (notGoingToTranslate && widget.selection == null)
|
||||
InlineTooltip(
|
||||
instructionsEnum: InstructionsEnum.l1Translation,
|
||||
onClose: () => setState(() {}),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_fetchingTranslation
|
||||
? const ToolbarContentLoadingIndicator()
|
||||
: Flexible(
|
||||
child: Column(
|
||||
children: [
|
||||
widget.selection != null
|
||||
? Text(
|
||||
selectionTranslation!,
|
||||
style: BotStyle.text(context),
|
||||
)
|
||||
: Text(
|
||||
repEvent!.text,
|
||||
style: BotStyle.text(context),
|
||||
),
|
||||
if (notGoingToTranslate && widget.selection == null)
|
||||
InlineTooltip(
|
||||
instructionsEnum: InstructionsEnum.l1Translation,
|
||||
onClose: () => setState(() {}),
|
||||
),
|
||||
if (widget.selection != null)
|
||||
InlineTooltip(
|
||||
instructionsEnum:
|
||||
InstructionsEnum.clickAgainToDeselect,
|
||||
onClose: () => setState(() {}),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (widget.selection != null)
|
||||
InlineTooltip(
|
||||
instructionsEnum: InstructionsEnum.clickAgainToDeselect,
|
||||
onClose: () => setState(() {}),
|
||||
),
|
||||
// if (widget.selection != null)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ class TtsController {
|
|||
await tts.awaitSpeakCompletion(true);
|
||||
|
||||
final voices = await tts.getVoices;
|
||||
debugPrint("voices: $voices");
|
||||
availableLangCodes = (voices as List)
|
||||
.map((v) {
|
||||
// on iOS / web, the codes are in 'locale', but on Android, they are in 'name'
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class IconNumberWidget extends StatelessWidget {
|
|||
),
|
||||
onPressed: onPressed,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
number.toString(),
|
||||
style: TextStyle(
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class OverlayContainer extends StatelessWidget {
|
||||
final Widget cardToShow;
|
||||
final Size cardSize;
|
||||
final Color? borderColor;
|
||||
final double maxHeight;
|
||||
final double maxWidth;
|
||||
|
||||
const OverlayContainer({
|
||||
super.key,
|
||||
required this.cardToShow,
|
||||
this.cardSize = const Size(300.0, 300.0),
|
||||
this.borderColor,
|
||||
required this.maxHeight,
|
||||
required this.maxWidth,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -28,14 +30,17 @@ class OverlayContainer extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: cardSize.width,
|
||||
maxHeight: cardSize.height,
|
||||
minWidth: cardSize.width,
|
||||
minHeight: cardSize.height,
|
||||
maxWidth: maxWidth,
|
||||
maxHeight: maxHeight,
|
||||
),
|
||||
//PTODO - position card above input/message
|
||||
// margin: const EdgeInsets.all(10),
|
||||
child: cardToShow,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [cardToShow],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,11 @@ class PangeaTextController extends TextEditingController {
|
|||
text.isNotEmpty) {
|
||||
OverlayUtil.showPositionedCard(
|
||||
context: context,
|
||||
cardToShow: const PaywallCard(),
|
||||
cardSize: const Size(325, 325),
|
||||
cardToShow: PaywallCard(
|
||||
chatController: choreographer.chatController,
|
||||
),
|
||||
maxHeight: 325,
|
||||
maxWidth: 325,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
);
|
||||
}
|
||||
|
|
@ -112,10 +115,11 @@ class PangeaTextController extends TextEditingController {
|
|||
if (cardToShow != null) {
|
||||
OverlayUtil.showPositionedCard(
|
||||
context: context,
|
||||
cardSize: matchIndex != -1 &&
|
||||
maxHeight: matchIndex != -1 &&
|
||||
choreographer.igc.igcTextData!.matches[matchIndex].isITStart
|
||||
? const Size(350, 260)
|
||||
: const Size(350, 400),
|
||||
? 260
|
||||
: 400,
|
||||
maxWidth: 350,
|
||||
cardToShow: cardToShow,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pages/chat/chat.dart';
|
||||
import 'package:fluffychat/pangea/utils/bot_style.dart';
|
||||
import 'package:fluffychat/pangea/widgets/common/bot_face_svg.dart';
|
||||
import 'package:fluffychat/pangea/widgets/igc/card_header.dart';
|
||||
|
|
@ -7,8 +8,10 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class PaywallCard extends StatelessWidget {
|
||||
final ChatController chatController;
|
||||
const PaywallCard({
|
||||
super.key,
|
||||
required this.chatController,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -69,6 +72,7 @@ class PaywallCard extends StatelessWidget {
|
|||
width: double.infinity,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
chatController.clearSelectedEvents();
|
||||
MatrixState.pangeaController.subscriptionController
|
||||
.showPaywall(context);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -237,50 +237,48 @@ class WordMatchContent extends StatelessWidget {
|
|||
? controller.currentExpression
|
||||
: BotExpression.addled,
|
||||
),
|
||||
Expanded(
|
||||
child: Scrollbar(
|
||||
Scrollbar(
|
||||
controller: scrollController,
|
||||
thumbVisibility: true,
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
thumbVisibility: true,
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// const SizedBox(height: 10.0),
|
||||
// if (matchCopy.description != null)
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(),
|
||||
// child: Text(
|
||||
// matchCopy.description!,
|
||||
// style: BotStyle.text(context),
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 8),
|
||||
if (!controller.widget.scm.pangeaMatch!.isITStart)
|
||||
ChoicesArray(
|
||||
originalSpan:
|
||||
controller.widget.scm.pangeaMatch!.matchContent,
|
||||
isLoading: controller.fetchingData,
|
||||
choices:
|
||||
controller.widget.scm.pangeaMatch!.match.choices
|
||||
?.map(
|
||||
(e) => Choice(
|
||||
text: e.value,
|
||||
color: e.selected ? e.type.color : null,
|
||||
isGold: e.type.name == 'bestCorrection',
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onPressed: controller.onChoiceSelect,
|
||||
uniqueKeyForLayerLink: (int index) =>
|
||||
"wordMatch$index",
|
||||
selectedChoiceIndex: controller.selectedChoiceIndex,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
PromptAndFeedback(controller: controller),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// const SizedBox(height: 10.0),
|
||||
// if (matchCopy.description != null)
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(),
|
||||
// child: Text(
|
||||
// matchCopy.description!,
|
||||
// style: BotStyle.text(context),
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 8),
|
||||
if (!controller.widget.scm.pangeaMatch!.isITStart)
|
||||
ChoicesArray(
|
||||
originalSpan:
|
||||
controller.widget.scm.pangeaMatch!.matchContent,
|
||||
isLoading: controller.fetchingData,
|
||||
choices:
|
||||
controller.widget.scm.pangeaMatch!.match.choices
|
||||
?.map(
|
||||
(e) => Choice(
|
||||
text: e.value,
|
||||
color: e.selected ? e.type.color : null,
|
||||
isGold: e.type.name == 'bestCorrection',
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onPressed: controller.onChoiceSelect,
|
||||
uniqueKeyForLayerLink: (int index) =>
|
||||
"wordMatch$index",
|
||||
selectedChoiceIndex: controller.selectedChoiceIndex,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
PromptAndFeedback(controller: controller),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import 'package:fluffychat/pangea/utils/bot_style.dart';
|
|||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/widgets/animations/gain_points.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
|
||||
import 'package:fluffychat/pangea/widgets/content_issue_button.dart';
|
||||
import 'package:fluffychat/pangea/widgets/practice_activity/multiple_choice_activity.dart';
|
||||
import 'package:fluffychat/pangea/widgets/practice_activity/no_more_practice_card.dart';
|
||||
|
|
@ -314,45 +313,43 @@ class MessagePracticeActivityCardState extends State<PracticeActivityCard> {
|
|||
return GamifiedTextWidget(userMessage: userMessage!);
|
||||
}
|
||||
|
||||
return Container(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 350,
|
||||
minWidth: 350,
|
||||
minHeight: minCardHeight,
|
||||
),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// Main content
|
||||
const Positioned(
|
||||
child: PointsGainedAnimation(),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: activityWidget,
|
||||
),
|
||||
// Conditionally show the darkening and progress indicator based on the loading state
|
||||
if (!savoringTheJoy && fetchingActivity) ...[
|
||||
// Semi-transparent overlay
|
||||
Container(
|
||||
color: Colors.black.withOpacity(0.5), // Darkening effect
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// Main content
|
||||
const Positioned(
|
||||
child: PointsGainedAnimation(),
|
||||
),
|
||||
// Circular progress indicator in the center
|
||||
const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: activityWidget,
|
||||
),
|
||||
// Conditionally show the darkening and progress indicator based on the loading state
|
||||
if (!savoringTheJoy && fetchingActivity) ...[
|
||||
// Semi-transparent overlay
|
||||
Container(
|
||||
color: Colors.black.withOpacity(0.5), // Darkening effect
|
||||
),
|
||||
// Circular progress indicator in the center
|
||||
const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
],
|
||||
// Flag button in the top right corner
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: ContentIssueButton(
|
||||
isActive: currentActivity != null,
|
||||
submitFeedback: submitFeedback,
|
||||
),
|
||||
),
|
||||
],
|
||||
// Flag button in the top right corner
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: ContentIssueButton(
|
||||
isActive: currentActivity != null,
|
||||
submitFeedback: submitFeedback,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:fluffychat/pangea/utils/bot_style.dart';
|
||||
import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
|
|
@ -10,16 +9,19 @@ class SelectToDefine extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(minHeight: minCardHeight),
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Center(
|
||||
child: Text(
|
||||
L10n.of(context)!.selectToDefine,
|
||||
style: BotStyle.text(context),
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
L10n.of(context)!.selectToDefine,
|
||||
style: BotStyle.text(context),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue