Commit 1ab548f4 by Torkel Ödegaard Committed by GitHub

Merge pull request #15832 from grafana/stop-playlist

Alternative fix to detecting when to stop a playlist
parents 2604e9e4 3375c72d
...@@ -7,6 +7,7 @@ import coreModule from '../../core/core_module'; ...@@ -7,6 +7,7 @@ import coreModule from '../../core/core_module';
import appEvents from 'app/core/app_events'; import appEvents from 'app/core/app_events';
import locationUtil from 'app/core/utils/location_util'; import locationUtil from 'app/core/utils/location_util';
import kbn from 'app/core/utils/kbn'; import kbn from 'app/core/utils/kbn';
import { store } from 'app/store/store';
export class PlaylistSrv { export class PlaylistSrv {
private cancelPromise: any; private cancelPromise: any;
...@@ -15,6 +16,8 @@ export class PlaylistSrv { ...@@ -15,6 +16,8 @@ export class PlaylistSrv {
private interval: number; private interval: number;
private startUrl: string; private startUrl: string;
private numberOfLoops = 0; private numberOfLoops = 0;
private storeUnsub: () => void;
private validPlaylistUrl: string;
isPlaying: boolean; isPlaying: boolean;
/** @ngInject */ /** @ngInject */
...@@ -39,15 +42,16 @@ export class PlaylistSrv { ...@@ -39,15 +42,16 @@ export class PlaylistSrv {
const dash = this.dashboards[this.index]; const dash = this.dashboards[this.index];
const queryParams = this.$location.search(); const queryParams = this.$location.search();
const filteredParams = _.pickBy(queryParams, value => value !== null); const filteredParams = _.pickBy(queryParams, value => value !== null);
const nextDashboardUrl = locationUtil.stripBaseFromUrl(dash.url);
// this is done inside timeout to make sure digest happens after // this is done inside timeout to make sure digest happens after
// as this can be called from react // as this can be called from react
this.$timeout(() => { this.$timeout(() => {
const stripedUrl = locationUtil.stripBaseFromUrl(dash.url); this.$location.url(nextDashboardUrl + '?' + toUrlParams(filteredParams));
this.$location.url(stripedUrl + '?' + toUrlParams(filteredParams));
}); });
this.index++; this.index++;
this.validPlaylistUrl = nextDashboardUrl;
this.cancelPromise = this.$timeout(() => this.next(), this.interval); this.cancelPromise = this.$timeout(() => this.next(), this.interval);
} }
...@@ -56,6 +60,15 @@ export class PlaylistSrv { ...@@ -56,6 +60,15 @@ export class PlaylistSrv {
this.next(); this.next();
} }
// Detect url changes not caused by playlist srv and stop playlist
storeUpdated() {
const state = store.getState();
if (state.location.path !== this.validPlaylistUrl) {
this.stop();
}
}
start(playlistId) { start(playlistId) {
this.stop(); this.stop();
...@@ -63,6 +76,10 @@ export class PlaylistSrv { ...@@ -63,6 +76,10 @@ export class PlaylistSrv {
this.index = 0; this.index = 0;
this.isPlaying = true; this.isPlaying = true;
// setup location tracking
this.storeUnsub = store.subscribe(() => this.storeUpdated());
this.validPlaylistUrl = this.$location.path();
appEvents.emit('playlist-started'); appEvents.emit('playlist-started');
return this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => { return this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
...@@ -85,6 +102,10 @@ export class PlaylistSrv { ...@@ -85,6 +102,10 @@ export class PlaylistSrv {
this.index = 0; this.index = 0;
this.isPlaying = false; this.isPlaying = false;
if (this.storeUnsub) {
this.storeUnsub();
}
if (this.cancelPromise) { if (this.cancelPromise) {
this.$timeout.cancel(this.cancelPromise); this.$timeout.cancel(this.cancelPromise);
} }
......
import configureMockStore from 'redux-mock-store';
import { PlaylistSrv } from '../playlist_srv'; import { PlaylistSrv } from '../playlist_srv';
import { setStore } from 'app/store/store';
const mockStore = configureMockStore();
setStore(
mockStore({
location: {},
})
);
const dashboards = [{ url: 'dash1' }, { url: 'dash2' }]; const dashboards = [{ url: 'dash1' }, { url: 'dash2' }];
...@@ -19,6 +29,7 @@ const createPlaylistSrv = (): [PlaylistSrv, { url: jest.MockInstance<any, any> } ...@@ -19,6 +29,7 @@ const createPlaylistSrv = (): [PlaylistSrv, { url: jest.MockInstance<any, any> }
const mockLocation = { const mockLocation = {
url: jest.fn(), url: jest.fn(),
search: () => ({}), search: () => ({}),
path: () => '/playlists/1',
}; };
const mockTimeout = jest.fn(); const mockTimeout = jest.fn();
...@@ -96,4 +107,32 @@ describe('PlaylistSrv', () => { ...@@ -96,4 +107,32 @@ describe('PlaylistSrv', () => {
expect(hrefMock).toHaveBeenCalledTimes(3); expect(hrefMock).toHaveBeenCalledTimes(3);
expect(hrefMock).toHaveBeenLastCalledWith(initialUrl); expect(hrefMock).toHaveBeenLastCalledWith(initialUrl);
}); });
it('storeUpdated should stop playlist when navigating away', async () => {
await srv.start(1);
srv.storeUpdated();
expect(srv.isPlaying).toBe(false);
});
it('storeUpdated should not stop playlist when navigating to next dashboard', async () => {
await srv.start(1);
srv.next();
setStore(
mockStore({
location: {
path: 'dash2',
},
})
);
expect((srv as any).validPlaylistUrl).toBe('dash2');
srv.storeUpdated();
expect(srv.isPlaying).toBe(true);
});
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment