Compare commits
2 Commits
86daad2455
...
b6eb12cf30
Author | SHA1 | Date | |
---|---|---|---|
b6eb12cf30 | |||
80f8129011 |
@ -5,8 +5,9 @@ import 'package:moxxyv2/shared/models/preferences.dart';
|
||||
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
|
||||
import 'package:moxxyv2/ui/constants.dart';
|
||||
import 'package:moxxyv2/ui/helpers.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/row.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/title.dart';
|
||||
import 'package:moxxyv2/ui/widgets/topbar.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
|
||||
Widget _buildLanguageOption(BuildContext context, String localeCode, PreferencesState state) {
|
||||
final selected = state.languageLocaleCode == localeCode;
|
||||
@ -45,57 +46,51 @@ class AppearanceSettingsPage extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: BorderlessTopbar.simple(t.pages.settings.appearance.title),
|
||||
body: BlocBuilder<PreferencesBloc, PreferencesState>(
|
||||
builder: (context, state) => SettingsList(
|
||||
sections: [
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.appearance.languageSection),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.appearance.language),
|
||||
description: Text(
|
||||
t.pages.settings.appearance.languageSubtext(
|
||||
selectedLanguage: localeCodeToLanguageName(state.languageLocaleCode),
|
||||
),
|
||||
),
|
||||
onPressed: (context) async {
|
||||
final result = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SimpleDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(textfieldRadiusRegular),
|
||||
),
|
||||
title: Text(t.pages.settings.appearance.language),
|
||||
children: [
|
||||
_buildLanguageOption(context, 'default', state),
|
||||
_buildLanguageOption(context, 'de', state),
|
||||
_buildLanguageOption(context, 'en', state),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (result == null) {
|
||||
// Do nothing as the dialog was dismissed
|
||||
return;
|
||||
}
|
||||
|
||||
// Change preferences and set the app's locale
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(languageLocaleCode: result),
|
||||
builder: (context, state) => ListView(
|
||||
children: [
|
||||
SectionTitle(t.pages.settings.appearance.languageSection),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.appearance.language,
|
||||
description: t.pages.settings.appearance.languageSubtext(
|
||||
selectedLanguage: localeCodeToLanguageName(state.languageLocaleCode),
|
||||
),
|
||||
onTap: () async {
|
||||
final result = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SimpleDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(textfieldRadiusRegular),
|
||||
),
|
||||
title: Text(t.pages.settings.appearance.language),
|
||||
children: [
|
||||
_buildLanguageOption(context, 'default', state),
|
||||
_buildLanguageOption(context, 'de', state),
|
||||
_buildLanguageOption(context, 'en', state),
|
||||
],
|
||||
);
|
||||
|
||||
if (result == 'default') {
|
||||
LocaleSettings.useDeviceLocale();
|
||||
} else {
|
||||
LocaleSettings.setLocaleRaw(result);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
if (result == null) {
|
||||
// Do nothing as the dialog was dismissed
|
||||
return;
|
||||
}
|
||||
|
||||
// Change preferences and set the app's locale
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(languageLocaleCode: result),
|
||||
),
|
||||
);
|
||||
|
||||
if (result == 'default') {
|
||||
LocaleSettings.useDeviceLocale();
|
||||
} else {
|
||||
LocaleSettings.setLocaleRaw(result);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -9,11 +9,12 @@ import 'package:moxxyv2/ui/bloc/cropbackground_bloc.dart';
|
||||
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
|
||||
import 'package:moxxyv2/ui/constants.dart';
|
||||
import 'package:moxxyv2/ui/helpers.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/row.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/title.dart';
|
||||
import 'package:moxxyv2/ui/widgets/topbar.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
|
||||
class ConversationSettingsPage extends StatelessWidget {
|
||||
const ConversationSettingsPage({ super.key });
|
||||
@ -67,89 +68,94 @@ class ConversationSettingsPage extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: BorderlessTopbar.simple(t.pages.settings.conversation.title),
|
||||
body: BlocBuilder<PreferencesBloc, PreferencesState>(
|
||||
builder: (context, state) => SettingsList(
|
||||
sections: [
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.conversation.appearance),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.conversation.selectBackgroundImage),
|
||||
description: Text(t.pages.settings.conversation.selectBackgroundImageDescription),
|
||||
onPressed: (context) async {
|
||||
final backgroundPath = await _pickBackgroundImage();
|
||||
builder: (context, state) => ListView(
|
||||
children: [
|
||||
SectionTitle(t.pages.settings.conversation.appearance),
|
||||
|
||||
if (backgroundPath != null) {
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<CropBackgroundBloc>().add(
|
||||
CropBackgroundRequestedEvent(backgroundPath),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.conversation.removeBackgroundImage),
|
||||
onPressed: (context) async {
|
||||
final result = await showConfirmationDialog(
|
||||
t.pages.settings.conversation.removeBackgroundImageConfirmTitle,
|
||||
t.pages.settings.conversation.removeBackgroundImageConfirmBody,
|
||||
context,
|
||||
);
|
||||
SettingsRow(
|
||||
title: t.pages.settings.conversation.selectBackgroundImage,
|
||||
description: t.pages.settings.conversation.selectBackgroundImageDescription,
|
||||
onTap: () async {
|
||||
final backgroundPath = await _pickBackgroundImage();
|
||||
|
||||
if (result) {
|
||||
// ignore: use_build_context_synchronously
|
||||
await _removeBackgroundImage(context, state);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
if (backgroundPath != null) {
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<CropBackgroundBloc>().add(
|
||||
CropBackgroundRequestedEvent(backgroundPath),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.conversation.behaviourSection),
|
||||
tiles: [
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.conversation.contactsIntegration),
|
||||
description: Text(t.pages.settings.conversation.contactsIntegrationBody),
|
||||
initialValue: state.enableContactIntegration,
|
||||
onToggle: (value) async {
|
||||
// Ensure that we have the permission before changing the value
|
||||
if (value && await Permission.contacts.status == PermissionStatus.denied) {
|
||||
if (!(await Permission.contacts.request().isGranted)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(enableContactIntegration: value),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
SettingsRow(
|
||||
title: t.pages.settings.conversation.removeBackgroundImage,
|
||||
onTap: () async {
|
||||
final result = await showConfirmationDialog(
|
||||
t.pages.settings.conversation.removeBackgroundImageConfirmTitle,
|
||||
t.pages.settings.conversation.removeBackgroundImageConfirmBody,
|
||||
context,
|
||||
);
|
||||
|
||||
if (result) {
|
||||
// ignore: use_build_context_synchronously
|
||||
await _removeBackgroundImage(context, state);
|
||||
}
|
||||
},
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.conversation.newChatsSection),
|
||||
tiles: [
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.conversation.newChatsMuteByDefault),
|
||||
initialValue: state.defaultMuteState,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
|
||||
SectionTitle(t.pages.settings.conversation.behaviourSection),
|
||||
|
||||
SettingsRow(
|
||||
title: t.pages.settings.conversation.contactsIntegration,
|
||||
description: t.pages.settings.conversation.contactsIntegrationBody,
|
||||
suffix: Switch(
|
||||
value: state.enableContactIntegration,
|
||||
onChanged: (value) async {
|
||||
// Ensure that we have the permission before changing the value
|
||||
if (value && await Permission.contacts.status == PermissionStatus.denied) {
|
||||
if (!(await Permission.contacts.request().isGranted)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(enableContactIntegration: value),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SectionTitle(t.pages.settings.conversation.newChatsSection),
|
||||
|
||||
SettingsRow(
|
||||
title: t.pages.settings.conversation.newChatsMuteByDefault,
|
||||
suffix: Switch(
|
||||
value: state.defaultMuteState,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(defaultMuteState: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.conversation.newChatsE2EE),
|
||||
initialValue: state.enableOmemoByDefault,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SettingsRow(
|
||||
title: t.pages.settings.conversation.newChatsE2EE,
|
||||
suffix: Switch(
|
||||
value: state.enableOmemoByDefault,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(enableOmemoByDefault: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -4,8 +4,9 @@ import 'package:moxxyv2/i18n/strings.g.dart';
|
||||
import 'package:moxxyv2/shared/models/preferences.dart';
|
||||
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
|
||||
import 'package:moxxyv2/ui/constants.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/row.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/title.dart';
|
||||
import 'package:moxxyv2/ui/widgets/topbar.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
|
||||
class DebuggingPage extends StatelessWidget {
|
||||
DebuggingPage({ super.key })
|
||||
@ -28,111 +29,112 @@ class DebuggingPage extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: BorderlessTopbar.simple(t.pages.settings.debugging.title),
|
||||
body: BlocBuilder<PreferencesBloc, PreferencesState>(
|
||||
builder: (context, state) => SettingsList(
|
||||
sections: [
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.debugging.generalSection),
|
||||
tiles: [
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.debugging.generalEnableDebugging),
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
builder: (context, state) => ListView(
|
||||
children: [
|
||||
SectionTitle(t.pages.settings.debugging.generalSection),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.debugging.generalEnableDebugging,
|
||||
suffix: Switch(
|
||||
value: state.debugEnabled,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(debugEnabled: value),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.debugging.generalEncryptionPassword,
|
||||
description: t.pages.settings.debugging.generalEncryptionPasswordSubtext,
|
||||
onTap: () {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text(t.pages.settings.debugging.generalEncryptionPassword),
|
||||
content: TextField(
|
||||
minLines: 1,
|
||||
obscureText: true,
|
||||
controller: _passphraseController,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t.global.dialogAccept),
|
||||
onPressed: () {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(debugPassphrase: _passphraseController.text),
|
||||
),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
initialValue: state.debugEnabled,
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.debugging.generalEncryptionPassword),
|
||||
description: Text(t.pages.settings.debugging.generalEncryptionPasswordSubtext),
|
||||
onPressed: (context) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text(t.pages.settings.debugging.generalEncryptionPassword),
|
||||
content: TextField(
|
||||
minLines: 1,
|
||||
obscureText: true,
|
||||
controller: _passphraseController,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t.global.dialogAccept),
|
||||
onPressed: () {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(debugPassphrase: _passphraseController.text),
|
||||
),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.debugging.generalLoggingIp),
|
||||
description: Text(t.pages.settings.debugging.generalLoggingIpSubtext),
|
||||
onPressed: (context) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text(t.pages.settings.debugging.generalLoggingIp),
|
||||
content: TextField(
|
||||
minLines: 1,
|
||||
controller: _ipController,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t.global.dialogAccept),
|
||||
onPressed: () {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(debugIp: _ipController.text),
|
||||
),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.debugging.generalLoggingPort),
|
||||
description: Text(t.pages.settings.debugging.generalLoggingPortSubtext),
|
||||
onPressed: (context) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text(t.pages.settings.debugging.generalLoggingPort),
|
||||
content: TextField(
|
||||
minLines: 1,
|
||||
controller: _portController,
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t.global.dialogAccept),
|
||||
onPressed: () {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(debugPort: int.parse(_portController.text)),
|
||||
),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
)
|
||||
);
|
||||
},
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.debugging.generalLoggingIp,
|
||||
description: t.pages.settings.debugging.generalLoggingIpSubtext,
|
||||
onTap: () {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text(t.pages.settings.debugging.generalLoggingIp),
|
||||
content: TextField(
|
||||
minLines: 1,
|
||||
obscureText: true,
|
||||
controller: _ipController,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t.global.dialogAccept),
|
||||
onPressed: () {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(debugIp: _ipController.text),
|
||||
),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.debugging.generalLoggingPort,
|
||||
description: t.pages.settings.debugging.generalLoggingPortSubtext,
|
||||
onTap: () {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text(t.pages.settings.debugging.generalLoggingPort),
|
||||
content: TextField(
|
||||
minLines: 1,
|
||||
controller: _portController,
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t.global.dialogAccept),
|
||||
onPressed: () {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(debugPort: int.parse(_portController.text)),
|
||||
),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -4,8 +4,9 @@ import 'package:moxxyv2/i18n/strings.g.dart';
|
||||
import 'package:moxxyv2/shared/models/preferences.dart';
|
||||
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
|
||||
import 'package:moxxyv2/ui/constants.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/row.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/title.dart';
|
||||
import 'package:moxxyv2/ui/widgets/topbar.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
|
||||
class _AutoDownloadSizes {
|
||||
const _AutoDownloadSizes(this.text, this.value);
|
||||
@ -45,6 +46,9 @@ class AutoDownloadSizeDialogState extends State<AutoDownloadSizeDialog> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(textfieldRadiusRegular),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
vertical: 12,
|
||||
@ -101,56 +105,66 @@ class NetworkPage extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: BorderlessTopbar.simple(t.pages.settings.network.title),
|
||||
body: BlocBuilder<PreferencesBloc, PreferencesState>(
|
||||
builder: (context, state) => SettingsList(
|
||||
sections: [
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.network.automaticDownloadsSection),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.network.automaticDownloadsText),
|
||||
),
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.network.wifi),
|
||||
initialValue: state.autoDownloadWifi,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(autoDownloadWifi: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.network.mobileData),
|
||||
initialValue: state.autoDownloadMobile,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(autoDownloadMobile: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.network.automaticDownloadsMaximumSize),
|
||||
description: Text(t.pages.settings.network.automaticDownloadsMaximumSizeSubtext),
|
||||
onPressed: (context) async {
|
||||
final result = await showDialog<int>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AutoDownloadSizeDialog(
|
||||
selectedValueInitial: state.maximumAutoDownloadSize,
|
||||
),
|
||||
);
|
||||
if (result == null) return;
|
||||
if (state.maximumAutoDownloadSize == result) return;
|
||||
builder: (context, state) => ListView(
|
||||
children: [
|
||||
SectionTitle(t.pages.settings.network.automaticDownloadsSection),
|
||||
|
||||
SettingsRow(
|
||||
title: t.pages.settings.network.automaticDownloadsText,
|
||||
),
|
||||
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(maximumAutoDownloadSize: result),
|
||||
),
|
||||
);
|
||||
},
|
||||
SettingsRow(
|
||||
title: t.pages.settings.network.wifi,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 16,
|
||||
),
|
||||
suffix: Switch(
|
||||
value: state.autoDownloadWifi,
|
||||
onChanged: (value) => context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(autoDownloadWifi: value),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.network.mobileData,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 16,
|
||||
),
|
||||
suffix: Switch(
|
||||
value: state.autoDownloadMobile,
|
||||
onChanged: (value) => context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(autoDownloadMobile: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
SettingsRow(
|
||||
title: t.pages.settings.network.automaticDownloadsMaximumSize,
|
||||
description: t.pages.settings.network.automaticDownloadsMaximumSizeSubtext,
|
||||
onTap: () async {
|
||||
final result = await showDialog<int>(
|
||||
context: context,
|
||||
builder: (context) => AutoDownloadSizeDialog(
|
||||
selectedValueInitial: state.maximumAutoDownloadSize,
|
||||
),
|
||||
);
|
||||
if (result == null) return;
|
||||
if (state.maximumAutoDownloadSize == result) return;
|
||||
|
||||
// ignore: use_build_context_synchronously
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(maximumAutoDownloadSize: result),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -5,8 +5,9 @@ import 'package:moxxyv2/shared/models/preferences.dart';
|
||||
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
|
||||
import 'package:moxxyv2/ui/constants.dart';
|
||||
import 'package:moxxyv2/ui/pages/settings/privacy/tile.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/row.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/title.dart';
|
||||
import 'package:moxxyv2/ui/widgets/topbar.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
|
||||
class PrivacyPage extends StatelessWidget {
|
||||
const PrivacyPage({ super.key });
|
||||
@ -23,88 +24,99 @@ class PrivacyPage extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: BorderlessTopbar.simple(t.pages.settings.privacy.title),
|
||||
body: BlocBuilder<PreferencesBloc, PreferencesState>(
|
||||
builder: (context, state) => SettingsList(
|
||||
sections: [
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.privacy.generalSection),
|
||||
tiles: [
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.privacy.showContactRequests),
|
||||
description: Text(t.pages.settings.privacy.showContactRequestsSubtext),
|
||||
initialValue: state.showSubscriptionRequests,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
builder: (context, state) => ListView(
|
||||
children: [
|
||||
SectionTitle(t.pages.settings.privacy.generalSection),
|
||||
|
||||
SettingsRow(
|
||||
title: t.pages.settings.privacy.showContactRequests,
|
||||
description: t.pages.settings.privacy.showContactRequestsSubtext,
|
||||
suffix: Switch(
|
||||
value: state.showSubscriptionRequests,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(showSubscriptionRequests: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.privacy.profilePictureVisibility),
|
||||
description: Text(t.pages.settings.privacy.profilePictureVisibilitSubtext),
|
||||
initialValue: state.isAvatarPublic,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.privacy.profilePictureVisibility,
|
||||
description: t.pages.settings.privacy.profilePictureVisibilitSubtext,
|
||||
suffix: Switch(
|
||||
value: state.isAvatarPublic,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(isAvatarPublic: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.privacy.autoAcceptSubscriptionRequests),
|
||||
description: Text(t.pages.settings.privacy.autoAcceptSubscriptionRequestsSubtext),
|
||||
initialValue: state.autoAcceptSubscriptionRequests,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.privacy.autoAcceptSubscriptionRequests,
|
||||
description: t.pages.settings.privacy.autoAcceptSubscriptionRequestsSubtext,
|
||||
suffix: Switch(
|
||||
value: state.autoAcceptSubscriptionRequests,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(autoAcceptSubscriptionRequests: value),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.privacy.conversationsSection),
|
||||
tiles: [
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.privacy.sendChatMarkers),
|
||||
description: Text(t.pages.settings.privacy.sendChatMarkersSubtext),
|
||||
initialValue: state.sendChatMarkers,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
|
||||
SectionTitle(t.pages.settings.privacy.conversationsSection),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.privacy.sendChatMarkers,
|
||||
description: t.pages.settings.privacy.sendChatMarkersSubtext,
|
||||
suffix: Switch(
|
||||
value: state.sendChatMarkers,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(sendChatMarkers: value),
|
||||
),
|
||||
),
|
||||
),
|
||||
SettingsTile.switchTile(
|
||||
title: Text(t.pages.settings.privacy.sendChatStates),
|
||||
description: Text(t.pages.settings.privacy.sendChatStatesSubtext),
|
||||
initialValue: state.sendChatStates,
|
||||
onToggle: (value) => context.read<PreferencesBloc>().add(
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.privacy.sendChatStates,
|
||||
description: t.pages.settings.privacy.sendChatStatesSubtext,
|
||||
suffix: Switch(
|
||||
value: state.sendChatStates,
|
||||
onChanged: (value) {
|
||||
context.read<PreferencesBloc>().add(
|
||||
PreferencesChangedEvent(
|
||||
state.copyWith(sendChatStates: value),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.privacy.redirectsSection),
|
||||
tiles: [
|
||||
RedirectSettingsTile(
|
||||
'Youtube',
|
||||
'Invidious',
|
||||
(state) => state.youtubeRedirect,
|
||||
(state, value) => state.copyWith(youtubeRedirect: value),
|
||||
(state) => state.enableYoutubeRedirect,
|
||||
(state, value) => state.copyWith(enableYoutubeRedirect: value),
|
||||
),
|
||||
RedirectSettingsTile(
|
||||
'Twitter',
|
||||
'Nitter',
|
||||
(state) => state.twitterRedirect,
|
||||
(state, value) => state.copyWith(twitterRedirect: value),
|
||||
(state) => state.enableTwitterRedirect,
|
||||
(state, value) => state.copyWith(enableTwitterRedirect: value),
|
||||
),
|
||||
],
|
||||
|
||||
SectionTitle(t.pages.settings.privacy.redirectsSection),
|
||||
RedirectSettingsTile(
|
||||
'Youtube',
|
||||
'Invidious',
|
||||
(state) => state.youtubeRedirect,
|
||||
(state, value) => state.copyWith(youtubeRedirect: value),
|
||||
(state) => state.enableYoutubeRedirect,
|
||||
(state, value) => state.copyWith(enableYoutubeRedirect: value),
|
||||
),
|
||||
RedirectSettingsTile(
|
||||
'Twitter',
|
||||
'Nitter',
|
||||
(state) => state.twitterRedirect,
|
||||
(state, value) => state.copyWith(twitterRedirect: value),
|
||||
(state) => state.enableTwitterRedirect,
|
||||
(state, value) => state.copyWith(enableTwitterRedirect: value),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -5,9 +5,9 @@ import 'package:moxxyv2/shared/models/preferences.dart';
|
||||
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
|
||||
import 'package:moxxyv2/ui/helpers.dart';
|
||||
import 'package:moxxyv2/ui/pages/settings/privacy/redirect_dialog.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/row.dart';
|
||||
|
||||
class RedirectSettingsTile extends AbstractSettingsTile {
|
||||
class RedirectSettingsTile extends StatelessWidget {
|
||||
const RedirectSettingsTile(
|
||||
this.serviceName,
|
||||
this.exampleProxy,
|
||||
@ -27,28 +27,13 @@ class RedirectSettingsTile extends AbstractSettingsTile {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<PreferencesBloc, PreferencesState>(
|
||||
builder: (context, state) => SettingsTile(
|
||||
title: Text(t.pages.settings.privacy.redirectsTitle(serviceName: serviceName)),
|
||||
description: Column(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
t.pages.settings.privacy.redirectText(
|
||||
serviceName: serviceName,
|
||||
exampleProxy: exampleProxy,
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
t.pages.settings.privacy.currentlySelected(proxy: getProxy(state)),
|
||||
),
|
||||
),
|
||||
],
|
||||
builder: (context, state) => SettingsRow(
|
||||
title: t.pages.settings.privacy.redirectsTitle(serviceName: serviceName),
|
||||
description: t.pages.settings.privacy.redirectText(
|
||||
serviceName: serviceName,
|
||||
exampleProxy: exampleProxy,
|
||||
),
|
||||
onPressed: (context) {
|
||||
onTap: () {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => RedirectDialog(
|
||||
@ -60,7 +45,7 @@ class RedirectSettingsTile extends AbstractSettingsTile {
|
||||
),
|
||||
);
|
||||
},
|
||||
trailing: Switch(
|
||||
suffix: Switch(
|
||||
value: getEnabled(state),
|
||||
onChanged: (value) {
|
||||
if (getProxy(state).isEmpty) {
|
||||
|
@ -5,9 +5,10 @@ import 'package:moxxyv2/i18n/strings.g.dart';
|
||||
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
|
||||
import 'package:moxxyv2/ui/constants.dart';
|
||||
import 'package:moxxyv2/ui/helpers.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/row.dart';
|
||||
import 'package:moxxyv2/ui/widgets/settings/title.dart';
|
||||
import 'package:moxxyv2/ui/widgets/topbar.dart';
|
||||
import 'package:phosphor_flutter/phosphor_flutter.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
|
||||
class SettingsPage extends StatelessWidget {
|
||||
const SettingsPage({ super.key });
|
||||
@ -23,91 +24,126 @@ class SettingsPage extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: BorderlessTopbar.simple(t.pages.settings.settings.title),
|
||||
body: SettingsList(
|
||||
sections: [
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.settings.conversationsSection),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.conversation.title),
|
||||
leading: const Icon(Icons.chat_bubble),
|
||||
onPressed: (context) => Navigator.pushNamed(context, conversationSettingsRoute),
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.stickers.title),
|
||||
leading: const Icon(PhosphorIcons.stickerBold),
|
||||
onPressed: (context) => Navigator.pushNamed(context, stickersRoute),
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.network.title),
|
||||
leading: const Icon(Icons.network_wifi),
|
||||
onPressed: (context) => Navigator.pushNamed(context, networkRoute),
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.privacy.title),
|
||||
leading: const Icon(Icons.shield),
|
||||
onPressed: (context) => Navigator.pushNamed(context, privacyRoute),
|
||||
)
|
||||
],
|
||||
body: ListView(
|
||||
children: [
|
||||
SectionTitle(t.pages.settings.settings.conversationsSection),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.settings.conversationsSection,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.chat_bubble),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, conversationSettingsRoute);
|
||||
},
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.stickers.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(PhosphorIcons.stickerBold),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, stickersRoute);
|
||||
},
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.network.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.network_wifi),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, networkRoute);
|
||||
},
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.privacy.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.shield),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, privacyRoute);
|
||||
},
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.settings.accountSection),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: Text(t.pages.blocklist.title),
|
||||
leading: const Icon(Icons.block),
|
||||
onPressed: (context) => Navigator.pushNamed(context, blocklistRoute),
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.settings.signOut),
|
||||
leading: const Icon(Icons.logout),
|
||||
onPressed: (context) async {
|
||||
final result = await showConfirmationDialog(
|
||||
t.pages.settings.settings.signOutConfirmTitle,
|
||||
t.pages.settings.settings.signOutConfirmBody,
|
||||
context,
|
||||
);
|
||||
|
||||
if (result) {
|
||||
GetIt.I.get<PreferencesBloc>().add(SignedOutEvent());
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
SectionTitle(t.pages.settings.settings.accountSection),
|
||||
SettingsRow(
|
||||
title: t.pages.blocklist.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.block),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, blocklistRoute);
|
||||
},
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.settings.miscellaneousSection),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.appearance.title),
|
||||
leading: const Icon(Icons.brush),
|
||||
onPressed: (context) => Navigator.pushNamed(context, appearanceRoute),
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.about.title),
|
||||
leading: const Icon(Icons.info),
|
||||
onPressed: (context) => Navigator.pushNamed(context, aboutRoute),
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.licenses.title),
|
||||
leading: const Icon(Icons.description),
|
||||
onPressed: (context) => Navigator.pushNamed(context, licensesRoute),
|
||||
)
|
||||
],
|
||||
SettingsRow(
|
||||
title: t.pages.settings.settings.signOut,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.logout),
|
||||
),
|
||||
onTap: () async {
|
||||
final result = await showConfirmationDialog(
|
||||
t.pages.settings.settings.signOutConfirmTitle,
|
||||
t.pages.settings.settings.signOutConfirmBody,
|
||||
context,
|
||||
);
|
||||
|
||||
if (result) {
|
||||
GetIt.I.get<PreferencesBloc>().add(SignedOutEvent());
|
||||
}
|
||||
},
|
||||
),
|
||||
// TODO(Unknown): Maybe also have a switch somewhere
|
||||
...kDebugMode ? [
|
||||
SettingsSection(
|
||||
title: Text(t.pages.settings.settings.debuggingSection),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: Text(t.pages.settings.debugging.title),
|
||||
leading: const Icon(Icons.info),
|
||||
onPressed: (context) => Navigator.pushNamed(context, debuggingRoute),
|
||||
)
|
||||
],
|
||||
)
|
||||
] : []
|
||||
|
||||
SectionTitle(t.pages.settings.settings.miscellaneousSection),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.appearance.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.logout),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, appearanceRoute);
|
||||
},
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.about.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.info),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, aboutRoute);
|
||||
},
|
||||
),
|
||||
SettingsRow(
|
||||
title: t.pages.settings.licenses.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.info),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, licensesRoute);
|
||||
},
|
||||
),
|
||||
|
||||
if (kDebugMode)
|
||||
SectionTitle(t.pages.settings.settings.debuggingSection),
|
||||
|
||||
if (kDebugMode)
|
||||
SettingsRow(
|
||||
title: t.pages.settings.debugging.title,
|
||||
prefix: const Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: Icon(Icons.info),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, debuggingRoute);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -12,6 +12,10 @@ class SettingsRow extends StatelessWidget {
|
||||
this.prefix,
|
||||
this.onTap,
|
||||
this.crossAxisAlignment = CrossAxisAlignment.center,
|
||||
this.padding = const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: 16,
|
||||
),
|
||||
super.key,
|
||||
});
|
||||
final String title;
|
||||
@ -21,16 +25,14 @@ class SettingsRow extends StatelessWidget {
|
||||
final Widget? prefix;
|
||||
final void Function()? onTap;
|
||||
final CrossAxisAlignment crossAxisAlignment;
|
||||
final EdgeInsets padding;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
horizontal: 16,
|
||||
),
|
||||
padding: padding,
|
||||
child: Row(
|
||||
crossAxisAlignment: crossAxisAlignment,
|
||||
children: [
|
||||
|
@ -1150,13 +1150,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
settings_ui:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: settings_ui
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
share_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -84,7 +84,6 @@ dependencies:
|
||||
qr_flutter: 4.0.0
|
||||
random_string: 2.3.1
|
||||
record: 4.4.3
|
||||
settings_ui: 2.0.2
|
||||
share_handler: 0.0.16
|
||||
slang: 3.4.0
|
||||
slang_flutter: 3.4.0
|
||||
|
Loading…
Reference in New Issue
Block a user