Skip to content

Commit

Permalink
feat: Secondary notification queue implementation
Browse files Browse the repository at this point in the history
* feat: Notification queues fixed #89 by @theimo1221
* Removal of events and compliance to tests
* Two PlayNotification Calls with 2nd having immediate resolve
* Two PlayNotification Calls with First Reolving Promise after 2nd
* Implement general Timeout functionality within PlayNotification and extend tests
* Revert changes to "returns false when not playing"
* Move new tests to seperate describe Block
* Add individual Timeout for specific queue items plus Test
* Clear specific timeout after it being played
* chore: Lint errors
* chore: Second TTS method
* chore: Fixing debug style
* chore: Fixing tests

Not merged:

* ~~Always trigger "STOPPED" event~~

Co-authored-by: Thiemo <[email protected]>
  • Loading branch information
svrooij and Thiemo authored Jan 18, 2021
1 parent 85025b9 commit 94d2d5e
Show file tree
Hide file tree
Showing 6 changed files with 1,379 additions and 23 deletions.
2 changes: 1 addition & 1 deletion examples/play-notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ sonos.PlayNotification({
// process.exit(0)
// }, 2000)
// })
// .catch(console.error)
// .catch(console.error)
93 changes: 93 additions & 0 deletions src/models/notificationQueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { PlayNotificationOptions } from './requests';

export interface NotificationQueueItem {
/**
* Desired PlayNotificationOptions
*
* @type {number}
*/
options: PlayNotificationOptions;

/**
* The Resolve Promise we have to resolve once finished successfully
*
* @type {(reject: boolean | PromiseLike<boolean>) => void}
*/
resolve: (resolve: boolean | PromiseLike<boolean>) => void;

/**
* The Reject Promise we have to resolve once finished with failure
*
* @type {(reject: boolean | PromiseLike<boolean>) => void}
*/
reject: (reject: boolean | PromiseLike<boolean>) => void;

/**
* Whether we should only resolve the promise when we reverted correctly
*
* @type {boolean}
*/
resolveAfterRevert: boolean;

/**
* Object with details regarding the timeout for this queue item
*
* @type {NotificationQueueTimeoutItem}
*/
generalTimeout?: NotificationQueueTimeoutItem;

/**
* Object with details regarding the timeout for this specific queue item (Starting when this is Queue Item becomes first)
*
* @type {NotificationQueueTimeoutItem}
*/
individualTimeout?: NotificationQueueTimeoutItem;
}

export class NotificationQueueTimeoutItem {
public constructor(
/**
* The timeout reference to clear if anything is okay
*
* @type {NotificationQueueTimeoutItem}
*/
public timeout: NodeJS.Timeout,

/**
* The timestamp when the timeout will fire
*
* @type {NotificationQueueTimeoutItem}
*/
public fireTime: number,
) { }

public timeLeft(): number {
return this.fireTime - (new Date()).getTime();
}
}

export class NotificationQueue {
public queue: NotificationQueueItem[] = [];

public promisesToResolve: Array<{
promise: (resolve: boolean | PromiseLike<boolean>) => void,
value: boolean,
timeout?: NotificationQueueTimeoutItem,
}> = [];

public playing = false;

/**
* Whether any item in the Queue changed the volume
*
* @type {boolean}
*/
public volumeChanged = false;

/**
* Whether the Queue played any item at all
*
* @type {boolean}
*/
public anythingPlayed = false;
}
21 changes: 21 additions & 0 deletions src/models/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,27 @@ export interface PlayNotificationOptionsBase {
* @memberof PlayNotificationOptionsBase
*/
volume?: number;

/**
*
* @deprecated Experimental feature, please dont depend on this
*/
resolveAfterRevert?: boolean;

/**
* In case no other timeout given this will result in 30 Minutes Default Timeout for Playing time only
* @deprecated Experimental feature, please dont depend on this
*/
defaultTimeout?: number;

/**
* This timeout starts as soon as this item is played next in the queue.
* Thus in case of an error resolving the PlayNotificationCall with false.
*
* @deprecated Experimental feature, please dont depend on this
*/
specificTimeout?: number;

}

export interface PlayNotificationOptions extends PlayNotificationOptionsBase {
Expand Down
2 changes: 1 addition & 1 deletion src/services/base-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ export default abstract class BaseService <TServiceEvent> {
}
});
this.events.on('newListener', async () => {
this.debug('Listener added');
this.debug('Listener added (sid: \'%s\', SONOS_DISABLE_EVENTS: %o)', this.sid, (typeof process.env.SONOS_DISABLE_EVENTS === 'undefined'));
if (this.sid === undefined && process.env.SONOS_DISABLE_EVENTS === undefined) {
this.debug('Subscribing to events');
await this.subscribeForEvents()
Expand Down
Loading

0 comments on commit 94d2d5e

Please sign in to comment.