From d37d4a6866f373718130f623bb60c482bc7af203 Mon Sep 17 00:00:00 2001 From: marcoabat Date: Sat, 12 Aug 2023 12:43:15 +0200 Subject: [PATCH] Shows username on listtile --- lib/main.dart | 7 ++++++- lib/models/profile.dart | 12 ++++++++++++ lib/pages/dashboard_page.dart | 2 +- lib/pages/detail_checklist_page.dart | 12 ++++++++++-- lib/pages/landing_page.dart | 7 ++++++- lib/services/dbhelper.dart | 18 ++++++++++++++++++ lib/services/profile_provider.dart | 18 ++++++++++++++++++ lib/widgets/item_list_tile.dart | 19 ++++++++++++++++++- 8 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 lib/models/profile.dart create mode 100644 lib/services/profile_provider.dart diff --git a/lib/main.dart b/lib/main.dart index b0dffda..859e9e1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,7 @@ import 'package:briessenchecker/pages/detail_checklist_page.dart'; import 'package:briessenchecker/pages/edit_checklist_page.dart'; import 'package:briessenchecker/services/checklist_provider.dart'; import 'package:briessenchecker/services/dbhelper.dart'; +import 'package:briessenchecker/services/profile_provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:provider/provider.dart'; @@ -16,6 +17,9 @@ void main() async { ChangeNotifierProvider( create: (_) => ChecklistProvider(), ), + ChangeNotifierProvider( + create: (_) => ProfileProvider(), + ), StreamProvider.value( value: DbHelper.checklistChangeEventStream, initialData: null, @@ -38,8 +42,9 @@ class MyApp extends StatelessWidget { theme: ThemeData.dark( useMaterial3: true, ).copyWith( + dividerTheme: const DividerThemeData(thickness: 1), colorScheme: ColorScheme.fromSeed( - seedColor: const Color.fromARGB(255, 0, 141, 42), + seedColor: const Color.fromARGB(255, 17, 212, 75), ), ), initialRoute: '/', diff --git a/lib/models/profile.dart b/lib/models/profile.dart new file mode 100644 index 0000000..27114d6 --- /dev/null +++ b/lib/models/profile.dart @@ -0,0 +1,12 @@ +class Profile { + final String id; + final String username; + final String language; + final String bio; + + Profile( + {required this.id, + this.username = '', + this.language = '', + this.bio = ''}); +} diff --git a/lib/pages/dashboard_page.dart b/lib/pages/dashboard_page.dart index 8cd250a..e9e93b5 100644 --- a/lib/pages/dashboard_page.dart +++ b/lib/pages/dashboard_page.dart @@ -106,7 +106,7 @@ class _DashboardPageState extends State { clChangeStream.listen(_onClChanged); return Scaffold( appBar: AppBar( - title: const Text('Brießenchecker9000'), + title: const Text('Brisenchecker9000'), actions: [ IconButton( onPressed: () => DbHelper.logout(), diff --git a/lib/pages/detail_checklist_page.dart b/lib/pages/detail_checklist_page.dart index 8761a83..2e66ae4 100644 --- a/lib/pages/detail_checklist_page.dart +++ b/lib/pages/detail_checklist_page.dart @@ -76,7 +76,7 @@ class _DetailChecklistPageState extends State { } else if (snapshot.hasError) { return Text('Ooooops, ${snapshot.error}'); } else { - return const CircularProgressIndicator(); + return const Center(child: CircularProgressIndicator()); } } @@ -110,6 +110,7 @@ class _DetailChecklistPageState extends State { isChecked: _checkedItemIds.contains(item.id), onCheckedChanged: (isChecked) => _onItemCheckedChanged(isChecked, item.id), + ownerId: item.ownerId, ); } @@ -179,9 +180,16 @@ class _DetailChecklistPageState extends State { if (snapshot.hasData) { _items = DbHelper.resToItemList(snapshot.data!); } - return ListView.builder( + return ListView.separated( itemCount: _items.length, itemBuilder: _itemListBuilder, + separatorBuilder: (context, index) { + return const Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 15.0), + child: Divider(), + )); + }, ); } diff --git a/lib/pages/landing_page.dart b/lib/pages/landing_page.dart index 53270b8..3e0ceda 100644 --- a/lib/pages/landing_page.dart +++ b/lib/pages/landing_page.dart @@ -1,8 +1,10 @@ import 'package:briessenchecker/pages/dashboard_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart' as p; import 'package:supabase_flutter/supabase_flutter.dart'; import '../services/dbhelper.dart'; +import '../services/profile_provider.dart'; import 'login_page.dart'; class LandingPage extends StatefulWidget { @@ -27,8 +29,11 @@ class _LandingPageState extends State { return const LoginPage(); } - void _onAuthEvent(AuthState event) { + void _onAuthEvent(AuthState event) async { if (event.event == AuthChangeEvent.signedIn) { + await DbHelper.fetchProfiles().then((value) => + p.Provider.of(context, listen: false) + .updateProfiles(value)); setState(() => _isLoggedIn = true); } else if (event.event == AuthChangeEvent.signedOut) { setState(() => _isLoggedIn = false); diff --git a/lib/services/dbhelper.dart b/lib/services/dbhelper.dart index 77e5b9d..c28f06f 100644 --- a/lib/services/dbhelper.dart +++ b/lib/services/dbhelper.dart @@ -9,6 +9,8 @@ import '../models/checklist.dart'; import '../models/listitem.dart'; import 'package:provider/provider.dart' as provider; +import '../models/profile.dart'; + class DbHelper { static const checkedItemsTableName = 'checkedItems'; static const checklistsTableName = 'checklists'; @@ -76,6 +78,22 @@ class DbHelper { return itemIdList; } + static Future> fetchProfiles() async { + List profiles = []; + final res = await _client + .from(profilesTableName) + .select>>(); + for (final element in res) { + profiles.add(Profile( + id: element['id'], + username: element['username'], + language: element['language'] ?? '', + bio: element['bio'] ?? '', + )); + } + return profiles; + } + static Future insertCheckedEntry(int checklistId, int itemId) async { final ownerId = _client.auth.currentSession!.user.id; await _client.from(checkedItemsTableName).insert({ diff --git a/lib/services/profile_provider.dart b/lib/services/profile_provider.dart new file mode 100644 index 0000000..533ce29 --- /dev/null +++ b/lib/services/profile_provider.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +import '../models/profile.dart'; + +class ProfileProvider extends ChangeNotifier { + List _profiles = []; + + void updateProfiles(List profiles, {bool silent = false}) { + _profiles = profiles; + if (!silent) notifyListeners(); + } + + Profile? getProfileById(String id) { + if (_profiles.isEmpty) return null; + final profile = _profiles.where((element) => element.id == id).first; + return profile; + } +} diff --git a/lib/widgets/item_list_tile.dart b/lib/widgets/item_list_tile.dart index 5c84028..3a25266 100644 --- a/lib/widgets/item_list_tile.dart +++ b/lib/widgets/item_list_tile.dart @@ -1,4 +1,8 @@ +import 'package:briessenchecker/services/dbhelper.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../services/profile_provider.dart'; typedef BoolCallback = void Function(bool isSelected); @@ -12,6 +16,7 @@ class ItemListTile extends StatefulWidget { required this.selectionMode, required this.isChecked, required this.onCheckedChanged, + this.ownerId = '', }); final String title; final String description; @@ -20,6 +25,7 @@ class ItemListTile extends StatefulWidget { final VoidCallback onTap; final BoolCallback onCheckedChanged; final BoolCallback itemSelectionChanged; + final String ownerId; @override State createState() => _ItemListTileState(); @@ -28,10 +34,12 @@ class ItemListTile extends StatefulWidget { class _ItemListTileState extends State { late bool isChecked; bool isSelected = false; + late ProfileProvider profileProvider; @override void initState() { super.initState(); + profileProvider = Provider.of(context, listen: false); isChecked = widget.isChecked; } @@ -39,7 +47,16 @@ class _ItemListTileState extends State { Widget build(BuildContext context) { return ListTile( title: Text(widget.title), - subtitle: Text(widget.description), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(widget.description), + Text( + profileProvider.getProfileById(widget.ownerId)?.username ?? '', + style: const TextStyle(color: Colors.grey), + ) + ], + ), onTap: _onTap, onLongPress: _onLongPress, selected: isSelected,