Skip to content

Commit

Permalink
Implement CallMember redialing (#241, #233)
Browse files Browse the repository at this point in the history
  • Loading branch information
skazkiful committed Dec 7, 2022
1 parent e597549 commit f7ee66e
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ All user visible changes to this project will be documented in this file. This p
- Searching. ([#206], [#205])
- Home page:
- Quick status changing menu. ([#204], [#203])
- Media panel:
- Participants redialing. ([#241], [#233])

### Changed

Expand Down Expand Up @@ -73,6 +75,8 @@ All user visible changes to this project will be documented in this file. This p
[#217]: /../../pull/217
[#218]: /../../pull/218
[#221]: /../../pull/221
[#233]: /../../issues/233
[#241]: /../../pull/241



Expand Down
1 change: 1 addition & 0 deletions assets/l10n/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ label_offline = Offline
label_online = Online
label_or_register = or register
label_outgoing_call = Outgoing call
label_participant_redial_successfully = Participant redialed
label_participants = Participants
label_participants_added_successfully = Participants successfully added
label_password = Password
Expand Down
1 change: 1 addition & 0 deletions assets/l10n/ru-RU.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ label_offline = Офлайн
label_online = Онлайн
label_or_register = или регистрация
label_outgoing_call = Исходящий звонок
label_participant_redial_successfully = Участник перенабран
label_participants = Участники
label_participants_added_successfully = Участники успешно добавлены
label_password = Пароль
Expand Down
27 changes: 27 additions & 0 deletions lib/api/backend/graphql/mutation/call/RedialChatCallMember.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright © 2022 IT ENGINEERING MANAGEMENT INC, <https://github.com/team113>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License v3.0 as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License v3.0 for
# more details.
#
# You should have received a copy of the GNU Affero General Public License v3.0
# along with this program. If not, see
# <https://www.gnu.org/licenses/agpl-3.0.html>.

mutation RedialChatCallMember($chatId: ChatId!, $memberId: UserId!) {
redialChatCallMember(chatId: $chatId, memberId: $memberId) {
__typename
... on ChatCallEventsVersioned {
...ChatCallEventsVersioned
}
... on RedialChatCallMemberError {
code
}
}
}
4 changes: 4 additions & 0 deletions lib/domain/repository/call.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ abstract class AbstractCallRepository {
ChatName? groupName,
);

/// Redials a [User] who left or declined the ongoing [ChatCall] in the
/// specified [Chat]-group by the authenticated [MyUser].
Future<void> redialChatCallMember(ChatId chatId, UserId memberId);

/// Generates the [ChatCallCredentials] for a [Chat] identified by the
/// provided [id].
///
Expand Down
12 changes: 11 additions & 1 deletion lib/domain/service/call.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,11 @@ class CallService extends DisposableService {

if (deviceId != null) {
await _callsRepo.leave(chatId, deviceId);
_callsRepo.remove(chatId);
} else {
await _callsRepo.decline(chatId);
}

_callsRepo.remove(chatId);
WebUtils.removeCall(chatId);
}

Expand Down Expand Up @@ -289,6 +291,14 @@ class CallService extends DisposableService {
}
}

/// Redials a [User] who left or declined the ongoing [ChatCall] in the
/// specified [Chat]-group by the authenticated [MyUser].
Future<void> redialChatCallMember(ChatId chatId, UserId memberId) async {
if (_callsRepo.contains(chatId)) {
await _callsRepo.redialChatCallMember(chatId, memberId);
}
}

/// Moves an ongoing [ChatCall] in a [Chat]-dialog to a newly created
/// [Chat]-group, optionally adding new members.
Future<void> transformDialogCallIntoGroupCall(
Expand Down
46 changes: 46 additions & 0 deletions lib/provider/gql/components/call.dart
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,52 @@ abstract class CallGraphQlMixin {
as ChatCallEventsVersionedMixin?);
}

/// Redials a [User] who left or declined the ongoing [ChatCall] in the
/// specified [Chat]-group by the authenticated [MyUser].
///
/// For using this mutation the authenticated [MyUser] must be a member of the
/// ongoing [ChatCall].
///
/// Redialed [User] should see the [ChatCall.answered] indicator as `false`,
/// and the ongoing [ChatCall] appearing in his [incomingCallsTopEvents]
/// again.
///
/// ### Authentication
///
/// Mandatory.
///
/// ### Result
///
/// One of the following [ChatCallEvent]s may be produced on success:
/// - [EventChatCallMemberRedialed].
///
/// ### Idempotent
///
/// Succeeds as no-op (and returns no [ChatEvent]) if the redialed [User]
/// didn't decline or leave the [ChatCall] yet, or has been redialed already.
Future<ChatCallEventsVersionedMixin?> redialChatCallMember(
ChatId chatId,
UserId memberId,
) async {
final variables = RedialChatCallMemberArguments(
chatId: chatId,
memberId: memberId,
);
final QueryResult result = await client.mutate(
MutationOptions(
operationName: 'RedialChatCallMember',
document: RedialChatCallMemberMutation(variables: variables).document,
variables: variables.toJson(),
),
onException: (data) => RedialChatCallMemberException(
(RedialChatCallMember$Mutation.fromJson(data).redialChatCallMember
as RedialChatCallMember$Mutation$RedialChatCallMember$RedialChatCallMemberError)
.code),
);
return (RedialChatCallMember$Mutation.fromJson(result.data!)
.redialChatCallMember as ChatCallEventsVersionedMixin?);
}

/// Moves an ongoing [ChatCall] in a [Chat]-dialog to a newly created
/// [Chat]-group, optionally adding new members.
///
Expand Down
31 changes: 31 additions & 0 deletions lib/provider/gql/exceptions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,37 @@ class ToggleChatCallHandException
}
}

/// Exception of `Mutation.redialChatCallMember` described in the [code].
class RedialChatCallMemberException
with LocalizedExceptionMixin
implements Exception {
const RedialChatCallMemberException(this.code);

/// Reason of why the mutation has failed.
final RedialChatCallMemberErrorCode code;

@override
String toString() => 'RedialChatCallMemberException($code)';

@override
String toMessage() {
switch (code) {
case RedialChatCallMemberErrorCode.notCallMember:
return 'err_not_call_member'.l10n;
case RedialChatCallMemberErrorCode.noCall:
return 'err_call_not_found'.l10n;
case RedialChatCallMemberErrorCode.unknownChat:
return 'err_unknown_chat'.l10n;
case RedialChatCallMemberErrorCode.notChatMember:
return 'err_not_member'.l10n;
case RedialChatCallMemberErrorCode.notGroup:
return 'err_contact_not_group'.l10n;
case RedialChatCallMemberErrorCode.artemisUnknown:
return 'err_unknown'.l10n;
}
}
}

/// Exception of `Mutation.createChatDirectLink` described in the [code].
class CreateChatDirectLinkException
with LocalizedExceptionMixin
Expand Down
4 changes: 4 additions & 0 deletions lib/store/call.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ class CallRepository implements AbstractCallRepository {
Future<void> toggleHand(ChatId chatId, bool raised) =>
_graphQlProvider.toggleChatCallHand(chatId, raised);

@override
Future<void> redialChatCallMember(ChatId chatId, UserId memberId) =>
_graphQlProvider.redialChatCallMember(chatId, memberId);

@override
Future<void> transformDialogCallIntoGroupCall(
ChatId chatId,
Expand Down
15 changes: 15 additions & 0 deletions lib/ui/page/call/participant/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import '/l10n/l10n.dart';
import '/provider/gql/exceptions.dart'
show
AddChatMemberException,
RedialChatCallMemberException,
RemoveChatMemberException,
TransformDialogCallIntoGroupCallException;
import '/util/message_popup.dart';
Expand Down Expand Up @@ -185,6 +186,20 @@ class ParticipantController extends GetxController {
}
}

/// Redials by specified [UserId] who left or declined the ongoing [ChatCall].
Future<void> redialChatCallMember(UserId memberId) async {
MessagePopup.success('label_participant_redial_successfully'.l10n);

try {
await _callService.redialChatCallMember(chatId.value, memberId);
} on RedialChatCallMemberException catch (e) {
MessagePopup.error(e);
} catch (e) {
MessagePopup.error(e);
rethrow;
}
}

/// Fetches the [chat].
void _fetchChat() async {
chat.value = null;
Expand Down
4 changes: 1 addition & 3 deletions lib/ui/page/call/participant/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,7 @@ class ParticipantView extends StatelessWidget {
color: Theme.of(context).colorScheme.secondary,
type: MaterialType.circle,
child: InkWell(
onTap: () {
// TODO: Redial the provided [user].
},
onTap: () => c.redialChatCallMember(user.id),
borderRadius: BorderRadius.circular(60),
child: SizedBox(
width: 30,
Expand Down

0 comments on commit f7ee66e

Please sign in to comment.