ltx-flutter/ltx_flutter/lib/appwrite/database_api.dart

217 lines
5.8 KiB
Dart

import 'package:appwrite/appwrite.dart';
import 'package:appwrite/models.dart';
import 'package:flutter/material.dart';
import 'package:ltx_flutter/appwrite/auth_api.dart';
import 'package:ltx_flutter/constants/constants.dart';
import 'package:intl/intl.dart';
class DatabaseAPI extends ChangeNotifier {
Client client = Client();
late final Account account;
late final Databases databases;
late final Realtime realtime;
final AuthAPI auth = AuthAPI();
late List<Document> _entries = [];
bool _ready = false;
// Getter methods
List<Document> get entries => _entries;
int get length => _entries.length;
bool get ready => _ready;
double get progress => length / total();
final DateFormat formatter = DateFormat('yyyy-MM-dd');
// Constructor
DatabaseAPI() {
init();
getAll();
subscribeRealtime();
}
init() {
client.setEndpoint(APPWRITE_URL).setProject(APPWRITE_PROJECT_ID);
account = Account(client);
databases = Databases(client);
realtime = Realtime(client);
}
elDate(dynamic el) {
return formatter.format(DateTime.parse(el.data['date']));
}
sortByDate(entries) {
return entries.sort(
(a, b) => a.$id.compareTo(b.$id),
);
}
subscribeRealtime() {
final subscription = realtime.subscribe(
['databases.$APPWRITE_DATABASE_ID.collections.$COLLECTION.documents']);
print("Subscribed to realtime");
subscription.stream.listen((response) {
String dateISO =
formatter.format(DateTime.parse(response.payload['date']));
if (response.events.contains(
'databases.$APPWRITE_DATABASE_ID.collections.$COLLECTION.documents.*.update')) {
// Entry was updated
int entryIndex =
_entries.indexWhere((element) => elDate(element) == dateISO);
Document newEntry = _entries[entryIndex];
newEntry.data['hours'] = response.payload['hours'];
newEntry.data['mood'] = response.payload['mood'];
newEntry.data['comments'] = response.payload['comments'];
_entries.removeAt(entryIndex);
_entries.add(newEntry);
notifyListeners();
// _entries.add(entry);
// sortByDate(_entries);
}
});
}
int total() {
String dateISO = DateTime.now().toIso8601String();
var referenceDate = DateTime.parse("2023-01-01");
final date = DateTime.parse(dateISO);
return date.difference(referenceDate).inDays + 1;
}
getAll() async {
String paginationQuery = Query.offset(0);
int max = total();
while (_entries.length < max) {
int remainder = max - _entries.length;
int limit = remainder > 100 ? 100 : remainder;
if (_entries.isNotEmpty) {
String lastDate = _entries.last.$id;
paginationQuery = Query.cursorAfter(lastDate);
}
List<Document> newEntries = await getEntries(
limit: limit,
paginationQuery: paginationQuery,
);
_entries.addAll(newEntries);
notifyListeners();
}
_ready = true;
}
getOne({required String date}) async {
try {
// print(date);
// print(_entries.last.$id);
return _entries.singleWhere((element) => element.$id == date);
} catch (e) {
int offset =
DateTime.parse(date).difference(DateTime.parse("2023-01-01")).inDays +
1;
List<Document> response = await getEntries(
limit: 1,
paginationQuery: Query.offset(offset),
);
if(response.isEmpty){
print("No entry in database; creating $date");
Document newEntry = await addEntry(date: date);
_entries.add(newEntry);
}
else{
_entries.add(response.first);
}
notifyListeners();
}
}
getEntries({int limit = 100, paginationQuery}) async {
var response = await databases.listDocuments(
databaseId: APPWRITE_DATABASE_ID,
collectionId: COLLECTION,
queries: [
Query.orderAsc("date"),
paginationQuery,
Query.limit(limit),
]);
return response.documents;
}
Future<Document> updateEntry(
{String? dateISO,
List<dynamic>? hours,
int? mood,
String? comments}) async {
String date = formatter.format(DateTime.parse(dateISO!));
int entryIndex = _entries.indexWhere((element) => elDate(element) == date);
hours ??= _entries[entryIndex].data['hours'];
comments ??= _entries[entryIndex].data['comments'];
mood ??= _entries[entryIndex].data['mood'];
Document newEntry = await databases.updateDocument(
databaseId: APPWRITE_DATABASE_ID,
collectionId: COLLECTION,
documentId: date,
data: {'hours': hours, 'mood': mood, 'comments': comments},
);
print("Updated $date.");
_entries.removeAt(entryIndex);
_entries.add(newEntry);
notifyListeners();
return newEntry;
}
updateHours(dayEntry, index, value) {
List<dynamic> hours = dayEntry.data['hours'];
try {
hours[index] = num.parse(value);
} catch (e) {
if (hours.length == index) {
hours.add(num.parse(value));
} else {
hours.addAll(List.generate(index - hours.length, (i) => -1));
hours.add(num.parse(value));
}
}
updateEntry(dateISO: dayEntry.data['date'], hours: hours);
}
Future<Document> addEntry(
{required String date,
List hours = const [],
dynamic mood,
String comments = ""}) async {
return databases.createDocument(
databaseId: APPWRITE_DATABASE_ID,
collectionId: COLLECTION,
documentId: date,
data: {
'date': date,
'hours': hours,
'mood': mood,
'comments': comments
});
}
Future<dynamic> deleteEntry({required String date}) {
return databases.deleteDocument(
databaseId: APPWRITE_DATABASE_ID,
collectionId: COLLECTION,
documentId: date);
}
}