Merge pull request #405 from pangeachat/inline-tooltip
Inline-tooltip [WIP]
This commit is contained in:
commit
f8ff2eb922
9 changed files with 119 additions and 50 deletions
|
|
@ -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:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/enum/instructions_enum.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/utils/instructions.dart';
|
||||
import 'package:fluffychat/widgets/matrix.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,
|
||||
|
|
|
|||
45
lib/pangea/enum/instructions_enum.dart
Normal file
45
lib/pangea/enum/instructions_enum.dart
Normal file
|
|
@ -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…
Add table
Reference in a new issue