Skip to content

Commit

Permalink
Merge pull request #88 from shockbytes/23-add-wishlist-book-screen
Browse files Browse the repository at this point in the history
23 add wishlist book screen
  • Loading branch information
shockbytes authored Nov 29, 2023
2 parents bc42c48 + a3f5397 commit ef29cc9
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 51 deletions.
65 changes: 47 additions & 18 deletions lib/src/data/book/firebase_book_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,57 @@ import 'package:dantex/src/data/book/entity/book_state.dart';
import 'package:dantex/src/data/book/search_criteria.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:rxdart/rxdart.dart';

class FirebaseBookRepository implements BookRepository {
final FirebaseAuth _fbAuth;
final FirebaseDatabase _fbDb;

FirebaseBookRepository(this._fbAuth, this._fbDb);
final BehaviorSubject<List<Book>> _booksSubject = BehaviorSubject();

FirebaseBookRepository(this._fbAuth, this._fbDb) {
_setupBooksSubject();
}

void _setupBooksSubject() {
_booksRef().onValue.listen(
(DatabaseEvent event) {
switch (event.type) {
case DatabaseEventType.childAdded:
// TODO: Handle this case.
break;

case DatabaseEventType.childRemoved:
// TODO: Handle this case.
break;

case DatabaseEventType.childChanged:
// TODO: Handle this case.
break;
case DatabaseEventType.childMoved:
// No need to handle this case.
break;
case DatabaseEventType.value:
final Map<String, dynamic>? data = event.snapshot.toMap();

if (data == null) {
return;
}

final List<Book> books = data.values.map(
(value) {
final Map<String, dynamic> bookMap =
(value as Map<dynamic, dynamic>).cast();
return Book.fromJson(bookMap);
},
).toList();

_booksSubject.add(books);
break;
}
},
);
}

@override
Future<void> create(Book book) {
Expand All @@ -28,23 +73,7 @@ class FirebaseBookRepository implements BookRepository {

@override
Stream<List<Book>> getAllBooks() {
return _booksRef().onValue.map(
(DatabaseEvent event) {
final Map<String, dynamic>? data = event.snapshot.toMap();

if (data == null) {
return [];
}

return data.values.map(
(value) {
final Map<String, dynamic> bookMap =
(value as Map<dynamic, dynamic>).cast();
return Book.fromJson(bookMap);
},
).toList();
},
);
return _booksSubject.stream;
}

@override
Expand Down
31 changes: 31 additions & 0 deletions lib/src/ui/main/book_state_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:dantex/src/data/book/entity/book_state.dart';
import 'package:dantex/src/providers/book.dart';
import 'package:dantex/src/ui/book/book_item_widget.dart';
import 'package:dantex/src/ui/core/generic_error_widget.dart';
import 'package:dantex/src/util/layout_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

Expand Down Expand Up @@ -37,6 +38,20 @@ class _BooksScreen extends StatelessWidget {
);
}

return LayoutBuilder(
builder: (context, constraints) {
final DeviceFormFactor formFactor = getDeviceFormFactor(constraints);

return switch (formFactor) {
DeviceFormFactor.desktop => _buildLargeLayout(columns: 3),
DeviceFormFactor.tablet => _buildLargeLayout(columns: 2),
DeviceFormFactor.phone => _buildPhoneLayout(),
};
},
);
}

Widget _buildPhoneLayout() {
return ListView.separated(
padding: const EdgeInsets.all(16.0),
physics: const BouncingScrollPhysics(),
Expand All @@ -46,4 +61,20 @@ class _BooksScreen extends StatelessWidget {
const SizedBox(height: 16),
);
}

Widget _buildLargeLayout({
required int columns,
}) {
return GridView.builder(
padding: const EdgeInsets.all(16),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: columns,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
childAspectRatio: 4,
),
itemBuilder: (context, index) => BookItemWidget(books[index]),
itemCount: books.length,
);
}
}
22 changes: 18 additions & 4 deletions lib/src/ui/wishlist/wishlist_page.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import 'package:dantex/src/data/book/entity/book_state.dart';
import 'package:dantex/src/ui/core/themed_app_bar.dart';
import 'package:dantex/src/ui/main/book_state_page.dart';
import 'package:dantex/src/util/layout_utils.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';

