feat: onPressChatTitle

This commit is contained in:
Stein Milder 2022-11-22 11:41:09 +01:00
parent 5e53049a3e
commit 7fd38e3770
9 changed files with 210 additions and 175 deletions

View file

@ -4,146 +4,29 @@
library flutter_community_chat; library flutter_community_chat;
import 'dart:typed_data';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_community_chat/service/chat_service.dart';
import 'package:flutter_community_chat_interface/flutter_community_chat_interface.dart'; import 'package:flutter_community_chat_interface/flutter_community_chat_interface.dart';
import 'package:flutter_community_chat_view/flutter_community_chat_view.dart'; import 'package:flutter_community_chat_view/flutter_community_chat_view.dart';
import 'package:flutter_image_picker/flutter_image_picker.dart';
export 'package:flutter_community_chat_view/flutter_community_chat_view.dart'; export 'package:flutter_community_chat_view/flutter_community_chat_view.dart';
export 'package:flutter_community_chat/service/chat_service.dart';
export 'package:flutter_community_chat_interface/flutter_community_chat_interface.dart';
class CommunityChat extends StatefulWidget { class CommunityChat extends StatelessWidget {
const CommunityChat({ const CommunityChat({
required this.dataProvider, required this.chatService,
this.options = const ChatOptions(),
this.translations = const ChatTranslations(),
this.imagePickerTheme = const ImagePickerTheme(),
this.imagePickerConfig = const ImagePickerConfig(),
super.key, super.key,
}); });
final CommunityChatInterface dataProvider; final ChatService chatService;
final ChatOptions options;
final ChatTranslations translations;
final ImagePickerTheme imagePickerTheme;
final ImagePickerConfig imagePickerConfig;
@override
State<CommunityChat> createState() => _CommunityChatState();
}
class _CommunityChatState extends State<CommunityChat> {
bool _isFetchingUsers = false;
Future<void> _push(BuildContext context, Widget widget) =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => widget),
);
void _pop(BuildContext context) => Navigator.of(context).pop();
Future<void> _onPressStartChat(BuildContext context) async {
if (!_isFetchingUsers) {
_isFetchingUsers = true;
await widget.dataProvider.getChatUsers().then(
(users) {
_isFetchingUsers = false;
_push(
context,
NewChatScreen(
options: widget.options,
translations: widget.translations,
onPressCreateChat: (user) => _onPressChat(
context,
PersonalChatModel(user: user),
popBeforePush: true,
),
users: users,
),
);
},
);
}
}
Future<void> _onPressChat(
BuildContext context,
ChatModel chat, {
bool popBeforePush = false,
}) =>
widget.dataProvider.setChat(chat).then((_) {
if (popBeforePush) {
_pop(context);
}
_push(
context,
ChatDetailScreen(
options: widget.options,
translations: widget.translations,
chat: chat,
chatMessages: widget.dataProvider.getMessagesStream(),
onPressSelectImage: (ChatModel chat) =>
_onPressSelectImage(context, chat),
onMessageSubmit: (ChatModel chat, String content) =>
widget.dataProvider.sendTextMessage(content),
),
);
});
void _beforeUploadingImage() => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(minutes: 1),
content: Row(
children: [
const SizedBox(
width: 25,
height: 25,
child: CircularProgressIndicator(color: Colors.grey),
),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Text(widget.translations.imageUploading),
),
],
),
),
);
_afterUploadingImage() => ScaffoldMessenger.of(context).hideCurrentSnackBar();
Future<void> _onPressSelectImage(BuildContext context, ChatModel chat) =>
showModalBottomSheet<Uint8List?>(
context: context,
builder: (BuildContext context) =>
widget.options.imagePickerContainerBuilder(
ImagePicker(
customButton: widget.options.closeImagePickerButtonBuilder(
context,
() => Navigator.of(context).pop(),
widget.translations,
),
imagePickerTheme: widget.imagePickerTheme,
imagePickerConfig: widget.imagePickerConfig,
),
),
).then(
(image) async {
_beforeUploadingImage();
if (image != null) {
await widget.dataProvider.sendImageMessage(image);
}
_afterUploadingImage();
},
);
@override @override
Widget build(BuildContext context) => ChatScreen( Widget build(BuildContext context) => ChatScreen(
chats: widget.dataProvider.getChatsStream(), chats: chatService.dataProvider.getChatsStream(),
onPressStartChat: () => _onPressStartChat(context), onPressStartChat: () => chatService.onPressStartChat(context),
onPressChat: (chat) => _onPressChat(context, chat), onPressChat: (chat) => chatService.onPressChat(context, chat),
onDeleteChat: (ChatModel chat) => widget.dataProvider.deleteChat(chat), onDeleteChat: (ChatModel chat) => chatService.deleteChat(chat),
options: widget.options, options: chatService.options,
translations: widget.translations, translations: chatService.translations(context),
); );
} }

