From ce4054f478e529e8b22c6ecd6bb73c09c7134f87 Mon Sep 17 00:00:00 2001 From: Niels Gorter Date: Fri, 26 Aug 2022 16:28:40 +0200 Subject: [PATCH] second commit --- example/lib/main.dart | 86 ++++++++++++-- lib/src/models/user.dart | 10 +- lib/src/services/profile_service.dart | 12 +- lib/src/widgets/avatar/avatar.dart | 6 +- lib/src/widgets/profile/profile_page.dart | 126 +++++++++++++++++++-- lib/src/widgets/profile/profile_style.dart | 5 + 6 files changed, 213 insertions(+), 32 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index fc90fbf..7df78ab 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,13 +16,12 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { late User _user; - MyProfileData profileData = const MyProfileData(); + MyProfileData profileData = MyProfileData(); @override void initState() { super.initState(); _user = User( - 'displayName', 'firstName', 'lastName', Uint8List.fromList( @@ -39,30 +38,97 @@ class _MyAppState extends State { primarySwatch: Colors.blue, ), home: ProfilePage( + service: MyProfileService(), user: _user, ), ); } } +class MyProfileService extends ProfileService { + @override + deleteProfile() { + return super.deleteProfile(); + } + + @override + editProfile( + User user, String key, String value) { + return super.editProfile(user, key, value); + } + + @override + uploadImage() { + return super.uploadImage(); + } +} + class MyProfileData extends ProfileData { - const MyProfileData({ + MyProfileData({ this.justMyNumber = '1', this.justMyString = 2, }); final String justMyNumber; - final int justMyString; + int justMyString; @override - Map mapWidget() { + Map mapWidget(Function update) { return { - 'justMyNumber': Container( + 'justMyString': Container( height: 100, - width: 100, - color: Colors.red, + width: 300, + child: Row( + children: [ + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: justMyString == 1 ? Colors.green : Colors.blue, + ), + onPressed: () { + justMyString = 1; + update(); + print(justMyString); + }, + child: const Text('1'), + ), + const Spacer(), + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: justMyString == 2 ? Colors.green : Colors.blue, + ), + onPressed: () { + justMyString = 2; + update(); + print(justMyString); + }, + child: const Text('2'), + ), + const Spacer(), + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: justMyString == 3 ? Colors.green : Colors.blue, + ), + onPressed: () { + justMyString = 3; + update(); + }, + child: const Text('3'), + ), + const Spacer(), + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: justMyString == 4 ? Colors.green : Colors.blue, + ), + onPressed: () { + justMyString = 4; + update(); + }, + child: const Text('4'), + ), + ], + ), ), - 'justMyString': null, + 'justMyNumber': null, }; } @@ -86,6 +152,6 @@ class MyProfileData extends ProfileData { @override ProfileData create() { - return const MyProfileData(); + return MyProfileData(); } } diff --git a/lib/src/models/user.dart b/lib/src/models/user.dart index a6539e6..76dbc09 100644 --- a/lib/src/models/user.dart +++ b/lib/src/models/user.dart @@ -6,14 +6,12 @@ import 'package:profile/src/widgets/item_builder/item_builder.dart'; import 'package:profile/src/widgets/item_builder/item_builder_options.dart'; class User { - String? displayName; String? firstName; String? lastName; Uint8List? image; T? profileData; User( - this.displayName, this.firstName, this.lastName, this.image, @@ -22,7 +20,6 @@ class User { factory User.fromMap(Map data) { return User( - data['displayName'], data['firstName'], data['lastName'], data['image'], @@ -32,7 +29,6 @@ class User { Map toMap() { return { - 'displayName': displayName, 'firstName': firstName, 'lastName': lastName, 'image': image, @@ -48,13 +44,14 @@ abstract class ProfileData { Map toMap(); - Map mapWidget(); + Map mapWidget(Function update); ProfileData create(); List buildItems( Map items, Map typeMap, + double spacing, Function(String, String) updateProfile, { ItemBuilder? itemBuilder, ItemBuilderOptions? itemBuilderOptions, @@ -83,6 +80,9 @@ abstract class ProfileData { }, ), ); + widgets.add(SizedBox( + height: spacing, + )); } return widgets; } diff --git a/lib/src/services/profile_service.dart b/lib/src/services/profile_service.dart index a530162..a94a3e5 100644 --- a/lib/src/services/profile_service.dart +++ b/lib/src/services/profile_service.dart @@ -1,9 +1,12 @@ import 'package:profile/profile.dart'; -class ProfileService { +abstract class ProfileService { const ProfileService(); - deleteProfile() {} + deleteProfile() { + print("Request to delete profile"); + // TODO(anyone) project specific + } editProfile(User user, String key, String value) { if (user.profileData != null) { @@ -16,5 +19,8 @@ class ProfileService { } } - uploadImage() {} + uploadImage() { + print('Request to change picture'); + // TODO(anyone) open image picker and update profile + } } diff --git a/lib/src/widgets/avatar/avatar.dart b/lib/src/widgets/avatar/avatar.dart index 0e306c0..0fb6896 100644 --- a/lib/src/widgets/avatar/avatar.dart +++ b/lib/src/widgets/avatar/avatar.dart @@ -9,13 +9,11 @@ class Avatar extends StatelessWidget { this.image, this.name, this.avatar, - this.displayName, this.style = const AvatarStyle(), }) : super(key: key); final Uint8List? image; final String? name; - final String? displayName; final Widget? avatar; final AvatarStyle style; @@ -24,9 +22,9 @@ class Avatar extends StatelessWidget { return Column( children: [ _avatar(), - if (displayName != null) + if (name != null) Text( - displayName!, + name!, style: style.displayNameStyle, ) ], diff --git a/lib/src/widgets/profile/profile_page.dart b/lib/src/widgets/profile/profile_page.dart index 511dbbb..6c20331 100644 --- a/lib/src/widgets/profile/profile_page.dart +++ b/lib/src/widgets/profile/profile_page.dart @@ -9,12 +9,13 @@ class ProfilePage extends StatefulWidget { const ProfilePage({ Key? key, required this.user, - this.service = const ProfileService(), + required this.service, this.style = const ProfileStyle(), this.customAvatar, this.showAvatar = true, this.itemBuilder, this.itemBuilderOptions, + this.showDeleteProfile = true, }) : super(key: key); final User user; @@ -22,7 +23,9 @@ class ProfilePage extends StatefulWidget { final ProfileStyle style; final Widget? customAvatar; final bool showAvatar; + final bool showDeleteProfile; final ItemBuilder? itemBuilder; + final ItemBuilderOptions? itemBuilderOptions; @override @@ -30,37 +33,140 @@ class ProfilePage extends StatefulWidget { } class _ProfilePageState extends State { + @override + Widget build(BuildContext context) { + return ProfileWrapper( + service: widget.service, + user: widget.user, + rebuild: () { + setState(() {}); + }, + style: widget.style, + customAvatar: widget.customAvatar, + showAvatar: widget.showAvatar, + showDeleteProfile: widget.showDeleteProfile, + itemBuilder: widget.itemBuilder, + itemBuilderOptions: widget.itemBuilderOptions, + key: UniqueKey(), + ); + } +} + +class ProfileWrapper extends StatefulWidget { + const ProfileWrapper({ + Key? key, + required this.user, + required this.service, + required this.rebuild, + this.style = const ProfileStyle(), + this.customAvatar, + this.showAvatar = true, + this.itemBuilder, + this.itemBuilderOptions, + this.showDeleteProfile = true, + }) : super(key: key); + + final User user; + final ProfileService service; + final ProfileStyle style; + final Widget? customAvatar; + final bool showAvatar; + final bool showDeleteProfile; + final ItemBuilder? itemBuilder; + final Function rebuild; + final ItemBuilderOptions? itemBuilderOptions; + + @override + State createState() => _ProfileWrapperState(); +} + +class _ProfileWrapperState extends State { late List profileItems; + List defaultItems = []; + @override void initState() { super.initState(); profileItems = widget.user.profileData!.buildItems( widget.user.profileData!.toMap(), - widget.user.profileData!.mapWidget(), + widget.user.profileData!.mapWidget(() { + widget.rebuild(); + }), + widget.style.betweenDefaultItemPadding, (key, value) { - const ProfileService().editProfile(widget.user, key, value); + widget.service.editProfile(widget.user, key, value); }, itemBuilder: widget.itemBuilder, itemBuilderOptions: widget.itemBuilderOptions, ); + if (widget.itemBuilder == null) { + ItemBuilder builder = ItemBuilder( + options: widget.itemBuilderOptions ?? const ItemBuilderOptions(), + ); + defaultItems.add(builder.build(widget.user.firstName, null, (v) { + widget.user.firstName = v; + })); + defaultItems.add( + SizedBox( + height: widget.style.betweenDefaultItemPadding, + ), + ); + defaultItems.add(builder.build(widget.user.lastName, null, (v) { + widget.user.lastName = v; + })); + } else { + defaultItems + .add(widget.itemBuilder!.build(widget.user.firstName, null, (v) { + widget.user.firstName = v; + })); + defaultItems.add( + SizedBox( + height: widget.style.betweenDefaultItemPadding, + ), + ); + defaultItems + .add(widget.itemBuilder!.build(widget.user.lastName, null, (v) { + widget.user.lastName = v; + })); + } } @override Widget build(BuildContext context) { return Material( child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), + padding: widget.style.pagePadding, child: Column( children: [ if (widget.showAvatar) - Avatar( - name: '${widget.user.firstName} ${widget.user.lastName}', - style: widget.style.avatarStyle, - displayName: widget.user.displayName, - avatar: widget.customAvatar, - image: widget.user.image, + InkWell( + onTap: () { + widget.service.uploadImage(); + }, + child: Avatar( + name: '${widget.user.firstName} ${widget.user.lastName}', + style: widget.style.avatarStyle, + avatar: widget.customAvatar, + image: widget.user.image, + ), ), + if (widget.showAvatar) + SizedBox( + height: widget.style.betweenDefaultItemPadding, + ), + ...defaultItems, ...profileItems, + if (widget.showDeleteProfile) + SizedBox( + height: widget.style.betweenDefaultItemPadding, + ), + if (widget.showDeleteProfile) + InkWell( + onTap: () { + widget.service.deleteProfile(); + }, + child: const Text('Profiel verwijderen'), + ), ], ), ), diff --git a/lib/src/widgets/profile/profile_style.dart b/lib/src/widgets/profile/profile_style.dart index 675b753..cbdded8 100644 --- a/lib/src/widgets/profile/profile_style.dart +++ b/lib/src/widgets/profile/profile_style.dart @@ -1,9 +1,14 @@ +import 'package:flutter/material.dart'; import 'package:profile/src/widgets/avatar/avatar_style.dart'; class ProfileStyle { const ProfileStyle({ this.avatarStyle = const AvatarStyle(), + this.betweenDefaultItemPadding = 10, + this.pagePadding = EdgeInsets.zero, }); final AvatarStyle avatarStyle; + final EdgeInsetsGeometry pagePadding; + final double betweenDefaultItemPadding; }