fix: update for safino

This commit is contained in:
mike doornenbal 2024-07-23 09:44:12 +02:00 committed by Freek van de Ven
parent 8f13d87a23
commit 44579ca306
12 changed files with 124 additions and 54 deletions

View file

@ -8,6 +8,7 @@ export "package:flutter_chat_interface/flutter_chat_interface.dart";
export "src/components/chat_row.dart"; export "src/components/chat_row.dart";
export "src/config/chat_options.dart"; export "src/config/chat_options.dart";
export "src/config/chat_text_styles.dart";
export "src/config/chat_translations.dart"; export "src/config/chat_translations.dart";
export "src/screens/chat_detail_screen.dart"; export "src/screens/chat_detail_screen.dart";
export "src/screens/chat_profile_screen.dart"; export "src/screens/chat_profile_screen.dart";

View file

@ -14,6 +14,7 @@ class ChatDetailRow extends StatefulWidget {
required this.message, required this.message,
required this.userAvatarBuilder, required this.userAvatarBuilder,
required this.onPressUserProfile, required this.onPressUserProfile,
required this.options,
this.usernameBuilder, this.usernameBuilder,
this.previousMessage, this.previousMessage,
this.showTime = false, this.showTime = false,
@ -37,16 +38,17 @@ class ChatDetailRow extends StatefulWidget {
/// Flag indicating whether to show the time. /// Flag indicating whether to show the time.
final bool showTime; final bool showTime;
final ChatOptions options;
@override @override
State<ChatDetailRow> createState() => _ChatDetailRowState(); State<ChatDetailRow> createState() => _ChatDetailRowState();
} }
class _ChatDetailRowState extends State<ChatDetailRow> { class _ChatDetailRowState extends State<ChatDetailRow> {
final DateFormatter _dateFormatter = DateFormatter();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var theme = Theme.of(context); var theme = Theme.of(context);
var dateFormatter = DateFormatter(options: widget.options);
var isNewDate = widget.previousMessage != null && var isNewDate = widget.previousMessage != null &&
widget.message.timestamp.day != widget.previousMessage?.timestamp.day; widget.message.timestamp.day != widget.previousMessage?.timestamp.day;
@ -103,17 +105,20 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
Text( Text(
widget.message.sender.fullName ?? widget.message.sender.fullName ??
widget.translations.anonymousUser, widget.translations.anonymousUser,
style: theme.textTheme.titleMedium, style: widget
.options.textstyles?.senderTextStyle ??
theme.textTheme.titleMedium,
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.only(top: 5.0), padding: const EdgeInsets.only(top: 5.0),
child: Text( child: Text(
_dateFormatter.format( dateFormatter.format(
date: widget.message.timestamp, date: widget.message.timestamp,
showFullDate: false, showFullDate: true,
), ),
style: theme.textTheme.labelSmall, style: widget.options.textstyles?.dateTextStyle ??
theme.textTheme.labelSmall,
), ),
), ),
], ],
@ -129,7 +134,9 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
Flexible( Flexible(
child: Text( child: Text(
(widget.message as ChatTextMessageModel).text, (widget.message as ChatTextMessageModel).text,
style: theme.textTheme.bodySmall, style: widget.options.textstyles
?.messageTextStyle ??
theme.textTheme.bodySmall,
), ),
), ),
if (widget.showTime && if (widget.showTime &&
@ -137,14 +144,16 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
!isNewDate && !isNewDate &&
!hasHeader) !hasHeader)
Text( Text(
_dateFormatter dateFormatter
.format( .format(
date: widget.message.timestamp, date: widget.message.timestamp,
showFullDate: true, showFullDate: true,
) )
.split(" ") .split(" ")
.last, .last,
style: theme.textTheme.labelSmall, style: widget
.options.textstyles?.dateTextStyle ??
theme.textTheme.labelSmall,
textAlign: TextAlign.end, textAlign: TextAlign.end,
), ),
], ],

View file

