mirror of
https://github.com/Iconica-Development/flutter_profile.git
synced 2025-05-18 16:53:45 +02:00
second commit
This commit is contained in:
parent
e755137d37
commit
ce4054f478
6 changed files with 213 additions and 32 deletions
|
@ -16,13 +16,12 @@ class MyApp extends StatefulWidget {
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> {
|
||||||
late User _user;
|
late User _user;
|
||||||
MyProfileData profileData = const MyProfileData();
|
MyProfileData profileData = MyProfileData();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_user = User(
|
_user = User(
|
||||||
'displayName',
|
|
||||||
'firstName',
|
'firstName',
|
||||||
'lastName',
|
'lastName',
|
||||||
Uint8List.fromList(
|
Uint8List.fromList(
|
||||||
|
@ -39,30 +38,97 @@ class _MyAppState extends State<MyApp> {
|
||||||
primarySwatch: Colors.blue,
|
primarySwatch: Colors.blue,
|
||||||
),
|
),
|
||||||
home: ProfilePage(
|
home: ProfilePage(
|
||||||
|
service: MyProfileService(),
|
||||||
user: _user,
|
user: _user,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MyProfileService extends ProfileService {
|
||||||
|
@override
|
||||||
|
deleteProfile() {
|
||||||
|
return super.deleteProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
editProfile<T extends ProfileData>(
|
||||||
|
User<ProfileData> user, String key, String value) {
|
||||||
|
return super.editProfile(user, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
uploadImage() {
|
||||||
|
return super.uploadImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MyProfileData extends ProfileData {
|
class MyProfileData extends ProfileData {
|
||||||
const MyProfileData({
|
MyProfileData({
|
||||||
this.justMyNumber = '1',
|
this.justMyNumber = '1',
|
||||||
this.justMyString = 2,
|
this.justMyString = 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String justMyNumber;
|
final String justMyNumber;
|
||||||
final int justMyString;
|
int justMyString;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> mapWidget() {
|
Map<String, dynamic> mapWidget(Function update) {
|
||||||
return {
|
return {
|
||||||
'justMyNumber': Container(
|
'justMyString': Container(
|
||||||
height: 100,
|
height: 100,
|
||||||
width: 100,
|
width: 300,
|
||||||
color: Colors.red,
|
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
|
@override
|
||||||
ProfileData create() {
|
ProfileData create() {
|
||||||
return const MyProfileData();
|
return MyProfileData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
import 'package:profile/src/widgets/item_builder/item_builder_options.dart';
|
||||||
|
|
||||||
class User<T extends ProfileData> {
|
class User<T extends ProfileData> {
|
||||||
String? displayName;
|
|
||||||
String? firstName;
|
String? firstName;
|
||||||
String? lastName;
|
String? lastName;
|
||||||
Uint8List? image;
|
Uint8List? image;
|
||||||
T? profileData;
|
T? profileData;
|
||||||
|
|
||||||
User(
|
User(
|
||||||
this.displayName,
|
|
||||||
this.firstName,
|
this.firstName,
|
||||||
this.lastName,
|
this.lastName,
|
||||||
this.image,
|
this.image,
|
||||||
|
@ -22,7 +20,6 @@ class User<T extends ProfileData> {
|
||||||
|
|
||||||
factory User.fromMap(Map<String, dynamic> data) {
|
factory User.fromMap(Map<String, dynamic> data) {
|
||||||
return User(
|
return User(
|
||||||
data['displayName'],
|
|
||||||
data['firstName'],
|
data['firstName'],
|
||||||
data['lastName'],
|
data['lastName'],
|
||||||
data['image'],
|
data['image'],
|
||||||
|
@ -32,7 +29,6 @@ class User<T extends ProfileData> {
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {
|
return {
|
||||||
'displayName': displayName,
|
|
||||||
'firstName': firstName,
|
'firstName': firstName,
|
||||||
'lastName': lastName,
|
'lastName': lastName,
|
||||||
'image': image,
|
'image': image,
|
||||||
|
@ -48,13 +44,14 @@ abstract class ProfileData {
|
||||||
|
|
||||||
Map<String, dynamic> toMap();
|
Map<String, dynamic> toMap();
|
||||||
|
|
||||||
Map<String, dynamic> mapWidget();
|
Map<String, dynamic> mapWidget(Function update);
|
||||||
|
|
||||||
ProfileData create();
|
ProfileData create();
|
||||||
|
|
||||||
List<Widget> buildItems(
|
List<Widget> buildItems(
|
||||||
Map<String, dynamic> items,
|
Map<String, dynamic> items,
|
||||||
Map<String, dynamic> typeMap,
|
Map<String, dynamic> typeMap,
|
||||||
|
double spacing,
|
||||||
Function(String, String) updateProfile, {
|
Function(String, String) updateProfile, {
|
||||||
ItemBuilder? itemBuilder,
|
ItemBuilder? itemBuilder,
|
||||||
ItemBuilderOptions? itemBuilderOptions,
|
ItemBuilderOptions? itemBuilderOptions,
|
||||||
|
@ -83,6 +80,9 @@ abstract class ProfileData {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
widgets.add(SizedBox(
|
||||||
|
height: spacing,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
return widgets;
|
return widgets;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import 'package:profile/profile.dart';
|
import 'package:profile/profile.dart';
|
||||||
|
|
||||||
class ProfileService {
|
abstract class ProfileService {
|
||||||
const ProfileService();
|
const ProfileService();
|
||||||
|
|
||||||
deleteProfile() {}
|
deleteProfile() {
|
||||||
|
print("Request to delete profile");
|
||||||
|
// TODO(anyone) project specific
|
||||||
|
}
|
||||||
|
|
||||||
editProfile<T extends ProfileData>(User user, String key, String value) {
|
editProfile<T extends ProfileData>(User user, String key, String value) {
|
||||||
if (user.profileData != null) {
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,11 @@ class Avatar extends StatelessWidget {
|
||||||
this.image,
|
this.image,
|
||||||
this.name,
|
this.name,
|
||||||
this.avatar,
|
this.avatar,
|
||||||
this.displayName,
|
|
||||||
this.style = const AvatarStyle(),
|
this.style = const AvatarStyle(),
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final Uint8List? image;
|
final Uint8List? image;
|
||||||
final String? name;
|
final String? name;
|
||||||
final String? displayName;
|
|
||||||
final Widget? avatar;
|
final Widget? avatar;
|
||||||
final AvatarStyle style;
|
final AvatarStyle style;
|
||||||
|
|
||||||
|
@ -24,9 +22,9 @@ class Avatar extends StatelessWidget {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
_avatar(),
|
_avatar(),
|
||||||
if (displayName != null)
|
if (name != null)
|
||||||
Text(
|
Text(
|
||||||
displayName!,
|
name!,
|
||||||
style: style.displayNameStyle,
|
style: style.displayNameStyle,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -9,12 +9,13 @@ class ProfilePage extends StatefulWidget {
|
||||||
const ProfilePage({
|
const ProfilePage({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.user,
|
required this.user,
|
||||||
this.service = const ProfileService(),
|
required this.service,
|
||||||
this.style = const ProfileStyle(),
|
this.style = const ProfileStyle(),
|
||||||
this.customAvatar,
|
this.customAvatar,
|
||||||
this.showAvatar = true,
|
this.showAvatar = true,
|
||||||
this.itemBuilder,
|
this.itemBuilder,
|
||||||
this.itemBuilderOptions,
|
this.itemBuilderOptions,
|
||||||
|
this.showDeleteProfile = true,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final User user;
|
final User user;
|
||||||
|
@ -22,7 +23,9 @@ class ProfilePage extends StatefulWidget {
|
||||||
final ProfileStyle style;
|
final ProfileStyle style;
|
||||||
final Widget? customAvatar;
|
final Widget? customAvatar;
|
||||||
final bool showAvatar;
|
final bool showAvatar;
|
||||||
|
final bool showDeleteProfile;
|
||||||
final ItemBuilder? itemBuilder;
|
final ItemBuilder? itemBuilder;
|
||||||
|
|
||||||
final ItemBuilderOptions? itemBuilderOptions;
|
final ItemBuilderOptions? itemBuilderOptions;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -30,37 +33,140 @@ class ProfilePage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ProfilePageState extends State<ProfilePage> {
|
class _ProfilePageState extends State<ProfilePage> {
|
||||||
|
@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<ProfileWrapper> createState() => _ProfileWrapperState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ProfileWrapperState extends State<ProfileWrapper> {
|
||||||
late List<Widget> profileItems;
|
late List<Widget> profileItems;
|
||||||
|
List<Widget> defaultItems = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
profileItems = widget.user.profileData!.buildItems(
|
profileItems = widget.user.profileData!.buildItems(
|
||||||
widget.user.profileData!.toMap(),
|
widget.user.profileData!.toMap(),
|
||||||
widget.user.profileData!.mapWidget(),
|
widget.user.profileData!.mapWidget(() {
|
||||||
|
widget.rebuild();
|
||||||
|
}),
|
||||||
|
widget.style.betweenDefaultItemPadding,
|
||||||
(key, value) {
|
(key, value) {
|
||||||
const ProfileService().editProfile(widget.user, key, value);
|
widget.service.editProfile(widget.user, key, value);
|
||||||
},
|
},
|
||||||
itemBuilder: widget.itemBuilder,
|
itemBuilder: widget.itemBuilder,
|
||||||
itemBuilderOptions: widget.itemBuilderOptions,
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Material(
|
return Material(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
padding: widget.style.pagePadding,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
if (widget.showAvatar)
|
if (widget.showAvatar)
|
||||||
Avatar(
|
InkWell(
|
||||||
name: '${widget.user.firstName} ${widget.user.lastName}',
|
onTap: () {
|
||||||
style: widget.style.avatarStyle,
|
widget.service.uploadImage();
|
||||||
displayName: widget.user.displayName,
|
},
|
||||||
avatar: widget.customAvatar,
|
child: Avatar(
|
||||||
image: widget.user.image,
|
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,
|
...profileItems,
|
||||||
|
if (widget.showDeleteProfile)
|
||||||
|
SizedBox(
|
||||||
|
height: widget.style.betweenDefaultItemPadding,
|
||||||
|
),
|
||||||
|
if (widget.showDeleteProfile)
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
widget.service.deleteProfile();
|
||||||
|
},
|
||||||
|
child: const Text('Profiel verwijderen'),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:profile/src/widgets/avatar/avatar_style.dart';
|
import 'package:profile/src/widgets/avatar/avatar_style.dart';
|
||||||
|
|
||||||
class ProfileStyle {
|
class ProfileStyle {
|
||||||
const ProfileStyle({
|
const ProfileStyle({
|
||||||
this.avatarStyle = const AvatarStyle(),
|
this.avatarStyle = const AvatarStyle(),
|
||||||
|
this.betweenDefaultItemPadding = 10,
|
||||||
|
this.pagePadding = EdgeInsets.zero,
|
||||||
});
|
});
|
||||||
|
|
||||||
final AvatarStyle avatarStyle;
|
final AvatarStyle avatarStyle;
|
||||||
|
final EdgeInsetsGeometry pagePadding;
|
||||||
|
final double betweenDefaultItemPadding;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue