From 3710d2ffe4d2f8631bdb808c91efc22ec745fbeb Mon Sep 17 00:00:00 2001 From: jiayi Date: Sat, 11 Jan 2025 03:36:27 +0800 Subject: [PATCH 1/3] Change files for project #111 --- Browser_IDE/IDEStartupMain.js | 11 +++++++++-- Browser_IDE/splashKitOnlineEnvParams.js | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Browser_IDE/IDEStartupMain.js b/Browser_IDE/IDEStartupMain.js index 367f683..edae36f 100644 --- a/Browser_IDE/IDEStartupMain.js +++ b/Browser_IDE/IDEStartupMain.js @@ -98,10 +98,17 @@ async function StartIDE() { setupIDEButtonEvents(); // uses current language // Create execution environment and project storage objects - // These constructors don't _do_ anything important. executionEnviroment = new ExecutionEnvironment(document.getElementById("ExecutionEnvironment"), activeLanguageSetup); appStorage = new AppStorage(); - storedProject = new IDBStoredProject(appStorage, activeLanguageSetup.getDefaultProject()); + + // Check if projectID exists in URL, if so, load that project + let projectID = SKO.projectID; + if (projectID) { + storedProject = new IDBStoredProject(appStorage, projectID); // Use project ID if available + } else { + storedProject = new IDBStoredProject(appStorage, activeLanguageSetup.getDefaultProject()); // Default project + } + unifiedFS = new UnifiedFS(storedProject, executionEnviroment); // Setup callbacks/listeners diff --git a/Browser_IDE/splashKitOnlineEnvParams.js b/Browser_IDE/splashKitOnlineEnvParams.js index 42e00db..2dea523 100644 --- a/Browser_IDE/splashKitOnlineEnvParams.js +++ b/Browser_IDE/splashKitOnlineEnvParams.js @@ -28,5 +28,7 @@ let SKO = (function(){ useCompressedBinaries: getEnvParam("useCompressedBinaries", "on", true) == "on", useMinifiedInterface: getEnvParam("useMinifiedInterface") == "on", isPRPreview: getEnvParam("isPRPreview", isPreview ? "on" : "off") == "on", + // add projectID + projectID: getEnvParam("projectID", null, true) }; })(); \ No newline at end of file From 65a7e39c3ea6f403e1412513174e0824fad1840b Mon Sep 17 00:00:00 2001 From: jiayi Date: Sat, 11 Jan 2025 04:47:19 +0800 Subject: [PATCH 2/3] Update IDEStartupMain.js and splashKitOnlineEnvParams.js --- Browser_IDE/IDEStartupMain.js | 3 ++- Browser_IDE/splashKitOnlineEnvParams.js | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Browser_IDE/IDEStartupMain.js b/Browser_IDE/IDEStartupMain.js index edae36f..2432f72 100644 --- a/Browser_IDE/IDEStartupMain.js +++ b/Browser_IDE/IDEStartupMain.js @@ -105,7 +105,8 @@ async function StartIDE() { let projectID = SKO.projectID; if (projectID) { storedProject = new IDBStoredProject(appStorage, projectID); // Use project ID if available - } else { + } + else { storedProject = new IDBStoredProject(appStorage, activeLanguageSetup.getDefaultProject()); // Default project } diff --git a/Browser_IDE/splashKitOnlineEnvParams.js b/Browser_IDE/splashKitOnlineEnvParams.js index 2dea523..f84ddaf 100644 --- a/Browser_IDE/splashKitOnlineEnvParams.js +++ b/Browser_IDE/splashKitOnlineEnvParams.js @@ -28,7 +28,6 @@ let SKO = (function(){ useCompressedBinaries: getEnvParam("useCompressedBinaries", "on", true) == "on", useMinifiedInterface: getEnvParam("useMinifiedInterface") == "on", isPRPreview: getEnvParam("isPRPreview", isPreview ? "on" : "off") == "on", - // add projectID - projectID: getEnvParam("projectID", null, true) + projectID: getEnvParam("projectID", null, true) // add projectID }; })(); \ No newline at end of file From 20ca29d9164ce0a9fd81f24058f9d35e4c2aae88 Mon Sep 17 00:00:00 2001 From: jiayi Date: Sun, 12 Jan 2025 17:49:07 +0800 Subject: [PATCH 3/3] Add Load Project feature with related UI and backend logic --- Browser_IDE/IDEStartupMain.js | 13 +++++ Browser_IDE/editorMain.js | 3 +- Browser_IDE/index.html | 1 + Browser_IDE/projectLoadUI.js | 91 +++++++++++++++++++++++++++++++++-- 4 files changed, 103 insertions(+), 5 deletions(-) diff --git a/Browser_IDE/IDEStartupMain.js b/Browser_IDE/IDEStartupMain.js index 2432f72..64dace0 100644 --- a/Browser_IDE/IDEStartupMain.js +++ b/Browser_IDE/IDEStartupMain.js @@ -66,6 +66,15 @@ let CompileQueue = new ActionQueue("CompileQueue", { cancelOn: [InitializeProjectQueue], }); +// add loadUserProject!!!!!!!!!!!!!!!! +let LoadUserProjectQueue = new ActionQueue("LoadUserProjectQueue", { + cancelRunning: false, + replaceQueued: false, + maxQueued: 100, + waitOn: [ExecutionEnvironmentLoadQueue, InitializeProjectQueue], + cancelOn: [InitializeProjectQueue, ExecutionEnvironmentLoadQueue], +}); + // Whenever both execution environment and load project queue clear, mirror the project ActionQueue.OnClear([ExecutionEnvironmentLoadQueue, InitializeProjectQueue], async function(){ MirrorProjectQueue.Schedule("Mirror", async function(){ @@ -124,6 +133,10 @@ async function StartIDE() { setupMinifiedInterface(); }); + // use LoadUserProjectQueue to load user projects!!!!!!!!! + LoadUserProjectQueue.Schedule("LoadUserProjects", async function() { + await ShowProjectLoader("Choose a project to load:", loadUserProjects); + }); CompilerInitQueue.Schedule("CompilerInit", async function CompilerInitQueue (isCanceled){ await initializeLanguageCompilerFiles(activeLanguageSetup); diff --git a/Browser_IDE/editorMain.js b/Browser_IDE/editorMain.js index e394281..00bb04d 100644 --- a/Browser_IDE/editorMain.js +++ b/Browser_IDE/editorMain.js @@ -906,7 +906,8 @@ function setupIDEButtonEvents() { setupProjectButton("DownloadProject", downloadProject); setupProjectButton("NewProject", () => scheduleProjectReInitialization(activeLanguageSetup.getDefaultProject())); setupProjectButton("LoadDemo", () => ShowProjectLoader("Choose a demo project:", LoadDemoProjects)); - + // Add the new "Load Project" button and its event!!!!!!!!!!!!!!!! + setupProjectButton("LoadProject", () => ShowProjectLoader("Choose a project to load:", loadUserProjects)); if (!activeLanguageSetup.supportHotReloading) document.getElementById("runOne").children[0].innerText = "Syntax Check File"; } diff --git a/Browser_IDE/index.html b/Browser_IDE/index.html index 6f4259b..42d7c6c 100644 --- a/Browser_IDE/index.html +++ b/Browser_IDE/index.html @@ -41,6 +41,7 @@
  • +
    • diff --git a/Browser_IDE/projectLoadUI.js b/Browser_IDE/projectLoadUI.js index 5ec9560..a4bce7b 100644 --- a/Browser_IDE/projectLoadUI.js +++ b/Browser_IDE/projectLoadUI.js @@ -1,6 +1,5 @@ "use strict"; - async function ShowProjectLoader(title, getChoices){ let closeButton = elem('button', {type:"button"}, [elem('i', {class: "bi bi-x-lg"}, [])]); @@ -65,10 +64,11 @@ async function ShowProjectLoader(title, getChoices){ if (activeLanguage.name != item["language"]) displayEditorNotification("Switching language to " + item["language"] + "
      Page will reload.", NotificationIcons.INFO); - let reroutedURL = await rerouteURL(item["file"]); + // wait until the project has loaded, only then switch language if needed + await loadProjectFromURL(await rerouteURL(item["file"])); - scheduleLoadProjectFromURL(reroutedURL); - schedulePotentialLanguageSwitch(item["language"]); + if (activeLanguage.name != item["language"]) + switchActiveLanguage(item["language"]); }); } gridContainer.appendChild(set); @@ -87,3 +87,86 @@ function LoadDemoProjects(){ return json; }); } + +//!!!!!!!!!!!!!!!! +async function loadUserProjects() { + return new Promise((resolve, reject) => { + // Open the database + let dbRequest = indexedDB.open('SplashkitOnline', 1); + + dbRequest.onupgradeneeded = function(event) { + let db = event.target.result; + // Create the 'userProjects' object store if it doesn't exist + if (!db.objectStoreNames.contains('userProjects')) { + db.createObjectStore('userProjects', { keyPath: 'id', autoIncrement: true }); + } + }; + + dbRequest.onsuccess = function(event) { + let db = event.target.result; + let transaction = db.transaction(['userProjects'], 'readonly'); + let objectStore = transaction.objectStore('userProjects'); + + // Get all projects + let getRequest = objectStore.getAll(); + + getRequest.onsuccess = function() { + // Convert to display format + let userProjects = getRequest.result.map(project => ({ + title: project.name, // project name + language: project.language || "Unknown", // default language + file: project.filePath || "", // file path + thumbnail: project.thumbnail || "" // thumbnail + })); + resolve(userProjects); + }; + + getRequest.onerror = function() { + reject('Failed to load user project data'); + }; + }; + + dbRequest.onerror = function() { + reject('Failed to open IndexedDB'); + }; + }); +} + +//!!!!!!!!!!!!!!!! +async function ShowProjectLoader(title, getChoices) { + let closeButton = elem('button', {type:"button"}, [elem('i', {class: "bi bi-x-lg"}, [])]); + + let loadingText = elem('div', {class: "sk-demo-window-loading-text", id:"DemoChooserLoader", style:{'position':'absolute'}}, [ + elem('h2', {style:{'text-align':'center'}}, ["Loading..."]) + ]); + + let mainRows = elem('div', {class: "sk-column"}, [ + elem('div', {class: "sk-header sk-header-indent"}, [ + elem('div', {class: "flex-column"}, [title]), + elem('div', {class: "flex-column"}, [closeButton]), + ]), + loadingText, + ]); + + let loaderWindow = elem('div', {class: "sk-main-columns sk-demo-window-container fade-on-create"}, [ + elem('div', {class: "sk-notification sk-notification-body sk-contents sk-contents-focusable sk-demo-window", tabindex: "10"}, [ + mainRows, + ]), + ]); + + closeButton.addEventListener('click', function() { + removeFadeOut(loaderWindow, 200); + }); + + // Show the window + document.body.appendChild(loaderWindow); + + try { + let choices = await getChoices(); + console.log(choices); + removeFadeOut(loadingText, 200); + } catch(e) { + console.error("Failed to load project data:", e); + loadingText.childNodes[0].innerText = "Failed to load project list, sorry!"; + } +} \ No newline at end of file