194 lines
4.5 KiB
Dart
194 lines
4.5 KiB
Dart
// gets all quotes from the database and returns them in a list
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:frontend/model/quote.dart';
|
|
import 'package:frontend/repository/quote_repository.dart';
|
|
import 'dart:math';
|
|
import 'dart:io';
|
|
|
|
class QuoteProvider extends ChangeNotifier {
|
|
List<Quote> _quotes = [];
|
|
Set<String> _authors = {};
|
|
bool _loading = false;
|
|
String? _error;
|
|
|
|
List<Quote> get quotes => _quotes;
|
|
Set<String> get authors => _authors;
|
|
bool get loading => _loading;
|
|
String? get error => _error;
|
|
List<Quote> get filteredQuotes {
|
|
final query = filterController.text.toLowerCase();
|
|
|
|
final filtered = _quotes.where((quote) {
|
|
switch (filterBy) {
|
|
case 0:
|
|
return quote.author.toLowerCase().contains(query);
|
|
case 1:
|
|
return quote.body.toLowerCase().contains(query);
|
|
default:
|
|
return true;
|
|
}
|
|
}).toList();
|
|
|
|
// sort descending
|
|
filtered.sort((a, b) => b.id.compareTo(a.id));
|
|
|
|
return filtered;
|
|
}
|
|
|
|
Map<String, int> get authorCounts {
|
|
final counts = <String, int>{};
|
|
|
|
for (var quote in filteredQuotes) {
|
|
counts.update(
|
|
quote.author,
|
|
(value) => value + 1,
|
|
ifAbsent: () => 1,
|
|
);
|
|
}
|
|
|
|
return counts;
|
|
}
|
|
|
|
final QuoteRepository repo = QuoteRepository();
|
|
|
|
int filterBy = 0; // 0 = by author, 1 = by quote
|
|
var filterController = TextEditingController(text: '');
|
|
|
|
void clearFilterController() {
|
|
filterController.text = '';
|
|
}
|
|
|
|
Quote randomQuote = Quote(
|
|
id: 0,
|
|
body: "quote text",
|
|
author: "dummy"
|
|
);
|
|
bool randomQuoteDeterminator = true;
|
|
String get randomQuoteText {
|
|
if (randomQuoteDeterminator) {
|
|
return randomQuote.body;
|
|
} else {
|
|
return randomQuote.author;
|
|
}
|
|
}
|
|
|
|
void flipRandomQuote() {
|
|
randomQuoteDeterminator = !randomQuoteDeterminator;
|
|
notifyListeners();
|
|
}
|
|
|
|
void nextRandomQuote() {
|
|
final random = Random();
|
|
randomQuote = filteredQuotes[random.nextInt(filteredQuotes.length)];
|
|
notifyListeners();
|
|
}
|
|
|
|
void filterQuotes() {
|
|
notifyListeners();
|
|
}
|
|
|
|
QuoteProvider() {
|
|
readQuotes(); // auto-load on creation
|
|
}
|
|
|
|
void populateAuthors() {
|
|
_authors = {};
|
|
for (var i = 0; i < quotes.length; i++) {
|
|
_authors.add(quotes[i].author);
|
|
}
|
|
}
|
|
|
|
void setFilterBy(int value) {
|
|
filterBy = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> readQuotes() async {
|
|
_loading = true;
|
|
_error = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
_quotes = await repo.readQuotes();
|
|
} catch (e) {
|
|
_error = e.toString();
|
|
}
|
|
|
|
populateAuthors();
|
|
|
|
_loading = false;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> createQuote(Quote quote) async {
|
|
final newQuote = await repo.createQuote(quote);
|
|
_quotes.add(newQuote);
|
|
populateAuthors();
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> updateQuote(Quote quote) async {
|
|
try {
|
|
_loading = true;
|
|
notifyListeners();
|
|
|
|
final updated = await repo.updateQuote(quote);
|
|
|
|
final index = _quotes.indexWhere((q) => q.id == quote.id);
|
|
if (index != -1) {
|
|
final oldAuthor = _quotes[index].author;
|
|
final newList = List<Quote>.from(_quotes);
|
|
newList[index] = updated;
|
|
_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 {
|
|
_loading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> deleteQuote(Quote quote) async {
|
|
await repo.deleteQuote(quote);
|
|
|
|
_quotes.removeWhere((q) => q.id == quote.id);
|
|
populateAuthors();
|
|
notifyListeners();
|
|
}
|
|
|
|
|
|
Future<Directory> _getSaveDirectory() async {
|
|
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
|
|
final path = Platform.isWindows
|
|
? Platform.environment['USERPROFILE']
|
|
: Platform.environment['HOME'];
|
|
|
|
return Directory(path!);
|
|
}
|
|
|
|
// Mobile fallback
|
|
return await getApplicationDocumentsDirectory();
|
|
}
|
|
|
|
Future<void> exportQuotesToFile() async {
|
|
final dir = await _getSaveDirectory();
|
|
|
|
final datetime = DateTime.now().toUtc().toString()
|
|
.replaceAll(" ", "T")
|
|
.replaceAll(":", "-")
|
|
.replaceAll(RegExp(r"\..*"), "");
|
|
|
|
final file = File('${dir.path}/hlasky_$datetime.txt');
|
|
await file.writeAsString("${filteredQuotes.join("\n")}\n");
|
|
}
|
|
} |