mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-18 18:33:49 +02:00
feat: add semantics for buttons
This commit is contained in:
parent
b3b8b1828e
commit
371ff6c335
15 changed files with 579 additions and 366 deletions
|
@ -24,6 +24,7 @@
|
|||
- Added enabled boolean to the messageInputBuilder and made parameters named
|
||||
- Added autoScrollTriggerOffset to the ChatPaginationControls to adjust when the auto scroll should be enabled
|
||||
- Added the ability to set the color of the CircularProgressIndicator of the ImageLoadingSnackbar by theme.snackBarTheme.actionTextColor
|
||||
- Added semantics for variable text, buttons and textfields
|
||||
|
||||
## 4.0.0
|
||||
- Move to the new user story architecture
|
||||
|
|
|
@ -33,6 +33,25 @@ class ChatSemantics {
|
|||
required this.newChatBioInput,
|
||||
required this.newChatSearchInput,
|
||||
required this.newGroupChatSearchInput,
|
||||
required this.profileStartChatButton,
|
||||
required this.chatsStartChatButton,
|
||||
required this.chatsDeleteConfirmButton,
|
||||
required this.newChatCreateGroupChatButton,
|
||||
required this.newGroupChatCreateGroupChatButton,
|
||||
required this.newGroupChatNextButton,
|
||||
required this.imagePickerCancelButton,
|
||||
required this.chatSelectImageIconButton,
|
||||
required this.chatSendMessageIconButton,
|
||||
required this.newChatSearchIconButton,
|
||||
required this.newGroupChatSearchIconButton,
|
||||
required this.chatBackButton,
|
||||
required this.chatTitleButton,
|
||||
required this.newGroupChatSelectImage,
|
||||
required this.newGroupChatRemoveImage,
|
||||
required this.newGroupChatRemoveUser,
|
||||
required this.profileTapUserButton,
|
||||
required this.chatsOpenChatButton,
|
||||
required this.userListTapUser,
|
||||
});
|
||||
|
||||
/// Default translations for the chat component view
|
||||
|
@ -58,6 +77,25 @@ class ChatSemantics {
|
|||
this.newChatBioInput = "input_text_bio",
|
||||
this.newChatSearchInput = "input_text_search",
|
||||
this.newGroupChatSearchInput = "input_text_search",
|
||||
this.profileStartChatButton = "button_start_chat",
|
||||
this.chatsStartChatButton = "button_start_chat",
|
||||
this.chatsDeleteConfirmButton = "button_delete_chat_confirm",
|
||||
this.newChatCreateGroupChatButton = "button_create_group_chat",
|
||||
this.newGroupChatCreateGroupChatButton = "button_create_group_chat",
|
||||
this.newGroupChatNextButton = "button_next",
|
||||
this.imagePickerCancelButton = "button_cancel",
|
||||
this.chatSelectImageIconButton = "button_icon_select_image",
|
||||
this.chatSendMessageIconButton = "button_icon_send_message",
|
||||
this.newChatSearchIconButton = "button_icon_search",
|
||||
this.newGroupChatSearchIconButton = "button_icon_search",
|
||||
this.chatBackButton = "button_back",
|
||||
this.chatTitleButton = "button_open_profile",
|
||||
this.newGroupChatSelectImage = "button_select_image",
|
||||
this.newGroupChatRemoveImage = "button_remove_image",
|
||||
this.newGroupChatRemoveUser = "button_remove_user",
|
||||
this.profileTapUserButton = _defaultProfileTapUserButton,
|
||||
this.chatsOpenChatButton = _defaultChatsOpenChatButton,
|
||||
this.userListTapUser = _defaultUserListTapUser,
|
||||
});
|
||||
|
||||
// Text
|
||||
|
@ -87,6 +125,33 @@ class ChatSemantics {
|
|||
final String newChatSearchInput;
|
||||
final String newGroupChatSearchInput;
|
||||
|
||||
// Buttons
|
||||
final String profileStartChatButton;
|
||||
final String chatsStartChatButton;
|
||||
final String chatsDeleteConfirmButton;
|
||||
final String newChatCreateGroupChatButton;
|
||||
final String newGroupChatCreateGroupChatButton;
|
||||
final String newGroupChatNextButton;
|
||||
final String imagePickerCancelButton;
|
||||
|
||||
// Icon buttons
|
||||
final String chatSelectImageIconButton;
|
||||
final String chatSendMessageIconButton;
|
||||
final String newChatSearchIconButton;
|
||||
final String newGroupChatSearchIconButton;
|
||||
|
||||
// Inkwells
|
||||
final String chatBackButton;
|
||||
final String chatTitleButton;
|
||||
final String newGroupChatSelectImage;
|
||||
final String newGroupChatRemoveImage;
|
||||
final String newGroupChatRemoveUser;
|
||||
|
||||
// Indexed inkwells
|
||||
final String Function(int index) profileTapUserButton;
|
||||
final String Function(int index) chatsOpenChatButton;
|
||||
final String Function(int index) userListTapUser;
|
||||
|
||||
ChatSemantics copyWith({
|
||||
String? profileTitle,
|
||||
String? profileDescription,
|
||||
|
@ -109,6 +174,25 @@ class ChatSemantics {
|
|||
String? newChatBioInput,
|
||||
String? newChatSearchInput,
|
||||
String? newGroupChatSearchInput,
|
||||
String? profileStartChatButton,
|
||||
String? chatsStartChatButton,
|
||||
String? chatsDeleteConfirmButton,
|
||||
String? newChatCreateGroupChatButton,
|
||||
String? newGroupChatCreateGroupChatButton,
|
||||
String? newGroupChatNextButton,
|
||||
String? imagePickerCancelButton,
|
||||
String? chatSelectImageIconButton,
|
||||
String? chatSendMessageIconButton,
|
||||
String? newChatSearchIconButton,
|
||||
String? newGroupChatSearchIconButton,
|
||||
String? chatBackButton,
|
||||
String? chatTitleButton,
|
||||
String? newGroupChatSelectImage,
|
||||
String? newGroupChatRemoveImage,
|
||||
String? newGroupChatRemoveUser,
|
||||
String Function(int)? profileTapUserButton,
|
||||
String Function(int)? chatsOpenChatButton,
|
||||
String Function(int)? userListTapUser,
|
||||
}) =>
|
||||
ChatSemantics(
|
||||
profileTitle: profileTitle ?? this.profileTitle,
|
||||
|
@ -137,6 +221,38 @@ class ChatSemantics {
|
|||
newChatSearchInput: newChatSearchInput ?? this.newChatSearchInput,
|
||||
newGroupChatSearchInput:
|
||||
newGroupChatSearchInput ?? this.newGroupChatSearchInput,
|
||||
profileStartChatButton:
|
||||
profileStartChatButton ?? this.profileStartChatButton,
|
||||
chatsStartChatButton: chatsStartChatButton ?? this.chatsStartChatButton,
|
||||
chatsDeleteConfirmButton:
|
||||
chatsDeleteConfirmButton ?? this.chatsDeleteConfirmButton,
|
||||
newChatCreateGroupChatButton:
|
||||
newChatCreateGroupChatButton ?? this.newChatCreateGroupChatButton,
|
||||
newGroupChatCreateGroupChatButton: newGroupChatCreateGroupChatButton ??
|
||||
this.newGroupChatCreateGroupChatButton,
|
||||
newGroupChatNextButton:
|
||||
newGroupChatNextButton ?? this.newGroupChatNextButton,
|
||||
imagePickerCancelButton:
|
||||
imagePickerCancelButton ?? this.imagePickerCancelButton,
|
||||
chatSelectImageIconButton:
|
||||
chatSelectImageIconButton ?? this.chatSelectImageIconButton,
|
||||
chatSendMessageIconButton:
|
||||
chatSendMessageIconButton ?? this.chatSendMessageIconButton,
|
||||
newChatSearchIconButton:
|
||||
newChatSearchIconButton ?? this.newChatSearchIconButton,
|
||||
newGroupChatSearchIconButton:
|
||||
newGroupChatSearchIconButton ?? this.newGroupChatSearchIconButton,
|
||||
chatBackButton: chatBackButton ?? this.chatBackButton,
|
||||
chatTitleButton: chatTitleButton ?? this.chatTitleButton,
|
||||
newGroupChatSelectImage:
|
||||
newGroupChatSelectImage ?? this.newGroupChatSelectImage,
|
||||
newGroupChatRemoveImage:
|
||||
newGroupChatRemoveImage ?? this.newGroupChatRemoveImage,
|
||||
newGroupChatRemoveUser:
|
||||
newGroupChatRemoveUser ?? this.newGroupChatRemoveUser,
|
||||
profileTapUserButton: profileTapUserButton ?? this.profileTapUserButton,
|
||||
chatsOpenChatButton: chatsOpenChatButton ?? this.chatsOpenChatButton,
|
||||
userListTapUser: userListTapUser ?? this.userListTapUser,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -150,3 +266,6 @@ String _defaultChatsChatSubTitle(int index) => "text_chat_sub_title_$index";
|
|||
String _defaultChatsChatLastUsed(int index) => "text_chat_last_used_$index";
|
||||
String _defaultChatsChatUnreadMessages(int index) =>
|
||||
"text_chat_unread_messages_$index";
|
||||
String _defaultProfileTapUserButton(int index) => "button_tap_user_$index";
|
||||
String _defaultChatsOpenChatButton(int index) => "button_open_chat_$index";
|
||||
String _defaultUserListTapUser(int index) => "button_tap_user_$index";
|
||||
|
|
|
@ -18,6 +18,7 @@ class FlutterChatEntryWidget extends StatefulWidget {
|
|||
this.counterBackgroundColor = Colors.red,
|
||||
this.textStyle,
|
||||
this.semanticIdUnreadMessages = "text_unread_messages_count",
|
||||
this.semanticIdOpenButton = "button_open_chat",
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
@ -51,6 +52,9 @@ class FlutterChatEntryWidget extends StatefulWidget {
|
|||
/// Semantic Id for the unread messages text
|
||||
final String semanticIdUnreadMessages;
|
||||
|
||||
/// Semantic Id for the unread messages text
|
||||
final String semanticIdOpenButton;
|
||||
|
||||
@override
|
||||
State<FlutterChatEntryWidget> createState() => _FlutterChatEntryWidgetState();
|
||||
}
|
||||
|
@ -83,7 +87,10 @@ class _FlutterChatEntryWidgetState extends State<FlutterChatEntryWidget> {
|
|||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => InkWell(
|
||||
Widget build(BuildContext context) => CustomSemantics(
|
||||
identifier: widget.semanticIdOpenButton,
|
||||
buttonWithVariableText: true,
|
||||
child: InkWell(
|
||||
onTap: () async =>
|
||||
widget.onTap?.call() ??
|
||||
Navigator.of(context).push(
|
||||
|
@ -140,6 +147,7 @@ class _FlutterChatEntryWidgetState extends State<FlutterChatEntryWidget> {
|
|||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ import "dart:typed_data";
|
|||
|
||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_chat/src/config/chat_options.dart";
|
||||
import "package:flutter_accessibility/flutter_accessibility.dart";
|
||||
import "package:flutter_chat/src/config/chat_options.dart";
|
||||
import "package:flutter_chat/src/config/screen_types.dart";
|
||||
import "package:flutter_chat/src/screens/chat_detail/widgets/chat_bottom.dart";
|
||||
import "package:flutter_chat/src/screens/chat_detail/widgets/chat_widgets.dart";
|
||||
|
@ -199,9 +199,12 @@ class _ChatAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||
|
||||
Widget? appBarIcon;
|
||||
if (onPressBack != null) {
|
||||
appBarIcon = InkWell(
|
||||
appBarIcon = CustomSemantics(
|
||||
identifier: options.semantics.chatBackButton,
|
||||
child: InkWell(
|
||||
onTap: onPressBack,
|
||||
child: const Icon(Icons.arrow_back_ios),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -209,7 +212,10 @@ class _ChatAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||
iconTheme: theme.appBarTheme.iconTheme,
|
||||
centerTitle: true,
|
||||
leading: appBarIcon,
|
||||
title: InkWell(
|
||||
title: CustomSemantics(
|
||||
identifier: options.semantics.chatTitleButton,
|
||||
buttonWithVariableText: true,
|
||||
child: InkWell(
|
||||
splashColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent,
|
||||
hoverColor: Colors.transparent,
|
||||
|
@ -224,6 +230,7 @@ class _ChatAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,9 @@ class ChatBottomInputSection extends HookWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
CustomSemantics(
|
||||
identifier: options.semantics.chatSelectImageIconButton,
|
||||
child: IconButton(
|
||||
alignment: Alignment.bottomRight,
|
||||
onPressed: isLoading ? null : onPressSelectImage,
|
||||
icon: Icon(
|
||||
|
@ -77,13 +79,17 @@ class ChatBottomInputSection extends HookWidget {
|
|||
color: options.iconEnabledColor,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
),
|
||||
CustomSemantics(
|
||||
identifier: options.semantics.chatSendMessageIconButton,
|
||||
child: IconButton(
|
||||
alignment: Alignment.bottomRight,
|
||||
disabledColor: options.iconDisabledColor,
|
||||
color: options.iconEnabledColor,
|
||||
onPressed: isLoading ? null : onClickSendMessage,
|
||||
icon: const Icon(Icons.send_rounded),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -119,7 +125,8 @@ class ChatBottomInputSection extends HookWidget {
|
|||
top: 16,
|
||||
bottom: 16,
|
||||
),
|
||||
// this ensures that that there is space at the end of the textfield
|
||||
// this ensures that that there is space at the end of the
|
||||
// textfield
|
||||
suffixIcon: AbsorbPointer(
|
||||
child: Opacity(
|
||||
opacity: 0.0,
|
||||
|
|
|
@ -297,7 +297,7 @@ class _DefaultChatImage extends StatelessWidget {
|
|||
options.imageProviderResolver(context, Uri.parse(imageUrl)),
|
||||
fit: BoxFit.fitWidth,
|
||||
errorBuilder: (context, error, stackTrace) => Text(
|
||||
// TODO: Non-replaceable text
|
||||
// TODO(Jacques): Non-replaceable text
|
||||
"Something went wrong with loading the image",
|
||||
style: textTheme.bodyLarge?.copyWith(
|
||||
color: messageTheme.textColor,
|
||||
|
|
|
@ -130,12 +130,18 @@ class _Body extends StatelessWidget {
|
|||
var chatUserDisplay = Wrap(
|
||||
children: [
|
||||
if (chat != null) ...[
|
||||
...chat!.users.map(
|
||||
(tappedUser) => Padding(
|
||||
...chat!.users.asMap().entries.map(
|
||||
(entry) {
|
||||
var index = entry.key;
|
||||
var tappedUser = entry.value;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 8,
|
||||
right: 8,
|
||||
),
|
||||
child: CustomSemantics(
|
||||
identifier: options.semantics.profileTapUserButton(index),
|
||||
child: InkWell(
|
||||
onTap: () => onTapUser?.call(tappedUser),
|
||||
child: Column(
|
||||
|
@ -166,8 +172,8 @@ class _Body extends StatelessWidget {
|
|||
user: User(
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
imageUrl:
|
||||
user.imageUrl != null || user.imageUrl != ""
|
||||
imageUrl: user.imageUrl != null ||
|
||||
user.imageUrl != ""
|
||||
? user.imageUrl
|
||||
: null,
|
||||
),
|
||||
|
@ -179,6 +185,8 @@ class _Body extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
|
@ -286,6 +294,8 @@ class _Body extends StatelessWidget {
|
|||
vertical: 24,
|
||||
horizontal: 80,
|
||||
),
|
||||
child: CustomSemantics(
|
||||
identifier: options.semantics.profileStartChatButton,
|
||||
child: FilledButton(
|
||||
onPressed: () {
|
||||
onPressStartChat?.call(user!.id);
|
||||
|
@ -302,6 +312,7 @@ class _Body extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
|
|
|
@ -197,6 +197,8 @@ class _BodyState extends State<_Body> {
|
|||
semantics.chatsChatLastUsed(index),
|
||||
semanticIdUnreadMessages:
|
||||
semantics.chatsChatUnreadMessages(index),
|
||||
semanticIdButton:
|
||||
semantics.chatsOpenChatButton(index),
|
||||
);
|
||||
|
||||
return !chat.canBeDeleted
|
||||
|
@ -275,6 +277,8 @@ class _BodyState extends State<_Body> {
|
|||
vertical: 24,
|
||||
horizontal: 4,
|
||||
),
|
||||
child: CustomSemantics(
|
||||
identifier: options.semantics.chatsStartChatButton,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: theme.colorScheme.primary,
|
||||
|
@ -290,6 +294,7 @@ class _BodyState extends State<_Body> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -303,6 +308,7 @@ class _ChatItem extends StatelessWidget {
|
|||
required this.semanticIdSubTitle,
|
||||
required this.semanticIdLastUsed,
|
||||
required this.semanticIdUnreadMessages,
|
||||
required this.semanticIdButton,
|
||||
});
|
||||
|
||||
final ChatModel chat;
|
||||
|
@ -311,6 +317,7 @@ class _ChatItem extends StatelessWidget {
|
|||
final String semanticIdSubTitle;
|
||||
final String semanticIdLastUsed;
|
||||
final String semanticIdUnreadMessages;
|
||||
final String semanticIdButton;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -330,7 +337,10 @@ class _ChatItem extends StatelessWidget {
|
|||
semanticIdUnreadMessages: semanticIdUnreadMessages,
|
||||
);
|
||||
|
||||
return InkWell(
|
||||
return CustomSemantics(
|
||||
identifier: semanticIdButton,
|
||||
buttonWithVariableText: true,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
onPressChat(chat);
|
||||
},
|
||||
|
@ -353,6 +363,7 @@ class _ChatItem extends StatelessWidget {
|
|||
child: chatListItem,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -530,6 +541,10 @@ Future<bool?> _deleteDialog(
|
|||
) async {
|
||||
var theme = Theme.of(context);
|
||||
|
||||
var scope = ChatScope.of(context);
|
||||
|
||||
var options = scope.options;
|
||||
|
||||
return showModalBottomSheet<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Container(
|
||||
|
@ -555,6 +570,8 @@ Future<bool?> _deleteDialog(
|
|||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 60),
|
||||
child: CustomSemantics(
|
||||
identifier: options.semantics.chatsDeleteConfirmButton,
|
||||
child: FilledButton(
|
||||
onPressed: () {
|
||||
Navigator.of(
|
||||
|
@ -572,6 +589,7 @@ Future<bool?> _deleteDialog(
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -145,6 +145,7 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||
SearchIcon(
|
||||
isSearching: isSearching,
|
||||
onPressed: onPressedSearchIcon,
|
||||
semanticId: options.semantics.newChatSearchIconButton,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -187,6 +188,8 @@ class _Body extends StatelessWidget {
|
|||
right: 32,
|
||||
top: 20,
|
||||
),
|
||||
child: CustomSemantics(
|
||||
identifier: options.semantics.newChatCreateGroupChatButton,
|
||||
child: FilledButton(
|
||||
onPressed: onPressCreateGroupChat,
|
||||
child: Row(
|
||||
|
@ -207,6 +210,7 @@ class _Body extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
Expanded(
|
||||
child: StreamBuilder<List<UserModel>>(
|
||||
|
|
|
@ -158,7 +158,9 @@ class _BodyState extends State<_Body> {
|
|||
Center(
|
||||
child: Stack(
|
||||
children: [
|
||||
InkWell(
|
||||
CustomSemantics(
|
||||
identifier: options.semantics.newGroupChatSelectImage,
|
||||
child: InkWell(
|
||||
onTap: () async => onPressSelectImage(
|
||||
context,
|
||||
options,
|
||||
|
@ -181,8 +183,10 @@ class _BodyState extends State<_Body> {
|
|||
)
|
||||
: null,
|
||||
),
|
||||
child:
|
||||
image == null ? const Icon(Icons.image) : null,
|
||||
child: image == null
|
||||
? const Icon(Icons.image)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (image != null)
|
||||
|
@ -197,6 +201,9 @@ class _BodyState extends State<_Body> {
|
|||
borderRadius: BorderRadius.circular(40),
|
||||
),
|
||||
child: Center(
|
||||
child: CustomSemantics(
|
||||
identifier:
|
||||
options.semantics.newGroupChatRemoveImage,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
|
@ -210,6 +217,7 @@ class _BodyState extends State<_Body> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
const SizedBox.shrink(),
|
||||
|
@ -354,7 +362,9 @@ class _BodyState extends State<_Body> {
|
|||
),
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: isButtonEnabled,
|
||||
builder: (context, isEnabled, child) => FilledButton(
|
||||
builder: (context, isEnabled, child) => CustomSemantics(
|
||||
identifier: "",
|
||||
child: FilledButton(
|
||||
onPressed: users.isNotEmpty
|
||||
? () async {
|
||||
if (!isPressed) {
|
||||
|
@ -384,6 +394,7 @@ class _BodyState extends State<_Body> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -402,7 +413,9 @@ class _SelectedUser extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
var chatScope = ChatScope.of(context);
|
||||
var options = chatScope.options;
|
||||
return InkWell(
|
||||
return CustomSemantics(
|
||||
identifier: options.semantics.newGroupChatRemoveUser,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
onRemove(user);
|
||||
},
|
||||
|
@ -435,6 +448,7 @@ class _SelectedUser extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_accessibility/flutter_accessibility.dart";
|
||||
import "package:flutter_chat/src/config/screen_types.dart";
|
||||
import "package:flutter_chat/src/screens/creation/widgets/search_field.dart";
|
||||
import "package:flutter_chat/src/screens/creation/widgets/search_icon.dart";
|
||||
|
@ -155,6 +156,7 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||
SearchIcon(
|
||||
isSearching: isSearching,
|
||||
onPressed: onPressedSearchIcon,
|
||||
semanticId: options.semantics.newGroupChatSearchIconButton,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -272,6 +274,8 @@ class _NextButton extends StatelessWidget {
|
|||
),
|
||||
child: Visibility(
|
||||
visible: selectedUsers.isNotEmpty,
|
||||
child: CustomSemantics(
|
||||
identifier: options.semantics.newGroupChatNextButton,
|
||||
child: FilledButton(
|
||||
onPressed: () async {
|
||||
await onPressGroupChatOverview(selectedUsers);
|
||||
|
@ -288,6 +292,7 @@ class _NextButton extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import "dart:typed_data";
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_accessibility/flutter_accessibility.dart";
|
||||
import "package:flutter_chat/src/config/chat_options.dart";
|
||||
import "package:flutter_chat/src/config/chat_translations.dart";
|
||||
import "package:flutter_chat/src/util/scope.dart";
|
||||
|
@ -71,7 +72,9 @@ class DefaultImagePickerDialog extends StatelessWidget {
|
|||
Icons.insert_drive_file_rounded,
|
||||
size: 60,
|
||||
),
|
||||
closeButtonBuilder: (ontap) => TextButton(
|
||||
closeButtonBuilder: (ontap) => CustomSemantics(
|
||||
identifier: options.semantics.imagePickerCancelButton,
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: Text(
|
||||
translations.cancelImagePickerBtn,
|
||||
|
@ -83,6 +86,7 @@ class DefaultImagePickerDialog extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ class SearchIcon extends StatelessWidget {
|
|||
const SearchIcon({
|
||||
required this.isSearching,
|
||||
required this.onPressed,
|
||||
required this.semanticId,
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
@ -15,15 +16,21 @@ class SearchIcon extends StatelessWidget {
|
|||
/// Callback function triggered when the search icon is pressed
|
||||
final VoidCallback onPressed;
|
||||
|
||||
/// Semantic id for icon button
|
||||
final String semanticId;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var theme = Theme.of(context);
|
||||
return IconButton(
|
||||
return Semantics(
|
||||
identifier: semanticId,
|
||||
child: IconButton(
|
||||
onPressed: onPressed,
|
||||
icon: Icon(
|
||||
isSearching ? Icons.close : Icons.search,
|
||||
color: theme.appBarTheme.iconTheme?.color ?? Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,10 @@ class _UserListState extends State<UserList> {
|
|||
itemBuilder: (context, index) {
|
||||
var user = filteredUsers[index];
|
||||
var isSelected = widget.selectedUsers.any((u) => u.id == user.id);
|
||||
return InkWell(
|
||||
return CustomSemantics(
|
||||
identifier: options.semantics.userListTapUser(index),
|
||||
buttonWithVariableText: true,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
if (widget.creatingGroup) {
|
||||
return handleGroupChatTap(user);
|
||||
|
@ -152,8 +155,9 @@ class _UserListState extends State<UserList> {
|
|||
user: User(
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
imageUrl:
|
||||
user.imageUrl != "" ? user.imageUrl : null,
|
||||
imageUrl: user.imageUrl != ""
|
||||
? user.imageUrl
|
||||
: null,
|
||||
),
|
||||
size: 44,
|
||||
),
|
||||
|
@ -185,6 +189,7 @@ class _UserListState extends State<UserList> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
@ -15,6 +15,9 @@ dependencies:
|
|||
intl: any
|
||||
flutter_hooks: ^0.20.5
|
||||
|
||||
flutter_accessibility:
|
||||
hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
||||
version: ^0.0.2
|
||||
flutter_image_picker:
|
||||
hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
||||
version: ^4.0.0
|
||||
|
|
Loading…
Reference in a new issue