Shows the version change banner only on plugin update and tries to reconnect when the interface is refreshed (#1807)

This commit is contained in:
Miguel de la Cruz 2021-11-13 12:03:53 +01:00 committed by GitHub
parent ea366a4ec3
commit d2bcb9ad66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 25 deletions

View file

@ -67,7 +67,7 @@ type Props = {
} }
const MainApp = (props: Props) => { const MainApp = (props: Props) => {
wsClient.initPlugin(manifest.id, props.webSocketClient) wsClient.initPlugin(manifest.id, manifest.version, props.webSocketClient)
useEffect(() => { useEffect(() => {
document.body.classList.add('focalboard-body') document.body.classList.add('focalboard-body')

View file

@ -132,4 +132,18 @@ describe('utils', () => {
expect(Utils.displayDateTime(date, intl)).toBe(`July 09, ${previousYear}, 5:35 AM`) 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)
})
})
}) })

View file

@ -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 * eg. versionA = 4.16.0, versionB = 4.17.0 returns 1
* compareVersionParam: The version to compare the former version against * versionA = 4.16.1, versionB = 4.16.1 returns 0
* * versionA = 4.16.1, versionB = 4.15.0 returns -1
* eg. currentVersionParam = 4.16.0, compareVersionParam = 4.17.0 returns false
* currentVersionParam = 4.16.1, compareVersionParam = 4.16.1 returns true
*/ */
static isVersionGreaterThanOrEqualTo(currentVersionParam: string, compareVersionParam: string): boolean { static compareVersions(versionA: string, versionB: string): number {
if (currentVersionParam === compareVersionParam) { if (versionA === versionB) {
return true return 0
} }
// We only care about the numbers // We only care about the numbers
const currentVersionNumber = (currentVersionParam || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null) const versionANumber = (versionA || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null)
const compareVersionNumber = (compareVersionParam || '').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++) { for (let i = 0; i < Math.max(versionANumber.length, versionBNumber.length); i++) {
const currentVersion = parseInt(currentVersionNumber[i], 10) || 0 const a = parseInt(versionANumber[i], 10) || 0
const compareVersion = parseInt(compareVersionNumber[i], 10) || 0 const b = parseInt(versionBNumber[i], 10) || 0
if (currentVersion > compareVersion) { if (a > b) {
return true return -1
} }
if (currentVersion < compareVersion) { if (a < b) {
return false return 1
} }
} }
// If all components are equal, then return true // If all components are equal, then return true
return true return 0
} }
static isDesktop(): boolean { 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 { static getReadToken(): string {

View file

@ -49,7 +49,9 @@ type OnConfigChangeHandler = (client: WSClient, clientConfig: ClientConfig) => v
class WSClient { class WSClient {
ws: WebSocket|null = null ws: WebSocket|null = null
client: MMWebSocketClient|null = null client: MMWebSocketClient|null = null
onPluginReconnect: null|(() => void) = null
pluginId = '' pluginId = ''
pluginVersion = ''
onAppVersionChangeHandler: ((versionHasChanged: boolean) => void) | null = null onAppVersionChangeHandler: ((versionHasChanged: boolean) => void) | null = null
clientPrefix = '' clientPrefix = ''
serverUrl: string | undefined serverUrl: string | undefined
@ -89,8 +91,9 @@ class WSClient {
this.serverUrl = serverUrl this.serverUrl = serverUrl
} }
initPlugin(pluginId: string, client: MMWebSocketClient): void { initPlugin(pluginId: string, pluginVersion: string, client: MMWebSocketClient): void {
this.pluginId = pluginId this.pluginId = pluginId
this.pluginVersion = pluginVersion
this.clientPrefix = `custom_${pluginId}_` this.clientPrefix = `custom_${pluginId}_`
this.client = client this.client = client
Utils.log(`WSClient initialised for plugin id "${pluginId}"`) Utils.log(`WSClient initialised for plugin id "${pluginId}"`)
@ -181,6 +184,7 @@ class WSClient {
handler(this) handler(this)
} }
} }
this.onPluginReconnect = onReconnect
const onClose = (connectFailCount: number) => { const onClose = (connectFailCount: number) => {
Utils.logError(`WSClient has been closed, connect fail count: ${connectFailCount}`) Utils.logError(`WSClient has been closed, connect fail count: ${connectFailCount}`)
@ -311,9 +315,29 @@ class WSClient {
return return
} }
if (data.plugin_statuses.some((s: any) => s.plugin_id === this.pluginId)) { const focalboardStatusChange = data.plugin_statuses.find((s: any) => s.plugin_id === this.pluginId)
Utils.log('Boards plugin has been updated') if (focalboardStatusChange) {
this.onAppVersionChangeHandler(true) // 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)
}
} }
} }