add author selection menu

This commit is contained in:
Odweta
2026-03-23 09:59:42 +01:00
parent e356fe8627
commit 67008188b9
5 changed files with 101 additions and 7 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'strings.dart'; import 'values/strings.dart';
import 'main_scaffold.dart'; import 'main_scaffold.dart';
// providers // providers
+1 -1
View File
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'strings.dart'; import 'values/strings.dart';
class MainScaffold extends StatelessWidget { class MainScaffold extends StatelessWidget {
final Widget child; final Widget child;
+34 -3
View File
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:frontend/provider/quote_provider.dart'; import 'package:frontend/provider/quote_provider.dart';
import 'package:frontend/model/quote.dart'; import 'package:frontend/model/quote.dart';
import 'package:provider/provider.dart';
import 'package:frontend/values/strings.dart'; import 'package:frontend/values/strings.dart';
import 'package:frontend/values/constants.dart'; import 'package:frontend/values/constants.dart';
@@ -12,7 +14,7 @@ class AddPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bodyController = TextEditingController(text: ''); final bodyController = TextEditingController(text: '');
final authorController = TextEditingController(text: ''); final authorController = TextEditingController(text: '');
final provider = QuoteProvider(); final provider = Provider.of<QuoteProvider>(context);
return Card( return Card(
margin: const EdgeInsets.all(Constants.edgeInset), margin: const EdgeInsets.all(Constants.edgeInset),
child: Padding( child: Padding(
@@ -40,11 +42,40 @@ class AddPage extends StatelessWidget {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
TextField( TextField(
controller: authorController, controller: authorController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: Strings.author, labelText: Strings.author,
suffixIcon: IconButton(
icon: Icon(Icons.arrow_drop_down),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
var authors = provider.authors.toList()..sort();
return SizedBox(
height: 300,
child: ListView.builder(
padding: const EdgeInsets.all(Constants.edgeInset),
itemCount: authors.length,
itemBuilder: (context, index) {
final author = authors[index];
return ListTile(
title: Text(author),
onTap: () {
authorController.text = author;
Navigator.pop(context);
},
);
},
),
);
},
);
},
),
), ),
), ),
+42 -1
View File
@@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
import 'package:frontend/provider/quote_provider.dart'; import 'package:frontend/provider/quote_provider.dart';
import 'package:frontend/model/quote.dart'; import 'package:frontend/model/quote.dart';
import 'package:frontend/strings.dart'; import 'package:frontend/values/strings.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:frontend/values/constants.dart';
class ListPage extends StatelessWidget { class ListPage extends StatelessWidget {
const ListPage({super.key}); const ListPage({super.key});
@@ -30,12 +32,18 @@ class ListPage extends StatelessWidget {
return return
ListView.builder( ListView.builder(
padding: EdgeInsets.all(Constants.edgeInset),
itemCount: provider.quotes.length, itemCount: provider.quotes.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final quote = provider.quotes[index]; final quote = provider.quotes[index];
return return
ListTile( ListTile(
contentPadding: EdgeInsets.only(
bottom: Constants.edgeInset,
left: Constants.edgeInset,
right: Constants.edgeInset,
),
title: Text(quote.body), title: Text(quote.body),
subtitle: Text(" ${quote.author}"), subtitle: Text(" ${quote.author}"),
trailing: PopupMenuButton<String>( trailing: PopupMenuButton<String>(
@@ -97,6 +105,39 @@ class ListPage extends StatelessWidget {
), ),
TextField( TextField(
controller: authorController, controller: authorController,
decoration: InputDecoration(
label: Text(Strings.author),
suffixIcon: IconButton(
icon: Icon(Icons.arrow_drop_down),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
var authors = provider.authors.toList()..sort();
return SizedBox(
height: 300,
child: ListView.builder(
padding: const EdgeInsets.all(Constants.edgeInset),
itemCount: authors.length,
itemBuilder: (context, index) {
final author = authors[index];
return ListTile(
title: Text(author),
onTap: () {
authorController.text = author;
Navigator.pop(context);
},
);
},
),
);
},
);
},
),
),
), ),
], ],
), ),
+23 -1
View File
@@ -7,10 +7,12 @@ import 'package:frontend/repository/quote_repository.dart';
class QuoteProvider extends ChangeNotifier { class QuoteProvider extends ChangeNotifier {
List<Quote> _quotes = []; List<Quote> _quotes = [];
Set<String> _authors = {};
bool _loading = false; bool _loading = false;
String? _error; String? _error;
List<Quote> get quotes => _quotes; List<Quote> get quotes => _quotes;
Set<String> get authors => _authors;
bool get loading => _loading; bool get loading => _loading;
String? get error => _error; String? get error => _error;
@@ -20,6 +22,13 @@ class QuoteProvider extends ChangeNotifier {
readQuotes(); // auto-load on creation readQuotes(); // auto-load on creation
} }
void populateAuthors() {
_authors = {};
for (var i = 0; i < quotes.length; i++) {
_authors.add(quotes[i].author);
}
}
Future<void> readQuotes() async { Future<void> readQuotes() async {
_loading = true; _loading = true;
_error = null; _error = null;
@@ -31,6 +40,8 @@ class QuoteProvider extends ChangeNotifier {
_error = e.toString(); _error = e.toString();
} }
populateAuthors();
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
} }
@@ -38,6 +49,7 @@ class QuoteProvider extends ChangeNotifier {
Future<void> createQuote(Quote quote) async { Future<void> createQuote(Quote quote) async {
final newQuote = await repo.createQuote(quote); final newQuote = await repo.createQuote(quote);
_quotes.add(newQuote); _quotes.add(newQuote);
populateAuthors();
notifyListeners(); notifyListeners();
} }
@@ -50,11 +62,20 @@ class QuoteProvider extends ChangeNotifier {
final index = _quotes.indexWhere((q) => q.id == quote.id); final index = _quotes.indexWhere((q) => q.id == quote.id);
if (index != -1) { if (index != -1) {
final oldAuthor = _quotes[index].author;
final newList = List<Quote>.from(_quotes); final newList = List<Quote>.from(_quotes);
newList[index] = updated; newList[index] = updated;
_quotes = newList; _quotes = newList;
Map<String, int> authorMap = {};
for (final q in quotes) {
authorMap[q.author] = (authorMap[q.author] ?? 0) + 1;
}
if (authorMap[oldAuthor] == 1) {
_authors.remove(oldAuthor);
}
_authors.add(updated.author);
} }
} finally { } finally {
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
} }
@@ -64,6 +85,7 @@ class QuoteProvider extends ChangeNotifier {
await repo.deleteQuote(quote); await repo.deleteQuote(quote);
_quotes.removeWhere((q) => q.id == quote.id); _quotes.removeWhere((q) => q.id == quote.id);
populateAuthors();
notifyListeners(); notifyListeners();
} }
} }