From c5ee39a2dc3a8225f418a80a5206845d456edbf6 Mon Sep 17 00:00:00 2001 From: pooiod7 <82846639+pooiod@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:14:35 -0500 Subject: [PATCH 1/2] Added extension SuperStorage, set featured to false on ScreenSharing because it's just an out of date version of "VIdeoSharing", Updated Cloud Storage icon, Compressed some if statements in VideoSharing, Dixed warning bug in VideoSharing, Updated CloudStorage to be able to delete files --- .../extensions/SuperStorage/SuperStorage.svg | 1 + .../extensions/cloudstorage/CloudStorage.svg | 1 + src/lib/libraries/extensions/index.jsx | 18 +- static/SuperStorage.js | 178 ++++++++++++++++++ static/VideoSharing.js | 58 ++---- static/cloudstorage.js | 34 +++- 6 files changed, 241 insertions(+), 49 deletions(-) create mode 100644 src/lib/libraries/extensions/SuperStorage/SuperStorage.svg create mode 100644 src/lib/libraries/extensions/cloudstorage/CloudStorage.svg create mode 100644 static/SuperStorage.js diff --git a/src/lib/libraries/extensions/SuperStorage/SuperStorage.svg b/src/lib/libraries/extensions/SuperStorage/SuperStorage.svg new file mode 100644 index 00000000000..aa4c46d0901 --- /dev/null +++ b/src/lib/libraries/extensions/SuperStorage/SuperStorage.svg @@ -0,0 +1 @@ +Made withhttps://penguinpaint.pages.dev \ No newline at end of file diff --git a/src/lib/libraries/extensions/cloudstorage/CloudStorage.svg b/src/lib/libraries/extensions/cloudstorage/CloudStorage.svg new file mode 100644 index 00000000000..615eb0fb0ab --- /dev/null +++ b/src/lib/libraries/extensions/cloudstorage/CloudStorage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/lib/libraries/extensions/index.jsx b/src/lib/libraries/extensions/index.jsx index d31b93f59ad..4a205a8ae7c 100644 --- a/src/lib/libraries/extensions/index.jsx +++ b/src/lib/libraries/extensions/index.jsx @@ -3,6 +3,7 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; import VideoSharing from './VidShare/VideoSharing.svg'; +import SuperStorage from './SuperStorage/SuperStorage.svg'; import NoahgptThumb from './noahgpt/costume1.svg'; import typescriptIcon from './snail-ide/typescript.svg'; import twGalleryIcon from './snail-ide/turbowarpgallery.svg'; @@ -10,7 +11,7 @@ import pmGalleryIcon from './snail-ide/penguinmodgallery.svg'; import musicIconURL from './music/music.png'; import roku from './roku/roku.png'; import share from './share/share.svg'; -import cloudstorageIconURL from './cloudstorage/costume1.svg'; +import cloudstorageIconURL from './cloudstorage/CloudStorage.svg'; import pythonIcon from './python/py.svg'; import extCreateIcon from './ext-create/logo.svg'; import extCreateInset from './ext-create/inset.svg'; @@ -235,8 +236,8 @@ const menuItems = [ iconURL: 'https://editor.snail-ide.com/Screensharing.png', // please forgive me the text is slightly offcenter collaborator: 'pooiod7', tags: ['penguinmod'], - description: 'Share your screen and get the current frame as a image.', - featured: true + description: 'Share your screen and get the current frame as an image. (replaced by VideoSharing)', + featured: false // This is actually an unfinished version of "VideoSharing" (kept to prevent old projects from braking) }, { name: 'VideoSharing', @@ -541,11 +542,20 @@ const menuItems = [ name: 'Cloud Storage', extensionId: 'https://editor.snail-ide.com/cloudstorage.js', collaborator: 'pooiod7', - iconURL: cloudstorageIconURL, // this needs to be redone soon + iconURL: cloudstorageIconURL, tags: ['penguinmod'], description: 'Store data in a database, similar to Storage and Better Storage, but powered by a Snap! extension.', featured: true }, + { + name: 'SuperStorage', + extensionId: 'https://editor.snail-ide.com/SuperStorage.js', + iconURL: SuperStorage, + tags: ['penguinmod'], + description: 'Store and retrieve data locally on device or remotely on a server.', + collaborator: 'pooiod7', + featured: true + }, { name: 'Text to Speech 2.0', extensionId: 'https://sharkpools-extensions.vercel.app/extension-code/Text-to-Speech.js', diff --git a/static/SuperStorage.js b/static/SuperStorage.js new file mode 100644 index 00000000000..0dbaf0a94ae --- /dev/null +++ b/static/SuperStorage.js @@ -0,0 +1,178 @@ + (function(Scratch) { + 'use strict'; + + if (!Scratch.extensions.unsandboxed) { + throw new Error('This extension must run unsandboxed'); + } + + class StorageV2 { + constructor() { + this.currentServer = "https://storage-ext.penguinmod.com/"; + this.useGlobal = true; + this.waitingForResponse = false; + this.serverFailedResponse = false; + this.serverError = ""; + } + + getInfo() { + return { + id: 'P7SuperStorage', + name: 'Super Storage', + color1: '#31b3d4', + color2: '#179fc2', + docsURI: 'https://pooiod7.neocities.org/markdown/#/projects/scratch/extensions/other/markdown/SuperStorage', + blocks: [ + { blockType: Scratch.BlockType.LABEL, text: "Local Storage" }, + { + opcode: 'getValue', + text: 'get local [KEY]', + disableMonitor: true, + blockType: Scratch.BlockType.REPORTER, + arguments: { + KEY: { type: Scratch.ArgumentType.STRING, defaultValue: "key" } + } + }, + { + opcode: 'setValue', + text: 'set local [KEY] to [VALUE]', + blockType: Scratch.BlockType.COMMAND, + arguments: { + KEY: { type: Scratch.ArgumentType.STRING, defaultValue: "key" }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "value" } + } + }, + { + opcode: 'deleteValue', + text: 'delete local [KEY]', + blockType: Scratch.BlockType.COMMAND, + arguments: { KEY: { type: Scratch.ArgumentType.STRING, defaultValue: "key" } } + }, + { + opcode: 'getKeys', + text: 'get all local stored names', + disableMonitor: true, + blockType: Scratch.BlockType.REPORTER + }, + { + blockType: Scratch.BlockType.LABEL, + text: "Server Storage" + }, + { + opcode: 'waitingForConnection', + text: 'waiting for server to respond?', + disableMonitor: true, + blockType: Scratch.BlockType.BOOLEAN + }, + { + opcode: 'connectionFailed', + text: 'server failed to respond?', + disableMonitor: true, + blockType: Scratch.BlockType.BOOLEAN + }, + { + opcode: 'serverErrorOutput', + text: 'server error', + disableMonitor: false, + blockType: Scratch.BlockType.REPORTER + }, + "---", + { + opcode: 'getServerValue', + text: 'get server [KEY]', + disableMonitor: true, + blockType: Scratch.BlockType.REPORTER, + arguments: { KEY: { type: Scratch.ArgumentType.STRING, defaultValue: "key" } } + }, + { + opcode: 'setServerValue', + text: 'set server [KEY] to [VALUE]', + blockType: Scratch.BlockType.COMMAND, + arguments: { + KEY: { type: Scratch.ArgumentType.STRING, defaultValue: "key" }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "value" } + } + }, + { + opcode: 'deleteServerValue', + text: 'delete server [KEY]', + blockType: Scratch.BlockType.COMMAND, + arguments: { KEY: { type: Scratch.ArgumentType.STRING, defaultValue: "key" } } + } + ] + }; + } + + getPrefix() { + return `P7_PROJECTSTORAGE_`; + } + + getAllKeys() { + return Object.keys(localStorage).filter(key => key.startsWith(this.getPrefix())).map(key => key.replace(this.getPrefix(), "")); + } + + runPenguinWebRequest(url, options, ifFailReturn) { + this.waitingForResponse = true; + this.serverFailedResponse = false; + this.serverError = ""; + + return fetch(url, options) + .then(response => response.ok ? response.text() : Promise.reject(response.text())) + .then(text => { + this.waitingForResponse = false; + return text; + }) + .catch(err => { + this.waitingForResponse = false; + this.serverFailedResponse = true; + this.serverError = err; + return ifFailReturn; + }); + } + + getKeys() { + return JSON.stringify(this.getAllKeys()); + } + + getValue(args) { + return localStorage.getItem(this.getPrefix() + args.KEY) || ""; + } + + setValue(args) { + localStorage.setItem(this.getPrefix() + args.KEY, args.VALUE); + } + + deleteValue(args) { + localStorage.removeItem(this.getPrefix() + args.KEY); + } + + waitingForConnection() { + return this.waitingForResponse; + } + + connectionFailed() { + return this.serverFailedResponse; + } + + serverErrorOutput() { + return this.serverError; + } + + getServerValue(args) { + return this.runPenguinWebRequest(`${this.currentServer}get?key=${args.KEY}`, null, ""); + } + + setServerValue(args) { + return this.runPenguinWebRequest(`${this.currentServer}set?key=${args.KEY}`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ "value": args.VALUE }) + }); + } + + deleteServerValue(args) { + return this.runPenguinWebRequest(`${this.currentServer}delete?key=${args.KEY}`, { method: "DELETE" }); + } + } + + Scratch.extensions.register(new StorageV2()); +})(Scratch); diff --git a/static/VideoSharing.js b/static/VideoSharing.js index f959f95c954..2c4d6fe5e2f 100644 --- a/static/VideoSharing.js +++ b/static/VideoSharing.js @@ -1,5 +1,5 @@ -// Video sharing (v2.4.1) by pooiod7 -// The successor to ScreenSharing +// Video sharing (v2.4.2) by pooiod7 +// Was originally the "ScreenSharing" extension (function(Scratch) { 'use strict'; @@ -21,7 +21,7 @@ let haswarned; function shouldwarn(){ - return Scratch.vm.runtime.isPackaged; + return !Scratch.vm.runtime.isPackaged; } class VideoSharing { @@ -245,18 +245,12 @@ } startScreenSharing() { - if (this.isSharing()) { - this.stopSharing(); - } + if (this.isSharing()) this.stopSharing(); - if (!this.canScreen()) { - return; - } + if (!this.canScreen()) return; if (shouldwarn()) { - if (!this.warn("screen")) { - return; - } + if (!this.warn("screen")) return; } return new Promise((resolve) => { @@ -283,14 +277,10 @@ } startCameraSharing() { - if (this.isSharing()) { - this.stopSharing(); - } + if (this.isSharing()) this.stopSharing(); if (shouldwarn()) { - if (!this.warn("camera")) { - return; - } + if (!this.warn("camera")) return; } return new Promise((resolve, reject) => { @@ -326,14 +316,10 @@ } getHEX(args) { - if (!this.isSharing()) { - return; - } + if (!this.isSharing()) return; var rez = args.REZ; - if (rez > 1) { - rez = 1; - } + if (rez > 1) rez = 1; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); const width = videoElement.videoWidth * rez; @@ -357,14 +343,10 @@ } getPNG(args) { - if (!this.isSharing()) { - return; - } + if (!this.isSharing()) return; var rez = args.REZ; - if (rez > 1) { - rez = 1; - } + if (rez > 1) rez = 1; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); const width = videoElement.videoWidth * rez; @@ -380,14 +362,10 @@ } getJPEG(args) { - if (!this.isSharing()) { - return; - } + if (!this.isSharing()) return; let rez = args.REZ; - if (rez > 1) { - rez = 1; - } + if (rez > 1) rez = 1; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); const width = videoElement.videoWidth * rez; @@ -404,14 +382,10 @@ } getWEBP(args) { - if (!this.isSharing()) { - return; - } + if (!this.isSharing()) return; let rez = args.REZ; - if (rez > 1) { - rez = 1; - } + if (rez > 1) rez = 1; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); diff --git a/static/cloudstorage.js b/static/cloudstorage.js index 89a15f13a81..eec5c845928 100644 --- a/static/cloudstorage.js +++ b/static/cloudstorage.js @@ -1,5 +1,4 @@ -// Simple file storage made with tools from Snap! -// Be careful, data can be replaced +// Simple file storage made with tools from Snap! (v1.2) by pooiod7 class ServerExtension { constructor(runtime) { @@ -29,6 +28,17 @@ class ServerExtension { }, }, }, + { + opcode: 'deleteFromServer', + blockType: Scratch.BlockType.COMMAND, + text: 'Delete [variableName]', + arguments: { + variableName: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'default.txt', + }, + }, + }, { opcode: 'loadFromServer', blockType: Scratch.BlockType.REPORTER, @@ -36,7 +46,7 @@ class ServerExtension { arguments: { variableName: { type: Scratch.ArgumentType.STRING, - defaultValue: 'data.txt', + defaultValue: 'default.txt', }, }, }, @@ -64,6 +74,24 @@ class ServerExtension { return false; }); } + + deleteFromServer(args, util) { + const variableName = args.variableName; + const content = args.content; + + const url = + this.serverURL + + '?type=delete&filename=./textfiles/' + + encodeURIComponent(variableName); + + return fetch(url) + .then(response => response.text()) + .then(result => (result === 'ok')) + .catch(error => { + console.error('Failed to delete data:', error); + return false; + }); + } loadFromServer(args, util) { const variableName = args.variableName; From 0c9c44e44afbd8b8a3b26c2191559a7fe5fe9413 Mon Sep 17 00:00:00 2001 From: pooiod7 <82846639+pooiod@users.noreply.github.com> Date: Thu, 14 Nov 2024 20:38:33 -0500 Subject: [PATCH 2/2] Update index.jsx --- src/lib/libraries/extensions/index.jsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/lib/libraries/extensions/index.jsx b/src/lib/libraries/extensions/index.jsx index 4a205a8ae7c..f93f23f47da 100644 --- a/src/lib/libraries/extensions/index.jsx +++ b/src/lib/libraries/extensions/index.jsx @@ -230,15 +230,6 @@ const menuItems = [ description: 'Do many things via the Scratch API; you can even fetch cloud data from projects!', featured: true }, - { - name: 'Screensharing', - extensionId: 'https://editor.snail-ide.com/screen-sharing.js', - iconURL: 'https://editor.snail-ide.com/Screensharing.png', // please forgive me the text is slightly offcenter - collaborator: 'pooiod7', - tags: ['penguinmod'], - description: 'Share your screen and get the current frame as an image. (replaced by VideoSharing)', - featured: false // This is actually an unfinished version of "VideoSharing" (kept to prevent old projects from braking) - }, { name: 'VideoSharing', extensionId: 'https://editor.snail-ide.com/VideoSharing.js',