import 'package:comunic/helpers/groups_helper.dart'; import 'package:comunic/helpers/settings_helper.dart'; import 'package:comunic/ui/widgets/safe_state.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:flutter/material.dart'; /// Show a dialog to offer the user to pick a virtual directory /// /// @author Pierre HUBERT enum VirtualDirectoryTargetType { USER, GROUP } enum _CheckStatus { EMPTY, PENDING, VALID, INVALID } Future showVirtualDirectoryDialog({ required BuildContext context, required String initialDirectory, required int id, required VirtualDirectoryTargetType type, }) async { return await showDialog( context: context, builder: (c) => _VirtualDirectoryPicker( type: type, id: id, initialDirectory: initialDirectory)); } class _VirtualDirectoryPicker extends StatefulWidget { final String initialDirectory; final int id; final VirtualDirectoryTargetType type; const _VirtualDirectoryPicker({ Key? key, required this.initialDirectory, required this.id, required this.type, }) : super(key: key); @override __VirtualDirectoryPickerState createState() => __VirtualDirectoryPickerState(); } class __VirtualDirectoryPickerState extends SafeState<_VirtualDirectoryPicker> { TextEditingController? _controller; var _status = _CheckStatus.VALID; String get _currentValue => _controller!.text; @override void initState() { super.initState(); _controller = TextEditingController(text: widget.initialDirectory); } @override Widget build(BuildContext context) { return AlertDialog( title: Text(tr("Choose a virtual directory")!), // Dialog content content: TextField( controller: _controller, onChanged: (s) => _checkValue(), decoration: InputDecoration( alignLabelWithHint: true, labelText: tr("Virtual directory"), helperText: _status == _CheckStatus.PENDING ? tr("Checking availability...") : (_status == _CheckStatus.VALID ? tr("You can use this virtual directory.") : null), errorText: _status == _CheckStatus.INVALID ? tr("This virtual directory is invalid / unvailable !") : null, ), ), // Dialog action actions: [ // Cancel MaterialButton( onPressed: () => Navigator.of(context).pop(), child: Text(tr("Cancel")!.toUpperCase()), ), // Confirm MaterialButton( onPressed: _status == _CheckStatus.VALID || _status == _CheckStatus.EMPTY ? () => Navigator.of(context).pop(_currentValue) : null, child: Text(tr("Confirm")!.toUpperCase()), ), ], ); } void _setStatus(_CheckStatus s) => setState(() => _status = s); /// Check new given value void _checkValue() async { final value = _currentValue; try { _setStatus(_CheckStatus.PENDING); if (value.length == 0) { _setStatus(_CheckStatus.EMPTY); return; } // Validate directory. This will throw in case of failure switch (widget.type) { case VirtualDirectoryTargetType.USER: await SettingsHelper.checkUserDirectoryAvailability(value); break; case VirtualDirectoryTargetType.GROUP: await GroupsHelper.checkVirtualDirectoryAvailability( widget.id, value); break; } if (_currentValue == value) { _setStatus(_CheckStatus.VALID); } } catch (e, stack) { if (_currentValue == value) { print("Could not validate given directory! $e\n$stack"); _setStatus(_CheckStatus.INVALID); } } } }