mirror of
https://github.com/Iconica-Development/flutter_timeline.git
synced 2025-05-19 02:23: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
|
## 2.1.0
|
||||||
|
|
||||||
- Fixed multiline textfield not being dismissible.
|
- Fixed multiline textfield not being dismissible.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// import 'package:example/apps/go_router/app.dart';
|
// import 'package:example/apps/go_router/app.dart';
|
||||||
// import 'package:example/apps/navigator/app.dart';
|
import 'package:example/apps/navigator/app.dart';
|
||||||
import 'package:example/apps/widgets/app.dart';
|
// import 'package:example/apps/widgets/app.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/date_symbol_data_local.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.
|
// Uncomment any, but only one, of these lines to run the example with specific navigation.
|
||||||
|
|
||||||
runApp(const WidgetApp());
|
// runApp(const WidgetApp());
|
||||||
// runApp(const NavigatorApp());
|
runApp(const NavigatorApp());
|
||||||
// runApp(const GoRouterApp());
|
// runApp(const GoRouterApp());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.1.0
|
version: 3.0.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
|
|
@ -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.1.0
|
version: 3.0.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
|
|
@ -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.1.0
|
version: 3.0.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
///
|
///
|
||||||
library flutter_timeline_view;
|
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_options.dart';
|
||||||
export 'src/config/timeline_styles.dart';
|
export 'src/config/timeline_styles.dart';
|
||||||
export 'src/config/timeline_theme.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/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/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_theme.dart';
|
||||||
import 'package:flutter_timeline_view/src/config/timeline_translations.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
|
|
||||||
class TimelineOptions {
|
class TimelineOptions {
|
||||||
const TimelineOptions({
|
const TimelineOptions({
|
||||||
this.theme = const TimelineTheme(),
|
this.textStyles = const TimelineTextStyles(),
|
||||||
this.translations = const TimelineTranslations.empty(),
|
this.translations = const TimelineTranslations.empty(),
|
||||||
this.imagePickerConfig = const ImagePickerConfig(),
|
this.imagePickerConfig = const ImagePickerConfig(),
|
||||||
this.imagePickerTheme = const ImagePickerTheme(),
|
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.filterOptions = const FilterOptions(),
|
||||||
this.categoriesOptions = const CategoriesOptions(),
|
this.categoriesOptions = const CategoriesOptions(),
|
||||||
this.requireImageForPost = false,
|
this.postTheme = const TimelinePostTheme(),
|
||||||
this.minTitleLength,
|
this.config = const TimelineConfig(),
|
||||||
this.maxTitleLength,
|
this.postConfig = const TimelinePostConfig(),
|
||||||
this.minContentLength,
|
this.theme = const TimelineTheme(),
|
||||||
this.maxContentLength,
|
this.postCreationTheme = const TimelinePostCreationTheme(),
|
||||||
|
this.postCreationConfig = const TimelinePostCreationConfig(),
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Theming options for the timeline
|
/// Parameter to set all textstyles within timeline
|
||||||
final TimelineTheme theme;
|
final TimelineTextStyles textStyles;
|
||||||
|
|
||||||
/// 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;
|
|
||||||
|
|
||||||
final TimelineTranslations translations;
|
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
|
/// ImagePickerTheme can be used to change the UI of the
|
||||||
/// Image Picker Widget to change the text/icons to your liking.
|
/// Image Picker Widget to change the text/icons to your liking.
|
||||||
final ImagePickerTheme imagePickerTheme;
|
final ImagePickerTheme imagePickerTheme;
|
||||||
|
@ -94,53 +42,20 @@ class TimelineOptions {
|
||||||
/// size and quality for the uploaded image.
|
/// size and quality for the uploaded image.
|
||||||
final ImagePickerConfig imagePickerConfig;
|
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
|
/// Options for filtering
|
||||||
final FilterOptions filterOptions;
|
final FilterOptions filterOptions;
|
||||||
|
|
||||||
/// Options for using the category selector.
|
/// Options for using the category selector.
|
||||||
final CategoriesOptions categoriesOptions;
|
final CategoriesOptions categoriesOptions;
|
||||||
|
|
||||||
/// Require image for post
|
final TimelineConfig config;
|
||||||
final bool requireImageForPost;
|
final TimelineTheme theme;
|
||||||
|
|
||||||
/// Minimum length of the title
|
final TimelinePostConfig postConfig;
|
||||||
final int? minTitleLength;
|
final TimelinePostTheme postTheme;
|
||||||
|
|
||||||
/// Maximum length of the title
|
final TimelinePostCreationTheme postCreationTheme;
|
||||||
final int? maxTitleLength;
|
final TimelinePostCreationConfig postCreationConfig;
|
||||||
|
|
||||||
/// Minimum length of the post content
|
|
||||||
final int? minContentLength;
|
|
||||||
|
|
||||||
/// Maximum length of the post content
|
|
||||||
final int? maxContentLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CategoriesOptions {
|
class CategoriesOptions {
|
||||||
|
|
|
@ -1,42 +1,17 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Iconica
|
// SPDX-FileCopyrightText: 2024 Iconica
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_timeline_view/src/config/timeline_styles.dart';
|
|
||||||
|
|
||||||
@immutable
|
|
||||||
class TimelineTheme {
|
class TimelineTheme {
|
||||||
const TimelineTheme({
|
const TimelineTheme({
|
||||||
this.iconColor,
|
this.dividerBuilder,
|
||||||
this.likeIcon,
|
this.pagePadding = const EdgeInsets.all(20),
|
||||||
this.commentIcon,
|
|
||||||
this.likedIcon,
|
|
||||||
this.sendIcon,
|
|
||||||
this.moreIcon,
|
|
||||||
this.deleteIcon,
|
|
||||||
this.textStyles = const TimelineTextStyles(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final Color? iconColor;
|
/// The builder for the divider
|
||||||
|
final Widget Function()? dividerBuilder;
|
||||||
|
|
||||||
/// The icon to display when the post is not yet liked
|
final EdgeInsets pagePadding;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,24 +69,28 @@ class _TimelinePostCreationScreenState
|
||||||
setState(() {
|
setState(() {
|
||||||
editingDone =
|
editingDone =
|
||||||
titleController.text.isNotEmpty && contentController.text.isNotEmpty;
|
titleController.text.isNotEmpty && contentController.text.isNotEmpty;
|
||||||
if (widget.options.requireImageForPost) {
|
if (widget.options.postCreationConfig.requireImageForPost) {
|
||||||
editingDone = editingDone && image != null;
|
editingDone = editingDone && image != null;
|
||||||
}
|
}
|
||||||
if (widget.options.minTitleLength != null) {
|
if (widget.options.postCreationConfig.minTitleLength != null) {
|
||||||
editingDone = editingDone &&
|
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 &&
|
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 &&
|
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 &&
|
editingDone = editingDone &&
|
||||||
contentController.text.length <= widget.options.maxContentLength!;
|
contentController.text.length <=
|
||||||
|
widget.options.postCreationConfig.maxContentLength!;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -119,7 +123,7 @@ class _TimelinePostCreationScreenState
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => FocusScope.of(context).unfocus(),
|
onTap: () => FocusScope.of(context).unfocus(),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: widget.options.padding,
|
padding: widget.options.postCreationTheme.pagePadding,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@ -129,7 +133,7 @@ class _TimelinePostCreationScreenState
|
||||||
widget.options.translations.title,
|
widget.options.translations.title,
|
||||||
style: theme.textTheme.displaySmall,
|
style: theme.textTheme.displaySmall,
|
||||||
),
|
),
|
||||||
widget.options.textInputBuilder?.call(
|
widget.options.postCreationTheme.textInputBuilder?.call(
|
||||||
titleController,
|
titleController,
|
||||||
null,
|
null,
|
||||||
'',
|
'',
|
||||||
|
@ -185,8 +189,8 @@ class _TimelinePostCreationScreenState
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
color: theme.colorScheme.background,
|
color: theme.colorScheme.background,
|
||||||
child: ImagePicker(
|
child: ImagePicker(
|
||||||
imagePickerConfig: widget.options.imagePickerConfig,
|
config: widget.options.imagePickerConfig,
|
||||||
imagePickerTheme: widget.options.imagePickerTheme,
|
theme: widget.options.imagePickerTheme,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -271,8 +275,8 @@ class _TimelinePostCreationScreenState
|
||||||
),
|
),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: (widget.options.buttonBuilder != null)
|
child: (widget.options.postCreationTheme.buttonBuilder != null)
|
||||||
? widget.options.buttonBuilder!(
|
? widget.options.postCreationTheme.buttonBuilder!(
|
||||||
context,
|
context,
|
||||||
onPostCreated,
|
onPostCreated,
|
||||||
widget.options.translations.checkPost,
|
widget.options.translations.checkPost,
|
||||||
|
|
|
@ -86,15 +86,16 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
TimelinePost? post;
|
TimelinePost? post;
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
|
||||||
late var textInputBuilder = widget.options.textInputBuilder ??
|
late var textInputBuilder =
|
||||||
(controller, suffixIcon, hintText) => TextField(
|
widget.options.postCreationTheme.textInputBuilder ??
|
||||||
textCapitalization: TextCapitalization.sentences,
|
(controller, suffixIcon, hintText) => TextField(
|
||||||
controller: controller,
|
textCapitalization: TextCapitalization.sentences,
|
||||||
decoration: InputDecoration(
|
controller: controller,
|
||||||
hintText: hintText,
|
decoration: InputDecoration(
|
||||||
suffixIcon: suffixIcon,
|
hintText: hintText,
|
||||||
),
|
suffixIcon: suffixIcon,
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -129,9 +130,9 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(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);
|
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) {
|
if (isLoading) {
|
||||||
const Center(
|
const Center(
|
||||||
|
@ -142,13 +143,13 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.options.translations.postLoadingError,
|
widget.options.translations.postLoadingError,
|
||||||
style: widget.options.theme.textStyles.errorTextStyle,
|
style: widget.options.textStyles.errorTextStyle,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var post = this.post!;
|
var post = this.post!;
|
||||||
post.reactions?.sort(
|
post.reactions?.sort(
|
||||||
(a, b) => widget.options.sortCommentsAscending
|
(a, b) => widget.options.config.sortCommentsAscending
|
||||||
? a.createdAt.compareTo(b.createdAt)
|
? a.createdAt.compareTo(b.createdAt)
|
||||||
: b.createdAt.compareTo(a.createdAt),
|
: b.createdAt.compareTo(a.createdAt),
|
||||||
);
|
);
|
||||||
|
@ -167,7 +168,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
},
|
},
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: widget.options.padding,
|
padding: widget.options.postTheme.pagePadding,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
@ -182,7 +183,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
if (post.creator!.imageUrl != null) ...[
|
if (post.creator!.imageUrl != null) ...[
|
||||||
widget.options.userAvatarBuilder?.call(
|
widget.options.postTheme.userAvatarBuilder
|
||||||
|
?.call(
|
||||||
post.creator!,
|
post.creator!,
|
||||||
40,
|
40,
|
||||||
) ??
|
) ??
|
||||||
|
@ -194,7 +196,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
widget.options.anonymousAvatarBuilder?.call(
|
widget.options.postTheme.anonymousAvatarBuilder
|
||||||
|
?.call(
|
||||||
post.creator!,
|
post.creator!,
|
||||||
40,
|
40,
|
||||||
) ??
|
) ??
|
||||||
|
@ -207,11 +210,11 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
],
|
],
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
widget.options.nameBuilder
|
widget.options.postTheme.nameBuilder
|
||||||
?.call(post.creator) ??
|
?.call(post.creator) ??
|
||||||
post.creator?.fullName ??
|
post.creator?.fullName ??
|
||||||
widget.options.translations.anonymousUser,
|
widget.options.translations.anonymousUser,
|
||||||
style: widget.options.theme.textStyles
|
style: widget.options.textStyles
|
||||||
.postCreatorTitleStyle ??
|
.postCreatorTitleStyle ??
|
||||||
theme.textTheme.titleMedium,
|
theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
|
@ -219,7 +222,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
if (widget.options.allowAllDeletion ||
|
if (widget.options.config.allowAllDeletion ||
|
||||||
post.creator?.userId == widget.userId)
|
post.creator?.userId == widget.userId)
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
onSelected: (value) => widget.onPostDelete(),
|
onSelected: (value) => widget.onPostDelete(),
|
||||||
|
@ -231,24 +234,27 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.options.translations.deletePost,
|
widget.options.translations.deletePost,
|
||||||
style: widget.options.theme.textStyles
|
style: widget.options.textStyles
|
||||||
.deletePostStyle ??
|
.deletePostStyle ??
|
||||||
theme.textTheme.bodyMedium,
|
theme.textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
widget.options.theme.deleteIcon ??
|
widget.options.postTheme.iconTheme
|
||||||
|
.deleteIcon ??
|
||||||
Icon(
|
Icon(
|
||||||
Icons.delete,
|
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(
|
Icon(
|
||||||
Icons.more_horiz_rounded,
|
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),
|
const SizedBox(height: 8),
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: widget.options.doubleTapTolike
|
child: widget.options.postConfig.doubleTapTolike
|
||||||
? TappableImage(
|
? TappableImage(
|
||||||
likeAndDislikeIcon: widget
|
likeAndDislikeIcon: widget.options.postTheme
|
||||||
.options.likeAndDislikeIconsForDoubleTap,
|
.iconTheme.likeAndDislikeIconsForDoubleTap,
|
||||||
post: post,
|
post: post,
|
||||||
userId: widget.userId,
|
userId: widget.userId,
|
||||||
onLike: ({required bool liked}) async {
|
onLike: ({required bool liked}) async {
|
||||||
|
@ -314,11 +320,13 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: widget.options.theme.likedIcon ??
|
child:
|
||||||
Icon(
|
widget.options.postTheme.iconTheme.likedIcon ??
|
||||||
Icons.thumb_up_rounded,
|
Icon(
|
||||||
color: widget.options.theme.iconColor,
|
Icons.thumb_up_rounded,
|
||||||
),
|
color: widget.options.postTheme.iconTheme
|
||||||
|
.iconColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
|
@ -333,49 +341,50 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: widget.options.theme.likeIcon ??
|
child:
|
||||||
Icon(
|
widget.options.postTheme.iconTheme.likeIcon ??
|
||||||
Icons.thumb_up_alt_outlined,
|
Icon(
|
||||||
color: widget.options.theme.iconColor,
|
Icons.thumb_up_alt_outlined,
|
||||||
size: widget.options.iconSize,
|
color: widget.options.postTheme.iconTheme
|
||||||
),
|
.iconColor,
|
||||||
|
size: widget.options.postTheme.iconSize,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
if (post.reactionEnabled)
|
if (post.reactionEnabled)
|
||||||
widget.options.theme.commentIcon ??
|
widget.options.postTheme.iconTheme.commentIcon ??
|
||||||
Icon(
|
Icon(
|
||||||
Icons.chat_bubble_outline_rounded,
|
Icons.chat_bubble_outline_rounded,
|
||||||
color: widget.options.theme.iconColor,
|
color:
|
||||||
size: widget.options.iconSize,
|
widget.options.postTheme.iconTheme.iconColor,
|
||||||
|
size: widget.options.postTheme.iconSize,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(
|
||||||
'${post.likes} ${widget.options.translations.likesTitle}',
|
'${post.likes} ${widget.options.translations.likesTitle}',
|
||||||
style: widget
|
style: widget.options.textStyles.postLikeTitleAndAmount ??
|
||||||
.options.theme.textStyles.postLikeTitleAndAmount ??
|
|
||||||
theme.textTheme.titleSmall
|
theme.textTheme.titleSmall
|
||||||
?.copyWith(color: Colors.black),
|
?.copyWith(color: Colors.black),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: widget.options.nameBuilder?.call(post.creator) ??
|
text: widget.options.postTheme.nameBuilder
|
||||||
|
?.call(post.creator) ??
|
||||||
post.creator?.fullName ??
|
post.creator?.fullName ??
|
||||||
widget.options.translations.anonymousUser,
|
widget.options.translations.anonymousUser,
|
||||||
style: widget
|
style: widget.options.textStyles.postCreatorNameStyle ??
|
||||||
.options.theme.textStyles.postCreatorNameStyle ??
|
|
||||||
theme.textTheme.titleSmall,
|
theme.textTheme.titleSmall,
|
||||||
children: [
|
children: [
|
||||||
const TextSpan(text: ' '),
|
const TextSpan(text: ' '),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: post.title,
|
text: post.title,
|
||||||
style:
|
style: widget.options.textStyles.postTitleStyle ??
|
||||||
widget.options.theme.textStyles.postTitleStyle ??
|
theme.textTheme.bodyMedium,
|
||||||
theme.textTheme.bodyMedium,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -427,7 +436,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onLongPressStart: (details) async {
|
onLongPressStart: (details) async {
|
||||||
if (reaction.creatorId == widget.userId ||
|
if (reaction.creatorId == widget.userId ||
|
||||||
widget.options.allowAllDeletion) {
|
widget.options.config.allowAllDeletion) {
|
||||||
var overlay = Overlay.of(context)
|
var overlay = Overlay.of(context)
|
||||||
.context
|
.context
|
||||||
.findRenderObject()! as RenderBox;
|
.findRenderObject()! as RenderBox;
|
||||||
|
@ -467,7 +476,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
children: [
|
children: [
|
||||||
if (reaction.creator?.imageUrl != null &&
|
if (reaction.creator?.imageUrl != null &&
|
||||||
reaction.creator!.imageUrl!.isNotEmpty) ...[
|
reaction.creator!.imageUrl!.isNotEmpty) ...[
|
||||||
widget.options.userAvatarBuilder?.call(
|
widget.options.postTheme.userAvatarBuilder?.call(
|
||||||
reaction.creator!,
|
reaction.creator!,
|
||||||
25,
|
25,
|
||||||
) ??
|
) ??
|
||||||
|
@ -478,7 +487,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
widget.options.anonymousAvatarBuilder?.call(
|
widget.options.postTheme.anonymousAvatarBuilder
|
||||||
|
?.call(
|
||||||
reaction.creator!,
|
reaction.creator!,
|
||||||
25,
|
25,
|
||||||
) ??
|
) ??
|
||||||
|
@ -496,7 +506,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.options.nameBuilder
|
widget.options.postTheme.nameBuilder
|
||||||
?.call(post.creator) ??
|
?.call(post.creator) ??
|
||||||
reaction.creator?.fullName ??
|
reaction.creator?.fullName ??
|
||||||
widget.options.translations
|
widget.options.translations
|
||||||
|
@ -517,7 +527,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text.rich(
|
child: Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: widget.options.nameBuilder
|
text: widget.options.postTheme.nameBuilder
|
||||||
?.call(post.creator) ??
|
?.call(post.creator) ??
|
||||||
reaction.creator?.fullName ??
|
reaction.creator?.fullName ??
|
||||||
widget
|
widget
|
||||||
|
@ -565,8 +575,8 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
color: theme.colorScheme.background,
|
color: theme.colorScheme.background,
|
||||||
child: ImagePicker(
|
child: ImagePicker(
|
||||||
imagePickerConfig: widget.options.imagePickerConfig,
|
config: widget.options.imagePickerConfig,
|
||||||
imagePickerTheme: widget.options.imagePickerTheme,
|
theme: widget.options.imagePickerTheme,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -598,7 +608,7 @@ class _TimelinePostScreenState extends State<_TimelinePostScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
translations: widget.options.translations,
|
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();
|
.toList();
|
||||||
|
|
||||||
// sort posts by date
|
// sort posts by date
|
||||||
if (widget.options.sortPostsAscending != null) {
|
if (widget.options.config.sortPostsAscending != null) {
|
||||||
posts.sort(
|
posts.sort(
|
||||||
(a, b) => widget.options.sortPostsAscending!
|
(a, b) => widget.options.config.sortPostsAscending!
|
||||||
? a.createdAt.compareTo(b.createdAt)
|
? a.createdAt.compareTo(b.createdAt)
|
||||||
: b.createdAt.compareTo(a.createdAt),
|
: b.createdAt.compareTo(a.createdAt),
|
||||||
);
|
);
|
||||||
|
@ -122,12 +122,12 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: widget.options.padding.top,
|
height: widget.options.postTheme.postPadding.top,
|
||||||
),
|
),
|
||||||
if (widget.filterEnabled) ...[
|
if (widget.filterEnabled) ...[
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: widget.options.padding.horizontal,
|
horizontal: widget.options.postTheme.postPadding.horizontal,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
@ -203,7 +203,7 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
||||||
children: [
|
children: [
|
||||||
...posts.map(
|
...posts.map(
|
||||||
(post) => Padding(
|
(post) => Padding(
|
||||||
padding: widget.options.postPadding,
|
padding: widget.options.postTheme.postPadding,
|
||||||
child: widget.postWidgetBuilder?.call(post) ??
|
child: widget.postWidgetBuilder?.call(post) ??
|
||||||
TimelinePostWidget(
|
TimelinePostWidget(
|
||||||
service: service,
|
service: service,
|
||||||
|
@ -253,7 +253,7 @@ class _TimelineScreenState extends State<TimelineScreen> {
|
||||||
category == null
|
category == null
|
||||||
? widget.options.translations.noPosts
|
? widget.options.translations.noPosts
|
||||||
: widget.options.translations.noPostsWithFilter,
|
: 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(
|
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),
|
padding: EdgeInsets.only(top: size.height * 0.05, bottom: 8),
|
||||||
child: Text(
|
child: Text(
|
||||||
options.translations.timelineSelectionDescription,
|
options.translations.timelineSelectionDescription,
|
||||||
style:
|
style: options.textStyles.categorySelectionDescriptionStyle ??
|
||||||
options.theme.textStyles.categorySelectionDescriptionStyle ??
|
theme.textTheme.displayMedium,
|
||||||
theme.textTheme.displayMedium,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
|
@ -55,7 +54,7 @@ class TimelineSelectionScreen extends StatelessWidget {
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8),
|
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||||
child: Text(
|
child: Text(
|
||||||
category.title,
|
category.title,
|
||||||
style: options.theme.textStyles.categorySelectionTitleStyle ??
|
style: options.textStyles.categorySelectionTitleStyle ??
|
||||||
theme.textTheme.displaySmall,
|
theme.textTheme.displaySmall,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -28,9 +28,9 @@ class CategorySelector extends StatelessWidget {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width:
|
width: options
|
||||||
options.categoriesOptions.categorySelectorHorizontalPadding ??
|
.categoriesOptions.categorySelectorHorizontalPadding ??
|
||||||
max(options.padding.horizontal - 4, 0),
|
max(options.postCreationTheme.pagePadding.horizontal - 4, 0),
|
||||||
),
|
),
|
||||||
for (var category in categories) ...[
|
for (var category in categories) ...[
|
||||||
options.categoriesOptions.categoryButtonBuilder?.call(
|
options.categoriesOptions.categoryButtonBuilder?.call(
|
||||||
|
@ -49,9 +49,9 @@ class CategorySelector extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width:
|
width: options
|
||||||
options.categoriesOptions.categorySelectorHorizontalPadding ??
|
.categoriesOptions.categorySelectorHorizontalPadding ??
|
||||||
max(options.padding.horizontal - 4, 0),
|
max(options.postCreationTheme.pagePadding.horizontal - 4, 0),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -50,7 +50,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
onTap: widget.onTap,
|
onTap: widget.onTap,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: widget.post.imageUrl != null
|
height: widget.post.imageUrl != null
|
||||||
? widget.options.postWidgetHeight
|
? widget.options.postTheme.postWidgetHeight
|
||||||
: null,
|
: null,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -67,7 +67,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
if (widget.post.creator!.imageUrl != null) ...[
|
if (widget.post.creator!.imageUrl != null) ...[
|
||||||
widget.options.userAvatarBuilder?.call(
|
widget.options.postTheme.userAvatarBuilder?.call(
|
||||||
widget.post.creator!,
|
widget.post.creator!,
|
||||||
40,
|
40,
|
||||||
) ??
|
) ??
|
||||||
|
@ -78,7 +78,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
widget.options.anonymousAvatarBuilder?.call(
|
widget.options.postTheme.anonymousAvatarBuilder?.call(
|
||||||
widget.post.creator!,
|
widget.post.creator!,
|
||||||
40,
|
40,
|
||||||
) ??
|
) ??
|
||||||
|
@ -91,19 +91,19 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
],
|
],
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
widget.options.nameBuilder
|
widget.options.postTheme.nameBuilder
|
||||||
?.call(widget.post.creator) ??
|
?.call(widget.post.creator) ??
|
||||||
widget.post.creator?.fullName ??
|
widget.post.creator?.fullName ??
|
||||||
widget.options.translations.anonymousUser,
|
widget.options.translations.anonymousUser,
|
||||||
style: widget.options.theme.textStyles
|
style:
|
||||||
.postCreatorTitleStyle ??
|
widget.options.textStyles.postCreatorTitleStyle ??
|
||||||
theme.textTheme.titleMedium,
|
theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
if (widget.options.allowAllDeletion ||
|
if (widget.options.config.allowAllDeletion ||
|
||||||
widget.post.creator?.userId == widget.userId)
|
widget.post.creator?.userId == widget.userId)
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
onSelected: (value) {
|
onSelected: (value) {
|
||||||
|
@ -119,24 +119,25 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.options.translations.deletePost,
|
widget.options.translations.deletePost,
|
||||||
style: widget.options.theme.textStyles
|
style:
|
||||||
.deletePostStyle ??
|
widget.options.textStyles.deletePostStyle ??
|
||||||
theme.textTheme.bodyMedium,
|
theme.textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
widget.options.theme.deleteIcon ??
|
widget.options.postTheme.iconTheme.deleteIcon ??
|
||||||
Icon(
|
Icon(
|
||||||
Icons.delete,
|
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(
|
Icon(
|
||||||
Icons.more_horiz_rounded,
|
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) ...[
|
if (widget.post.imageUrl != null) ...[
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: widget.options.postWidgetHeight != null ? 1 : 0,
|
flex: widget.options.postTheme.postWidgetHeight != null ? 1 : 0,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: widget.options.doubleTapTolike
|
child: widget.options.postConfig.doubleTapTolike
|
||||||
? TappableImage(
|
? TappableImage(
|
||||||
likeAndDislikeIcon:
|
likeAndDislikeIcon: widget.options.postTheme.iconTheme
|
||||||
widget.options.likeAndDislikeIconsForDoubleTap,
|
.likeAndDislikeIconsForDoubleTap,
|
||||||
post: widget.post,
|
post: widget.post,
|
||||||
userId: widget.userId,
|
userId: widget.userId,
|
||||||
onLike: ({required bool liked}) async {
|
onLike: ({required bool liked}) async {
|
||||||
|
@ -188,7 +189,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
// post information
|
// post information
|
||||||
if (widget.options.iconsWithValues)
|
if (widget.options.postTheme.iconsWithValues)
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
TextButton.icon(
|
TextButton.icon(
|
||||||
|
@ -210,7 +211,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: widget.options.theme.likeIcon ??
|
icon: widget.options.postTheme.iconTheme.likeIcon ??
|
||||||
Icon(
|
Icon(
|
||||||
widget.post.likedBy?.contains(widget.userId) ?? false
|
widget.post.likedBy?.contains(widget.userId) ?? false
|
||||||
? Icons.favorite
|
? Icons.favorite
|
||||||
|
@ -221,7 +222,7 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
if (widget.post.reactionEnabled)
|
if (widget.post.reactionEnabled)
|
||||||
TextButton.icon(
|
TextButton.icon(
|
||||||
onPressed: widget.onTap,
|
onPressed: widget.onTap,
|
||||||
icon: widget.options.theme.commentIcon ??
|
icon: widget.options.postTheme.iconTheme.commentIcon ??
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.chat_bubble_outline_outlined,
|
Icons.chat_bubble_outline_outlined,
|
||||||
),
|
),
|
||||||
|
@ -238,11 +239,12 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
onTap: widget.onTapUnlike,
|
onTap: widget.onTapUnlike,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: widget.options.theme.likedIcon ??
|
child: widget.options.postTheme.iconTheme.likedIcon ??
|
||||||
Icon(
|
Icon(
|
||||||
Icons.thumb_up_rounded,
|
Icons.thumb_up_rounded,
|
||||||
color: widget.options.theme.iconColor,
|
color:
|
||||||
size: widget.options.iconSize,
|
widget.options.postTheme.iconTheme.iconColor,
|
||||||
|
size: widget.options.postTheme.iconSize,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -251,11 +253,12 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
onTap: widget.onTapLike,
|
onTap: widget.onTapLike,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: widget.options.theme.likedIcon ??
|
child: widget.options.postTheme.iconTheme.likedIcon ??
|
||||||
Icon(
|
Icon(
|
||||||
Icons.thumb_up_rounded,
|
Icons.thumb_up_rounded,
|
||||||
color: widget.options.theme.iconColor,
|
color:
|
||||||
size: widget.options.iconSize,
|
widget.options.postTheme.iconTheme.iconColor,
|
||||||
|
size: widget.options.postTheme.iconSize,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -264,11 +267,11 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
if (widget.post.reactionEnabled) ...[
|
if (widget.post.reactionEnabled) ...[
|
||||||
Container(
|
Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: widget.options.theme.commentIcon ??
|
child: widget.options.postTheme.iconTheme.commentIcon ??
|
||||||
Icon(
|
Icon(
|
||||||
Icons.chat_bubble_outline_rounded,
|
Icons.chat_bubble_outline_rounded,
|
||||||
color: widget.options.theme.iconColor,
|
color: widget.options.postTheme.iconTheme.iconColor,
|
||||||
size: widget.options.iconSize,
|
size: widget.options.postTheme.iconSize,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -279,33 +282,32 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
|
|
||||||
if (widget.options.itemInfoBuilder != null) ...[
|
if (widget.options.postTheme.itemInfoBuilder != null) ...[
|
||||||
widget.options.itemInfoBuilder!(
|
widget.options.postTheme.itemInfoBuilder!(
|
||||||
post: widget.post,
|
post: widget.post,
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
Text(
|
Text(
|
||||||
'${widget.post.likes} '
|
'${widget.post.likes} '
|
||||||
'${widget.options.translations.likesTitle}',
|
'${widget.options.translations.likesTitle}',
|
||||||
style: widget
|
style: widget.options.textStyles.listPostLikeTitleAndAmount ??
|
||||||
.options.theme.textStyles.listPostLikeTitleAndAmount ??
|
|
||||||
theme.textTheme.titleSmall,
|
theme.textTheme.titleSmall,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: widget.options.nameBuilder?.call(widget.post.creator) ??
|
text: widget.options.postTheme.nameBuilder
|
||||||
|
?.call(widget.post.creator) ??
|
||||||
widget.post.creator?.fullName ??
|
widget.post.creator?.fullName ??
|
||||||
widget.options.translations.anonymousUser,
|
widget.options.translations.anonymousUser,
|
||||||
style: widget.options.theme.textStyles.listCreatorNameStyle ??
|
style: widget.options.textStyles.listCreatorNameStyle ??
|
||||||
theme.textTheme.titleSmall,
|
theme.textTheme.titleSmall,
|
||||||
children: [
|
children: [
|
||||||
const TextSpan(text: ' '),
|
const TextSpan(text: ' '),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: widget.post.title,
|
text: widget.post.title,
|
||||||
style:
|
style: widget.options.textStyles.listPostTitleStyle ??
|
||||||
widget.options.theme.textStyles.listPostTitleStyle ??
|
theme.textTheme.bodyMedium,
|
||||||
theme.textTheme.bodyMedium,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -313,12 +315,12 @@ class _TimelinePostWidgetState extends State<TimelinePostWidget> {
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
widget.options.translations.viewPost,
|
widget.options.translations.viewPost,
|
||||||
style: widget.options.theme.textStyles.viewPostStyle ??
|
style: widget.options.textStyles.viewPostStyle ??
|
||||||
theme.textTheme.bodySmall,
|
theme.textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
if (widget.options.dividerBuilder != null)
|
if (widget.options.theme.dividerBuilder != null)
|
||||||
widget.options.dividerBuilder!(),
|
widget.options.theme.dividerBuilder!(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -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.1.0
|
version: 3.0.0
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ dependencies:
|
||||||
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
|
||||||
ref: 1.0.4
|
ref: 3.0.0
|
||||||
collection: any
|
collection: any
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
Loading…
Reference in a new issue