Add option to navigate to new project from file menu (#3876)
Rel #3861 TLD-2551 This PR adds a menu item to both multiplayer and local editor components, to create a new shared project in the file menu. I think it might be helpful to add a dialog as well. At the moment it feels a bit sudden to jump to a new page right after clicking. However it's non-destructive, and it would add an unnecessary extra step. What do you think? ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [ ] `sdk` — Changes the tldraw SDK - [x] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [ ] `bugfix` — Bug fix - [x] `feature` — New feature - [ ] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know ### Test Plan 1. Add a step-by-step description of how to test your PR here. 2. - [ ] Unit Tests - [ ] End to end tests ### Release Notes - Add a brief release note for your PR here.
This commit is contained in:
parent
5d7f368fd6
commit
7071b5fee2
3 changed files with 22 additions and 3 deletions
|
@ -4,7 +4,12 @@ import {
|
||||||
LEAVE_SHARED_PROJECT_ACTION,
|
LEAVE_SHARED_PROJECT_ACTION,
|
||||||
SHARE_PROJECT_ACTION,
|
SHARE_PROJECT_ACTION,
|
||||||
} from '../utils/sharing'
|
} from '../utils/sharing'
|
||||||
import { NEW_PROJECT_ACTION, OPEN_FILE_ACTION, SAVE_FILE_COPY_ACTION } from '../utils/useFileSystem'
|
import {
|
||||||
|
NEW_PROJECT_ACTION,
|
||||||
|
NEW_SHARED_PROJECT_ACTION,
|
||||||
|
OPEN_FILE_ACTION,
|
||||||
|
SAVE_FILE_COPY_ACTION,
|
||||||
|
} from '../utils/useFileSystem'
|
||||||
|
|
||||||
export function LocalFileMenu() {
|
export function LocalFileMenu() {
|
||||||
const actions = useActions()
|
const actions = useActions()
|
||||||
|
@ -13,6 +18,7 @@ export function LocalFileMenu() {
|
||||||
<TldrawUiMenuSubmenu id="file" label="menu.file">
|
<TldrawUiMenuSubmenu id="file" label="menu.file">
|
||||||
<TldrawUiMenuGroup id="file-actions">
|
<TldrawUiMenuGroup id="file-actions">
|
||||||
<TldrawUiMenuItem {...actions[NEW_PROJECT_ACTION]} />
|
<TldrawUiMenuItem {...actions[NEW_PROJECT_ACTION]} />
|
||||||
|
<TldrawUiMenuItem {...actions[NEW_SHARED_PROJECT_ACTION]} />
|
||||||
<TldrawUiMenuItem {...actions[OPEN_FILE_ACTION]} />
|
<TldrawUiMenuItem {...actions[OPEN_FILE_ACTION]} />
|
||||||
<TldrawUiMenuItem {...actions[SAVE_FILE_COPY_ACTION]} />
|
<TldrawUiMenuItem {...actions[SAVE_FILE_COPY_ACTION]} />
|
||||||
</TldrawUiMenuGroup>
|
</TldrawUiMenuGroup>
|
||||||
|
@ -32,6 +38,7 @@ export function MultiplayerFileMenu() {
|
||||||
<TldrawUiMenuItem {...actions[SAVE_FILE_COPY_ACTION]} />
|
<TldrawUiMenuItem {...actions[SAVE_FILE_COPY_ACTION]} />
|
||||||
</TldrawUiMenuGroup>
|
</TldrawUiMenuGroup>
|
||||||
<TldrawUiMenuGroup id="share">
|
<TldrawUiMenuGroup id="share">
|
||||||
|
<TldrawUiMenuItem {...actions[NEW_SHARED_PROJECT_ACTION]} />
|
||||||
<TldrawUiMenuItem {...actions[FORK_PROJECT_ACTION]} />
|
<TldrawUiMenuItem {...actions[FORK_PROJECT_ACTION]} />
|
||||||
<TldrawUiMenuItem {...actions[LEAVE_SHARED_PROJECT_ACTION]} />
|
<TldrawUiMenuItem {...actions[LEAVE_SHARED_PROJECT_ACTION]} />
|
||||||
</TldrawUiMenuGroup>
|
</TldrawUiMenuGroup>
|
||||||
|
|
|
@ -35,5 +35,5 @@ export function Component() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
return <Navigate to={`/${ROOM_PREFIX}/${data.slug}`} />
|
return <Navigate replace to={`/${ROOM_PREFIX}/${data.slug}`} />
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { fileOpen, fileSave } from 'browser-fs-access'
|
import { fileOpen, fileSave } from 'browser-fs-access'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
import {
|
import {
|
||||||
Editor,
|
Editor,
|
||||||
TLDRAW_FILE_EXTENSION,
|
TLDRAW_FILE_EXTENSION,
|
||||||
|
@ -18,11 +19,13 @@ import { useHandleUiEvents } from './useHandleUiEvent'
|
||||||
export const SAVE_FILE_COPY_ACTION = 'save-file-copy'
|
export const SAVE_FILE_COPY_ACTION = 'save-file-copy'
|
||||||
export const OPEN_FILE_ACTION = 'open-file'
|
export const OPEN_FILE_ACTION = 'open-file'
|
||||||
export const NEW_PROJECT_ACTION = 'new-file'
|
export const NEW_PROJECT_ACTION = 'new-file'
|
||||||
|
export const NEW_SHARED_PROJECT_ACTION = 'new-shared-file'
|
||||||
|
|
||||||
const saveFileNames = new WeakMap<TLStore, string>()
|
const saveFileNames = new WeakMap<TLStore, string>()
|
||||||
|
|
||||||
export function useFileSystem({ isMultiplayer }: { isMultiplayer: boolean }): TLUiOverrides {
|
export function useFileSystem({ isMultiplayer }: { isMultiplayer: boolean }): TLUiOverrides {
|
||||||
const handleUiEvent = useHandleUiEvents()
|
const handleUiEvent = useHandleUiEvents()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
return useMemo((): TLUiOverrides => {
|
return useMemo((): TLUiOverrides => {
|
||||||
return {
|
return {
|
||||||
|
@ -67,6 +70,15 @@ export function useFileSystem({ isMultiplayer }: { isMultiplayer: boolean }): TL
|
||||||
await parseAndLoadDocument(editor, await file.text(), msg, addToast)
|
await parseAndLoadDocument(editor, await file.text(), msg, addToast)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
actions[NEW_SHARED_PROJECT_ACTION] = {
|
||||||
|
id: NEW_SHARED_PROJECT_ACTION,
|
||||||
|
label: 'action.new-shared-project',
|
||||||
|
readonlyOk: true,
|
||||||
|
async onSelect(source) {
|
||||||
|
handleUiEvent('create-new-shared-project', { source })
|
||||||
|
navigate('/new')
|
||||||
|
},
|
||||||
|
}
|
||||||
actions[NEW_PROJECT_ACTION] = {
|
actions[NEW_PROJECT_ACTION] = {
|
||||||
id: NEW_PROJECT_ACTION,
|
id: NEW_PROJECT_ACTION,
|
||||||
label: 'action.new-project',
|
label: 'action.new-project',
|
||||||
|
@ -93,7 +105,7 @@ export function useFileSystem({ isMultiplayer }: { isMultiplayer: boolean }): TL
|
||||||
return actions
|
return actions
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}, [isMultiplayer, handleUiEvent])
|
}, [handleUiEvent, isMultiplayer, navigate])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSaveFileCopyAction(
|
export function getSaveFileCopyAction(
|
||||||
|
|
Loading…
Reference in a new issue