Shows username on listtile

This commit is contained in:
marcoabat
2023-08-12 12:43:15 +02:00
parent 271190b459
commit d37d4a6866
8 changed files with 89 additions and 6 deletions

View File

@@ -2,6 +2,7 @@ import 'package:briessenchecker/pages/detail_checklist_page.dart';
import 'package:briessenchecker/pages/edit_checklist_page.dart'; import 'package:briessenchecker/pages/edit_checklist_page.dart';
import 'package:briessenchecker/services/checklist_provider.dart'; import 'package:briessenchecker/services/checklist_provider.dart';
import 'package:briessenchecker/services/dbhelper.dart'; import 'package:briessenchecker/services/dbhelper.dart';
import 'package:briessenchecker/services/profile_provider.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -16,6 +17,9 @@ void main() async {
ChangeNotifierProvider( ChangeNotifierProvider(
create: (_) => ChecklistProvider(), create: (_) => ChecklistProvider(),
), ),
ChangeNotifierProvider(
create: (_) => ProfileProvider(),
),
StreamProvider.value( StreamProvider.value(
value: DbHelper.checklistChangeEventStream, value: DbHelper.checklistChangeEventStream,
initialData: null, initialData: null,
@@ -38,8 +42,9 @@ class MyApp extends StatelessWidget {
theme: ThemeData.dark( theme: ThemeData.dark(
useMaterial3: true, useMaterial3: true,
).copyWith( ).copyWith(
dividerTheme: const DividerThemeData(thickness: 1),
colorScheme: ColorScheme.fromSeed( colorScheme: ColorScheme.fromSeed(
seedColor: const Color.fromARGB(255, 0, 141, 42), seedColor: const Color.fromARGB(255, 17, 212, 75),
), ),
), ),
initialRoute: '/', initialRoute: '/',

12
lib/models/profile.dart Normal file
View File

@@ -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 = ''});
}

View File

@@ -106,7 +106,7 @@ class _DashboardPageState extends State<DashboardPage> {
clChangeStream.listen(_onClChanged); clChangeStream.listen(_onClChanged);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Brienchecker9000'), title: const Text('Brisenchecker9000'),
actions: [ actions: [
IconButton( IconButton(
onPressed: () => DbHelper.logout(), onPressed: () => DbHelper.logout(),

View File

@@ -76,7 +76,7 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
} else if (snapshot.hasError) { } else if (snapshot.hasError) {
return Text('Ooooops, ${snapshot.error}'); return Text('Ooooops, ${snapshot.error}');
} else { } else {
return const CircularProgressIndicator(); return const Center(child: CircularProgressIndicator());
} }
} }
@@ -110,6 +110,7 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
isChecked: _checkedItemIds.contains(item.id), isChecked: _checkedItemIds.contains(item.id),
onCheckedChanged: (isChecked) => onCheckedChanged: (isChecked) =>
_onItemCheckedChanged(isChecked, item.id), _onItemCheckedChanged(isChecked, item.id),
ownerId: item.ownerId,
); );
} }
@@ -179,9 +180,16 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
if (snapshot.hasData) { if (snapshot.hasData) {
_items = DbHelper.resToItemList(snapshot.data!); _items = DbHelper.resToItemList(snapshot.data!);
} }
return ListView.builder( return ListView.separated(
itemCount: _items.length, itemCount: _items.length,
itemBuilder: _itemListBuilder, itemBuilder: _itemListBuilder,
separatorBuilder: (context, index) {
return const Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.0),
child: Divider(),
));
},
); );
} }

View File

