Make engine background color driven by theme setting (#1842)

* Bump ts lib

* Make engine background color driven by theme setting

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Force snapshots to dark mode, fix theme init

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Don't assume we have engineCommandManager in CameraControls,
because for some reason it's being loaded before engineConnection in test environments?

* Merge branch 'main' into change-bg-color

* Replace optional chaining with this.engineCommandManager

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Okay now all snapshot tests are actually in dark mode

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* trigger ci

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
This commit is contained in:
Frank Noirot
2024-03-22 09:35:07 -04:00
committed by GitHub
parent 54b234360e
commit 8038b5d7a3
24 changed files with 61 additions and 18 deletions

View File

@ -22,7 +22,7 @@ test.beforeEach(async ({ context, page }) => {
onboardingStatus: 'dismissed', onboardingStatus: 'dismissed',
showDebugPanel: true, showDebugPanel: true,
textWrapping: 'On', textWrapping: 'On',
theme: 'system', theme: 'dark',
unitSystem: 'imperial', unitSystem: 'imperial',
}) })
) )
@ -397,7 +397,7 @@ test('Draft segments should look right', async ({ page, context }) => {
onboardingStatus: 'dismissed', onboardingStatus: 'dismissed',
showDebugPanel: true, showDebugPanel: true,
textWrapping: 'On', textWrapping: 'On',
theme: 'system', theme: 'dark',
unitSystem: 'imperial', unitSystem: 'imperial',
}) })
) )
@ -475,7 +475,7 @@ test('Client side scene scale should match engine scale inch', async ({
onboardingStatus: 'dismissed', onboardingStatus: 'dismissed',
showDebugPanel: true, showDebugPanel: true,
textWrapping: 'On', textWrapping: 'On',
theme: 'system', theme: 'dark',
unitSystem: 'imperial', unitSystem: 'imperial',
}) })
) )
@ -575,7 +575,7 @@ test('Client side scene scale should match engine scale mm', async ({
onboardingStatus: 'dismissed', onboardingStatus: 'dismissed',
showDebugPanel: true, showDebugPanel: true,
textWrapping: 'On', textWrapping: 'On',
theme: 'system', theme: 'dark',
unitSystem: 'metric', unitSystem: 'metric',
}) })
) )

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -10,7 +10,7 @@
"@fortawesome/react-fontawesome": "^0.2.0", "@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.18", "@headlessui/react": "^1.7.18",
"@headlessui/tailwindcss": "^0.2.0", "@headlessui/tailwindcss": "^0.2.0",
"@kittycad/lib": "^0.0.55", "@kittycad/lib": "^0.1.0",
"@lezer/javascript": "^1.4.9", "@lezer/javascript": "^1.4.9",
"@open-rpc/client-js": "^1.8.1", "@open-rpc/client-js": "^1.8.1",
"@react-hook/resize-observer": "^1.2.6", "@react-hook/resize-observer": "^1.2.6",

View File

