You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fluffychat/lib/pangea/learning_settings/pages/settings_learning_view.dart

351 lines
16 KiB
Dart

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:app_settings/app_settings.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/chat_settings/widgets/language_level_dropdown.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/models/language_model.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/p_language_dropdown.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/p_settings_switch_list_tile.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/matrix.dart';
class SettingsLearningView extends StatelessWidget {
final SettingsLearningController controller;
const SettingsLearningView(this.controller, {super.key});
void _showKeyboardSettingsDialog(BuildContext context) {
String title;
String? steps;
String? description;
String buttonText;
VoidCallback buttonAction;
if (kIsWeb) {
title = L10n.of(context).autocorrectNotAvailable; // Default
buttonText = 'OK';
buttonAction = () {
Navigator.of(context).pop();
};
} else if (Platform.isIOS) {
title = L10n.of(context).enableAutocorrectPopupTitle;
steps = L10n.of(context).enableAutocorrectPopupSteps;
description = L10n.of(context).enableAutocorrectPopupDescription;
buttonText = L10n.of(context).settings;
buttonAction = () {
AppSettings.openAppSettings();
};
} else {
title = L10n.of(context).downloadGboardTitle;
steps = L10n.of(context).downloadGboardSteps;
description = L10n.of(context).downloadGboardDescription;
buttonText = L10n.of(context).downloadGboard;
buttonAction = () {
launchUrlString(
'https://play.google.com/store/apps/details?id=com.google.android.inputmethod.latin',
);
};
}
showAdaptiveDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog.adaptive(
title: Text(L10n.of(context).enableAutocorrectWarning),
content: SingleChildScrollView(
child: Column(
spacing: 8.0,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(title),
if (steps != null)
Text(
steps,
textAlign: TextAlign.start,
),
if (description != null) Text(description),
],
),
),
actions: [
TextButton(
child: Text(L10n.of(context).close),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
onPressed: buttonAction,
child: Text(buttonText),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Matrix.of(context).client.onSync.stream.where((update) {
return update.accountData != null &&
update.accountData!.any(
(event) => event.type == ModelKey.userProfile,
);
}),
builder: (context, _) {
final dialogContent = Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
L10n.of(context).learningSettings,
),
leading: IconButton(
icon: const Icon(Icons.close),
onPressed: controller.onSettingsClose,
),
),
body: ListTileTheme(
iconColor: Theme.of(context).textTheme.bodyLarge!.color,
child: Form(
key: controller.formKey,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 8.0,
),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
spacing: 16.0,
children: [
PLanguageDropdown(
onChange: (lang) =>
controller.setSelectedLanguage(
sourceLanguage: lang,
),
initialLanguage:
controller.selectedSourceLanguage ??
LanguageModel.unknown,
languages: MatrixState.pangeaController
.pLanguageStore.baseOptions,
isL2List: false,
decorationText: L10n.of(context).myBaseLanguage,
hasError: controller.languageMatchError != null,
backgroundColor: Theme.of(context)
.colorScheme
.surfaceContainerHigh,
),
PLanguageDropdown(
onChange: (lang) =>
controller.setSelectedLanguage(
targetLanguage: lang,
),
initialLanguage:
controller.selectedTargetLanguage,
languages: MatrixState.pangeaController
.pLanguageStore.targetOptions,
isL2List: true,
decorationText: L10n.of(context).iWantToLearn,
error: controller.languageMatchError,
backgroundColor: Theme.of(context)
.colorScheme
.surfaceContainerHigh,
),
CountryPickerDropdown(controller),
LanguageLevelDropdown(
initialLevel: controller.cefrLevel,
onChanged: controller.setCefrLevel,
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.white54,
),
borderRadius: BorderRadius.circular(8.0),
),
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
ProfileSettingsSwitchListTile.adaptive(
defaultValue: controller
.getToolSetting(ToolSetting.autoIGC),
title:
ToolSetting.autoIGC.toolName(context),
subtitle: ToolSetting.autoIGC
.toolDescription(context),
onChange: (bool value) =>
controller.updateToolSetting(
ToolSetting.autoIGC,
value,
),
enabled: true,
),
ProfileSettingsSwitchListTile.adaptive(
defaultValue: controller.getToolSetting(
ToolSetting.enableAutocorrect,
),
title: ToolSetting.enableAutocorrect
.toolName(context),
subtitle: ToolSetting.enableAutocorrect
.toolDescription(context),
onChange: (bool value) {
controller.updateToolSetting(
ToolSetting.enableAutocorrect,
value,
);
if (value) {
_showKeyboardSettingsDialog(context);
}
},
enabled: true,
),
],
),
),
for (final toolSetting
in ToolSetting.values.where(
(tool) =>
tool.isAvailableSetting &&
tool != ToolSetting.autoIGC &&
tool != ToolSetting.enableAutocorrect,
))
Column(
children: [
ProfileSettingsSwitchListTile.adaptive(
defaultValue: controller
.getToolSetting(toolSetting),
title: toolSetting.toolName(context),
subtitle: toolSetting ==
ToolSetting.enableTTS &&
!controller.isTTSSupported
? null
: toolSetting
.toolDescription(context),
onChange: (bool value) =>
controller.updateToolSetting(
toolSetting,
value,
),
enabled:
toolSetting == ToolSetting.enableTTS
? controller.isTTSSupported
: true,
),
if (toolSetting == ToolSetting.enableTTS &&
!controller.isTTSSupported)
Row(
children: [
Padding(
padding: const EdgeInsets.only(
right: 16.0,
),
child: Icon(
Icons.info_outlined,
color: Theme.of(context)
.disabledColor,
),
),
Flexible(
child: RichText(
text: TextSpan(
text: L10n.of(context)
.couldNotFindTTS,
style: TextStyle(
color: Theme.of(context)
.disabledColor,
),
children: [
if (PlatformInfos.isWindows ||
PlatformInfos.isAndroid)
TextSpan(
text: L10n.of(context)
.ttsInstructionsHyperlink,
style: const TextStyle(
color: Colors.blue,
fontWeight:
FontWeight.bold,
decoration:
TextDecoration
.underline,
),
recognizer:
TapGestureRecognizer()
..onTap = () {
launchUrlString(
PlatformInfos
.isWindows
? AppConfig
.windowsTTSDownloadInstructions
: AppConfig
.androidTTSDownloadInstructions,
);
},
),
],
),
),
),
],
),
],
),
SwitchListTile.adaptive(
value: controller.publicProfile,
onChanged: controller.setPublicProfile,
title: Text(
L10n.of(context).publicProfileTitle,
),
subtitle: Text(
L10n.of(context).publicProfileDesc,
),
activeColor: AppConfig.activeToggleColor,
contentPadding: EdgeInsets.zero,
),
],
),
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: controller.submit,
child: Text(L10n.of(context).saveChanges),
),
),
),
],
),
),
),
),
);
return FullWidthDialog(
dialogContent: dialogContent,
maxWidth: 600,
maxHeight: 800,
);
},
);
}
}