Make onboarding code resets persist again, await confirmation to reset code (#3151)
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@ -136,7 +136,6 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
||||
iconClassName: action.iconClassName,
|
||||
iconSize: 'md',
|
||||
}}
|
||||
paneIsOpen={false}
|
||||
onClick={action.action}
|
||||
/>
|
||||
))}
|
||||
@ -186,7 +185,7 @@ interface ModelingPaneButtonProps
|
||||
iconSize?: 'sm' | 'md' | 'lg'
|
||||
}
|
||||
onClick: () => void
|
||||
paneIsOpen: boolean
|
||||
paneIsOpen?: boolean
|
||||
}
|
||||
|
||||
function ModelingPaneButton({
|
||||
@ -220,12 +219,20 @@ function ModelingPaneButton({
|
||||
'rounded-sm ' + (paneIsOpen ? '!bg-primary' : '!bg-transparent')
|
||||
}
|
||||
/>
|
||||
<span className="sr-only">{paneConfig.title} pane</span>
|
||||
<Tooltip position="right" hoverOnly>
|
||||
<span className="flex-1">{paneConfig.title} pane: </span>
|
||||
<span className="hotkey text-xs capitalize">
|
||||
{paneConfig.keybinding}
|
||||
<span className="sr-only">
|
||||
{paneConfig.title}
|
||||
{paneIsOpen !== undefined ? ` pane` : ''}
|
||||
</span>
|
||||
<Tooltip
|
||||
position="right"
|
||||
contentClassName="max-w-none flex items-center gap-4"
|
||||
hoverOnly
|
||||
>
|
||||
<span className="flex-1">
|
||||
{paneConfig.title}
|
||||
{paneIsOpen !== undefined ? ` pane` : ''}
|
||||
</span>
|
||||
<kbd className="hotkey text-xs capitalize">{paneConfig.keybinding}</kbd>
|
||||
</Tooltip>
|
||||
</button>
|
||||
)
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { useModelingContext } from 'hooks/useModelingContext'
|
||||
import { OnboardingButtons, useDemoCode, useDismiss, useNextClick } from '.'
|
||||
import {
|
||||
kbdClasses,
|
||||
OnboardingButtons,
|
||||
useDemoCode,
|
||||
useDismiss,
|
||||
useNextClick,
|
||||
} from '.'
|
||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||
|
||||
export default function OnboardingCodeEditor() {
|
||||
@ -66,8 +72,8 @@ export default function OnboardingCodeEditor() {
|
||||
</p>
|
||||
<p className="my-4">
|
||||
You can resize the pane by dragging the handle on the right, and you
|
||||
can collapse it by clicking the title bar or pressing{' '}
|
||||
<kbd>Shift</kbd> + <kbd>C</kbd>.
|
||||
can collapse it by clicking the X button in the pane's title bar or
|
||||
pressing <kbd className={kbdClasses}>Shift + C</kbd>.
|
||||
</p>
|
||||
</section>
|
||||
<OnboardingButtons
|
||||
|
@ -19,8 +19,9 @@ export default function Export() {
|
||||
<section className="flex-1">
|
||||
<h2 className="text-2xl font-bold">Export</h2>
|
||||
<p className="my-4">
|
||||
Try opening the project menu and clicking the "Export Part" at the
|
||||
bottom of the pane.
|
||||
In addition to the "Export current part" button in the project menu,
|
||||
you can also click the Export button icon at the bottom of the left
|
||||
sidebar. Try clicking it now.
|
||||
</p>
|
||||
<p className="my-4">
|
||||
{APP_NAME} uses{' '}
|
||||
|
@ -21,9 +21,10 @@ export default function FutureWork() {
|
||||
<div className="max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded">
|
||||
<h1 className="text-2xl font-bold">Future Work</h1>
|
||||
<p className="my-4">
|
||||
We have curves, cuts, and many more CAD features coming soon. We want
|
||||
your feedback on this user interface, and we want to know what
|
||||
features you want to see next. Please message us in{' '}
|
||||
We have curves, cuts, multi-profile sketch mode, and many more CAD
|
||||
features coming soon. We want your feedback on this user interface,
|
||||
and we want to know what features you want to see next. Please message
|
||||
us in{' '}
|
||||
<a
|
||||
href="https://discord.gg/JQEpHR7Nt2"
|
||||
target="_blank"
|
||||
|
@ -18,11 +18,45 @@ import {
|
||||
PROJECT_ENTRYPOINT,
|
||||
} from 'lib/constants'
|
||||
import { createNewProjectDirectory, listProjects } from 'lib/tauri'
|
||||
import { useState } from 'react'
|
||||
|
||||
function OnboardingWithNewFile() {
|
||||
/**
|
||||
* Show either a welcome screen or a warning screen
|
||||
* depending on if the user has code in the editor.
|
||||
*/
|
||||
export default function OnboardingIntroduction() {
|
||||
const [shouldShowWarning, setShouldShowWarning] = useState(
|
||||
codeManager.code !== '' && codeManager.code !== bracket
|
||||
)
|
||||
|
||||
return shouldShowWarning ? (
|
||||
<OnboardingResetWarning setShouldShowWarning={setShouldShowWarning} />
|
||||
) : (
|
||||
<OnboardingIntroductionInner />
|
||||
)
|
||||
}
|
||||
|
||||
interface OnboardingResetWarningProps {
|
||||
setShouldShowWarning: (arg: boolean) => void
|
||||
}
|
||||
|
||||
function OnboardingResetWarning(props: OnboardingResetWarningProps) {
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 grid place-content-center bg-chalkboard-110/50">
|
||||
<div className="max-w-3xl p-8 rounded bg-chalkboard-10 dark:bg-chalkboard-90">
|
||||
{!isTauri() ? (
|
||||
<OnboardingWarningWeb {...props} />
|
||||
) : (
|
||||
<OnboardingWarningDesktop />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function OnboardingWarningDesktop() {
|
||||
const navigate = useNavigate()
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.INDEX)
|
||||
|
||||
async function createAndOpenNewProject() {
|
||||
const projects = await listProjects()
|
||||
@ -38,40 +72,17 @@ function OnboardingWithNewFile() {
|
||||
)}${paths.ONBOARDING.INDEX}`
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 grid place-content-center bg-chalkboard-110/50">
|
||||
<div className="max-w-3xl p-8 rounded bg-chalkboard-10 dark:bg-chalkboard-90">
|
||||
{!isTauri() ? (
|
||||
<>
|
||||
<h1 className="text-3xl font-bold text-warn-80 dark:text-warn-10">
|
||||
Replaying onboarding resets your code
|
||||
</h1>
|
||||
<p className="my-4">
|
||||
We see you have some of your own code written in this project.
|
||||
Please save it somewhere else before continuing the onboarding.
|
||||
</p>
|
||||
<OnboardingButtons
|
||||
className="mt-6"
|
||||
dismiss={dismiss}
|
||||
next={() => {
|
||||
// We do want to update both the state and editor here.
|
||||
codeManager.updateCodeEditor(bracket)
|
||||
kclManager.executeCode(true)
|
||||
next()
|
||||
}}
|
||||
nextText="Overwrite code and continue"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<h1 className="flex flex-wrap items-center gap-4 text-3xl font-bold">
|
||||
Would you like to create a new project?
|
||||
</h1>
|
||||
<section className="my-12">
|
||||
<p className="my-4">
|
||||
You have some content in this project that we don't want to
|
||||
overwrite. If you would like to create a new project, please
|
||||
click the button below.
|
||||
You have some content in this project that we don't want to overwrite.
|
||||
If you would like to create a new project, please click the button
|
||||
below.
|
||||
</p>
|
||||
</section>
|
||||
<OnboardingButtons
|
||||
@ -85,13 +96,45 @@ function OnboardingWithNewFile() {
|
||||
nextText="Make a new project"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function OnboardingIntroduction() {
|
||||
function OnboardingWarningWeb(props: OnboardingResetWarningProps) {
|
||||
const dismiss = useDismiss()
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className="text-3xl font-bold text-warn-80 dark:text-warn-10">
|
||||
Replaying onboarding resets your code
|
||||
</h1>
|
||||
<p className="my-4">
|
||||
We see you have some of your own code written in this project. Please
|
||||
save it somewhere else before continuing the onboarding.
|
||||
</p>
|
||||
<OnboardingButtons
|
||||
className="mt-6"
|
||||
dismiss={dismiss}
|
||||
next={async () => {
|
||||
// We do want to update both the state and editor here.
|
||||
codeManager.updateCodeStateEditor(bracket)
|
||||
await codeManager.writeToFile()
|
||||
|
||||
kclManager.isFirstRender = true
|
||||
await kclManager.executeCode(true).then(() => {
|
||||
kclManager.isFirstRender = false
|
||||
})
|
||||
props.setShouldShowWarning(false)
|
||||
}}
|
||||
nextText="Overwrite code and continue"
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function OnboardingIntroductionInner() {
|
||||
// Reset the code to the bracket code
|
||||
useDemoCode()
|
||||
|
||||
const {
|
||||
settings: {
|
||||
state: {
|
||||
@ -108,12 +151,8 @@ export default function OnboardingIntroduction() {
|
||||
: ''
|
||||
const dismiss = useDismiss()
|
||||
const next = useNextClick(onboardingPaths.CAMERA)
|
||||
const currentCode = codeManager.code
|
||||
const isStarterCode = currentCode === '' || currentCode === bracket
|
||||
|
||||
useDemoCode()
|
||||
|
||||
return isStarterCode ? (
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 grid place-content-center bg-chalkboard-110/50">
|
||||
<div className="max-w-3xl p-8 rounded bg-chalkboard-10 dark:bg-chalkboard-90">
|
||||
<h1 className="flex flex-wrap items-center gap-4 text-3xl font-bold">
|
||||
@ -172,7 +211,5 @@ export default function OnboardingIntroduction() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<OnboardingWithNewFile />
|
||||
)
|
||||
}
|
||||
|
@ -20,8 +20,9 @@ export default function ProjectMenu() {
|
||||
<section className="flex-1">
|
||||
<h2 className="text-2xl font-bold">Project Menu</h2>
|
||||
<p className="my-4">
|
||||
Click on your part's name in the upper left to open the project
|
||||
menu.
|
||||
Click on {tauri ? `your part's name` : `the app name`} in the upper
|
||||
left to open the project menu, where you can open the project
|
||||
settings and export your current part.
|
||||
{tauri && (
|
||||
<> You can click the Zoo logo to quickly navigate home.</>
|
||||
)}
|
||||
@ -43,8 +44,8 @@ export default function ProjectMenu() {
|
||||
) : (
|
||||
<>
|
||||
<p className="my-4">
|
||||
From here you can export your part. You can't manage separate
|
||||
files and separate projects from the browser; you have to{' '}
|
||||
You can't manage separate files and separate projects from the
|
||||
browser; you have to{' '}
|
||||
<a
|
||||
href="https://zoo.dev/modeling-app/download"
|
||||
target="_blank"
|
||||
|
@ -10,12 +10,16 @@ export default function Sketching() {
|
||||
const next = useNextClick(onboardingPaths.FUTURE_WORK)
|
||||
|
||||
useEffect(() => {
|
||||
async function clearEditor() {
|
||||
// We do want to update both the state and editor here.
|
||||
codeManager.updateCodeEditor('')
|
||||
if (kclManager.engineCommandManager.engineConnection?.isReady()) {
|
||||
// If the engine is ready, promptly execute the loaded code
|
||||
kclManager.executeCode(true)
|
||||
codeManager.updateCodeStateEditor('')
|
||||
kclManager.isFirstRender = true
|
||||
await kclManager.executeCode(true).then(() => {
|
||||
kclManager.isFirstRender = false
|
||||
})
|
||||
}
|
||||
|
||||
clearEditor()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
@ -43,19 +43,13 @@ export default function UserMenu() {
|
||||
<h2 className="text-2xl font-bold">User Menu</h2>
|
||||
<p className="my-4">
|
||||
Click {buttonDescription} in the upper right to open the user menu.
|
||||
You can change your settings, sign out, or request a feature.
|
||||
You can change your user-level settings, sign out, or request a
|
||||
feature.
|
||||
</p>
|
||||
<p className="my-4">
|
||||
We only support global settings at the moment, but we are working to
|
||||
implement{' '}
|
||||
<a
|
||||
href="https://github.com/KittyCAD/modeling-app/issues/1503"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
per-project settings
|
||||
</a>{' '}
|
||||
now.
|
||||
Many settings can be set either a user or per-project level. User
|
||||
settings will apply to all projects, while project settings will
|
||||
only apply to the current project.
|
||||
</p>
|
||||
</section>
|
||||
<OnboardingButtons
|
||||
|
@ -19,7 +19,7 @@ import { paths } from 'lib/paths'
|
||||
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
|
||||
import { ActionButton } from 'components/ActionButton'
|
||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||
import { codeManager, editorManager } from 'lib/singletons'
|
||||
import { codeManager, editorManager, kclManager } from 'lib/singletons'
|
||||
import { bracket } from 'lib/exampleKcl'
|
||||
|
||||
export const kbdClasses =
|
||||
@ -80,8 +80,13 @@ export const onboardingRoutes = [
|
||||
export function useDemoCode() {
|
||||
useEffect(() => {
|
||||
if (!editorManager.editorView) return
|
||||
setTimeout(() => {
|
||||
setTimeout(async () => {
|
||||
codeManager.updateCodeStateEditor(bracket)
|
||||
kclManager.isFirstRender = true
|
||||
await kclManager.executeCode(true).then(() => {
|
||||
kclManager.isFirstRender = false
|
||||
})
|
||||
codeManager.writeToFile()
|
||||
})
|
||||
}, [editorManager.editorView])
|
||||
}
|
||||
@ -171,8 +176,8 @@ export function OnboardingButtons({
|
||||
onClick={dismiss}
|
||||
iconStart={{
|
||||
icon: 'close',
|
||||
className: 'text-chalkboard-10',
|
||||
bgClassName: 'bg-destroy-80 group-hover:bg-destroy-80',
|
||||
iconClassName: 'text-destroy-20 group-hover:text-destroy-10',
|
||||
}}
|
||||
className="hover:border-destroy-40 hover:bg-destroy-10/50 dark:hover:bg-destroy-80/50"
|
||||
>
|
||||
|