Skip to content

Commit 149d446

Browse files
fix: custom trees
1 parent b458e05 commit 149d446

3 files changed

Lines changed: 58 additions & 19 deletions

File tree

src/dialogs/TreeImportDialog.jsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useMemo, useState } from 'react';
22
import {
33
Dialog,
44
DialogContent,
@@ -28,6 +28,12 @@ export default function TreeImportDialog(props) {
2828
const [labelCache, setLabelCache] = useState('');
2929
const [availablePlants, setAvailablePlants] = useState();
3030
const [downloadPending, setDownloadPending] = useState();
31+
const [selectedCategory, setSelectedCategory] = useState('trees');
32+
33+
const filteredPlants = useMemo(() => {
34+
return availablePlants?.[selectedCategory] || [];
35+
}, [availablePlants, selectedCategory]);
36+
3137
const handleClose = (event, reason) => {
3238
// if (reason === 'backdropClick') {
3339
event.preventDefault();
@@ -76,23 +82,26 @@ export default function TreeImportDialog(props) {
7682
<Grid container spacing={2}>
7783
<Grid size={2}>
7884
<List>
79-
<ListItemButton selected={true}>
85+
<ListItemButton selected={selectedCategory === 'trees'} onClick={(e) => setSelectedCategory('trees')}>
8086
<ListItemText primary="Trees" />
8187
</ListItemButton>
82-
<ListItemButton>
88+
<ListItemButton selected={selectedCategory === 'grasses'} onClick={(e) => setSelectedCategory('grasses')}>
8389
<ListItemText primary="Grasses" />
8490
</ListItemButton>
85-
<ListItemButton>
91+
<ListItemButton selected={selectedCategory === 'rocks'} onClick={(e) => setSelectedCategory('rocks')}>
8692
<ListItemText primary="Rocks" />
8793
</ListItemButton>
88-
<ListItemButton>
89-
<ListItemText primary="Houses" />
94+
<ListItemButton selected={selectedCategory === 'buildings'} onClick={(e) => setSelectedCategory('buildings')}>
95+
<ListItemText primary="Buildings" />
96+
</ListItemButton>
97+
<ListItemButton selected={selectedCategory === 'custom'} onClick={(e) => setSelectedCategory('custom')}>
98+
<ListItemText primary="Custom" />
9099
</ListItemButton>
91100
</List>
92101
</Grid>
93102
<Grid size={10}>
94103
<Grid container spacing={3}>
95-
{availablePlants?.trees?.map(tree => {
104+
{filteredPlants.map(tree => {
96105
return (
97106
<Grid size={3} key={tree.title}>
98107
<Card variant="outlined">

src/lib/cache/plants.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ export function getAvailablePlants(tree) {
8484
const plantCache = getPlantCache();
8585
console.log('Found cached plants', plantCache);
8686
return {
87+
custom: Object.values(plantCache).filter(p => p.type === 'custom').map(p => {
88+
return {
89+
...p,
90+
thumbnail: `${RESOURCES_FILE_PROTOCOL}://plant-cache/${path.basename(p.thumbnail)}`,
91+
_cache: {
92+
...p,
93+
_fileExists: true
94+
}
95+
}
96+
}),
8797
trees: TREES.map(plant => {
8898
const cache = plantCache?.[plant.id];
8999
let url;

src/trees/main.js

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { randomUUID } from 'crypto';
55
import { TREE_MAKER_FILE_PROTOCOL } from '../constants';
66
import { pathToFileURL } from 'url';
77
import { exportTreePackage } from '../lib/workers/index';
8+
import { PLANT_CACHE } from '../lib/cache/plants';
9+
import { cachePlant } from '../lib/app';
810

911
let treeMakerScope = new Map();
1012
export let treeWindow;
@@ -57,26 +59,34 @@ export function createTreeMakerWindow() {
5759
treeWindow.show();
5860
}
5961

60-
ipcMain.handle('treeMaker.export', async (event, thumbnailUri) => {
62+
ipcMain.handle('treeMaker.export', async (event, thumbnailUri, plantOptions = {}) => {
6163
const thumbnailRaw = thumbnailUri.split('base64,')?.[1];
6264
if (!thumbnailRaw?.length) {
6365
throw new Error('Missing thumbnail data');
6466
}
6567

66-
const result = await dialog.showSaveDialog({
67-
defaultPath: 'TreePack'
68-
// filters: [{ extensions: ['.glb'] }]
69-
});
70-
if (result.canceled || !result.filePath?.length) {
71-
return;
72-
}
73-
const outputFile = result.filePath;
68+
// const result = await dialog.showSaveDialog({
69+
// defaultPath: 'TreePack'
70+
// // filters: [{ extensions: ['.glb'] }]
71+
// });
72+
// if (result.canceled || !result.filePath?.length) {
73+
// return;
74+
// }
75+
76+
const treeId = randomUUID();
77+
const filename = `custom-${treeId}.glb`;
78+
const filenamePNG = `custom-${treeId}.png`;
79+
const outputFileGLB = path.join(PLANT_CACHE, filename);
80+
const outputFilePNG = path.join(PLANT_CACHE, filenamePNG);
81+
82+
7483
const inputFiles = [...treeMakerScope.values()]
7584
.sort((a, b) => a.lod < b.lod ? -1 : 1)
7685
.map(tree => tree.path);
7786

78-
const outputFileGLB = `${outputFile}.glb`;
79-
const outputFilePNG = `${outputFile}.png`;
87+
// const outputFile = filePath;
88+
// const outputFileGLB = `${outputFile}.glb`;
89+
// const outputFilePNG = `${outputFile}.png`;
8090
console.log('inputFiles', inputFiles);
8191
console.log('outputFileGLB', outputFileGLB);
8292
console.log('outputFilePNG', outputFilePNG);
@@ -86,7 +96,17 @@ ipcMain.handle('treeMaker.export', async (event, thumbnailUri) => {
8696
// can take a while for compressing textures...
8797
await exportTreePackage(inputFiles, outputFileGLB);
8898

89-
shell.showItemInFolder(outputFileGLB);
99+
cachePlant({
100+
id: treeId,
101+
key: treeId,
102+
type: 'custom',
103+
title: plantOptions.title ?? 'Custom Plant',
104+
addedAt: new Date(),
105+
thumbnail: outputFilePNG,
106+
filePath: outputFileGLB,
107+
});
108+
109+
// shell.showItemInFolder(outputFileGLB);
90110

91111
});
92112

0 commit comments

Comments
 (0)