chore: refactor most theme related classes into a /theme folder
stream_chat_theme.dart remains in /src because I feel it will cause too much of a mess if moved.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:shimmer/shimmer.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/attachment_title.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/attachment_upload_state_builder.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/attachment_widget.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/attachment_title.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/attachment_widget.dart';
|
||||
import 'package:stream_chat_flutter/src/full_screen_media.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/src/video_thumbnail_image.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import 'package:stream_chat_flutter/src/channel_bottom_sheet.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
|
||||
/// Widget to display deleted message
|
||||
class DeletedMessage extends StatelessWidget {
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/src/video_thumbnail_image.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment_actions_modal.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
/// Header/AppBar widget for media display screen
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/full_screen_media.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:stream_chat_flutter/src/extension.dart';
|
||||
import 'package:stream_chat_flutter/src/message_action.dart';
|
||||
import 'package:stream_chat_flutter/src/reaction_picker.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/src/utils.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import 'package:stream_chat_flutter/src/message_widget.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||
import 'package:stream_chat_flutter/src/swipeable.dart';
|
||||
import 'package:stream_chat_flutter/src/system_message.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
import 'package:visibility_detector/visibility_detector.dart';
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
|
||||
import 'package:stream_chat_flutter/src/reaction_picker.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/info_tile.dart';
|
||||
import 'package:stream_chat_flutter/src/message_search_item.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:collection/collection.dart' show IterableExtension;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import 'package:stream_chat_flutter/src/message_actions_modal.dart';
|
||||
import 'package:stream_chat_flutter/src/message_reactions_modal.dart';
|
||||
import 'package:stream_chat_flutter/src/quoted_message_widget.dart';
|
||||
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/src/url_attachment.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/extension.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Theme for avatar
|
||||
class AvatarTheme {
|
||||
/// Constructor for creating [AvatarTheme]
|
||||
AvatarTheme({
|
||||
BoxConstraints? constraints,
|
||||
BorderRadius? borderRadius,
|
||||
}) : _constraints = constraints,
|
||||
_borderRadius = borderRadius;
|
||||
|
||||
final BoxConstraints? _constraints;
|
||||
final BorderRadius? _borderRadius;
|
||||
|
||||
/// Get constraints for avatar
|
||||
BoxConstraints get constraints =>
|
||||
_constraints ??
|
||||
const BoxConstraints.tightFor(
|
||||
height: 32,
|
||||
width: 32,
|
||||
);
|
||||
|
||||
/// Get border radius
|
||||
BorderRadius get borderRadius => _borderRadius ?? BorderRadius.circular(20);
|
||||
|
||||
/// Copy with another theme
|
||||
AvatarTheme copyWith({
|
||||
BoxConstraints? constraints,
|
||||
BorderRadius? borderRadius,
|
||||
}) =>
|
||||
AvatarTheme(
|
||||
constraints: constraints ?? _constraints,
|
||||
borderRadius: borderRadius ?? _borderRadius,
|
||||
);
|
||||
|
||||
/// Merge with another AvatarTheme
|
||||
AvatarTheme merge(AvatarTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
constraints: other._constraints,
|
||||
borderRadius: other._borderRadius,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/avatar_theme.dart';
|
||||
|
||||
/// Theme for [ChannelHeader]
|
||||
class ChannelHeaderTheme {
|
||||
/// Constructor for creating a [ChannelHeaderTheme]
|
||||
const ChannelHeaderTheme({
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.avatarTheme,
|
||||
this.color,
|
||||
});
|
||||
|
||||
/// Theme for title
|
||||
final TextStyle? title;
|
||||
|
||||
/// Theme for subtitle
|
||||
final TextStyle? subtitle;
|
||||
|
||||
/// Theme for avatar
|
||||
final AvatarTheme? avatarTheme;
|
||||
|
||||
/// Color for [ChannelHeaderTheme]
|
||||
final Color? color;
|
||||
|
||||
/// Copy with theme
|
||||
ChannelHeaderTheme copyWith({
|
||||
TextStyle? title,
|
||||
TextStyle? subtitle,
|
||||
AvatarTheme? avatarTheme,
|
||||
Color? color,
|
||||
}) =>
|
||||
ChannelHeaderTheme(
|
||||
title: title ?? this.title,
|
||||
subtitle: subtitle ?? this.subtitle,
|
||||
avatarTheme: avatarTheme ?? this.avatarTheme,
|
||||
color: color ?? this.color,
|
||||
);
|
||||
|
||||
/// Merge with other [ChannelHeaderTheme]
|
||||
ChannelHeaderTheme merge(ChannelHeaderTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
title: title?.merge(other.title) ?? other.title,
|
||||
subtitle: subtitle?.merge(other.subtitle) ?? other.subtitle,
|
||||
avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme,
|
||||
color: other.color,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/avatar_theme.dart';
|
||||
|
||||
/// Theme dedicated to the [ChannelListHeader]
|
||||
class ChannelListHeaderTheme {
|
||||
/// Returns a new [ChannelListHeaderTheme]
|
||||
const ChannelListHeaderTheme({
|
||||
this.title,
|
||||
this.avatarTheme,
|
||||
this.color,
|
||||
});
|
||||
|
||||
/// Style of the title text
|
||||
final TextStyle? title;
|
||||
|
||||
/// Theme dedicated to the userAvatar
|
||||
final AvatarTheme? avatarTheme;
|
||||
|
||||
/// Background color of the appbar
|
||||
final Color? color;
|
||||
|
||||
/// Returns a new [ChannelListHeaderTheme] replacing some of its properties
|
||||
ChannelListHeaderTheme copyWith({
|
||||
TextStyle? title,
|
||||
AvatarTheme? avatarTheme,
|
||||
Color? color,
|
||||
}) =>
|
||||
ChannelListHeaderTheme(
|
||||
title: title ?? this.title,
|
||||
avatarTheme: avatarTheme ?? this.avatarTheme,
|
||||
color: color ?? this.color,
|
||||
);
|
||||
|
||||
/// Merges [this] [ChannelListHeaderTheme] with the [other]
|
||||
ChannelListHeaderTheme merge(ChannelListHeaderTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
title: title?.merge(other.title) ?? other.title,
|
||||
avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme,
|
||||
color: other.color,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// Overrides the default style of [ChannelListView] descendants.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ChannelListViewThemeData], which is used to configure this theme.
|
||||
class ChannelListViewTheme extends InheritedTheme {
|
||||
/// Creates a [ChannelListViewTheme].
|
||||
///
|
||||
/// The [data] parameter must not be null.
|
||||
const ChannelListViewTheme({
|
||||
Key? key,
|
||||
required this.data,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
/// The configuration of this theme.
|
||||
final ChannelListViewThemeData data;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// If there is no enclosing [ChannelListViewTheme] widget, then
|
||||
/// [StreamChatThemeData.channelListViewTheme] is used.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// ChannelListViewTheme theme = ChannelListViewTheme.of(context);
|
||||
/// ```
|
||||
static ChannelListViewThemeData of(BuildContext context) {
|
||||
final channelListViewTheme =
|
||||
context.dependOnInheritedWidgetOfExactType<ChannelListViewTheme>();
|
||||
return channelListViewTheme?.data ??
|
||||
StreamChatTheme.of(context).channelListViewTheme;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrap(BuildContext context, Widget child) =>
|
||||
ChannelListViewTheme(data: data, child: child);
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(ChannelListViewTheme oldWidget) =>
|
||||
data != oldWidget.data;
|
||||
}
|
||||
|
||||
/// A style that overrides the default appearance of [ChannelListView]s when
|
||||
/// used with [ChannelListViewTheme] or with the overall [StreamChatTheme]'s
|
||||
/// [StreamChatThemeData.channelListViewTheme].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ChannelListViewTheme], the theme which is configured with this class.
|
||||
/// * [StreamChatThemeData.channelListViewTheme], which can be used to override
|
||||
/// the default style for [ChannelListView]s below the overall
|
||||
/// [StreamChatTheme].
|
||||
class ChannelListViewThemeData with Diagnosticable {
|
||||
/// Creates a [ChannelListViewThemeData].
|
||||
const ChannelListViewThemeData({
|
||||
this.backgroundColor,
|
||||
});
|
||||
|
||||
/// The color of the [ChannelListView] background.
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// Copies this [ChannelListViewThemeData] to another.
|
||||
ChannelListViewThemeData copyWith({
|
||||
Color? backgroundColor,
|
||||
}) =>
|
||||
ChannelListViewThemeData(
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
);
|
||||
|
||||
/// Linearly interpolate between two [ChannelListViewThemeData] themes.
|
||||
///
|
||||
/// All the properties must be non-null.
|
||||
ChannelListViewThemeData lerp(
|
||||
ChannelListViewThemeData a,
|
||||
ChannelListViewThemeData b,
|
||||
double t,
|
||||
) =>
|
||||
ChannelListViewThemeData(
|
||||
backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
|
||||
);
|
||||
|
||||
/// Merges one [ChannelListViewThemeData] with another.
|
||||
ChannelListViewThemeData merge(ChannelListViewThemeData? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
backgroundColor: other.backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is ChannelListViewThemeData &&
|
||||
runtimeType == other.runtimeType &&
|
||||
backgroundColor == other.backgroundColor;
|
||||
|
||||
@override
|
||||
int get hashCode => backgroundColor.hashCode;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(ColorProperty('backgroundColor', backgroundColor));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/avatar_theme.dart';
|
||||
|
||||
/// Theme for channel preview
|
||||
class ChannelPreviewTheme {
|
||||
/// Constructor for creating [ChannelPreviewTheme]
|
||||
const ChannelPreviewTheme({
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.lastMessageAt,
|
||||
this.avatarTheme,
|
||||
this.unreadCounterColor,
|
||||
this.indicatorIconSize,
|
||||
});
|
||||
|
||||
/// Theme for title
|
||||
final TextStyle? title;
|
||||
|
||||
/// Theme for subtitle
|
||||
final TextStyle? subtitle;
|
||||
|
||||
/// Theme of last message at
|
||||
final TextStyle? lastMessageAt;
|
||||
|
||||
/// Avatar theme
|
||||
final AvatarTheme? avatarTheme;
|
||||
|
||||
/// Unread counter color
|
||||
final Color? unreadCounterColor;
|
||||
|
||||
/// Indicator icon size
|
||||
final double? indicatorIconSize;
|
||||
|
||||
/// Copy with theme
|
||||
ChannelPreviewTheme copyWith({
|
||||
TextStyle? title,
|
||||
TextStyle? subtitle,
|
||||
TextStyle? lastMessageAt,
|
||||
AvatarTheme? avatarTheme,
|
||||
Color? unreadCounterColor,
|
||||
double? indicatorIconSize,
|
||||
}) =>
|
||||
ChannelPreviewTheme(
|
||||
title: title ?? this.title,
|
||||
subtitle: subtitle ?? this.subtitle,
|
||||
lastMessageAt: lastMessageAt ?? this.lastMessageAt,
|
||||
avatarTheme: avatarTheme ?? this.avatarTheme,
|
||||
unreadCounterColor: unreadCounterColor ?? this.unreadCounterColor,
|
||||
indicatorIconSize: indicatorIconSize ?? this.indicatorIconSize,
|
||||
);
|
||||
|
||||
/// Merge with theme
|
||||
ChannelPreviewTheme merge(ChannelPreviewTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
title: title?.merge(other.title) ?? other.title,
|
||||
subtitle: subtitle?.merge(other.subtitle) ?? other.subtitle,
|
||||
lastMessageAt:
|
||||
lastMessageAt?.merge(other.lastMessageAt) ?? other.lastMessageAt,
|
||||
avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme,
|
||||
unreadCounterColor: other.unreadCounterColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import 'package:stream_chat_flutter/src/theme/channel_header_theme.dart';
|
||||
|
||||
/// Channel theme data
|
||||
class ChannelTheme {
|
||||
/// Constructor for creating [ChannelTheme]
|
||||
ChannelTheme({
|
||||
required this.channelHeaderTheme,
|
||||
});
|
||||
|
||||
/// Theme of the [ChannelHeader] widget
|
||||
final ChannelHeaderTheme channelHeaderTheme;
|
||||
|
||||
/// Creates a copy of [ChannelTheme] with specified attributes overridden.
|
||||
ChannelTheme copyWith({
|
||||
ChannelHeaderTheme? channelHeaderTheme,
|
||||
}) =>
|
||||
ChannelTheme(
|
||||
channelHeaderTheme: channelHeaderTheme ?? this.channelHeaderTheme,
|
||||
);
|
||||
|
||||
/// Merge with theme
|
||||
ChannelTheme merge(ChannelTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
channelHeaderTheme: channelHeaderTheme.merge(other.channelHeaderTheme),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Theme that holds colors
|
||||
class ColorTheme {
|
||||
/// Initialise with light theme
|
||||
ColorTheme.light({
|
||||
this.textHighEmphasis = const Color(0xff000000),
|
||||
this.textLowEmphasis = const Color(0xff7a7a7a),
|
||||
this.disabled = const Color(0xffdbdbdb),
|
||||
this.borders = const Color(0xffecebeb),
|
||||
this.inputBg = const Color(0xfff2f2f2),
|
||||
this.appBg = const Color(0xfffcfcfc),
|
||||
this.barsBg = const Color(0xffffffff),
|
||||
this.linkBg = const Color(0xffe9f2ff),
|
||||
this.accentPrimary = const Color(0xff005FFF),
|
||||
this.accentError = const Color(0xffFF3842),
|
||||
this.accentInfo = const Color(0xff20E070),
|
||||
this.highlight = const Color(0xfffbf4dd),
|
||||
this.overlay = const Color.fromRGBO(0, 0, 0, 0.2),
|
||||
this.overlayDark = const Color.fromRGBO(0, 0, 0, 0.6),
|
||||
this.bgGradient = const LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xfff7f7f7), Color(0xfffcfcfc)],
|
||||
stops: [0, 1],
|
||||
),
|
||||
this.borderTop = const Effect(
|
||||
sigmaX: 0, sigmaY: -1, color: Color(0xff000000), blur: 0, alpha: 0.08),
|
||||
this.borderBottom = const Effect(
|
||||
sigmaX: 0, sigmaY: 1, color: Color(0xff000000), blur: 0, alpha: 0.08),
|
||||
this.shadowIconButton = const Effect(
|
||||
sigmaX: 0, sigmaY: 2, color: Color(0xff000000), alpha: 0.5, blur: 4),
|
||||
this.modalShadow = const Effect(
|
||||
sigmaX: 0, sigmaY: 0, color: Color(0xff000000), alpha: 1, blur: 8),
|
||||
}) : brightness = Brightness.light;
|
||||
|
||||
/// Initialise with dark theme
|
||||
ColorTheme.dark({
|
||||
this.textHighEmphasis = const Color(0xffffffff),
|
||||
this.textLowEmphasis = const Color(0xff7a7a7a),
|
||||
this.disabled = const Color(0xff2d2f2f),
|
||||
this.borders = const Color(0xff1c1e22),
|
||||
this.inputBg = const Color(0xff13151b),
|
||||
this.appBg = const Color(0xff070A0D),
|
||||
this.barsBg = const Color(0xff101418),
|
||||
this.linkBg = const Color(0xff00193D),
|
||||
this.accentPrimary = const Color(0xff005FFF),
|
||||
this.accentError = const Color(0xffFF3742),
|
||||
this.accentInfo = const Color(0xff20E070),
|
||||
this.borderTop = const Effect(
|
||||
sigmaX: 0,
|
||||
sigmaY: -1,
|
||||
color: Color(0xff141924),
|
||||
blur: 0,
|
||||
),
|
||||
this.borderBottom = const Effect(
|
||||
sigmaX: 0,
|
||||
sigmaY: 1,
|
||||
color: Color(0xff141924),
|
||||
blur: 0,
|
||||
alpha: 1,
|
||||
),
|
||||
this.shadowIconButton = const Effect(
|
||||
sigmaX: 0,
|
||||
sigmaY: 2,
|
||||
color: Color(0xff000000),
|
||||
alpha: 0.5,
|
||||
blur: 4,
|
||||
),
|
||||
this.modalShadow = const Effect(
|
||||
sigmaX: 0,
|
||||
sigmaY: 0,
|
||||
color: Color(0xff000000),
|
||||
alpha: 1,
|
||||
blur: 8,
|
||||
),
|
||||
this.highlight = const Color(0xff302d22),
|
||||
this.overlay = const Color.fromRGBO(0, 0, 0, 0.4),
|
||||
this.overlayDark = const Color.fromRGBO(255, 255, 255, 0.6),
|
||||
this.bgGradient = const LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Color(0xff101214),
|
||||
Color(0xff070a0d),
|
||||
],
|
||||
stops: [0, 1],
|
||||
),
|
||||
}) : brightness = Brightness.dark;
|
||||
|
||||
///
|
||||
final Color textHighEmphasis;
|
||||
|
||||
///
|
||||
final Color textLowEmphasis;
|
||||
|
||||
///
|
||||
final Color disabled;
|
||||
|
||||
///
|
||||
final Color borders;
|
||||
|
||||
///
|
||||
final Color inputBg;
|
||||
|
||||
///
|
||||
final Color appBg;
|
||||
|
||||
///
|
||||
final Color barsBg;
|
||||
|
||||
///
|
||||
final Color linkBg;
|
||||
|
||||
///
|
||||
final Color accentPrimary;
|
||||
|
||||
///
|
||||
final Color accentError;
|
||||
|
||||
///
|
||||
final Color accentInfo;
|
||||
|
||||
///
|
||||
final Effect borderTop;
|
||||
|
||||
///
|
||||
final Effect borderBottom;
|
||||
|
||||
///
|
||||
final Effect shadowIconButton;
|
||||
|
||||
///
|
||||
final Effect modalShadow;
|
||||
|
||||
///
|
||||
final Color highlight;
|
||||
|
||||
///
|
||||
final Color overlay;
|
||||
|
||||
///
|
||||
final Color overlayDark;
|
||||
|
||||
///
|
||||
final Gradient bgGradient;
|
||||
|
||||
///
|
||||
final Brightness brightness;
|
||||
|
||||
/// Copy with theme
|
||||
ColorTheme copyWith({
|
||||
Brightness brightness = Brightness.light,
|
||||
Color? textHighEmphasis,
|
||||
Color? textLowEmphasis,
|
||||
Color? disabled,
|
||||
Color? borders,
|
||||
Color? inputBg,
|
||||
Color? appBg,
|
||||
Color? barsBg,
|
||||
Color? linkBg,
|
||||
Color? accentPrimary,
|
||||
Color? accentError,
|
||||
Color? accentInfo,
|
||||
Effect? borderTop,
|
||||
Effect? borderBottom,
|
||||
Effect? shadowIconButton,
|
||||
Effect? modalShadow,
|
||||
Color? highlight,
|
||||
Color? overlay,
|
||||
Color? overlayDark,
|
||||
Gradient? bgGradient,
|
||||
}) =>
|
||||
brightness == Brightness.light
|
||||
? ColorTheme.light(
|
||||
textHighEmphasis: textHighEmphasis ?? this.textHighEmphasis,
|
||||
textLowEmphasis: textLowEmphasis ?? this.textLowEmphasis,
|
||||
disabled: disabled ?? this.disabled,
|
||||
borders: borders ?? this.borders,
|
||||
inputBg: inputBg ?? this.inputBg,
|
||||
appBg: appBg ?? this.appBg,
|
||||
barsBg: barsBg ?? this.barsBg,
|
||||
linkBg: linkBg ?? this.linkBg,
|
||||
accentPrimary: accentPrimary ?? this.accentPrimary,
|
||||
accentError: accentError ?? this.accentError,
|
||||
accentInfo: accentInfo ?? this.accentInfo,
|
||||
borderTop: borderTop ?? this.borderTop,
|
||||
borderBottom: borderBottom ?? this.borderBottom,
|
||||
shadowIconButton: shadowIconButton ?? this.shadowIconButton,
|
||||
modalShadow: modalShadow ?? this.modalShadow,
|
||||
highlight: highlight ?? this.highlight,
|
||||
overlay: overlay ?? this.overlay,
|
||||
overlayDark: overlayDark ?? this.overlayDark,
|
||||
bgGradient: bgGradient ?? this.bgGradient,
|
||||
)
|
||||
: ColorTheme.dark(
|
||||
textHighEmphasis: textHighEmphasis ?? this.textHighEmphasis,
|
||||
textLowEmphasis: textLowEmphasis ?? this.textLowEmphasis,
|
||||
disabled: disabled ?? this.disabled,
|
||||
borders: borders ?? this.borders,
|
||||
inputBg: inputBg ?? this.inputBg,
|
||||
appBg: appBg ?? this.appBg,
|
||||
barsBg: barsBg ?? this.barsBg,
|
||||
linkBg: linkBg ?? this.linkBg,
|
||||
accentPrimary: accentPrimary ?? this.accentPrimary,
|
||||
accentError: accentError ?? this.accentError,
|
||||
accentInfo: accentInfo ?? this.accentInfo,
|
||||
borderTop: borderTop ?? this.borderTop,
|
||||
borderBottom: borderBottom ?? this.borderBottom,
|
||||
shadowIconButton: shadowIconButton ?? this.shadowIconButton,
|
||||
modalShadow: modalShadow ?? this.modalShadow,
|
||||
highlight: highlight ?? this.highlight,
|
||||
overlay: overlay ?? this.overlay,
|
||||
overlayDark: overlayDark ?? this.overlayDark,
|
||||
bgGradient: bgGradient ?? this.bgGradient,
|
||||
);
|
||||
|
||||
/// Merge color theme
|
||||
ColorTheme merge(ColorTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
textHighEmphasis: other.textHighEmphasis,
|
||||
textLowEmphasis: other.textLowEmphasis,
|
||||
disabled: other.disabled,
|
||||
borders: other.borders,
|
||||
inputBg: other.inputBg,
|
||||
appBg: other.appBg,
|
||||
barsBg: other.barsBg,
|
||||
linkBg: other.linkBg,
|
||||
accentPrimary: other.accentPrimary,
|
||||
accentError: other.accentError,
|
||||
accentInfo: other.accentInfo,
|
||||
highlight: other.highlight,
|
||||
overlay: other.overlay,
|
||||
overlayDark: other.overlayDark,
|
||||
bgGradient: other.bgGradient,
|
||||
borderTop: other.borderTop,
|
||||
borderBottom: other.borderBottom,
|
||||
shadowIconButton: other.shadowIconButton,
|
||||
modalShadow: other.modalShadow,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Effect store
|
||||
class Effect {
|
||||
/// Constructor for creating [Effect]
|
||||
const Effect({
|
||||
this.sigmaX,
|
||||
this.sigmaY,
|
||||
this.color,
|
||||
this.alpha,
|
||||
this.blur,
|
||||
});
|
||||
|
||||
///
|
||||
final double? sigmaX;
|
||||
|
||||
///
|
||||
final double? sigmaY;
|
||||
|
||||
///
|
||||
final Color? color;
|
||||
|
||||
///
|
||||
final double? alpha;
|
||||
|
||||
///
|
||||
final double? blur;
|
||||
|
||||
/// Copy with new effect
|
||||
Effect copyWith({
|
||||
double? sigmaX,
|
||||
double? sigmaY,
|
||||
Color? color,
|
||||
double? alpha,
|
||||
double? blur,
|
||||
}) =>
|
||||
Effect(
|
||||
sigmaX: sigmaX ?? this.sigmaX,
|
||||
sigmaY: sigmaY ?? this.sigmaY,
|
||||
color: color ?? this.color,
|
||||
alpha: color as double? ?? this.alpha,
|
||||
blur: blur ?? this.blur,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// Overrides the default style of [GalleryFooter] descendants.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [GalleryFooterThemeData], which is used to configure this theme.
|
||||
class GalleryFooterTheme extends InheritedTheme {
|
||||
/// Creates an [GalleryFooterTheme].
|
||||
///
|
||||
/// The [data] parameter must not be null.
|
||||
const GalleryFooterTheme({
|
||||
Key? key,
|
||||
required this.data,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
/// The configuration of this theme.
|
||||
final GalleryFooterThemeData data;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// If there is no enclosing [GalleryFooterTheme] widget, then
|
||||
/// [StreamChatThemeData.galleryFooterTheme] is used.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// ImageFooterTheme theme = ImageFooterTheme.of(context);
|
||||
/// ```
|
||||
static GalleryFooterThemeData of(BuildContext context) {
|
||||
final imageFooterTheme =
|
||||
context.dependOnInheritedWidgetOfExactType<GalleryFooterTheme>();
|
||||
return imageFooterTheme?.data ??
|
||||
StreamChatTheme.of(context).galleryFooterTheme;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrap(BuildContext context, Widget child) =>
|
||||
GalleryFooterTheme(data: data, child: child);
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(GalleryFooterTheme oldWidget) =>
|
||||
data != oldWidget.data;
|
||||
}
|
||||
|
||||
/// A style that overrides the default appearance of [GalleryFooter]s when used
|
||||
/// with [GalleryFooterTheme] or with the overall [StreamChatTheme]'s
|
||||
/// [StreamChatThemeData.galleryFooterTheme].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [GalleryFooterTheme], the theme which is configured with this class.
|
||||
/// * [StreamChatThemeData.galleryFooterTheme], which can be used to override
|
||||
/// the default style for [GalleryFooter]s below the overall [StreamChatTheme].
|
||||
class GalleryFooterThemeData with Diagnosticable {
|
||||
/// Creates an [GalleryFooterThemeData].
|
||||
const GalleryFooterThemeData({
|
||||
this.backgroundColor,
|
||||
this.shareIconColor,
|
||||
this.titleTextStyle,
|
||||
this.gridIconButtonColor,
|
||||
this.bottomSheetBarrierColor,
|
||||
this.bottomSheetBackgroundColor,
|
||||
this.bottomSheetPhotosTextStyle,
|
||||
this.bottomSheetCloseIconColor,
|
||||
});
|
||||
|
||||
/// The background color for the [GalleryFooter] widget.
|
||||
///
|
||||
/// Defaults to [ColorTheme.barsBg].
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// The color for the "share" icon.
|
||||
///
|
||||
/// Defaults to [ColorTheme.textHighEmphasis].
|
||||
final Color? shareIconColor;
|
||||
|
||||
/// The [TextStyle] to use for the [GalleryFooter] title text.
|
||||
///
|
||||
/// Defaults to [TextTheme.headlineBold].
|
||||
final TextStyle? titleTextStyle;
|
||||
|
||||
/// The color to use for the "grid" icon.
|
||||
///
|
||||
/// Defaults to [ColorTheme.textHighEmphasis].
|
||||
final Color? gridIconButtonColor;
|
||||
|
||||
/// The color to use behind the bottom sheet.
|
||||
///
|
||||
/// Defaults to [ColorTheme.overlay].
|
||||
final Color? bottomSheetBarrierColor;
|
||||
|
||||
/// The background color to use for the bottom sheet.
|
||||
///
|
||||
/// Defaults to [ColorTheme.barsBg].
|
||||
final Color? bottomSheetBackgroundColor;
|
||||
|
||||
/// The [TextStyle] to use for the "photos" text in the bottom sheet.
|
||||
///
|
||||
/// Defaults to [TextTheme.headlineBold].
|
||||
final TextStyle? bottomSheetPhotosTextStyle;
|
||||
|
||||
/// The color to use for the "close" icon.
|
||||
///
|
||||
/// Defaults to [ColorTheme.textHighEmphasis].
|
||||
final Color? bottomSheetCloseIconColor;
|
||||
|
||||
/// Copies this [GalleryFooterThemeData] to another.
|
||||
GalleryFooterThemeData copyWith({
|
||||
Color? backgroundColor,
|
||||
Color? shareIconColor,
|
||||
TextStyle? titleTextStyle,
|
||||
Color? gridIconButtonColor,
|
||||
Color? bottomSheetBarrierColor,
|
||||
Color? bottomSheetBackgroundColor,
|
||||
TextStyle? bottomSheetPhotosTextStyle,
|
||||
Color? bottomSheetCloseIconColor,
|
||||
}) =>
|
||||
GalleryFooterThemeData(
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
shareIconColor: shareIconColor ?? this.shareIconColor,
|
||||
titleTextStyle: titleTextStyle ?? this.titleTextStyle,
|
||||
gridIconButtonColor: gridIconButtonColor ?? this.gridIconButtonColor,
|
||||
bottomSheetBarrierColor:
|
||||
bottomSheetBarrierColor ?? this.bottomSheetBarrierColor,
|
||||
bottomSheetBackgroundColor:
|
||||
bottomSheetBackgroundColor ?? this.bottomSheetBackgroundColor,
|
||||
bottomSheetPhotosTextStyle:
|
||||
bottomSheetPhotosTextStyle ?? this.bottomSheetPhotosTextStyle,
|
||||
bottomSheetCloseIconColor:
|
||||
bottomSheetCloseIconColor ?? this.bottomSheetCloseIconColor,
|
||||
);
|
||||
|
||||
/// Linearly interpolate between two [GalleryFooter] themes.
|
||||
///
|
||||
/// All the properties must be non-null.
|
||||
GalleryFooterThemeData lerp(
|
||||
GalleryFooterThemeData a,
|
||||
GalleryFooterThemeData b,
|
||||
double t,
|
||||
) =>
|
||||
GalleryFooterThemeData(
|
||||
backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
|
||||
shareIconColor: Color.lerp(a.shareIconColor, b.shareIconColor, t),
|
||||
titleTextStyle: TextStyle.lerp(a.titleTextStyle, b.titleTextStyle, t),
|
||||
gridIconButtonColor:
|
||||
Color.lerp(a.gridIconButtonColor, b.gridIconButtonColor, t),
|
||||
bottomSheetBarrierColor:
|
||||
Color.lerp(a.bottomSheetBarrierColor, b.bottomSheetBarrierColor, t),
|
||||
bottomSheetBackgroundColor: Color.lerp(
|
||||
a.bottomSheetBackgroundColor, b.bottomSheetBackgroundColor, t),
|
||||
bottomSheetPhotosTextStyle: TextStyle.lerp(
|
||||
a.bottomSheetPhotosTextStyle, b.bottomSheetPhotosTextStyle, t),
|
||||
bottomSheetCloseIconColor: Color.lerp(
|
||||
a.bottomSheetCloseIconColor, b.bottomSheetCloseIconColor, t),
|
||||
);
|
||||
|
||||
/// Merges one [GalleryFooterThemeData] with another.
|
||||
GalleryFooterThemeData merge(GalleryFooterThemeData? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
backgroundColor: other.backgroundColor,
|
||||
bottomSheetBarrierColor: other.bottomSheetBarrierColor,
|
||||
bottomSheetBackgroundColor: other.bottomSheetBackgroundColor,
|
||||
bottomSheetCloseIconColor: other.bottomSheetCloseIconColor,
|
||||
bottomSheetPhotosTextStyle: other.bottomSheetPhotosTextStyle,
|
||||
gridIconButtonColor: other.gridIconButtonColor,
|
||||
titleTextStyle: other.titleTextStyle,
|
||||
shareIconColor: other.shareIconColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is GalleryFooterThemeData &&
|
||||
runtimeType == other.runtimeType &&
|
||||
backgroundColor == other.backgroundColor &&
|
||||
shareIconColor == other.shareIconColor &&
|
||||
titleTextStyle == other.titleTextStyle &&
|
||||
gridIconButtonColor == other.gridIconButtonColor &&
|
||||
bottomSheetBarrierColor == other.bottomSheetBarrierColor &&
|
||||
bottomSheetBackgroundColor == other.bottomSheetBackgroundColor &&
|
||||
bottomSheetPhotosTextStyle == other.bottomSheetPhotosTextStyle &&
|
||||
bottomSheetCloseIconColor == other.bottomSheetCloseIconColor;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
backgroundColor.hashCode ^
|
||||
shareIconColor.hashCode ^
|
||||
titleTextStyle.hashCode ^
|
||||
gridIconButtonColor.hashCode ^
|
||||
bottomSheetBarrierColor.hashCode ^
|
||||
bottomSheetBackgroundColor.hashCode ^
|
||||
bottomSheetPhotosTextStyle.hashCode ^
|
||||
bottomSheetCloseIconColor.hashCode;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties
|
||||
..add(ColorProperty('backgroundColor', backgroundColor))
|
||||
..add(ColorProperty('shareIconColor', shareIconColor))
|
||||
..add(DiagnosticsProperty('titleTextStyle', titleTextStyle))
|
||||
..add(ColorProperty('gridIconButtonColor', gridIconButtonColor))
|
||||
..add(ColorProperty('bottomSheetBarrierColor', bottomSheetBarrierColor))
|
||||
..add(ColorProperty(
|
||||
'bottomSheetBackgroundColor', bottomSheetBackgroundColor))
|
||||
..add(DiagnosticsProperty(
|
||||
'bottomSheetPhotosTextStyle', bottomSheetPhotosTextStyle))
|
||||
..add(ColorProperty(
|
||||
'bottomSheetCloseIconColor', bottomSheetCloseIconColor));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// Overrides the default style of [GalleryHeader] descendants.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [GalleryHeaderThemeData], which is used to configure this theme.
|
||||
class GalleryHeaderTheme extends InheritedTheme {
|
||||
/// Creates an [GalleryHeaderTheme].
|
||||
///
|
||||
/// The [data] parameter must not be null.
|
||||
const GalleryHeaderTheme({
|
||||
Key? key,
|
||||
required this.data,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
/// The configuration of this theme.
|
||||
final GalleryHeaderThemeData data;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// If there is no enclosing [GalleryHeaderTheme] widget, then
|
||||
/// [StreamChatThemeData.galleryHeaderTheme] is used.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// ImageHeaderTheme theme = ImageHeaderTheme.of(context);
|
||||
/// ```
|
||||
static GalleryHeaderThemeData of(BuildContext context) {
|
||||
final galleryHeaderTheme =
|
||||
context.dependOnInheritedWidgetOfExactType<GalleryHeaderTheme>();
|
||||
return galleryHeaderTheme?.data ??
|
||||
StreamChatTheme.of(context).galleryHeaderTheme;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrap(BuildContext context, Widget child) =>
|
||||
GalleryHeaderTheme(data: data, child: child);
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(GalleryHeaderTheme oldWidget) =>
|
||||
data != oldWidget.data;
|
||||
}
|
||||
|
||||
/// A style that overrides the default appearance of [GalleryHeader]s when used
|
||||
/// with [GalleryHeaderTheme] or with the overall [StreamChatTheme]'s
|
||||
/// [StreamChatThemeData.galleryHeaderTheme].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [GalleryHeaderTheme], the theme which is configured with this class.
|
||||
/// * [StreamChatThemeData.galleryHeaderTheme], which can be used to override
|
||||
/// the default style for [GalleryHeader]s below the overall [StreamChatTheme].
|
||||
class GalleryHeaderThemeData with Diagnosticable {
|
||||
/// Creates an [GalleryHeaderThemeData].
|
||||
const GalleryHeaderThemeData({
|
||||
this.closeButtonColor,
|
||||
this.backgroundColor,
|
||||
this.iconMenuPointColor,
|
||||
this.titleTextStyle,
|
||||
this.subtitleTextStyle,
|
||||
this.bottomSheetBarrierColor,
|
||||
});
|
||||
|
||||
/// The color of the "close" button.
|
||||
///
|
||||
/// Defaults to [ColorTheme.textHighEmphasis].
|
||||
final Color? closeButtonColor;
|
||||
|
||||
/// The background color of the [GalleryHeader] widget.
|
||||
///
|
||||
/// Defaults to [ChannelHeaderTheme.color].
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// Defaults to [ColorTheme.textHighEmphasis].
|
||||
final Color? iconMenuPointColor;
|
||||
|
||||
/// The [TextStyle] to use for the [GalleryHeader] title text.
|
||||
///
|
||||
/// Defaults to [TextTheme.headlineBold].
|
||||
final TextStyle? titleTextStyle;
|
||||
|
||||
/// The [TextStyle] to use for the [GalleryHeader] subtitle text.
|
||||
///
|
||||
/// Defaults to [ChannelPreviewTheme.subtitle].
|
||||
final TextStyle? subtitleTextStyle;
|
||||
|
||||
///
|
||||
final Color? bottomSheetBarrierColor;
|
||||
|
||||
/// Copies this [GalleryHeaderThemeData] to another.
|
||||
GalleryHeaderThemeData copyWith({
|
||||
Color? closeButtonColor,
|
||||
Color? backgroundColor,
|
||||
Color? iconMenuPointColor,
|
||||
TextStyle? titleTextStyle,
|
||||
TextStyle? subtitleTextStyle,
|
||||
Color? bottomSheetBarrierColor,
|
||||
}) =>
|
||||
GalleryHeaderThemeData(
|
||||
closeButtonColor: closeButtonColor ?? this.closeButtonColor,
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
iconMenuPointColor: iconMenuPointColor ?? this.iconMenuPointColor,
|
||||
titleTextStyle: titleTextStyle ?? this.titleTextStyle,
|
||||
subtitleTextStyle: subtitleTextStyle ?? this.subtitleTextStyle,
|
||||
bottomSheetBarrierColor:
|
||||
bottomSheetBarrierColor ?? this.bottomSheetBarrierColor,
|
||||
);
|
||||
|
||||
/// Linearly interpolate between two [GalleryHeader] themes.
|
||||
///
|
||||
/// All the properties must be non-null.
|
||||
GalleryHeaderThemeData lerp(
|
||||
GalleryHeaderThemeData a,
|
||||
GalleryHeaderThemeData b,
|
||||
double t,
|
||||
) =>
|
||||
GalleryHeaderThemeData(
|
||||
closeButtonColor: Color.lerp(a.closeButtonColor, b.closeButtonColor, t),
|
||||
backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
|
||||
iconMenuPointColor:
|
||||
Color.lerp(a.iconMenuPointColor, b.iconMenuPointColor, t),
|
||||
titleTextStyle: TextStyle.lerp(a.titleTextStyle, b.titleTextStyle, t),
|
||||
subtitleTextStyle:
|
||||
TextStyle.lerp(a.subtitleTextStyle, b.subtitleTextStyle, t),
|
||||
bottomSheetBarrierColor:
|
||||
Color.lerp(a.bottomSheetBarrierColor, b.bottomSheetBarrierColor, t),
|
||||
);
|
||||
|
||||
/// Merges one [GalleryHeaderThemeData] with the another
|
||||
GalleryHeaderThemeData merge(GalleryHeaderThemeData? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
closeButtonColor: other.closeButtonColor,
|
||||
backgroundColor: other.backgroundColor,
|
||||
iconMenuPointColor: other.iconMenuPointColor,
|
||||
titleTextStyle: other.titleTextStyle,
|
||||
subtitleTextStyle: other.subtitleTextStyle,
|
||||
bottomSheetBarrierColor: other.bottomSheetBarrierColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is GalleryHeaderThemeData &&
|
||||
runtimeType == other.runtimeType &&
|
||||
closeButtonColor == other.closeButtonColor &&
|
||||
backgroundColor == other.backgroundColor &&
|
||||
iconMenuPointColor == other.iconMenuPointColor &&
|
||||
titleTextStyle == other.titleTextStyle &&
|
||||
subtitleTextStyle == other.subtitleTextStyle &&
|
||||
bottomSheetBarrierColor == other.bottomSheetBarrierColor;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
closeButtonColor.hashCode ^
|
||||
backgroundColor.hashCode ^
|
||||
iconMenuPointColor.hashCode ^
|
||||
titleTextStyle.hashCode ^
|
||||
subtitleTextStyle.hashCode ^
|
||||
bottomSheetBarrierColor.hashCode;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties
|
||||
..add(ColorProperty('closeButtonColor', closeButtonColor))
|
||||
..add(ColorProperty('backgroundColor', backgroundColor))
|
||||
..add(ColorProperty('iconMenuPointColor', iconMenuPointColor))
|
||||
..add(DiagnosticsProperty('titleTextStyle', titleTextStyle))
|
||||
..add(DiagnosticsProperty('subtitleTextStyle', subtitleTextStyle))
|
||||
..add(ColorProperty('bottomSheetBarrierColor', bottomSheetBarrierColor));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/extension.dart';
|
||||
|
||||
/// Defines the theme dedicated to the [MessageInput] widget
|
||||
class MessageInputTheme {
|
||||
/// Returns a new [MessageInputTheme]
|
||||
const MessageInputTheme({
|
||||
this.sendAnimationDuration,
|
||||
this.actionButtonColor,
|
||||
this.sendButtonColor,
|
||||
this.actionButtonIdleColor,
|
||||
this.sendButtonIdleColor,
|
||||
this.inputBackground,
|
||||
this.inputTextStyle,
|
||||
this.inputDecoration,
|
||||
this.activeBorderGradient,
|
||||
this.idleBorderGradient,
|
||||
this.borderRadius,
|
||||
this.expandButtonColor,
|
||||
});
|
||||
|
||||
/// Duration of the [MessageInput] send button animation
|
||||
final Duration? sendAnimationDuration;
|
||||
|
||||
/// Background color of [MessageInput] send button
|
||||
final Color? sendButtonColor;
|
||||
|
||||
/// Background color of [MessageInput] action buttons
|
||||
final Color? actionButtonColor;
|
||||
|
||||
/// Background color of [MessageInput] send button
|
||||
final Color? sendButtonIdleColor;
|
||||
|
||||
/// Background color of [MessageInput] action buttons
|
||||
final Color? actionButtonIdleColor;
|
||||
|
||||
/// Background color of [MessageInput] expand button
|
||||
final Color? expandButtonColor;
|
||||
|
||||
/// Background color of [MessageInput]
|
||||
final Color? inputBackground;
|
||||
|
||||
/// TextStyle of [MessageInput]
|
||||
final TextStyle? inputTextStyle;
|
||||
|
||||
/// InputDecoration of [MessageInput]
|
||||
final InputDecoration? inputDecoration;
|
||||
|
||||
/// Border gradient when the [MessageInput] is not focused
|
||||
final Gradient? idleBorderGradient;
|
||||
|
||||
/// Border gradient when the [MessageInput] is focused
|
||||
final Gradient? activeBorderGradient;
|
||||
|
||||
/// Border radius of [MessageInput]
|
||||
final BorderRadius? borderRadius;
|
||||
|
||||
/// Returns a new [MessageInputTheme] replacing some of its properties
|
||||
MessageInputTheme copyWith({
|
||||
Duration? sendAnimationDuration,
|
||||
Color? inputBackground,
|
||||
Color? actionButtonColor,
|
||||
Color? sendButtonColor,
|
||||
Color? actionButtonIdleColor,
|
||||
Color? sendButtonIdleColor,
|
||||
Color? expandButtonColor,
|
||||
TextStyle? inputTextStyle,
|
||||
InputDecoration? inputDecoration,
|
||||
Gradient? activeBorderGradient,
|
||||
Gradient? idleBorderGradient,
|
||||
BorderRadius? borderRadius,
|
||||
}) =>
|
||||
MessageInputTheme(
|
||||
sendAnimationDuration:
|
||||
sendAnimationDuration ?? this.sendAnimationDuration,
|
||||
inputBackground: inputBackground ?? this.inputBackground,
|
||||
actionButtonColor: actionButtonColor ?? this.actionButtonColor,
|
||||
sendButtonColor: sendButtonColor ?? this.sendButtonColor,
|
||||
actionButtonIdleColor:
|
||||
actionButtonIdleColor ?? this.actionButtonIdleColor,
|
||||
expandButtonColor: expandButtonColor ?? this.expandButtonColor,
|
||||
inputTextStyle: inputTextStyle ?? this.inputTextStyle,
|
||||
sendButtonIdleColor: sendButtonIdleColor ?? this.sendButtonIdleColor,
|
||||
inputDecoration: inputDecoration ?? this.inputDecoration,
|
||||
activeBorderGradient: activeBorderGradient ?? this.activeBorderGradient,
|
||||
idleBorderGradient: idleBorderGradient ?? this.idleBorderGradient,
|
||||
borderRadius: borderRadius ?? this.borderRadius,
|
||||
);
|
||||
|
||||
/// Merges [this] [MessageInputTheme] with the [other]
|
||||
MessageInputTheme merge(MessageInputTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
sendAnimationDuration: other.sendAnimationDuration,
|
||||
inputBackground: other.inputBackground,
|
||||
actionButtonColor: other.actionButtonColor,
|
||||
actionButtonIdleColor: other.actionButtonIdleColor,
|
||||
sendButtonColor: other.sendButtonColor,
|
||||
sendButtonIdleColor: other.sendButtonIdleColor,
|
||||
inputTextStyle:
|
||||
inputTextStyle?.merge(other.inputTextStyle) ?? other.inputTextStyle,
|
||||
inputDecoration: inputDecoration?.merge(other.inputDecoration) ??
|
||||
other.inputDecoration,
|
||||
activeBorderGradient: other.activeBorderGradient,
|
||||
idleBorderGradient: other.idleBorderGradient,
|
||||
borderRadius: other.borderRadius,
|
||||
expandButtonColor: other.expandButtonColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// Overrides the default style of [MessageListView] descendants.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [MessageListViewThemeData], which is used to configure this theme.
|
||||
class MessageListViewTheme extends InheritedTheme {
|
||||
/// Creates a [MessageListViewTheme].
|
||||
///
|
||||
/// The [data] parameter must not be null.
|
||||
const MessageListViewTheme({
|
||||
Key? key,
|
||||
required this.data,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
/// The configuration of this theme.
|
||||
final MessageListViewThemeData data;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// If there is no enclosing [MessageListViewTheme] widget, then
|
||||
/// [StreamChatThemeData.messageListViewTheme] is used.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// MessageListViewTheme theme = MessageListViewTheme.of(context);
|
||||
/// ```
|
||||
static MessageListViewThemeData of(BuildContext context) {
|
||||
final messageListViewTheme =
|
||||
context.dependOnInheritedWidgetOfExactType<MessageListViewTheme>();
|
||||
return messageListViewTheme?.data ??
|
||||
StreamChatTheme.of(context).messageListViewTheme;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrap(BuildContext context, Widget child) =>
|
||||
MessageListViewTheme(data: data, child: child);
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(MessageListViewTheme oldWidget) =>
|
||||
data != oldWidget.data;
|
||||
}
|
||||
|
||||
/// A style that overrides the default appearance of [MessageListView]s when
|
||||
/// used with [MessageListViewTheme] or with the overall [StreamChatTheme]'s
|
||||
/// [StreamChatThemeData.messageListViewTheme].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [MessageListViewTheme], the theme which is configured with this class.
|
||||
/// * [StreamChatThemeData.messageListViewTheme], which can be used to override
|
||||
/// the default style for [MessageListView]s below the overall
|
||||
/// [StreamChatTheme].
|
||||
class MessageListViewThemeData with Diagnosticable {
|
||||
/// Creates a [MessageListViewThemeData].
|
||||
const MessageListViewThemeData({
|
||||
this.backgroundColor,
|
||||
});
|
||||
|
||||
/// The color of the [MessageListView] background.
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// Copies this [MessageListViewThemeData] to another.
|
||||
MessageListViewThemeData copyWith({
|
||||
Color? backgroundColor,
|
||||
}) =>
|
||||
MessageListViewThemeData(
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
);
|
||||
|
||||
/// Linearly interpolate between two [MessageListView] themes.
|
||||
///
|
||||
/// All the properties must be non-null.
|
||||
MessageListViewThemeData lerp(
|
||||
MessageListViewThemeData a,
|
||||
MessageListViewThemeData b,
|
||||
double t,
|
||||
) =>
|
||||
MessageListViewThemeData(
|
||||
backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
|
||||
);
|
||||
|
||||
/// Merges one [MessageListViewThemeData] with another.
|
||||
MessageListViewThemeData merge(MessageListViewThemeData? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
backgroundColor: other.backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is MessageListViewThemeData &&
|
||||
runtimeType == other.runtimeType &&
|
||||
backgroundColor == other.backgroundColor;
|
||||
|
||||
@override
|
||||
int get hashCode => backgroundColor.hashCode;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(ColorProperty('backgroundColor', backgroundColor));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// Overrides the default style of [MessageSearchListView] descendants.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [UserListViewThemeData], which is used to configure this theme.
|
||||
class MessageSearchListViewTheme extends InheritedTheme {
|
||||
/// Creates a [UserListViewTheme].
|
||||
///
|
||||
/// The [data] parameter must not be null.
|
||||
const MessageSearchListViewTheme({
|
||||
Key? key,
|
||||
required this.data,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
/// The configuration of this theme.
|
||||
final MessageSearchListViewThemeData data;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// If there is no enclosing [MessageSearchListView] widget, then
|
||||
/// [StreamChatThemeData.messageSearchListViewTheme] is used.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// MessageSearchListViewTheme theme = MessageSearchListViewTheme.of(context);
|
||||
/// ```
|
||||
static MessageSearchListViewThemeData of(BuildContext context) {
|
||||
final messageSearchListViewTheme = context
|
||||
.dependOnInheritedWidgetOfExactType<MessageSearchListViewTheme>();
|
||||
return messageSearchListViewTheme?.data ??
|
||||
StreamChatTheme.of(context).messageSearchListViewTheme;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrap(BuildContext context, Widget child) =>
|
||||
MessageSearchListViewTheme(data: data, child: child);
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(MessageSearchListViewTheme oldWidget) =>
|
||||
data != oldWidget.data;
|
||||
}
|
||||
|
||||
/// A style that overrides the default appearance of [MessageSearchListView]s
|
||||
/// when used with [MessageSearchListView] or with the overall
|
||||
/// [StreamChatTheme]'s [StreamChatThemeData.messageSearchListViewTheme].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [MessageSearchListViewTheme], the theme which is configured with this
|
||||
/// class.
|
||||
/// * [StreamChatThemeData.messageSearchListViewTheme], which can be used to
|
||||
/// override the default style for [UserListView]s below the overall
|
||||
/// [StreamChatTheme].
|
||||
class MessageSearchListViewThemeData with Diagnosticable {
|
||||
/// Creates a [MessageSearchListViewThemeData].
|
||||
const MessageSearchListViewThemeData({
|
||||
this.backgroundColor,
|
||||
});
|
||||
|
||||
/// The color of the [MessageSearchListView] background.
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// Copies this [MessageSearchListViewThemeData] to another.
|
||||
MessageSearchListViewThemeData copyWith({
|
||||
Color? backgroundColor,
|
||||
}) =>
|
||||
MessageSearchListViewThemeData(
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
);
|
||||
|
||||
/// Linearly interpolate between two [UserListViewThemeData] themes.
|
||||
///
|
||||
/// All the properties must be non-null.
|
||||
MessageSearchListViewThemeData lerp(
|
||||
MessageSearchListViewThemeData a,
|
||||
MessageSearchListViewThemeData b,
|
||||
double t,
|
||||
) =>
|
||||
MessageSearchListViewThemeData(
|
||||
backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
|
||||
);
|
||||
|
||||
/// Merges one [MessageSearchListViewThemeData] with another.
|
||||
MessageSearchListViewThemeData merge(MessageSearchListViewThemeData? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
backgroundColor: other.backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is MessageSearchListViewThemeData &&
|
||||
runtimeType == other.runtimeType &&
|
||||
backgroundColor == other.backgroundColor;
|
||||
|
||||
@override
|
||||
int get hashCode => backgroundColor.hashCode;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(ColorProperty('backgroundColor', backgroundColor));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/avatar_theme.dart';
|
||||
|
||||
/// Class for getting message theme
|
||||
class MessageTheme {
|
||||
/// Constructor into [MessageTheme]
|
||||
const MessageTheme({
|
||||
this.replies,
|
||||
this.messageText,
|
||||
this.messageAuthor,
|
||||
this.messageLinks,
|
||||
this.messageBackgroundColor,
|
||||
this.messageBorderColor,
|
||||
this.reactionsBackgroundColor,
|
||||
this.reactionsBorderColor,
|
||||
this.reactionsMaskColor,
|
||||
this.avatarTheme,
|
||||
this.createdAt,
|
||||
});
|
||||
|
||||
/// Text style for message text
|
||||
final TextStyle? messageText;
|
||||
|
||||
/// Text style for message author
|
||||
final TextStyle? messageAuthor;
|
||||
|
||||
/// Text style for message links
|
||||
final TextStyle? messageLinks;
|
||||
|
||||
/// Text style for created at text
|
||||
final TextStyle? createdAt;
|
||||
|
||||
/// Text style for replies
|
||||
final TextStyle? replies;
|
||||
|
||||
/// Color for messageBackgroundColor
|
||||
final Color? messageBackgroundColor;
|
||||
|
||||
/// Color for message border color
|
||||
final Color? messageBorderColor;
|
||||
|
||||
/// Color for reactions
|
||||
final Color? reactionsBackgroundColor;
|
||||
|
||||
/// Colors reaction border
|
||||
final Color? reactionsBorderColor;
|
||||
|
||||
/// Color for reaction mask
|
||||
final Color? reactionsMaskColor;
|
||||
|
||||
/// Theme of the avatar
|
||||
final AvatarTheme? avatarTheme;
|
||||
|
||||
/// Copy with a theme
|
||||
MessageTheme copyWith({
|
||||
TextStyle? messageText,
|
||||
TextStyle? messageAuthor,
|
||||
TextStyle? messageLinks,
|
||||
TextStyle? createdAt,
|
||||
TextStyle? replies,
|
||||
Color? messageBackgroundColor,
|
||||
Color? messageBorderColor,
|
||||
AvatarTheme? avatarTheme,
|
||||
Color? reactionsBackgroundColor,
|
||||
Color? reactionsBorderColor,
|
||||
Color? reactionsMaskColor,
|
||||
}) =>
|
||||
MessageTheme(
|
||||
messageText: messageText ?? this.messageText,
|
||||
messageAuthor: messageAuthor ?? this.messageAuthor,
|
||||
messageLinks: messageLinks ?? this.messageLinks,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
messageBackgroundColor:
|
||||
messageBackgroundColor ?? this.messageBackgroundColor,
|
||||
messageBorderColor: messageBorderColor ?? this.messageBorderColor,
|
||||
avatarTheme: avatarTheme ?? this.avatarTheme,
|
||||
replies: replies ?? this.replies,
|
||||
reactionsBackgroundColor:
|
||||
reactionsBackgroundColor ?? this.reactionsBackgroundColor,
|
||||
reactionsBorderColor: reactionsBorderColor ?? this.reactionsBorderColor,
|
||||
reactionsMaskColor: reactionsMaskColor ?? this.reactionsMaskColor,
|
||||
);
|
||||
|
||||
/// Merge with a theme
|
||||
MessageTheme merge(MessageTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
messageText: messageText?.merge(other.messageText) ?? other.messageText,
|
||||
messageAuthor:
|
||||
messageAuthor?.merge(other.messageAuthor) ?? other.messageAuthor,
|
||||
messageLinks:
|
||||
messageLinks?.merge(other.messageLinks) ?? other.messageLinks,
|
||||
createdAt: createdAt?.merge(other.createdAt) ?? other.createdAt,
|
||||
replies: replies?.merge(other.replies) ?? other.replies,
|
||||
messageBackgroundColor: other.messageBackgroundColor,
|
||||
messageBorderColor: other.messageBorderColor,
|
||||
avatarTheme: avatarTheme?.merge(other.avatarTheme) ?? other.avatarTheme,
|
||||
reactionsBackgroundColor: other.reactionsBackgroundColor,
|
||||
reactionsBorderColor: other.reactionsBorderColor,
|
||||
reactionsMaskColor: other.reactionsMaskColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Class for holding text theme
|
||||
class TextTheme {
|
||||
/// Initialise light text theme
|
||||
TextTheme.light({
|
||||
this.title = const TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
this.headlineBold = const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
this.headline = const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black,
|
||||
),
|
||||
this.bodyBold = const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
this.body = const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black,
|
||||
),
|
||||
this.footnoteBold = const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black,
|
||||
),
|
||||
this.footnote = const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
this.captionBold = const TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
});
|
||||
|
||||
/// Initialise with dark theme
|
||||
TextTheme.dark({
|
||||
this.title = const TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
this.headlineBold = const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
this.headline = const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
this.bodyBold = const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
this.body = const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
this.footnoteBold = const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
this.footnote = const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.white,
|
||||
),
|
||||
this.captionBold = const TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
});
|
||||
|
||||
/// Text theme for title
|
||||
final TextStyle title;
|
||||
|
||||
/// Body Text theme for headline
|
||||
final TextStyle headlineBold;
|
||||
|
||||
/// Text theme for headline
|
||||
final TextStyle headline;
|
||||
|
||||
/// Bold Text theme for body
|
||||
final TextStyle bodyBold;
|
||||
|
||||
/// Text theme body
|
||||
final TextStyle body;
|
||||
|
||||
/// Bold Text theme for footnote
|
||||
final TextStyle footnoteBold;
|
||||
|
||||
/// Text theme for footnote
|
||||
final TextStyle footnote;
|
||||
|
||||
/// Bold Text theme for caption
|
||||
final TextStyle captionBold;
|
||||
|
||||
/// Copy with theme
|
||||
TextTheme copyWith({
|
||||
Brightness brightness = Brightness.light,
|
||||
TextStyle? body,
|
||||
TextStyle? title,
|
||||
TextStyle? headlineBold,
|
||||
TextStyle? headline,
|
||||
TextStyle? bodyBold,
|
||||
TextStyle? footnoteBold,
|
||||
TextStyle? footnote,
|
||||
TextStyle? captionBold,
|
||||
}) =>
|
||||
brightness == Brightness.light
|
||||
? TextTheme.light(
|
||||
body: body ?? this.body,
|
||||
title: title ?? this.title,
|
||||
headlineBold: headlineBold ?? this.headlineBold,
|
||||
headline: headline ?? this.headline,
|
||||
bodyBold: bodyBold ?? this.bodyBold,
|
||||
footnoteBold: footnoteBold ?? this.footnoteBold,
|
||||
footnote: footnote ?? this.footnote,
|
||||
captionBold: captionBold ?? this.captionBold,
|
||||
)
|
||||
: TextTheme.dark(
|
||||
body: body ?? this.body,
|
||||
title: title ?? this.title,
|
||||
headlineBold: headlineBold ?? this.headlineBold,
|
||||
headline: headline ?? this.headline,
|
||||
bodyBold: bodyBold ?? this.bodyBold,
|
||||
footnoteBold: footnoteBold ?? this.footnoteBold,
|
||||
footnote: footnote ?? this.footnote,
|
||||
captionBold: captionBold ?? this.captionBold,
|
||||
);
|
||||
|
||||
/// Merge text theme
|
||||
TextTheme merge(TextTheme? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
body: body.merge(other.body),
|
||||
title: title.merge(other.title),
|
||||
headlineBold: headlineBold.merge(other.headlineBold),
|
||||
headline: headline.merge(other.headline),
|
||||
bodyBold: bodyBold.merge(other.bodyBold),
|
||||
footnoteBold: footnoteBold.merge(other.footnoteBold),
|
||||
footnote: footnote.merge(other.footnote),
|
||||
captionBold: captionBold.merge(other.captionBold),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
export 'avatar_theme.dart';
|
||||
export 'channel_header_theme.dart';
|
||||
export 'channel_list_header_theme.dart';
|
||||
export 'channel_list_view_theme.dart';
|
||||
export 'channel_preview_theme.dart';
|
||||
export 'channel_theme.dart';
|
||||
export 'color_theme.dart';
|
||||
export 'gallery_footer_theme.dart';
|
||||
export 'gallery_header_theme.dart';
|
||||
export 'message_input_theme.dart';
|
||||
export 'message_list_view_theme.dart';
|
||||
export 'message_search_list_view_theme.dart';
|
||||
export 'message_theme.dart';
|
||||
export 'text_theme.dart';
|
||||
export 'user_list_view_theme.dart';
|
||||
@@ -0,0 +1,111 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
/// Overrides the default style of [UserListView] descendants.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [UserListViewThemeData], which is used to configure this theme.
|
||||
class UserListViewTheme extends InheritedTheme {
|
||||
/// Creates a [UserListViewTheme].
|
||||
///
|
||||
/// The [data] parameter must not be null.
|
||||
const UserListViewTheme({
|
||||
Key? key,
|
||||
required this.data,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
/// The configuration of this theme.
|
||||
final UserListViewThemeData data;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// If there is no enclosing [UserListViewTheme] widget, then
|
||||
/// [StreamChatThemeData.userListViewTheme] is used.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// UserListViewTheme theme = UserListViewTheme.of(context);
|
||||
/// ```
|
||||
static UserListViewThemeData of(BuildContext context) {
|
||||
final userListViewTheme =
|
||||
context.dependOnInheritedWidgetOfExactType<UserListViewTheme>();
|
||||
return userListViewTheme?.data ??
|
||||
StreamChatTheme.of(context).userListViewTheme;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrap(BuildContext context, Widget child) =>
|
||||
UserListViewTheme(data: data, child: child);
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(UserListViewTheme oldWidget) =>
|
||||
data != oldWidget.data;
|
||||
}
|
||||
|
||||
/// A style that overrides the default appearance of [UserListView]s when
|
||||
/// used with [UserListViewTheme] or with the overall [StreamChatTheme]'s
|
||||
/// [StreamChatThemeData.userListViewTheme].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [UserListViewTheme], the theme which is configured with this class.
|
||||
/// * [StreamChatThemeData.userListViewTheme], which can be used to override
|
||||
/// the default style for [UserListView]s below the overall
|
||||
/// [StreamChatTheme].
|
||||
class UserListViewThemeData with Diagnosticable {
|
||||
/// Creates a [UserListViewThemeData].
|
||||
const UserListViewThemeData({
|
||||
this.backgroundColor,
|
||||
});
|
||||
|
||||
/// The color of the [ChannelListView] background.
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// Copies this [ChannelListViewThemeData] to another.
|
||||
UserListViewThemeData copyWith({
|
||||
Color? backgroundColor,
|
||||
}) =>
|
||||
UserListViewThemeData(
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
);
|
||||
|
||||
/// Linearly interpolate between two [UserListViewThemeData] themes.
|
||||
///
|
||||
/// All the properties must be non-null.
|
||||
UserListViewThemeData lerp(
|
||||
UserListViewThemeData a,
|
||||
UserListViewThemeData b,
|
||||
double t,
|
||||
) =>
|
||||
UserListViewThemeData(
|
||||
backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
|
||||
);
|
||||
|
||||
/// Merges one [UserListViewThemeData] with another.
|
||||
UserListViewThemeData merge(UserListViewThemeData? other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
backgroundColor: other.backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is UserListViewThemeData &&
|
||||
runtimeType == other.runtimeType &&
|
||||
backgroundColor == other.backgroundColor;
|
||||
|
||||
@override
|
||||
int get hashCode => backgroundColor.hashCode;
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(ColorProperty('backgroundColor', backgroundColor));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/themes.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ export 'src/stream_chat_theme.dart';
|
||||
export 'src/stream_neumorphic_button.dart';
|
||||
export 'src/stream_svg_icon.dart';
|
||||
export 'src/system_message.dart';
|
||||
export 'src/theme/themes.dart';
|
||||
export 'src/thread_header.dart';
|
||||
export 'src/typing_indicator.dart';
|
||||
export 'src/unread_indicator.dart';
|
||||
|
||||
Reference in New Issue
Block a user