From a8fe95497da6bd5c2cc864a9c4691740fa5a2761 Mon Sep 17 00:00:00 2001 From: Abhay Maurya Date: Tue, 26 Oct 2021 17:02:39 +0530 Subject: [PATCH] update firestore data fetch --- lib/notifiers/firestore_notifier.dart | 16 ++++++ lib/pages/home_page.dart | 71 ++++++++++++++------------- lib/services/firestore_service.dart | 41 ++++++++++++---- lib/widgets/notice_tile.dart | 38 ++++++-------- 4 files changed, 99 insertions(+), 67 deletions(-) diff --git a/lib/notifiers/firestore_notifier.dart b/lib/notifiers/firestore_notifier.dart index 371779a..873b52c 100644 --- a/lib/notifiers/firestore_notifier.dart +++ b/lib/notifiers/firestore_notifier.dart @@ -7,9 +7,25 @@ class FirestoreNotifier with ChangeNotifier { final FirestoreService _firestoreService = locator(); Stream>? get noticesStream => _firestoreService.noticesStream; int get limit => _firestoreService.limit; + bool get priorityCheck => _firestoreService.priorityCheck; set limit(int value) { _firestoreService.limit = value; notifyListeners(); } + + void initNoticeStream() { + _firestoreService.initNoticeStream(false); + notifyListeners(); + } + + void loadMore() { + _firestoreService.loadMore(); + notifyListeners(); + } + + void togglePriorityCheck() { + _firestoreService.togglePriorityCheck(); + notifyListeners(); + } } diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index b8cdc9a..f1d1b66 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,8 +1,12 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:ip_notices/models/notice.dart'; +import 'package:ip_notices/notifiers/firestore_notifier.dart'; +import 'package:ip_notices/services/logger.dart'; import 'package:ip_notices/widgets/about_button.dart'; import 'package:ip_notices/widgets/notice_tile.dart'; +import 'package:ip_notices/widgets/theme_switch.dart'; +import 'package:provider/provider.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @@ -12,41 +16,37 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State { - bool priorityCheck = false; - int limit = 8; bool loading = false; ScrollController controller = ScrollController(); @override void initState() { super.initState(); + Future.delayed(const Duration()) + .then((value) => context.read().initNoticeStream()); controller.addListener(_scrollListener); } void _scrollListener() { if (controller.position.pixels == controller.position.maxScrollExtent) { - print("at the end of list"); + logger.d("at the end of list"); setState(() { - limit = limit + 8; + context.read().loadMore(); }); - print(limit); + logger.i(context.read().limit); } } @override Widget build(BuildContext context) { - Query notices = FirebaseFirestore.instance - .collection('notices') - .orderBy('createdAt', descending: true) - .limit(limit); return CupertinoPageScaffold( backgroundColor: Colors.white, child: CustomScrollView( physics: const BouncingScrollPhysics(), controller: controller, slivers: [ - CupertinoSliverNavigationBar( + const CupertinoSliverNavigationBar( leading: AboutButton(), - // trailing: ThemeSwitchButton(), + trailing: ThemeSwitchButton(), border: null, automaticallyImplyLeading: false, padding: EdgeInsetsDirectional.zero, @@ -56,13 +56,11 @@ class _HomePageState extends State { color: Colors.black, ), ), - backgroundColor: Colors.white, + backgroundColor: Colors.transparent, ), CupertinoSliverRefreshControl( onRefresh: () { - setState(() { - limit = 8; - }); + context.read().initNoticeStream(); return Future.delayed(const Duration(seconds: 1)) ..then((_) {}); }, @@ -77,28 +75,32 @@ class _HomePageState extends State { child: Row( children: [ Text( - priorityCheck ? "Priority" : "Latest", + context.watch().priorityCheck + ? "Priority" + : "Latest", style: TextStyle( color: Colors.black.withOpacity(0.8), fontWeight: FontWeight.w600, fontSize: 20, ), ), - Spacer(), + const Spacer(), ClipOval( child: Material( elevation: 0, color: Colors.transparent, borderRadius: BorderRadius.circular(500), child: IconButton( - icon: priorityCheck - ? Icon(CupertinoIcons.star) - : Icon(CupertinoIcons.time), + icon: context + .watch() + .priorityCheck + ? const Icon(CupertinoIcons.star) + : const Icon(CupertinoIcons.time), color: Colors.black.withOpacity(0.8), onPressed: () { - setState(() { - priorityCheck = !priorityCheck; - }); + context + .read() + .togglePriorityCheck(); }, ), ), @@ -111,16 +113,17 @@ class _HomePageState extends State { childCount: 1, ), ), - StreamBuilder( - stream: notices.snapshots(), + StreamBuilder>( + stream: context.watch().noticesStream, builder: - (BuildContext context, AsyncSnapshot snapshot) { + (BuildContext context, AsyncSnapshot> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { loading = true; } else { loading = false; } if (snapshot.hasError) { + logger.e(snapshot.error); return SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { @@ -146,7 +149,7 @@ class _HomePageState extends State { return SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { - if (index == snapshot.data?.docs.length) { + if (index == snapshot.data?.length) { return SizedBox( height: 100, width: 100, @@ -159,27 +162,27 @@ class _HomePageState extends State { : Container()), ); } - final bool download = snapshot.data?.docs[index]['url'] + final bool download = snapshot.data?[index].url .toString() .toLowerCase() .contains(".pdf") ?? false; - if (priorityCheck) { - if (snapshot.data?.docs[index]['priority']) { + if (context.watch().priorityCheck) { + if (snapshot.data?[index].priority ?? false) { return NoticeTile( download: download, - document: snapshot.data?.docs[index], + document: snapshot.data?[index], ); } } else { return NoticeTile( download: download, - document: snapshot.data?.docs[index], + document: snapshot.data?[index], ); } return Container(); }, - childCount: snapshot.data?.docs.length ?? 0 + 1, + childCount: snapshot.data?.length ?? 0 + 1, ), ); } diff --git a/lib/services/firestore_service.dart b/lib/services/firestore_service.dart index 57386ab..26d0536 100644 --- a/lib/services/firestore_service.dart +++ b/lib/services/firestore_service.dart @@ -1,22 +1,43 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:ip_notices/models/notice.dart'; +import 'package:ip_notices/services/logger.dart'; class FirestoreService { FirebaseFirestore firestore = FirebaseFirestore.instance; Stream>? noticesStream; int limit = 10; + bool priorityCheck = false; - FirestoreService() { - initNoticeStream(); + void initNoticeStream(bool more) { + logger.i("Init"); + if (!more) { + limit = 10; + } + noticesStream = priorityCheck + ? FirebaseFirestore.instance + .collection('notices') + .orderBy('createdAt', descending: true) + .where('priority', isEqualTo: true) + .limit(limit) + .snapshots() + .map((event) => + event.docs.map((doc) => Notice.fromJson(doc.data())).toList()) + : FirebaseFirestore.instance + .collection('notices') + .orderBy('createdAt', descending: true) + .limit(limit) + .snapshots() + .map((event) => + event.docs.map((doc) => Notice.fromJson(doc.data())).toList()); } - void initNoticeStream() { - noticesStream = FirebaseFirestore.instance - .collection('notices') - .orderBy('createdAt', descending: true) - .limit(limit) - .snapshots() - .map((event) => - event.docs.map((doc) => Notice.fromJson(doc.data())).toList()); + void loadMore() { + limit = limit + 10; + initNoticeStream(true); + } + + void togglePriorityCheck() { + priorityCheck = !priorityCheck; + initNoticeStream(false); } } diff --git a/lib/widgets/notice_tile.dart b/lib/widgets/notice_tile.dart index cc52a3b..cb5b0e9 100644 --- a/lib/widgets/notice_tile.dart +++ b/lib/widgets/notice_tile.dart @@ -1,11 +1,11 @@ import 'dart:io'; import 'dart:math'; -import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_downloader/flutter_downloader.dart'; import 'package:ip_notices/main.dart'; +import 'package:ip_notices/models/notice.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:share_plus/share_plus.dart'; @@ -18,7 +18,7 @@ class NoticeTile extends StatelessWidget { required this.download, }) : super(key: key); - final DocumentSnapshot? document; + final Notice? document; final bool download; _launchURL(String url) async { @@ -69,7 +69,7 @@ class NoticeTile extends StatelessWidget { color: Colors.red[400], size: 30.0), ), title: Text( - (document?.data() as Map)["title"], + (document?.title ?? ''), style: TextStyle( color: prefs.get('theme') == 0 ? Color(0xFF333333) @@ -90,7 +90,7 @@ class NoticeTile extends StatelessWidget { Padding( padding: const EdgeInsets.only(top: 2.0), child: Text( - " ${(document?.data() as Map)["date"]}", + " ${document?.date}", style: TextStyle( color: prefs.get('theme') == 0 ? Color(0xFF333333).withOpacity(0.8) @@ -114,8 +114,7 @@ class NoticeTile extends StatelessWidget { trailingIcon: CupertinoIcons.doc_text, onPressed: () { Navigator.pop(context); - String link = - "http://www.ipu.ac.in${(document?.data() as Map)["url"]}"; + String link = "http://www.ipu.ac.in${document?.url}"; _launchURL(link); }, ), @@ -128,8 +127,7 @@ class NoticeTile extends StatelessWidget { if (!status.isGranted) { await Permission.storage.request(); } - String link = - "http://www.ipu.ac.in${(document?.data() as Map)["url"]}"; + String link = "http://www.ipu.ac.in${document?.url}"; String _localPath = (await _findLocalPath()) + '/Notices'; final savedDir = Directory(_localPath); bool hasExisted = await savedDir.exists(); @@ -144,7 +142,7 @@ class NoticeTile extends StatelessWidget { final taskId = await FlutterDownloader.enqueue( url: link, fileName: - '${(document?.data() as Map)["title"].toString().replaceAll("/", "")} $name.pdf', + '${document?.title.toString().replaceAll("/", "")} $name.pdf', savedDir: _localPath, showNotification: true, openFileFromNotification: true, @@ -157,10 +155,8 @@ class NoticeTile extends StatelessWidget { trailingIcon: CupertinoIcons.share, onPressed: () { Navigator.pop(context); - String link = - "http://www.ipu.ac.in${(document?.data() as Map)["url"]}"; - Share.share( - "$link\n${(document?.data() as Map)["title"]}"); + String link = "http://www.ipu.ac.in${document?.url}"; + Share.share("$link\n${document?.title}"); }, ) ] @@ -171,8 +167,7 @@ class NoticeTile extends StatelessWidget { trailingIcon: CupertinoIcons.doc_text, onPressed: () { Navigator.pop(context); - String link = - "http://www.ipu.ac.in${(document?.data() as Map)["url"]}"; + String link = "http://www.ipu.ac.in${document?.url}"; _launchURL(link); }, ), @@ -181,10 +176,8 @@ class NoticeTile extends StatelessWidget { trailingIcon: CupertinoIcons.share, onPressed: () { Navigator.pop(context); - String link = - "http://www.ipu.ac.in${(document?.data() as Map)["url"]}"; - Share.share( - "$link\n${(document?.data() as Map)["title"]}"); + String link = "http://www.ipu.ac.in${document?.url}"; + Share.share("$link\n${document?.title}"); }, ) ], @@ -215,8 +208,7 @@ class NoticeTile extends StatelessWidget { debugPrint("Long Press"); }, onTap: () { - String link = - "http://www.ipu.ac.in${(document?.data() as Map)["url"]}"; + String link = "http://www.ipu.ac.in${document?.url}"; _launchURL(link); }, contentPadding: EdgeInsets.fromLTRB(20, 10, 20, 10), @@ -231,7 +223,7 @@ class NoticeTile extends StatelessWidget { color: Colors.red[400], size: 30.0), ), title: Text( - (document?.data() as Map)["title"], + document?.title ?? '', style: TextStyle( color: Colors.black, fontWeight: FontWeight.w600, @@ -248,7 +240,7 @@ class NoticeTile extends StatelessWidget { Padding( padding: const EdgeInsets.only(top: 2.0), child: Text( - " ${(document?.data() as Map)["date"]}", + " ${document?.date}", style: TextStyle( color: Colors.black.withOpacity(0.8), fontSize: 12,