From 6d631fd4ee36a4ffe1ff165f4679b8304e27bb25 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 27 Feb 2020 16:53:29 +0000 Subject: [PATCH 1/7] Change useNotification to work with v1 JS API as well as v2 --- src/useNotification.ts | 33 ++++++++++++--------- src/utils/helpers/getNotificationWindow.ts | 34 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 src/utils/helpers/getNotificationWindow.ts diff --git a/src/useNotification.ts b/src/useNotification.ts index dc4bbdb..c1a7a8f 100644 --- a/src/useNotification.ts +++ b/src/useNotification.ts @@ -12,7 +12,9 @@ import { } from "react"; import ReactDOM from "react-dom"; import { IUseNotificationOptions } from "../index"; +import getNotificationWindow from "./utils/helpers/getNotificationWindow"; import { injectNode, injectNodes } from "./utils/helpers/inject"; +import { isWindowV1, isWindowV2 } from "./utils/helpers/isWindow"; import reducer, { INITIAL_WINDOW_STATE } from "./utils/reducers/WindowReducer"; import WINDOW_ACTION from "./utils/types/enums/WindowAction"; import WINDOW_STATE from "./utils/types/enums/WindowState"; @@ -34,6 +36,8 @@ export default ({ shouldInheritCss, shouldInheritScripts, }: IUseNotificationOptions) => { + const version = fin.Window.getCurrentSync().getWebWindow ? + OpenFinJavaScriptAPIVersion.TWO : OpenFinJavaScriptAPIVersion.ONE; const [name, setName] = useState(null); const [htmlDocument, setHtmlDocument] = useState(null); const [populateJsx, setPopulateJsx] = useState(null); @@ -57,9 +61,13 @@ export default ({ }, [parentDocument, injectNodes, htmlDocument]); useEffect(() => { - if (notificationWindow.windowRef) { + if (notificationWindow.windowRef && isWindowV1(notificationWindow.windowRef)) { setHtmlDocument( - (notificationWindow.windowRef as _Window).getWebWindow().document, + notificationWindow.windowRef.getNativeWindow().document, + ); + } else if (notificationWindow.windowRef && isWindowV2(notificationWindow.windowRef)) { + setHtmlDocument( + notificationWindow.windowRef.getWebWindow().document, ); } }, [notificationWindow.windowRef]); @@ -70,24 +78,23 @@ export default ({ ref && notificationWindow.state === WINDOW_STATE.LAUNCHING ) { - fin.Application.getCurrent().then(async (application) => { - const childWindows = await application.getChildWindows(); - childWindows.map((win) => { - if (win.identity.name && win.identity.name === name) { - dispatch({ - payload: win, - type: WINDOW_ACTION.SET_WINDOW, - }); - } + getNotificationWindow(version, name).then((childWindow) => { + dispatch({ + payload: childWindow, + type: WINDOW_ACTION.SET_WINDOW, }); dispatchNewState(WINDOW_STATE.LAUNCHED); - }); + }).catch((error) => { throw error; }); } }, [name, notificationWindow.state, ref]); useEffect(() => { if (ref && ref.noteWin) { - setName(ref.noteWin.windowOpts.name || null); + if (version === OpenFinJavaScriptAPIVersion.ONE) { + setName(ref.noteWin.windowOpts.uuid || null); + } else { + setName(ref.noteWin.windowOpts.name || null); + } } }, [ref]); diff --git a/src/utils/helpers/getNotificationWindow.ts b/src/utils/helpers/getNotificationWindow.ts new file mode 100644 index 0000000..81712c0 --- /dev/null +++ b/src/utils/helpers/getNotificationWindow.ts @@ -0,0 +1,34 @@ +import { _Window } from "openfin/_v2/api/window/window"; + +const getNotificationWindowV1 = (name: string): Promise => + new Promise((resolve, reject) => { + const application = fin.desktop.Application.getCurrent(); + application.getChildWindows((childWindows) => { + childWindows + // A "queueCounter" window needs to be filtered out (it has the same name/uuid): + .filter((win: any) => win.nativeWindow) + .map((win: any) => { + if (win.uuid && win.uuid === name) { + resolve(win); + } + }); + }, reject); + }); + +const getNotificationWindowV2 = (name: string): Promise<_Window> => + new Promise((resolve, reject) => { + fin.Application.getCurrent().then(async (application) => { + const childWindows = await application.getChildWindows(); + childWindows.map((win) => { + if (win.identity.name && win.identity.name === name) { + resolve(win); + } + }); + reject("No notification windows opened."); + }).catch(reject); + }); + +export default (version: OpenFinJavaScriptAPIVersion, name: string): Promise => + version === OpenFinJavaScriptAPIVersion.ONE ? + getNotificationWindowV1(name) : + getNotificationWindowV2(name); From 81f8017d3be8ac69872072c9b87d714d48a3de4b Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 27 Feb 2020 17:05:43 +0000 Subject: [PATCH 2/7] Refactor window options so the v1/v2 specific code is in getNotificationWindow --- src/useNotification.ts | 16 ++++++---------- src/utils/helpers/getNotificationWindow.ts | 18 +++++++++++------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/useNotification.ts b/src/useNotification.ts index c1a7a8f..535f1b8 100644 --- a/src/useNotification.ts +++ b/src/useNotification.ts @@ -38,7 +38,7 @@ export default ({ }: IUseNotificationOptions) => { const version = fin.Window.getCurrentSync().getWebWindow ? OpenFinJavaScriptAPIVersion.TWO : OpenFinJavaScriptAPIVersion.ONE; - const [name, setName] = useState(null); + const [windowOptions, setWindowOptions] = useState(null); const [htmlDocument, setHtmlDocument] = useState(null); const [populateJsx, setPopulateJsx] = useState(null); const [ref, setRef] = useState(null); @@ -74,11 +74,11 @@ export default ({ useEffect(() => { if ( - name && + windowOptions && ref && notificationWindow.state === WINDOW_STATE.LAUNCHING ) { - getNotificationWindow(version, name).then((childWindow) => { + getNotificationWindow(version, windowOptions).then((childWindow) => { dispatch({ payload: childWindow, type: WINDOW_ACTION.SET_WINDOW, @@ -86,15 +86,11 @@ export default ({ dispatchNewState(WINDOW_STATE.LAUNCHED); }).catch((error) => { throw error; }); } - }, [name, notificationWindow.state, ref]); + }, [windowOptions, notificationWindow.state, ref]); useEffect(() => { if (ref && ref.noteWin) { - if (version === OpenFinJavaScriptAPIVersion.ONE) { - setName(ref.noteWin.windowOpts.uuid || null); - } else { - setName(ref.noteWin.windowOpts.name || null); - } + setWindowOptions(ref.noteWin.windowOpts || null); } }, [ref]); @@ -107,7 +103,7 @@ export default ({ ) { populate(jsxElement); } - }, [jsx, populateJsx, name, notificationWindow]); + }, [jsx, populateJsx, windowOptions, notificationWindow]); useEffect(() => { if (shouldInheritCss) { diff --git a/src/utils/helpers/getNotificationWindow.ts b/src/utils/helpers/getNotificationWindow.ts index 81712c0..18b5817 100644 --- a/src/utils/helpers/getNotificationWindow.ts +++ b/src/utils/helpers/getNotificationWindow.ts @@ -1,6 +1,7 @@ import { _Window } from "openfin/_v2/api/window/window"; +import { WindowOption } from "openfin/_v2/api/window/windowOption"; -const getNotificationWindowV1 = (name: string): Promise => +const getNotificationWindowV1 = (windowOptions: WindowOption): Promise => new Promise((resolve, reject) => { const application = fin.desktop.Application.getCurrent(); application.getChildWindows((childWindows) => { @@ -8,19 +9,19 @@ const getNotificationWindowV1 = (name: string): Promise => // A "queueCounter" window needs to be filtered out (it has the same name/uuid): .filter((win: any) => win.nativeWindow) .map((win: any) => { - if (win.uuid && win.uuid === name) { + if (win.uuid && win.uuid === windowOptions.uuid) { resolve(win); } }); }, reject); }); -const getNotificationWindowV2 = (name: string): Promise<_Window> => +const getNotificationWindowV2 = (windowOptions: WindowOption): Promise<_Window> => new Promise((resolve, reject) => { fin.Application.getCurrent().then(async (application) => { const childWindows = await application.getChildWindows(); childWindows.map((win) => { - if (win.identity.name && win.identity.name === name) { + if (win.identity.name && win.identity.name === windowOptions.name) { resolve(win); } }); @@ -28,7 +29,10 @@ const getNotificationWindowV2 = (name: string): Promise<_Window> => }).catch(reject); }); -export default (version: OpenFinJavaScriptAPIVersion, name: string): Promise => +export default ( + version: OpenFinJavaScriptAPIVersion, + windowOptions: WindowOption, +): Promise => version === OpenFinJavaScriptAPIVersion.ONE ? - getNotificationWindowV1(name) : - getNotificationWindowV2(name); + getNotificationWindowV1(windowOptions) : + getNotificationWindowV2(windowOptions); From b215fe2837e0c10bc946343f367340546bc7f129 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 27 Feb 2020 17:09:13 +0000 Subject: [PATCH 3/7] Made types stricter --- src/utils/helpers/getNotificationWindow.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/helpers/getNotificationWindow.ts b/src/utils/helpers/getNotificationWindow.ts index 18b5817..e5d3fa3 100644 --- a/src/utils/helpers/getNotificationWindow.ts +++ b/src/utils/helpers/getNotificationWindow.ts @@ -1,14 +1,14 @@ import { _Window } from "openfin/_v2/api/window/window"; import { WindowOption } from "openfin/_v2/api/window/windowOption"; -const getNotificationWindowV1 = (windowOptions: WindowOption): Promise => +const getNotificationWindowV1 = (windowOptions: WindowOption): Promise => new Promise((resolve, reject) => { const application = fin.desktop.Application.getCurrent(); application.getChildWindows((childWindows) => { childWindows // A "queueCounter" window needs to be filtered out (it has the same name/uuid): - .filter((win: any) => win.nativeWindow) - .map((win: any) => { + .filter((win: fin.OpenFinWindow) => win.getNativeWindow()) + .map((win: fin.OpenFinWindow) => { if (win.uuid && win.uuid === windowOptions.uuid) { resolve(win); } From ac16ccfaeb839f66a849a87637729b0bf84a53ca Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 28 Feb 2020 10:33:15 +0000 Subject: [PATCH 4/7] Fix bug with useChildWindow where a re-launch of the child window caused a crash. Fix bug with useNotification so that if a child window is open when the notification is launched, the notification is modified, not the child window. Refactor getChildWindows helper to only deal with getting the child windows, no longer in choosing the correct one. This means that it can be used for both useNotification and useChildWindow. --- package-lock.json | 2 +- package.json | 2 +- src/useChildWindow.ts | 27 ++++++++------- src/useNotification.ts | 36 +++++++++++++++----- src/utils/helpers/getChildWindows.ts | 20 ++++++++++++ src/utils/helpers/getNotificationWindow.ts | 38 ---------------------- 6 files changed, 66 insertions(+), 59 deletions(-) create mode 100644 src/utils/helpers/getChildWindows.ts delete mode 100644 src/utils/helpers/getNotificationWindow.ts diff --git a/package-lock.json b/package-lock.json index 17da32a..11c12e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openfin-react-hooks", - "version": "2.0.2", + "version": "2.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ea3a2b0..86c9b52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openfin-react-hooks", - "version": "2.0.2", + "version": "2.0.3", "description": "A collection of React Hooks built on top of the Openfin API", "main": "dist/index.js", "scripts": { diff --git a/src/useChildWindow.ts b/src/useChildWindow.ts index 256adde..eb9a81b 100644 --- a/src/useChildWindow.ts +++ b/src/useChildWindow.ts @@ -1,9 +1,11 @@ +import { _Window } from "openfin/_v2/api/window/window"; import { WindowOption } from "openfin/_v2/api/window/windowOption"; import { useCallback, useEffect, useReducer, useState } from "react"; import ReactDOM from "react-dom"; import { IUseChildWindowOptions } from "../index"; import createWindow from "./utils/helpers/createWindow"; +import getChildWindows from "./utils/helpers/getChildWindows"; import { injectNode, injectNodes } from "./utils/helpers/inject"; import { isWindowV1, isWindowV2 } from "./utils/helpers/isWindow"; import reducer, { INITIAL_WINDOW_STATE } from "./utils/reducers/WindowReducer"; @@ -59,7 +61,10 @@ export default ({ return () => { if (childWindow.windowRef && isWindowV1(childWindow.windowRef)) { - childWindow.windowRef.getNativeWindow().onclose = null; + const nativeWindow = childWindow.windowRef.getNativeWindow(); + if (nativeWindow) { + nativeWindow.onclose = null; + } } else if (childWindow.windowRef && isWindowV2(childWindow.windowRef)) { childWindow.windowRef.removeListener("closed", reset); } @@ -96,16 +101,16 @@ export default ({ }, [childWindow.state]); const closeExistingWindow = useCallback(async () => { - const application = await fin.Application.getCurrent(); - const childWindows = await application.getChildWindows(); - - await Promise.all( - childWindows.map((win) => - win.identity.name && win.identity.name === name - ? win.close() - : Promise.resolve(), - ), - ); + const windowsToClose: Array = await getChildWindows(version); + if (version === OpenFinJavaScriptAPIVersion.ONE) { + await Promise.all( + windowsToClose.map((windowToClose) => + new Promise((resolve, reject) => + windowToClose.close(true, resolve, reject)))); + } else if (version === OpenFinJavaScriptAPIVersion.TWO) { + await Promise.all( + windowsToClose.map((windowToClose) => windowToClose.close())); + } }, [name]); const dispatchError = (error: string) => { diff --git a/src/useNotification.ts b/src/useNotification.ts index 535f1b8..1ec50a2 100644 --- a/src/useNotification.ts +++ b/src/useNotification.ts @@ -12,7 +12,7 @@ import { } from "react"; import ReactDOM from "react-dom"; import { IUseNotificationOptions } from "../index"; -import getNotificationWindow from "./utils/helpers/getNotificationWindow"; +import getChildWindows from "./utils/helpers/getChildWindows"; import { injectNode, injectNodes } from "./utils/helpers/inject"; import { isWindowV1, isWindowV2 } from "./utils/helpers/isWindow"; import reducer, { INITIAL_WINDOW_STATE } from "./utils/reducers/WindowReducer"; @@ -78,13 +78,33 @@ export default ({ ref && notificationWindow.state === WINDOW_STATE.LAUNCHING ) { - getNotificationWindow(version, windowOptions).then((childWindow) => { - dispatch({ - payload: childWindow, - type: WINDOW_ACTION.SET_WINDOW, - }); - dispatchNewState(WINDOW_STATE.LAUNCHED); - }).catch((error) => { throw error; }); + getChildWindows(version).then((childWindows: any[]) => { + let childWindow: _Window | fin.OpenFinWindow | null = null; + if (version === OpenFinJavaScriptAPIVersion.ONE) { + childWindow = childWindows + // A "queueCounter" window needs to be filtered out (it has the same name/uuid): + .filter((win: fin.OpenFinWindow) => win.getNativeWindow()) + // This includes only notification windows. + // There doesn't seem to be a better way of differentiating child windows from notifications: + .filter((win: fin.OpenFinWindow) => win.name.includes("newNotifications")) + .find((win) => (win.uuid && win.uuid === windowOptions.uuid)); + } else { + childWindows.map((win) => { + if (win.identity.name && win.identity.name === windowOptions.name) { + childWindow = win; + } + }); + } + if (childWindow) { + dispatch({ + payload: childWindow, + type: WINDOW_ACTION.SET_WINDOW, + }); + dispatchNewState(WINDOW_STATE.LAUNCHED); + } else { + dispatchError("Failed to get notification window"); + } + }).catch((error: any) => { throw error; }); } }, [windowOptions, notificationWindow.state, ref]); diff --git a/src/utils/helpers/getChildWindows.ts b/src/utils/helpers/getChildWindows.ts new file mode 100644 index 0000000..750e3e6 --- /dev/null +++ b/src/utils/helpers/getChildWindows.ts @@ -0,0 +1,20 @@ +import { _Window } from "openfin/_v2/api/window/window"; + +const getChildWindowsV1 = (): Promise => + new Promise((resolve, reject) => { + const application = fin.desktop.Application.getCurrent(); + application.getChildWindows(resolve, reject); + }); + +const getChildWindowsV2 = (): Promise<_Window[]> => + new Promise((resolve, reject) => { + fin.Application.getCurrent().then(async (application) => { + const childWindows = await application.getChildWindows(); + resolve(childWindows); + }).catch(reject); + }); + +export default (version: OpenFinJavaScriptAPIVersion): Promise => + version === OpenFinJavaScriptAPIVersion.ONE ? + getChildWindowsV1() : + getChildWindowsV2(); diff --git a/src/utils/helpers/getNotificationWindow.ts b/src/utils/helpers/getNotificationWindow.ts deleted file mode 100644 index e5d3fa3..0000000 --- a/src/utils/helpers/getNotificationWindow.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { _Window } from "openfin/_v2/api/window/window"; -import { WindowOption } from "openfin/_v2/api/window/windowOption"; - -const getNotificationWindowV1 = (windowOptions: WindowOption): Promise => - new Promise((resolve, reject) => { - const application = fin.desktop.Application.getCurrent(); - application.getChildWindows((childWindows) => { - childWindows - // A "queueCounter" window needs to be filtered out (it has the same name/uuid): - .filter((win: fin.OpenFinWindow) => win.getNativeWindow()) - .map((win: fin.OpenFinWindow) => { - if (win.uuid && win.uuid === windowOptions.uuid) { - resolve(win); - } - }); - }, reject); - }); - -const getNotificationWindowV2 = (windowOptions: WindowOption): Promise<_Window> => - new Promise((resolve, reject) => { - fin.Application.getCurrent().then(async (application) => { - const childWindows = await application.getChildWindows(); - childWindows.map((win) => { - if (win.identity.name && win.identity.name === windowOptions.name) { - resolve(win); - } - }); - reject("No notification windows opened."); - }).catch(reject); - }); - -export default ( - version: OpenFinJavaScriptAPIVersion, - windowOptions: WindowOption, -): Promise => - version === OpenFinJavaScriptAPIVersion.ONE ? - getNotificationWindowV1(windowOptions) : - getNotificationWindowV2(windowOptions); From da69869c1145fd4d1ca8aaabde88857ea237f282 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 13 Mar 2020 12:51:30 +0000 Subject: [PATCH 5/7] Fix bug where calling 'close' before a previous call was finished caused a crash, by making reset function async --- src/useChildWindow.ts | 12 +++++++----- src/useNotification.ts | 14 ++++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/useChildWindow.ts b/src/useChildWindow.ts index eb9a81b..8f2133d 100644 --- a/src/useChildWindow.ts +++ b/src/useChildWindow.ts @@ -44,10 +44,12 @@ export default ({ } }, [parentDocument, injectNodes, htmlDocument]); - const reset = () => { - dispatch({ type: WINDOW_ACTION.RESET }); - setHtmlDocument(null); - }; + const reset = async () => + new Promise((resolve) => { + dispatch({ type: WINDOW_ACTION.RESET }); + setHtmlDocument(null); + resolve(); + }); useEffect(() => { if (childWindow.windowRef && isWindowV1(childWindow.windowRef)) { @@ -180,7 +182,7 @@ export default ({ if (childWindow.windowRef) { await childWindow.windowRef.close(); } - reset(); + await reset(); } catch (error) { dispatchError(error); } diff --git a/src/useNotification.ts b/src/useNotification.ts index 1ec50a2..74a6229 100644 --- a/src/useNotification.ts +++ b/src/useNotification.ts @@ -176,18 +176,20 @@ export default ({ }); }; - const reset = () => { - dispatch({ type: WINDOW_ACTION.RESET }); - setHtmlDocument(null); - setRef(null); - }; + const reset = async () => + new Promise((resolve) => { + dispatch({ type: WINDOW_ACTION.RESET }); + setHtmlDocument(null); + setRef(null); + resolve(); + }); const close = useCallback(async () => { try { if (ref) { await ref.close(); } - reset(); + await reset(); } catch (error) { throw new Error(error); } From 37cea91f6448e8cdfd2528e59fcd21e5428bfab1 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 13 Mar 2020 16:15:49 +0000 Subject: [PATCH 6/7] Change type of error object from any to Error --- src/useNotification.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/useNotification.ts b/src/useNotification.ts index 74a6229..69c77c9 100644 --- a/src/useNotification.ts +++ b/src/useNotification.ts @@ -104,7 +104,7 @@ export default ({ } else { dispatchError("Failed to get notification window"); } - }).catch((error: any) => { throw error; }); + }).catch((error: Error) => { throw error; }); } }, [windowOptions, notificationWindow.state, ref]); From 26f560ad9ad80270bc43c475717238eaf6ef811d Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 13 Mar 2020 16:28:19 +0000 Subject: [PATCH 7/7] Refactor search for correct window --- src/useNotification.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/useNotification.ts b/src/useNotification.ts index 69c77c9..e058da9 100644 --- a/src/useNotification.ts +++ b/src/useNotification.ts @@ -89,11 +89,8 @@ export default ({ .filter((win: fin.OpenFinWindow) => win.name.includes("newNotifications")) .find((win) => (win.uuid && win.uuid === windowOptions.uuid)); } else { - childWindows.map((win) => { - if (win.identity.name && win.identity.name === windowOptions.name) { - childWindow = win; - } - }); + childWindow = childWindows.find((win) => + win.identity.name && win.identity.name === windowOptions.name); } if (childWindow) { dispatch({