feat: added widget to make dialog full screen on mobile with constraints on web (#1499)
This commit is contained in:
parent
426d1429b3
commit
cdfc8b831e
5 changed files with 185 additions and 184 deletions
|
|
@ -7,6 +7,7 @@ import 'package:fluffychat/pangea/analytics/enums/progress_indicators_enum.dart'
|
|||
import 'package:fluffychat/pangea/analytics/models/construct_list_model.dart';
|
||||
import 'package:fluffychat/pangea/analytics/models/construct_use_model.dart';
|
||||
import 'package:fluffychat/pangea/analytics/widgets/analytics_summary/morph_analytics_popup/morph_analytics_xp_tile.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class MorphAnalyticsPopup extends StatefulWidget {
|
||||
|
|
@ -123,33 +124,26 @@ class MorphAnalyticsPopupState extends State<MorphAnalyticsPopup> {
|
|||
);
|
||||
}
|
||||
|
||||
return Dialog(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 400,
|
||||
maxHeight: 600,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20.0),
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.type.indicator.tooltip(context)),
|
||||
leading: IconButton(
|
||||
icon: selectedCategory == null
|
||||
? const Icon(Icons.close)
|
||||
: const Icon(Icons.chevron_left_outlined),
|
||||
onPressed: selectedCategory == null
|
||||
? Navigator.of(context).pop
|
||||
: () => setSelectedCategory(null),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: dialogContent,
|
||||
),
|
||||
return FullWidthDialog(
|
||||
dialogContent: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.type.indicator.tooltip(context)),
|
||||
leading: IconButton(
|
||||
icon: selectedCategory == null
|
||||
? const Icon(Icons.close)
|
||||
: const Icon(Icons.chevron_left_outlined),
|
||||
onPressed: selectedCategory == null
|
||||
? Navigator.of(context).pop
|
||||
: () => setSelectedCategory(null),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: dialogContent,
|
||||
),
|
||||
),
|
||||
maxWidth: 600,
|
||||
maxHeight: 800,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import 'package:fluffychat/pangea/analytics/models/construct_list_model.dart';
|
|||
import 'package:fluffychat/pangea/analytics/models/construct_use_model.dart';
|
||||
import 'package:fluffychat/pangea/analytics/utils/get_grammar_copy.dart';
|
||||
import 'package:fluffychat/pangea/analytics/widgets/analytics_summary/vocab_analytics_popup/vocab_definition_popup.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
/// Displays vocab analytics, sorted into categories
|
||||
|
|
@ -159,8 +160,21 @@ class VocabAnalyticsPopupState extends State<VocabAnalyticsPopup> {
|
|||
final Widget greens = dialogWidget(LemmaCategoryEnum.greens, greenLemmas);
|
||||
final Widget seeds = dialogWidget(LemmaCategoryEnum.seeds, seedLemmas);
|
||||
|
||||
return ListView(
|
||||
children: [flowers, greens, seeds],
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(ProgressIndicatorEnum.wordsUsed.tooltip(context)),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
),
|
||||
// TODO: add search and training buttons?
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: ListView(
|
||||
children: [flowers, greens, seeds],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -238,30 +252,10 @@ class VocabAnalyticsPopupState extends State<VocabAnalyticsPopup> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 400,
|
||||
maxHeight: 600,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20.0),
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(ProgressIndicatorEnum.wordsUsed.tooltip(context)),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
),
|
||||
// TODO: add search and training buttons?
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: dialogContent,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
return FullWidthDialog(
|
||||
dialogContent: dialogContent,
|
||||
maxWidth: 600,
|
||||
maxHeight: 800,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import 'package:fluffychat/pangea/chat_settings/models/bot_options_model.dart';
|
|||
import 'package:fluffychat/pangea/chat_settings/widgets/conversation_bot/conversation_bot_no_permission_dialog.dart';
|
||||
import 'package:fluffychat/pangea/chat_settings/widgets/conversation_bot/conversation_bot_settings_form.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
|
||||
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
|
@ -175,135 +176,125 @@ class ConversationBotSettingsDialogState
|
|||
Widget build(BuildContext context) {
|
||||
final dialogContent = Form(
|
||||
key: formKey,
|
||||
child: Container(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
constraints: kIsWeb
|
||||
? const BoxConstraints(
|
||||
maxWidth: 450,
|
||||
maxHeight: 725,
|
||||
)
|
||||
: null,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
),
|
||||
child: Text(
|
||||
L10n.of(context).botConfig,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: () => Navigator.of(context).pop(null),
|
||||
child: Text(
|
||||
L10n.of(context).botConfig,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
],
|
||||
),
|
||||
InkWell(
|
||||
onTap: hasPermission
|
||||
? null
|
||||
: () => showNoPermissionDialog(context),
|
||||
child: SwitchListTile(
|
||||
title: Text(
|
||||
L10n.of(context).conversationBotStatus,
|
||||
),
|
||||
value: addBot,
|
||||
onChanged: hasPermission
|
||||
? (bool value) {
|
||||
setState(() => addBot = value);
|
||||
}
|
||||
: null, // Keeps the switch disabled
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: () => Navigator.of(context).pop(null),
|
||||
),
|
||||
],
|
||||
),
|
||||
InkWell(
|
||||
onTap:
|
||||
hasPermission ? null : () => showNoPermissionDialog(context),
|
||||
child: SwitchListTile(
|
||||
title: Text(
|
||||
L10n.of(context).conversationBotStatus,
|
||||
),
|
||||
value: addBot,
|
||||
onChanged: hasPermission
|
||||
? (bool value) {
|
||||
setState(() => addBot = value);
|
||||
}
|
||||
: null, // Keeps the switch disabled
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
AnimatedOpacity(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
opacity: addBot ? 1.0 : 0.5,
|
||||
child: ConversationBotSettingsForm(
|
||||
botOptions: botOptions,
|
||||
discussionKeywordsController:
|
||||
discussionKeywordsController,
|
||||
discussionTopicController:
|
||||
discussionTopicController,
|
||||
customSystemPromptController:
|
||||
customSystemPromptController,
|
||||
hasPermission: hasPermission,
|
||||
enabled: addBot,
|
||||
hasUpdatedMode: hasUpdatedMode,
|
||||
onUpdateBotMode: onUpdateChatMode,
|
||||
onUpdateBotLanguage: onUpdateBotLanguage,
|
||||
onUpdateBotVoice: onUpdateBotVoice,
|
||||
onUpdateBotLanguageLevel: onUpdateBotLanguageLevel,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
AnimatedOpacity(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
opacity: addBot ? 1.0 : 0.5,
|
||||
child: ConversationBotSettingsForm(
|
||||
botOptions: botOptions,
|
||||
discussionKeywordsController:
|
||||
discussionKeywordsController,
|
||||
discussionTopicController: discussionTopicController,
|
||||
customSystemPromptController:
|
||||
customSystemPromptController,
|
||||
hasPermission: hasPermission,
|
||||
enabled: addBot,
|
||||
hasUpdatedMode: hasUpdatedMode,
|
||||
onUpdateBotMode: onUpdateChatMode,
|
||||
onUpdateBotLanguage: onUpdateBotLanguage,
|
||||
onUpdateBotVoice: onUpdateBotVoice,
|
||||
onUpdateBotLanguageLevel: onUpdateBotLanguageLevel,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (hasPermission)
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(null);
|
||||
},
|
||||
child: Text(L10n.of(context).cancel),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (hasPermission)
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (!hasPermission) {
|
||||
Navigator.of(context).pop(null);
|
||||
return;
|
||||
}
|
||||
final isValid = formKey.currentState!.validate();
|
||||
if (!isValid) return;
|
||||
|
||||
updateFromTextControllers();
|
||||
botOptions.targetLanguage ??= MatrixState
|
||||
.pangeaController.languageController.userL2?.langCode;
|
||||
|
||||
Navigator.of(context).pop(botOptions);
|
||||
|
||||
final bool isBotRoomMember =
|
||||
await widget.room.botIsInRoom;
|
||||
if (addBot && !isBotRoomMember) {
|
||||
await widget.room.invite(BotName.byEnvironment);
|
||||
} else if (!addBot && isBotRoomMember) {
|
||||
await widget.room.kick(BotName.byEnvironment);
|
||||
}
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(null);
|
||||
},
|
||||
child: hasPermission
|
||||
? Text(L10n.of(context).confirm)
|
||||
: Text(L10n.of(context).close),
|
||||
child: Text(L10n.of(context).cancel),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (!hasPermission) {
|
||||
Navigator.of(context).pop(null);
|
||||
return;
|
||||
}
|
||||
final isValid = formKey.currentState!.validate();
|
||||
if (!isValid) return;
|
||||
|
||||
updateFromTextControllers();
|
||||
botOptions.targetLanguage ??= MatrixState
|
||||
.pangeaController.languageController.userL2?.langCode;
|
||||
|
||||
Navigator.of(context).pop(botOptions);
|
||||
|
||||
final bool isBotRoomMember = await widget.room.botIsInRoom;
|
||||
if (addBot && !isBotRoomMember) {
|
||||
await widget.room.invite(BotName.byEnvironment);
|
||||
} else if (!addBot && isBotRoomMember) {
|
||||
await widget.room.kick(BotName.byEnvironment);
|
||||
}
|
||||
},
|
||||
child: hasPermission
|
||||
? Text(L10n.of(context).confirm)
|
||||
: Text(L10n.of(context).close),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return kIsWeb
|
||||
? Dialog(child: dialogContent)
|
||||
: Dialog.fullscreen(child: dialogContent);
|
||||
return FullWidthDialog(
|
||||
dialogContent: dialogContent,
|
||||
maxWidth: 450,
|
||||
maxHeight: 725,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
lib/pangea/common/widgets/full_width_dialog.dart
Normal file
36
lib/pangea/common/widgets/full_width_dialog.dart
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FullWidthDialog extends StatelessWidget {
|
||||
final Widget dialogContent;
|
||||
final double maxWidth;
|
||||
final double maxHeight;
|
||||
|
||||
const FullWidthDialog({
|
||||
required this.dialogContent,
|
||||
required this.maxWidth,
|
||||
required this.maxHeight,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final content = ConstrainedBox(
|
||||
constraints: kIsWeb
|
||||
? BoxConstraints(
|
||||
maxWidth: maxWidth,
|
||||
maxHeight: maxHeight,
|
||||
)
|
||||
: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width,
|
||||
maxHeight: MediaQuery.of(context).size.height,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20.0),
|
||||
child: dialogContent,
|
||||
),
|
||||
);
|
||||
|
||||
return kIsWeb ? Dialog(child: content) : Dialog.fullscreen(child: content);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
|
@ -7,6 +6,7 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/pages/settings_learning.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/widgets/country_picker_tile.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/widgets/language_tile.dart';
|
||||
|
|
@ -125,25 +125,11 @@ class SettingsLearningView extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
|
||||
return kIsWeb
|
||||
? Dialog(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 600,
|
||||
maxHeight: 600,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20.0),
|
||||
child: dialogContent,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Dialog.fullscreen(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 600),
|
||||
child: dialogContent,
|
||||
),
|
||||
);
|
||||
return FullWidthDialog(
|
||||
dialogContent: dialogContent,
|
||||
maxWidth: 600,
|
||||
maxHeight: 600,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue