This commit is contained in:
Deven Joshi
2021-05-05 19:07:32 +05:30
parent 9b09874df1
commit 0590fe1a76
19 changed files with 68 additions and 70 deletions
@@ -67,6 +67,7 @@ class AttachmentError extends StatelessWidget {
this.size, this.size,
}) : super(key: key); }) : super(key: key);
/// Size of error
final Size? size; final Size? size;
@override @override
@@ -6,10 +6,12 @@ import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
import 'package:stream_chat_flutter/src/utils.dart'; import 'package:stream_chat_flutter/src/utils.dart';
import 'package:stream_chat_flutter/src/video_thumbnail_image.dart'; import 'package:stream_chat_flutter/src/video_thumbnail_image.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import 'package:stream_chat_flutter/src/upload_progress_indicator.dart';
import '../upload_progress_indicator.dart'; // ignore: always_use_package_imports
import 'attachment_widget.dart'; import 'attachment_widget.dart';
/// Widget for displaying file attachments
class FileAttachment extends AttachmentWidget { class FileAttachment extends AttachmentWidget {
/// Constructor for creating a widget when attachment is of type 'file' /// Constructor for creating a widget when attachment is of type 'file'
const FileAttachment({ const FileAttachment({
@@ -5,9 +5,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:stream_chat_flutter/src/extension.dart';
import '../stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'extension.dart';
/// Callback to download an attachment asset /// Callback to download an attachment asset
typedef AttachmentDownloader = Future<String> Function( typedef AttachmentDownloader = Future<String> Function(
@@ -17,6 +16,16 @@ typedef AttachmentDownloader = Future<String> Function(
/// Widget that shows the options in the gallery view /// Widget that shows the options in the gallery view
class AttachmentActionsModal extends StatelessWidget { class AttachmentActionsModal extends StatelessWidget {
/// Returns a new [AttachmentActionsModal]
const AttachmentActionsModal({
Key? key,
required this.currentIndex,
required this.message,
this.onShowMessage,
this.imageDownloader,
this.fileDownloader,
}) : super(key: key);
/// The message containing the attachments /// The message containing the attachments
final Message message; final Message message;
@@ -32,15 +41,6 @@ class AttachmentActionsModal extends StatelessWidget {
/// Callback to provide download files /// Callback to provide download files
final AttachmentDownloader? fileDownloader; final AttachmentDownloader? fileDownloader;
/// Returns a new [AttachmentActionsModal]
const AttachmentActionsModal({
required this.currentIndex,
required this.message,
this.onShowMessage,
this.imageDownloader,
this.fileDownloader,
});
@override @override
Widget build(BuildContext context) => GestureDetector( Widget build(BuildContext context) => GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
@@ -62,7 +62,7 @@ class AttachmentActionsModal extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Container( child: SizedBox(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -89,6 +89,7 @@ class AttachmentActionsModal extends StatelessWidget {
), ),
_buildButton( _buildButton(
context, context,
// ignore: lines_longer_than_80_chars
'Save ${message.attachments[currentIndex].type == 'video' ? 'Video' : 'Image'}', 'Save ${message.attachments[currentIndex].type == 'video' ? 'Video' : 'Image'}',
StreamSvgIcon.iconSave( StreamSvgIcon.iconSave(
size: 24, size: 24,
@@ -203,7 +204,7 @@ class AttachmentActionsModal extends StatelessWidget {
child: Row( child: Row(
children: [ children: [
icon, icon,
SizedBox(width: 16), const SizedBox(width: 16),
Text( Text(
title, title,
style: StreamChatTheme.of(context) style: StreamChatTheme.of(context)
@@ -253,7 +254,7 @@ class AttachmentActionsModal extends StatelessWidget {
) )
: progress.toProgressIndicatorValue == 1.0 : progress.toProgressIndicatorValue == 1.0
? SizedBox( ? SizedBox(
key: Key('completedIcon'), key: const Key('completedIcon'),
height: 160, height: 160,
width: 160, width: 160,
child: StreamSvgIcon.check( child: StreamSvgIcon.check(
@@ -314,14 +315,13 @@ class AttachmentActionsModal extends StatelessWidget {
} }
class _DownloadProgress { class _DownloadProgress {
final int total;
final int received;
const _DownloadProgress(this.total, this.received); const _DownloadProgress(this.total, this.received);
factory _DownloadProgress.initial() { factory _DownloadProgress.initial() =>
return _DownloadProgress(double.maxFinite.toInt(), 0); _DownloadProgress(double.maxFinite.toInt(), 0);
}
final int total;
final int received;
double get toProgressIndicatorValue => received / total; double get toProgressIndicatorValue => received / total;
@@ -196,7 +196,7 @@ class ChannelImage extends StatelessWidget {
); );
if (selected) { if (selected) {
child = ClipRRect( child = ClipRRect(
key: Key('selectedImage'), key: const Key('selectedImage'),
borderRadius: (borderRadius ?? borderRadius: (borderRadius ??
StreamChatTheme.of(context) StreamChatTheme.of(context)
.ownMessageTheme .ownMessageTheme
@@ -3,9 +3,9 @@ import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart'; import 'package:jiffy/jiffy.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'connection_status_builder.dart'; /// Widget which shows channel info
class ChannelInfo extends StatelessWidget { class ChannelInfo extends StatelessWidget {
/// Constructor which creates a [ChannelInfo] widget
const ChannelInfo({ const ChannelInfo({
Key? key, Key? key,
required this.channel, required this.channel,
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
/// This widget is used for showing user tiles for mentions /// This widget is used for showing user tiles for mentions
/// Use [title], [subtitle], [leading], [trailing] for /// Use [title], [subtitle], [leading], [trailing] for
@@ -4,8 +4,6 @@ import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import '../stream_chat_flutter.dart';
/// Text widget to display in message /// Text widget to display in message
class MessageText extends StatelessWidget { class MessageText extends StatelessWidget {
/// Constructor for creating a [MessageText] widget /// Constructor for creating a [MessageText] widget
@@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import 'user_item.dart';
/// Callback called when tapping on a user /// Callback called when tapping on a user
typedef UserTapCallback = void Function(User, Widget?); typedef UserTapCallback = void Function(User, Widget?);
@@ -3,10 +3,9 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import '../stream_chat_flutter.dart'; /// Launch URL
import 'stream_svg_icon.dart';
Future<void> launchURL(BuildContext context, String? url) async { Future<void> launchURL(BuildContext context, String? url) async {
if (url != null && await canLaunch(url)) { if (url != null && await canLaunch(url)) {
await launch(url); await launch(url);
@@ -20,6 +19,7 @@ Future<void> launchURL(BuildContext context, String? url) async {
} }
} }
/// Shows confirmation dialog
Future<bool?> showConfirmationDialog( Future<bool?> showConfirmationDialog(
BuildContext context, { BuildContext context, {
required String title, required String title,
@@ -60,6 +60,6 @@ class IVideoService {
); );
} }
// ignore: non_constant_identifier_names
/// Get instance of [IVideoService] /// Get instance of [IVideoService]
// ignore: non_constant_identifier_names
IVideoService get VideoService => IVideoService.instance; IVideoService get VideoService => IVideoService.instance;
+2 -2
View File
@@ -12,10 +12,10 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
stream_chat_flutter_core: ^2.0.0-nullsafety.0 stream_chat_flutter_core: ^2.0.0-nullsafety.0
photo_view: ^0.11.1
rxdart: ^0.26.0 rxdart: ^0.26.0
scrollable_positioned_list: ^0.2.0-nullsafety.0 scrollable_positioned_list: ^0.2.0-nullsafety.0
jiffy: ^4.1.0 jiffy: ^4.1.0
photo_view: ^0.11.1
flutter_svg: ^0.22.0 flutter_svg: ^0.22.0
flutter_portal: ^0.4.0 flutter_portal: ^0.4.0
cached_network_image: ^3.0.0 cached_network_image: ^3.0.0
@@ -57,6 +57,6 @@ dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
mocktail: ^0.1.2 mocktail: ^0.1.2
pedantic: ^1.11.0
golden_toolkit: ^0.9.0 golden_toolkit: ^0.9.0
pedantic: ^1.11.0
@@ -23,7 +23,8 @@ class MockAttachmentDownloader extends Mock {
void main() { void main() {
setUpAll(() { setUpAll(() {
registerFallbackValue(MaterialPageRoute(builder: (context) => SizedBox())); registerFallbackValue(
MaterialPageRoute(builder: (context) => const SizedBox()));
registerFallbackValue(Message()); registerFallbackValue(Message());
}); });
@@ -461,9 +462,9 @@ void main() {
MaterialApp( MaterialApp(
builder: (context, child) => StreamChat( builder: (context, child) => StreamChat(
client: client, client: client,
child: child!, child: child,
), ),
home: Container( home: SizedBox(
child: AttachmentActionsModal( child: AttachmentActionsModal(
fileDownloader: fileDownloader, fileDownloader: fileDownloader,
message: Message( message: Message(
@@ -19,7 +19,7 @@ void main() {
child: Center( child: Center(
child: StreamChatTheme( child: StreamChatTheme(
data: StreamChatThemeData.fromTheme(theme), data: StreamChatThemeData.fromTheme(theme),
child: StreamBackButton(), child: const StreamBackButton(),
), ),
), ),
), ),
@@ -26,7 +26,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size(100, 100), surfaceSize: const Size(100, 100),
); );
await screenMatchesGolden(tester, 'reaction_bubble_0'); await screenMatchesGolden(tester, 'reaction_bubble_0');
}, },
@@ -47,7 +47,7 @@ void main() {
StreamChat( StreamChat(
client: client, client: client,
streamChatThemeData: theme, streamChatThemeData: theme,
child: Container( child: SizedBox(
child: ReactionBubble( child: ReactionBubble(
reactions: [ reactions: [
Reaction( Reaction(
@@ -61,7 +61,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size(100, 100), surfaceSize: const Size(100, 100),
); );
await screenMatchesGolden(tester, 'reaction_bubble_like_light'); await screenMatchesGolden(tester, 'reaction_bubble_like_light');
}, },
@@ -97,7 +97,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size(100, 100), surfaceSize: const Size(100, 100),
); );
await screenMatchesGolden(tester, 'reaction_bubble_like_dark'); await screenMatchesGolden(tester, 'reaction_bubble_like_dark');
}, },
@@ -141,7 +141,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size(140, 140), surfaceSize: const Size(140, 140),
); );
await screenMatchesGolden(tester, 'reaction_bubble_3_light'); await screenMatchesGolden(tester, 'reaction_bubble_3_light');
}, },
@@ -185,7 +185,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size(140, 140), surfaceSize: const Size(140, 140),
); );
await screenMatchesGolden(tester, 'reaction_bubble_3_dark'); await screenMatchesGolden(tester, 'reaction_bubble_3_dark');
}, },
@@ -205,7 +205,7 @@ void main() {
StreamChat( StreamChat(
client: client, client: client,
streamChatThemeData: StreamChatThemeData.fromTheme(themeData), streamChatThemeData: StreamChatThemeData.fromTheme(themeData),
child: Container( child: SizedBox(
child: ReactionBubble( child: ReactionBubble(
reactions: [ reactions: [
Reaction( Reaction(
@@ -230,7 +230,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size(200, 200), surfaceSize: const Size(200, 200),
); );
await screenMatchesGolden(tester, 'reaction_bubble_2'); await screenMatchesGolden(tester, 'reaction_bubble_2');
@@ -1,19 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SimpleFrame extends StatelessWidget { class SimpleFrame extends StatelessWidget {
final Widget child;
const SimpleFrame({Key? key, required this.child}) : super(key: key); const SimpleFrame({Key? key, required this.child}) : super(key: key);
final Widget child;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => Container(
return Container( padding: const EdgeInsets.all(4),
padding: const EdgeInsets.all(4), decoration: BoxDecoration(
decoration: BoxDecoration( color: const Color(0xFFFFFFFF),
color: const Color(0xFFFFFFFF), border: Border.all(color: const Color(0xFF9E9E9E)),
border: Border.all(color: const Color(0xFF9E9E9E)), ),
), child: child,
child: child, );
);
}
} }
@@ -102,7 +102,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size.square(200), surfaceSize: const Size.square(200),
); );
await screenMatchesGolden(tester, 'system_message_light'); await screenMatchesGolden(tester, 'system_message_light');
@@ -153,7 +153,7 @@ void main() {
), ),
), ),
), ),
surfaceSize: Size.square(200), surfaceSize: const Size.square(200),
); );
await screenMatchesGolden(tester, 'system_message_dark'); await screenMatchesGolden(tester, 'system_message_dark');
@@ -117,13 +117,13 @@ void main() {
child: Scaffold( child: Scaffold(
body: ThreadHeader( body: ThreadHeader(
parent: Message(), parent: Message(),
subtitle: Text('subtitle'), subtitle: const Text('subtitle'),
leading: Text('leading'), leading: const Text('leading'),
title: Text('title'), title: const Text('title'),
onTitleTap: () { onTitleTap: () {
tapped = true; tapped = true;
}, },
actions: [ actions: const [
Text('action'), Text('action'),
], ],
), ),
@@ -67,14 +67,14 @@ void main() {
client: client, client: client,
child: StreamChannel( child: StreamChannel(
channel: channel, channel: channel,
child: Scaffold( child: const Scaffold(
body: TypingIndicator(), body: TypingIndicator(),
), ),
), ),
), ),
)); ));
expect(find.byKey(Key('typings')), findsOneWidget); expect(find.byKey(const Key('typings')), findsOneWidget);
}, },
); );
} }
@@ -36,7 +36,7 @@ void main() {
client: client, client: client,
child: StreamChannel( child: StreamChannel(
channel: channel, channel: channel,
child: Scaffold( child: const Scaffold(
body: UnreadIndicator(), body: UnreadIndicator(),
), ),
), ),