View file

@ -0,0 +1,127 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_community_chat/ui/components/image_loading_snackbar.dart';
import 'package:flutter_community_chat_interface/flutter_community_chat_interface.dart';
import 'package:flutter_community_chat_view/flutter_community_chat_view.dart';
import 'package:flutter_image_picker/flutter_image_picker.dart';
abstract class ChatService {
ChatService({
required this.options,
required this.imagePickerTheme,
required this.imagePickerConfig,
required this.dataProvider,
});
final CommunityChatInterface dataProvider;
final ChatOptions options;
final ImagePickerTheme imagePickerTheme;
final ImagePickerConfig imagePickerConfig;
bool _isFetchingUsers = false;
ChatTranslations translations(BuildContext buildContext);
Future<void> _push(BuildContext context, Widget widget) =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => widget),
);
void _pop(BuildContext context) => Navigator.of(context).pop();
Future<void> onPressStartChat(BuildContext context) async {
if (!_isFetchingUsers) {
_isFetchingUsers = true;
await dataProvider.getChatUsers().then(
(users) {
_isFetchingUsers = false;
_push(
context,
buildNewChatScreen(context, users),
);
},
);
}
}
Widget buildNewChatScreen(
BuildContext context,
List<ChatUserModel> users,
) =>
NewChatScreen(
options: options,
translations: translations(context),
onPressCreateChat: (user) => onPressChat(
context,
PersonalChatModel(user: user),
popBeforePush: true,
),
users: users,
);
Future<void> onPressChat(
BuildContext context,
ChatModel chat, {
bool popBeforePush = false,
}) =>
dataProvider.setChat(chat).then((_) {
if (popBeforePush) {
_pop(context);
}
_push(
context,
buildChatDetailScreen(context, chat),
);
});
Widget buildChatDetailScreen(
BuildContext context,
ChatModel chat,
) =>
ChatDetailScreen(
options: options,
translations: translations(context),
chat: chat,
chatMessages: dataProvider.getMessagesStream(),
onPressSelectImage: (ChatModel chat) => onPressSelectImage(
context,
chat,
),
onMessageSubmit: (ChatModel chat, String content) =>
dataProvider.sendTextMessage(content),
);
Future<void> onPressSelectImage(
BuildContext context,
ChatModel chat,
) =>
showModalBottomSheet<Uint8List?>(
context: context,
builder: (BuildContext context) => options.imagePickerContainerBuilder(
ImagePicker(
customButton: options.closeImagePickerButtonBuilder(
context,
() => Navigator.of(context).pop(),
translations(context),
),
),
),
).then(
(image) async {
var messenger = ScaffoldMessenger.of(context);
messenger.showSnackBar(
getImageLoadingSnackbar(
translations(context),
),
);
if (image != null) {
await dataProvider.sendImageMessage(image);
}
messenger.hideCurrentSnackBar();
},
);
Future<void> deleteChat(ChatModel chat) => dataProvider.deleteChat(chat);
}

View file

@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
import 'package:flutter_community_chat/flutter_community_chat.dart';
SnackBar getImageLoadingSnackbar(ChatTranslations translations) => SnackBar(
duration: const Duration(minutes: 1),
content: Row(
children: [
const SizedBox(
width: 25,
height: 25,
child: CircularProgressIndicator(color: Colors.grey),
),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Text(translations.imageUploading),
),
],
),
);

View file

@ -179,7 +179,7 @@ packages:
description: description:
path: "packages/flutter_community_chat_interface" path: "packages/flutter_community_chat_interface"
ref: HEAD ref: HEAD
resolved-ref: "09686cb451b5dc9c94e1088ce74dbee811064cdb" resolved-ref: "772764f84a2282f2f49de4a0910ae15024ceabd5"
url: "https://github.com/Iconica-Development/flutter_community_chat.git" url: "https://github.com/Iconica-Development/flutter_community_chat.git"
source: git source: git
version: "0.0.1" version: "0.0.1"
@ -188,7 +188,7 @@ packages:
description: description:
path: "packages/flutter_community_chat_view" path: "packages/flutter_community_chat_view"
ref: HEAD ref: HEAD
resolved-ref: "09686cb451b5dc9c94e1088ce74dbee811064cdb" resolved-ref: "772764f84a2282f2f49de4a0910ae15024ceabd5"
url: "https://github.com/Iconica-Development/flutter_community_chat.git" url: "https://github.com/Iconica-Development/flutter_community_chat.git"
source: git source: git
version: "0.0.1" version: "0.0.1"

View file

