Skip to content

Commit

Permalink
feat: supports deck modification
Browse files Browse the repository at this point in the history
  • Loading branch information
3waffel committed Aug 8, 2024
1 parent af6712a commit 5aa5086
Show file tree
Hide file tree
Showing 14 changed files with 652 additions and 411 deletions.
223 changes: 0 additions & 223 deletions lib/common/card_database.dart

This file was deleted.

24 changes: 24 additions & 0 deletions lib/common/database/card_database.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:flutter/foundation.dart';
import 'package:vocab_box/common/database/firebase_database.dart';
import 'package:vocab_box/common/database/local_database.dart';
import 'package:vocab_box/models/card.dart';

abstract class CardDatabase {
static const table = 'default_deck';

Future<void> createTable(String table);
Future<void> deleteTable(String table);
Future<List<Map<String, Object?>>> getTable(String table);
Future<List<Map<String, Object?>>> getLearningFromTable(String table);
Future<List<String>> getTableNameList();
Future<void> insertMany({
required Iterable<CardModel> cardList,
required String table,
});
Future<void> updateMany({
required Iterable<CardModel> cardList,
required String table,
});
}

CardDatabase cardDatabase = kIsWeb ? FireBaseDatabase() : LocalDatabase();
121 changes: 121 additions & 0 deletions lib/common/database/firebase_database.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:vocab_box/common/deck_loader.dart';
import 'package:vocab_box/models/card.dart';

import 'card_database.dart';

typedef FBDatabase = DocumentReference<Map<String, dynamic>>;

class FireBaseDatabase implements CardDatabase {
static const table = 'default_deck';

/// private constructor
FireBaseDatabase._internal();
static final FireBaseDatabase _instance = FireBaseDatabase._internal();
factory FireBaseDatabase() => _instance;

static FBDatabase? _database = null;
Future<FBDatabase> get database async {
if (_database != null) {
return _database!;
}
_database = await _openDatabase();
return _database!;
}

Future<FBDatabase> _openDatabase() async {
final auth = FirebaseAuth.instance;
final uid = auth.currentUser!.uid;
final users = FirebaseFirestore.instance.collection("users");

final dbRef = users.doc(uid);
final tableRef = dbRef.collection(table);

final tableSnapshot = await tableRef.get();
if (tableSnapshot.docs.length == 0) {
await dbRef.set(
{table: tableRef.path},
SetOptions(merge: true),
);
final cardList = await DeckLoader().loadFromAsset();
for (var card in cardList) {
await tableRef.doc(card.id.toString()).set(card.toMap());
}
}
return dbRef;
}

Future<List<Map<String, Object?>>> getLearningFromTable(String table) async {
final dbRef = await database;
final tableRef = dbRef.collection(table);
final tableSnapshot =
await tableRef.where("isLearning", isEqualTo: 1).get();
return List.generate(
tableSnapshot.docs.length,
(index) => tableSnapshot.docs[index].data(),
);
}

Future<void> createTable(String table) async {
final tables = await getTableNameList();
if (tables.contains(table)) {
return;
}

final dbRef = await database;
final tableRef = dbRef.collection(table);
await dbRef.set(
{table: tableRef.path},
SetOptions(merge: true),
);
}

Future<void> deleteTable(String table) async {
final dbRef = await database;
final tableRef = dbRef.collection(table);
final tableSnapshot = await tableRef.get();

for (var doc in tableSnapshot.docs) {
await doc.reference.delete();
}
dbRef.update({table: null});
}

Future<List<Map<String, Object?>>> getTable(String table) async {
final dbRef = await database;
final tableSnapshot = await dbRef.collection(table).get();
return List.generate(
tableSnapshot.docs.length,
(index) => tableSnapshot.docs[index].data(),
);
}

Future<List<String>> getTableNameList() async {
final dbRef = await database;
final dbSnapshot = await dbRef.get();
final data = dbSnapshot.data()!;
data.removeWhere((key, value) => value == null);
return List.from(data.keys);
}

Future<void> insertMany({
required Iterable<CardModel> cardList,
required String table,
}) async {
final db = await database;
for (var item in cardList) {
await db.collection(table).doc(item.id.toString()).set(item.toMap());
}
}

Future<void> updateMany({
required Iterable<CardModel> cardList,
required String table,
}) async {
final db = await database;
for (var item in cardList) {
await db.collection(table).doc(item.id.toString()).set(item.toMap());
}
}
}
Loading

0 comments on commit 5aa5086

Please sign in to comment.