import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:fcs/data/services/services.dart'; import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/vo/message.dart'; import 'package:fcs/pages/main/model/base_model.dart'; import 'package:logging/logging.dart'; class MessageModel extends BaseModel { final log = Logger('MessageModel'); List messages = []; @override logout() async { if (listener != null) await listener!.cancel(); messages = []; } late Query query; DocumentSnapshot? prevSnap; late bool isEnded; late bool isLoading; String? userID; StreamSubscription? listener; static const int rowPerLoad = 20; void initQuery(String? userID) { if (userID == null) return; this.messages = []; this.userID = userID; this.prevSnap = null; query = FirebaseFirestore.instance .collection("$user_collection/$userID/$messages_collection") .orderBy('date', descending: true); load(); } Future load() async { // if (prevSnap == null) return; Query _query = prevSnap != null ? query.startAfterDocument(prevSnap!) : query; QuerySnapshot snapshot = await _query.limit(rowPerLoad).get(GetOptions(source: Source.server)); int count = snapshot.docs.length; isEnded = count < rowPerLoad; prevSnap = count > 0 ? snapshot.docs[count - 1] : prevSnap; snapshot.docs.forEach((e) { messages.add(Message.fromMap(e.data() as Map, e.id)); if (messages.length == 1) { _initListener(e); } }); notifyListeners(); } void _initListener(DocumentSnapshot snap) { if (listener != null) listener!.cancel(); listener = FirebaseFirestore.instance .collection("$user_collection/$userID/$messages_collection") .orderBy('date', descending: true) .endBeforeDocument(snap) .snapshots(includeMetadataChanges: true) .listen((qs) { qs.docChanges.forEach((c) { switch (c.type) { case DocumentChangeType.added: log.info("added!! $c"); messages.insert( 0, Message.fromMap( c.doc.data() as Map, c.doc.id)); notifyListeners(); break; case DocumentChangeType.modified: log.info("modified!! $c"); break; default: } }); }); } Future sendMessage(String msg, String receiverID) { Message message = Message(message: msg, receiverID: receiverID); return Services.instance.commonService.sendMessage(message); } Future seenMessages(String ownerID, bool seenByOwner) { return Services.instance.commonService.seenMessage(ownerID, seenByOwner); } }