Skip to content

Commit 7ffbd56

Browse files
authored
feat: implement configurable call actions in chat contact info (#883)
* feat: add configuration support for video call button in contact info * chore: enable video call button in chat contact info by default
1 parent e61323a commit 7ffbd56

10 files changed

Lines changed: 287 additions & 37 deletions

File tree

assets/themes/app.config.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,10 @@
265265
"messaging": {
266266
"sms": {},
267267
"chats": {
268-
"groupChatButtonEnabled": true
268+
"groupChatButtonEnabled": true,
269+
"contactInfo": {
270+
"showVideoButtonAction": true
271+
}
269272
}
270273
}
271274
}

lib/data/feature_access.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ abstract final class MessagingMapper {
366366
coreChatsSupport: coreSupport.supportsChats,
367367
tabEnabled: tabEnabled,
368368
groupChatSupport: appConfig.messaging.chats.groupChatButtonEnabled,
369-
contactInfoVideoCallSupport: true,
369+
contactInfoVideoCallSupport: appConfig.messaging.chats.contactInfo.showVideoButtonAction,
370370
);
371371
}
372372
}

lib/features/messaging/bloc/messaging_bloc.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class MessagingBloc extends Bloc<MessagingEvent, MessagingState> {
3636
this._smsRepository,
3737
this._smsOutboxRepository,
3838
this._submitNotification,
39-
) : super(MessagingState.initial(_client)) {
39+
) : super(MessagingState.initial(_client, _messagingConfig)) {
4040
on<Connect>(_connect);
4141
on<Refresh>(_refresh);
4242
on<Disconnect>(_onDisconnect);

lib/features/messaging/bloc/messaging_state.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ part of 'messaging_bloc.dart';
33
enum ConnectionStatus { initial, error, connecting, connected }
44

55
class MessagingState with EquatableMixin {
6-
const MessagingState._(this.client, this.status, this.error);
6+
const MessagingState._(this.client, this.status, this.messagingConfig, this.error);
77

88
final PhoenixSocket client;
99
final ConnectionStatus status;
10+
final MessagingConfig messagingConfig;
1011
final Exception? error;
1112

12-
factory MessagingState.initial(PhoenixSocket client) {
13-
return MessagingState._(client, ConnectionStatus.initial, null);
13+
factory MessagingState.initial(PhoenixSocket client, MessagingConfig messagingConfig) {
14+
return MessagingState._(client, ConnectionStatus.initial, messagingConfig, null);
1415
}
1516

16-
MessagingState copyWith({ConnectionStatus? status, Exception? error}) {
17-
return MessagingState._(client, status ?? this.status, error);
17+
MessagingState copyWith({ConnectionStatus? status, MessagingConfig? messagingConfig, Exception? error}) {
18+
return MessagingState._(client, status ?? this.status, messagingConfig ?? this.messagingConfig, error);
1819
}
1920

2021
@override

lib/features/messaging/features/chat_conversation/view/conversation_screen.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ class _ChatConversationScreenState extends State<ChatConversationScreen> {
4040
value: conversationCubit,
4141
child: ClipRRect(
4242
borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
43-
child: DialogInfo(userId, state.credentials.participantId!),
43+
child: DialogInfo(
44+
userId,
45+
state.credentials.participantId!,
46+
isAudioCallEnabled: true,
47+
isVideoCallEnabled: messagingBloc.state.messagingConfig.contactInfoVideoCallSupport,
48+
),
4449
),
4550
),
4651
);

lib/features/messaging/features/chat_conversation/widgets/dialog_info.dart

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,25 @@ import 'package:flutter/material.dart';
44

55
import 'package:flutter_bloc/flutter_bloc.dart';
66

7+
import 'package:webtrit_phone/app/notifications/notifications.dart';
78
import 'package:webtrit_phone/features/features.dart';
89
import 'package:webtrit_phone/l10n/l10n.dart';
910
import 'package:webtrit_phone/models/models.dart';
10-
import 'package:webtrit_phone/app/notifications/notifications.dart';
1111
import 'package:webtrit_phone/widgets/widgets.dart' hide ConfirmDialog;
1212

1313
class DialogInfo extends StatefulWidget {
14-
const DialogInfo(this.userId, this.participantId, {super.key});
14+
const DialogInfo(
15+
this.userId,
16+
this.participantId, {
17+
required this.isAudioCallEnabled,
18+
required this.isVideoCallEnabled,
19+
super.key,
20+
});
1521

1622
final String userId;
1723
final String participantId;
24+
final bool isAudioCallEnabled;
25+
final bool isVideoCallEnabled;
1826

1927
@override
2028
State<DialogInfo> createState() => _DialogInfoState();
@@ -110,31 +118,22 @@ class _DialogInfoState extends State<DialogInfo> {
110118
),
111119
const SizedBox(height: 24),
112120
if (contact != null && contact.kind == ContactKind.visible) ...[
113-
Divider(),
121+
const Divider(),
114122
Expanded(
115123
child: ListView(
116124
children: [
117125
for (ContactPhone contactPhone in contact.phones)
118126
ListTile(
127+
contentPadding: EdgeInsets.zero,
119128
title: Text(contactPhone.number),
120129
trailing: Row(
121130
mainAxisSize: MainAxisSize.min,
122-
children: [
123-
IconButton(
124-
splashRadius: 24,
125-
icon: const Icon(Icons.call),
126-
onPressed: () => _onCall(contactPhone, contact, false),
127-
),
128-
IconButton(
129-
splashRadius: 24,
130-
icon: const Icon(Icons.videocam),
131-
onPressed: () => _onCall(contactPhone, contact, true),
132-
),
133-
],
131+
children: _buildCallActions(contactPhone, contact),
134132
),
135133
),
136134
for (ContactEmail contactEmail in contact.emails)
137135
ListTile(
136+
contentPadding: EdgeInsets.zero,
138137
title: Text(contactEmail.address),
139138
trailing: IconButton(
140139
splashRadius: 24,
@@ -147,7 +146,7 @@ class _DialogInfoState extends State<DialogInfo> {
147146
),
148147
const SizedBox(height: 8),
149148
] else
150-
Spacer(),
149+
const Spacer(),
151150
],
152151
),
153152
);
@@ -170,4 +169,22 @@ class _DialogInfoState extends State<DialogInfo> {
170169
},
171170
);
172171
}
172+
173+
/// Returns a list of call action buttons based on provided configuration.
174+
List<Widget> _buildCallActions(ContactPhone contactPhone, Contact contact) {
175+
return [
176+
if (widget.isAudioCallEnabled)
177+
IconButton(
178+
splashRadius: 24,
179+
icon: const Icon(Icons.call),
180+
onPressed: () => _onCall(contactPhone, contact, false),
181+
),
182+
if (widget.isVideoCallEnabled)
183+
IconButton(
184+
splashRadius: 24,
185+
icon: const Icon(Icons.videocam),
186+
onPressed: () => _onCall(contactPhone, contact, true),
187+
),
188+
];
189+
}
173190
}

packages/webtrit_appearance_theme/lib/models/features_config/app_config.dart

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,12 +612,28 @@ class AppConfigSms with _$AppConfigSms {
612612
@freezed
613613
@JsonSerializable(explicitToJson: true)
614614
class AppConfigChats with _$AppConfigChats {
615-
const AppConfigChats({this.groupChatButtonEnabled = true});
615+
const AppConfigChats({this.groupChatButtonEnabled = true, this.contactInfo = const ChatContactInfo()});
616616

617617
@override
618618
final bool groupChatButtonEnabled;
619619

620+
@override
621+
final ChatContactInfo contactInfo;
622+
620623
factory AppConfigChats.fromJson(Map<String, Object?> json) => _$AppConfigChatsFromJson(json);
621624

622625
Map<String, Object?> toJson() => _$AppConfigChatsToJson(this);
623626
}
627+
628+
@freezed
629+
@JsonSerializable(explicitToJson: true)
630+
class ChatContactInfo with _$ChatContactInfo {
631+
const ChatContactInfo({this.showVideoButtonAction = true});
632+
633+
@override
634+
final bool showVideoButtonAction;
635+
636+
factory ChatContactInfo.fromJson(Map<String, Object?> json) => _$ChatContactInfoFromJson(json);
637+
638+
Map<String, Object?> toJson() => _$ChatContactInfoToJson(this);
639+
}

0 commit comments

Comments
 (0)