From ab0f96121e2c6cc4606482eefc184f780c3b640c Mon Sep 17 00:00:00 2001 From: Freek van de Ven Date: Wed, 22 May 2024 11:43:55 +0200 Subject: [PATCH] feat: make all translations required for TimelineTranslations and provide an .empty() alternative --- CHANGELOG.md | 1 + .../flutter_timeline_gorouter_userstory.dart | 8 +- .../flutter_timeline_navigator_userstory.dart | 8 +- .../lib/src/config/timeline_options.dart | 2 +- .../lib/src/config/timeline_translations.dart | 105 ++++++++++++------ .../timeline_post_creation_screen.dart | 24 ++-- .../lib/src/screens/timeline_post_screen.dart | 14 +-- .../lib/src/screens/timeline_screen.dart | 4 +- .../screens/timeline_selection_screen.dart | 2 +- .../lib/src/widgets/reaction_bottom.dart | 2 +- .../lib/src/widgets/timeline_post_widget.dart | 6 +- 11 files changed, 110 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac0409e..8494fed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Add a refresh functionality to the timeline with a pull to refresh callback to allow additional functionality when refreshing the timeline - Use the adaptive variants of the material elements in the timeline - Change the default blue color to the primary color of the Theme.of(context) in the timeline +- Change the TimelineTranslations constructor to require all translations or use the TimelineTranslations.empty constructor if you don't want to specify all translations ## 3.0.1 diff --git a/packages/flutter_timeline/lib/src/flutter_timeline_gorouter_userstory.dart b/packages/flutter_timeline/lib/src/flutter_timeline_gorouter_userstory.dart index d3247ce..8026163 100644 --- a/packages/flutter_timeline/lib/src/flutter_timeline_gorouter_userstory.dart +++ b/packages/flutter_timeline/lib/src/flutter_timeline_gorouter_userstory.dart @@ -74,7 +74,7 @@ List getTimelineStoryRoutes({ config .optionsBuilder(context) .translations - .timeLineScreenTitle!, + .timeLineScreenTitle, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, @@ -120,7 +120,7 @@ List getTimelineStoryRoutes({ leading: backButton, backgroundColor: const Color(0xff212121), title: Text( - config.optionsBuilder(context).translations.postCreation!, + config.optionsBuilder(context).translations.postCreation, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, @@ -236,7 +236,7 @@ List getTimelineStoryRoutes({ backgroundColor: const Color(0xff212121), leading: backButton, title: Text( - config.optionsBuilder(context).translations.postCreation!, + config.optionsBuilder(context).translations.postCreation, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, @@ -284,7 +284,7 @@ List getTimelineStoryRoutes({ leading: backButton, backgroundColor: const Color(0xff212121), title: Text( - config.optionsBuilder(context).translations.postOverview!, + config.optionsBuilder(context).translations.postOverview, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, diff --git a/packages/flutter_timeline/lib/src/flutter_timeline_navigator_userstory.dart b/packages/flutter_timeline/lib/src/flutter_timeline_navigator_userstory.dart index 93f2348..48288e6 100644 --- a/packages/flutter_timeline/lib/src/flutter_timeline_navigator_userstory.dart +++ b/packages/flutter_timeline/lib/src/flutter_timeline_navigator_userstory.dart @@ -92,7 +92,7 @@ Widget _timelineScreenRoute({ appBar: AppBar( backgroundColor: const Color(0xff212121), title: Text( - config.optionsBuilder(context).translations.timeLineScreenTitle!, + config.optionsBuilder(context).translations.timeLineScreenTitle, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, @@ -246,7 +246,7 @@ Widget _postCreationScreenRoute({ backgroundColor: const Color(0xff212121), leading: backButton, title: Text( - config.optionsBuilder(context).translations.postCreation!, + config.optionsBuilder(context).translations.postCreation, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, @@ -313,7 +313,7 @@ Widget _postOverviewScreenRoute({ leading: backButton, backgroundColor: const Color(0xff212121), title: Text( - config.optionsBuilder(context).translations.postOverview!, + config.optionsBuilder(context).translations.postOverview, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, @@ -372,7 +372,7 @@ Widget _postCategorySelectionScreen({ leading: backButton, backgroundColor: const Color(0xff212121), title: Text( - config.optionsBuilder(context).translations.postCreation!, + config.optionsBuilder(context).translations.postCreation, style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 24, diff --git a/packages/flutter_timeline_view/lib/src/config/timeline_options.dart b/packages/flutter_timeline_view/lib/src/config/timeline_options.dart index b3c04d4..dc20e32 100644 --- a/packages/flutter_timeline_view/lib/src/config/timeline_options.dart +++ b/packages/flutter_timeline_view/lib/src/config/timeline_options.dart @@ -12,7 +12,7 @@ import 'package:intl/intl.dart'; class TimelineOptions { const TimelineOptions({ this.theme = const TimelineTheme(), - this.translations = const TimelineTranslations(), + this.translations = const TimelineTranslations.empty(), this.imagePickerConfig = const ImagePickerConfig(), this.imagePickerTheme = const ImagePickerTheme(), this.timelinePostHeight, diff --git a/packages/flutter_timeline_view/lib/src/config/timeline_translations.dart b/packages/flutter_timeline_view/lib/src/config/timeline_translations.dart index 61f2d27..dca146d 100644 --- a/packages/flutter_timeline_view/lib/src/config/timeline_translations.dart +++ b/packages/flutter_timeline_view/lib/src/config/timeline_translations.dart @@ -5,8 +5,50 @@ import 'package:flutter/material.dart'; @immutable + +/// Class that holds all the translations for the timeline component view and +/// the corresponding userstory class TimelineTranslations { + /// TimelineTranslations constructor where everything is required use this + /// if you want to be sure to have all translations specified + /// If you just want the default values use the empty constructor + /// and optionally override the values with the copyWith method const TimelineTranslations({ + required this.anonymousUser, + required this.noPosts, + required this.noPostsWithFilter, + required this.title, + required this.titleHintText, + required this.content, + required this.contentHintText, + required this.contentDescription, + required this.uploadImage, + required this.uploadImageDescription, + required this.allowComments, + required this.allowCommentsDescription, + required this.commentsTitleOnPost, + required this.checkPost, + required this.postAt, + required this.deletePost, + required this.deleteReaction, + required this.viewPost, + required this.likesTitle, + required this.commentsTitle, + required this.firstComment, + required this.writeComment, + required this.postLoadingError, + required this.timelineSelectionDescription, + required this.searchHint, + required this.postOverview, + required this.postIn, + required this.postCreation, + required this.yes, + required this.no, + required this.timeLineScreenTitle, + }); + + /// Default translations for the timeline component view + const TimelineTranslations.empty({ this.anonymousUser = 'Anonymous user', this.noPosts = 'No posts yet', this.noPostsWithFilter = 'No posts with this filter', @@ -41,45 +83,46 @@ class TimelineTranslations { this.timeLineScreenTitle = 'iconinstagram', }); - final String? noPosts; - final String? noPostsWithFilter; - final String? anonymousUser; + final String noPosts; + final String noPostsWithFilter; + final String anonymousUser; - final String? title; - final String? content; - final String? contentDescription; - final String? uploadImage; - final String? uploadImageDescription; - final String? allowComments; - final String? allowCommentsDescription; - final String? checkPost; - final String? postAt; + final String title; + final String content; + final String contentDescription; + final String uploadImage; + final String uploadImageDescription; + final String allowComments; + final String allowCommentsDescription; + final String checkPost; + final String postAt; - final String? titleHintText; - final String? contentHintText; + final String titleHintText; + final String contentHintText; - final String? deletePost; - final String? deleteReaction; - final String? viewPost; - final String? likesTitle; - final String? commentsTitle; - final String? commentsTitleOnPost; - final String? writeComment; - final String? firstComment; - final String? postLoadingError; + final String deletePost; + final String deleteReaction; + final String viewPost; + final String likesTitle; + final String commentsTitle; + final String commentsTitleOnPost; + final String writeComment; + final String firstComment; + final String postLoadingError; - final String? timelineSelectionDescription; + final String timelineSelectionDescription; - final String? searchHint; + final String searchHint; - final String? postOverview; - final String? postIn; - final String? postCreation; + final String postOverview; + final String postIn; + final String postCreation; - final String? yes; - final String? no; - final String? timeLineScreenTitle; + final String yes; + final String no; + final String timeLineScreenTitle; + /// Method to override the default values of the translations TimelineTranslations copyWith({ String? noPosts, String? noPostsWithFilter, diff --git a/packages/flutter_timeline_view/lib/src/screens/timeline_post_creation_screen.dart b/packages/flutter_timeline_view/lib/src/screens/timeline_post_creation_screen.dart index b212b49..ff08b94 100644 --- a/packages/flutter_timeline_view/lib/src/screens/timeline_post_creation_screen.dart +++ b/packages/flutter_timeline_view/lib/src/screens/timeline_post_creation_screen.dart @@ -128,7 +128,7 @@ class _TimelinePostCreationScreenState crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - widget.options.translations.title!, + widget.options.translations.title, style: const TextStyle( fontWeight: FontWeight.w800, fontSize: 20, @@ -149,7 +149,7 @@ class _TimelinePostCreationScreenState ), const SizedBox(height: 16), Text( - widget.options.translations.content!, + widget.options.translations.content, style: const TextStyle( fontWeight: FontWeight.w800, fontSize: 20, @@ -157,7 +157,7 @@ class _TimelinePostCreationScreenState ), const SizedBox(height: 4), Text( - widget.options.translations.contentDescription!, + widget.options.translations.contentDescription, style: theme.textTheme.bodyMedium, ), // input field for the content @@ -177,14 +177,14 @@ class _TimelinePostCreationScreenState ), // input field for the content Text( - widget.options.translations.uploadImage!, + widget.options.translations.uploadImage, style: const TextStyle( fontWeight: FontWeight.w800, fontSize: 20, ), ), Text( - widget.options.translations.uploadImageDescription!, + widget.options.translations.uploadImageDescription, style: theme.textTheme.bodyMedium, ), // image picker field @@ -271,14 +271,14 @@ class _TimelinePostCreationScreenState const SizedBox(height: 16), Text( - widget.options.translations.commentsTitle!, + widget.options.translations.commentsTitle, style: const TextStyle( fontWeight: FontWeight.w800, fontSize: 20, ), ), Text( - widget.options.translations.allowCommentsDescription!, + widget.options.translations.allowCommentsDescription, style: theme.textTheme.bodyMedium, ), Row( @@ -293,7 +293,7 @@ class _TimelinePostCreationScreenState }); }, ), - Text(widget.options.translations.yes!), + Text(widget.options.translations.yes), Checkbox( activeColor: theme.colorScheme.primary, value: !allowComments, @@ -303,7 +303,7 @@ class _TimelinePostCreationScreenState }); }, ), - Text(widget.options.translations.no!), + Text(widget.options.translations.no), ], ), const SizedBox(height: 120), @@ -314,7 +314,7 @@ class _TimelinePostCreationScreenState ? widget.options.buttonBuilder!( context, onPostCreated, - widget.options.translations.checkPost!, + widget.options.translations.checkPost, enabled: editingDone, ) : ElevatedButton( @@ -334,8 +334,8 @@ class _TimelinePostCreationScreenState padding: const EdgeInsets.all(12.0), child: Text( widget.enablePostOverviewScreen - ? widget.options.translations.checkPost! - : widget.options.translations.postCreation!, + ? widget.options.translations.checkPost + : widget.options.translations.postCreation, style: const TextStyle( color: Colors.white, fontSize: 20, diff --git a/packages/flutter_timeline_view/lib/src/screens/timeline_post_screen.dart b/packages/flutter_timeline_view/lib/src/screens/timeline_post_screen.dart index a9e5d77..970949e 100644 --- a/packages/flutter_timeline_view/lib/src/screens/timeline_post_screen.dart +++ b/packages/flutter_timeline_view/lib/src/screens/timeline_post_screen.dart @@ -150,7 +150,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> { if (this.post == null) { return Center( child: Text( - widget.options.translations.postLoadingError!, + widget.options.translations.postLoadingError, style: widget.options.theme.textStyles.errorTextStyle, ), ); @@ -219,7 +219,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> { widget.options.nameBuilder ?.call(post.creator) ?? post.creator?.fullName ?? - widget.options.translations.anonymousUser!, + widget.options.translations.anonymousUser, style: widget.options.theme.textStyles .postCreatorTitleStyle ?? theme.textTheme.titleMedium, @@ -239,7 +239,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> { child: Row( children: [ Text( - widget.options.translations.deletePost!, + widget.options.translations.deletePost, style: widget.options.theme.textStyles .deletePostStyle ?? theme.textTheme.bodyMedium, @@ -439,7 +439,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> { const SizedBox(height: 20), if (post.reactionEnabled) ...[ Text( - widget.options.translations.commentsTitleOnPost!, + widget.options.translations.commentsTitleOnPost, style: theme.textTheme.titleMedium, ), for (var reaction @@ -467,7 +467,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> { PopupMenuItem( value: 'delete', child: Text( - widget.options.translations.deleteReaction!, + widget.options.translations.deleteReaction, ), ), ], @@ -521,7 +521,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> { ?.call(post.creator) ?? reaction.creator?.fullName ?? widget.options.translations - .anonymousUser!, + .anonymousUser, style: theme.textTheme.titleSmall, ), Padding( @@ -563,7 +563,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> { if (post.reactions?.isEmpty ?? true) ...[ const SizedBox(height: 16), Text( - widget.options.translations.firstComment!, + widget.options.translations.firstComment, ), ], const SizedBox(height: 120), diff --git a/packages/flutter_timeline_view/lib/src/screens/timeline_screen.dart b/packages/flutter_timeline_view/lib/src/screens/timeline_screen.dart index 38f7603..bb0855f 100644 --- a/packages/flutter_timeline_view/lib/src/screens/timeline_screen.dart +++ b/packages/flutter_timeline_view/lib/src/screens/timeline_screen.dart @@ -289,9 +289,9 @@ class _TimelineScreenState extends State { padding: const EdgeInsets.all(8.0), child: Text( category == null - ? widget.options.translations.noPosts! + ? widget.options.translations.noPosts : widget - .options.translations.noPostsWithFilter!, + .options.translations.noPostsWithFilter, style: widget.options.theme.textStyles.noPostsStyle, ), diff --git a/packages/flutter_timeline_view/lib/src/screens/timeline_selection_screen.dart b/packages/flutter_timeline_view/lib/src/screens/timeline_selection_screen.dart index f0b369e..39f3317 100644 --- a/packages/flutter_timeline_view/lib/src/screens/timeline_selection_screen.dart +++ b/packages/flutter_timeline_view/lib/src/screens/timeline_selection_screen.dart @@ -29,7 +29,7 @@ class TimelineSelectionScreen extends StatelessWidget { Padding( padding: EdgeInsets.only(top: size.height * 0.05, bottom: 8), child: Text( - options.translations.timelineSelectionDescription!, + options.translations.timelineSelectionDescription, style: const TextStyle( fontWeight: FontWeight.w800, fontSize: 20, diff --git a/packages/flutter_timeline_view/lib/src/widgets/reaction_bottom.dart b/packages/flutter_timeline_view/lib/src/widgets/reaction_bottom.dart index 8a62f7c..2118f60 100644 --- a/packages/flutter_timeline_view/lib/src/widgets/reaction_bottom.dart +++ b/packages/flutter_timeline_view/lib/src/widgets/reaction_bottom.dart @@ -65,7 +65,7 @@ class _ReactionBottomState extends State { ], ), ), - widget.translations.writeComment!, + widget.translations.writeComment, ), ), ), diff --git a/packages/flutter_timeline_view/lib/src/widgets/timeline_post_widget.dart b/packages/flutter_timeline_view/lib/src/widgets/timeline_post_widget.dart index abbb8a4..0989380 100644 --- a/packages/flutter_timeline_view/lib/src/widgets/timeline_post_widget.dart +++ b/packages/flutter_timeline_view/lib/src/widgets/timeline_post_widget.dart @@ -94,7 +94,7 @@ class _TimelinePostWidgetState extends State { widget.options.nameBuilder ?.call(widget.post.creator) ?? widget.post.creator?.fullName ?? - widget.options.translations.anonymousUser!, + widget.options.translations.anonymousUser, style: widget.options.theme.textStyles .postCreatorTitleStyle ?? theme.textTheme.titleMedium, @@ -118,7 +118,7 @@ class _TimelinePostWidgetState extends State { child: Row( children: [ Text( - widget.options.translations.deletePost!, + widget.options.translations.deletePost, style: widget.options.theme.textStyles .deletePostStyle ?? theme.textTheme.bodyMedium, @@ -318,7 +318,7 @@ class _TimelinePostWidgetState extends State { ), const SizedBox(height: 4), Text( - widget.options.translations.viewPost!, + widget.options.translations.viewPost, style: widget.options.theme.textStyles.viewPostStyle ?? theme.textTheme.bodySmall, ),