1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 21:09:21 +00:00
comunicmobile/lib/ui/dialogs/virtual_directory_dialog.dart

143 lines
4.0 KiB
Dart

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<String?> showVirtualDirectoryDialog({
required BuildContext context,
required String initialDirectory,
required int id,
required VirtualDirectoryTargetType type,
}) async {
assert(context != null);
assert(initialDirectory != null);
assert(id != null);
assert(type != null);
return await showDialog<String>(
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,
}) : assert(initialDirectory != null),
assert(id != null),
assert(type != null),
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: <Widget>[
// 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);
}
}
}
}