Fix view replacement to prioritize existing views

Previously views earlier in the list would take priority because not all url matches were being found first.
This commit is contained in:
Max Goodhart
2020-06-18 22:13:38 -07:00
parent f605535e32
commit 61235b3066

View File

@@ -114,36 +114,40 @@ export default class StreamWindow extends EventEmitter {
setViews(viewURLMap) { setViews(viewURLMap) {
const { views } = this const { views } = this
const boxes = boxesFromViewURLMap(GRID_COUNT, GRID_COUNT, viewURLMap) const boxes = boxesFromViewURLMap(GRID_COUNT, GRID_COUNT, viewURLMap)
const remainingBoxes = new Set(boxes.filter(({ url }) => url))
const unusedViews = new Set(views) const unusedViews = new Set(views)
for (const box of boxes) { const viewsToDisplay = []
const { url, x, y, w, h, spaces } = box
if (!url) {
continue
}
const unusedViewsArray = views.filter((s) => unusedViews.has(s))
const matchingURLViews = unusedViewsArray.filter(
(s) => s.state.context.url === url,
)
const matchers = [
// First try to find a loaded view of the same URL... // First try to find a loaded view of the same URL...
let space = matchingURLViews.find((s) => (v, url) =>
s.state.matches('displaying.running'), unusedViews.has(v) &&
) v.state.context.url === url &&
if (!space) { v.state.matches('displaying.running'),
// Then try view with the same URL that is still loading... // Then try view with the same URL that is still loading...
space = matchingURLViews[0] (v, url) => unusedViews.has(v) && v.state.context.url === url,
} // If none could be found, try an unused view.
if (!space) { (v) => unusedViews.has(v),
// If none could be found, launch a new view. () => {
space = unusedViewsArray[0]
}
if (!space) {
throw new Error('could not find a usable view') throw new Error('could not find a usable view')
},
]
for (const matcher of matchers) {
for (const box of remainingBoxes) {
const { url } = box
const view = views.find((v) => matcher(v, url))
if (view) {
viewsToDisplay.push({ box, view })
unusedViews.delete(view)
remainingBoxes.delete(box)
}
}
} }
for (const { box, view } of viewsToDisplay) {
const { url, x, y, w, h, spaces } = box
const pos = { const pos = {
x: SPACE_WIDTH * x, x: SPACE_WIDTH * x,
y: SPACE_HEIGHT * y, y: SPACE_HEIGHT * y,
@@ -151,12 +155,11 @@ export default class StreamWindow extends EventEmitter {
height: SPACE_HEIGHT * h, height: SPACE_HEIGHT * h,
spaces, spaces,
} }
space.send({ type: 'DISPLAY', pos, url }) view.send({ type: 'DISPLAY', pos, url })
unusedViews.delete(space)
} }
for (const space of unusedViews) { for (const view of unusedViews) {
space.send('CLEAR') view.send('CLEAR')
} }
} }