diff --git a/lib/main.dart b/lib/main.dart index 644afd4..dc098f9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,22 @@ import 'package:flutter/material.dart'; +import 'package:maggs_victory_voyage/services/feed_provider.dart'; +import 'package:provider/provider.dart'; import 'package:maggs_victory_voyage/services/db_helper.dart'; import 'pages/splash_page.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await DbHelper.init(); - runApp(const Application()); + runApp( + MultiProvider( + providers: [ + ChangeNotifierProvider( + create: (_) => Feed(), + ) + ], + child: const Application(), + ), + ); } class Application extends StatelessWidget { diff --git a/lib/models/feed_item.dart b/lib/models/feed_item.dart new file mode 100644 index 0000000..176065d --- /dev/null +++ b/lib/models/feed_item.dart @@ -0,0 +1,16 @@ +class FeedItem { + final String text; + final DateTime timestamp; + + FeedItem.fromMap(Map map) + : text = map['text'], + timestamp = DateTime.parse(map['timestamp']); + + @override + bool operator ==(Object other) { + if (other is FeedItem) { + return other.timestamp == timestamp; + } + return false; + } +} diff --git a/lib/pages/splash_page.dart b/lib/pages/splash_page.dart index b7da741..03e94d0 100644 --- a/lib/pages/splash_page.dart +++ b/lib/pages/splash_page.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:maggs_victory_voyage/services/db_helper.dart'; +import 'package:provider/provider.dart'; +import '../services/feed_provider.dart'; import 'login_page.dart'; class SplashPage extends StatefulWidget { @@ -41,6 +43,8 @@ class _SplashPageState extends State { if (DbHelper.currentUser == null) { return const LoginPage(); } + + Provider.of(context, listen: false).feed; return Scaffold( body: const Column( children: [ diff --git a/lib/services/db_helper.dart b/lib/services/db_helper.dart index 1aaaffd..7febd56 100644 --- a/lib/services/db_helper.dart +++ b/lib/services/db_helper.dart @@ -2,6 +2,8 @@ import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; +import '../models/feed_item.dart'; + class DbHelper { static Future get _prefs async => SharedPreferences.getInstance(); @@ -58,9 +60,21 @@ class DbHelper { return false; } + static Future> fetchFeed() async { + List items = []; + final res = await _supabase.from('feed').select(); + for (final map in res) { + items.add(FeedItem.fromMap(map)); + } + return items; + } + static void logout() async { final prefs = await _prefs; bool success = await prefs.remove('username'); _supabase.auth.signOut(); } + + static Stream>> get feedStream => + _supabase.from('feed').stream(primaryKey: ['timestamp']); } diff --git a/lib/services/feed_provider.dart b/lib/services/feed_provider.dart new file mode 100644 index 0000000..66d3f84 --- /dev/null +++ b/lib/services/feed_provider.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:maggs_victory_voyage/services/db_helper.dart'; + +import '../models/feed_item.dart'; + +class Feed extends ChangeNotifier { + final List _feed = []; + Stream? feedStream; + + List get feed { + if (feedStream == null) { + DbHelper.fetchFeed().then((value) { + _feed.clear(); + _feed.addAll(value); + }); + feedStream = DbHelper.feedStream; + feedStream!.listen( + (event) => _updateFeed(event), + ); + } + return _feed; + } + + void _updateFeed(List> data) { + final List newFeed = + data.map((e) => FeedItem.fromMap(e)).toList(); + + final newItems = + newFeed.where((element) => !_feed.contains(element)).toList(); + + if (newItems.isNotEmpty) { + _feed.addAll(newItems); + notifyListeners(); + } + } +}