class WishlistPage extends StatelessWidget {
const WishlistPage({super.key});

@override
Widget build(BuildContext context) {
return const Material(
child: Center(
child: Text('TODO Implement Wishlist'),
),
return LayoutBuilder(
builder: (context, constraints) {
return Scaffold(
appBar: isDesktop(constraints)
? null
: ThemedAppBar(
title: Text('navigation.wishlist'.tr()),
),
body: const Center(
child: BookStatePage(BookState.wishlist),
),
);
},
);
}
}
32 changes: 16 additions & 16 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ packages:
dependency: "direct main"
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.2"
version: "1.18.0"
convert:
dependency: transitive
description:
Expand Down Expand Up @@ -535,10 +535,10 @@ packages:
dependency: "direct main"
description:
name: flutter_platform_widgets
sha256: "107d5bc9a167b4e268cba44075ee399b6b2c63d44ede28f7e8c983d7fa4b59be"
sha256: "4970c211af1dad0a161e6379d04de2cace80283da0439f2f87d31a541f9b2b84"
url: "https://pub.dev"
source: hosted
version: "3.3.5"
version: "6.0.2"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
Expand Down Expand Up @@ -761,10 +761,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
mime:
dependency: transitive
description:
Expand Down Expand Up @@ -1118,10 +1118,10 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
state_notifier:
dependency: transitive
description:
Expand All @@ -1134,10 +1134,10 @@ packages:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
stream_transform:
dependency: transitive
description:
Expand Down Expand Up @@ -1174,10 +1174,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
version: "0.6.1"
timeline_tile:
dependency: "direct main"
description:
Expand Down Expand Up @@ -1326,10 +1326,10 @@ packages:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
Expand Down Expand Up @@ -1371,5 +1371,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.1.0 <4.0.0"
flutter: ">=3.13.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.16.0"
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies:
sdk: flutter

shared_preferences: ^2.2.1
flutter_platform_widgets: ^3.3.5
flutter_platform_widgets: ^6.0.2
flutter_svg: ^2.0.7
lottie: ^2.6.0
google_fonts: ^6.1.0
Expand Down
26 changes: 14 additions & 12 deletions test/data/book/firebase_book_repository_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ void main() {
final oldDbRef = MockDatabaseReference();
final newDbRef = MockDatabaseReference();

when(user.uid).thenReturn('userId');
when(fbAuth.currentUser).thenReturn(user);
when(fbDb.ref('users/userId/books')).thenReturn(oldDbRef);
when(oldDbRef.onValue).thenAnswer((_) => const Stream.empty());
when(oldDbRef.push()).thenReturn(newDbRef);
when(newDbRef.key).thenReturn('bookKey');

final fbAuthRepo = FirebaseBookRepository(fbAuth, fbDb);
final book = Book(
id: 'id',
Expand All @@ -46,15 +53,9 @@ void main() {
labels: [],
);

when(user.uid).thenReturn('userId');
when(fbAuth.currentUser).thenReturn(user);
when(fbDb.ref('users/userId/books')).thenReturn(oldDbRef);
when(oldDbRef.push()).thenReturn(newDbRef);
when(newDbRef.key).thenReturn('bookKey');

await fbAuthRepo.create(book);
verify(fbAuth.currentUser).called(1);
verify(fbDb.ref('users/userId/books')).called(1);
verify(fbAuth.currentUser).called(2);
verify(fbDb.ref('users/userId/books')).called(2);
verify(oldDbRef.push()).called(1);
verify(newDbRef.key).called(1);
verify(newDbRef.set(book.copyWith(id: 'bookKey').toJson())).called(1);
Expand All @@ -67,17 +68,18 @@ void main() {
final oldDbRef = MockDatabaseReference();
final newDbRef = MockDatabaseReference();

final fbAuthRepo = FirebaseBookRepository(fbAuth, fbDb);

when(user.uid).thenReturn('userId');
when(fbAuth.currentUser).thenReturn(user);
when(fbDb.ref('users/userId/books')).thenReturn(oldDbRef);
when(oldDbRef.onValue).thenAnswer((_) => const Stream.empty());
when(oldDbRef.child('bookId')).thenReturn(newDbRef);
when(newDbRef.remove()).thenAnswer((_) async {});

final fbAuthRepo = FirebaseBookRepository(fbAuth, fbDb);

await fbAuthRepo.delete('bookId');
verify(fbAuth.currentUser).called(1);
verify(fbDb.ref('users/userId/books')).called(1);
verify(fbAuth.currentUser).called(2);
verify(fbDb.ref('users/userId/books')).called(2);
verify(oldDbRef.child('bookId')).called(1);
verify(newDbRef.remove()).called(1);
});
Expand Down

0 comments on commit ef29cc9

Please sign in to comment.