diff --git a/mattermost-plugin/webapp/src/index.tsx b/mattermost-plugin/webapp/src/index.tsx index e0b86702f..083b5b9cf 100644 --- a/mattermost-plugin/webapp/src/index.tsx +++ b/mattermost-plugin/webapp/src/index.tsx @@ -67,7 +67,7 @@ type Props = { } const MainApp = (props: Props) => { - wsClient.initPlugin(manifest.id, props.webSocketClient) + wsClient.initPlugin(manifest.id, manifest.version, props.webSocketClient) useEffect(() => { document.body.classList.add('focalboard-body') diff --git a/webapp/src/utils.test.ts b/webapp/src/utils.test.ts index b1d3e9eed..773ab1b3d 100644 --- a/webapp/src/utils.test.ts +++ b/webapp/src/utils.test.ts @@ -132,4 +132,18 @@ describe('utils', () => { expect(Utils.displayDateTime(date, intl)).toBe(`July 09, ${previousYear}, 5:35 AM`) }) }) + + describe('compare versions', () => { + it('should return one if b > a', () => { + expect(Utils.compareVersions('0.9.4', '0.10.0')).toBe(1) + }) + + it('should return zero if a = b', () => { + expect(Utils.compareVersions('1.2.3', '1.2.3')).toBe(0) + }) + + it('should return minus one if b < a', () => { + expect(Utils.compareVersions('10.9.4', '10.9.2')).toBe(-1) + }) + }) }) diff --git a/webapp/src/utils.ts b/webapp/src/utils.ts index 26fad7279..a323010a6 100644 --- a/webapp/src/utils.ts +++ b/webapp/src/utils.ts @@ -546,41 +546,39 @@ class Utils { } /** - * Boolean function to check if a version is greater than another. + * Function to check how a version compares to another * - * currentVersionParam: The version being checked - * compareVersionParam: The version to compare the former version against - * - * eg. currentVersionParam = 4.16.0, compareVersionParam = 4.17.0 returns false - * currentVersionParam = 4.16.1, compareVersionParam = 4.16.1 returns true + * eg. versionA = 4.16.0, versionB = 4.17.0 returns 1 + * versionA = 4.16.1, versionB = 4.16.1 returns 0 + * versionA = 4.16.1, versionB = 4.15.0 returns -1 */ - static isVersionGreaterThanOrEqualTo(currentVersionParam: string, compareVersionParam: string): boolean { - if (currentVersionParam === compareVersionParam) { - return true + static compareVersions(versionA: string, versionB: string): number { + if (versionA === versionB) { + return 0 } // We only care about the numbers - const currentVersionNumber = (currentVersionParam || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null) - const compareVersionNumber = (compareVersionParam || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null) + const versionANumber = (versionA || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null) + const versionBNumber = (versionB || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null) - for (let i = 0; i < Math.max(currentVersionNumber.length, compareVersionNumber.length); i++) { - const currentVersion = parseInt(currentVersionNumber[i], 10) || 0 - const compareVersion = parseInt(compareVersionNumber[i], 10) || 0 - if (currentVersion > compareVersion) { - return true + for (let i = 0; i < Math.max(versionANumber.length, versionBNumber.length); i++) { + const a = parseInt(versionANumber[i], 10) || 0 + const b = parseInt(versionBNumber[i], 10) || 0 + if (a > b) { + return -1 } - if (currentVersion < compareVersion) { - return false + if (a < b) { + return 1 } } // If all components are equal, then return true - return true + return 0 } static isDesktop(): boolean { - return Utils.isDesktopApp() && Utils.isVersionGreaterThanOrEqualTo(Utils.getDesktopVersion(), '5.0.0') + return Utils.isDesktopApp() && (Utils.compareVersions(Utils.getDesktopVersion(), '5.0.0') <= 0) } static getReadToken(): string { diff --git a/webapp/src/wsclient.ts b/webapp/src/wsclient.ts index 0ab189202..4d8349b7f 100644 --- a/webapp/src/wsclient.ts +++ b/webapp/src/wsclient.ts @@ -49,7 +49,9 @@ type OnConfigChangeHandler = (client: WSClient, clientConfig: ClientConfig) => v class WSClient { ws: WebSocket|null = null client: MMWebSocketClient|null = null + onPluginReconnect: null|(() => void) = null pluginId = '' + pluginVersion = '' onAppVersionChangeHandler: ((versionHasChanged: boolean) => void) | null = null clientPrefix = '' serverUrl: string | undefined @@ -89,8 +91,9 @@ class WSClient { this.serverUrl = serverUrl } - initPlugin(pluginId: string, client: MMWebSocketClient): void { + initPlugin(pluginId: string, pluginVersion: string, client: MMWebSocketClient): void { this.pluginId = pluginId + this.pluginVersion = pluginVersion this.clientPrefix = `custom_${pluginId}_` this.client = client Utils.log(`WSClient initialised for plugin id "${pluginId}"`) @@ -181,6 +184,7 @@ class WSClient { handler(this) } } + this.onPluginReconnect = onReconnect const onClose = (connectFailCount: number) => { Utils.logError(`WSClient has been closed, connect fail count: ${connectFailCount}`) @@ -311,9 +315,29 @@ class WSClient { return } - if (data.plugin_statuses.some((s: any) => s.plugin_id === this.pluginId)) { - Utils.log('Boards plugin has been updated') - this.onAppVersionChangeHandler(true) + const focalboardStatusChange = data.plugin_statuses.find((s: any) => s.plugin_id === this.pluginId) + if (focalboardStatusChange) { + // if the plugin version is greater than the current one, + // show the new version banner + if (Utils.compareVersions(this.pluginVersion, focalboardStatusChange.version) > 0) { + Utils.log('Boards plugin has been updated') + this.onAppVersionChangeHandler(true) + } + + // if the plugin version is greater or equal, trigger a + // reconnect to resubscribe in case the interface hasn't + // been reloaded + if (Utils.compareVersions(this.pluginVersion, focalboardStatusChange.version) >= 0) { + // this is a temporal solution that leaves a second + // between the message and the reconnect so the server + // has time to register the WS handler + setTimeout(() => { + if (this.onPluginReconnect) { + Utils.log('Reconnecting after plugin update') + this.onPluginReconnect() + } + }, 1000) + } } }