Skip to content

Commit

Permalink
feat: added basic dictionary system
Browse files Browse the repository at this point in the history
chore: added additional TODOs
  • Loading branch information
SethCohen committed Mar 27, 2023
1 parent 33115be commit 3351465
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 6 deletions.
24 changes: 24 additions & 0 deletions src/lib/models/dictionary_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class DictionaryModel {
String cardId;
String title;
String instructions;
String image;

DictionaryModel(
{required this.cardId,
required this.title,
required this.instructions,
required this.image});

factory DictionaryModel.fromMap(
String cardId,
Map<String, dynamic> data,
) {
return DictionaryModel(
cardId: cardId,
title: data['title'],
instructions: data['instructions'],
image: data['image'],
);
}
}
48 changes: 45 additions & 3 deletions src/lib/pages/dictionary_page.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/data_provider.dart';

class DictionaryPage extends StatefulWidget {
const DictionaryPage({super.key});
Expand All @@ -8,10 +10,50 @@ class DictionaryPage extends StatefulWidget {
}

class _DictionaryPageState extends State<DictionaryPage> {
final ScrollController _scrollController = ScrollController();

@override
void initState() {
super.initState();
_scrollController.addListener(_scrollListener);
}

@override
Widget build(BuildContext context) {
// TODO create dictionary page
// TODO add searching functionality
return const Center(child: CircularProgressIndicator());
final cards = context.watch<DataProvider>().dictionary;

// TODO add search bar
// TODO restyle with better loading indicator and better card design
return Scrollbar(
thumbVisibility: true,
controller: _scrollController,
child: ListView.builder(
controller: _scrollController,
itemCount: cards.length + 1,
itemBuilder: (context, index) {
if (index == cards.length) {
return SizedBox(
height: MediaQuery.of(context).size.height,
child: const Center(child: CircularProgressIndicator()),
);
}

return Card(
child: ListTile(
title: Text(cards[index].title),
subtitle: Text(cards[index].instructions),
leading: Image.network(cards[index].image),
),
);
}),
);
}

void _scrollListener() {
if (_scrollController.offset >=
_scrollController.position.maxScrollExtent &&
!_scrollController.position.outOfRange) {
context.read<DataProvider>().loadMoreDictionary();
}
}
}
1 change: 1 addition & 0 deletions src/lib/pages/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class _HomePageState extends State<HomePage> {
super.initState();

context.read<DataProvider>().loadLessons();
context.read<DataProvider>().loadDictionary();
}

@override
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pages/lessons_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class _LessonsPageState extends State<LessonsPage> {
Widget build(BuildContext context) {
final decks = context.watch<DataProvider>().lessons;

// TODO fix loading more lessons
// TODO add loading indicator
return ListView.builder(
controller: _scrollController,
itemCount: decks.length,
Expand Down
49 changes: 46 additions & 3 deletions src/lib/providers/data_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:spaced_repetition/sm.dart';
import '../models/dictionary_model.dart';
import '../models/lesson_model.dart';
import '../models/flashcard_model.dart';
import '../models/review_model.dart';
Expand All @@ -13,11 +14,14 @@ const pageSize = 5;
class DataProvider extends ChangeNotifier {
List<LessonModel> _lessons = [];
Map<String, List<ReviewModel>> _reviews = {};
List<DictionaryModel> _dictionary = [];

late DocumentSnapshot<Map<String, dynamic>> _lastDeckDoc;
late DocumentSnapshot<Map<String, dynamic>> _lastCardDoc;

List<LessonModel> get lessons => _lessons;
Map<String, List<ReviewModel>> get reviews => _reviews;
List<DictionaryModel> get dictionary => _dictionary;

Future<void> loadLessons() async {
final lessons = await FirebaseFirestore.instance
Expand Down Expand Up @@ -90,9 +94,9 @@ class DataProvider extends ChangeNotifier {
.where('userId', isEqualTo: currentUser.uid)
.get();

final reviewModelList = reviews.docs
.map((doc) => ReviewModel.fromMap(doc.id, doc.data()))
.toList();
final reviewModelList = reviews.docs.map((doc) {
return ReviewModel.fromMap(doc.id, doc.data());
}).toList();
_reviews =
groupBy(reviewModelList, (ReviewModel review) => review.deckTitle);
} on Exception catch (e) {
Expand Down Expand Up @@ -189,4 +193,43 @@ class DataProvider extends ChangeNotifier {
_reviews.remove(deckTitle);
notifyListeners();
}

Future<void> loadDictionary() async {
final dictionary = await FirebaseFirestore.instance
.collectionGroup('cards')
.where('type', isEqualTo: 'immutable')
.limit(pageSize)
.get();

_dictionary = dictionary.docs
.map((doc) => DictionaryModel.fromMap(doc.id, doc.data()))
.toList();

_lastCardDoc = dictionary.docs.last;

notifyListeners();
}

Future<void> loadMoreDictionary() async {
final cards = await FirebaseFirestore.instance
.collectionGroup('cards')
.where('type', isEqualTo: 'immutable')
.startAfterDocument(_lastCardDoc)
.limit(pageSize)
.get();

// If there are no more cards to fetch, return the current list of dictionary
if (cards.docs.isEmpty) {
return;
}

_dictionary = _dictionary
..addAll(cards.docs
.map((doc) => DictionaryModel.fromMap(doc.id, doc.data()))
.toList());

_lastCardDoc = cards.docs.last;

notifyListeners();
}
}
1 change: 1 addition & 0 deletions src/lib/widgets/flashcard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class _FlashcardState extends State<Flashcard> {
double cardWidth = screenWidth * 0.15;

return SizedBox(
// TODO fix responsiveness based of screen
width: cardWidth,
child: Card(
child: Column(
Expand Down

0 comments on commit 3351465

Please sign in to comment.