Skip to content

Commit f65dd35

Browse files
Merge pull request #24 from setrsoft/main
Refactor components for improved state management
2 parents 02ce305 + 5ec98c4 commit f65dd35

25 files changed

Lines changed: 299 additions & 355 deletions

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ WALLS_CDN_BASE=https://huggingface.co/datasets/setrsoft/climbing-walls/resolve/m
5050
# --- PostHog analytics ---
5151
# Project API Key (Project Settings → Project API Key). Leave empty to disable.
5252
VITE_PUBLIC_POSTHOG_PROJECT_TOKEN=phc_xxxxxxxxxxxxxxxxxxxx
53-
VITE_PUBLIC_POSTHOG_HOST=https://eu.i.posthog.com
53+
VITE_PUBLIC_POSTHOG_HOST=https://e.setrsoft.com

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
SetRsoft is an open source community driven software. Test it live on the website http://www.setrsoft.com/
1919

20-
For better understanding the purpose of this project you can have a look at [one of those videos](https://www.youtube.com/results?search_query=routesetting+in+climbing+gym).
20+
For better understanding the purpose of this project you can have a look at [this video made for 42Builders](https://e.pcloud.link/publink/show?code=XZJuQiZvUY5trMn7pXG09SRvvzBpJmPkl5k).
2121

2222
Feel free to create new Github Issues for new features or signal bugs.
2323

frontend/package-lock.json

Lines changed: 30 additions & 77 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@
1818
"posthog-js": "^1.364.7",
1919
"react": "^19.2.0",
2020
"react-dom": "^19.2.0",
21-
"react-helmet-async": "^2.0.1",
2221
"react-i18next": "^16.6.0",
2322
"react-router-dom": "^7.13.1",
2423
"three": "^0.177.0",
25-
"uuid": "^11.1.0",
24+
"uuid": "^14.0.0",
2625
"zustand": "^5.0.4"
2726
},
2827
"devDependencies": {

frontend/src/features/editor/EditorApp.tsx

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { useEffect, useRef, useState } from "react";
1+
import { useEffect, useMemo, useRef, useState } from "react";
22
import { useGLTF } from "@react-three/drei";
33
import { useParams } from "react-router-dom";
44
import { useQuery } from "@tanstack/react-query";
55
import { posthog } from "@/shared/analytics/posthog";
66

77
import useWallSessionQuery from "./utils/WallSessionQuery";
88
import { usePlacementStore } from "./store";
9+
import type { SessionHoldInstance } from "./store";
910
import { useHandleLoadSession } from "./utils/HandleLoadSession";
1011

1112
import MainCanvas from "./components/MainCanvas";
@@ -15,15 +16,6 @@ import FileManager from "./components/FileManager";
1516
import { useTranslation } from "react-i18next";
1617
import Tutorial from "./components/Tutorial";
1718

18-
interface HoldInstance {
19-
id: string;
20-
hold_instance_id?: string;
21-
hold_type?: {
22-
glb_url?: string;
23-
};
24-
[key: string]: unknown;
25-
}
26-
2719
const transformTools = [
2820
{ id: "translate", icon: "open_with", label: "Translate", hint: "Shift + Left click" },
2921
{ id: "rotate", icon: "sync", label: "Rotate", hint: "Left click" },
@@ -46,6 +38,8 @@ function EditorApp() {
4638
queryKey: ["wallsession", wallId],
4739
queryFn: () => fetchWallSession(wallId as string),
4840
enabled: !!wallId,
41+
staleTime: Infinity,
42+
refetchOnWindowFocus: false,
4943
});
5044

5145
const session_data = data?.wall_session || data;
@@ -63,12 +57,10 @@ function EditorApp() {
6357
}, [wallId, setObjects, setWallColors, setHoldColors, setColoredTexture, setHasUnsavedChanges]);
6458

6559
useEffect(() => {
66-
if (session_data?.id && wallModels.length > 0) {
60+
if (session_data?.id && wallModels.length > 0 && !sessionOpenedRef.current) {
61+
sessionOpenedRef.current = true;
6762
handleLoad();
68-
if (!sessionOpenedRef.current) {
69-
sessionOpenedRef.current = true;
70-
posthog.capture('editor session opened', { wall_id: wallId, session_id: session_data.id });
71-
}
63+
posthog.capture('editor session opened', { wall_id: wallId, session_id: session_data.id });
7264
}
7365
}, [session_data?.id, wallId, wallModels.length, handleLoad]);
7466

@@ -84,23 +76,26 @@ function EditorApp() {
8476
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
8577
}, [hasUnsavedChanges, t]);
8678

87-
const holdModels: Array<Record<string, HoldInstance>> = [];
88-
const holdModelsGLBURL: string[] = [];
89-
9079
useEffect(() => {
9180
const glbUrl = session_data?.related_wall?.glb_url;
9281
setWallModels(glbUrl ? [glbUrl] : []);
9382
}, [session_data?.related_wall?.glb_url]);
9483

95-
if (session_data?.related_holds_collection) {
96-
session_data.holds_collection_instances?.forEach((hold: any) => {
97-
hold.hold_instance_id = hold.id;
98-
holdModels.push(hold);
99-
if (hold.hold_type?.glb_url) {
100-
holdModelsGLBURL.push(hold.hold_type.glb_url);
101-
}
102-
});
103-
}
84+
const { holdModels, holdModelsGLBURL } = useMemo(() => {
85+
const holdModels: SessionHoldInstance[] = [];
86+
const glbUrlSet = new Set<string>();
87+
if (session_data?.related_holds_collection) {
88+
session_data.holds_collection_instances?.forEach((hold: SessionHoldInstance) => {
89+
const holdWithId = { ...hold, hold_instance_id: hold.id };
90+
holdModels.push(holdWithId);
91+
if (holdWithId.hold_type?.glb_url) {
92+
glbUrlSet.add(holdWithId.hold_type.glb_url);
93+
}
94+
});
95+
}
96+
const holdModelsGLBURL = Array.from(glbUrlSet);
97+
return { holdModels, holdModelsGLBURL };
98+
}, [session_data?.related_holds_collection, session_data?.holds_collection_instances]);
10499

105100
const { preload } = useGLTF;
106101
useEffect(() => {

0 commit comments

Comments
 (0)