feat: add a refreshindicator to the timeline with an extra callback onRefresh

This commit is contained in:
Freek van de Ven 2024-05-21 08:39:34 +02:00
parent 7fa33cdfb4
commit 035f795130
5 changed files with 80 additions and 60 deletions

View file

@ -7,6 +7,7 @@
- Set an optional max length on the default post title input field - Set an optional max length on the default post title input field
- Add a postCreationFloatingActionButtonColor to the timeline theme to set the color of the floating action button - Add a postCreationFloatingActionButtonColor to the timeline theme to set the color of the floating action button
- Add a post and a category to the postViewOpenPageBuilder function - Add a post and a category to the postViewOpenPageBuilder function
- Add a refresh functionality to the timeline with a pull to refresh callback to allow additional functionality when refreshing the timeline
## 3.0.1 ## 3.0.1

View file

@ -33,6 +33,7 @@ List<GoRoute> getTimelineStoryRoutes({
var timelineScreen = TimelineScreen( var timelineScreen = TimelineScreen(
userId: config.getUserId?.call(context) ?? config.userId, userId: config.getUserId?.call(context) ?? config.userId,
onUserTap: (user) => config.onUserTap?.call(context, user), onUserTap: (user) => config.onUserTap?.call(context, user),
onRefresh: config.onRefresh,
service: service, service: service,
options: config.optionsBuilder(context), options: config.optionsBuilder(context),
onPostTap: (post) async => onPostTap: (post) async =>

View file

@ -60,6 +60,7 @@ Widget _timelineScreenRoute({
), ),
), ),
), ),
onRefresh: config.onRefresh,
filterEnabled: config.filterEnabled, filterEnabled: config.filterEnabled,
postWidgetBuilder: config.postWidgetBuilder, postWidgetBuilder: config.postWidgetBuilder,
); );

View file

@ -57,6 +57,7 @@ class TimelineUserStoryConfiguration {
this.postOverviewOpenPageBuilder, this.postOverviewOpenPageBuilder,
this.onPostTap, this.onPostTap,
this.onUserTap, this.onUserTap,
this.onRefresh,
this.onPostDelete, this.onPostDelete,
this.filterEnabled = false, this.filterEnabled = false,
this.postWidgetBuilder, this.postWidgetBuilder,
@ -127,6 +128,9 @@ class TimelineUserStoryConfiguration {
/// A callback function invoked when the user's profile is tapped. /// A callback function invoked when the user's profile is tapped.
final Function(BuildContext context, String userId)? onUserTap; final Function(BuildContext context, String userId)? onUserTap;
/// A callback function invoked when the timeline is refreshed by pulling down
final Function(BuildContext context, String? category)? onRefresh;
/// A callback function invoked when a post deletion is requested. /// A callback function invoked when a post deletion is requested.
final Widget Function(BuildContext context, TimelinePost post)? onPostDelete; final Widget Function(BuildContext context, TimelinePost post)? onPostDelete;

View file

@ -16,6 +16,7 @@ class TimelineScreen extends StatefulWidget {
this.onPostTap, this.onPostTap,
this.scrollController, this.scrollController,
this.onUserTap, this.onUserTap,
this.onRefresh,
this.posts, this.posts,
this.timelineCategory, this.timelineCategory,
this.postWidgetBuilder, this.postWidgetBuilder,
@ -45,6 +46,9 @@ class TimelineScreen extends StatefulWidget {
/// Called when a post is tapped /// Called when a post is tapped
final Function(TimelinePost)? onPostTap; final Function(TimelinePost)? onPostTap;
/// Called when the timeline is refreshed by pulling down
final Function(BuildContext context, String? category)? onRefresh;
/// If this is not null, the user can tap on the user avatar or name /// If this is not null, the user can tap on the user avatar or name
final Function(String userId)? onUserTap; final Function(String userId)? onUserTap;
@ -218,13 +222,19 @@ class _TimelineScreenState extends State<TimelineScreen> {
height: 12, height: 12,
), ),
Expanded( Expanded(
child: RefreshIndicator(
onRefresh: () async {
await widget.onRefresh?.call(context, category);
await loadPosts();
},
child: SingleChildScrollView( child: SingleChildScrollView(
controller: controller, controller: controller,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
/// Add a optional custom header to the list of posts /// Add a optional custom header to the list of posts
widget.options.listHeaderBuilder?.call(context, category) ?? widget.options.listHeaderBuilder
?.call(context, category) ??
const SizedBox.shrink(), const SizedBox.shrink(),
...posts.map( ...posts.map(
(post) => Padding( (post) => Padding(
@ -252,7 +262,8 @@ class _TimelineScreenState extends State<TimelineScreen> {
options: widget.options, options: widget.options,
post: post, post: post,
onPostDelete: () { onPostDelete: () {
service.postService.deletePost(post); service.postService
.deletePost(post);
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
), ),
@ -279,7 +290,8 @@ class _TimelineScreenState extends State<TimelineScreen> {
? widget.options.translations.noPosts! ? widget.options.translations.noPosts!
: widget : widget
.options.translations.noPostsWithFilter!, .options.translations.noPostsWithFilter!,
style: widget.options.theme.textStyles.noPostsStyle, style:
widget.options.theme.textStyles.noPostsStyle,
), ),
), ),
), ),
@ -287,6 +299,7 @@ class _TimelineScreenState extends State<TimelineScreen> {
), ),
), ),
), ),
),
SizedBox( SizedBox(
height: widget.options.padding.bottom, height: widget.options.padding.bottom,
), ),