From ff06c96de2e3310c94b794115329b3d177758cc9 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Thu, 20 Sep 2018 06:19:28 -0700 Subject: [PATCH] Provide a way to prevent closing Webamp (#655) * Provide a way to prevent closing Webamp Fixes #653 * Fix typos for onWillClose in usage and types --- docs/usage.md | 15 +++++++++++++++ index.d.ts | 9 +++++++++ js/actionCreators/index.ts | 20 +++++++++++++++++--- js/actionTypes.ts | 1 + js/index.js | 6 ++++++ js/types.ts | 4 ++++ js/webampLazy.js | 9 ++++++++- 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 808e14ed..dfb7e4d1 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -216,6 +216,21 @@ const unsubscribe = webamp.onTrackDidChange((track => { unsubscribe(); ``` +### `onWillClose(callback)` + +A callback which will be called when Webamp is _about to_ close. Returns an "unsubscribe" function. The callback will be passed a `cancel` function which you can use to conditionally prevent Webamp from being closed. + +```JavaScript +const unsubscribe = webamp.onWillClose((cancel) => { + if (!window.confirm("Are you sure you want to close Webamp?")) { + cancel(); + } +}); + +// If at some point in the future you want to stop listening to these events: +unsubscribe(); +``` + ### `onClose(callback)` A callback which will be called when Webamp is closed. Returns an "unsubscribe" function. diff --git a/index.d.ts b/index.d.ts index 785c8edd..75491739 100644 --- a/index.d.ts +++ b/index.d.ts @@ -160,6 +160,15 @@ export default class Webamp { */ public onTrackDidChange(callback: (track: Track) => any): () => void; + /** + * A callback which will be called when Webamp is _about to_ close. Returns an + * "unsubscribe" function. The callback will be passed a `cancel` function + * which you can use to conditionally prevent Webamp from being closed. + * + * @returns An "unsubscribe" function. Useful if at some point in the future you want to stop listening to these events. + */ + public onWillClose(callback: (cancel: () => void) => any): () => void; + /** * A callback which will be called when Webamp is closed. * diff --git a/js/actionCreators/index.ts b/js/actionCreators/index.ts index 14203c1d..baa08af9 100644 --- a/js/actionCreators/index.ts +++ b/js/actionCreators/index.ts @@ -1,4 +1,9 @@ -import { CLOSE_WINAMP, STOP, TOGGLE_VISUALIZER_STYLE } from "../actionTypes"; +import { + CLOSE_WINAMP, + STOP, + TOGGLE_VISUALIZER_STYLE, + CLOSE_REQUESTED +} from "../actionTypes"; import { Dispatchable } from "../types"; export { @@ -71,8 +76,17 @@ export { export function close(): Dispatchable { return dispatch => { - dispatch({ type: STOP }); - dispatch({ type: CLOSE_WINAMP }); + // TODO: This could probably be improved by adding a "PREVENT_CLOSE" action + // or something, but this works okay for now. + let defaultPrevented = false; + const cancel = () => { + defaultPrevented = true; + }; + dispatch({ type: CLOSE_REQUESTED, cancel }); + if (!defaultPrevented) { + dispatch({ type: STOP }); + dispatch({ type: CLOSE_WINAMP }); + } }; } diff --git a/js/actionTypes.ts b/js/actionTypes.ts index 98243293..ec1ce8f5 100644 --- a/js/actionTypes.ts +++ b/js/actionTypes.ts @@ -70,3 +70,4 @@ export const DISABLE_MARQUEE = "DISABLE_MARQUEE"; export const SET_DUMMY_VIZ_DATA = "SET_DUMMY_VIZ_DATA"; export const SET_WINDOW_VISIBILITY = "SET_WINDOW_VISIBILITY"; export const LOADING = "LOADING"; +export const CLOSE_REQUESTED = "CLOSE_REQUESTED"; diff --git a/js/index.js b/js/index.js index 92153d39..c347e586 100644 --- a/js/index.js +++ b/js/index.js @@ -262,6 +262,12 @@ Raven.context(() => { }); } + webamp.onWillClose(cancel => { + if (!window.confirm("Are you sure you want to close Webamp?")) { + cancel(); + } + }); + webamp.renderWhenReady(document.getElementById("app")); // Expose webamp instance for debugging and integration tests. diff --git a/js/types.ts b/js/types.ts index dc9dc3c9..cf72e23f 100644 --- a/js/types.ts +++ b/js/types.ts @@ -336,6 +336,10 @@ export type Action = } | { type: "MINIMIZE_WINAMP"; + } + | { + type: "CLOSE_REQUESTED"; + cancel: () => void; }; export interface WebampWindow { diff --git a/js/webampLazy.js b/js/webampLazy.js index 0fb88f08..34eb257b 100644 --- a/js/webampLazy.js +++ b/js/webampLazy.js @@ -27,7 +27,8 @@ import { LOADED, REGISTER_VISUALIZER, SET_Z_INDEX, - SET_MEDIA + SET_MEDIA, + CLOSE_REQUESTED } from "./actionTypes"; import Emitter from "./emitter"; @@ -182,6 +183,12 @@ class Winamp { this.store.dispatch(loadMediaFiles(tracks, LOAD_STYLE.PLAY)); } + onWillClose(cb) { + return this._actionEmitter.on(CLOSE_REQUESTED, action => { + cb(action.cancel); + }); + } + onClose(cb) { return this._actionEmitter.on(CLOSE_WINAMP, cb); }