Files
hlaskovnik-reimagined/frontend/lib/provider/quote_provider.dart
T

221 lines
5.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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;
}
List<MapEntry<String, int>> get sortedAuthorCounts {
final counts = <String, int>{};
for (var quote in filteredQuotes) {
counts.update(
quote.author,
(value) => value + 1,
ifAbsent: () => 1,
);
}
final list = counts.entries.toList()
..sort((a, b) => b.value.compareTo(a.value)); // descending
return list;
}
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");
}
Color getLeaderboardEntryBgColor(BuildContext context, int index) {
switch (index) {
case 0:
return Colors.yellow.shade300; // 1st place
case 1:
return Colors.grey.shade300; // 2nd place
case 2:
return Colors.brown.shade300; // 3rd place
default:
return Theme.of(context).cardColor; // default for all other entries
}
}
Color getLeaderboardEntryFgColor(BuildContext context, int index) {
switch (index) {
case 0:
case 1:
case 2:
return Colors.black;
default:
return Theme.of(context).textTheme.bodyMedium!.color!;
}
}
}