Merge pull request #405 from pangeachat/inline-tooltip

Inline-tooltip [WIP]
pull/1384/head
ggurdin 1 year ago committed by GitHub
commit f8ff2eb922
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -4065,6 +4065,8 @@
"practice": "Practice",
"noLanguagesSet": "No languages set",
"noActivitiesFound": "No practice activities found for this message",
"hintTitle": "Hint:",
"speechToTextBody": "See how well you did by looking at your Accuracy and Words Per Minute scores",
"previous": "Previous",
"languageButtonLabel": "Language: {currentLanguage}",
"@languageButtonLabel": {

@ -4,8 +4,8 @@ import 'package:fluffychat/pages/chat/events/message.dart';
import 'package:fluffychat/pages/chat/seen_by_row.dart';
import 'package:fluffychat/pages/chat/typing_indicators.dart';
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
import 'package:fluffychat/pangea/enum/instructions_enum.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/utils/instructions.dart';
import 'package:fluffychat/pangea/widgets/chat/locked_chat_message.dart';
import 'package:fluffychat/utils/account_config.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
@ -46,7 +46,7 @@ class ChatEventList extends StatelessWidget {
// card, attach it on top of the first shown message
WidgetsBinding.instance.addPostFrameCallback((_) {
if (events.isEmpty) return;
controller.pangeaController.instructions.show(
controller.pangeaController.instructions.showInstructionsPopup(
context,
InstructionsEnum.clickMessage,
events[0].eventId,

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/utils/instructions.dart';
import 'package:fluffychat/pangea/enum/instructions_enum.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';
@ -37,7 +37,7 @@ class ITBotButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
choreographer.pangeaController.instructions.show(
choreographer.pangeaController.instructions.showInstructionsPopup(
context,
InstructionsEnum.itInstructions,
choreographer.itBotTransformTargetKey,
@ -46,7 +46,8 @@ class ITBotButton extends StatelessWidget {
return IconButton(
icon: const BotFace(width: 40.0, expression: BotExpression.idle),
onPressed: () => choreographer.pangeaController.instructions.show(
onPressed: () =>
choreographer.pangeaController.instructions.showInstructionsPopup(
context,
InstructionsEnum.itInstructions,
choreographer.itBotTransformTargetKey,

@ -0,0 +1,45 @@
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
enum InstructionsEnum {
itInstructions,
clickMessage,
blurMeansTranslate,
tooltipInstructions,
speechToText,
}
extension Copy on InstructionsEnum {
String title(BuildContext context) {
switch (this) {
case InstructionsEnum.itInstructions:
return L10n.of(context)!.itInstructionsTitle;
case InstructionsEnum.clickMessage:
return L10n.of(context)!.clickMessageTitle;
case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateTitle;
case InstructionsEnum.tooltipInstructions:
return L10n.of(context)!.tooltipInstructionsTitle;
case InstructionsEnum.speechToText:
return L10n.of(context)!.hintTitle;
}
}
String body(BuildContext context) {
switch (this) {
case InstructionsEnum.itInstructions:
return L10n.of(context)!.itInstructionsBody;
case InstructionsEnum.clickMessage:
return L10n.of(context)!.clickMessageBody;
case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateBody;
case InstructionsEnum.speechToText:
return L10n.of(context)!.speechToTextBody;
case InstructionsEnum.tooltipInstructions:
return PlatformInfos.isMobile
? L10n.of(context)!.tooltipInstructionsMobileBody
: L10n.of(context)!.tooltipInstructionsBrowserBody;
}
}
}

@ -4,8 +4,8 @@ import 'package:country_picker/country_picker.dart';
import 'package:fluffychat/pangea/constants/local.key.dart';
import 'package:fluffychat/pangea/constants/model_keys.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/enum/instructions_enum.dart';
import 'package:fluffychat/pangea/models/space_model.dart';
import 'package:fluffychat/pangea/utils/instructions.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';

@ -1,4 +1,5 @@
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/pangea/enum/instructions_enum.dart';
import 'package:fluffychat/pangea/utils/inline_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -14,17 +15,29 @@ import 'overlay.dart';
class InstructionsController {
late PangeaController _pangeaController;
// We have these three methods to make sure that the instructions are not shown too much
/// Instruction popup was closed by the user
final Map<InstructionsEnum, bool> _instructionsClosed = {};
/// Instruction popup has already been shown this session
final Map<InstructionsEnum, bool> _instructionsShown = {};
/// Returns true if the user requested this popup not be shown again
bool? toggledOff(InstructionsEnum key) =>
_pangeaController.pStoreService.read(key.toString());
InstructionsController(PangeaController pangeaController) {
_pangeaController = pangeaController;
}
/// Returns true if the instructions were closed
/// or turned off by the user via the toggle switch
bool wereInstructionsTurnedOff(InstructionsEnum key) =>
_pangeaController.pStoreService.read(key.toString()) ??
_instructionsClosed[key] ??
false;
toggledOff(key) ?? _instructionsClosed[key] ?? false;
void turnOffInstruction(InstructionsEnum key) =>
_instructionsClosed[key] = true;
Future<void> updateEnableInstructions(
InstructionsEnum key,
@ -35,7 +48,9 @@ class InstructionsController {
value,
);
Future<void> show(
/// Instruction Card gives users tips on
/// how to use Pangea Chat's features
Future<void> showInstructionsPopup(
BuildContext context,
InstructionsEnum key,
String transformTargetKey, [
@ -98,45 +113,35 @@ class InstructionsController {
),
);
}
}
enum InstructionsEnum {
itInstructions,
clickMessage,
blurMeansTranslate,
tooltipInstructions,
}
extension Copy on InstructionsEnum {
String title(BuildContext context) {
switch (this) {
case InstructionsEnum.itInstructions:
return L10n.of(context)!.itInstructionsTitle;
case InstructionsEnum.clickMessage:
return L10n.of(context)!.clickMessageTitle;
case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateTitle;
case InstructionsEnum.tooltipInstructions:
return L10n.of(context)!.tooltipInstructionsTitle;
/// Returns a widget that will be added to existing widget
/// which displays hint text defined in the enum extension
Widget getInstructionInlineTooltip(
BuildContext context,
InstructionsEnum key,
VoidCallback onClose,
) {
if (wereInstructionsTurnedOff(key)) {
return const SizedBox();
}
}
String body(BuildContext context) {
switch (this) {
case InstructionsEnum.itInstructions:
return L10n.of(context)!.itInstructionsBody;
case InstructionsEnum.clickMessage:
return L10n.of(context)!.clickMessageBody;
case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateBody;
case InstructionsEnum.tooltipInstructions:
return PlatformInfos.isMobile
? L10n.of(context)!.tooltipInstructionsMobileBody
: L10n.of(context)!.tooltipInstructionsBrowserBody;
if (L10n.of(context) == null) {
ErrorHandler.logError(
m: "null context in ITBotButton.showCard",
s: StackTrace.current,
);
return const SizedBox();
}
return InlineTooltip(
body: InstructionsEnum.speechToText.body(context),
onClose: onClose,
);
}
}
/// User can toggle on to prevent Instruction Card
/// from appearing in future sessions
class InstructionsToggle extends StatefulWidget {
const InstructionsToggle({
super.key,

@ -1,9 +1,9 @@
import 'dart:developer';
import 'package:fluffychat/pangea/enum/instructions_enum.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/models/speech_to_text_models.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:fluffychat/pangea/utils/instructions.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';
@ -65,6 +65,13 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
}
}
void closeHint() {
MatrixState.pangeaController.instructions.turnOffInstruction(
InstructionsEnum.speechToText,
);
setState(() {});
}
TextSpan _buildTranscriptText(BuildContext context) {
final Transcript transcript = speechToTextResponse!.transcript;
final List<InlineSpan> spans = [];
@ -172,7 +179,8 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
number:
"${selectedToken?.confidence ?? speechToTextResponse!.transcript.confidence}%",
toolTip: L10n.of(context)!.accuracy,
onPressed: () => MatrixState.pangeaController.instructions.show(
onPressed: () => MatrixState.pangeaController.instructions
.showInstructionsPopup(
context,
InstructionsEnum.tooltipInstructions,
widget.messageEvent.eventId,
@ -184,7 +192,8 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
number:
wordsPerMinuteString != null ? "$wordsPerMinuteString" : "??",
toolTip: L10n.of(context)!.wordsPerMinute,
onPressed: () => MatrixState.pangeaController.instructions.show(
onPressed: () => MatrixState.pangeaController.instructions
.showInstructionsPopup(
context,
InstructionsEnum.tooltipInstructions,
widget.messageEvent.eventId,
@ -193,6 +202,11 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
),
],
),
MatrixState.pangeaController.instructions.getInstructionInlineTooltip(
context,
InstructionsEnum.speechToText,
closeHint,
),
],
);
}

@ -137,6 +137,8 @@ class ToolbarDisplayController {
? Alignment.bottomLeft
: Alignment.topLeft,
backgroundColor: const Color.fromRGBO(0, 0, 0, 1).withAlpha(100),
closePrevOverlay:
MatrixState.pangeaController.subscriptionController.isSubscribed,
);
if (MatrixState.pAnyState.entries.isNotEmpty) {

@ -3,10 +3,10 @@ import 'dart:ui';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/enum/instructions_enum.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/models/representation_content_model.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:fluffychat/pangea/utils/instructions.dart';
import 'package:fluffychat/pangea/widgets/chat/message_context_menu.dart';
import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -115,7 +115,7 @@ class PangeaRichTextState extends State<PangeaRichText> {
@override
Widget build(BuildContext context) {
if (blur > 0) {
pangeaController.instructions.show(
pangeaController.instructions.showInstructionsPopup(
context,
InstructionsEnum.blurMeansTranslate,
widget.pangeaMessageEvent.eventId,

Loading…
Cancel
Save