diff --git a/packages/chatty/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/chatty/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/packages/chatty/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/chatty/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/chatty/lib/data/auth_repository.dart b/packages/chatty/lib/data/auth_repository.dart index 2ac77e8..db5849e 100644 --- a/packages/chatty/lib/data/auth_repository.dart +++ b/packages/chatty/lib/data/auth_repository.dart @@ -1,7 +1,7 @@ import 'package:stream_chatter/domain/models/auth_user.dart'; abstract class AuthRepository { - Future getAuthUser(); + Future getAuthUser(); Future signIn(); Future logout(); } diff --git a/packages/chatty/lib/data/image_picker_repository.dart b/packages/chatty/lib/data/image_picker_repository.dart index f5632f0..08d7ab8 100644 --- a/packages/chatty/lib/data/image_picker_repository.dart +++ b/packages/chatty/lib/data/image_picker_repository.dart @@ -1,5 +1,5 @@ import 'dart:io'; abstract class ImagePickerRepository { - Future pickImage(); + Future pickImage(); } diff --git a/packages/chatty/lib/data/local/image_picker_impl.dart b/packages/chatty/lib/data/local/image_picker_impl.dart index 90c63e0..2bd82dd 100644 --- a/packages/chatty/lib/data/local/image_picker_impl.dart +++ b/packages/chatty/lib/data/local/image_picker_impl.dart @@ -4,10 +4,17 @@ import 'package:stream_chatter/data/image_picker_repository.dart'; class ImagePickerImpl extends ImagePickerRepository { @override - Future pickImage() async { + Future pickImage() async { final picker = ImagePicker(); - final pickedFile = - await picker.getImage(source: ImageSource.gallery, maxWidth: 400); + final pickedFile = await picker.getImage( + source: ImageSource.gallery, + maxWidth: 400, + ); + + if (pickedFile == null) { + return null; + } + return File(pickedFile.path); } } diff --git a/packages/chatty/lib/data/local/stream_api_local_impl.dart b/packages/chatty/lib/data/local/stream_api_local_impl.dart index a2d2e35..8337c92 100644 --- a/packages/chatty/lib/data/local/stream_api_local_impl.dart +++ b/packages/chatty/lib/data/local/stream_api_local_impl.dart @@ -8,7 +8,7 @@ class StreamApiLocalImpl extends StreamApiRepository { final StreamChatClient _client; @override - Future connectUser(ChatUser user, String token) async { + Future connectUser(ChatUser user, String? token) async { Map extraData = {}; if (user.image != null) { extraData['image'] = user.image; @@ -18,7 +18,7 @@ class StreamApiLocalImpl extends StreamApiRepository { } await _client.disconnect(); await _client.connectUser( - User(id: user.id, extraData: extraData), + User(id: user.id!, extraData: extraData as Map), token, ); return user; @@ -28,12 +28,12 @@ class StreamApiLocalImpl extends StreamApiRepository { Future> getChatUsers() async { final result = await _client.queryUsers(); final chatUsers = result.users - .where((element) => element.id != _client.state.user.id) + .where((element) => element.id != _client.state.user!.id) .map( (e) => ChatUser( id: e.id, name: e.name, - image: e.extraData['image'], + image: e.extraData['image'] as String?, ), ) .toList(); @@ -47,25 +47,25 @@ class StreamApiLocalImpl extends StreamApiRepository { @override Future createGroupChat( - String channelId, String name, List members, - {String image}) async { + String channelId, String? name, List? members, + {String? image}) async { final channel = _client.channel('messaging', id: channelId, extraData: { - 'name': name, - 'image': image, - 'members': [_client.state.user.id, ...members], + 'name': name!, + 'image': image!, + 'members': [_client.state.user!.id, ...members!], }); await channel.watch(); return channel; } @override - Future createSimpleChat(String friendId) async { + Future createSimpleChat(String? friendId) async { final channel = _client.channel('messaging', - id: '${_client.state.user.id.hashCode}${friendId.hashCode}', + id: '${_client.state.user!.id.hashCode}${friendId.hashCode}', extraData: { 'members': [ friendId, - _client.state.user.id, + _client.state.user!.id, ], }); await channel.watch(); @@ -84,6 +84,6 @@ class StreamApiLocalImpl extends StreamApiRepository { User(id: userId), token, ); - return _client.state.user.name != null && _client.state.user.name != userId; + return _client.state.user!.name != null && _client.state.user!.name != userId; } } diff --git a/packages/chatty/lib/data/local/upload_storage_local_impl.dart b/packages/chatty/lib/data/local/upload_storage_local_impl.dart index 8a3b804..a1b0f63 100644 --- a/packages/chatty/lib/data/local/upload_storage_local_impl.dart +++ b/packages/chatty/lib/data/local/upload_storage_local_impl.dart @@ -4,7 +4,7 @@ import 'package:stream_chatter/data/upload_storage_repository.dart'; class UploadStorageLocalImpl extends UploadStorageRepository { @override - Future uploadPhoto(File file, String path) async { + Future uploadPhoto(File? file, String path) async { return 'https://lh3.googleusercontent.com/a-/AOh14GjhqGZ-V7tNXS1pOIp9vbBij4OS9JbzxXgxgy1t=s600-k-no-rp-mo'; } } diff --git a/packages/chatty/lib/data/prod/auth_impl.dart b/packages/chatty/lib/data/prod/auth_impl.dart index 71bb3c6..cc8e139 100644 --- a/packages/chatty/lib/data/prod/auth_impl.dart +++ b/packages/chatty/lib/data/prod/auth_impl.dart @@ -7,7 +7,7 @@ class AuthImpl extends AuthRepository { FirebaseAuth _auth = FirebaseAuth.instance; @override - Future getAuthUser() async { + Future getAuthUser() async { final user = _auth.currentUser; if (user != null) { return AuthUser(user.uid); @@ -19,16 +19,21 @@ class AuthImpl extends AuthRepository { Future signIn() async { try { UserCredential userCredential; - final GoogleSignInAccount googleUser = await GoogleSignIn().signIn(); + final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn(); + + if (googleUser == null) { + throw Exception('login error'); + } + final GoogleSignInAuthentication googleAuth = await googleUser.authentication; final GoogleAuthCredential googleAuthCredential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, - ); + ) as GoogleAuthCredential; userCredential = await _auth.signInWithCredential(googleAuthCredential); - final user = userCredential.user; + final user = userCredential.user!; return AuthUser(user.uid); } catch (e) { print(e); diff --git a/packages/chatty/lib/data/prod/persistent_storage_impl.dart b/packages/chatty/lib/data/prod/persistent_storage_impl.dart index 5d247d5..d701846 100644 --- a/packages/chatty/lib/data/prod/persistent_storage_impl.dart +++ b/packages/chatty/lib/data/prod/persistent_storage_impl.dart @@ -13,6 +13,6 @@ class PersistentStorageImpl extends PersistentStorageRepository { @override Future updateDarkMode(bool isDarkMode) async { final preference = await SharedPreferences.getInstance(); - return await preference.setBool(_isDarkMode, isDarkMode); + await preference.setBool(_isDarkMode, isDarkMode); } } diff --git a/packages/chatty/lib/data/prod/stream_api_impl.dart b/packages/chatty/lib/data/prod/stream_api_impl.dart index a60cd1c..877e210 100644 --- a/packages/chatty/lib/data/prod/stream_api_impl.dart +++ b/packages/chatty/lib/data/prod/stream_api_impl.dart @@ -11,7 +11,7 @@ class StreamApiImpl extends StreamApiRepository { final StreamChatClient _client; @override - Future connectUser(ChatUser user, String token) async { + Future connectUser(ChatUser user, String? token) async { Map extraData = {}; if (user.image != null) { extraData['image'] = user.image; @@ -21,7 +21,7 @@ class StreamApiImpl extends StreamApiRepository { } await _client.disconnect(); await _client.connectUser( - User(id: user.id, extraData: extraData), + User(id: user.id!, extraData: extraData as Map), token, ); return user; @@ -31,12 +31,12 @@ class StreamApiImpl extends StreamApiRepository { Future> getChatUsers() async { final result = await _client.queryUsers(); final chatUsers = result.users - .where((element) => element.id != _client.state.user.id) + .where((element) => element.id != _client.state.user!.id) .map( (e) => ChatUser( id: e.id, name: e.name, - image: e.extraData['image'], + image: e.extraData['image'] as String?, ), ) .toList(); @@ -44,10 +44,10 @@ class StreamApiImpl extends StreamApiRepository { } @override - Future getToken(String userId) async { + Future getToken(String userId) async { //TODO: use your own implementation in Production final response = await http.post( - 'your_backend_url', + Uri.parse('your_backend_url'), body: jsonEncode({'id': userId}), headers: { 'Content-Type': 'application/json; charset=UTF-8', @@ -62,25 +62,25 @@ class StreamApiImpl extends StreamApiRepository { } @override - Future createGroupChat(String id, String name, List members, - {String image}) async { + Future createGroupChat(String id, String? name, List? members, + {String? image}) async { final channel = _client.channel('messaging', id: id, extraData: { - 'name': name, - 'image': image, - 'members': [_client.state.user.id, ...members], + 'name': name!, + 'image': image!, + 'members': [_client.state.user!.id, ...members!], }); await channel.watch(); return channel; } @override - Future createSimpleChat(String friendId) async { + Future createSimpleChat(String? friendId) async { final channel = _client.channel('messaging', - id: '${_client.state.user.id.hashCode}${friendId.hashCode}', + id: '${_client.state.user!.id.hashCode}${friendId.hashCode}', extraData: { 'members': [ friendId, - _client.state.user.id, + _client.state.user!.id, ], }); await channel.watch(); @@ -99,6 +99,6 @@ class StreamApiImpl extends StreamApiRepository { User(id: userId), token, ); - return _client.state.user.name != null && _client.state.user.name != userId; + return _client.state.user!.name != null && _client.state.user!.name != userId; } } diff --git a/packages/chatty/lib/data/prod/upload_storage_impl.dart b/packages/chatty/lib/data/prod/upload_storage_impl.dart index 37f6830..a476f43 100644 --- a/packages/chatty/lib/data/prod/upload_storage_impl.dart +++ b/packages/chatty/lib/data/prod/upload_storage_impl.dart @@ -4,9 +4,9 @@ import 'package:stream_chatter/data/upload_storage_repository.dart'; class UploadStorageImpl extends UploadStorageRepository { @override - Future uploadPhoto(File file, String path) async { + Future uploadPhoto(File? file, String path) async { final ref = firebase_storage.FirebaseStorage.instance.ref(path); - final uploadTask = ref.putFile(file); + final uploadTask = ref.putFile(file!); await uploadTask; return await ref.getDownloadURL(); } diff --git a/packages/chatty/lib/data/stream_api_repository.dart b/packages/chatty/lib/data/stream_api_repository.dart index 3d5c215..b722932 100644 --- a/packages/chatty/lib/data/stream_api_repository.dart +++ b/packages/chatty/lib/data/stream_api_repository.dart @@ -3,12 +3,12 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; abstract class StreamApiRepository { Future> getChatUsers(); - Future getToken(String userId); + Future getToken(String userId); Future connectIfExist(String userId); - Future connectUser(ChatUser user, String token); + Future connectUser(ChatUser user, String? token); Future createGroupChat( - String channelId, String name, List members, - {String image}); - Future createSimpleChat(String friendId); + String channelId, String? name, List? members, + {String? image}); + Future createSimpleChat(String? friendId); Future logout(); } diff --git a/packages/chatty/lib/data/upload_storage_repository.dart b/packages/chatty/lib/data/upload_storage_repository.dart index 6876138..88590ee 100644 --- a/packages/chatty/lib/data/upload_storage_repository.dart +++ b/packages/chatty/lib/data/upload_storage_repository.dart @@ -1,5 +1,5 @@ import 'dart:io'; abstract class UploadStorageRepository { - Future uploadPhoto(File file, String path); + Future uploadPhoto(File? file, String path); } diff --git a/packages/chatty/lib/domain/models/chat_user.dart b/packages/chatty/lib/domain/models/chat_user.dart index 05a0a61..9ad376b 100644 --- a/packages/chatty/lib/domain/models/chat_user.dart +++ b/packages/chatty/lib/domain/models/chat_user.dart @@ -1,6 +1,6 @@ class ChatUser { const ChatUser({this.name, this.image, this.id}); - final String name; - final String image; - final String id; + final String? name; + final String? image; + final String? id; } diff --git a/packages/chatty/lib/domain/usecases/create_group_usecase.dart b/packages/chatty/lib/domain/usecases/create_group_usecase.dart index 0e19d80..4b0dc78 100644 --- a/packages/chatty/lib/domain/usecases/create_group_usecase.dart +++ b/packages/chatty/lib/domain/usecases/create_group_usecase.dart @@ -7,9 +7,9 @@ import 'package:uuid/uuid.dart'; class CreateGroupInput { CreateGroupInput({this.imageFile, this.name, this.members}); - final File imageFile; - final String name; - final List members; + final File? imageFile; + final String? name; + final List? members; } class CreateGroupUseCase { @@ -23,7 +23,7 @@ class CreateGroupUseCase { Future createGroup(CreateGroupInput input) async { final channelId = Uuid().v4(); - String image; + String? image; if (input.imageFile != null) { image = await _uploadStorageRepository.uploadPhoto( input.imageFile, 'channels/$channelId'); diff --git a/packages/chatty/lib/domain/usecases/profile_sign_in_usecase.dart b/packages/chatty/lib/domain/usecases/profile_sign_in_usecase.dart index 1c18918..19969d6 100644 --- a/packages/chatty/lib/domain/usecases/profile_sign_in_usecase.dart +++ b/packages/chatty/lib/domain/usecases/profile_sign_in_usecase.dart @@ -5,10 +5,12 @@ import 'package:stream_chatter/data/stream_api_repository.dart'; import 'package:stream_chatter/data/upload_storage_repository.dart'; import 'package:stream_chatter/domain/models/chat_user.dart'; +import '../exceptions/auth_exception.dart'; + class ProfileInput { ProfileInput({this.imageFile, this.name}); - final File imageFile; - final String name; + final File? imageFile; + final String? name; } class ProfileSignInUseCase { @@ -24,13 +26,21 @@ class ProfileSignInUseCase { Future verify(ProfileInput input) async { final auth = await _authRepository.getAuthUser(); + if (auth == null) { + throw AuthException(AuthErrorCode.not_auth); + } final token = await _streamApiRepository.getToken(auth.id); - String image; + String? image; if (input.imageFile != null) { image = await _uploadStorageRepository.uploadPhoto( input.imageFile, 'users/${auth.id}'); } await _streamApiRepository.connectUser( - ChatUser(name: input.name, id: auth.id, image: image), token); + ChatUser( + name: input.name, + id: auth.id, + image: image, + ), + token); } } diff --git a/packages/chatty/lib/ui/common/avatar_image_view.dart b/packages/chatty/lib/ui/common/avatar_image_view.dart index 76ee22a..08a2fbf 100644 --- a/packages/chatty/lib/ui/common/avatar_image_view.dart +++ b/packages/chatty/lib/ui/common/avatar_image_view.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; class AvatarImageView extends StatelessWidget { - const AvatarImageView({Key key, this.onTap, this.child}) : super(key: key); - final Widget child; - final VoidCallback onTap; + const AvatarImageView({Key? key, this.onTap, this.child}) : super(key: key); + final Widget? child; + final VoidCallback? onTap; @override Widget build(BuildContext context) { diff --git a/packages/chatty/lib/ui/common/loading_view.dart b/packages/chatty/lib/ui/common/loading_view.dart index 9e1cded..6ff3f12 100644 --- a/packages/chatty/lib/ui/common/loading_view.dart +++ b/packages/chatty/lib/ui/common/loading_view.dart @@ -5,8 +5,8 @@ class LoadingView extends StatelessWidget { final Widget child; const LoadingView({ - Key key, - @required this.child, + Key? key, + required this.child, this.isLoading = false, }) : super(key: key); diff --git a/packages/chatty/lib/ui/common/my_channel_preview.dart b/packages/chatty/lib/ui/common/my_channel_preview.dart index 8886b47..cd2417f 100644 --- a/packages/chatty/lib/ui/common/my_channel_preview.dart +++ b/packages/chatty/lib/ui/common/my_channel_preview.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart' show IterableExtension; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:jiffy/jiffy.dart'; @@ -30,22 +31,22 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// Modify it to change the widget appearance. class MyChannelPreview extends StatelessWidget { /// Function called when tapping this widget - final void Function(Channel) onTap; + final void Function(Channel)? onTap; /// Function called when long pressing this widget - final void Function(Channel) onLongPress; + final void Function(Channel)? onLongPress; /// Channel displayed final Channel channel; /// The function called when the image is tapped - final VoidCallback onImageTap; + final VoidCallback? onImageTap; - final String heroTag; + final String? heroTag; MyChannelPreview({ - @required this.channel, - Key key, + required this.channel, + Key? key, this.onTap, this.onLongPress, this.onImageTap, @@ -59,24 +60,24 @@ class MyChannelPreview extends StatelessWidget { initialData: channel.isMuted, builder: (context, snapshot) { return Opacity( - opacity: snapshot.data ? 0.5 : 1, + opacity: snapshot.data! ? 0.5 : 1, child: ListTile( contentPadding: const EdgeInsets.symmetric( horizontal: 8, ), onTap: () { if (onTap != null) { - onTap(channel); + onTap!(channel); } }, onLongPress: () { if (onLongPress != null) { - onLongPress(channel); + onLongPress!(channel); } }, leading: Material( child: Hero( - tag: heroTag, + tag: heroTag!, child: StreamChannel( channel: channel, child: ChannelImage( @@ -95,13 +96,13 @@ class MyChannelPreview extends StatelessWidget { ), ), StreamBuilder>( - stream: channel.state.membersStream, - initialData: channel.state.members, + stream: channel.state!.membersStream, + initialData: channel.state!.members, builder: (context, snapshot) { if (!snapshot.hasData || - snapshot.data.isEmpty || - !snapshot.data.any((Member e) => - e.user.id == channel.client.state.user.id)) { + snapshot.data!.isEmpty || + !snapshot.data!.any((Member e) => + e.user!.id == channel.client.state.user!.id)) { return SizedBox(); } return ChannelUnreadIndicator( @@ -116,26 +117,26 @@ class MyChannelPreview extends StatelessWidget { Flexible(child: _buildSubtitle(context)), Builder( builder: (context) { - final lastMessage = channel.state.messages.lastWhere( + final lastMessage = + channel.state!.messages.lastWhereOrNull( (m) => !m.isDeleted && m.shadowed != true, - orElse: () => null, ); if (lastMessage?.user?.id == - StreamChat.of(context).user.id) { + StreamChat.of(context).user!.id) { return Padding( padding: const EdgeInsets.only(right: 4.0), child: SendingIndicator( - message: lastMessage, + message: lastMessage!, size: StreamChatTheme.of(context) .channelPreviewTheme .indicatorIconSize, - isMessageRead: channel.state.read + isMessageRead: channel.state!.read ?.where((element) => element.user.id != - channel.client.state.user.id) - ?.where((element) => element.lastRead + channel.client.state.user!.id) + .where((element) => element.lastRead .isAfter(lastMessage.createdAt)) - ?.isNotEmpty == + .isNotEmpty == true, ), ); @@ -152,14 +153,14 @@ class MyChannelPreview extends StatelessWidget { } Widget _buildDate(BuildContext context) { - return StreamBuilder( + return StreamBuilder( stream: channel.lastMessageAtStream, initialData: channel.lastMessageAt, builder: (context, snapshot) { if (!snapshot.hasData) { return SizedBox(); } - final lastMessageAt = snapshot.data.toLocal(); + final lastMessageAt = snapshot.data!.toLocal(); String stringDate; final now = DateTime.now(); @@ -198,11 +199,11 @@ class MyChannelPreview extends StatelessWidget { ' Channel is muted', style: StreamChatTheme.of(context) .channelPreviewTheme - .subtitle + .subtitle! .copyWith( color: StreamChatTheme.of(context) .channelPreviewTheme - .subtitle + .subtitle! .color, ), ), @@ -212,21 +213,20 @@ class MyChannelPreview extends StatelessWidget { return TypingIndicator( channel: channel, alternativeWidget: _buildLastMessage(context), - style: StreamChatTheme.of(context).channelPreviewTheme.subtitle.copyWith( + style: StreamChatTheme.of(context).channelPreviewTheme.subtitle!.copyWith( color: - StreamChatTheme.of(context).channelPreviewTheme.subtitle.color, + StreamChatTheme.of(context).channelPreviewTheme.subtitle!.color, ), ); } Widget _buildLastMessage(BuildContext context) { - return StreamBuilder>( - stream: channel.state.messagesStream, - initialData: channel.state.messages, + return StreamBuilder?>( + stream: channel.state!.messagesStream, + initialData: channel.state!.messages, builder: (context, snapshot) { - final lastMessage = snapshot.data?.lastWhere( - (m) => m.shadowed != true && !m.isDeleted, - orElse: () => null); + final lastMessage = snapshot.data + ?.lastWhereOrNull((m) => m.shadowed != true && !m.isDeleted); if (lastMessage == null) { return SizedBox(); } @@ -254,21 +254,21 @@ class MyChannelPreview extends StatelessWidget { return Text.rich( _getDisplayText( - text, + text!, lastMessage.mentionedUsers, lastMessage.attachments, - StreamChatTheme.of(context).channelPreviewTheme.subtitle.copyWith( + StreamChatTheme.of(context).channelPreviewTheme.subtitle!.copyWith( color: StreamChatTheme.of(context) .channelPreviewTheme - .subtitle + .subtitle! .color, fontStyle: (lastMessage.isSystem || lastMessage.isDeleted) ? FontStyle.italic : FontStyle.normal), - StreamChatTheme.of(context).channelPreviewTheme.subtitle.copyWith( + StreamChatTheme.of(context).channelPreviewTheme.subtitle!.copyWith( color: StreamChatTheme.of(context) .channelPreviewTheme - .subtitle + .subtitle! .color, fontStyle: (lastMessage.isSystem || lastMessage.isDeleted) ? FontStyle.italic @@ -321,8 +321,8 @@ class MyChannelPreview extends StatelessWidget { class ChannelUnreadIndicator extends StatelessWidget { const ChannelUnreadIndicator({ - Key key, - @required this.channel, + Key? key, + required this.channel, }) : super(key: key); final Channel channel; @@ -330,8 +330,8 @@ class ChannelUnreadIndicator extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder( - stream: channel.state.unreadCountStream, - initialData: channel.state.unreadCount, + stream: channel.state!.unreadCountStream, + initialData: channel.state!.unreadCount, builder: (context, snapshot) { if (!snapshot.hasData || snapshot.data == 0) { return SizedBox(); @@ -351,7 +351,7 @@ class ChannelUnreadIndicator extends StatelessWidget { ), child: Center( child: Text( - '${snapshot.data > 99 ? '99+' : snapshot.data}', + '${snapshot.data! > 99 ? '99+' : snapshot.data}', style: TextStyle( fontSize: 11, color: Colors.white, diff --git a/packages/chatty/lib/ui/home/chat/chat_view.dart b/packages/chatty/lib/ui/home/chat/chat_view.dart index 5267162..0bed83a 100644 --- a/packages/chatty/lib/ui/home/chat/chat_view.dart +++ b/packages/chatty/lib/ui/home/chat/chat_view.dart @@ -23,11 +23,10 @@ class ChatView extends StatelessWidget { ), body: ChannelsBloc( child: ChannelListView( - filter: { - 'members': { - '\$in': [StreamChat.of(context).user?.id], - } - }, + filter: Filter.in_( + 'members', + [StreamChat.of(context).user!.id], + ), sort: [SortOption('last_message_at')], channelPreviewBuilder: (context, channel) { return Container( @@ -36,22 +35,22 @@ class ChatView extends StatelessWidget { channel: channel, heroTag: channel.id, onImageTap: () { - String name; - String image; + String? name; + String? image; final currentUser = StreamChat.of(context).client.state.user; if (channel.isGroup) { name = channel.extraData['name']; image = channel.extraData['image']; } else { - final friend = channel.state.members - .where((element) => element.userId != currentUser.id) + final friend = channel.state!.members + .where((element) => element.userId != currentUser!.id) .first - .user; + .user!; name = friend.name; - image = friend.extraData['image']; + image = friend.extraData['image'] as String?; } - return Navigator.of(context).push( + Navigator.of(context).push( PageRouteBuilder( barrierColor: Colors.black45, barrierDismissible: true, @@ -110,15 +109,15 @@ class ChannelPage extends StatelessWidget { class ChatDetailView extends StatelessWidget { const ChatDetailView({ - Key key, + Key? key, this.image, this.name, this.channelId, }) : super(key: key); - final String image; - final String name; - final String channelId; + final String? image; + final String? name; + final String? channelId; @override Widget build(BuildContext context) { @@ -135,10 +134,10 @@ class ChatDetailView extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Hero( - tag: channelId, + tag: channelId!, child: ClipOval( child: Image.network( - image, + image!, height: 180, width: 180, fit: BoxFit.cover, @@ -146,7 +145,7 @@ class ChatDetailView extends StatelessWidget { ), ), Text( - name, + name!, style: TextStyle( fontWeight: FontWeight.w700, fontSize: 22, diff --git a/packages/chatty/lib/ui/home/chat/selection/friends_selection_view.dart b/packages/chatty/lib/ui/home/chat/selection/friends_selection_view.dart index d7c0d1f..3fdb50b 100644 --- a/packages/chatty/lib/ui/home/chat/selection/friends_selection_view.dart +++ b/packages/chatty/lib/ui/home/chat/selection/friends_selection_view.dart @@ -143,9 +143,9 @@ class FriendsSelectionView extends StatelessWidget { CircleAvatar( radius: 30, backgroundImage: NetworkImage( - chatUserState.chatUser.image), + chatUserState.chatUser.image!), ), - Text(chatUserState.chatUser.name), + Text(chatUserState.chatUser.name!), ], ), Positioned( @@ -178,9 +178,9 @@ class FriendsSelectionView extends StatelessWidget { }, leading: CircleAvatar( backgroundImage: - NetworkImage(chatUserState.chatUser.image), + NetworkImage(chatUserState.chatUser.image!), ), - title: Text(chatUserState.chatUser.name), + title: Text(chatUserState.chatUser.name!), trailing: isGroup ? Checkbox( value: chatUserState.selected, diff --git a/packages/chatty/lib/ui/home/chat/selection/group_selection_cubit.dart b/packages/chatty/lib/ui/home/chat/selection/group_selection_cubit.dart index 79ac5eb..db72b1a 100644 --- a/packages/chatty/lib/ui/home/chat/selection/group_selection_cubit.dart +++ b/packages/chatty/lib/ui/home/chat/selection/group_selection_cubit.dart @@ -13,8 +13,8 @@ class GroupSelectionState { this.channel, this.isLoading = false, }); - final File file; - final Channel channel; + final File? file; + final Channel? channel; final bool isLoading; } diff --git a/packages/chatty/lib/ui/home/chat/selection/group_selection_view.dart b/packages/chatty/lib/ui/home/chat/selection/group_selection_view.dart index 70c100b..42f65e5 100644 --- a/packages/chatty/lib/ui/home/chat/selection/group_selection_view.dart +++ b/packages/chatty/lib/ui/home/chat/selection/group_selection_view.dart @@ -28,7 +28,7 @@ class GroupSelectionView extends StatelessWidget { context, Scaffold( body: StreamChannel( - channel: snapshot.channel, + channel: snapshot.channel!, child: ChannelPage(), ), ), @@ -60,9 +60,9 @@ class GroupSelectionView extends StatelessWidget { children: [ AvatarImageView( onTap: context.read().pickImage, - child: snapshot?.file != null + child: snapshot.file != null ? Image.file( - snapshot?.file, + snapshot.file!, fit: BoxFit.cover, ) : Icon( @@ -104,9 +104,9 @@ class GroupSelectionView extends StatelessWidget { CircleAvatar( radius: 30, backgroundImage: - NetworkImage(chatUserState.chatUser.image), + NetworkImage(chatUserState.chatUser.image!), ), - Text(chatUserState.chatUser.name), + Text(chatUserState.chatUser.name!), ], ), ); diff --git a/packages/chatty/lib/ui/home/home_view.dart b/packages/chatty/lib/ui/home/home_view.dart index 5d30d87..0492889 100644 --- a/packages/chatty/lib/ui/home/home_view.dart +++ b/packages/chatty/lib/ui/home/home_view.dart @@ -36,7 +36,7 @@ class HomeView extends StatelessWidget { class HomeNavigationBar extends StatelessWidget { const HomeNavigationBar({ - Key key, + Key? key, }) : super(key: key); @override @@ -110,16 +110,16 @@ class HomeNavigationBar extends StatelessWidget { class _HomeNavItem extends StatelessWidget { const _HomeNavItem({ - Key key, + Key? key, this.iconData, this.text, this.onTap, this.selected = false, }) : super(key: key); - final IconData iconData; - final String text; - final VoidCallback onTap; + final IconData? iconData; + final String? text; + final VoidCallback? onTap; final bool selected; @override @@ -135,7 +135,7 @@ class _HomeNavItem extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Icon(iconData, color: color), - Text(text, style: TextStyle(color: color)), + Text(text!, style: TextStyle(color: color)), ], ), ); diff --git a/packages/chatty/lib/ui/home/settings/settings_view.dart b/packages/chatty/lib/ui/home/settings/settings_view.dart index 17020ff..4347749 100644 --- a/packages/chatty/lib/ui/home/settings/settings_view.dart +++ b/packages/chatty/lib/ui/home/settings/settings_view.dart @@ -10,8 +10,8 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class SettingsView extends StatelessWidget { @override Widget build(BuildContext context) { - final user = StreamChat.of(context).client.state.user; - final image = user?.extraData['image']; + final user = StreamChat.of(context).client.state.user!; + final image = user.extraData['image']; final textColor = Theme.of(context).appBarTheme.color; return MultiBlocProvider( providers: [ @@ -48,7 +48,7 @@ class SettingsView extends StatelessWidget { onTap: () => null, child: image != null ? Image.network( - image, + image as String, fit: BoxFit.cover, ) : Icon( diff --git a/packages/chatty/lib/ui/profile_verify/profile_verify_cubit.dart b/packages/chatty/lib/ui/profile_verify/profile_verify_cubit.dart index 2593f36..0dd4824 100644 --- a/packages/chatty/lib/ui/profile_verify/profile_verify_cubit.dart +++ b/packages/chatty/lib/ui/profile_verify/profile_verify_cubit.dart @@ -11,7 +11,7 @@ class ProfileState { this.success = false, this.loading = false, }); - final File file; + final File? file; final bool success; final bool loading; } diff --git a/packages/chatty/lib/ui/profile_verify/profile_verify_view.dart b/packages/chatty/lib/ui/profile_verify/profile_verify_view.dart index 4000202..6b6c2bd 100644 --- a/packages/chatty/lib/ui/profile_verify/profile_verify_view.dart +++ b/packages/chatty/lib/ui/profile_verify/profile_verify_view.dart @@ -39,7 +39,7 @@ class ProfileVerifyView extends StatelessWidget { onTap: context.read().pickImage, child: snapshot.file != null ? Image.file( - snapshot.file, + snapshot.file!, fit: BoxFit.cover, ) : Icon( diff --git a/packages/chatty/pubspec.yaml b/packages/chatty/pubspec.yaml index 6327bfd..c0f4552 100644 --- a/packages/chatty/pubspec.yaml +++ b/packages/chatty/pubspec.yaml @@ -4,22 +4,23 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: sdk: flutter - flutter_bloc: 6.1.2 - stream_chat_flutter: 1.3.0-beta - uuid: 2.2.2 + flutter_bloc: ^7.0.0 + stream_chat_flutter: ^2.0.0-nullsafety.3 + uuid: ^3.0.4 - firebase_core: 0.7.0 - google_sign_in: 4.5.9 - firebase_auth: 0.20.0+1 - firebase_storage: 7.0.0 - shared_preferences: 0.5.12+4 + firebase_core: ^1.2.0 + google_sign_in: ^5.0.3 + firebase_auth: ^1.2.0 + firebase_storage: ^8.1.0 + shared_preferences: ^2.0.5 http: any + collection: ^1.15.0-nullsafety.4 dev_dependencies: flutter_test: