Feed stream with changenotifier
This commit is contained in:
@@ -1,11 +1,22 @@
|
|||||||
import 'package:flutter/material.dart';
|
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 'package:maggs_victory_voyage/services/db_helper.dart';
|
||||||
import 'pages/splash_page.dart';
|
import 'pages/splash_page.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await DbHelper.init();
|
await DbHelper.init();
|
||||||
runApp(const Application());
|
runApp(
|
||||||
|
MultiProvider(
|
||||||
|
providers: [
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (_) => Feed(),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
child: const Application(),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Application extends StatelessWidget {
|
class Application extends StatelessWidget {
|
||||||
|
|||||||
16
lib/models/feed_item.dart
Normal file
16
lib/models/feed_item.dart
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
class FeedItem {
|
||||||
|
final String text;
|
||||||
|
final DateTime timestamp;
|
||||||
|
|
||||||
|
FeedItem.fromMap(Map<String, dynamic> map)
|
||||||
|
: text = map['text'],
|
||||||
|
timestamp = DateTime.parse(map['timestamp']);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (other is FeedItem) {
|
||||||
|
return other.timestamp == timestamp;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:maggs_victory_voyage/services/db_helper.dart';
|
import 'package:maggs_victory_voyage/services/db_helper.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../services/feed_provider.dart';
|
||||||
import 'login_page.dart';
|
import 'login_page.dart';
|
||||||
|
|
||||||
class SplashPage extends StatefulWidget {
|
class SplashPage extends StatefulWidget {
|
||||||
@@ -41,6 +43,8 @@ class _SplashPageState extends State<SplashPage> {
|
|||||||
if (DbHelper.currentUser == null) {
|
if (DbHelper.currentUser == null) {
|
||||||
return const LoginPage();
|
return const LoginPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Provider.of<Feed>(context, listen: false).feed;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: const Column(
|
body: const Column(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
|
||||||
|
import '../models/feed_item.dart';
|
||||||
|
|
||||||
class DbHelper {
|
class DbHelper {
|
||||||
static Future<SharedPreferences> get _prefs async =>
|
static Future<SharedPreferences> get _prefs async =>
|
||||||
SharedPreferences.getInstance();
|
SharedPreferences.getInstance();
|
||||||
@@ -58,9 +60,21 @@ class DbHelper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<List<FeedItem>> fetchFeed() async {
|
||||||
|
List<FeedItem> items = [];
|
||||||
|
final res = await _supabase.from('feed').select();
|
||||||
|
for (final map in res) {
|
||||||
|
items.add(FeedItem.fromMap(map));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
static void logout() async {
|
static void logout() async {
|
||||||
final prefs = await _prefs;
|
final prefs = await _prefs;
|
||||||
bool success = await prefs.remove('username');
|
bool success = await prefs.remove('username');
|
||||||
_supabase.auth.signOut();
|
_supabase.auth.signOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Stream<List<Map<String, dynamic>>> get feedStream =>
|
||||||
|
_supabase.from('feed').stream(primaryKey: ['timestamp']);
|
||||||
}
|
}
|
||||||
|
|||||||
36
lib/services/feed_provider.dart
Normal file
36
lib/services/feed_provider.dart
Normal file
@@ -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<FeedItem> _feed = [];
|
||||||
|
Stream? feedStream;
|
||||||
|
|
||||||
|
List<FeedItem> 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<Map<String, dynamic>> data) {
|
||||||
|
final List<FeedItem> newFeed =
|
||||||
|
data.map((e) => FeedItem.fromMap(e)).toList();
|
||||||
|
|
||||||
|
final newItems =
|
||||||
|
newFeed.where((element) => !_feed.contains(element)).toList();
|
||||||
|
|
||||||
|
if (newItems.isNotEmpty) {
|
||||||
|
_feed.addAll(newItems);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user