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) => {
wsClient.initPlugin(manifest.id, props.webSocketClient)
wsClient.initPlugin(manifest.id, manifest.version, props.webSocketClient)
useEffect(() => {
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`)
})
})
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
* 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 {

View file

@ -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)
}
}
}