Browse Source

neon: constrain settings pages

pull/456/head
Nikolas Rimikis 1 year ago
parent
commit
18f062a614
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 190
      packages/neon/neon/lib/src/pages/account_settings.dart
  2. 98
      packages/neon/neon/lib/src/pages/nextcloud_app_settings.dart
  3. 457
      packages/neon/neon/lib/src/pages/settings.dart

190
packages/neon/neon/lib/src/pages/account_settings.dart

@ -10,13 +10,14 @@ import 'package:neon/src/settings/widgets/custom_settings_tile.dart';
import 'package:neon/src/settings/widgets/dropdown_button_settings_tile.dart'; import 'package:neon/src/settings/widgets/dropdown_button_settings_tile.dart';
import 'package:neon/src/settings/widgets/settings_category.dart'; import 'package:neon/src/settings/widgets/settings_category.dart';
import 'package:neon/src/settings/widgets/settings_list.dart'; import 'package:neon/src/settings/widgets/settings_list.dart';
import 'package:neon/src/theme/dialog.dart';
import 'package:neon/src/utils/confirmation_dialog.dart'; import 'package:neon/src/utils/confirmation_dialog.dart';
import 'package:neon/src/widgets/exception.dart'; import 'package:neon/src/widgets/exception.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart'; import 'package:neon/src/widgets/linear_progress_indicator.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
class AccountSettingsPage extends StatelessWidget { class AccountSettingsPage extends StatelessWidget {
AccountSettingsPage({ const AccountSettingsPage({
required this.bloc, required this.bloc,
required this.account, required this.account,
super.key, super.key,
@ -25,104 +26,115 @@ class AccountSettingsPage extends StatelessWidget {
final AccountsBloc bloc; final AccountsBloc bloc;
final Account account; final Account account;
late final _options = bloc.getOptionsFor(account);
late final _userDetailsBloc = bloc.getUserDetailsBlocFor(account);
late final _name = account.client.humanReadableID;
@override @override
Widget build(final BuildContext context) => Scaffold( Widget build(final BuildContext context) {
resizeToAvoidBottomInset: false, final options = bloc.getOptionsFor(account);
appBar: AppBar( final userDetailsBloc = bloc.getUserDetailsBlocFor(account);
title: Text(_name), final name = account.client.humanReadableID;
actions: [
IconButton( final appBar = AppBar(
onPressed: () async { title: Text(name),
if (await showConfirmationDialog( actions: [
context, IconButton(
AppLocalizations.of(context).accountOptionsRemoveConfirm(account.client.humanReadableID), onPressed: () async {
)) { if (await showConfirmationDialog(
final isActive = bloc.activeAccount.value == account; context,
AppLocalizations.of(context).accountOptionsRemoveConfirm(account.client.humanReadableID),
)) {
final isActive = bloc.activeAccount.value == account;
bloc.removeAccount(account); bloc.removeAccount(account);
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously
if (!context.mounted) { if (!context.mounted) {
return; return;
} }
if (isActive) { if (isActive) {
const HomeRoute().go(context); const HomeRoute().go(context);
} else { } else {
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
} }
}, },
tooltip: AppLocalizations.of(context).accountOptionsRemove, tooltip: AppLocalizations.of(context).accountOptionsRemove,
icon: Icon(MdiIcons.delete), icon: Icon(MdiIcons.delete),
),
IconButton(
onPressed: () async {
if (await showConfirmationDialog(
context,
AppLocalizations.of(context).settingsResetForConfirmation(_name),
)) {
await _options.reset();
}
},
tooltip: AppLocalizations.of(context).settingsResetFor(_name),
icon: Icon(MdiIcons.cogRefresh),
),
],
), ),
body: ResultBuilder<ProvisioningApiUserDetails>.behaviorSubject( IconButton(
stream: _userDetailsBloc.userDetails, onPressed: () async {
builder: (final context, final userDetails) => SettingsList( if (await showConfirmationDialog(
categories: [ context,
SettingsCategory( AppLocalizations.of(context).settingsResetForConfirmation(name),
title: Text(AppLocalizations.of(context).accountOptionsCategoryStorageInfo), )) {
tiles: [ await options.reset();
CustomSettingsTile( }
title: Column( },
crossAxisAlignment: CrossAxisAlignment.start, tooltip: AppLocalizations.of(context).settingsResetFor(name),
children: [ icon: Icon(MdiIcons.cogRefresh),
if (userDetails.hasData) ...[ ),
LinearProgressIndicator( ],
value: userDetails.requireData.quota.relative / 100, );
backgroundColor: Theme.of(context).colorScheme.primary.withOpacity(0.3),
), final body = ResultBuilder<ProvisioningApiUserDetails>.behaviorSubject(
const SizedBox( stream: userDetailsBloc.userDetails,
height: 10, builder: (final context, final userDetails) => SettingsList(
), categories: [
Text( SettingsCategory(
AppLocalizations.of(context).accountOptionsQuotaUsedOf( title: Text(AppLocalizations.of(context).accountOptionsCategoryStorageInfo),
filesize(userDetails.requireData.quota.used, 1), tiles: [
filesize(userDetails.requireData.quota.total, 1), CustomSettingsTile(
userDetails.requireData.quota.relative.toString(), title: Column(
), crossAxisAlignment: CrossAxisAlignment.start,
), children: [
], if (userDetails.hasData) ...[
NeonException( LinearProgressIndicator(
userDetails.error, value: userDetails.requireData.quota.relative / 100,
onRetry: _userDetailsBloc.refresh, backgroundColor: Theme.of(context).colorScheme.primary.withOpacity(0.3),
), ),
NeonLinearProgressIndicator( const SizedBox(
visible: userDetails.isLoading, height: 10,
),
Text(
AppLocalizations.of(context).accountOptionsQuotaUsedOf(
filesize(userDetails.requireData.quota.used, 1),
filesize(userDetails.requireData.quota.total, 1),
userDetails.requireData.quota.relative.toString(),
), ),
], ),
],
NeonException(
userDetails.error,
onRetry: userDetailsBloc.refresh,
), ),
), NeonLinearProgressIndicator(
], visible: userDetails.isLoading,
),
],
),
), ),
SettingsCategory( ],
title: Text(AppLocalizations.of(context).optionsCategoryGeneral), ),
tiles: [ SettingsCategory(
DropdownButtonSettingsTile( title: Text(AppLocalizations.of(context).optionsCategoryGeneral),
option: _options.initialApp, tiles: [
), DropdownButtonSettingsTile(
], option: options.initialApp,
), ),
], ],
), ),
],
),
);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: appBar,
body: Center(
child: ConstrainedBox(
constraints: NeonDialogTheme.of(context).constraints,
child: body,
), ),
); ),
);
}
} }

98
packages/neon/neon/lib/src/pages/nextcloud_app_settings.dart

@ -8,6 +8,7 @@ import 'package:neon/src/settings/widgets/checkbox_settings_tile.dart';
import 'package:neon/src/settings/widgets/dropdown_button_settings_tile.dart'; import 'package:neon/src/settings/widgets/dropdown_button_settings_tile.dart';
import 'package:neon/src/settings/widgets/settings_category.dart'; import 'package:neon/src/settings/widgets/settings_category.dart';
import 'package:neon/src/settings/widgets/settings_list.dart'; import 'package:neon/src/settings/widgets/settings_list.dart';
import 'package:neon/src/theme/dialog.dart';
import 'package:neon/src/utils/confirmation_dialog.dart'; import 'package:neon/src/utils/confirmation_dialog.dart';
class NextcloudAppSettingsPage extends StatelessWidget { class NextcloudAppSettingsPage extends StatelessWidget {
@ -19,53 +20,62 @@ class NextcloudAppSettingsPage extends StatelessWidget {
final AppImplementation appImplementation; final AppImplementation appImplementation;
@override @override
Widget build(final BuildContext context) => Scaffold( Widget build(final BuildContext context) {
resizeToAvoidBottomInset: false, final appBar = AppBar(
appBar: AppBar( title: Text(appImplementation.name(context)),
title: Text(appImplementation.name(context)), actions: [
actions: [ IconButton(
IconButton( onPressed: () async {
onPressed: () async { if (await showConfirmationDialog(
if (await showConfirmationDialog( context,
context, AppLocalizations.of(context).settingsResetForConfirmation(appImplementation.name(context)),
AppLocalizations.of(context).settingsResetForConfirmation(appImplementation.name(context)), )) {
)) { await appImplementation.options.reset();
await appImplementation.options.reset(); }
} },
}, tooltip: AppLocalizations.of(context).settingsResetFor(appImplementation.name(context)),
tooltip: AppLocalizations.of(context).settingsResetFor(appImplementation.name(context)), icon: Icon(MdiIcons.cogRefresh),
icon: Icon(MdiIcons.cogRefresh),
),
],
), ),
body: SettingsList( ],
categories: [ );
for (final category in [...appImplementation.options.categories, null]) ...[
if (appImplementation.options.options final body = SettingsList(
.where((final option) => option.category == category) categories: [
.isNotEmpty) ...[ for (final category in [...appImplementation.options.categories, null]) ...[
SettingsCategory( if (appImplementation.options.options.where((final option) => option.category == category).isNotEmpty) ...[
title: Text( SettingsCategory(
category != null ? category.name(context) : AppLocalizations.of(context).optionsCategoryOther, title: Text(
), category != null ? category.name(context) : AppLocalizations.of(context).optionsCategoryOther,
tiles: [ ),
for (final option tiles: [
in appImplementation.options.options.where((final option) => option.category == category)) ...[ for (final option
if (option is ToggleOption) ...[ in appImplementation.options.options.where((final option) => option.category == category)) ...[
CheckBoxSettingsTile( if (option is ToggleOption) ...[
option: option, CheckBoxSettingsTile(
), option: option,
] else if (option is SelectOption) ...[ ),
DropdownButtonSettingsTile( ] else if (option is SelectOption) ...[
option: option, DropdownButtonSettingsTile(
), option: option,
], ),
],
], ],
), ],
], ],
], ),
], ],
],
],
);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: appBar,
body: Center(
child: ConstrainedBox(
constraints: NeonDialogTheme.of(context).constraints,
child: body,
), ),
); ),
);
}
} }

457
packages/neon/neon/lib/src/pages/settings.dart

@ -19,6 +19,7 @@ import 'package:neon/src/settings/widgets/settings_list.dart';
import 'package:neon/src/settings/widgets/settings_tile.dart'; import 'package:neon/src/settings/widgets/settings_tile.dart';
import 'package:neon/src/settings/widgets/text_settings_tile.dart'; import 'package:neon/src/settings/widgets/text_settings_tile.dart';
import 'package:neon/src/theme/branding.dart'; import 'package:neon/src/theme/branding.dart';
import 'package:neon/src/theme/dialog.dart';
import 'package:neon/src/utils/confirmation_dialog.dart'; import 'package:neon/src/utils/confirmation_dialog.dart';
import 'package:neon/src/utils/global_options.dart'; import 'package:neon/src/utils/global_options.dart';
import 'package:neon/src/utils/save_file.dart'; import 'package:neon/src/utils/save_file.dart';
@ -57,263 +58,271 @@ class _SettingsPageState extends State<SettingsPage> {
final accountsBloc = Provider.of<AccountsBloc>(context, listen: false); final accountsBloc = Provider.of<AccountsBloc>(context, listen: false);
final appImplementations = Provider.of<Iterable<AppImplementation>>(context); final appImplementations = Provider.of<Iterable<AppImplementation>>(context);
return Scaffold( final appBar = AppBar(
resizeToAvoidBottomInset: false, title: Text(AppLocalizations.of(context).settings),
appBar: AppBar( actions: [
title: Text(AppLocalizations.of(context).settings), IconButton(
actions: [ onPressed: () async {
IconButton( if (await showConfirmationDialog(context, AppLocalizations.of(context).settingsResetAllConfirmation)) {
onPressed: () async { await globalOptions.reset();
if (await showConfirmationDialog(context, AppLocalizations.of(context).settingsResetAllConfirmation)) {
await globalOptions.reset();
for (final appImplementation in appImplementations) { for (final appImplementation in appImplementations) {
await appImplementation.options.reset(); await appImplementation.options.reset();
} }
for (final account in accountsBloc.accounts.value) { for (final account in accountsBloc.accounts.value) {
await accountsBloc.getOptionsFor(account).reset(); await accountsBloc.getOptionsFor(account).reset();
}
} }
}, }
tooltip: AppLocalizations.of(context).settingsResetAll, },
icon: Icon(MdiIcons.cogRefresh), tooltip: AppLocalizations.of(context).settingsResetAll,
), icon: Icon(MdiIcons.cogRefresh),
], ),
), ],
body: StreamBuilder<List<Account>>( );
stream: accountsBloc.accounts, final body = StreamBuilder<List<Account>>(
initialData: accountsBloc.accounts.valueOrNull, stream: accountsBloc.accounts,
builder: ( initialData: accountsBloc.accounts.valueOrNull,
final context, builder: (
final accountsSnapshot, final context,
) { final accountsSnapshot,
final platform = Provider.of<NeonPlatform>(context, listen: false); ) {
return StreamBuilder<bool>( final platform = Provider.of<NeonPlatform>(context, listen: false);
stream: globalOptions.pushNotificationsEnabled.enabled, return StreamBuilder<bool>(
initialData: globalOptions.pushNotificationsEnabled.enabled.valueOrNull, stream: globalOptions.pushNotificationsEnabled.enabled,
builder: ( initialData: globalOptions.pushNotificationsEnabled.enabled.valueOrNull,
final context, builder: (
final pushNotificationsEnabledEnabledSnapshot, final context,
) => final pushNotificationsEnabledEnabledSnapshot,
SettingsList( ) =>
initialCategory: widget.initialCategory?.name, SettingsList(
categories: [ initialCategory: widget.initialCategory?.name,
categories: [
SettingsCategory(
title: Text(AppLocalizations.of(context).settingsApps),
key: ValueKey(SettingsCageories.apps.name),
tiles: <SettingsTile>[
for (final appImplementation in appImplementations) ...[
if (appImplementation.options.options.isNotEmpty) ...[
CustomSettingsTile(
leading: appImplementation.buildIcon(),
title: Text(appImplementation.name(context)),
onTap: () {
NextcloudAppSettingsRoute(appid: appImplementation.id).go(context);
},
),
],
],
],
),
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryTheme),
key: ValueKey(SettingsCageories.theme.name),
tiles: [
DropdownButtonSettingsTile(
option: globalOptions.themeMode,
),
CheckBoxSettingsTile(
option: globalOptions.themeOLEDAsDark,
),
CheckBoxSettingsTile(
option: globalOptions.themeKeepOriginalAccentColor,
),
],
),
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryNavigation),
key: ValueKey(SettingsCageories.navigation.name),
tiles: [
DropdownButtonSettingsTile(
option: globalOptions.navigationMode,
),
],
),
if (platform.canUsePushNotifications) ...[
SettingsCategory( SettingsCategory(
title: Text(AppLocalizations.of(context).settingsApps), title: Text(AppLocalizations.of(context).optionsCategoryPushNotifications),
key: ValueKey(SettingsCageories.apps.name), key: ValueKey(SettingsCageories.pushNotifications.name),
tiles: <SettingsTile>[ tiles: [
for (final appImplementation in appImplementations) ...[ if (pushNotificationsEnabledEnabledSnapshot.hasData &&
if (appImplementation.options.options.isNotEmpty) ...[ !pushNotificationsEnabledEnabledSnapshot.requireData) ...[
CustomSettingsTile( TextSettingsTile(
leading: appImplementation.buildIcon(), text: AppLocalizations.of(context).globalOptionsPushNotificationsEnabledDisabledNotice,
title: Text(appImplementation.name(context)), style: TextStyle(
onTap: () { fontWeight: FontWeight.w600,
NextcloudAppSettingsRoute(appid: appImplementation.id).go(context); fontStyle: FontStyle.italic,
}, color: Theme.of(context).colorScheme.error,
), ),
], ),
], ],
CheckBoxSettingsTile(
option: globalOptions.pushNotificationsEnabled,
),
DropdownButtonSettingsTile(
option: globalOptions.pushNotificationsDistributor,
),
], ],
), ),
],
if (platform.canUseWindowManager) ...[
SettingsCategory( SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryTheme), title: Text(AppLocalizations.of(context).optionsCategoryStartup),
key: ValueKey(SettingsCageories.theme.name), key: ValueKey(SettingsCageories.startup.name),
tiles: [ tiles: [
DropdownButtonSettingsTile(
option: globalOptions.themeMode,
),
CheckBoxSettingsTile( CheckBoxSettingsTile(
option: globalOptions.themeOLEDAsDark, option: globalOptions.startupMinimized,
), ),
CheckBoxSettingsTile( CheckBoxSettingsTile(
option: globalOptions.themeKeepOriginalAccentColor, option: globalOptions.startupMinimizeInsteadOfExit,
), ),
], ],
), ),
],
if (platform.canUseWindowManager && platform.canUseSystemTray) ...[
SettingsCategory( SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryNavigation), title: Text(AppLocalizations.of(context).optionsCategorySystemTray),
key: ValueKey(SettingsCageories.navigation.name), key: ValueKey(SettingsCageories.systemTray.name),
tiles: [ tiles: [
DropdownButtonSettingsTile( CheckBoxSettingsTile(
option: globalOptions.navigationMode, option: globalOptions.systemTrayEnabled,
),
CheckBoxSettingsTile(
option: globalOptions.systemTrayHideToTrayWhenMinimized,
), ),
], ],
), ),
if (platform.canUsePushNotifications) ...[ ],
SettingsCategory( SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryPushNotifications), title: Text(AppLocalizations.of(context).optionsCategoryAccounts),
key: ValueKey(SettingsCageories.pushNotifications.name), key: ValueKey(SettingsCageories.accounts.name),
tiles: [ tiles: [
if (pushNotificationsEnabledEnabledSnapshot.hasData && if (accountsSnapshot.requireData.length > 1) ...[
!pushNotificationsEnabledEnabledSnapshot.requireData) ...[ CheckBoxSettingsTile(
TextSettingsTile( option: globalOptions.rememberLastUsedAccount,
text: AppLocalizations.of(context).globalOptionsPushNotificationsEnabledDisabledNotice, ),
style: TextStyle( DropdownButtonSettingsTile(
fontWeight: FontWeight.w600, option: globalOptions.initialAccount,
fontStyle: FontStyle.italic, ),
color: Theme.of(context).colorScheme.error,
),
),
],
CheckBoxSettingsTile(
option: globalOptions.pushNotificationsEnabled,
),
DropdownButtonSettingsTile(
option: globalOptions.pushNotificationsDistributor,
),
],
),
],
if (platform.canUseWindowManager) ...[
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryStartup),
key: ValueKey(SettingsCageories.startup.name),
tiles: [
CheckBoxSettingsTile(
option: globalOptions.startupMinimized,
),
CheckBoxSettingsTile(
option: globalOptions.startupMinimizeInsteadOfExit,
),
],
),
],
if (platform.canUseWindowManager && platform.canUseSystemTray) ...[
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategorySystemTray),
key: ValueKey(SettingsCageories.systemTray.name),
tiles: [
CheckBoxSettingsTile(
option: globalOptions.systemTrayEnabled,
),
CheckBoxSettingsTile(
option: globalOptions.systemTrayHideToTrayWhenMinimized,
),
],
),
],
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryAccounts),
key: ValueKey(SettingsCageories.accounts.name),
tiles: [
if (accountsSnapshot.requireData.length > 1) ...[
CheckBoxSettingsTile(
option: globalOptions.rememberLastUsedAccount,
),
DropdownButtonSettingsTile(
option: globalOptions.initialAccount,
),
],
for (final account in accountsSnapshot.requireData) ...[
AccountSettingsTile(
account: account,
onTap: () {
AccountSettingsRoute(accountid: account.id).go(context);
},
),
],
CustomSettingsTile(
title: ElevatedButton.icon(
onPressed: () async => const LoginRoute().push(context),
icon: Icon(MdiIcons.accountPlus),
label: Text(AppLocalizations.of(context).globalOptionsAccountsAdd),
),
)
], ],
), for (final account in accountsSnapshot.requireData) ...[
SettingsCategory( AccountSettingsTile(
title: Text(AppLocalizations.of(context).optionsCategoryOther), account: account,
key: ValueKey(SettingsCageories.other.name), onTap: () {
tiles: <SettingsTile>[ AccountSettingsRoute(accountid: account.id).go(context);
CustomSettingsTile(
leading: Icon(
MdiIcons.scriptText,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).licenses),
onTap: () async {
final branding = Branding.of(context);
showLicensePage(
context: context,
applicationName: branding.name,
applicationIcon: branding.logo,
applicationLegalese: branding.legalese,
applicationVersion: Provider.of<PackageInfo>(context, listen: false).version,
);
}, },
), ),
CustomSettingsTile( ],
leading: Icon( CustomSettingsTile(
MdiIcons.export, title: ElevatedButton.icon(
color: Theme.of(context).colorScheme.primary, onPressed: () async => const LoginRoute().push(context),
), icon: Icon(MdiIcons.accountPlus),
title: Text(AppLocalizations.of(context).settingsExport), label: Text(AppLocalizations.of(context).globalOptionsAccountsAdd),
onTap: () async { ),
final settingsExportHelper = _buildSettingsExportHelper(context); )
],
),
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryOther),
key: ValueKey(SettingsCageories.other.name),
tiles: <SettingsTile>[
CustomSettingsTile(
leading: Icon(
MdiIcons.scriptText,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).licenses),
onTap: () async {
final branding = Branding.of(context);
showLicensePage(
context: context,
applicationName: branding.name,
applicationIcon: branding.logo,
applicationLegalese: branding.legalese,
applicationVersion: Provider.of<PackageInfo>(context, listen: false).version,
);
},
),
CustomSettingsTile(
leading: Icon(
MdiIcons.export,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).settingsExport),
onTap: () async {
final settingsExportHelper = _buildSettingsExportHelper(context);
try { try {
final fileName = final fileName =
'nextcloud-neon-settings-${DateTime.now().millisecondsSinceEpoch ~/ 1000}.json.base64'; 'nextcloud-neon-settings-${DateTime.now().millisecondsSinceEpoch ~/ 1000}.json.base64';
final data = base64.encode( final data = base64.encode(
utf8.encode( utf8.encode(
json.encode( json.encode(
settingsExportHelper.toJsonExport(), settingsExportHelper.toJsonExport(),
),
), ),
); ),
await saveFileWithPickDialog(fileName, Uint8List.fromList(utf8.encode(data))); );
} catch (e, s) { await saveFileWithPickDialog(fileName, Uint8List.fromList(utf8.encode(data)));
debugPrint(e.toString()); } catch (e, s) {
debugPrint(s.toString()); debugPrint(e.toString());
NeonException.showSnackbar(context, e); debugPrint(s.toString());
} NeonException.showSnackbar(context, e);
}, }
},
),
CustomSettingsTile(
leading: Icon(
MdiIcons.import,
color: Theme.of(context).colorScheme.primary,
), ),
CustomSettingsTile( title: Text(AppLocalizations.of(context).settingsImport),
leading: Icon( onTap: () async {
MdiIcons.import, final settingsExportHelper = _buildSettingsExportHelper(context);
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).settingsImport),
onTap: () async {
final settingsExportHelper = _buildSettingsExportHelper(context);
try { try {
final result = await FilePicker.platform.pickFiles( final result = await FilePicker.platform.pickFiles(
withData: true, withData: true,
); );
if (result == null) { if (result == null) {
return; return;
} }
if (!result.files.single.path!.endsWith('.json.base64')) { if (!result.files.single.path!.endsWith('.json.base64')) {
if (mounted) { if (mounted) {
NeonException.showSnackbar( NeonException.showSnackbar(
context, context,
AppLocalizations.of(context).settingsImportWrongFileExtension, AppLocalizations.of(context).settingsImportWrongFileExtension,
); );
}
return;
} }
return;
}
final data = json.decode(utf8.decode(base64.decode(utf8.decode(result.files.single.bytes!)))); final data = json.decode(utf8.decode(base64.decode(utf8.decode(result.files.single.bytes!))));
await settingsExportHelper.applyFromJson(data as Map<String, dynamic>); await settingsExportHelper.applyFromJson(data as Map<String, dynamic>);
} catch (e, s) { } catch (e, s) {
debugPrint(e.toString()); debugPrint(e.toString());
debugPrint(s.toString()); debugPrint(s.toString());
NeonException.showSnackbar(context, e); NeonException.showSnackbar(context, e);
} }
}, },
), ),
], ],
), ),
], ],
), ),
); );
}, },
);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: appBar,
body: Center(
child: ConstrainedBox(
constraints: NeonDialogTheme.of(context).constraints,
child: body,
),
), ),
); );
} }

Loading…
Cancel
Save