@ -265,15 +265,15 @@ export class CameraControls {
this.onCameraChange() this.onCameraChange()
} }
setTimeout(() => { setTimeout(() => {
engineCommandManager.subscribeTo({ this.engineCommandManager.subscribeTo({
event: 'camera_drag_end', event: 'camera_drag_end',
callback: cb, callback: cb,
}) })
engineCommandManager.subscribeTo({ this.engineCommandManager.subscribeTo({
event: 'default_camera_zoom', event: 'default_camera_zoom',
callback: cb, callback: cb,
}) })
engineCommandManager.subscribeTo({ this.engineCommandManager.subscribeTo({
event: 'default_camera_get_settings', event: 'default_camera_get_settings',
callback: cb, callback: cb,
}) })

View File

@ -66,13 +66,13 @@ export const ModelingMachineProvider = ({
const { const {
auth, auth,
settings: { settings: {
context: { baseUnit }, context: { baseUnit, theme },
}, },
} = useSettingsAuthContext() } = useSettingsAuthContext()
const { code } = useKclContext() const { code } = useKclContext()
const token = auth?.context?.token const token = auth?.context?.token
const streamRef = useRef<HTMLDivElement>(null) const streamRef = useRef<HTMLDivElement>(null)
useSetupEngineManager(streamRef, token) useSetupEngineManager(streamRef, token, theme)
const { const {
isShiftDown, isShiftDown,

View File

@ -11,7 +11,7 @@ import {
validateSettings, validateSettings,
} from 'lib/settings/settingsUtils' } from 'lib/settings/settingsUtils'
import { toast } from 'react-hot-toast' import { toast } from 'react-hot-toast'
import { setThemeClass, Themes } from 'lib/theme' import { getThemeColorForEngine, setThemeClass, Themes } from 'lib/theme'
import { import {
AnyStateMachine, AnyStateMachine,
ContextFrom, ContextFrom,
@ -22,7 +22,8 @@ import {
import { isTauri } from 'lib/isTauri' import { isTauri } from 'lib/isTauri'
import { settingsCommandBarConfig } from 'lib/commandBarConfigs/settingsCommandConfig' import { settingsCommandBarConfig } from 'lib/commandBarConfigs/settingsCommandConfig'
import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig' import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig'
import { kclManager, sceneInfra } from 'lib/singletons' import { kclManager, sceneInfra, engineCommandManager } from 'lib/singletons'
import { v4 as uuidv4 } from 'uuid'
type MachineContext<T extends AnyStateMachine> = { type MachineContext<T extends AnyStateMachine> = {
state: StateFrom<T> state: StateFrom<T>
@ -95,6 +96,16 @@ export const SettingsAuthProviderBase = ({
: context.baseUnit : context.baseUnit
sceneInfra.baseUnit = newBaseUnit sceneInfra.baseUnit = newBaseUnit
}, },
setEngineTheme: (context) => {
engineCommandManager.sendSceneCommand({
cmd_id: uuidv4(),
type: 'modeling_cmd_req',
cmd: {
type: 'set_background_color',
color: getThemeColorForEngine(context.theme),
},
})
},
toastSuccess: (context, event) => { toastSuccess: (context, event) => {
const truncatedNewValue = const truncatedNewValue =
'data' in event && event.data instanceof Object 'data' in event && event.data instanceof Object

View File

@ -3,10 +3,12 @@ import { parse } from '../lang/wasm'
import { useStore } from '../useStore' import { useStore } from '../useStore'
import { engineCommandManager, kclManager } from 'lib/singletons' import { engineCommandManager, kclManager } from 'lib/singletons'
import { deferExecution } from 'lib/utils' import { deferExecution } from 'lib/utils'
import { Themes } from 'lib/theme'
export function useSetupEngineManager( export function useSetupEngineManager(
streamRef: React.RefObject<HTMLDivElement>, streamRef: React.RefObject<HTMLDivElement>,
token?: string token?: string,
theme = Themes.System
) { ) {
const { const {
setMediaStream, setMediaStream,
@ -43,6 +45,7 @@ export function useSetupEngineManager(
return kclManager.executeAst(_ast, true) return kclManager.executeAst(_ast, true)
}, },
token, token,
theme,
}) })
setStreamDimensions({ setStreamDimensions({
streamWidth: quadWidth, streamWidth: quadWidth,

View File

@ -4,6 +4,7 @@ import { Models } from '@kittycad/lib'
import { exportSave } from 'lib/exportSave' import { exportSave } from 'lib/exportSave'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { getNodePathFromSourceRange } from 'lang/queryAst' import { getNodePathFromSourceRange } from 'lang/queryAst'
import { Themes, getThemeColorForEngine } from 'lib/theme'
let lastMessage = '' let lastMessage = ''
@ -887,6 +888,7 @@ export class EngineCommandManager {
height, height,
executeCode, executeCode,
token, token,
theme = Themes.Dark,
}: { }: {
setMediaStream: (stream: MediaStream) => void setMediaStream: (stream: MediaStream) => void
setIsStreamReady: (isStreamReady: boolean) => void setIsStreamReady: (isStreamReady: boolean) => void
@ -894,6 +896,7 @@ export class EngineCommandManager {
height: number height: number
executeCode: (code?: string, force?: boolean) => void executeCode: (code?: string, force?: boolean) => void
token?: string token?: string
theme?: Themes
}) { }) {
if (width === 0 || height === 0) { if (width === 0 || height === 0) {
return return
@ -919,6 +922,19 @@ export class EngineCommandManager {
} }
}, },
onEngineConnectionOpen: () => { onEngineConnectionOpen: () => {
// Set the stream background color
// This takes RGBA values from 0-1
// So we convert from the conventional 0-255 found in Figma
this.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'set_background_color',
color: getThemeColorForEngine(theme),
},
})
// Make the axis gizmo. // Make the axis gizmo.
// We do this after the connection opened to avoid a race condition. // We do this after the connection opened to avoid a race condition.
// Connected opened is the last thing that happens when the stream // Connected opened is the last thing that happens when the stream

View File

@ -4,6 +4,7 @@ import {
EngineCommand, EngineCommand,
} from '../lang/std/engineConnection' } from '../lang/std/engineConnection'
import { Models } from '@kittycad/lib' import { Models } from '@kittycad/lib'
import { Themes } from './theme'
type WebSocketResponse = Models['OkWebSocketResponseData_type'] type WebSocketResponse = Models['OkWebSocketResponseData_type']
@ -81,6 +82,7 @@ export async function executor(
width: 0, width: 0,
height: 0, height: 0,
executeCode: () => {}, executeCode: () => {},
theme: Themes.Dark,
}) })
await engineCommandManager.waitForReady await engineCommandManager.waitForReady
engineCommandManager.startNewSession() engineCommandManager.startNewSession()

View File

@ -6,7 +6,8 @@ export enum Themes {
// Get the theme from the system settings manually // Get the theme from the system settings manually
export function getSystemTheme(): Exclude<Themes, 'system'> { export function getSystemTheme(): Exclude<Themes, 'system'> {
return typeof window !== 'undefined' && 'matchMedia' in window return typeof globalThis.window !== 'undefined' &&
'matchMedia' in globalThis.window
? window.matchMedia('(prefers-color-scheme: dark)').matches ? window.matchMedia('(prefers-color-scheme: dark)').matches
? Themes.Dark ? Themes.Dark
: Themes.Light : Themes.Light
@ -21,3 +22,12 @@ export function setThemeClass(theme: Themes) {
document.body.classList.remove('dark') document.body.classList.remove('dark')
} }
} }
export function getThemeColorForEngine(theme: Themes) {
const resolvedTheme = theme === Themes.System ? getSystemTheme() : theme
const dark = 28 / 255
const light = 242 / 255
return resolvedTheme === Themes.Dark
? { r: dark, g: dark, b: dark, a: 1 }
: { r: light, g: light, b: light, a: 1 }
}

View File

@ -112,6 +112,7 @@ export const settingsMachine = createMachine(
'persistSettings', 'persistSettings',
'toastSuccess', 'toastSuccess',
'setThemeClass', 'setThemeClass',
'setEngineTheme',
], ],
target: 'idle', target: 'idle',
internal: true, internal: true,

View File

@ -1802,10 +1802,10 @@
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
"@kittycad/lib@^0.0.55": "@kittycad/lib@^0.1.0":
version "0.0.55" version "0.1.0"
resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-0.0.55.tgz#7fe327bb8c55422d7d233b5982a35eb32095d44b" resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-0.1.0.tgz#1a65936cd4f933bbea5a691f195f6eb63f1c14b2"
integrity sha512-Xvs7WJqW/U2VG5MSKjUx8uDY7e9Wibq/zpfXVef26+b1W0OS0A6MZOXAMmHwDVuAYWuHDdgPa/Hg8NGK1GXd1g== integrity sha512-Zx7ukUDIJSoDowMII+j5WU8FqcYaOA3HqtG6dNwSiv4+MdU+Ifuj+XjduqxUxP0Z4eaq4u6hV8lBsv4b4CYzeA==
dependencies: dependencies:
node-fetch "3.3.2" node-fetch "3.3.2"
openapi-types "^12.0.0" openapi-types "^12.0.0"