@ -3,10 +3,12 @@
// SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: BSD-3-Clause
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_chat_view/flutter_chat_view.dart";
class ChatRow extends StatelessWidget { class ChatRow extends StatelessWidget {
const ChatRow({ const ChatRow({
required this.title, required this.title,
required this.options,
this.unreadMessages = 0, this.unreadMessages = 0,
this.lastUsed, this.lastUsed,
this.subTitle, this.subTitle,
@ -29,6 +31,8 @@ class ChatRow extends StatelessWidget {
/// The avatar associated with the chat. /// The avatar associated with the chat.
final Widget? avatar; final Widget? avatar;
final ChatOptions options;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var theme = Theme.of(context); var theme = Theme.of(context);
@ -49,7 +53,8 @@ class ChatRow extends StatelessWidget {
title, title,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: theme.textTheme.titleMedium, style: options.textstyles?.senderTextStyle ??
theme.textTheme.titleMedium,
), ),
if (subTitle != null) ...[ if (subTitle != null) ...[
Padding( Padding(
@ -57,10 +62,14 @@ class ChatRow extends StatelessWidget {
child: Text( child: Text(
subTitle!, subTitle!,
style: unreadMessages > 0 style: unreadMessages > 0
? theme.textTheme.bodySmall!.copyWith( ? options.textstyles?.messageTextStyle!.copyWith(
fontWeight: FontWeight.w800,
) ??
theme.textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
) )
: theme.textTheme.bodySmall, : options.textstyles?.messageTextStyle ??
theme.textTheme.bodySmall,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 2, maxLines: 2,
), ),
@ -79,7 +88,8 @@ class ChatRow extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 4.0), padding: const EdgeInsets.only(bottom: 4.0),
child: Text( child: Text(
lastUsed!, lastUsed!,
style: theme.textTheme.labelSmall, style: options.textstyles?.dateTextStyle ??
theme.textTheme.labelSmall,
), ),
), ),
], ],

View file

@ -13,12 +13,19 @@ class ChatOptions {
this.messageInputBuilder = _createMessageInput, this.messageInputBuilder = _createMessageInput,
this.chatRowContainerBuilder = _createChatRowContainer, this.chatRowContainerBuilder = _createChatRowContainer,
this.imagePickerContainerBuilder = _createImagePickerContainer, this.imagePickerContainerBuilder = _createImagePickerContainer,
this.scaffoldBuilder = _createScaffold, this.chatScreenScaffoldBuilder = _createChatScreenScaffold,
this.chatDetailScaffoldBuilder = _createChatScreenScaffold,
this.chatProfileScaffoldBuilder = _createChatScreenScaffold,
this.newChatScreenScaffoldBuilder = _createChatScreenScaffold,
this.newGroupChatScreenScaffoldBuilder = _createChatScreenScaffold,
this.newGroupChatOverviewScaffoldBuilder = _createChatScreenScaffold,
this.userAvatarBuilder = _createUserAvatar, this.userAvatarBuilder = _createUserAvatar,
this.groupAvatarBuilder = _createGroupAvatar, this.groupAvatarBuilder = _createGroupAvatar,
this.noChatsPlaceholderBuilder = _createNoChatsPlaceholder, this.noChatsPlaceholderBuilder = _createNoChatsPlaceholder,
this.noUsersPlaceholderBuilder = _createNoUsersPlaceholder, this.noUsersPlaceholderBuilder = _createNoUsersPlaceholder,
this.paddingAroundChatList, this.paddingAroundChatList,
this.textstyles,
this.dateformat,
}); });
/// Builder function for the new chat button. /// Builder function for the new chat button.
@ -34,7 +41,23 @@ class ChatOptions {
final ImagePickerContainerBuilder imagePickerContainerBuilder; final ImagePickerContainerBuilder imagePickerContainerBuilder;
/// Builder function for the scaffold containing the chat view. /// Builder function for the scaffold containing the chat view.
final ScaffoldBuilder scaffoldBuilder; final ScaffoldBuilder chatScreenScaffoldBuilder;
/// Builder function for the scaffold containing the chat detail view.
final ScaffoldBuilder chatDetailScaffoldBuilder;
/// Builder function for the scaffold containing the chat profile view.
final ScaffoldBuilder chatProfileScaffoldBuilder;
/// Builder function for the scaffold containing the new chat view.
final ScaffoldBuilder newChatScreenScaffoldBuilder;
/// Builder function for the scaffold containing the new groupchat view.
final ScaffoldBuilder newGroupChatScreenScaffoldBuilder;
/// Builder function for the scaffold containing the new
/// groupchat overview view.
final ScaffoldBuilder newGroupChatOverviewScaffoldBuilder;
/// Builder function for the user avatar. /// Builder function for the user avatar.
final UserAvatarBuilder userAvatarBuilder; final UserAvatarBuilder userAvatarBuilder;
@ -50,6 +73,11 @@ class ChatOptions {
/// The padding around the chat list. /// The padding around the chat list.
final EdgeInsets? paddingAroundChatList; final EdgeInsets? paddingAroundChatList;
final ChatTextStyles? textstyles;
// ignore: avoid_positional_boolean_parameters
final String Function(bool showFullDate, DateTime date)? dateformat;
} }
Widget _createNewChatButton( Widget _createNewChatButton(
@ -182,7 +210,7 @@ Widget _createImagePickerContainer(
); );
} }
Scaffold _createScaffold( Scaffold _createChatScreenScaffold(
AppBar appbar, AppBar appbar,
Widget body, Widget body,
Color backgroundColor, Color backgroundColor,

View file

@ -0,0 +1,13 @@
import "package:flutter/material.dart";
class ChatTextStyles {
ChatTextStyles({
this.senderTextStyle,
this.messageTextStyle,
this.dateTextStyle,
});
final TextStyle? senderTextStyle;
final TextStyle? messageTextStyle;
final TextStyle? dateTextStyle;
}

View file

@ -106,6 +106,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
for (var message in chatMessages) { for (var message in chatMessages) {
detailRows.add( detailRows.add(
ChatDetailRow( ChatDetailRow(
options: widget.options,
showTime: true, showTime: true,
message: message, message: message,
translations: widget.translations, translations: widget.translations,
@ -149,9 +150,8 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
: (chatModel is PersonalChatModel) : (chatModel is PersonalChatModel)
? chatModel.user.firstName ?? widget.translations.anonymousUser ? chatModel.user.firstName ?? widget.translations.anonymousUser
: ""; : "";
return widget.options.chatDetailScaffoldBuilder(
return Scaffold( AppBar(
appBar: AppBar(
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
const IconThemeData(color: Colors.white), const IconThemeData(color: Colors.white),
centerTitle: true, centerTitle: true,
@ -168,12 +168,11 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
child: widget.chatTitleBuilder?.call(chatTitle) ?? child: widget.chatTitleBuilder?.call(chatTitle) ??
Text( Text(
chatTitle, chatTitle,
style: theme.textTheme.headlineLarge,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
), ),
), ),
body: Stack( Stack(
children: [ children: [
Column( Column(
children: [ children: [
@ -262,6 +261,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
], ],
], ],
), ),
theme.scaffoldBackgroundColor,
); );
}, },
); );

View file

@ -77,9 +77,8 @@ class _ProfileScreenState extends State<ChatProfileScreen> {
imageUrl: data.imageUrl, imageUrl: data.imageUrl,
); );
} }
return widget.options.chatProfileScaffoldBuilder(
return Scaffold( AppBar(
appBar: AppBar(
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
const IconThemeData(color: Colors.white), const IconThemeData(color: Colors.white),
title: Text( title: Text(
@ -90,10 +89,9 @@ class _ProfileScreenState extends State<ChatProfileScreen> {
: (data is GroupChatModel) : (data is GroupChatModel)
? data.title ? data.title
: "", : "",
style: theme.textTheme.headlineLarge,
), ),
), ),
body: snapshot.hasData snapshot.hasData
? Stack( ? Stack(
children: [ children: [
ListView( ListView(
@ -210,7 +208,10 @@ class _ProfileScreenState extends State<ChatProfileScreen> {
], ],
], ],
) )
: const Center(child: CircularProgressIndicator()), : const Center(
child: CircularProgressIndicator(),
),
theme.scaffoldBackgroundColor,
); );
}, },
); );

View file

@ -58,7 +58,6 @@ class ChatScreen extends StatefulWidget {
} }
class _ChatScreenState extends State<ChatScreen> { class _ChatScreenState extends State<ChatScreen> {
final DateFormatter _dateFormatter = DateFormatter();
bool _hasCalledOnNoChats = false; bool _hasCalledOnNoChats = false;
ScrollController controller = ScrollController(); ScrollController controller = ScrollController();
bool showIndicator = false; bool showIndicator = false;
@ -73,13 +72,14 @@ class _ChatScreenState extends State<ChatScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var dateFormatter = DateFormatter(options: widget.options);
var translations = widget.translations; var translations = widget.translations;
var theme = Theme.of(context); var theme = Theme.of(context);
return widget.options.scaffoldBuilder( return widget.options.chatScreenScaffoldBuilder(
AppBar( AppBar(
title: Text( title: Text(
translations.chatsTitle, translations.chatsTitle,
style: theme.textTheme.headlineLarge,
), ),
centerTitle: true, centerTitle: true,
actions: [ actions: [
@ -202,14 +202,14 @@ class _ChatScreenState extends State<ChatScreen> {
widget: widget, widget: widget,
chat: chat, chat: chat,
translations: translations, translations: translations,
dateFormatter: _dateFormatter, dateFormatter: dateFormatter,
), ),
) )
: ChatListItem( : ChatListItem(
widget: widget, widget: widget,
chat: chat, chat: chat,
translations: translations, translations: translations,
dateFormatter: _dateFormatter, dateFormatter: dateFormatter,
), ),
), ),
), ),
@ -231,7 +231,7 @@ class _ChatScreenState extends State<ChatScreen> {
), ),
], ],
), ),
theme.colorScheme.surface, theme.scaffoldBackgroundColor,
); );
} }
@ -331,6 +331,7 @@ class ChatListItem extends StatelessWidget {
child: widget.options.chatRowContainerBuilder( child: widget.options.chatRowContainerBuilder(
(chat is PersonalChatModel) (chat is PersonalChatModel)
? ChatRow( ? ChatRow(
options: widget.options,
unreadMessages: chat.unreadMessages ?? 0, unreadMessages: chat.unreadMessages ?? 0,
avatar: widget.options.userAvatarBuilder( avatar: widget.options.userAvatarBuilder(
(chat as PersonalChatModel).user, (chat as PersonalChatModel).user,
@ -351,6 +352,7 @@ class ChatListItem extends StatelessWidget {
: null, : null,
) )
: ChatRow( : ChatRow(
options: widget.options,
title: (chat as GroupChatModel).title, title: (chat as GroupChatModel).title,
unreadMessages: chat.unreadMessages ?? 0, unreadMessages: chat.unreadMessages ?? 0,
subTitle: chat.lastMessage != null subTitle: chat.lastMessage != null

View file

@ -46,8 +46,8 @@ class _NewChatScreenState extends State<NewChatScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var theme = Theme.of(context); var theme = Theme.of(context);
return Scaffold( return widget.options.newChatScreenScaffoldBuilder(
appBar: AppBar( AppBar(
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
const IconThemeData(color: Colors.white), const IconThemeData(color: Colors.white),
title: _buildSearchField(), title: _buildSearchField(),
@ -55,7 +55,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
_buildSearchIcon(), _buildSearchIcon(),
], ],
), ),
body: Column( Column(
children: [ children: [
if (widget.showGroupChatButton && !_isSearching) ...[ if (widget.showGroupChatButton && !_isSearching) ...[
Padding( Padding(
@ -106,6 +106,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
), ),
], ],
), ),
theme.scaffoldBackgroundColor,
); );
} }
@ -135,7 +136,6 @@ class _NewChatScreenState extends State<NewChatScreen> {
) )
: Text( : Text(
widget.translations.newChatTitle, widget.translations.newChatTitle,
style: theme.textTheme.headlineLarge,
); );
} }

View file

@ -51,17 +51,16 @@ class _NewGroupChatOverviewScreenState
}); });
} }
return Scaffold( return widget.options.newGroupChatOverviewScaffoldBuilder(
appBar: AppBar( AppBar(
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
const IconThemeData(color: Colors.white), const IconThemeData(color: Colors.white),
backgroundColor: theme.appBarTheme.backgroundColor, backgroundColor: theme.appBarTheme.backgroundColor,
title: Text( title: Text(
widget.translations.newGroupChatTitle, widget.translations.newGroupChatTitle,
style: theme.appBarTheme.titleTextStyle,
), ),
), ),
body: Stack( Stack(
children: [ children: [
SingleChildScrollView( SingleChildScrollView(
child: Padding( child: Padding(
@ -286,7 +285,7 @@ class _NewGroupChatOverviewScreenState
), ),
], ],
), ),
// floatingActionButton: FloatingActionButton( theme.scaffoldBackgroundColor,
); );
} }

