lint
This commit is contained in:
@@ -2,7 +2,10 @@ import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
/// Displays a list of users who reacted
|
||||
class UserReactionDisplay extends StatelessWidget {
|
||||
|
||||
/// Constructor for creating a [UserReactionDisplay]
|
||||
const UserReactionDisplay({
|
||||
Key? key,
|
||||
required this.reactionToEmoji,
|
||||
@@ -10,13 +13,17 @@ class UserReactionDisplay extends StatelessWidget {
|
||||
this.size = 30,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Reaction map
|
||||
final Map<String, String> reactionToEmoji;
|
||||
|
||||
/// Message which is reacted to
|
||||
final Message message;
|
||||
|
||||
/// Size of Icon
|
||||
final double size;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
Widget build(BuildContext context) => Container(
|
||||
color: Colors.black87,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -25,9 +32,8 @@ class UserReactionDisplay extends StatelessWidget {
|
||||
children: reactionToEmoji.keys.map((reactionType) {
|
||||
final firstUserReaction = message.latestReactions!
|
||||
.firstWhere((element) => element.type == reactionType,
|
||||
orElse: () {
|
||||
return null;
|
||||
} as Reaction Function()?);
|
||||
//ignore: unnecessary_parenthesis
|
||||
orElse: (() => null) as Reaction Function()?);
|
||||
|
||||
if (firstUserReaction.user == null) {
|
||||
return IconButton(
|
||||
@@ -52,5 +58,4 @@ class UserReactionDisplay extends StatelessWidget {
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ Future<void> launchURL(BuildContext context, String? url) async {
|
||||
} else {
|
||||
// ignore: deprecated_member_use
|
||||
Scaffold.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Cannot launch the url'),
|
||||
),
|
||||
);
|
||||
@@ -27,11 +27,10 @@ Future<bool?> showConfirmationDialog(
|
||||
Widget? icon,
|
||||
String? question,
|
||||
String? cancelText,
|
||||
}) {
|
||||
return showModalBottomSheet(
|
||||
}) => showModalBottomSheet(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.white,
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
@@ -42,20 +41,20 @@ Future<bool?> showConfirmationDialog(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 26),
|
||||
const SizedBox(height: 26),
|
||||
if (icon != null) icon,
|
||||
SizedBox(height: 26),
|
||||
const SizedBox(height: 26),
|
||||
Text(
|
||||
title,
|
||||
style: StreamChatTheme.of(context).textTheme.headlineBold,
|
||||
),
|
||||
SizedBox(height: 7),
|
||||
const SizedBox(height: 7),
|
||||
if (question != null)
|
||||
Text(
|
||||
question,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 36),
|
||||
const SizedBox(height: 36),
|
||||
Container(
|
||||
color: effect.color!.withOpacity(effect.alpha ?? 1),
|
||||
height: 1,
|
||||
@@ -110,8 +109,8 @@ Future<bool?> showConfirmationDialog(
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Shows info dialog
|
||||
Future<bool?> showInfoDialog(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
@@ -119,26 +118,24 @@ Future<bool?> showInfoDialog(
|
||||
Widget? icon,
|
||||
String? details,
|
||||
StreamChatThemeData? theme,
|
||||
}) {
|
||||
return showModalBottomSheet(
|
||||
}) => showModalBottomSheet(
|
||||
backgroundColor:
|
||||
theme?.colorTheme.white ?? StreamChatTheme.of(context).colorTheme.white,
|
||||
context: context,
|
||||
shape: RoundedRectangleBorder(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
)),
|
||||
builder: (context) {
|
||||
return SafeArea(
|
||||
builder: (context) => SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 26,
|
||||
),
|
||||
if (icon != null) icon,
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 26,
|
||||
),
|
||||
Text(
|
||||
@@ -146,11 +143,11 @@ Future<bool?> showInfoDialog(
|
||||
style: theme?.textTheme.headlineBold ??
|
||||
StreamChatTheme.of(context).textTheme.headlineBold,
|
||||
),
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 7,
|
||||
),
|
||||
if (details != null) Text(details),
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 36,
|
||||
),
|
||||
Container(
|
||||
@@ -175,10 +172,8 @@ Future<bool?> showInfoDialog(
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Get random png with initials
|
||||
String getRandomPicUrl(User user) =>
|
||||
@@ -335,15 +330,16 @@ StreamSvgIcon getFileTypeImage(String? type) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps attachment widget with custom shape
|
||||
Widget wrapAttachmentWidget(
|
||||
BuildContext context,
|
||||
Widget attachmentWidget,
|
||||
ShapeBorder attachmentShape,
|
||||
// ignore: avoid_positional_boolean_parameters
|
||||
bool reverse,
|
||||
BorderRadius borderRadius,
|
||||
) {
|
||||
return ClipRRect(
|
||||
borderRadius: borderRadius,
|
||||
) => ClipRRect(
|
||||
borderRadius: borderRadius,
|
||||
child: Material(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: attachmentShape,
|
||||
@@ -355,4 +351,3 @@ Widget wrapAttachmentWidget(
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,14 @@ import 'package:synchronized/synchronized.dart';
|
||||
import 'package:video_compress/video_compress.dart';
|
||||
import 'package:video_thumbnail/video_thumbnail.dart';
|
||||
|
||||
///
|
||||
class IVideoService {
|
||||
IVideoService._();
|
||||
|
||||
/// Singleton instance of [IVideoService]
|
||||
static final IVideoService instance = IVideoService._();
|
||||
final _lock = Lock();
|
||||
|
||||
IVideoService._();
|
||||
|
||||
/// compress video from [path]
|
||||
/// compress video from [path] return [Future<MediaInfo>]
|
||||
///
|
||||
@@ -26,18 +28,20 @@ class IVideoService {
|
||||
/// );
|
||||
/// debugPrint(info.toJson());
|
||||
/// ```
|
||||
Future<MediaInfo?> compressVideo(String? path) async {
|
||||
return _lock.synchronized(() {
|
||||
return VideoCompress.compressVideo(
|
||||
path!,
|
||||
Future<MediaInfo?> compressVideo(String? path) async => _lock.synchronized(
|
||||
() => VideoCompress.compressVideo(
|
||||
path!,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Generates a thumbnail image data in memory as UInt8List, it can be easily used by Image.memory(...).
|
||||
/// The video can be a local video file, or an URL repreents iOS or Android native supported video format.
|
||||
/// Speicify the maximum height or width for the thumbnail or 0 for same resolution as the original video.
|
||||
/// The lower quality value creates lower quality of the thumbnail image, but it gets ignored for PNG format.
|
||||
/// Generates a thumbnail image data in memory as UInt8List,
|
||||
/// it can be easily used by Image.memory(...).
|
||||
/// The video can be a local video file, or an URL repreents iOS or
|
||||
/// Android native supported video format.
|
||||
/// Speicify the maximum height or width for the thumbnail or 0 for
|
||||
/// same resolution as the original video.
|
||||
/// The lower quality value creates lower quality of the thumbnail image,
|
||||
/// but it gets ignored for PNG format.
|
||||
Future<Uint8List?> generateVideoThumbnail({
|
||||
required String video,
|
||||
ImageFormat imageFormat = ImageFormat.PNG,
|
||||
@@ -45,17 +49,17 @@ class IVideoService {
|
||||
int maxWidth = 0,
|
||||
int timeMs = 0,
|
||||
int quality = 10,
|
||||
}) {
|
||||
return VideoThumbnail.thumbnailData(
|
||||
video: video,
|
||||
imageFormat: imageFormat,
|
||||
maxHeight: maxHeight,
|
||||
maxWidth: maxWidth,
|
||||
timeMs: timeMs,
|
||||
quality: quality,
|
||||
);
|
||||
}
|
||||
}) =>
|
||||
VideoThumbnail.thumbnailData(
|
||||
video: video,
|
||||
imageFormat: imageFormat,
|
||||
maxHeight: maxHeight,
|
||||
maxWidth: maxWidth,
|
||||
timeMs: timeMs,
|
||||
quality: quality,
|
||||
);
|
||||
}
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
/// Get instance of [IVideoService]
|
||||
IVideoService get VideoService => IVideoService.instance;
|
||||
|
||||
@@ -9,14 +9,7 @@ import 'stream_svg_icon.dart';
|
||||
import 'video_service.dart';
|
||||
|
||||
class VideoThumbnailImage extends StatefulWidget {
|
||||
final String video;
|
||||
final double? width;
|
||||
final double? height;
|
||||
final BoxFit? fit;
|
||||
final ImageFormat format;
|
||||
final Widget Function(BuildContext, Object?)? errorBuilder;
|
||||
final WidgetBuilder? placeholderBuilder;
|
||||
|
||||
/// Constructor for creating [VideoThumbnailImage]
|
||||
const VideoThumbnailImage({
|
||||
Key? key,
|
||||
required this.video,
|
||||
@@ -28,6 +21,25 @@ class VideoThumbnailImage extends StatefulWidget {
|
||||
this.placeholderBuilder,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Video path
|
||||
final String video;
|
||||
|
||||
/// Width of widget
|
||||
final double? width;
|
||||
|
||||
/// Height of widget
|
||||
final double? height;
|
||||
|
||||
/// Fit of iamge
|
||||
final BoxFit? fit;
|
||||
|
||||
/// Image format
|
||||
final ImageFormat format;
|
||||
|
||||
/// Builds widget on error
|
||||
final Widget Function(BuildContext, Object?)? errorBuilder;
|
||||
final WidgetBuilder? placeholderBuilder;
|
||||
|
||||
@override
|
||||
_VideoThumbnailImageState createState() => _VideoThumbnailImageState();
|
||||
}
|
||||
@@ -56,11 +68,9 @@ class _VideoThumbnailImageState extends State<VideoThumbnailImage> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<Uint8List?>(
|
||||
Widget build(BuildContext context) => FutureBuilder<Uint8List?>(
|
||||
future: thumbnailFuture,
|
||||
builder: (context, snapshot) {
|
||||
return AnimatedSwitcher(
|
||||
builder: (context, snapshot) => AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
child: Builder(
|
||||
key: ValueKey<AsyncSnapshot<Uint8List?>>(snapshot),
|
||||
@@ -73,7 +83,7 @@ class _VideoThumbnailImageState extends State<VideoThumbnailImage> {
|
||||
}
|
||||
if (!snapshot.hasData) {
|
||||
return Container(
|
||||
constraints: BoxConstraints.expand(),
|
||||
constraints: const BoxConstraints.expand(),
|
||||
child: widget.placeholderBuilder?.call(context) ??
|
||||
Shimmer.fromColors(
|
||||
baseColor: StreamChatTheme.of(context)
|
||||
@@ -97,8 +107,6 @@ class _VideoThumbnailImageState extends State<VideoThumbnailImage> {
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user