Bugfix: update sketch mode colors on theme change (#3849)
* Update client-side scene mesh base colors properly * Add E2E test * Remove use of `as`
This commit is contained in:
@ -552,4 +552,70 @@ test.describe('Testing settings', () => {
|
||||
await changeUnitOfMeasureInGizmo('m', 'Meters')
|
||||
})
|
||||
})
|
||||
|
||||
test('Changing theme in sketch mode', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(() => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([5, 0], %)
|
||||
|> line([0, 5], %)
|
||||
|> line([-5, 0], %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(5, sketch001)
|
||||
`
|
||||
)
|
||||
})
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
// Selectors and constants
|
||||
const editSketchButton = page.getByRole('button', { name: 'Edit Sketch' })
|
||||
const lineToolButton = page.getByTestId('line')
|
||||
const segmentOverlays = page.getByTestId('segment-overlay')
|
||||
const sketchOriginLocation = { x: 600, y: 250 }
|
||||
const darkThemeSegmentColor: [number, number, number] = [215, 215, 215]
|
||||
const lightThemeSegmentColor: [number, number, number] = [90, 90, 90]
|
||||
|
||||
await test.step(`Get into sketch mode`, async () => {
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page.mouse.click(700, 200)
|
||||
await expect(editSketchButton).toBeVisible()
|
||||
await editSketchButton.click()
|
||||
|
||||
// We use the line tool as a proxy for sketch mode
|
||||
await expect(lineToolButton).toBeVisible()
|
||||
await expect(segmentOverlays).toHaveCount(4)
|
||||
// but we allow more time to pass for animating to the sketch
|
||||
await page.waitForTimeout(1000)
|
||||
})
|
||||
|
||||
await test.step(`Check the sketch line color before`, async () => {
|
||||
await expect
|
||||
.poll(() =>
|
||||
u.getGreatestPixDiff(sketchOriginLocation, darkThemeSegmentColor)
|
||||
)
|
||||
.toBeLessThan(15)
|
||||
})
|
||||
|
||||
await test.step(`Change theme to light using command palette`, async () => {
|
||||
await page.keyboard.press('ControlOrMeta+K')
|
||||
await page.getByRole('option', { name: 'theme' }).click()
|
||||
await page.getByRole('option', { name: 'light' }).click()
|
||||
await expect(page.getByText('theme to "light"')).toBeVisible()
|
||||
|
||||
// Make sure we haven't left sketch mode
|
||||
await expect(lineToolButton).toBeVisible()
|
||||
})
|
||||
|
||||
await test.step(`Check the sketch line color after`, async () => {
|
||||
await expect
|
||||
.poll(() =>
|
||||
u.getGreatestPixDiff(sketchOriginLocation, lightThemeSegmentColor)
|
||||
)
|
||||
.toBeLessThan(15)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -102,7 +102,7 @@ import {
|
||||
getRectangleCallExpressions,
|
||||
updateRectangleSketch,
|
||||
} from 'lib/rectangleTool'
|
||||
import { getThemeColorForThreeJs } from 'lib/theme'
|
||||
import { getThemeColorForThreeJs, Themes } from 'lib/theme'
|
||||
import { err, reportRejection, trap } from 'lib/trap'
|
||||
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
||||
import { Point3d } from 'wasm-lib/kcl/bindings/Point3d'
|
||||
@ -1473,6 +1473,25 @@ export class SceneEntities {
|
||||
to,
|
||||
})
|
||||
}
|
||||
/**
|
||||
* Update the base color of each of the THREEjs meshes
|
||||
* that represent each of the sketch segments, to get the
|
||||
* latest value from `sceneInfra._theme`
|
||||
*/
|
||||
updateSegmentBaseColor(newColor: Themes.Light | Themes.Dark) {
|
||||
const newColorThreeJs = getThemeColorForThreeJs(newColor)
|
||||
Object.values(this.activeSegments).forEach((group) => {
|
||||
group.userData.baseColor = newColorThreeJs
|
||||
group.traverse((child) => {
|
||||
if (
|
||||
child instanceof Mesh &&
|
||||
child.material instanceof MeshBasicMaterial
|
||||
) {
|
||||
child.material.color.set(newColorThreeJs)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
removeSketchGrid() {
|
||||
if (this.axisGroup) this.scene.remove(this.axisGroup)
|
||||
}
|
||||
|
@ -17,7 +17,12 @@ import decamelize from 'decamelize'
|
||||
import { Actor, AnyStateMachine, ContextFrom, Prop, StateFrom } from 'xstate'
|
||||
import { isDesktop } from 'lib/isDesktop'
|
||||
import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig'
|
||||
import { kclManager, sceneInfra, engineCommandManager } from 'lib/singletons'
|
||||
import {
|
||||
kclManager,
|
||||
sceneInfra,
|
||||
engineCommandManager,
|
||||
sceneEntitiesManager,
|
||||
} from 'lib/singletons'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { IndexLoaderData } from 'lib/types'
|
||||
import { settings } from 'lib/settings/initialSettings'
|
||||
@ -137,6 +142,7 @@ export const SettingsAuthProviderBase = ({
|
||||
setClientTheme: ({ context }) => {
|
||||
const opposingTheme = getOppositeTheme(context.app.theme.current)
|
||||
sceneInfra.theme = opposingTheme
|
||||
sceneEntitiesManager.updateSegmentBaseColor(opposingTheme)
|
||||
},
|
||||
setEngineEdges: ({ context }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
|
Reference in New Issue
Block a user