import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:solaragent/auth.dart'; class NotificationScreen extends StatefulWidget { const NotificationScreen({super.key}); @override State createState() => _NotificationScreenState(); } class _NotificationScreenState extends State { final notificationEndpoint = Uri.parse('https://id.solsynth.dev/api/notifications?skip=0&take=25'); List notifications = List.empty(); @override void initState() { super.initState(); pullNotifications(); } Future pullNotifications() async { if (await authClient.isAuthorized()) { var res = await authClient.client!.get(notificationEndpoint); if (res.statusCode == 200) { setState(() { notifications = jsonDecode(utf8.decode(res.bodyBytes))["data"]; }); } } } Future markAsRead(element) async { if (authClient.client != null) { var id = element['id']; var uri = Uri.parse('https://id.solsynth.dev/api/notifications/$id/read'); await authClient.client!.put(uri); } } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: RefreshIndicator( onRefresh: pullNotifications, child: CustomScrollView( slivers: [ // Title SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.only(left: 10, right: 10, top: 20), child: ListTile( title: Text( 'Notifications', style: Theme.of(context).textTheme.headlineSmall, ), ), ), ), // Content notifications.isEmpty ? SliverToBoxAdapter( child: Container( padding: const EdgeInsets.symmetric(horizontal: 10), color: Colors.grey[300], child: const ListTile( leading: Icon(Icons.check), title: Text('You\'re done!'), subtitle: Text( 'There are no notifications unread for you.', ), ), ), ) : SliverList.builder( itemCount: notifications.length, itemBuilder: (BuildContext context, int index) { var element = notifications[index]; return Dismissible( key: Key('notification-$index'), onDismissed: (direction) { var subject = element["subject"]; markAsRead(element).then((value) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: RichText( text: TextSpan(children: [ TextSpan( text: subject, style: const TextStyle( fontWeight: FontWeight.bold), ), const TextSpan( text: " is marked as read", ) ]), ), ), ); }); setState(() { notifications.removeAt(index); }); }, background: Container( color: Colors.green, ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: ListTile( title: Text(element["subject"]), subtitle: Text(element["content"]), ), ), ); }, ), // Tips SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.only(top: 10), child: Text( "Pull to refresh, swipe to dismiss", textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodySmall, ), ), ), ], ), ), ), ); } }