mirror of
https://github.com/Iconica-Development/flutter_timeline.git
synced 2025-05-18 18:13:46 +02:00
wip: Big refactor and update of image picker package. Still missing some docs on some parameters
This commit is contained in:
parent
898583d1d1
commit
fe1dcd6d0d
21 changed files with 385 additions and 278 deletions
|
@ -1,3 +1,8 @@
|
|||
## 3.0.0
|
||||
|
||||
- Reorder of all parameters of TimelineOptions
|
||||
- Updated Flutter Image Picker form 1.0.4 to 3.0.0
|
||||
|
||||
## 2.1.0
|
||||
|
||||
- Fixed multiline textfield not being dismissible.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// import 'package:example/apps/go_router/app.dart';
|
||||
// import 'package:example/apps/navigator/app.dart';
|
||||
import 'package:example/apps/widgets/app.dart';
|
||||
import 'package:example/apps/navigator/app.dart';
|
||||
// import 'package:example/apps/widgets/app.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
|
||||
|
@ -9,7 +9,7 @@ void main() {
|
|||
|
||||
// Uncomment any, but only one, of these lines to run the example with specific navigation.
|
||||
|
||||
runApp(const WidgetApp());
|
||||
// runApp(const NavigatorApp());
|
||||
// runApp(const WidgetApp());
|
||||
runApp(const NavigatorApp());
|
||||
// runApp(const GoRouterApp());
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
name: flutter_timeline
|
||||
description: Visual elements and interface combined into one package
|
||||
version: 2.1.0
|
||||
version: 3.0.0
|
||||
|
||||
publish_to: none
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
name: flutter_timeline_firebase
|
||||
description: Implementation of the Flutter Timeline interface for Firebase.
|
||||
version: 2.1.0
|
||||
version: 3.0.0
|
||||
|
||||
publish_to: none
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
name: flutter_timeline_interface
|
||||
description: Interface for the service of the Flutter Timeline component
|
||||
version: 2.1.0
|
||||
version: 3.0.0
|
||||
|
||||
publish_to: none
|
||||
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
///
|
||||
library flutter_timeline_view;
|
||||
|
||||
export 'src/config/icon_timeline_theme.dart';
|
||||
export 'src/config/post_config.dart';
|
||||
export 'src/config/post_creation_config.dart';
|
||||
export 'src/config/post_theme.dart';
|
||||
export 'src/config/timeline_config.dart';
|
||||
export 'src/config/timeline_options.dart';
|
||||
export 'src/config/timeline_styles.dart';
|
||||
export 'src/config/timeline_theme.dart';
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// SPDX-FileCopyrightText: 2023 Iconica
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@immutable
|
||||
class IconTimelineTheme {
|
||||
const IconTimelineTheme({
|
||||
this.iconColor,
|
||||
this.likeIcon,
|
||||
this.commentIcon,
|
||||
this.likedIcon,
|
||||
this.sendIcon,
|
||||
this.moreIcon,
|
||||
this.deleteIcon,
|
||||
this.likeAndDislikeIconsForDoubleTap = const (
|
||||
Icon(
|
||||
Icons.favorite_rounded,
|
||||
color: Color(0xFFC3007A),
|
||||
),
|
||||
null,
|
||||
),
|
||||
});
|
||||
|
||||
final Color? iconColor;
|
||||
|
||||
/// The icon to display when the post is not yet liked
|
||||
final Widget? likeIcon;
|
||||
|
||||
/// The icon to display to indicate that a post has comments enabled
|
||||
final Widget? commentIcon;
|
||||
|
||||
/// The icon to display when the post is liked
|
||||
final Widget? likedIcon;
|
||||
|
||||
/// The icon to display to submit a comment
|
||||
final Widget? sendIcon;
|
||||
|
||||
/// The icon for more actions (open delete menu)
|
||||
final Widget? moreIcon;
|
||||
|
||||
/// The icon for delete action (delete post)
|
||||
final Widget? deleteIcon;
|
||||
|
||||
/// The icons to display when double tap to like is enabled
|
||||
final (Icon?, Icon?) likeAndDislikeIconsForDoubleTap;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2024 Iconica
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
class TimelinePostConfig {
|
||||
const TimelinePostConfig({
|
||||
this.doubleTapTolike = false,
|
||||
});
|
||||
|
||||
/// Whether to allow double tap to like
|
||||
final bool doubleTapTolike;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// SPDX-FileCopyrightText: 2024 Iconica
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
class TimelinePostCreationConfig {
|
||||
const TimelinePostCreationConfig({
|
||||
this.requireImageForPost = false,
|
||||
this.minTitleLength,
|
||||
this.maxTitleLength,
|
||||
this.minContentLength,
|
||||
this.maxContentLength,
|
||||
});
|
||||
|
||||
/// Require image for post
|
||||
final bool requireImageForPost;
|
||||
|
||||
/// Minimum length of the title
|
||||
final int? minTitleLength;
|
||||
|
||||
/// Maximum length of the title
|
||||
final int? maxTitleLength;
|
||||
|
||||
/// Minimum length of the post content
|
||||
final int? minContentLength;
|
||||
|
||||
/// Maximum length of the post content
|
||||
final int? maxContentLength;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// SPDX-FileCopyrightText: 2024 Iconica
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_timeline_view/src/config/timeline_options.dart';
|
||||
|
||||
class TimelinePostCreationTheme {
|
||||
const TimelinePostCreationTheme({
|
||||
this.buttonBuilder,
|
||||
this.textInputBuilder,
|
||||
this.pagePadding = const EdgeInsets.all(20),
|
||||
});
|
||||
|
||||
final ButtonBuilder? buttonBuilder;
|
||||
|
||||
final TextInputBuilder? textInputBuilder;
|
||||
|
||||
final EdgeInsets pagePadding;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
// SPDX-FileCopyrightText: 2024 Iconica
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_timeline_interface/flutter_timeline_interface.dart';
|
||||
import 'package:flutter_timeline_view/flutter_timeline_view.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class TimelinePostTheme {
|
||||
const TimelinePostTheme({
|
||||
this.timelinePostHeight,
|
||||
this.iconsWithValues = false,
|
||||
this.itemInfoBuilder,
|
||||
this.dateFormat,
|
||||
this.timeFormat,
|
||||
this.userAvatarBuilder,
|
||||
this.anonymousAvatarBuilder,
|
||||
this.nameBuilder,
|
||||
this.iconSize = 26,
|
||||
this.postWidgetHeight,
|
||||
this.postPadding = const EdgeInsets.all(12.0),
|
||||
this.pagePadding = const EdgeInsets.all(20),
|
||||
this.iconTheme = const IconTimelineTheme(),
|
||||
});
|
||||
|
||||
/// The height of a post in the timeline
|
||||
final double? timelinePostHeight;
|
||||
|
||||
/// Whether to display the icons with values
|
||||
final bool iconsWithValues;
|
||||
|
||||
/// The builder for the item info, all below the like and comment buttons
|
||||
final Widget Function({required TimelinePost post})? itemInfoBuilder;
|
||||
|
||||
/// The format to display the post date in
|
||||
final DateFormat? dateFormat;
|
||||
|
||||
/// The format to display the post time in
|
||||
final DateFormat? timeFormat;
|
||||
|
||||
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;
|
||||
|
||||
/// Size of icons like the comment and like icons. Dafualts to 26
|
||||
final double iconSize;
|
||||
|
||||
/// Sets a predefined height for the postWidget.
|
||||
final double? postWidgetHeight;
|
||||
|
||||
/// Padding of each post
|
||||
final EdgeInsets postPadding;
|
||||
|
||||
final EdgeInsets pagePadding;
|
||||
|
||||
/// Theming options for the icons within timeline
|
||||
final IconTimelineTheme iconTheme;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-FileCopyrightText: 2024 Iconica
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
class TimelineConfig {
|
||||
const TimelineConfig({
|
||||
this.allowAllDeletion = false,
|
||||
this.sortCommentsAscending = true,
|
||||
this.sortPostsAscending,
|
||||
});
|
||||
|
||||
/// Allow all posts to be deleted instead of
|
||||
/// only the posts of the current user
|
||||
final bool allowAllDeletion;
|
||||
|
||||
/// Whether to sort comments ascending or descending
|
||||
final bool sortCommentsAscending;
|
||||
|
||||
/// Whether to sort posts ascending or descending
|
||||
final bool? sortPostsAscending;
|
||||
}
|
|
@ -5,87 +5,35 @@ import 'package:collection/collection.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_image_picker/flutter_image_picker.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/post_config.dart';
|
||||
import 'package:flutter_timeline_view/src/config/post_creation_config.dart';
|
||||
import 'package:flutter_timeline_view/src/config/post_creation_theme.dart';
|
||||
import 'package:flutter_timeline_view/src/config/post_theme.dart';
|
||||
import 'package:flutter_timeline_view/src/config/timeline_config.dart';
|
||||
import 'package:flutter_timeline_view/src/config/timeline_theme.dart';
|
||||
import 'package:flutter_timeline_view/src/config/timeline_translations.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class TimelineOptions {
|
||||
const TimelineOptions({
|
||||
this.theme = const TimelineTheme(),
|
||||
this.textStyles = const TimelineTextStyles(),
|
||||
this.translations = const TimelineTranslations.empty(),
|
||||
this.imagePickerConfig = const ImagePickerConfig(),
|
||||
this.imagePickerTheme = const ImagePickerTheme(),
|
||||
this.timelinePostHeight,
|
||||
this.allowAllDeletion = false,
|
||||
this.sortCommentsAscending = true,
|
||||
this.sortPostsAscending,
|
||||
this.doubleTapTolike = false,
|
||||
this.iconsWithValues = false,
|
||||
this.likeAndDislikeIconsForDoubleTap = const (
|
||||
Icon(
|
||||
Icons.favorite_rounded,
|
||||
color: Color(0xFFC3007A),
|
||||
),
|
||||
null,
|
||||
),
|
||||
this.itemInfoBuilder,
|
||||
this.dateFormat,
|
||||
this.timeFormat,
|
||||
this.buttonBuilder,
|
||||
this.textInputBuilder,
|
||||
this.dividerBuilder,
|
||||
this.userAvatarBuilder,
|
||||
this.anonymousAvatarBuilder,
|
||||
this.nameBuilder,
|
||||
this.padding = const EdgeInsets.symmetric(vertical: 12.0),
|
||||
this.iconSize = 26,
|
||||
this.postWidgetHeight,
|
||||
this.postPadding = const EdgeInsets.all(12.0),
|
||||
this.filterOptions = const FilterOptions(),
|
||||
this.categoriesOptions = const CategoriesOptions(),
|
||||
this.requireImageForPost = false,
|
||||
this.minTitleLength,
|
||||
this.maxTitleLength,
|
||||
this.minContentLength,
|
||||
this.maxContentLength,
|
||||
this.postTheme = const TimelinePostTheme(),
|
||||
this.config = const TimelineConfig(),
|
||||
this.postConfig = const TimelinePostConfig(),
|
||||
this.theme = const TimelineTheme(),
|
||||
this.postCreationTheme = const TimelinePostCreationTheme(),
|
||||
this.postCreationConfig = const TimelinePostCreationConfig(),
|
||||
});
|
||||
|
||||
/// Theming options for the timeline
|
||||
final TimelineTheme theme;
|
||||
|
||||
/// The format to display the post date in
|
||||
final DateFormat? dateFormat;
|
||||
|
||||
/// The format to display the post time in
|
||||
final DateFormat? timeFormat;
|
||||
|
||||
/// Whether to sort comments ascending or descending
|
||||
final bool sortCommentsAscending;
|
||||
|
||||
/// Whether to sort posts ascending or descending
|
||||
final bool? sortPostsAscending;
|
||||
|
||||
/// Allow all posts to be deleted instead of
|
||||
/// only the posts of the current user
|
||||
final bool allowAllDeletion;
|
||||
|
||||
/// The height of a post in the timeline
|
||||
final double? timelinePostHeight;
|
||||
/// Parameter to set all textstyles within timeline
|
||||
final TimelineTextStyles textStyles;
|
||||
|
||||
final TimelineTranslations translations;
|
||||
|
||||
final ButtonBuilder? buttonBuilder;
|
||||
|
||||
final TextInputBuilder? textInputBuilder;
|
||||
|
||||
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;
|
||||
|
@ -94,53 +42,20 @@ class TimelineOptions {
|
|||
/// size and quality for the uploaded image.
|
||||
final ImagePickerConfig imagePickerConfig;
|
||||
|
||||
/// Whether to allow double tap to like
|
||||
final bool doubleTapTolike;
|
||||
|
||||
/// The icons to display when double tap to like is enabled
|
||||
final (Icon?, Icon?) likeAndDislikeIconsForDoubleTap;
|
||||
|
||||
/// Whether to display the icons with values
|
||||
final bool iconsWithValues;
|
||||
|
||||
/// The builder for the item info, all below the like and comment buttons
|
||||
final Widget Function({required TimelinePost post})? itemInfoBuilder;
|
||||
|
||||
/// The builder for the divider
|
||||
final Widget Function()? dividerBuilder;
|
||||
|
||||
/// The padding between posts in the timeline
|
||||
final EdgeInsets padding;
|
||||
|
||||
/// Size of icons like the comment and like icons. Dafualts to 26
|
||||
final double iconSize;
|
||||
|
||||
/// Sets a predefined height for the postWidget.
|
||||
final double? postWidgetHeight;
|
||||
|
||||
/// Padding of each post
|
||||
final EdgeInsets postPadding;
|
||||
|
||||
/// Options for filtering
|
||||
final FilterOptions filterOptions;
|
||||
|
||||
/// Options for using the category selector.
|
||||
final CategoriesOptions categoriesOptions;
|
||||
|
||||
/// Require image for post
|
||||
final bool requireImageForPost;
|
||||
final TimelineConfig config;
|
||||
final TimelineTheme theme;
|
||||
|
||||
/// Minimum length of the title
|
||||
final int? minTitleLength;
|
||||
final TimelinePostConfig postConfig;
|
||||
final TimelinePostTheme postTheme;
|
||||
|
||||
/// Maximum length of the title
|
||||
final int? maxTitleLength;
|
||||
|
||||
/// Minimum length of the post content
|
||||
final int? minContentLength;
|
||||
|
||||
/// Maximum length of the post content
|
||||
final int? maxContentLength;
|
||||
final TimelinePostCreationTheme postCreationTheme;
|
||||
final TimelinePostCreationConfig postCreationConfig;
|
||||
}
|
||||
|
||||
class CategoriesOptions {
|
||||
|
|
|
@ -1,42 +1,17 @@
|
|||
// SPDX-FileCopyrightText: 2023 Iconica
|
||||
// SPDX-FileCopyrightText: 2024 Iconica
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_timeline_view/src/config/timeline_styles.dart';
|
||||
|
||||
@immutable
|
||||
class TimelineTheme {
|
||||
const TimelineTheme({
|
||||
this.iconColor,
|
||||
this.likeIcon,
|
||||
this.commentIcon,
|
||||
this.likedIcon,
|
||||
this.sendIcon,
|
||||
this.moreIcon,
|
||||
this.deleteIcon,
|
||||
this.textStyles = const TimelineTextStyles(),
|
||||
this.dividerBuilder,
|
||||
this.pagePadding = const EdgeInsets.all(20),
|
||||
});
|
||||
|
||||
final Color? iconColor;
|
||||
/// The builder for the divider
|
||||
final Widget Function()? dividerBuilder;
|
||||
|
||||
/// The icon to display when the post is not yet liked
|
||||
final Widget? likeIcon;
|
||||
|
||||
/// The icon to display to indicate that a post has comments enabled
|
||||
final Widget? commentIcon;
|
||||
|
||||
/// The icon to display when the post is liked
|
||||
final Widget? likedIcon;
|
||||
|
||||
/// The icon to display to submit a comment
|
||||
final Widget? sendIcon;
|
||||
|
||||
/// The icon for more actions (open delete menu)
|
||||
final Widget? moreIcon;
|
||||
|
||||
/// The icon for delete action (delete post)
|
||||
final Widget? deleteIcon;
|
||||
|
||||
final TimelineTextStyles textStyles;
|
||||
final EdgeInsets pagePadding;
|
||||
}
|
||||
|
|
|
@ -69,24 +69,28 @@ class _TimelinePostCreationScreenState
|
|||
setState(() {
|
||||
editingDone =
|
||||
titleController.text.isNotEmpty && contentController.text.isNotEmpty;
|
||||
if (widget.options.requireImageForPost) {
|
||||
if (widget.options.postCreationConfig.requireImageForPost) {
|
||||
editingDone = editingDone && image != null;
|
||||
}
|
||||
if (widget.options.minTitleLength != null) {
|
||||
if (widget.options.postCreationConfig.minTitleLength != null) {
|
||||
editingDone = editingDone &&
|
||||
titleController.text.length >= widget.options.minTitleLength!;
|
||||
titleController.text.length >=
|
||||
widget.options.postCreationConfig.minTitleLength!;
|
||||
}
|
||||
if (widget.options.maxTitleLength != null) {
|
||||
if (widget.options.postCreationConfig.maxTitleLength != null) {
|
||||
editingDone = editingDone &&
|
||||
titleController.text.length <= widget.options.maxTitleLength!;
|
||||
titleController.text.length <=
|
||||
widget.options.postCreationConfig.maxTitleLength!;
|
||||
}
|
||||
if (widget.options.minContentLength != null) {
|
||||
if (widget.options.postCreationConfig.minContentLength != null) {
|
||||
editingDone = editingDone &&
|
||||
contentController.text.length >= widget.options.minContentLength!;
|
||||
contentController.text.length >=
|
||||
widget.options.postCreationConfig.minContentLength!;
|
||||
}
|
||||
if (widget.options.maxContentLength != null) {
|
||||
if (widget.options.postCreationConfig.maxContentLength != null) {
|
||||
editingDone = editingDone &&
|
||||
contentController.text.length <= widget.options.maxContentLength!;
|
||||
contentController.text.length <=
|
||||
widget.options.postCreationConfig.maxContentLength!;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -119,7 +123,7 @@ class _TimelinePostCreationScreenState
|
|||
return GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Padding(
|
||||
padding: widget.options.padding,
|
||||
padding: widget.options.postCreationTheme.pagePadding,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -129,7 +133,7 @@ class _TimelinePostCreationScreenState
|
|||
widget.options.translations.title,
|
||||
style: theme.textTheme.displaySmall,
|
||||
),
|
||||
widget.options.textInputBuilder?.call(
|
||||
widget.options.postCreationTheme.textInputBuilder?.call(
|
||||
titleController,
|
||||
null,
|
||||
'',
|
||||
|
@ -185,8 +189,8 @@ class _TimelinePostCreationScreenState
|
|||
padding: const EdgeInsets.all(8.0),
|
||||
color: theme.colorScheme.background,
|
||||
child: ImagePicker(
|
||||
imagePickerConfig: widget.options.imagePickerConfig,
|
||||
imagePickerTheme: widget.options.imagePickerTheme,
|
||||
config: widget.options.imagePickerConfig,
|
||||
theme: widget.options.imagePickerTheme,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -271,8 +275,8 @@ class _TimelinePostCreationScreenState
|
|||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: (widget.options.buttonBuilder != null)
|
||||
? widget.options.buttonBuilder!(
|
||||
child: (widget.options.postCreationTheme.buttonBuilder != null)
|
||||
? widget.options.postCreationTheme.buttonBuilder!(
|
||||
context,
|
||||
onPostCreated,
|
||||
widget.options.translations.checkPost,
|
||||
|
|
|
@ -86,15 +86,16 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
TimelinePost? post;
|
||||
bool isLoading = true;
|
||||
|
||||
late var textInputBuilder = widget.options.textInputBuilder ??
|
||||
(controller, suffixIcon, hintText) => TextField(
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
suffixIcon: suffixIcon,
|
||||
),
|
||||
);
|
||||
late var textInputBuilder =
|
||||
widget.options.postCreationTheme.textInputBuilder ??
|
||||
(controller, suffixIcon, hintText) => TextField(
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
suffixIcon: suffixIcon,
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -129,9 +130,9 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var theme = Theme.of(context);
|
||||
var dateFormat = widget.options.dateFormat ??
|
||||
var dateFormat = widget.options.postTheme.dateFormat ??
|
||||
DateFormat('dd/MM/yyyy', Localizations.localeOf(context).languageCode);
|
||||
var timeFormat = widget.options.timeFormat ?? DateFormat('HH:mm');
|
||||
var timeFormat = widget.options.postTheme.timeFormat ?? DateFormat('HH:mm');
|
||||
|
||||
if (isLoading) {
|
||||
const Center(
|
||||
|
@ -142,13 +143,13 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
return Center(
|
||||
child: Text(
|
||||
widget.options.translations.postLoadingError,
|
||||
style: widget.options.theme.textStyles.errorTextStyle,
|
||||
style: widget.options.textStyles.errorTextStyle,
|
||||
),
|
||||
);
|
||||
}
|
||||
var post = this.post!;
|
||||
post.reactions?.sort(
|
||||
(a, b) => widget.options.sortCommentsAscending
|
||||
(a, b) => widget.options.config.sortCommentsAscending
|
||||
? a.createdAt.compareTo(b.createdAt)
|
||||
: b.createdAt.compareTo(a.createdAt),
|
||||
);
|
||||
|
@ -167,7 +168,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
},
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: widget.options.padding,
|
||||
padding: widget.options.postTheme.pagePadding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -182,7 +183,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
child: Row(
|
||||
children: [
|
||||
if (post.creator!.imageUrl != null) ...[
|
||||
widget.options.userAvatarBuilder?.call(
|
||||
widget.options.postTheme.userAvatarBuilder
|
||||
?.call(
|
||||
post.creator!,
|
||||
40,
|
||||
) ??
|
||||
|
@ -194,7 +196,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
),
|
||||
),
|
||||
] else ...[
|
||||
widget.options.anonymousAvatarBuilder?.call(
|
||||
widget.options.postTheme.anonymousAvatarBuilder
|
||||
?.call(
|
||||
post.creator!,
|
||||
40,
|
||||
) ??
|
||||
|
@ -207,11 +210,11 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
],
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
widget.options.nameBuilder
|
||||
widget.options.postTheme.nameBuilder
|
||||
?.call(post.creator) ??
|
||||
post.creator?.fullName ??
|
||||
widget.options.translations.anonymousUser,
|
||||
style: widget.options.theme.textStyles
|
||||
style: widget.options.textStyles
|
||||
.postCreatorTitleStyle ??
|
||||
theme.textTheme.titleMedium,
|
||||
),
|
||||
|
@ -219,7 +222,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
),
|
||||
),
|
||||
const Spacer(),
|
||||
if (widget.options.allowAllDeletion ||
|
||||
if (widget.options.config.allowAllDeletion ||
|
||||
post.creator?.userId == widget.userId)
|
||||
PopupMenuButton(
|
||||
onSelected: (value) => widget.onPostDelete(),
|
||||
|
@ -231,24 +234,27 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
children: [
|
||||
Text(
|
||||
widget.options.translations.deletePost,
|
||||
style: widget.options.theme.textStyles
|
||||
style: widget.options.textStyles
|
||||
.deletePostStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
widget.options.theme.deleteIcon ??
|
||||
widget.options.postTheme.iconTheme
|
||||
.deleteIcon ??
|
||||
Icon(
|
||||
Icons.delete,
|
||||
color: widget.options.theme.iconColor,
|
||||
color: widget.options.postTheme
|
||||
.iconTheme.iconColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
child: widget.options.theme.moreIcon ??
|
||||
child: widget.options.postTheme.iconTheme.moreIcon ??
|
||||
Icon(
|
||||
Icons.more_horiz_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
color: widget
|
||||
.options.postTheme.iconTheme.iconColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -258,10 +264,10 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
const SizedBox(height: 8),
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: widget.options.doubleTapTolike
|
||||
child: widget.options.postConfig.doubleTapTolike
|
||||
? TappableImage(
|
||||
likeAndDislikeIcon: widget
|
||||
.options.likeAndDislikeIconsForDoubleTap,
|
||||
likeAndDislikeIcon: widget.options.postTheme
|
||||
.iconTheme.likeAndDislikeIconsForDoubleTap,
|
||||
post: post,
|
||||
userId: widget.userId,
|
||||
onLike: ({required bool liked}) async {
|
||||
|
@ -314,11 +320,13 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.likedIcon ??
|
||||
Icon(
|
||||
Icons.thumb_up_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
),
|
||||
child:
|
||||
widget.options.postTheme.iconTheme.likedIcon ??
|
||||
Icon(
|
||||
Icons.thumb_up_rounded,
|
||||
color: widget.options.postTheme.iconTheme
|
||||
.iconColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
|
@ -333,49 +341,50 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.likeIcon ??
|
||||
Icon(
|
||||
Icons.thumb_up_alt_outlined,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
),
|
||||
child:
|
||||
widget.options.postTheme.iconTheme.likeIcon ??
|
||||
Icon(
|
||||
Icons.thumb_up_alt_outlined,
|
||||
color: widget.options.postTheme.iconTheme
|
||||
.iconColor,
|
||||
size: widget.options.postTheme.iconSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 8),
|
||||
if (post.reactionEnabled)
|
||||
widget.options.theme.commentIcon ??
|
||||
widget.options.postTheme.iconTheme.commentIcon ??
|
||||
Icon(
|
||||
Icons.chat_bubble_outline_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
color:
|
||||
widget.options.postTheme.iconTheme.iconColor,
|
||||
size: widget.options.postTheme.iconSize,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'${post.likes} ${widget.options.translations.likesTitle}',
|
||||
style: widget
|
||||
.options.theme.textStyles.postLikeTitleAndAmount ??
|
||||
style: widget.options.textStyles.postLikeTitleAndAmount ??
|
||||
theme.textTheme.titleSmall
|
||||
?.copyWith(color: Colors.black),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: widget.options.nameBuilder?.call(post.creator) ??
|
||||
text: widget.options.postTheme.nameBuilder
|
||||
?.call(post.creator) ??
|
||||
post.creator?.fullName ??
|
||||
widget.options.translations.anonymousUser,
|
||||
style: widget
|
||||
.options.theme.textStyles.postCreatorNameStyle ??
|
||||
style: widget.options.textStyles.postCreatorNameStyle ??
|
||||
theme.textTheme.titleSmall,
|
||||
children: [
|
||||
const TextSpan(text: ' '),
|
||||
TextSpan(
|
||||
text: post.title,
|
||||
style:
|
||||
widget.options.theme.textStyles.postTitleStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
style: widget.options.textStyles.postTitleStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -427,7 +436,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
GestureDetector(
|
||||
onLongPressStart: (details) async {
|
||||
if (reaction.creatorId == widget.userId ||
|
||||
widget.options.allowAllDeletion) {
|
||||
widget.options.config.allowAllDeletion) {
|
||||
var overlay = Overlay.of(context)
|
||||
.context
|
||||
.findRenderObject()! as RenderBox;
|
||||
|
@ -467,7 +476,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
children: [
|
||||
if (reaction.creator?.imageUrl != null &&
|
||||
reaction.creator!.imageUrl!.isNotEmpty) ...[
|
||||
widget.options.userAvatarBuilder?.call(
|
||||
widget.options.postTheme.userAvatarBuilder?.call(
|
||||
reaction.creator!,
|
||||
25,
|
||||
) ??
|
||||
|
@ -478,7 +487,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
),
|
||||
),
|
||||
] else ...[
|
||||
widget.options.anonymousAvatarBuilder?.call(
|
||||
widget.options.postTheme.anonymousAvatarBuilder
|
||||
?.call(
|
||||
reaction.creator!,
|
||||
25,
|
||||
) ??
|
||||
|
@ -496,7 +506,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.options.nameBuilder
|
||||
widget.options.postTheme.nameBuilder
|
||||
?.call(post.creator) ??
|
||||
reaction.creator?.fullName ??
|
||||
widget.options.translations
|
||||
|
@ -517,7 +527,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
Expanded(
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: widget.options.nameBuilder
|
||||
text: widget.options.postTheme.nameBuilder
|
||||
?.call(post.creator) ??
|
||||
reaction.creator?.fullName ??
|
||||
widget
|
||||
|
@ -565,8 +575,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
padding: const EdgeInsets.all(8.0),
|
||||
color: theme.colorScheme.background,
|
||||
child: ImagePicker(
|
||||
imagePickerConfig: widget.options.imagePickerConfig,
|
||||
imagePickerTheme: widget.options.imagePickerTheme,
|
||||
config: widget.options.imagePickerConfig,
|
||||
theme: widget.options.imagePickerTheme,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -598,7 +608,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
|||
),
|
||||
),
|
||||
translations: widget.options.translations,
|
||||
iconColor: widget.options.theme.iconColor,
|
||||
iconColor: widget.options.postTheme.iconTheme.iconColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -110,9 +110,9 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
|||
.toList();
|
||||
|
||||
// sort posts by date
|
||||
if (widget.options.sortPostsAscending != null) {
|
||||
if (widget.options.config.sortPostsAscending != null) {
|
||||
posts.sort(
|
||||
(a, b) => widget.options.sortPostsAscending!
|
||||
(a, b) => widget.options.config.sortPostsAscending!
|
||||
? a.createdAt.compareTo(b.createdAt)
|
||||
: b.createdAt.compareTo(a.createdAt),
|
||||
);
|
||||
|
@ -122,12 +122,12 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.options.padding.top,
|
||||
height: widget.options.postTheme.postPadding.top,
|
||||
),
|
||||
if (widget.filterEnabled) ...[
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: widget.options.padding.horizontal,
|
||||
horizontal: widget.options.postTheme.postPadding.horizontal,
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
|
@ -203,7 +203,7 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
|||
children: [
|
||||
...posts.map(
|
||||
(post) => Padding(
|
||||
padding: widget.options.postPadding,
|
||||
padding: widget.options.postTheme.postPadding,
|
||||
child: widget.postWidgetBuilder?.call(post) ??
|
||||
TimelinePostWidget(
|
||||
service: service,
|
||||
|
@ -253,7 +253,7 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
|||
category == null
|
||||
? widget.options.translations.noPosts
|
||||
: widget.options.translations.noPostsWithFilter,
|
||||
style: widget.options.theme.textStyles.noPostsStyle,
|
||||
style: widget.options.textStyles.noPostsStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -262,7 +262,7 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
|||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: widget.options.padding.bottom,
|
||||
height: widget.options.postTheme.postPadding.bottom,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -31,9 +31,8 @@ class TimelineSelectionScreen extends StatelessWidget {
|
|||
padding: EdgeInsets.only(top: size.height * 0.05, bottom: 8),
|
||||
child: Text(
|
||||
options.translations.timelineSelectionDescription,
|
||||
style:
|
||||
options.theme.textStyles.categorySelectionDescriptionStyle ??
|
||||
theme.textTheme.displayMedium,
|
||||
style: options.textStyles.categorySelectionDescriptionStyle ??
|
||||
theme.textTheme.displayMedium,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
|
@ -55,7 +54,7 @@ class TimelineSelectionScreen extends StatelessWidget {
|
|||
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
category.title,
|
||||
style: options.theme.textStyles.categorySelectionTitleStyle ??
|
||||
style: options.textStyles.categorySelectionTitleStyle ??
|
||||
theme.textTheme.displaySmall,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -28,9 +28,9 @@ class CategorySelector extends StatelessWidget {
|
|||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width:
|
||||
options.categoriesOptions.categorySelectorHorizontalPadding ??
|
||||
max(options.padding.horizontal - 4, 0),
|
||||
width: options
|
||||
.categoriesOptions.categorySelectorHorizontalPadding ??
|
||||
max(options.postCreationTheme.pagePadding.horizontal - 4, 0),
|
||||
),
|
||||
for (var category in categories) ...[
|
||||
options.categoriesOptions.categoryButtonBuilder?.call(
|
||||
|
@ -49,9 +49,9 @@ class CategorySelector extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
SizedBox(
|
||||
width:
|
||||
options.categoriesOptions.categorySelectorHorizontalPadding ??
|
||||
max(options.padding.horizontal - 4, 0),
|
||||
width: options
|
||||
.categoriesOptions.categorySelectorHorizontalPadding ??
|
||||
max(options.postCreationTheme.pagePadding.horizontal - 4, 0),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -50,7 +50,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
onTap: widget.onTap,
|
||||
child: SizedBox(
|
||||
height: widget.post.imageUrl != null
|
||||
? widget.options.postWidgetHeight
|
||||
? widget.options.postTheme.postWidgetHeight
|
||||
: null,
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
|
@ -67,7 +67,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
child: Row(
|
||||
children: [
|
||||
if (widget.post.creator!.imageUrl != null) ...[
|
||||
widget.options.userAvatarBuilder?.call(
|
||||
widget.options.postTheme.userAvatarBuilder?.call(
|
||||
widget.post.creator!,
|
||||
40,
|
||||
) ??
|
||||
|
@ -78,7 +78,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
),
|
||||
),
|
||||
] else ...[
|
||||
widget.options.anonymousAvatarBuilder?.call(
|
||||
widget.options.postTheme.anonymousAvatarBuilder?.call(
|
||||
widget.post.creator!,
|
||||
40,
|
||||
) ??
|
||||
|
@ -91,19 +91,19 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
],
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
widget.options.nameBuilder
|
||||
widget.options.postTheme.nameBuilder
|
||||
?.call(widget.post.creator) ??
|
||||
widget.post.creator?.fullName ??
|
||||
widget.options.translations.anonymousUser,
|
||||
style: widget.options.theme.textStyles
|
||||
.postCreatorTitleStyle ??
|
||||
theme.textTheme.titleMedium,
|
||||
style:
|
||||
widget.options.textStyles.postCreatorTitleStyle ??
|
||||
theme.textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
if (widget.options.allowAllDeletion ||
|
||||
if (widget.options.config.allowAllDeletion ||
|
||||
widget.post.creator?.userId == widget.userId)
|
||||
PopupMenuButton(
|
||||
onSelected: (value) {
|
||||
|
@ -119,24 +119,25 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
children: [
|
||||
Text(
|
||||
widget.options.translations.deletePost,
|
||||
style: widget.options.theme.textStyles
|
||||
.deletePostStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
style:
|
||||
widget.options.textStyles.deletePostStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
widget.options.theme.deleteIcon ??
|
||||
widget.options.postTheme.iconTheme.deleteIcon ??
|
||||
Icon(
|
||||
Icons.delete,
|
||||
color: widget.options.theme.iconColor,
|
||||
color: widget
|
||||
.options.postTheme.iconTheme.iconColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
child: widget.options.theme.moreIcon ??
|
||||
child: widget.options.postTheme.iconTheme.moreIcon ??
|
||||
Icon(
|
||||
Icons.more_horiz_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
color: widget.options.postTheme.iconTheme.iconColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -145,13 +146,13 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
if (widget.post.imageUrl != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
Flexible(
|
||||
flex: widget.options.postWidgetHeight != null ? 1 : 0,
|
||||
flex: widget.options.postTheme.postWidgetHeight != null ? 1 : 0,
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: widget.options.doubleTapTolike
|
||||
child: widget.options.postConfig.doubleTapTolike
|
||||
? TappableImage(
|
||||
likeAndDislikeIcon:
|
||||
widget.options.likeAndDislikeIconsForDoubleTap,
|
||||
likeAndDislikeIcon: widget.options.postTheme.iconTheme
|
||||
.likeAndDislikeIconsForDoubleTap,
|
||||
post: widget.post,
|
||||
userId: widget.userId,
|
||||
onLike: ({required bool liked}) async {
|
||||
|
@ -188,7 +189,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
height: 8,
|
||||
),
|
||||
// post information
|
||||
if (widget.options.iconsWithValues)
|
||||
if (widget.options.postTheme.iconsWithValues)
|
||||
Row(
|
||||
children: [
|
||||
TextButton.icon(
|
||||
|
@ -210,7 +211,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
);
|
||||
}
|
||||
},
|
||||
icon: widget.options.theme.likeIcon ??
|
||||
icon: widget.options.postTheme.iconTheme.likeIcon ??
|
||||
Icon(
|
||||
widget.post.likedBy?.contains(widget.userId) ?? false
|
||||
? Icons.favorite
|
||||
|
@ -221,7 +222,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
if (widget.post.reactionEnabled)
|
||||
TextButton.icon(
|
||||
onPressed: widget.onTap,
|
||||
icon: widget.options.theme.commentIcon ??
|
||||
icon: widget.options.postTheme.iconTheme.commentIcon ??
|
||||
const Icon(
|
||||
Icons.chat_bubble_outline_outlined,
|
||||
),
|
||||
|
@ -238,11 +239,12 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
onTap: widget.onTapUnlike,
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.likedIcon ??
|
||||
child: widget.options.postTheme.iconTheme.likedIcon ??
|
||||
Icon(
|
||||
Icons.thumb_up_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
color:
|
||||
widget.options.postTheme.iconTheme.iconColor,
|
||||
size: widget.options.postTheme.iconSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -251,11 +253,12 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
onTap: widget.onTapLike,
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.likedIcon ??
|
||||
child: widget.options.postTheme.iconTheme.likedIcon ??
|
||||
Icon(
|
||||
Icons.thumb_up_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
color:
|
||||
widget.options.postTheme.iconTheme.iconColor,
|
||||
size: widget.options.postTheme.iconSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -264,11 +267,11 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
if (widget.post.reactionEnabled) ...[
|
||||
Container(
|
||||
color: Colors.transparent,
|
||||
child: widget.options.theme.commentIcon ??
|
||||
child: widget.options.postTheme.iconTheme.commentIcon ??
|
||||
Icon(
|
||||
Icons.chat_bubble_outline_rounded,
|
||||
color: widget.options.theme.iconColor,
|
||||
size: widget.options.iconSize,
|
||||
color: widget.options.postTheme.iconTheme.iconColor,
|
||||
size: widget.options.postTheme.iconSize,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -279,33 +282,32 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
height: 8,
|
||||
),
|
||||
|
||||
if (widget.options.itemInfoBuilder != null) ...[
|
||||
widget.options.itemInfoBuilder!(
|
||||
if (widget.options.postTheme.itemInfoBuilder != null) ...[
|
||||
widget.options.postTheme.itemInfoBuilder!(
|
||||
post: widget.post,
|
||||
),
|
||||
] else ...[
|
||||
Text(
|
||||
'${widget.post.likes} '
|
||||
'${widget.options.translations.likesTitle}',
|
||||
style: widget
|
||||
.options.theme.textStyles.listPostLikeTitleAndAmount ??
|
||||
style: widget.options.textStyles.listPostLikeTitleAndAmount ??
|
||||
theme.textTheme.titleSmall,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: widget.options.nameBuilder?.call(widget.post.creator) ??
|
||||
text: widget.options.postTheme.nameBuilder
|
||||
?.call(widget.post.creator) ??
|
||||
widget.post.creator?.fullName ??
|
||||
widget.options.translations.anonymousUser,
|
||||
style: widget.options.theme.textStyles.listCreatorNameStyle ??
|
||||
style: widget.options.textStyles.listCreatorNameStyle ??
|
||||
theme.textTheme.titleSmall,
|
||||
children: [
|
||||
const TextSpan(text: ' '),
|
||||
TextSpan(
|
||||
text: widget.post.title,
|
||||
style:
|
||||
widget.options.theme.textStyles.listPostTitleStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
style: widget.options.textStyles.listPostTitleStyle ??
|
||||
theme.textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -313,12 +315,12 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
|||
const SizedBox(height: 4),
|
||||
Text(
|
||||
widget.options.translations.viewPost,
|
||||
style: widget.options.theme.textStyles.viewPostStyle ??
|
||||
style: widget.options.textStyles.viewPostStyle ??
|
||||
theme.textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
if (widget.options.dividerBuilder != null)
|
||||
widget.options.dividerBuilder!(),
|
||||
if (widget.options.theme.dividerBuilder != null)
|
||||
widget.options.theme.dividerBuilder!(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
name: flutter_timeline_view
|
||||
description: Visual elements of the Flutter Timeline Component
|
||||
version: 2.1.0
|
||||
version: 3.0.0
|
||||
|
||||
publish_to: none
|
||||
|
||||
|
@ -27,7 +27,7 @@ dependencies:
|
|||
flutter_image_picker:
|
||||
git:
|
||||
url: https://github.com/Iconica-Development/flutter_image_picker
|
||||
ref: 1.0.4
|
||||
ref: 3.0.0
|
||||
collection: any
|
||||
|
||||
dev_dependencies:
|
||||
|
|
Loading…
Reference in a new issue