Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit 5ce89aa

Browse files
committed
fix(packages/core): MMR rendering is glitchy
we update the bottom stripe, then fetch the content for the first tab, then update the Presentation (e.g. from Slim to Normal). since the middle one is asynchronous, this introduces a glitchy UI effect Fixes #3589
1 parent 75e1e70 commit 5ce89aa

File tree

4 files changed

+32
-10
lines changed

4 files changed

+32
-10
lines changed

packages/core/src/models/mmr/show.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,12 @@ export async function show<T extends MetadataBearing>(tab: Tab, mmr: MultiModalR
140140
// const buttons = mmr.buttons ? formatButtons(tab, mmr, mmr.buttons) : ([] as SidecarMode[])
141141
const ourModesWithButtons = modes.concat(mmr.buttons || [])
142142

143+
// first, do a "modelOnly" pass, to get the full list of modes
144+
// see https://github.com/IBM/kui/issues/3589
143145
const modesWithButtons = addModeButtons(tab, ourModesWithButtons, mmr, {
144146
preserveBackButton: true,
145-
show: mmr.defaultMode
147+
show: mmr.defaultMode,
148+
modelOnly: true
146149
})
147150

148151
const defaultMode =
@@ -153,7 +156,15 @@ export async function show<T extends MetadataBearing>(tab: Tab, mmr: MultiModalR
153156
throw new Error('default mode is a button')
154157
}
155158

156-
const content = hasContent(defaultMode) ? defaultMode : undefined
159+
const content = hasContent(defaultMode) ? await renderContent(tab, mmr, defaultMode) : undefined
160+
161+
// now that we've rendered the initial/default content, do a pass
162+
// over the modes and add them to the UI; see
163+
// https://github.com/IBM/kui/issues/3589
164+
addModeButtons(tab, ourModesWithButtons, mmr, {
165+
preserveBackButton: true,
166+
show: mmr.defaultMode
167+
})
157168

158169
if (content) {
159170
const custom: CustomSpec = Object.assign(
@@ -165,7 +176,7 @@ export async function show<T extends MetadataBearing>(tab: Tab, mmr: MultiModalR
165176
prettyName: mmr.prettyName,
166177
nameHash: mmr.nameHash
167178
},
168-
await renderContent(tab, mmr, content)
179+
content
169180
)
170181

171182
const { showCustom } = await import('../../webapp/views/sidecar')

packages/core/src/webapp/bottom-stripe.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ export function isSidecarMode(entity: string | HTMLElement | Table | SidecarMode
4848
interface BottomStripOptions {
4949
show?: string
5050
preserveBackButton?: boolean
51+
52+
/** only generate model, do not update view? */
53+
modelOnly?: boolean
5154
}
5255

5356
export const rawCSS = {
@@ -351,14 +354,18 @@ export const addModeButtons = (
351354
addRelevantModes(tab, modesUnsorted, command, entity)
352355
}
353356

354-
if (options.show && modesUnsorted.find(_ => _.mode === options.show)) {
357+
if (options && options.show && modesUnsorted.find(_ => _.mode === options.show)) {
355358
modesUnsorted = modesUnsorted.map(_ => Object.assign({}, _))
356359

357360
modesUnsorted.filter(_ => _.defaultMode && _.mode !== options.show).forEach(_ => (_.defaultMode = false))
358361

359362
modesUnsorted.find(_ => _.mode === options.show).defaultMode = true
360363
}
361364

365+
if (options && options.modelOnly) {
366+
return modesUnsorted
367+
}
368+
362369
// obey the `order` constraints of the modes
363370
const modes = modesUnsorted.sort((a, b) => {
364371
return (a.order || 0) - (b.order || 0)

packages/test/src/api/mmr.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export class TestMMR {
233233
await this.app.client.waitForExist(Selectors.SIDECAR_MODE_BUTTON_SELECTED(expectMode.mode))
234234
}
235235
} catch (err) {
236-
return Common.oops(this)(err)
236+
return Common.oops(this, true)(err)
237237
}
238238
})
239239

@@ -244,7 +244,7 @@ export class TestMMR {
244244
await SidecarExpect.textPlainContent(expectMode.content)(this.app)
245245
}
246246
} catch (err) {
247-
return Common.oops(this)(err)
247+
return Common.oops(this, true)(err)
248248
}
249249
})
250250
} else if (expectMode.contentType === 'table') {
@@ -255,7 +255,7 @@ export class TestMMR {
255255
assert.strictEqual(rows.value.length, expectMode.nRows)
256256
}
257257
} catch (err) {
258-
return Common.oops(this)(err)
258+
return Common.oops(this, true)(err)
259259
}
260260
})
261261
it(`should show ${expectMode.nCells} table cells in the ${expectMode.mode} tab`, async () => {
@@ -265,7 +265,7 @@ export class TestMMR {
265265
assert.strictEqual(cells.value.length, expectMode.nCells)
266266
}
267267
} catch (err) {
268-
return Common.oops(this)(err)
268+
return Common.oops(this, true)(err)
269269
}
270270
})
271271
} else if (expectMode.contentType === 'yaml') {
@@ -276,7 +276,7 @@ export class TestMMR {
276276
await SidecarExpect.yaml(expectMode.content)(this.app)
277277
}
278278
} catch (err) {
279-
return Common.oops(this)(err)
279+
return Common.oops(this, true)(err)
280280
}
281281
})
282282
} else {
@@ -286,7 +286,7 @@ export class TestMMR {
286286
await SidecarExpect.textPlainContent(expectMode.content)(this.app)
287287
}
288288
} catch (err) {
289-
return Common.oops(this)(err)
289+
return Common.oops(this, true)(err)
290290
}
291291
})
292292
}

packages/test/src/api/util.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,12 @@ export const waitForXtermInput = (app: Application, N: number) => {
195195
}
196196

197197
export const expectText = (app: Application, expectedText: string) => async (selector: string) => {
198+
let idx = 0
198199
await app.client.waitUntil(async () => {
199200
const actualText = await app.client.getText(selector)
201+
if (++idx > 5) {
202+
console.error(`still waiting for text; actualText=${actualText} expectedText=${expectedText}`)
203+
}
200204
return actualText === expectedText
201205
})
202206
return app

0 commit comments

Comments
 (0)