mirror of
https://github.com/Iconica-Development/flutter_timeline.git
synced 2025-05-19 10:33:44 +02:00
feat(post-creation): add post overview screen before posting
This commit is contained in:
parent
eca34a9502
commit
2225a2a2c2
13 changed files with 144 additions and 21 deletions
|
@ -1,7 +1,9 @@
|
||||||
## 2.0.1
|
## 2.1.0
|
||||||
|
|
||||||
- Fixed multiline textfield not being dismissible.
|
- Fixed multiline textfield not being dismissible.
|
||||||
- Fixed liking a new post you created.
|
- Fixed liking a new post you created.
|
||||||
|
- Added options to require image and enforce content length in post creation
|
||||||
|
- Added post overview screen before creating post
|
||||||
|
|
||||||
## 1.0.0 - November 27 2023
|
## 1.0.0 - November 27 2023
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,12 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
children: [
|
children: [
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
heroTag: 'btn1',
|
heroTag: 'btn1',
|
||||||
onPressed: () =>
|
onPressed: () => createPost(
|
||||||
createPost(context, timelineService, timelineOptions),
|
context,
|
||||||
|
timelineService,
|
||||||
|
timelineOptions,
|
||||||
|
getConfig(timelineService),
|
||||||
|
),
|
||||||
child: const Icon(
|
child: const Icon(
|
||||||
Icons.edit,
|
Icons.edit,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
|
|
@ -45,7 +45,12 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
heroTag: 'btn1',
|
heroTag: 'btn1',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
createPost(context, timelineService, timelineOptions);
|
createPost(
|
||||||
|
context,
|
||||||
|
timelineService,
|
||||||
|
timelineOptions,
|
||||||
|
getConfig(timelineService),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: const Icon(
|
child: const Icon(
|
||||||
Icons.edit,
|
Icons.edit,
|
||||||
|
|
|
@ -5,7 +5,8 @@ TimelineUserStoryConfiguration getConfig(TimelineService service) {
|
||||||
return TimelineUserStoryConfiguration(
|
return TimelineUserStoryConfiguration(
|
||||||
service: service,
|
service: service,
|
||||||
userId: 'test_user',
|
userId: 'test_user',
|
||||||
optionsBuilder: (context) => options);
|
optionsBuilder: (context) => options,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = TimelineOptions(
|
var options = TimelineOptions(
|
||||||
|
@ -33,9 +34,39 @@ var options = TimelineOptions(
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
void createPost(BuildContext context, TimelineService service,
|
void navigateToOverview(
|
||||||
TimelineOptions options) async {
|
BuildContext context,
|
||||||
await Navigator.push(
|
TimelineService service,
|
||||||
|
TimelineOptions options,
|
||||||
|
TimelinePost post,
|
||||||
|
) {
|
||||||
|
if (context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => TimelinePostOverviewScreen(
|
||||||
|
timelinePost: post,
|
||||||
|
options: options,
|
||||||
|
service: service,
|
||||||
|
onPostSubmit: (post) {
|
||||||
|
service.postService.createPost(post);
|
||||||
|
if (context.mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createPost(
|
||||||
|
BuildContext context,
|
||||||
|
TimelineService service,
|
||||||
|
TimelineOptions options,
|
||||||
|
TimelineUserStoryConfiguration configuration) async {
|
||||||
|
await Navigator.pushReplacement(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => Scaffold(
|
builder: (context) => Scaffold(
|
||||||
|
@ -47,6 +78,9 @@ void createPost(BuildContext context, TimelineService service,
|
||||||
onPostCreated: (post) {
|
onPostCreated: (post) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
|
onPostOverview: (post) {
|
||||||
|
navigateToOverview(context, service, options, post);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -55,6 +55,7 @@ class TimelineUserStoryConfiguration {
|
||||||
this.onPostDelete,
|
this.onPostDelete,
|
||||||
this.filterEnabled = false,
|
this.filterEnabled = false,
|
||||||
this.postWidgetBuilder,
|
this.postWidgetBuilder,
|
||||||
|
this.enablePostOverviewScreen = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The ID of the user associated with this user story configuration.
|
/// The ID of the user associated with this user story configuration.
|
||||||
|
@ -84,4 +85,7 @@ class TimelineUserStoryConfiguration {
|
||||||
|
|
||||||
/// A function that builds a widget for a timeline post.
|
/// A function that builds a widget for a timeline post.
|
||||||
final Widget Function(TimelinePost post)? postWidgetBuilder;
|
final Widget Function(TimelinePost post)? postWidgetBuilder;
|
||||||
|
|
||||||
|
/// Boolean to enable timeline post overview screen before submitting
|
||||||
|
final bool enablePostOverviewScreen;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
name: flutter_timeline
|
name: flutter_timeline
|
||||||
description: Visual elements and interface combined into one package
|
description: Visual elements and interface combined into one package
|
||||||
version: 2.0.0
|
version: 2.1.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
@ -19,13 +19,13 @@ dependencies:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_timeline
|
url: https://github.com/Iconica-Development/flutter_timeline
|
||||||
path: packages/flutter_timeline_view
|
path: packages/flutter_timeline_view
|
||||||
ref: 2.0.0
|
ref: 2.1.0
|
||||||
|
|
||||||
flutter_timeline_interface:
|
flutter_timeline_interface:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_timeline
|
url: https://github.com/Iconica-Development/flutter_timeline
|
||||||
path: packages/flutter_timeline_interface
|
path: packages/flutter_timeline_interface
|
||||||
ref: 2.0.0
|
ref: 2.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^2.0.0
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
name: flutter_timeline_firebase
|
name: flutter_timeline_firebase
|
||||||
description: Implementation of the Flutter Timeline interface for Firebase.
|
description: Implementation of the Flutter Timeline interface for Firebase.
|
||||||
version: 2.0.0
|
version: 2.1.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ dependencies:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_timeline
|
url: https://github.com/Iconica-Development/flutter_timeline
|
||||||
path: packages/flutter_timeline_interface
|
path: packages/flutter_timeline_interface
|
||||||
ref: 2.0.0
|
ref: 2.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^2.0.0
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
name: flutter_timeline_interface
|
name: flutter_timeline_interface
|
||||||
description: Interface for the service of the Flutter Timeline component
|
description: Interface for the service of the Flutter Timeline component
|
||||||
version: 2.0.0
|
version: 2.1.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ export 'src/config/timeline_styles.dart';
|
||||||
export 'src/config/timeline_theme.dart';
|
export 'src/config/timeline_theme.dart';
|
||||||
export 'src/config/timeline_translations.dart';
|
export 'src/config/timeline_translations.dart';
|
||||||
export 'src/screens/timeline_post_creation_screen.dart';
|
export 'src/screens/timeline_post_creation_screen.dart';
|
||||||
|
export 'src/screens/timeline_post_overview_screen.dart';
|
||||||
export 'src/screens/timeline_post_screen.dart';
|
export 'src/screens/timeline_post_screen.dart';
|
||||||
export 'src/screens/timeline_screen.dart';
|
export 'src/screens/timeline_screen.dart';
|
||||||
export 'src/screens/timeline_selection_screen.dart';
|
export 'src/screens/timeline_selection_screen.dart';
|
||||||
|
|
|
@ -29,6 +29,8 @@ class TimelineTranslations {
|
||||||
required this.postLoadingError,
|
required this.postLoadingError,
|
||||||
required this.timelineSelectionDescription,
|
required this.timelineSelectionDescription,
|
||||||
required this.searchHint,
|
required this.searchHint,
|
||||||
|
required this.postOverview,
|
||||||
|
required this.postIn,
|
||||||
});
|
});
|
||||||
|
|
||||||
const TimelineTranslations.empty()
|
const TimelineTranslations.empty()
|
||||||
|
@ -54,7 +56,9 @@ class TimelineTranslations {
|
||||||
postAt = 'at',
|
postAt = 'at',
|
||||||
postLoadingError = 'Something went wrong while loading the post',
|
postLoadingError = 'Something went wrong while loading the post',
|
||||||
timelineSelectionDescription = 'Choose a category',
|
timelineSelectionDescription = 'Choose a category',
|
||||||
searchHint = 'Search...';
|
searchHint = 'Search...',
|
||||||
|
postOverview = 'Post Overview',
|
||||||
|
postIn = 'Post in';
|
||||||
|
|
||||||
final String noPosts;
|
final String noPosts;
|
||||||
final String noPostsWithFilter;
|
final String noPostsWithFilter;
|
||||||
|
@ -83,6 +87,9 @@ class TimelineTranslations {
|
||||||
|
|
||||||
final String searchHint;
|
final String searchHint;
|
||||||
|
|
||||||
|
final String postOverview;
|
||||||
|
final String postIn;
|
||||||
|
|
||||||
TimelineTranslations copyWith({
|
TimelineTranslations copyWith({
|
||||||
String? noPosts,
|
String? noPosts,
|
||||||
String? noPostsWithFilter,
|
String? noPostsWithFilter,
|
||||||
|
@ -106,6 +113,8 @@ class TimelineTranslations {
|
||||||
String? postLoadingError,
|
String? postLoadingError,
|
||||||
String? timelineSelectionDescription,
|
String? timelineSelectionDescription,
|
||||||
String? searchHint,
|
String? searchHint,
|
||||||
|
String? postOverview,
|
||||||
|
String? postIn,
|
||||||
}) =>
|
}) =>
|
||||||
TimelineTranslations(
|
TimelineTranslations(
|
||||||
noPosts: noPosts ?? this.noPosts,
|
noPosts: noPosts ?? this.noPosts,
|
||||||
|
@ -133,5 +142,7 @@ class TimelineTranslations {
|
||||||
timelineSelectionDescription:
|
timelineSelectionDescription:
|
||||||
timelineSelectionDescription ?? this.timelineSelectionDescription,
|
timelineSelectionDescription ?? this.timelineSelectionDescription,
|
||||||
searchHint: searchHint ?? this.searchHint,
|
searchHint: searchHint ?? this.searchHint,
|
||||||
|
postOverview: postOverview ?? this.postOverview,
|
||||||
|
postIn: postIn ?? this.postIn,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:dotted_border/dotted_border.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_image_picker/flutter_image_picker.dart';
|
import 'package:flutter_image_picker/flutter_image_picker.dart';
|
||||||
import 'package:flutter_timeline_interface/flutter_timeline_interface.dart';
|
import 'package:flutter_timeline_interface/flutter_timeline_interface.dart';
|
||||||
|
import 'package:flutter_timeline_view/flutter_timeline_view.dart';
|
||||||
import 'package:flutter_timeline_view/src/config/timeline_options.dart';
|
import 'package:flutter_timeline_view/src/config/timeline_options.dart';
|
||||||
|
|
||||||
class TimelinePostCreationScreen extends StatefulWidget {
|
class TimelinePostCreationScreen extends StatefulWidget {
|
||||||
|
@ -17,6 +18,7 @@ class TimelinePostCreationScreen extends StatefulWidget {
|
||||||
required this.service,
|
required this.service,
|
||||||
required this.options,
|
required this.options,
|
||||||
this.postCategory,
|
this.postCategory,
|
||||||
|
this.onPostOverview,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -33,6 +35,9 @@ class TimelinePostCreationScreen extends StatefulWidget {
|
||||||
/// The options for the timeline
|
/// The options for the timeline
|
||||||
final TimelineOptions options;
|
final TimelineOptions options;
|
||||||
|
|
||||||
|
/// Nullable callback for routing to the post overview
|
||||||
|
final void Function(TimelinePost)? onPostOverview;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<TimelinePostCreationScreen> createState() =>
|
State<TimelinePostCreationScreen> createState() =>
|
||||||
_TimelinePostCreationScreenState();
|
_TimelinePostCreationScreenState();
|
||||||
|
@ -101,9 +106,14 @@ class _TimelinePostCreationScreenState
|
||||||
reactionEnabled: allowComments,
|
reactionEnabled: allowComments,
|
||||||
image: image,
|
image: image,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (widget.onPostOverview != null) {
|
||||||
|
widget.onPostOverview?.call(post);
|
||||||
|
} else {
|
||||||
var newPost = await widget.service.postService.createPost(post);
|
var newPost = await widget.service.postService.createPost(post);
|
||||||
widget.onPostCreated.call(newPost);
|
widget.onPostCreated.call(newPost);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
// ignore_for_file: prefer_expression_function_bodies
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_timeline_interface/flutter_timeline_interface.dart';
|
||||||
|
import 'package:flutter_timeline_view/flutter_timeline_view.dart';
|
||||||
|
|
||||||
|
class TimelinePostOverviewScreen extends StatelessWidget {
|
||||||
|
const TimelinePostOverviewScreen({
|
||||||
|
required this.timelinePost,
|
||||||
|
required this.options,
|
||||||
|
required this.service,
|
||||||
|
required this.onPostSubmit,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
final TimelinePost timelinePost;
|
||||||
|
final TimelineOptions options;
|
||||||
|
final TimelineService service;
|
||||||
|
final void Function(TimelinePost) onPostSubmit;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(options.translations.postOverview),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: TimelinePostScreen(
|
||||||
|
userId: timelinePost.creatorId,
|
||||||
|
options: options,
|
||||||
|
post: timelinePost,
|
||||||
|
onPostDelete: () {},
|
||||||
|
service: service,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 30.0),
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
onPostSubmit(timelinePost);
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'${options.translations.postIn} ${timelinePost.category}',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
name: flutter_timeline_view
|
name: flutter_timeline_view
|
||||||
description: Visual elements of the Flutter Timeline Component
|
description: Visual elements of the Flutter Timeline Component
|
||||||
version: 2.0.0
|
version: 2.1.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ dependencies:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_timeline
|
url: https://github.com/Iconica-Development/flutter_timeline
|
||||||
path: packages/flutter_timeline_interface
|
path: packages/flutter_timeline_interface
|
||||||
ref: 2.0.0
|
ref: 2.1.0
|
||||||
flutter_image_picker:
|
flutter_image_picker:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_image_picker
|
url: https://github.com/Iconica-Development/flutter_image_picker
|
||||||
|
|
Loading…
Reference in a new issue