mirror of
https://github.com/Iconica-Development/flutter_timeline.git
synced 2025-05-18 18:13:46 +02:00
fix: timeline_screen
This commit is contained in:
parent
c99ecffa64
commit
38dd43ab39
10 changed files with 134 additions and 141 deletions
|
@ -45,13 +45,13 @@ List<GoRoute> getTimelineStoryRoutes({
|
|||
filterEnabled: config.filterEnabled,
|
||||
postWidgetBuilder: config.postWidgetBuilder,
|
||||
);
|
||||
|
||||
var theme = Theme.of(context);
|
||||
var button = FloatingActionButton(
|
||||
backgroundColor: config
|
||||
.optionsBuilder(context)
|
||||
.theme
|
||||
.postCreationFloatingActionButtonColor ??
|
||||
Theme.of(context).primaryColor,
|
||||
theme.colorScheme.primary,
|
||||
onPressed: () async => context.push(
|
||||
TimelineUserStoryRoutes.timelineCategorySelection,
|
||||
),
|
||||
|
@ -59,7 +59,7 @@ List<GoRoute> getTimelineStoryRoutes({
|
|||
child: const Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
size: 30,
|
||||
size: 24,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -70,17 +70,12 @@ List<GoRoute> getTimelineStoryRoutes({
|
|||
?.call(context, timelineScreen, button) ??
|
||||
Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: const Color(0xff212121),
|
||||
title: Text(
|
||||
config
|
||||
.optionsBuilder(context)
|
||||
.translations
|
||||
.timeLineScreenTitle,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
style: theme.textTheme.headlineLarge,
|
||||
),
|
||||
),
|
||||
body: timelineScreen,
|
||||
|
|
|
@ -65,13 +65,13 @@ Widget _timelineScreenRoute({
|
|||
filterEnabled: config.filterEnabled,
|
||||
postWidgetBuilder: config.postWidgetBuilder,
|
||||
);
|
||||
|
||||
var theme = Theme.of(context);
|
||||
var button = FloatingActionButton(
|
||||
backgroundColor: config
|
||||
.optionsBuilder(context)
|
||||
.theme
|
||||
.postCreationFloatingActionButtonColor ??
|
||||
Theme.of(context).primaryColor,
|
||||
theme.colorScheme.primary,
|
||||
onPressed: () async => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => _postCategorySelectionScreen(
|
||||
|
@ -84,21 +84,16 @@ Widget _timelineScreenRoute({
|
|||
child: const Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
size: 30,
|
||||
size: 24,
|
||||
),
|
||||
);
|
||||
|
||||
return config.homeOpenPageBuilder?.call(context, timelineScreen, button) ??
|
||||
Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: const Color(0xff212121),
|
||||
title: Text(
|
||||
config.optionsBuilder(context).translations.timeLineScreenTitle,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
style: theme.textTheme.headlineLarge,
|
||||
),
|
||||
),
|
||||
body: timelineScreen,
|
||||
|
|
|
@ -5,13 +5,13 @@ class TimelineCategory {
|
|||
const TimelineCategory({
|
||||
required this.key,
|
||||
required this.title,
|
||||
required this.icon,
|
||||
this.icon,
|
||||
this.canCreate = true,
|
||||
this.canView = true,
|
||||
});
|
||||
final String? key;
|
||||
final String title;
|
||||
final Widget icon;
|
||||
final Widget? icon;
|
||||
final bool canCreate;
|
||||
final bool canView;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class TimelineOptions {
|
|||
this.imagePickerTheme = const ImagePickerTheme(),
|
||||
this.timelinePostHeight,
|
||||
this.sortCommentsAscending = true,
|
||||
this.sortPostsAscending,
|
||||
this.sortPostsAscending = false,
|
||||
this.doubleTapTolike = false,
|
||||
this.iconsWithValues = false,
|
||||
this.likeAndDislikeIconsForDoubleTap = const (
|
||||
|
@ -38,7 +38,7 @@ class TimelineOptions {
|
|||
this.userAvatarBuilder,
|
||||
this.anonymousAvatarBuilder,
|
||||
this.nameBuilder,
|
||||
this.iconSize = 26,
|
||||
this.iconSize = 24,
|
||||
this.postWidgetHeight,
|
||||
this.filterOptions = const FilterOptions(),
|
||||
this.categoriesOptions = const CategoriesOptions(),
|
||||
|
@ -178,35 +178,14 @@ List<TimelineCategory> _getDefaultCategories(context) => [
|
|||
const TimelineCategory(
|
||||
key: null,
|
||||
title: 'All',
|
||||
icon: Padding(
|
||||
padding: EdgeInsets.only(right: 8.0),
|
||||
child: Icon(
|
||||
Icons.apps,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
const TimelineCategory(
|
||||
key: 'Category',
|
||||
title: 'Category',
|
||||
icon: Padding(
|
||||
padding: EdgeInsets.only(right: 8.0),
|
||||
child: Icon(
|
||||
Icons.category,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
const TimelineCategory(
|
||||
key: 'Category with two lines',
|
||||
title: 'Category with two lines',
|
||||
icon: Padding(
|
||||
padding: EdgeInsets.only(right: 8.0),
|
||||
child: Icon(
|
||||
Icons.category,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class TimelinePaddingOptions {
|
|||
this.mainPadding =
|
||||
const EdgeInsets.only(left: 12.0, top: 24.0, right: 12.0, bottom: 12.0),
|
||||
this.postPadding =
|
||||
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 12.0),
|
||||
const EdgeInsets.only(left: 12.0, top: 6, right: 12.0, bottom: 8),
|
||||
this.postOverviewButtonBottomPadding = 30.0,
|
||||
this.categoryButtonTextPadding,
|
||||
});
|
||||
|
|
|
@ -76,7 +76,7 @@ class TimelineTranslations {
|
|||
this.deleteCancelButton = 'Cancel',
|
||||
this.deleteReaction = 'Delete Reaction',
|
||||
this.viewPost = 'View post',
|
||||
this.likesTitle = 'Likes',
|
||||
this.likesTitle = 'likes',
|
||||
this.commentsTitle = 'Are people allowed to comment?',
|
||||
this.firstComment = 'Be the first to comment',
|
||||
this.writeComment = 'Write your comment here...',
|
||||
|
|
|
@ -32,37 +32,40 @@ class _CategorySelectorState extends State<CategorySelector> {
|
|||
widget.options.categoriesOptions.categoriesBuilder!(context);
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: widget.options.categoriesOptions
|
||||
.categorySelectorHorizontalPadding ??
|
||||
max(widget.options.paddings.mainPadding.left - 20, 0),
|
||||
),
|
||||
for (var category in categories) ...[
|
||||
widget.options.categoriesOptions.categoryButtonBuilder?.call(
|
||||
category,
|
||||
() => widget.onTapCategory(category.key),
|
||||
widget.filter == category.key,
|
||||
widget.isOnTop,
|
||||
) ??
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: CategorySelectorButton(
|
||||
isOnTop: widget.isOnTop,
|
||||
category: category,
|
||||
selected: widget.filter == category.key,
|
||||
onTap: () => widget.onTapCategory(category.key),
|
||||
options: widget.options,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: widget.options.categoriesOptions
|
||||
.categorySelectorHorizontalPadding ??
|
||||
max(widget.options.paddings.mainPadding.left - 20, 0),
|
||||
),
|
||||
for (var category in categories) ...[
|
||||
widget.options.categoriesOptions.categoryButtonBuilder?.call(
|
||||
category,
|
||||
() => widget.onTapCategory(category.key),
|
||||
widget.filter == category.key,
|
||||
widget.isOnTop,
|
||||
) ??
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: CategorySelectorButton(
|
||||
isOnTop: widget.isOnTop,
|
||||
category: category,
|
||||
selected: widget.filter == category.key,
|
||||
onTap: () => widget.onTapCategory(category.key),
|
||||
options: widget.options,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
SizedBox(
|
||||
width: widget.options.categoriesOptions
|
||||
.categorySelectorHorizontalPadding ??
|
||||
max(widget.options.paddings.mainPadding.right - 4, 0),
|
||||
),
|
||||
],
|
||||
SizedBox(
|
||||
width: widget.options.categoriesOptions
|
||||
.categorySelectorHorizontalPadding ??
|
||||
max(widget.options.paddings.mainPadding.right - 4, 0),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ class CategorySelectorButton extends StatelessWidget {
|
|||
var theme = Theme.of(context);
|
||||
var size = MediaQuery.of(context).size;
|
||||
|
||||
return SizedBox(
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 100),
|
||||
height: isOnTop ? 140 : 40,
|
||||
child: TextButton(
|
||||
onPressed: onTap,
|
||||
|
@ -81,11 +82,13 @@ class CategorySelectorButton extends StatelessWidget {
|
|||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
category.icon,
|
||||
SizedBox(
|
||||
width:
|
||||
options.paddings.categoryButtonTextPadding ?? 8,
|
||||
),
|
||||
if (category.icon != null) ...[
|
||||
category.icon!,
|
||||
SizedBox(
|
||||
width:
|
||||
options.paddings.categoryButtonTextPadding ?? 8,
|
||||
),
|
||||
],
|
||||
Expanded(
|
||||
child: _CategoryButtonText(
|
||||
category: category,
|
||||
|
@ -124,7 +127,9 @@ class _CategoryButtonText extends StatelessWidget {
|
|||
Widget build(BuildContext context) => Text(
|
||||
category.title,
|
||||
style: (options.theme.textStyles.categoryTitleStyle ??
|
||||
theme.textTheme.labelLarge)
|
||||
(selected
|
||||
? theme.textTheme.titleMedium
|
||||
: theme.textTheme.bodyMedium))
|
||||
?.copyWith(
|
||||
color: selected
|
||||
? options.theme.categorySelectionButtonSelectedTextColor ??
|
||||
|
|
|
@ -52,6 +52,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var theme = Theme.of(context);
|
||||
var isLikedByUser = widget.post.likedBy?.contains(widget.userId) ?? false;
|
||||
return InkWell(
|
||||
onTap: widget.onTap,
|
||||
child: SizedBox(
|
||||
|
@ -103,7 +104,9 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
widget.options.translations.anonymousUser,
|
||||
style: widget.options.theme.textStyles
|
||||
.postCreatorTitleStyle ??
|
||||
theme.textTheme.titleMedium,
|
||||
theme.textTheme.titleSmall!.copyWith(
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -204,17 +207,16 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
height: 8,
|
||||
),
|
||||
// post information
|
||||
if (widget.options.iconsWithValues)
|
||||
if (widget.options.iconsWithValues) ...[
|
||||
Row(
|
||||
children: [
|
||||
TextButton.icon(
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () async {
|
||||
var userId = widget.userId;
|
||||
|
||||
var liked =
|
||||
widget.post.likedBy?.contains(userId) ?? false;
|
||||
|
||||
if (!liked) {
|
||||
if (!isLikedByUser) {
|
||||
await widget.service.postService.likePost(
|
||||
userId,
|
||||
widget.post,
|
||||
|
@ -228,61 +230,67 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
},
|
||||
icon: widget.options.theme.likeIcon ??
|
||||
Icon(
|
||||
widget.post.likedBy?.contains(widget.userId) ?? false
|
||||
isLikedByUser
|
||||
? Icons.favorite_rounded
|
||||
: Icons.favorite_outline_outlined,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
),
|
||||
label: Text('${widget.post.likes}'),
|
||||
),
|
||||
if (widget.post.reactionEnabled)
|
||||
TextButton.icon(
|
||||
const SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Text('${widget.post.likes}'),
|
||||
if (widget.post.reactionEnabled) ...[
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: widget.onTap,
|
||||
icon: widget.options.theme.commentIcon ??
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.chat_bubble_outline_outlined,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
),
|
||||
label: Text('${widget.post.reaction}'),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Text('${widget.post.reaction}'),
|
||||
],
|
||||
],
|
||||
)
|
||||
else
|
||||
),
|
||||
] else ...[
|
||||
Row(
|
||||
children: [
|
||||
if (widget.post.likedBy?.contains(widget.userId) ??
|
||||
false) ...[
|
||||
InkWell(
|
||||
onTap: widget.onTapUnlike,
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.likedIcon ??
|
||||
Icon(
|
||||
Icons.favorite_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
InkWell(
|
||||
onTap: widget.onTapLike,
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.likeIcon ??
|
||||
Icon(
|
||||
Icons.favorite_outline,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed:
|
||||
isLikedByUser ? widget.onTapUnlike : widget.onTapLike,
|
||||
icon: (isLikedByUser
|
||||
? widget.options.theme.likedIcon
|
||||
: widget.options.theme.likeIcon) ??
|
||||
Icon(
|
||||
isLikedByUser
|
||||
? Icons.favorite_rounded
|
||||
: Icons.favorite_outline,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (widget.post.reactionEnabled) ...[
|
||||
Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.commentIcon ??
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: widget.onTap,
|
||||
icon: widget.options.theme.commentIcon ??
|
||||
Icon(
|
||||
Icons.chat_bubble_outline_rounded,
|
||||
Icons.chat_bubble_outline_outlined,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
),
|
||||
|
@ -290,6 +298,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
|
@ -305,23 +314,25 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
'${widget.options.translations.likesTitle}',
|
||||
style: widget
|
||||
.options.theme.textStyles.listPostLikeTitleAndAmount ??
|
||||
theme.textTheme.titleSmall,
|
||||
theme.textTheme.titleSmall!.copyWith(
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: widget.options.nameBuilder?.call(widget.post.creator) ??
|
||||
widget.post.creator?.fullName ??
|
||||
widget.options.translations.anonymousUser,
|
||||
style: widget.options.theme.textStyles.listCreatorNameStyle ??
|
||||
theme.textTheme.titleSmall,
|
||||
theme.textTheme.titleSmall!.copyWith(
|
||||
color: Colors.black,
|
||||
),
|
||||
children: [
|
||||
const TextSpan(text: ' '),
|
||||
TextSpan(
|
||||
text: widget.post.title,
|
||||
style:
|
||||
widget.options.theme.textStyles.listPostTitleStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
theme.textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -330,7 +341,9 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
Text(
|
||||
widget.options.translations.viewPost,
|
||||
style: widget.options.theme.textStyles.viewPostStyle ??
|
||||
theme.textTheme.bodySmall,
|
||||
theme.textTheme.titleSmall!.copyWith(
|
||||
color: const Color(0xFF8D8D8D),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (widget.options.dividerBuilder != null)
|
||||
|
|
|
@ -9,7 +9,7 @@ version: 4.1.0
|
|||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: '>=3.1.3 <4.0.0'
|
||||
sdk: ">=3.1.3 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
@ -18,18 +18,22 @@ dependencies:
|
|||
cached_network_image: ^3.2.2
|
||||
dotted_border: ^2.1.0
|
||||
flutter_html: ^3.0.0-beta.2
|
||||
|
||||
|
||||
flutter_timeline_interface:
|
||||
git:
|
||||
url: https://github.com/Iconica-Development/flutter_timeline
|
||||
path: packages/flutter_timeline_interface
|
||||
ref: 4.1.0
|
||||
git:
|
||||
url: https://github.com/Iconica-Development/flutter_timeline
|
||||
path: packages/flutter_timeline_interface
|
||||
ref: 4.1.0
|
||||
flutter_image_picker:
|
||||
git:
|
||||
url: https://github.com/Iconica-Development/flutter_image_picker
|
||||
ref: 1.0.5
|
||||
collection: any
|
||||
|
||||
dependency_overrides:
|
||||
flutter_timeline_interface:
|
||||
path: packages/flutter_timeline_interface
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.0
|
||||
flutter_iconica_analysis:
|
||||
|
@ -38,4 +42,3 @@ dev_dependencies:
|
|||
ref: 6.0.0
|
||||
|
||||
flutter:
|
||||
|
||||
|
|
Loading…
Reference in a new issue