Skip to content

Commit

Permalink
fix thumbnail on publish
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoecheza committed Oct 30, 2024
1 parent 784011d commit db191be
Show file tree
Hide file tree
Showing 16 changed files with 117 additions and 31 deletions.
24 changes: 24 additions & 0 deletions packages/preload/src/modules/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,30 @@ export async function writeScene({
});
}

/**
* Updates the scene metadata to reference the new thumbnail path.
*
* @param path - The path to the project directory.
* @param scene - The current scene object.
* @param thumbnailPath - The path to the newly saved thumbnail.
*/
export async function updateSceneThumbnail(
path: string,
scene: Scene,
thumbnailPath: string,
): Promise<void> {
await writeScene({
path,
scene: {
...scene,
display: {
...scene.display,
navmapThumbnail: thumbnailPath,
},
},
});
}

/**
* Parses a string representing coordinates and returns an object with x and y properties.
* @param {string} coords - A string representing coordinates in the format "x,y".
Expand Down
36 changes: 25 additions & 11 deletions packages/preload/src/modules/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { Template, Workspace } from '/shared/types/workspace';
import { getConfig, setConfig } from './config';
import { exists, writeFile as deepWriteFile } from './fs';
import { hasDependency } from './pkg';
import { getRowsAndCols, parseCoords } from './scene';
import { getRowsAndCols, parseCoords, updateSceneThumbnail } from './scene';
import { getEditorHome } from './editor';
import { invoke } from './invoke';
import { getOudatedDeps } from './npm';
Expand Down Expand Up @@ -73,9 +73,10 @@ export async function getProjectThumbnailPath(_path: string) {

export async function getProjectThumbnailAsBase64(
projectPath: string,
scene: Scene,
scene?: Scene,
): Promise<string> {
try {
scene = scene ?? (await getScene(projectPath));
const thumbnailPath = path.join(projectPath, scene.display?.navmapThumbnail || '');
return (await fs.readFile(thumbnailPath)).toString('base64');
} catch (e) {
Expand All @@ -90,6 +91,8 @@ export async function getProjectThumbnailAsBase64(
}
}

export async function saveProjectThumbnail() {}

export async function getOutdatedPackages(_path: string): Promise<DependencyState> {
const outdated = await getOudatedDeps(_path, PACKAGES_LIST);
return outdated as DependencyState;
Expand Down Expand Up @@ -347,12 +350,14 @@ export async function reimportProject(_path: string): Promise<Project | undefine
}

/**
* Saves a thumbnail image to a specified path.
* Saves a base64-encoded thumbnail image for a project and updates the scene metadata
* if the current thumbnail is missing or invalid. Returns the updated thumbnail image
* in base64 format.
*
* @param {Object} params - The parameters for the function.
* @param {string} params.path - The path where the thumbnail will be saved.
* @param {string} params.thumbnail - The base64-encoded string of the thumbnail image.
* @returns {Promise<void>} A promise that resolves when the thumbnail has been saved.
* @param {Object} params - The parameters needed to save the thumbnail.
* @param {string} params.path - The path to the project directory.
* @param {string} params.thumbnail - The base64-encoded thumbnail image data.
* @returns {Promise<string>} A promise that resolves with the updated thumbnail in base64 format.
*/
export async function saveThumbnail({
path: _path,
Expand All @@ -361,12 +366,21 @@ export async function saveThumbnail({
path: string;
thumbnail: string;
}): Promise<void> {
await deepWriteFile(await getProjectThumbnailPath(_path), thumbnail, { encoding: 'base64' });
const thumbnailPath = await getProjectThumbnailPath(_path);
const [scene] = await Promise.all([
getScene(_path),
deepWriteFile(thumbnailPath, thumbnail, { encoding: 'base64' }),
]);

// If a current thumbnail exists but is invalid (file not found), update the scene metadata
const currentThumb = scene.display?.navmapThumbnail;
if (!currentThumb || !(await exists(currentThumb))) {
const relativeThumbnailPath = path.relative(_path, thumbnailPath);
await updateSceneThumbnail(_path, scene, relativeThumbnailPath);
}
}

export async function openFolder(_path: string) {
const error = await shell.openPath(_path);
if (error) {
throw new Error(error);
}
if (error) throw new Error(error);
}
9 changes: 7 additions & 2 deletions packages/renderer/src/components/EditorPage/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function EditorPage() {
error,
project,
refreshProject,
saveAndGetThumbnail,
inspectorPort,
openPreview,
publishScene,
Expand Down Expand Up @@ -75,9 +76,13 @@ export function EditorPage() {

const handleOpenModal = useCallback(
(type: ModalType) => () => {
setOpen(type);
const rpc = iframeRef.current;
if (rpc) {
saveAndGetThumbnail(rpc);
setOpen(type);
}
},
[],
[iframeRef.current],
);

const handleCloseModal = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { ChainId } from '@dcl/schemas/dist/dapps/chain-id';
import {
Checkbox,
CircularProgress as Loader,
FormControl,
InputLabel,
MenuItem,
Expand Down Expand Up @@ -44,13 +45,13 @@ export function PublishToWorld({ onClose }: { onClose: () => void }) {
onClose();
}, []);

return !emptyNames ? (
return emptyNames ? (
<EmptyNames />
) : (
<SelectWorld
project={project!}
onPublish={handleClickPublish}
/>
) : (
<EmptyNames />
);
}

Expand Down Expand Up @@ -131,6 +132,9 @@ function SelectWorld({ project, onPublish }: { project: Project; onPublish: () =
}
}, [project, name]);

// TODO: handle failed state...
const projectIsReady = project.status === 'succeeded';

return (
<div className="SelectWorld">
<div>
Expand All @@ -149,10 +153,9 @@ function SelectWorld({ project, onPublish }: { project: Project; onPublish: () =
</Typography>
</div>
<div className="box">
<img
className="thumbnail"
src={addBase64ImagePrefix(project.thumbnail)}
/>
<div className="thumbnail">
{!projectIsReady ? <Loader /> : <img src={addBase64ImagePrefix(project.thumbnail)} />}
</div>
<div className="selection">
<Select
variant="standard"
Expand Down Expand Up @@ -258,7 +261,7 @@ function SelectWorld({ project, onPublish }: { project: Project; onPublish: () =
)}
<Button
onClick={handleClick}
disabled={!name || (hasWorldContent && !confirmWorldReplaceContent)}
disabled={!projectIsReady || !name || (hasWorldContent && !confirmWorldReplaceContent)}
>
{t('modal.publish_project.worlds.select_world.action')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@

.MuiModal-root .SelectWorld .thumbnail {
width: 250px;
display: flex;
align-items: center;
justify-content: center;
}

.MuiModal-root .SelectWorld .thumbnail img {
width: 100%;
object-fit: cover;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function PublishProject({ open, project, onSubmit, onClose }: Props) {
open={open}
title={
step !== 'publish-to-world'
? t('modal.publish_project.title', { title: project?.title })
? t('modal.publish_project.title', { title: project.title })
: ''
}
onClose={handleClose}
Expand Down
3 changes: 3 additions & 0 deletions packages/renderer/src/components/ProjectCard/component.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { CircularProgress as Loader, Typography } from 'decentraland-ui2';
import { type MouseEvent, useCallback } from 'react';

import { t } from '/@/modules/store/translation/utils';

import { Dropdown } from '../Dropdown';

import type { Props } from './types';
Expand Down Expand Up @@ -102,6 +104,7 @@ function Overlay({
onClick={handleClick}
>
<Loader />
{t('scene_list.saving')}
</div>
);
}
1 change: 1 addition & 0 deletions packages/renderer/src/components/ProjectCard/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
opacity: 0.6;
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 10px;
Expand Down
15 changes: 10 additions & 5 deletions packages/renderer/src/hooks/useEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,18 @@ export const useEditor = () => {
[workspaceActions.updateProject, project],
);

const saveAndGetThumbnail = useCallback(async (rpcInfo: RPCInfo) => {
const thumbnail = await generateThumbnail(rpcInfo);
if (thumbnail) {
const data = { path: rpcInfo.project.path, thumbnail: stripBase64ImagePrefix(thumbnail) };
return dispatch(workspaceActions.saveAndGetThumbnail(data)).unwrap();
}
}, []);

// TODO: find a proper name for this function
const refreshProject = useCallback(
async (rpcInfo: RPCInfo) => {
const thumbnail = await generateThumbnail(rpcInfo);
if (thumbnail) {
const data = { path: rpcInfo.project.path, thumbnail: stripBase64ImagePrefix(thumbnail) };
await dispatch(workspaceActions.saveThumbnail(data)).unwrap();
}
const _ = await saveAndGetThumbnail(rpcInfo);
dispatch(workspaceActions.getProject(rpcInfo.project.path));
},
[workspaceActions.getProject, project],
Expand All @@ -84,6 +88,7 @@ export const useEditor = () => {
openPreview,
openCode,
updateScene,
saveAndGetThumbnail,
refreshProject,
};
};
2 changes: 1 addition & 1 deletion packages/renderer/src/hooks/useWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const useWorkspace = () => {
dispatch(workspaceActions.setSortBy(type));
}, []);

const runProject = useCallback(async (project: Project) => {
const runProject = useCallback((project: Project) => {
dispatch(workspaceActions.runProject(project));
navigate('/editor');
}, []);
Expand Down
1 change: 1 addition & 0 deletions packages/renderer/src/modules/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function resizeImage(image: string, maxWidth: number, maxHeight: number)
export const BASE64_PREFIX = 'data:image/png;base64,';

export function addBase64ImagePrefix(base64: string) {
if (base64.startsWith(BASE64_PREFIX)) return base64;
return `${BASE64_PREFIX}${base64}`;
}

Expand Down
12 changes: 12 additions & 0 deletions packages/renderer/src/modules/store/editor/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ export const slice = createSlice({
builder.addCase(runScene.rejected, state => {
state.loadingPreview = false;
});
builder.addCase(workspaceActions.saveAndGetThumbnail.pending, state => {
if (state.project) state.project.status = 'loading';
});
builder.addCase(workspaceActions.saveAndGetThumbnail.fulfilled, (state, action) => {
if (state.project) {
state.project.thumbnail = action.payload;
state.project.status = 'succeeded';
}
});
builder.addCase(workspaceActions.saveAndGetThumbnail.rejected, state => {
if (state.project) state.project.status = 'failed';
});
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@
"size": "Size"
},
"results": "{count} {count, plural, one {scene} other {scenes}}",
"parcel_count": "{parcels} {parcels, plural, one {parcel} other {parcels}}"
"parcel_count": "{parcels} {parcels, plural, one {parcel} other {parcels}}",
"saving": "Saving..."
},
"navbar": {
"menu": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@
"size": "Tamaño"
},
"results": "{count} {count, plural, one {escena} other {escenas}}",
"parcel_count": "{parcels} {parcels, plural, one {parcela} other {parcelas}}"
"parcel_count": "{parcels} {parcels, plural, one {parcela} other {parcelas}}",
"saving": "Guardando..."
},
"navbar": {
"menu": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@
"size": "尺寸"
},
"results": "{count}结果",
"parcel_count": "{parcels} {包裹, plural, one {包裹} other {包裹}}"
"parcel_count": "{parcels} {包裹, plural, one {包裹} other {包裹}}",
"saving": "保存..."
},
"navbar": {
"menu": {
Expand Down
8 changes: 8 additions & 0 deletions packages/renderer/src/modules/store/workspace/thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ export const installProject = createAsyncThunk('npm/install', async (path: strin
npm.install(path),
);
export const saveThumbnail = createAsyncThunk('workspace/saveThumbnail', workspace.saveThumbnail);
export const saveAndGetThumbnail = createAsyncThunk(
'workspace/saveAndGetThumbnail',
async (opts: Parameters<typeof workspace.saveThumbnail>[0], { dispatch }) => {
await dispatch(saveThumbnail(opts)).unwrap();
const thumbnail = await workspace.getProjectThumbnailAsBase64(opts.path);
return thumbnail;
},
);
export const createProjectAndInstall = createAsyncThunk(
'workspace/createProjectAndInstall',
async (opts: Parameters<typeof workspace.createProject>[0], { dispatch }) => {
Expand Down

0 comments on commit db191be

Please sign in to comment.