diff --git a/theatre/studio/src/Studio.ts b/theatre/studio/src/Studio.ts index 8a3e959..97e3a0f 100644 --- a/theatre/studio/src/Studio.ts +++ b/theatre/studio/src/Studio.ts @@ -57,6 +57,13 @@ export class Studio { this._attachToIncomingProjects() this.paneManager = new PaneManager(this) + + /** + * @todo If studio.initialize() is not called within a few milliseconds, + * we should console.warn() the user that `@theatre/studio` is still in + * their bundle. This way we can avoid issues like + * [this](https://discord.com/channels/870988717190426644/892469755225710642/892479678797971486). + */ } async initialize(opts?: Parameters[0]) { @@ -209,7 +216,7 @@ export class Studio { this._store.redo() } - createExportedStateOfProject(projectId: string): OnDiskState { - return this._store.createExportedStateOfProject(projectId) + createContentOfSaveFile(projectId: string): OnDiskState { + return this._store.createContentOfSaveFile(projectId) } } diff --git a/theatre/studio/src/StudioStore/StudioStore.ts b/theatre/studio/src/StudioStore/StudioStore.ts index d22c570..308e73b 100644 --- a/theatre/studio/src/StudioStore/StudioStore.ts +++ b/theatre/studio/src/StudioStore/StudioStore.ts @@ -280,9 +280,17 @@ export default class StudioStore { this._reduxStore.dispatch(studioActions.historic.redo()) } - createExportedStateOfProject(projectId: string): OnDiskState { + createContentOfSaveFile(projectId: string): OnDiskState { + const projectState = + this._reduxStore.getState().$persistent.historic.innerState.coreByProject[ + projectId + ] + + if (!projectState) { + throw new Error(`Project ${projectId} has not been initialized.`) + } + const revision = generateDiskStateRevision() - // let's assume projectId is already loaded this.tempTransaction(({stateEditors}) => { stateEditors.coreByProject.historic.revisionHistory.add({ diff --git a/theatre/studio/src/TheatreStudio.ts b/theatre/studio/src/TheatreStudio.ts index d56dc27..45fe314 100644 --- a/theatre/studio/src/TheatreStudio.ts +++ b/theatre/studio/src/TheatreStudio.ts @@ -301,6 +301,25 @@ export interface IStudio { * studio is present. */ getStudioProject(): IProject + + /** + * Creates a JSON object that contains the state of the project. You can use this + * to programmatically save the state of your projects to the storage system of your + * choice, rather than manually clicking on the "Export" button in the UI. + * + * @param projectId same projectId as in `core.getProject(projectId)` + * + * Usage: + * ```ts + * const projectId = "project" + * const json = studio.createContentOfSaveFile(projectId) + * const string = JSON.stringify(json) + * fetch(`/projects/${projectId}/state`, {method: 'POST', body: string}).then(() => { + * console.log("Saved") + * }) + * ``` + */ + createContentOfSaveFile(projectId: string): Record } export default class TheatreStudio implements IStudio { @@ -431,4 +450,8 @@ export default class TheatreStudio implements IStudio { destroyPane(paneId: string): void { return getStudio().paneManager.destroyPane(paneId) } + + createContentOfSaveFile(projectId: string): Record { + return getStudio().createContentOfSaveFile(projectId) as $IntentionalAny + } } diff --git a/theatre/studio/src/panels/DetailPanel/ProjectDetails/ProjectDetails.tsx b/theatre/studio/src/panels/DetailPanel/ProjectDetails/ProjectDetails.tsx index fcf3415..751c1a5 100644 --- a/theatre/studio/src/panels/DetailPanel/ProjectDetails/ProjectDetails.tsx +++ b/theatre/studio/src/panels/DetailPanel/ProjectDetails/ProjectDetails.tsx @@ -35,7 +35,7 @@ const ProjectDetails: React.FC<{ const exportProject = useCallback(() => { const str = JSON.stringify( - getStudio().createExportedStateOfProject(project.address.projectId), + getStudio().createContentOfSaveFile(project.address.projectId), null, 2, )