@@ -1,8 +1,10 @@
import 'package:briessenchecker/pages/dashboard_page.dart'; import 'package:briessenchecker/pages/dashboard_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart' as p;
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
import '../services/dbhelper.dart'; import '../services/dbhelper.dart';
import '../services/profile_provider.dart';
import 'login_page.dart'; import 'login_page.dart';
class LandingPage extends StatefulWidget { class LandingPage extends StatefulWidget {
@@ -27,8 +29,11 @@ class _LandingPageState extends State<LandingPage> {
return const LoginPage(); return const LoginPage();
} }
void _onAuthEvent(AuthState event) { void _onAuthEvent(AuthState event) async {
if (event.event == AuthChangeEvent.signedIn) { if (event.event == AuthChangeEvent.signedIn) {
await DbHelper.fetchProfiles().then((value) =>
p.Provider.of<ProfileProvider>(context, listen: false)
.updateProfiles(value));
setState(() => _isLoggedIn = true); setState(() => _isLoggedIn = true);
} else if (event.event == AuthChangeEvent.signedOut) { } else if (event.event == AuthChangeEvent.signedOut) {
setState(() => _isLoggedIn = false); setState(() => _isLoggedIn = false);

View File

@@ -9,6 +9,8 @@ import '../models/checklist.dart';
import '../models/listitem.dart'; import '../models/listitem.dart';
import 'package:provider/provider.dart' as provider; import 'package:provider/provider.dart' as provider;
import '../models/profile.dart';
class DbHelper { class DbHelper {
static const checkedItemsTableName = 'checkedItems'; static const checkedItemsTableName = 'checkedItems';
static const checklistsTableName = 'checklists'; static const checklistsTableName = 'checklists';
@@ -76,6 +78,22 @@ class DbHelper {
return itemIdList; return itemIdList;
} }
static Future<List<Profile>> fetchProfiles() async {
List<Profile> profiles = [];
final res = await _client
.from(profilesTableName)
.select<List<Map<String, dynamic>>>();
for (final element in res) {
profiles.add(Profile(
id: element['id'],
username: element['username'],
language: element['language'] ?? '',
bio: element['bio'] ?? '',
));
}
return profiles;
}
static Future<void> insertCheckedEntry(int checklistId, int itemId) async { static Future<void> insertCheckedEntry(int checklistId, int itemId) async {
final ownerId = _client.auth.currentSession!.user.id; final ownerId = _client.auth.currentSession!.user.id;
await _client.from(checkedItemsTableName).insert({ await _client.from(checkedItemsTableName).insert({

View File

@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
import '../models/profile.dart';
class ProfileProvider extends ChangeNotifier {
List<Profile> _profiles = [];
void updateProfiles(List<Profile> 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;
}
}

View File

@@ -1,4 +1,8 @@
import 'package:briessenchecker/services/dbhelper.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/profile_provider.dart';
typedef BoolCallback = void Function(bool isSelected); typedef BoolCallback = void Function(bool isSelected);
@@ -12,6 +16,7 @@ class ItemListTile extends StatefulWidget {
required this.selectionMode, required this.selectionMode,
required this.isChecked, required this.isChecked,
required this.onCheckedChanged, required this.onCheckedChanged,
this.ownerId = '',
}); });
final String title; final String title;
final String description; final String description;
@@ -20,6 +25,7 @@ class ItemListTile extends StatefulWidget {
final VoidCallback onTap; final VoidCallback onTap;
final BoolCallback onCheckedChanged; final BoolCallback onCheckedChanged;
final BoolCallback itemSelectionChanged; final BoolCallback itemSelectionChanged;
final String ownerId;
@override @override
State<ItemListTile> createState() => _ItemListTileState(); State<ItemListTile> createState() => _ItemListTileState();
@@ -28,10 +34,12 @@ class ItemListTile extends StatefulWidget {
class _ItemListTileState extends State<ItemListTile> { class _ItemListTileState extends State<ItemListTile> {
late bool isChecked; late bool isChecked;
bool isSelected = false; bool isSelected = false;
late ProfileProvider profileProvider;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
profileProvider = Provider.of<ProfileProvider>(context, listen: false);
isChecked = widget.isChecked; isChecked = widget.isChecked;
} }
@@ -39,7 +47,16 @@ class _ItemListTileState extends State<ItemListTile> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListTile( return ListTile(
title: Text(widget.title), 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, onTap: _onTap,
onLongPress: _onLongPress, onLongPress: _onLongPress,
selected: isSelected, selected: isSelected,