feat:add namebuilder

This commit is contained in:
Tim 2023-12-14 11:37:03 +01:00
parent 03b14924a2
commit d60244fa3e
5 changed files with 180 additions and 108 deletions

View file

@ -26,6 +26,7 @@ class TimelinePost {
this.reactions,
this.imageUrl,
this.image,
this.data = const {},
});
factory TimelinePost.fromJson(String id, Map<String, dynamic> json) =>
@ -50,6 +51,7 @@ class TimelinePost {
.toList(),
createdAt: DateTime.parse(json['created_at'] as String),
reactionEnabled: json['reaction_enabled'] as bool,
data: json['data'] ?? {},
);
/// The unique identifier of the post.
@ -94,6 +96,9 @@ class TimelinePost {
/// If reacting is enabled on the post.
final bool reactionEnabled;
/// Option to add extra data to a timelinepost that won't be shown anywhere
final Map<String, dynamic> data;
TimelinePost copyWith({
String? id,
String? creatorId,
@ -109,6 +114,7 @@ class TimelinePost {
List<TimelinePostReaction>? reactions,
DateTime? createdAt,
bool? reactionEnabled,
Map<String, dynamic>? data,
}) =>
TimelinePost(
id: id ?? this.id,
@ -125,6 +131,7 @@ class TimelinePost {
reactions: reactions ?? this.reactions,
createdAt: createdAt ?? this.createdAt,
reactionEnabled: reactionEnabled ?? this.reactionEnabled,
data: data ?? this.data,
);
Map<String, dynamic> toJson() => {
@ -140,5 +147,6 @@ class TimelinePost {
'reactions': reactions?.map((e) => e.toJson()).toList() ?? [],
'created_at': createdAt.toIso8601String(),
'reaction_enabled': reactionEnabled,
'data': data,
};
}

View file

@ -24,6 +24,8 @@ class TimelineOptions {
this.buttonBuilder,
this.textInputBuilder,
this.userAvatarBuilder,
this.anonymousAvatarBuilder,
this.nameBuilder,
});
/// Theming options for the timeline
@ -56,6 +58,12 @@ class TimelineOptions {
final UserAvatarBuilder? userAvatarBuilder;
/// When the imageUrl is null this anonymousAvatarBuilder will be used
/// You can use it to display a default avatarW
final UserAvatarBuilder? anonymousAvatarBuilder;
final String Function(TimelinePosterUserModel?)? nameBuilder;
/// ImagePickerTheme can be used to change the UI of the
/// Image Picker Widget to change the text/icons to your liking.
final ImagePickerTheme imagePickerTheme;
@ -78,7 +86,7 @@ typedef TextInputBuilder = Widget Function(
String hintText,
);
typedef UserAvatarBuilder = Widget Function(
typedef UserAvatarBuilder = Widget? Function(
TimelinePosterUserModel user,
double size,
);

View file

@ -123,6 +123,7 @@ class _TimelinePostCreationScreenState
height: 100,
child: TextField(
controller: contentController,
textCapitalization: TextCapitalization.sentences,
expands: true,
maxLines: null,
minLines: null,

View file

@ -153,17 +153,29 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
post.creator!.imageUrl!,
),
),
] else ...[
widget.options.anonymousAvatarBuilder?.call(
post.creator!,
40,
) ??
const CircleAvatar(
radius: 20,
child: Icon(
Icons.person,
),
),
],
const SizedBox(width: 10),
if (post.creator!.fullName != null) ...[
Text(
post.creator!.fullName!,
widget.options.nameBuilder
?.call(post.creator) ??
post.creator?.fullName ??
widget.options.translations.anonymousUser,
style: widget.options.theme.textStyles
.postCreatorTitleStyle ??
theme.textTheme.titleMedium,
),
],
],
),
),
const Spacer(),
@ -206,19 +218,23 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
),
],
),
const SizedBox(height: 8),
// image of the post
if (post.imageUrl != null) ...[
CachedNetworkImage(
imageUrl: post.imageUrl!,
const SizedBox(height: 8),
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: CachedNetworkImage(
width: double.infinity,
imageUrl: post.imageUrl!,
fit: BoxFit.fitHeight,
),
),
],
const SizedBox(
height: 8,
),
// post information
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
Row(
children: [
if (post.likedBy?.contains(widget.userId) ?? false) ...[
InkWell(
@ -262,7 +278,7 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
),
],
),
),
const SizedBox(height: 8),
Text(
'${post.likes} ${widget.options.translations.likesTitle}',
style: widget
@ -272,7 +288,8 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
const SizedBox(height: 4),
Text.rich(
TextSpan(
text: post.creator?.fullName ??
text: widget.options.nameBuilder?.call(post.creator) ??
post.creator?.fullName ??
widget.options.translations.anonymousUser,
style: widget
.options.theme.textStyles.postCreatorNameStyle ??
@ -287,9 +304,8 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
),
],
),
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
const SizedBox(height: 20),
Html(
data: post.content,
style: {
@ -300,15 +316,20 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
'#': Style(
maxLines: 3,
textOverflow: TextOverflow.ellipsis,
padding: HtmlPaddings.zero,
margin: Margins.zero,
),
'H1': Style(
margin: Margins.all(0),
padding: HtmlPaddings.zero,
margin: Margins.zero,
),
'H2': Style(
margin: Margins.all(0),
padding: HtmlPaddings.zero,
margin: Margins.zero,
),
'H3': Style(
margin: Margins.all(0),
padding: HtmlPaddings.zero,
margin: Margins.zero,
),
},
),
@ -319,7 +340,7 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
'${timeFormat.format(post.createdAt)}',
style: theme.textTheme.bodySmall,
),
const SizedBox(height: 12),
const SizedBox(height: 20),
if (post.reactionEnabled) ...[
Text(
widget.options.translations.commentsTitle,
@ -381,6 +402,17 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
reaction.creator!.imageUrl!,
),
),
] else ...[
widget.options.anonymousAvatarBuilder?.call(
reaction.creator!,
25,
) ??
const CircleAvatar(
radius: 20,
child: Icon(
Icons.person,
),
),
],
const SizedBox(width: 10),
if (reaction.imageUrl != null) ...[
@ -389,6 +421,8 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.options.nameBuilder
?.call(post.creator) ??
reaction.creator?.fullName ??
widget.options.translations
.anonymousUser,
@ -408,7 +442,9 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
Expanded(
child: Text.rich(
TextSpan(
text: reaction.creator?.fullName ??
text: widget.options.nameBuilder
?.call(post.creator) ??
reaction.creator?.fullName ??
widget
.options.translations.anonymousUser,
style: theme.textTheme.titleSmall,

View file

@ -68,16 +68,27 @@ class TimelinePostWidget extends StatelessWidget {
post.creator!.imageUrl!,
),
),
],
const SizedBox(width: 10),
if (post.creator!.fullName != null) ...[
Text(
post.creator!.fullName!,
style: options.theme.textStyles
.listPostCreatorTitleStyle ??
theme.textTheme.titleMedium,
] else ...[
options.anonymousAvatarBuilder?.call(
post.creator!,
40,
) ??
const CircleAvatar(
radius: 20,
child: Icon(
Icons.person,
),
),
],
const SizedBox(width: 10),
Text(
options.nameBuilder?.call(post.creator) ??
post.creator?.fullName ??
options.translations.anonymousUser,
style:
options.theme.textStyles.postCreatorTitleStyle ??
theme.textTheme.titleMedium,
),
],
),
),
@ -118,22 +129,26 @@ class TimelinePostWidget extends StatelessWidget {
),
],
),
const SizedBox(height: 8),
// image of the post
if (post.imageUrl != null) ...[
const SizedBox(height: 8),
Flexible(
flex: height != null ? 1 : 0,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: CachedNetworkImage(
imageUrl: post.imageUrl!,
width: double.infinity,
imageUrl: post.imageUrl!,
fit: BoxFit.fitWidth,
),
),
),
],
const SizedBox(
height: 8,
),
// post information
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
Row(
children: [
if (post.likedBy?.contains(userId) ?? false) ...[
InkWell(
@ -163,7 +178,10 @@ class TimelinePostWidget extends StatelessWidget {
),
],
),
const SizedBox(
height: 8,
),
Text(
'${post.likes} ${options.translations.likesTitle}',
style: options.theme.textStyles.listPostLikeTitleAndAmount ??
@ -172,7 +190,8 @@ class TimelinePostWidget extends StatelessWidget {
const SizedBox(height: 4),
Text.rich(
TextSpan(
text: post.creator?.fullName ??
text: options.nameBuilder?.call(post.creator) ??
post.creator?.fullName ??
options.translations.anonymousUser,
style: options.theme.textStyles.listCreatorNameStyle ??
theme.textTheme.titleSmall,
@ -185,8 +204,8 @@ class TimelinePostWidget extends StatelessWidget {
),
],
),
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
Text(
options.translations.viewPost,
style: options.theme.textStyles.viewPostStyle ??