View file

@ -30,9 +30,8 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var theme = Theme.of(context); var theme = Theme.of(context);
return Scaffold( return widget.options.newGroupChatScreenScaffoldBuilder(
backgroundColor: theme.colorScheme.surface, AppBar(
appBar: AppBar(
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
const IconThemeData(color: Colors.white), const IconThemeData(color: Colors.white),
backgroundColor: theme.appBarTheme.backgroundColor, backgroundColor: theme.appBarTheme.backgroundColor,
@ -41,7 +40,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
_buildSearchIcon(), _buildSearchIcon(),
], ],
), ),
body: FutureBuilder<List<ChatUserModel>>( FutureBuilder<List<ChatUserModel>>(
// ignore: discarded_futures // ignore: discarded_futures
future: widget.service.chatUserService.getAllUsers(), future: widget.service.chatUserService.getAllUsers(),
builder: (context, snapshot) { builder: (context, snapshot) {
@ -63,6 +62,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
return const SizedBox.shrink(); return const SizedBox.shrink();
}, },
), ),
theme.scaffoldBackgroundColor,
); );
} }
@ -92,7 +92,6 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
) )
: Text( : Text(
widget.translations.newGroupChatButton, widget.translations.newGroupChatButton,
style: theme.appBarTheme.titleTextStyle,
); );
} }

