Marco
b83f547f6b
Now, an on-the-fly food lookup is created from existing entries on startup. Those entries are used to make suggestions when the user is typing to enter new food entries.
167 lines
3.9 KiB
Dart
167 lines
3.9 KiB
Dart
import 'dart:developer';
|
|
import 'dart:io';
|
|
|
|
import 'package:calodiary/food_entry_bloc.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:universal_platform/universal_platform.dart';
|
|
|
|
class FoodStorage {
|
|
static late FoodStorage _instance;
|
|
late String path;
|
|
late Map<String, double> _foodLookupDatabase = {};
|
|
|
|
FoodStorage._create();
|
|
|
|
static Future<FoodStorage> create() async {
|
|
var storage = FoodStorage._create();
|
|
|
|
Directory dir = Directory('');
|
|
|
|
if (UniversalPlatform.isDesktop) {
|
|
dir = await getApplicationCacheDirectory();
|
|
} else if (UniversalPlatform.isAndroid) {
|
|
dir = await getApplicationDocumentsDirectory();
|
|
}
|
|
|
|
storage.path = dir.path;
|
|
_instance = storage;
|
|
|
|
return _instance;
|
|
}
|
|
|
|
static FoodStorage getInstance() => _instance;
|
|
|
|
Future<List<FoodEntry>> getEntriesForDate(DateTime date) async {
|
|
List<FoodEntry> entries = [];
|
|
var filePath = '$path/${date.year}/${date.month}/${date.day}';
|
|
|
|
var file = File(filePath);
|
|
var exists = await file.exists();
|
|
|
|
if (!exists) return [];
|
|
|
|
var lines = await file.readAsLines();
|
|
|
|
for (var line in lines) {
|
|
var fields = line.split(',');
|
|
var entry = FoodEntry(
|
|
name: fields[1],
|
|
mass: double.parse(fields[2]),
|
|
kcalPerMass: double.parse(fields[3]));
|
|
entries.add(entry);
|
|
}
|
|
|
|
return entries;
|
|
}
|
|
|
|
Future<void> writeEntriesForDate(
|
|
DateTime date, List<FoodEntry> foodEntries) async {
|
|
var filePath = '$path/${date.year}/${date.month}/${date.day}';
|
|
var file = File(filePath);
|
|
|
|
var exists = await file.exists();
|
|
|
|
if (!exists) {
|
|
await file.create(recursive: true);
|
|
}
|
|
|
|
String fullString = '';
|
|
for (var entry in foodEntries) {
|
|
fullString += '${entry.toString()}\n';
|
|
}
|
|
|
|
await file.writeAsString(fullString);
|
|
}
|
|
|
|
Future<void> updateLimit(double limit) async {
|
|
var filePath = '$path/limit';
|
|
var file = File(filePath);
|
|
|
|
var exists = await file.exists();
|
|
if (!exists) {
|
|
await file.create();
|
|
}
|
|
|
|
await file.writeAsString(limit.toString());
|
|
}
|
|
|
|
Future<double> readLimit() async {
|
|
var filePath = '$path/limit';
|
|
var file = File(filePath);
|
|
var exists = await file.exists();
|
|
|
|
if (!exists) {
|
|
return 2000;
|
|
}
|
|
|
|
var line = await file.readAsLines();
|
|
|
|
double limit;
|
|
try {
|
|
limit = double.parse(line[0]);
|
|
} catch (e) {
|
|
limit = 2000;
|
|
}
|
|
|
|
return limit;
|
|
}
|
|
|
|
Future<String> readBrightness() async {
|
|
var filePath = '$path/brightness';
|
|
var file = File(filePath);
|
|
var exists = await file.exists();
|
|
|
|
if (!exists) {
|
|
return 'dark';
|
|
}
|
|
|
|
var line = await file.readAsLines();
|
|
|
|
if (line.isEmpty || (line[0] != 'dark' && line[0] != 'light')) {
|
|
return 'dark';
|
|
}
|
|
|
|
return line[0];
|
|
}
|
|
|
|
Future<void> writeBrightness(String brightness) async {
|
|
var filePath = '$path/brightness';
|
|
var file = File(filePath);
|
|
var exists = await file.exists();
|
|
|
|
if (!exists) {
|
|
file.create();
|
|
}
|
|
|
|
await file.writeAsString(brightness);
|
|
}
|
|
|
|
Future<void> buildFoodLookupDatabase() async {
|
|
// get a list of dates of the last 365 days
|
|
var dates = List<DateTime>.generate(365, (idx) {
|
|
var pastDay = Duration(days: idx);
|
|
return DateTime.now().subtract(pastDay);
|
|
});
|
|
|
|
for (var date in dates) {
|
|
addFoodEntryToLookupDatabaseFor(date);
|
|
}
|
|
}
|
|
|
|
Future<void> addFoodEntryToLookupDatabaseFor(DateTime date) async {
|
|
var entriesForDate = await getEntriesForDate(date);
|
|
|
|
for (var entry in entriesForDate) {
|
|
_foodLookupDatabase[entry.name] = entry.kcalPerMass;
|
|
log("Added entry: ${entry.name}/${entry.kcalPerMass}");
|
|
}
|
|
}
|
|
|
|
void addFoodEntryToLookupDatabase(FoodEntry entry) {
|
|
_foodLookupDatabase[entry.name] = entry.kcalPerMass;
|
|
log("Added entry: ${entry.name}/${entry.kcalPerMass}");
|
|
}
|
|
|
|
Map<String, double> get getFoodEntryLookupDatabase => _foodLookupDatabase;
|
|
}
|