Browse Source

neon_notes: get blocs via context

pull/377/head
Nikolas Rimikis 2 years ago
parent
commit
b003ab9df5
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 15
      packages/neon/neon_notes/lib/dialogs/create_note.dart
  2. 14
      packages/neon/neon_notes/lib/dialogs/select_category.dart
  3. 4
      packages/neon/neon_notes/lib/pages/category.dart
  4. 14
      packages/neon/neon_notes/lib/pages/main.dart
  5. 6
      packages/neon/neon_notes/lib/pages/note.dart
  6. 58
      packages/neon/neon_notes/lib/widgets/categories_view.dart
  7. 41
      packages/neon/neon_notes/lib/widgets/notes_floating_action_button.dart
  8. 173
      packages/neon/neon_notes/lib/widgets/notes_view.dart

15
packages/neon/neon_notes/lib/dialogs/create_note.dart

@ -2,12 +2,10 @@ part of '../neon_notes.dart';
class NotesCreateNoteDialog extends StatefulWidget {
const NotesCreateNoteDialog({
required this.bloc,
this.category,
super.key,
});
final NotesBloc bloc;
final String? category;
@override
@ -17,8 +15,17 @@ class NotesCreateNoteDialog extends StatefulWidget {
class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
final formKey = GlobalKey<FormState>();
final controller = TextEditingController();
late NotesBloc bloc;
String? selectedCategory;
@override
void initState() {
bloc = Provider.of<NotesBloc>(context, listen: false);
super.initState();
}
void submit() {
if (formKey.currentState!.validate()) {
Navigator.of(context).pop([controller.text, widget.category ?? selectedCategory]);
@ -27,7 +34,7 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
@override
Widget build(final BuildContext context) => ResultBuilder<List<NextcloudNotesNote>>(
stream: widget.bloc.notes,
stream: bloc.notes,
builder: (final context, final notes) => NeonDialog(
title: Text(AppLocalizations.of(context).noteCreate),
children: [
@ -51,7 +58,7 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
Center(
child: NeonException(
notes.error,
onRetry: widget.bloc.refresh,
onRetry: bloc.refresh,
),
),
Center(

14
packages/neon/neon_notes/lib/dialogs/select_category.dart

@ -2,12 +2,10 @@ part of '../neon_notes.dart';
class NotesSelectCategoryDialog extends StatefulWidget {
const NotesSelectCategoryDialog({
required this.bloc,
this.initialCategory,
super.key,
});
final NotesBloc bloc;
final String? initialCategory;
@override
@ -16,9 +14,17 @@ class NotesSelectCategoryDialog extends StatefulWidget {
class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> {
final formKey = GlobalKey<FormState>();
late NotesBloc bloc;
String? selectedCategory;
@override
void initState() {
bloc = Provider.of<NotesBloc>(context, listen: false);
super.initState();
}
void submit() {
if (formKey.currentState!.validate()) {
Navigator.of(context).pop(selectedCategory);
@ -27,7 +33,7 @@ class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> {
@override
Widget build(final BuildContext context) => ResultBuilder<List<NextcloudNotesNote>>(
stream: widget.bloc.notes,
stream: bloc.notes,
builder: (final context, final notes) => NeonDialog(
title: Text(AppLocalizations.of(context).category),
children: [
@ -39,7 +45,7 @@ class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> {
Center(
child: NeonException(
notes.error,
onRetry: widget.bloc.refresh,
onRetry: bloc.refresh,
),
),
Center(

4
packages/neon/neon_notes/lib/pages/category.dart

@ -2,12 +2,10 @@ part of '../neon_notes.dart';
class NotesCategoryPage extends StatelessWidget {
const NotesCategoryPage({
required this.bloc,
required this.category,
super.key,
});
final NotesBloc bloc;
final NoteCategory category;
@override
@ -17,11 +15,9 @@ class NotesCategoryPage extends StatelessWidget {
title: Text(category.name != '' ? category.name : AppLocalizations.of(context).categoryUncategorized),
),
body: NotesView(
bloc: bloc,
category: category.name,
),
floatingActionButton: NotesFloatingActionButton(
bloc: bloc,
category: category.name,
),
);

14
packages/neon/neon_notes/lib/pages/main.dart

@ -26,17 +26,13 @@ class _NotesMainPageState extends State<NotesMainPage> {
@override
Widget build(final BuildContext context) {
final views = [
NotesView(
bloc: bloc,
),
NotesCategoriesView(
bloc: bloc,
),
const views = [
NotesView(),
NotesCategoriesView(),
];
final floatingActionButtons = [
NotesFloatingActionButton(bloc: bloc),
const floatingActionButtons = [
NotesFloatingActionButton(),
null,
];

6
packages/neon/neon_notes/lib/pages/note.dart

@ -3,18 +3,17 @@ part of '../neon_notes.dart';
class NotesNotePage extends StatefulWidget {
const NotesNotePage({
required this.bloc,
required this.notesBloc,
super.key,
});
final NotesNoteBloc bloc;
final NotesBloc notesBloc;
@override
State<NotesNotePage> createState() => _NotesNotePageState();
}
class _NotesNotePageState extends State<NotesNotePage> {
late NotesBloc notesBloc;
late final _contentController = TextEditingController()..text = widget.bloc.initialContent;
late final _titleController = TextEditingController()..text = widget.bloc.initialTitle;
final _contentFocusNode = FocusNode();
@ -32,6 +31,8 @@ class _NotesNotePageState extends State<NotesNotePage> {
void initState() {
super.initState();
notesBloc = Provider.of<NotesBloc>(context, listen: false);
widget.bloc.errors.listen((final error) {
handleNotesException(context, error);
});
@ -118,7 +119,6 @@ class _NotesNotePageState extends State<NotesNotePage> {
final result = await showDialog<String>(
context: context,
builder: (final context) => NotesSelectCategoryDialog(
bloc: widget.notesBloc,
initialCategory: category,
),
);

58
packages/neon/neon_notes/lib/widgets/categories_view.dart

@ -2,39 +2,40 @@ part of '../neon_notes.dart';
class NotesCategoriesView extends StatelessWidget {
const NotesCategoriesView({
required this.bloc,
super.key,
});
final NotesBloc bloc;
@override
Widget build(final BuildContext context) => ResultBuilder<List<NextcloudNotesNote>>(
stream: bloc.notes,
builder: (final context, final notes) => SortBoxBuilder<CategoriesSortProperty, NoteCategory>(
sortBox: categoriesSortBox,
sortPropertyOption: bloc.options.categoriesSortPropertyOption,
sortBoxOrderOption: bloc.options.categoriesSortBoxOrderOption,
input: notes.data
?.map((final note) => note.category)
.toSet()
.map(
(final category) => NoteCategory(
category,
notes.data!.where((final note) => note.category == category).length,
),
)
.toList(),
builder: (final context, final sorted) => NeonListView<NoteCategory>(
scrollKey: 'notes-categories',
items: sorted,
isLoading: notes.loading,
error: notes.error,
onRefresh: bloc.refresh,
builder: _buildCategory,
),
Widget build(final BuildContext context) {
final bloc = Provider.of<NotesBloc>(context, listen: false);
return ResultBuilder<List<NextcloudNotesNote>>(
stream: bloc.notes,
builder: (final context, final notes) => SortBoxBuilder<CategoriesSortProperty, NoteCategory>(
sortBox: categoriesSortBox,
sortPropertyOption: bloc.options.categoriesSortPropertyOption,
sortBoxOrderOption: bloc.options.categoriesSortBoxOrderOption,
input: notes.data
?.map((final note) => note.category)
.toSet()
.map(
(final category) => NoteCategory(
category,
notes.data!.where((final note) => note.category == category).length,
),
)
.toList(),
builder: (final context, final sorted) => NeonListView<NoteCategory>(
scrollKey: 'notes-categories',
items: sorted,
isLoading: notes.loading,
error: notes.error,
onRefresh: bloc.refresh,
builder: _buildCategory,
),
);
),
);
}
Widget _buildCategory(
final BuildContext context,
@ -54,7 +55,6 @@ class NotesCategoriesView extends StatelessWidget {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (final context) => NotesCategoryPage(
bloc: bloc,
category: category,
),
),

41
packages/neon/neon_notes/lib/widgets/notes_floating_action_button.dart

@ -2,32 +2,33 @@ part of '../neon_notes.dart';
class NotesFloatingActionButton extends StatelessWidget {
const NotesFloatingActionButton({
required this.bloc,
this.category,
super.key,
});
final NotesBloc bloc;
final String? category;
@override
Widget build(final BuildContext context) => FloatingActionButton(
onPressed: () async {
final result = await showDialog<List>(
context: context,
builder: (final context) => NotesCreateNoteDialog(
bloc: bloc,
category: category,
),
Widget build(final BuildContext context) {
final bloc = Provider.of<NotesBloc>(context, listen: false);
return FloatingActionButton(
onPressed: () async {
final result = await showDialog<List>(
context: context,
builder: (final context) => NotesCreateNoteDialog(
category: category,
),
);
if (result != null) {
bloc.createNote(
title: result[0] as String,
category: result[1] as String? ?? '',
);
if (result != null) {
bloc.createNote(
title: result[0] as String,
category: result[1] as String? ?? '',
);
}
},
tooltip: AppLocalizations.of(context).noteCreate,
child: const Icon(Icons.add),
);
}
},
tooltip: AppLocalizations.of(context).noteCreate,
child: const Icon(Icons.add),
);
}
}

173
packages/neon/neon_notes/lib/widgets/notes_view.dart

@ -2,111 +2,114 @@ part of '../neon_notes.dart';
class NotesView extends StatelessWidget {
const NotesView({
required this.bloc,
this.category,
super.key,
});
final NotesBloc bloc;
final String? category;
@override
Widget build(final BuildContext context) => ResultBuilder<List<NextcloudNotesNote>>(
stream: bloc.notes,
builder: (final context, final notes) => SortBoxBuilder<NotesSortProperty, NextcloudNotesNote>(
Widget build(final BuildContext context) {
final bloc = Provider.of<NotesBloc>(context, listen: false);
return ResultBuilder<List<NextcloudNotesNote>>(
stream: bloc.notes,
builder: (final context, final notes) => SortBoxBuilder<NotesSortProperty, NextcloudNotesNote>(
sortBox: notesSortBox,
sortPropertyOption: bloc.options.notesSortPropertyOption,
sortBoxOrderOption: bloc.options.notesSortBoxOrderOption,
input: category != null
? notes.data?.where((final note) => note.favorite && note.category == category).toList()
: notes.data?.where((final note) => note.favorite).toList(),
builder: (final context, final sortedFavorites) => SortBoxBuilder<NotesSortProperty, NextcloudNotesNote>(
sortBox: notesSortBox,
sortPropertyOption: bloc.options.notesSortPropertyOption,
sortBoxOrderOption: bloc.options.notesSortBoxOrderOption,
input: category != null
? notes.data?.where((final note) => note.favorite && note.category == category).toList()
: notes.data?.where((final note) => note.favorite).toList(),
builder: (final context, final sortedFavorites) => SortBoxBuilder<NotesSortProperty, NextcloudNotesNote>(
sortBox: notesSortBox,
sortPropertyOption: bloc.options.notesSortPropertyOption,
sortBoxOrderOption: bloc.options.notesSortBoxOrderOption,
input: category != null
? notes.data?.where((final note) => !note.favorite && note.category == category).toList()
: notes.data?.where((final note) => !note.favorite).toList(),
builder: (final context, final sortedNonFavorites) => NeonListView<NextcloudNotesNote>(
scrollKey: 'notes-notes',
withFloatingActionButton: true,
items: [
...?sortedFavorites,
...?sortedNonFavorites,
],
isLoading: notes.loading,
error: notes.error,
onRefresh: bloc.refresh,
builder: _buildNote,
),
? notes.data?.where((final note) => !note.favorite && note.category == category).toList()
: notes.data?.where((final note) => !note.favorite).toList(),
builder: (final context, final sortedNonFavorites) => NeonListView<NextcloudNotesNote>(
scrollKey: 'notes-notes',
withFloatingActionButton: true,
items: [
...?sortedFavorites,
...?sortedNonFavorites,
],
isLoading: notes.loading,
error: notes.error,
onRefresh: bloc.refresh,
builder: _buildNote,
),
),
);
),
);
}
Widget _buildNote(
final BuildContext context,
final NextcloudNotesNote note,
) =>
ListTile(
title: Text(note.title),
subtitle: Row(
children: [
RelativeTime(
date: DateTime.fromMillisecondsSinceEpoch(note.modified * 1000),
) {
final bloc = Provider.of<NotesBloc>(context, listen: false);
return ListTile(
title: Text(note.title),
subtitle: Row(
children: [
RelativeTime(
date: DateTime.fromMillisecondsSinceEpoch(note.modified * 1000),
),
if (note.category != '') ...[
const SizedBox(
width: 8,
),
if (note.category != '') ...[
const SizedBox(
width: 8,
),
Icon(
MdiIcons.tag,
size: 14,
color: NotesCategoryColor.compute(note.category),
),
const SizedBox(
width: 2,
),
Text(note.category),
],
Icon(
MdiIcons.tag,
size: 14,
color: NotesCategoryColor.compute(note.category),
),
const SizedBox(
width: 2,
),
Text(note.category),
],
],
),
trailing: IconButton(
onPressed: () {
bloc.updateNote(
note.id,
note.etag,
favorite: !note.favorite,
);
},
tooltip: note.favorite ? AppLocalizations.of(context).noteUnstar : AppLocalizations.of(context).noteStar,
icon: Icon(
note.favorite ? Icons.star : Icons.star_outline,
color: Theme.of(context).colorScheme.primary,
),
trailing: IconButton(
onPressed: () {
bloc.updateNote(
note.id,
note.etag,
favorite: !note.favorite,
);
},
tooltip: note.favorite ? AppLocalizations.of(context).noteUnstar : AppLocalizations.of(context).noteStar,
icon: Icon(
note.favorite ? Icons.star : Icons.star_outline,
color: Theme.of(context).colorScheme.primary,
),
),
onTap: () async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (final context) => NotesNotePage(
bloc: NotesNoteBloc(
bloc.options,
Provider.of<AccountsBloc>(context, listen: false).activeAccount.value!.client,
bloc,
note,
),
notesBloc: bloc,
),
onTap: () async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (final context) => NotesNotePage(
bloc: NotesNoteBloc(
bloc.options,
Provider.of<AccountsBloc>(context, listen: false).activeAccount.value!.client,
bloc,
note,
),
),
);
},
onLongPress: () async {
final result = await showConfirmationDialog(
context,
AppLocalizations.of(context).noteDeleteConfirm(note.title),
);
if (result) {
bloc.deleteNote(note.id);
}
},
);
),
);
},
onLongPress: () async {
final result = await showConfirmationDialog(
context,
AppLocalizations.of(context).noteDeleteConfirm(note.title),
);
if (result) {
bloc.deleteNote(note.id);
}
},
);
}
}

Loading…
Cancel
Save