View file

@ -2,9 +2,14 @@
// //
// SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: BSD-3-Clause
import "package:flutter_chat_view/flutter_chat_view.dart";
import "package:intl/intl.dart"; import "package:intl/intl.dart";
class DateFormatter { class DateFormatter {
DateFormatter({
required this.options,
});
final ChatOptions options;
final _now = DateTime.now(); final _now = DateTime.now();
bool _isToday(DateTime date) => bool _isToday(DateTime date) =>
@ -45,17 +50,20 @@ class DateFormatter {
required DateTime date, required DateTime date,
bool showFullDate = false, bool showFullDate = false,
}) { }) {
if(showFullDate) { if (options.dateformat != null) {
return DateFormat("dd - MM - yyyy HH:mm").format(date); return options.dateformat!(showFullDate, date);
} }
if (_isToday(date)) { if (_isToday(date)) {
return DateFormat("HH:mm").format(date); return DateFormat(
"HH:mm",
).format(date);
} else if (_isYesterday(date)) { } else if (_isYesterday(date)) {
return "yesterday"; return "yesterday";
} else if (_isThisYear(date)) { } else if (_isThisYear(date)) {
return DateFormat("dd MMMM").format(date); return DateFormat("dd-MM${showFullDate ? " HH:mm" : ""}").format(date);
} else { } else {
return DateFormat("dd - MM - yyyy").format(date); return DateFormat("dd-MM-yyyy${showFullDate ? " HH:mm" : ""}")
.format(date);
} }
} }
} }