diff --git a/src/definition/accessors/INotifier.ts b/src/definition/accessors/INotifier.ts index 35cf457e7..7610d56eb 100644 --- a/src/definition/accessors/INotifier.ts +++ b/src/definition/accessors/INotifier.ts @@ -3,6 +3,31 @@ import { IRoom } from '../rooms'; import { IUser } from '../users'; import { IMessageBuilder } from './IMessageBuilder'; +export enum TypingScope { + Room = 'room', +} + +export interface ITypingOptions { + /** + * The typing scope where the typing message should be presented, + * TypingScope.Room by default. + */ + scope?: TypingScope; + /** + * The id of the typing scope + * + * TypingScope.Room <-> room.id + */ + id: string; + /** + * The name of the user who is typing the message + * + * **Note**: If not provided, it will use app assigned + * user's name by default. + */ + username?: string; +} + export interface INotifier { /** * Notifies the provided user of the provided message. @@ -26,6 +51,13 @@ export interface INotifier { */ notifyRoom(room: IRoom, message: IMessage): Promise; + /** + * Notifies all of the users a typing indicator in the provided scope. + * + * @returns a cancellation function to stop typing + */ + typing(options: ITypingOptions): Promise<() => Promise>; + /** Gets a new message builder for building a notification message. */ getMessageBuilder(): IMessageBuilder; } diff --git a/src/server/accessors/Notifier.ts b/src/server/accessors/Notifier.ts index 208bcbdc4..c8fd65422 100644 --- a/src/server/accessors/Notifier.ts +++ b/src/server/accessors/Notifier.ts @@ -1,4 +1,5 @@ import { IMessageBuilder, INotifier } from '../../definition/accessors'; +import { ITypingOptions, TypingScope } from '../../definition/accessors/INotifier'; import { IMessage } from '../../definition/messages'; import { IRoom } from '../../definition/rooms'; import { IUser } from '../../definition/users'; @@ -32,6 +33,19 @@ export class Notifier implements INotifier { await this.msgBridge.notifyRoom(room, message, this.appId); } + public async typing(options: ITypingOptions): Promise<() => Promise> { + options.scope = options.scope || TypingScope.Room; + + if (!options.username) { + const appUser = await this.userBridge.getAppUser(this.appId); + options.username = appUser && appUser.name || ''; + } + + this.msgBridge.typing({ ...options, isTyping: true }); + + return () => this.msgBridge.typing({ ...options, isTyping: false }); + } + public getMessageBuilder(): IMessageBuilder { return new MessageBuilder(); } diff --git a/src/server/bridges/IMessageBridge.ts b/src/server/bridges/IMessageBridge.ts index 83b5a4228..c4d4f7e98 100644 --- a/src/server/bridges/IMessageBridge.ts +++ b/src/server/bridges/IMessageBridge.ts @@ -1,11 +1,17 @@ +import { ITypingOptions } from '../../definition/accessors/INotifier'; import { IMessage } from '../../definition/messages'; import { IRoom } from '../../definition/rooms'; import { IUser } from '../../definition/users/IUser'; +export interface ITypingDescriptor extends ITypingOptions { + isTyping: boolean; +} + export interface IMessageBridge { create(message: IMessage, appId: string): Promise; getById(messageId: string, appId: string): Promise; update(message: IMessage, appId: string): Promise; notifyUser(user: IUser, message: IMessage, appId: string): Promise; notifyRoom(room: IRoom, message: IMessage, appId: string): Promise; + typing(options: ITypingDescriptor): Promise; } diff --git a/tests/test-data/bridges/messageBridge.ts b/tests/test-data/bridges/messageBridge.ts index 09d37ce8b..b9fc60f91 100644 --- a/tests/test-data/bridges/messageBridge.ts +++ b/tests/test-data/bridges/messageBridge.ts @@ -1,8 +1,8 @@ import { IMessage } from '../../../src/definition/messages'; import { IRoom } from '../../../src/definition/rooms'; import { IUser } from '../../../src/definition/users'; - import { IMessageBridge } from '../../../src/server/bridges'; +import { ITypingDescriptor } from '../../../src/server/bridges/IMessageBridge'; export class TestsMessageBridge implements IMessageBridge { public create(message: IMessage, appId: string): Promise { @@ -24,4 +24,8 @@ export class TestsMessageBridge implements IMessageBridge { public notifyRoom(room: IRoom, message: IMessage, appId: string): Promise { throw new Error('Method not implemented.'); } + + public typing(options: ITypingDescriptor): Promise { + throw new Error('Method not implemented.'); + } }