@ -14,7 +14,7 @@ packages:
name: _flutterfire_internals name: _flutterfire_internals
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.8" version: "1.0.9"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
@ -84,21 +84,21 @@ packages:
name: cloud_firestore name: cloud_firestore
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.5" version: "4.1.0"
cloud_firestore_platform_interface: cloud_firestore_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: cloud_firestore_platform_interface name: cloud_firestore_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.8.5" version: "5.9.0"
cloud_firestore_web: cloud_firestore_web:
dependency: transitive dependency: transitive
description: description:
name: cloud_firestore_web name: cloud_firestore_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.5" version: "3.1.0"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
@ -154,28 +154,28 @@ packages:
name: firebase_auth name: firebase_auth
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.2" version: "4.1.3"
firebase_auth_platform_interface: firebase_auth_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_auth_platform_interface name: firebase_auth_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.11.2" version: "6.11.3"
firebase_auth_web: firebase_auth_web:
dependency: transitive dependency: transitive
description: description:
name: firebase_auth_web name: firebase_auth_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.1.2" version: "5.1.3"
firebase_core: firebase_core:
dependency: "direct main" dependency: "direct main"
description: description:
name: firebase_core name: firebase_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.0" version: "2.3.0"
firebase_core_platform_interface: firebase_core_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -196,21 +196,21 @@ packages:
name: firebase_storage name: firebase_storage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "11.0.5" version: "11.0.6"
firebase_storage_platform_interface: firebase_storage_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_storage_platform_interface name: firebase_storage_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.23" version: "4.1.24"
firebase_storage_web: firebase_storage_web:
dependency: transitive dependency: transitive
description: description:
name: firebase_storage_web name: firebase_storage_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.3.15" version: "3.3.16"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@ -228,7 +228,7 @@ packages:
description: description:
path: "packages/flutter_community_chat_interface" path: "packages/flutter_community_chat_interface"
ref: HEAD ref: HEAD
resolved-ref: "09686cb451b5dc9c94e1088ce74dbee811064cdb" resolved-ref: "772764f84a2282f2f49de4a0910ae15024ceabd5"
url: "https://github.com/Iconica-Development/flutter_community_chat.git" url: "https://github.com/Iconica-Development/flutter_community_chat.git"
source: git source: git
version: "0.0.1" version: "0.0.1"

View file

@ -186,7 +186,7 @@ packages:
description: description:
path: "packages/flutter_community_chat_interface" path: "packages/flutter_community_chat_interface"
ref: HEAD ref: HEAD
resolved-ref: "09686cb451b5dc9c94e1088ce74dbee811064cdb" resolved-ref: "772764f84a2282f2f49de4a0910ae15024ceabd5"
url: "https://github.com/Iconica-Development/flutter_community_chat.git" url: "https://github.com/Iconica-Development/flutter_community_chat.git"
source: git source: git
version: "0.0.1" version: "0.0.1"

View file

@ -17,6 +17,7 @@ class ChatDetailScreen extends StatelessWidget {
this.translations = const ChatTranslations(), this.translations = const ChatTranslations(),
this.chatMessages, this.chatMessages,
this.onPressSelectImage, this.onPressSelectImage,
this.onPressChatTitle,
super.key, super.key,
}); });
@ -26,12 +27,16 @@ class ChatDetailScreen extends StatelessWidget {
final Stream<List<ChatMessageModel>>? chatMessages; final Stream<List<ChatMessageModel>>? chatMessages;
final Function(ChatModel)? onPressSelectImage; final Function(ChatModel)? onPressSelectImage;
final Future<void> Function(ChatModel chat, String text) onMessageSubmit; final Future<void> Function(ChatModel chat, String text) onMessageSubmit;
final Future<void> Function(ChatModel chat)? onPressChatTitle;
@override @override
Widget build(BuildContext context) => Scaffold( Widget build(BuildContext context) => Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: true, centerTitle: true,
title: Row( title: GestureDetector(
onTap: () =>
onPressChatTitle != null ? onPressChatTitle!(chat) : {},
child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (chat is PersonalChatModel) ...[ if (chat is PersonalChatModel) ...[
@ -67,6 +72,7 @@ class ChatDetailScreen extends StatelessWidget {
], ],
), ),
), ),
),
body: Column( body: Column(
children: [ children: [
Expanded( Expanded(

View file

@ -179,7 +179,7 @@ packages:
description: description:
path: "packages/flutter_community_chat_interface" path: "packages/flutter_community_chat_interface"
ref: HEAD ref: HEAD
resolved-ref: "09686cb451b5dc9c94e1088ce74dbee811064cdb" resolved-ref: "772764f84a2282f2f49de4a0910ae15024ceabd5"
url: "https://github.com/Iconica-Development/flutter_community_chat.git" url: "https://github.com/Iconica-Development/flutter_community_chat.git"
source: git source: git
version: "0.0.1" version: "0.0.1"