import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/notifications/notifs.dart'; import 'package:loris/pages/notifications/single_notif.dart'; import 'package:loris/partials/loadingbox.dart'; import '../../business_logic/websocket.dart' as websocket; final notifStream = StreamController.broadcast(); class Notifications extends StatefulWidget { const Notifications({Key? key}) : super(key: key); @override State createState() => _NotificationsState(); } class _NotificationsState extends State { List notifs = []; Map maxIdData = {}; final ScrollController _controller = ScrollController(); Future loadMore() async { final data = await loadOldNotifications(maxIdData); final models = data.models; maxIdData = data.latest; List widgets = []; for (int i = 0; i < models.length; i++) { widgets.add( SingleNotif( model: models[i], ), ); } if (mounted) { setState(() { notifs.addAll(widgets); }); cleanChildren(); } } void reload() { if (mounted) { setState(() { _controller.animateTo( 0, duration: const Duration(seconds: 1), curve: Curves.easeInOut, ); maxIdData = {}; notifs = [const LoadingBox()]; }); loadMore(); } } @override void initState() { super.initState(); for (int i = 0; i < websocket.map.length; i++) { final keyI = websocket.map.keys.toList()[i]; websocket.map[keyI]!["home"]!.stream.listen((event) async { Map json = jsonDecode(event); if (json["event"] == "notification") { SingleNotif notif = SingleNotif( model: NotificationModel.fromJson( jsonDecode(json["payload"]), keyI, ), ); if (mounted) { setState(() { notifStream.sink.add(1); notifs.insert(0, notif); }); } } }); } loadMore(); } void cleanChildren() { setState(() { notifs.removeWhere((element) { return element.runtimeType != SingleNotif; }); notifs.add( TextButton.icon( onPressed: () { loadMore(); }, icon: const Icon(Icons.more_horiz), label: Text( "load-older-notifications".i18n(), ), ), ); }); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ Container( color: Theme.of(context).colorScheme.surface, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ IconButton( onPressed: () { reload(); }, icon: const Icon(Icons.refresh)) ], ), ), Expanded( child: ListView.separated( controller: _controller, addSemanticIndexes: true, itemBuilder: ((context, index) => notifs[index]), separatorBuilder: (context, index) => const SizedBox( height: 8, ), itemCount: notifs.length), ), ], ); } }