Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added subscribe and unsubscribe for notification service #86

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/classes/internal.NotificationService.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ The NotificationService allows inviting participants to a conference.

### Methods

- [subscribe](internal.NotificationService.md#subscribe)
- [unsubscribe](internal.NotificationService.md#unsubscribe)
- [decline](internal.NotificationService.md#decline)
- [invite](internal.NotificationService.md#invite)
- [onInvitationReceived](internal.NotificationService.md#oninvitationreceived)
Expand All @@ -24,6 +26,42 @@ The NotificationService allows inviting participants to a conference.

## Methods

### subscribe

▸ **subscribe**(`events`): `Promise`<`void`\>

Subscribes to the specified notifications.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `events` | [`Subscription`](../interfaces/internal.Subscription.md)[] | An array of the subscribed subscription types. |

#### Returns

`Promise`<`void`\>

___

### unsubscribe

▸ **unsubscribe**(`events`): `Promise`<`void`\>

Unsubscribes from the specified notifications.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `events` | [`Subscription`](../interfaces/internal.Subscription.md)[] | An array of the subscribed subscription types. |

#### Returns

`Promise`<`void`\>

___

### decline

▸ **decline**(`conference`): `Promise`<`void`\>
Expand Down
28 changes: 28 additions & 0 deletions docs/interfaces/internal.Subscription.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Interface: Subscription

[internal](../modules/internal.md).Subscription

The Subscription model is an interface for all subscription types.

## Table of contents

### Properties

- [type](internal.Subscription.md#type)
- [conferenceAlias](internal.Subscription.md#conferencealias)

## Properties

### type

• **type**: `string`

The subscription type.

___

### conferenceAlias

• **conferenceAlias**: `string`

The conference alias.
1 change: 1 addition & 0 deletions docs/modules/internal.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
- [FileConverted](../interfaces/internal.FileConverted.md)
- [FilePresentation](../interfaces/internal.FilePresentation.md)
- [InvitationReceivedEventType](../interfaces/internal.InvitationReceivedEventType.md)
- [Subscription](../interfaces/internal.Subscription.md)
- [RecordingStatusUpdatedEventType](../interfaces/internal.RecordingStatusUpdatedEventType.md)
- [Recording](../interfaces/internal.Recording.md)
- [VideoPresentationEventType](../interfaces/internal.VideoPresentationEventType.md)
Expand Down
25 changes: 25 additions & 0 deletions example/src/components/DolbyIOProvider/DolbyIOProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import type {
Conference,
Participant,
} from '../../../../src/services/conference/models';
import {
SubscriptionType
} from '../../../../src/services/notification/models';

export interface IDolbyIOProvider {
isInitialized?: Boolean;
Expand Down Expand Up @@ -207,6 +210,17 @@ const DolbyIOProvider: React.FC = ({ children }) => {
'@conference-previous',
JSON.stringify(joinedConference)
);

await CommsAPI.notification.subscribe(
[
SubscriptionType.ActiveParticipants,
SubscriptionType.ConferenceCreated,
SubscriptionType.ConferenceEnded,
SubscriptionType.InvitationReceived,
SubscriptionType.ParticipantJoined,
SubscriptionType.ParticipantLeft
].map( (s) => { return { type: s, conferenceAlias: alias } })
);
} catch (e: any) {
Alert.alert('Conference not joined', e.toString());
}
Expand Down Expand Up @@ -290,6 +304,17 @@ const DolbyIOProvider: React.FC = ({ children }) => {
};
const leave = async (leaveRoom: boolean) => {
try {
await CommsAPI.notification.unsubscribe(
[
SubscriptionType.ActiveParticipants,
SubscriptionType.ConferenceCreated,
SubscriptionType.ConferenceEnded,
SubscriptionType.InvitationReceived,
SubscriptionType.ParticipantJoined,
SubscriptionType.ParticipantLeft
].map( (s) => { return { type: s, conferenceAlias: conference?.alias ?? "" } })
);

const conferenceLeaveOptions = {
leaveRoom,
};
Expand Down
60 changes: 60 additions & 0 deletions ios/Services/Models/SubscriptionDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import Foundation
import VoxeetSDK

enum Event: String {
case invitationReceived = "SUBSCRIPTION_TYPE_INVITATION_RECEIVED"
case activeParticipants = "SUBSCRIPTION_TYPE_ACTIVE_PARTICIPANTS"
case conferenceCreated = "SUBSCRIPTION_TYPE_CONFERENCE_CREATED"
case conferenceEnded = "SUBSCRIPTION_TYPE_CONFERENCE_ENDED"
case participantJoined = "SUBSCRIPTION_TYPE_PARTICIPANT_JOINED"
case participantLeft = "SUBSCRIPTION_TYPE_PARTICIPANT_LEFT"
}

internal struct SubscriptionDTO {

static func create(with dictionary: [String: Any]) -> SubscriptionDTO? {
guard
let type: String = dictionary.value(for: Keys.type),
let conferenceAlias: String = dictionary.value(for: Keys.conferenceAlias)
else { return nil }

return SubscriptionDTO(type: type, conferenceAlias: conferenceAlias)
}

let type: String
let conferenceAlias: String

func subscription() -> VTSubscribeBase? {
switch type {
case Event.invitationReceived.rawValue:
return VTSubscribeInvitation(conferenceAlias: conferenceAlias)
case Event.activeParticipants.rawValue:
return VTSubscribeActiveParticipants(conferenceAlias: conferenceAlias)
case Event.conferenceCreated.rawValue:
return VTSubscribeConferenceCreated(conferenceAlias: conferenceAlias)
case Event.conferenceEnded.rawValue:
return VTSubscribeConferenceEnded(conferenceAlias: conferenceAlias)
case Event.participantJoined.rawValue:
return VTSubscribeParticipantJoined(conferenceAlias: conferenceAlias)
case Event.participantLeft.rawValue:
return VTSubscribeParticipantLeft(conferenceAlias: conferenceAlias)
default:
return nil
}
}
}

// MARK: - ReactModelMappable
extension SubscriptionDTO: ReactModelMappable {
func toReactModel() -> ReactModelType {
return [
Keys.type: type,
Keys.conferenceAlias: conferenceAlias
].mapKeysToRawValue()
}
}

// MARK: - ReactModel Keys
private enum Keys: String {
case type, conferenceAlias
}
24 changes: 24 additions & 0 deletions ios/Services/NotificationService/NotificationServiceModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,30 @@ public class NotificationServiceModule: ReactEmitter {
VoxeetSDK.shared.notification.delegate = nil;
}

/// Subscribes to the specified notifications.
/// - Parameters:
/// - events: An array of the subscribed subscription types.
/// - resolve: returns on success
/// - reject: returns error on failure
@objc(subscribe:resolver:rejecter:)
public func subscribe(events: [[String: Any]],
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock) {
VoxeetSDK.shared.notification.subscribe(subscriptions: events.compactMap { SubscriptionDTO.create(with:$0)?.subscription() })
}

/// Unsubscribes from the specified notifications.
/// - Parameters:
/// - events: An array of the subscribed subscription types.
/// - resolve: returns on success
/// - reject: returns error on failure
@objc(unsubscribe:resolver:rejecter:)
public func unsubscribe(events: [[String: Any]],
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock) {
VoxeetSDK.shared.notification.unsubscribe(subscriptions: events.compactMap { SubscriptionDTO.create(with:$0)?.subscription() })
}

/// Notifies conference participants about a conference invitation.
/// - Parameters:
/// - conference: The conference object.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

@interface RCT_EXTERN_REMAP_MODULE(CommsAPINotificationServiceModule, RNNotificationServiceModule, NSObject)

RCT_EXTERN_METHOD(subscribe:(NSArray<NSDictionary *> * _Nonnull)events
resolver:(RCTPromiseResolveBlock _Nonnull)resolve
rejecter:(RCTPromiseRejectBlock _Nonnull)reject);

RCT_EXTERN_METHOD(unsubscribe:(NSArray<NSDictionary *> * _Nonnull)events
resolver:(RCTPromiseResolveBlock _Nonnull)resolve
rejecter:(RCTPromiseRejectBlock _Nonnull)reject);

RCT_EXTERN_METHOD(invite:(NSDictionary * _Nonnull)conference
participants:(NSArray<NSDictionary *> * _Nonnull)participants
resolver:(RCTPromiseResolveBlock _Nonnull)resolve
Expand Down
17 changes: 17 additions & 0 deletions src/services/notification/NotificationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
} from '../conference/models';
import { NotificationServiceEventNames } from './events';
import type { InvitationReceivedEventType } from './events';
import type { Subscription } from './models';

const { CommsAPINotificationServiceModule } = NativeModules;

Expand All @@ -20,6 +21,22 @@ export class NotificationService {
/** @internal */
_nativeEvents = new NativeEvents(CommsAPINotificationServiceModule);

/**
* Subscribes to the specified notifications.
* @param events An array of the subscribed subscription types.
*/
public async subscribe(events: Subscription[]): Promise<void> {
return this._nativeModule.subscribe(events);
}

/**
* Unsubscribes from the specified notifications.
* @param events An array of the subscribed subscription types.
*/
public async unsubscribe(events: Subscription[]): Promise<void> {
return this._nativeModule.unsubscribe(events);
}

/**
* Declines the conference invitation.
* @param conference The conference object.
Expand Down
22 changes: 22 additions & 0 deletions src/services/notification/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ const testConference: Conference = {
describe('NotificationService', () => {
NotificationService._nativeEvents.addListener = jest.fn();

describe('subscribe()', () => {
it('should invoke subscribe method with correct arguments', () => {
NotificationService.subscribe([
{ type: 'event', conferenceAlias: 'alias' },
]);
expect(CommsAPINotificationServiceModule.subscribe).toHaveBeenCalledWith([
{ type: 'event', conferenceAlias: 'alias' },
]);
});
});

describe('unsubscribe()', () => {
it('should invoke unsubscribe method with correct arguments', () => {
NotificationService.unsubscribe([
{ type: 'event', conferenceAlias: 'alias' },
]);
expect(
CommsAPINotificationServiceModule.unsubscribe
).toHaveBeenCalledWith([{ type: 'event', conferenceAlias: 'alias' }]);
});
});

describe('invite()', () => {
it('should invoke exported invite method with correct arguments', () => {
NotificationService.invite(testConference, [{ info: {} }]);
Expand Down
17 changes: 17 additions & 0 deletions src/services/notification/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/** The SubscriptionType model gathers the subscription types. */
export enum SubscriptionType {
InvitationReceived = 'SUBSCRIPTION_TYPE_INVITATION_RECEIVED',
ActiveParticipants = 'SUBSCRIPTION_TYPE_ACTIVE_PARTICIPANTS',
ConferenceCreated = 'SUBSCRIPTION_TYPE_CONFERENCE_CREATED',
ConferenceEnded = 'SUBSCRIPTION_TYPE_CONFERENCE_ENDED',
ParticipantJoined = 'SUBSCRIPTION_TYPE_PARTICIPANT_JOINED',
ParticipantLeft = 'SUBSCRIPTION_TYPE_PARTICIPANT_LEFT',
}

/** The Subscription model is an interface for all subscription types. */
export interface Subscription {
/** The subscription type. */
type: string;
/** The conference alias. */
conferenceAlias: string;
}
2 changes: 2 additions & 0 deletions src/setupTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ jest.mock('react-native', () => {
getParticipant: jest.fn(),
};
RN.NativeModules.CommsAPINotificationServiceModule = {
subscribe: jest.fn(),
unsubscribe: jest.fn(),
invite: jest.fn(),
decline: jest.fn(),
};
Expand Down