diff --git a/package.json b/package.json index 0a10c382c..0124eadd7 100644 --- a/package.json +++ b/package.json @@ -164,7 +164,7 @@ "postcss-normalize": "8.0.1", "postcss-preset-env": "6.7.0", "postcss-safe-parser": "5.0.2", - "prettier": "^2.8.8", + "prettier": "^3.2.4", "react-dev-utils": "^11.0.3", "react-test-renderer": "^17.0.2", "redux-mock-store": "^1.5.4", diff --git a/src/containers/WebComponentLoader.jsx b/src/containers/WebComponentLoader.jsx index 273c13dda..f5442ded0 100644 --- a/src/containers/WebComponentLoader.jsx +++ b/src/containers/WebComponentLoader.jsx @@ -24,6 +24,8 @@ const WebComponentLoader = (props) => { const { authKey, identifier, + codeIdentifier, + assetIdentifier, code, senseHatAlwaysEnabled = false, instructions, @@ -94,6 +96,8 @@ const WebComponentLoader = (props) => { useProject({ projectIdentifier: projectIdentifier, + codeIdentifier, + assetIdentifier, code, accessToken: user?.access_token, loadRemix, diff --git a/src/hooks/useProject.js b/src/hooks/useProject.js index e349ddf85..043be07cf 100644 --- a/src/hooks/useProject.js +++ b/src/hooks/useProject.js @@ -7,6 +7,8 @@ import { useTranslation } from "react-i18next"; export const useProject = ({ projectIdentifier = null, + codeIdentifier = null, + assetIdentifier = null, code = null, accessToken = null, loadRemix = false, @@ -71,6 +73,18 @@ export const useProject = ({ return; } + if (codeIdentifier || assetIdentifier) { + dispatch( + syncProject("load")({ + codeIdentifier, + assetIdentifier, + locale: i18n.language, + accessToken: accessToken, + }), + ); + return; + } + const data = defaultPythonProject; dispatch(setProject(data)); } diff --git a/src/redux/EditorSlice.js b/src/redux/EditorSlice.js index ecded2a11..617a73282 100644 --- a/src/redux/EditorSlice.js +++ b/src/redux/EditorSlice.js @@ -18,13 +18,27 @@ export const syncProject = (actionName) => createAsyncThunk( `editor/${actionName}Project`, async ( - { project, identifier, locale, accessToken, autosave }, + { + project, + identifier, + codeIdentifier, + assetIdentifier, + locale, + accessToken, + autosave, + }, { rejectWithValue }, ) => { let response; switch (actionName) { case "load": - response = await readProject(identifier, locale, accessToken); + response = await readProject( + identifier, + codeIdentifier, + assetIdentifier, + locale, + accessToken, + ); break; case "loadRemix": response = await loadRemix(identifier, accessToken); diff --git a/src/utils/apiCallHandler.js b/src/utils/apiCallHandler.js index 8357d2331..d176721c7 100644 --- a/src/utils/apiCallHandler.js +++ b/src/utils/apiCallHandler.js @@ -1,5 +1,6 @@ import axios from "axios"; import omit from "lodash/omit"; +import { defaultPythonProject } from "./defaultProjects"; const host = process.env.REACT_APP_API_ENDPOINT; @@ -68,12 +69,66 @@ export const createRemix = async (project, accessToken) => { ); }; -export const readProject = async (projectIdentifier, locale, accessToken) => { +export const readProject = async ( + projectIdentifier, + codeIdentifier, + assetIdentifier, + locale, + accessToken, +) => { const queryString = locale ? `?locale=${locale}` : ""; - return await get( - `${host}/api/projects/${projectIdentifier}${queryString}`, - headers(accessToken), - ); + + //todo, check if code and asset are same, check if normal identifier, load, merge, return + + if (projectIdentifier) { + return await get( + `${host}/api/projects/${projectIdentifier}${queryString}`, + headers(accessToken), + ); + } else { + //Load separate code and assets + + const loadCode = new Promise(async (resolve, reject) => { + if (!codeIdentifier) return resolve(defaultPythonProject); + + const code = await get( + `${host}/api/projects/${codeIdentifier}${queryString}`, + headers(accessToken), + ); + + resolve({ + components: code.data.components, + identifier: code.data.identifier, + locale: code.data.locale, + name: code.data.name, + project_type: code.data.project_type, + user_id: code.data.user_id, + }); + }); + + const loadAssets = new Promise(async (resolve, reject) => { + if (!assetIdentifier) return resolve({ image_list: [] }); + + const assets = await get( + `${host}/api/projects/${assetIdentifier}/images`, + headers(accessToken), + ); + + resolve({ + image_list: assets.data.image_list, + }); + }); + + const result = await Promise.all([loadCode, loadAssets]).then((res) => { + return res.reduce(function (acc, row) { + return { ...acc, ...row }; + }, {}); + }); + + return { + data: result, + }; + } }; export const readProjectList = async (page, accessToken) => { diff --git a/src/web-component.js b/src/web-component.js index 9cdb605c9..c8ed8fe1f 100644 --- a/src/web-component.js +++ b/src/web-component.js @@ -39,6 +39,8 @@ class WebComponent extends HTMLElement { "host_styles", "auth_key", "identifier", + "code_identifier", + "asset_identifier", "code", "sense_hat_always_enabled", "instructions", diff --git a/yarn.lock b/yarn.lock index e0c4f6929..19d16346b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10938,10 +10938,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.8.8: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.4.tgz#4723cadeac2ce7c9227de758e5ff9b14e075f283" + integrity sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ== pretty-bytes@^5.3.0, pretty-bytes@^5.6.0: version "5.6.0"