chore(repo): remove deprecated code.
Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
@@ -1,510 +0,0 @@
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
|
||||
import 'package:collection/collection.dart'
|
||||
show IterableExtension, ListEquality;
|
||||
import 'package:contextmenu/contextmenu.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/context_menu_items/stream_chat_context_menu_item.dart';
|
||||
import 'package:stream_chat_flutter/src/dialogs/dialogs.dart';
|
||||
import 'package:stream_chat_flutter/src/message_widget/sending_indicator_builder.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
/// {@template channelPreview}
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// Shows a preview for the current [Channel].
|
||||
///
|
||||
/// Uses a [StreamBuilder] to render the channel information image as soon as
|
||||
/// it updates.
|
||||
///
|
||||
/// It is not recommended to use this widget directly as it is the
|
||||
/// default channel preview widget used by [ChannelListView].
|
||||
///
|
||||
/// The UI is rendered based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget's appearance.
|
||||
/// {@endtemplate}
|
||||
@Deprecated('Use StreamChannelListTile instead.')
|
||||
class ChannelPreview extends StatelessWidget {
|
||||
/// {@macro channelPreview}
|
||||
const ChannelPreview({
|
||||
required this.channel,
|
||||
super.key,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.onViewInfoTap,
|
||||
this.onImageTap,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.leading,
|
||||
this.sendingIndicator,
|
||||
this.trailing,
|
||||
});
|
||||
|
||||
/// The action to perform when this widget is tapped or clicked.
|
||||
final void Function(Channel)? onTap;
|
||||
|
||||
/// The action to perform when this widget is long pressed.
|
||||
final void Function(Channel)? onLongPress;
|
||||
|
||||
/// The action to perform when 'View Info' is tapped or clicked.
|
||||
final ViewInfoCallback? onViewInfoTap;
|
||||
|
||||
/// The [Channel] being previewed.
|
||||
final Channel channel;
|
||||
|
||||
/// The action to perform when the image is tapped
|
||||
final VoidCallback? onImageTap;
|
||||
|
||||
/// Widget rendering the title
|
||||
final Widget? title;
|
||||
|
||||
/// Widget rendering the subtitle
|
||||
final Widget? subtitle;
|
||||
|
||||
/// Widget rendering the leading element. By default it shows the
|
||||
/// [StreamChannelAvatar].
|
||||
final Widget? leading;
|
||||
|
||||
/// Widget rendering the trailing element. By default it shows the date of
|
||||
/// the last message.
|
||||
final Widget? trailing;
|
||||
|
||||
/// Widget rendering the sending indicator. By default it uses the
|
||||
/// [StreamSendingIndicator] widget.
|
||||
final Widget? sendingIndicator;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final channelPreviewTheme = StreamChannelPreviewTheme.of(context);
|
||||
final streamChatState = StreamChat.of(context);
|
||||
final streamChatTheme = StreamChatTheme.of(context);
|
||||
return BetterStreamBuilder<bool>(
|
||||
stream: channel.isMutedStream,
|
||||
initialData: channel.isMuted,
|
||||
builder: (context, data) => AnimatedOpacity(
|
||||
opacity: data ? 0.5 : 1,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (context) => [
|
||||
StreamChatContextMenuItem(
|
||||
leading: StreamSvgIcon.user(
|
||||
color: Colors.grey,
|
||||
),
|
||||
title: Text(context.translations.viewInfoLabel),
|
||||
onClick: () {
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
if (onViewInfoTap != null) {
|
||||
onViewInfoTap?.call(channel);
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => ChannelInfoDialog(
|
||||
channel: channel,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
StreamChatContextMenuItem(
|
||||
leading: StreamSvgIcon.mute(
|
||||
color: Colors.grey,
|
||||
),
|
||||
title: channel.isGroup
|
||||
? Text(
|
||||
context.translations
|
||||
.toggleMuteUnmuteGroupText(isMuted: channel.isMuted),
|
||||
)
|
||||
: Text(
|
||||
context.translations
|
||||
.toggleMuteUnmuteUserText(isMuted: channel.isMuted),
|
||||
),
|
||||
onClick: () async {
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => ConfirmationDialog(
|
||||
titleText: channel.isGroup
|
||||
? context.translations
|
||||
.toggleMuteUnmuteGroupText(isMuted: channel.isMuted)
|
||||
: context.translations
|
||||
.toggleMuteUnmuteUserText(isMuted: channel.isMuted),
|
||||
promptText: channel.isGroup
|
||||
? context.translations.toggleMuteUnmuteGroupQuestion(
|
||||
isMuted: channel.isMuted,
|
||||
)
|
||||
: context.translations.toggleMuteUnmuteUserQuestion(
|
||||
isMuted: channel.isMuted,
|
||||
),
|
||||
affirmativeText: context.translations
|
||||
.toggleMuteUnmuteAction(isMuted: channel.isMuted),
|
||||
onConfirmation: () async {
|
||||
try {
|
||||
if (channel.isMuted) {
|
||||
await channel.unmute();
|
||||
} else {
|
||||
await channel.mute();
|
||||
}
|
||||
} catch (e) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => MessageDialog(
|
||||
messageText: e.toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (channel.isGroup)
|
||||
StreamChatContextMenuItem(
|
||||
leading: StreamSvgIcon.userRemove(
|
||||
color: Colors.red,
|
||||
),
|
||||
title: Text(
|
||||
context.translations.leaveGroupLabel,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
onClick: () {
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => ConfirmationDialog(
|
||||
titleText: context.translations.leaveGroupLabel,
|
||||
promptText:
|
||||
context.translations.leaveConversationQuestion,
|
||||
affirmativeText: context.translations.leaveLabel,
|
||||
onConfirmation: () async {
|
||||
final userAsMember = channel.state?.members.firstWhere(
|
||||
(e) =>
|
||||
e.user?.id ==
|
||||
StreamChat.of(context).currentUser?.id,
|
||||
);
|
||||
try {
|
||||
await channel.removeMembers([userAsMember!.user!.id]);
|
||||
} catch (e) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => MessageDialog(
|
||||
messageText: e.toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (!channel.isGroup)
|
||||
StreamChatContextMenuItem(
|
||||
leading: StreamSvgIcon.delete(
|
||||
color: Colors.red,
|
||||
),
|
||||
title: Text(
|
||||
context.translations.deleteConversationLabel,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
onClick: () {
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => ConfirmationDialog(
|
||||
titleText: context.translations.deleteConversationLabel,
|
||||
promptText:
|
||||
context.translations.deleteConversationQuestion,
|
||||
affirmativeText: context.translations.deleteLabel,
|
||||
onConfirmation: () async {
|
||||
try {
|
||||
await channel.delete();
|
||||
} catch (e) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => MessageDialog(
|
||||
messageText: e.toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
child: ListTile(
|
||||
visualDensity: VisualDensity.compact,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
onTap: () => onTap?.call(channel),
|
||||
onLongPress: () => onLongPress?.call(channel),
|
||||
leading: leading ??
|
||||
StreamChannelAvatar(
|
||||
onTap: onImageTap,
|
||||
channel: channel,
|
||||
),
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: title ??
|
||||
ChannelName(
|
||||
textStyle: channelPreviewTheme.titleStyle,
|
||||
),
|
||||
),
|
||||
BetterStreamBuilder<List<Member>>(
|
||||
stream: channel.state?.membersStream,
|
||||
initialData: channel.state?.members,
|
||||
comparator: const ListEquality().equals,
|
||||
builder: (context, members) {
|
||||
if (members.isEmpty ||
|
||||
!members.any((Member e) =>
|
||||
e.user!.id ==
|
||||
channel.client.state.currentUser?.id)) {
|
||||
return const SizedBox();
|
||||
}
|
||||
return StreamUnreadIndicator(
|
||||
cid: channel.cid,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
subtitle: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Flexible(child: subtitle ?? _Subtitle(channel: channel)),
|
||||
sendingIndicator ??
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final lastMessage =
|
||||
channel.state?.messages.lastWhereOrNull(
|
||||
(m) => !m.isDeleted && !m.shadowed,
|
||||
);
|
||||
if (lastMessage?.user?.id ==
|
||||
streamChatState.currentUser?.id) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 4),
|
||||
child: BetterStreamBuilder<List<Read>>(
|
||||
stream: channel.state?.readStream,
|
||||
initialData: channel.state?.read,
|
||||
builder: (context, data) {
|
||||
final hasNonUrlAttachments = lastMessage!
|
||||
.attachments
|
||||
.where((it) =>
|
||||
it.titleLink == null ||
|
||||
it.type == 'giphy')
|
||||
.isNotEmpty;
|
||||
|
||||
return SendingIndicatorBuilder(
|
||||
messageTheme: streamChatTheme.ownMessageTheme,
|
||||
message: lastMessage,
|
||||
hasNonUrlAttachments: hasNonUrlAttachments,
|
||||
streamChat: streamChatState,
|
||||
streamChatTheme: streamChatTheme,
|
||||
channel: channel,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
},
|
||||
),
|
||||
trailing ?? _Date(channel: channel),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Date extends StatelessWidget {
|
||||
const _Date({
|
||||
required this.channel,
|
||||
});
|
||||
|
||||
final Channel channel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BetterStreamBuilder<DateTime>(
|
||||
stream: channel.lastMessageAtStream,
|
||||
initialData: channel.lastMessageAt,
|
||||
builder: (context, data) {
|
||||
final lastMessageAt = data.toLocal();
|
||||
|
||||
String stringDate;
|
||||
final now = DateTime.now();
|
||||
|
||||
final startOfDay = DateTime(now.year, now.month, now.day);
|
||||
|
||||
if (lastMessageAt.millisecondsSinceEpoch >=
|
||||
startOfDay.millisecondsSinceEpoch) {
|
||||
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).jm;
|
||||
} else if (lastMessageAt.millisecondsSinceEpoch >=
|
||||
startOfDay
|
||||
.subtract(const Duration(days: 1))
|
||||
.millisecondsSinceEpoch) {
|
||||
stringDate = context.translations.yesterdayLabel;
|
||||
} else if (startOfDay.difference(lastMessageAt).inDays < 7) {
|
||||
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).EEEE;
|
||||
} else {
|
||||
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).yMd;
|
||||
}
|
||||
|
||||
return Text(
|
||||
stringDate,
|
||||
style: StreamChannelPreviewTheme.of(context).lastMessageAtStyle,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Subtitle extends StatelessWidget {
|
||||
const _Subtitle({
|
||||
required this.channel,
|
||||
});
|
||||
|
||||
final Channel channel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final channelPreviewTheme = StreamChannelPreviewTheme.of(context);
|
||||
if (channel.isMuted) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
StreamSvgIcon.mute(
|
||||
size: 16,
|
||||
),
|
||||
Text(
|
||||
' ${context.translations.channelIsMutedText}',
|
||||
style: channelPreviewTheme.subtitleStyle,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return StreamTypingIndicator(
|
||||
channel: channel,
|
||||
alternativeWidget: _LastMessage(
|
||||
channel: channel,
|
||||
),
|
||||
style: channelPreviewTheme.subtitleStyle,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _LastMessage extends StatelessWidget {
|
||||
const _LastMessage({
|
||||
required this.channel,
|
||||
});
|
||||
|
||||
final Channel channel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: BetterStreamBuilder<List<Message>>(
|
||||
stream: channel.state!.messagesStream,
|
||||
initialData: channel.state!.messages,
|
||||
builder: (context, data) {
|
||||
final lastMessage =
|
||||
data.lastWhereOrNull((m) => !m.shadowed && !m.isDeleted);
|
||||
if (lastMessage == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
var text = lastMessage.text;
|
||||
final parts = <String>[
|
||||
...lastMessage.attachments.map((e) {
|
||||
if (e.type == 'image') {
|
||||
return '📷';
|
||||
} else if (e.type == 'video') {
|
||||
return '🎬';
|
||||
} else if (e.type == 'giphy') {
|
||||
return '[GIF]';
|
||||
}
|
||||
return e == lastMessage.attachments.last
|
||||
? (e.title ?? 'File')
|
||||
: '${e.title ?? 'File'} , ';
|
||||
}),
|
||||
lastMessage.text ?? '',
|
||||
];
|
||||
|
||||
text = parts.join(' ');
|
||||
|
||||
final channelPreviewTheme = StreamChannelPreviewTheme.of(context);
|
||||
return Text.rich(
|
||||
_getDisplayText(
|
||||
text,
|
||||
lastMessage.mentionedUsers,
|
||||
lastMessage.attachments,
|
||||
channelPreviewTheme.subtitleStyle?.copyWith(
|
||||
color: channelPreviewTheme.subtitleStyle?.color,
|
||||
fontStyle: (lastMessage.isSystem || lastMessage.isDeleted)
|
||||
? FontStyle.italic
|
||||
: FontStyle.normal,
|
||||
),
|
||||
channelPreviewTheme.subtitleStyle?.copyWith(
|
||||
color: channelPreviewTheme.subtitleStyle?.color,
|
||||
fontStyle: (lastMessage.isSystem || lastMessage.isDeleted)
|
||||
? FontStyle.italic
|
||||
: FontStyle.normal,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.start,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TextSpan _getDisplayText(
|
||||
String text,
|
||||
List<User> mentions,
|
||||
List<Attachment> attachments,
|
||||
TextStyle? normalTextStyle,
|
||||
TextStyle? mentionsTextStyle,
|
||||
) {
|
||||
final textList = text.split(' ');
|
||||
final resList = <TextSpan>[];
|
||||
for (final e in textList) {
|
||||
if (mentions.isNotEmpty &&
|
||||
mentions.any((element) => '@${element.name}' == e)) {
|
||||
resList.add(TextSpan(
|
||||
text: '$e ',
|
||||
style: mentionsTextStyle,
|
||||
));
|
||||
} else if (attachments.isNotEmpty &&
|
||||
attachments
|
||||
.where((e) => e.title != null)
|
||||
.any((element) => element.title == e)) {
|
||||
resList.add(TextSpan(
|
||||
text: '$e ',
|
||||
style: normalTextStyle?.copyWith(fontStyle: FontStyle.italic),
|
||||
));
|
||||
} else {
|
||||
resList.add(TextSpan(
|
||||
text: e == textList.last ? e : '$e ',
|
||||
style: normalTextStyle,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return TextSpan(children: resList);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user