You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
5.2 KiB
200 lines
5.2 KiB
import 'package:flutter/material.dart'; |
|
import 'package:neon/blocs.dart'; |
|
import 'package:neon/utils.dart'; |
|
import 'package:neon/widgets.dart'; |
|
import 'package:neon_notes/l10n/localizations.dart'; |
|
import 'package:neon_notes/neon_notes.dart'; |
|
import 'package:nextcloud/notes.dart' as notes; |
|
|
|
/// A dialog for creating a note. |
|
class NotesCreateNoteDialog extends StatefulWidget { |
|
/// Creates a new create note dialog. |
|
const NotesCreateNoteDialog({ |
|
required this.bloc, |
|
this.initialCategory, |
|
super.key, |
|
}); |
|
|
|
/// The active notes bloc. |
|
final NotesBloc bloc; |
|
|
|
/// The initial category of the note. |
|
final String? initialCategory; |
|
|
|
@override |
|
State<NotesCreateNoteDialog> createState() => _NotesCreateNoteDialogState(); |
|
} |
|
|
|
class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> { |
|
final formKey = GlobalKey<FormState>(); |
|
final controller = TextEditingController(); |
|
String? selectedCategory; |
|
|
|
@override |
|
void dispose() { |
|
controller.dispose(); |
|
super.dispose(); |
|
} |
|
|
|
void submit() { |
|
if (formKey.currentState!.validate()) { |
|
Navigator.of(context).pop((controller.text, widget.initialCategory ?? selectedCategory)); |
|
} |
|
} |
|
|
|
@override |
|
Widget build(final BuildContext context) { |
|
final titleField = Form( |
|
key: formKey, |
|
child: TextFormField( |
|
autofocus: true, |
|
controller: controller, |
|
decoration: InputDecoration( |
|
hintText: NotesLocalizations.of(context).noteTitle, |
|
), |
|
validator: (final input) => validateNotEmpty(context, input), |
|
onFieldSubmitted: (final _) { |
|
submit(); |
|
}, |
|
), |
|
); |
|
|
|
final folderSelector = ResultBuilder<List<notes.Note>>.behaviorSubject( |
|
subject: widget.bloc.notesList, |
|
builder: (final context, final notes) { |
|
if (notes.hasError) { |
|
return Center( |
|
child: NeonError( |
|
notes.error, |
|
onRetry: widget.bloc.refresh, |
|
), |
|
); |
|
} |
|
if (!notes.hasData) { |
|
return Center( |
|
child: NeonLinearProgressIndicator( |
|
visible: notes.isLoading, |
|
), |
|
); |
|
} |
|
|
|
return NotesCategorySelect( |
|
categories: notes.requireData.map((final note) => note.category).toSet().toList(), |
|
onChanged: (final category) { |
|
selectedCategory = category; |
|
}, |
|
onSubmitted: submit, |
|
); |
|
}, |
|
); |
|
|
|
return NeonDialog( |
|
title: Text(NotesLocalizations.of(context).noteCreate), |
|
content: Material( |
|
child: Column( |
|
mainAxisSize: MainAxisSize.min, |
|
crossAxisAlignment: CrossAxisAlignment.end, |
|
children: [ |
|
titleField, |
|
const SizedBox(height: 8), |
|
folderSelector, |
|
], |
|
), |
|
), |
|
actions: [ |
|
NeonDialogAction( |
|
isDefaultAction: true, |
|
onPressed: submit, |
|
child: Text( |
|
NotesLocalizations.of(context).noteCreate, |
|
textAlign: TextAlign.end, |
|
), |
|
), |
|
], |
|
); |
|
} |
|
} |
|
|
|
/// A dialog for selecting a category for a note. |
|
class NotesSelectCategoryDialog extends StatefulWidget { |
|
/// Creates a new category selection dialog. |
|
const NotesSelectCategoryDialog({ |
|
required this.bloc, |
|
this.initialCategory, |
|
super.key, |
|
}); |
|
|
|
/// The active notes bloc. |
|
final NotesBloc bloc; |
|
|
|
/// The initial category of the note. |
|
final String? initialCategory; |
|
|
|
@override |
|
State<NotesSelectCategoryDialog> createState() => _NotesSelectCategoryDialogState(); |
|
} |
|
|
|
class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> { |
|
final formKey = GlobalKey<FormState>(); |
|
|
|
String? selectedCategory; |
|
|
|
void submit() { |
|
if (formKey.currentState!.validate()) { |
|
Navigator.of(context).pop(selectedCategory); |
|
} |
|
} |
|
|
|
@override |
|
Widget build(final BuildContext context) { |
|
final folderSelector = ResultBuilder<List<notes.Note>>.behaviorSubject( |
|
subject: widget.bloc.notesList, |
|
builder: (final context, final notes) { |
|
if (notes.hasError) { |
|
return Center( |
|
child: NeonError( |
|
notes.error, |
|
onRetry: widget.bloc.refresh, |
|
), |
|
); |
|
} |
|
if (!notes.hasData) { |
|
return Center( |
|
child: NeonLinearProgressIndicator( |
|
visible: notes.isLoading, |
|
), |
|
); |
|
} |
|
|
|
return Form( |
|
key: formKey, |
|
child: NotesCategorySelect( |
|
categories: notes.requireData.map((final note) => note.category).toSet().toList(), |
|
initialValue: widget.initialCategory, |
|
onChanged: (final category) { |
|
selectedCategory = category; |
|
}, |
|
onSubmitted: submit, |
|
), |
|
); |
|
}, |
|
); |
|
|
|
return NeonDialog( |
|
title: Text(NotesLocalizations.of(context).category), |
|
content: Material( |
|
child: folderSelector, |
|
), |
|
actions: [ |
|
NeonDialogAction( |
|
isDefaultAction: true, |
|
onPressed: submit, |
|
child: Text( |
|
NotesLocalizations.of(context).noteSetCategory, |
|
textAlign: TextAlign.end, |
|
), |
|
), |
|
], |
|
); |
|
} |
|
}
|
|
|