Skip to content

Commit

Permalink
🐛 fix: extensions not loading with code and file (#129)
Browse files Browse the repository at this point in the history
* fix not loading extensions with code

Signed-off-by: kokodev <[email protected]>

* Fix file not being able to load

Signed-off-by: kokodev <[email protected]>

* Ensure that project still loads even if not saved with eureka

Signed-off-by: kokodev <[email protected]>

* Add error message

Signed-off-by: kokodev <[email protected]>

* I forgot this is not useState

Signed-off-by: kokodev <[email protected]>

* Last error. i forgot to use my code editor

Signed-off-by: kokodev <[email protected]>

* Update applier.ts

Signed-off-by: kokodev <[email protected]>

* Add Return empty string

Signed-off-by: kokodev <[email protected]>

* add classname

Signed-off-by: kokodev <[email protected]>

* add classname in css

Signed-off-by: kokodev <[email protected]>

* Use span instead.

Signed-off-by: kokodev <[email protected]>

* Update style.css

Signed-off-by: kokodev <[email protected]>

---------

Signed-off-by: kokodev <[email protected]>
  • Loading branch information
SimonShiki authored Nov 22, 2024
2 parents f1e0ddb + 6b833d1 commit 2c688a9
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 37 deletions.
97 changes: 62 additions & 35 deletions src/main/dashboard/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ function classNames(...classes: (string | null | undefined)[]): string {
return classes.filter(Boolean).join(' ');
}

function stringToDataURL (str: string) {
return `data:text/plain;base64,${btoa(str)}`;
function utoa(data) {
return btoa(unescape(encodeURIComponent(data)));
}

function stringToDataURL(str) {
return `data:text/plain;base64,${utoa(str)}`;
}

function SwitchComponent (props: SwitchProps) {
Expand Down Expand Up @@ -93,19 +97,23 @@ function SwitchComponent (props: SwitchProps) {
function LoaderForm() {
const [loaderType, setLoaderType] = createSignal<LoaderType>('URL');
const [extensionURL, setURL] = createSignal('');
const [errorMessage, setErrorMessage] = createSignal('');
const [extensionCode, setCode] = createSignal('');
const [extensionFile, setFile] = createSignal<File | null>();
const [extensionFile, setFile] = createSignal<File | null>(null);
const [fileContent, setFileContent] = createSignal<string | null>(null); // Store file content
const [loading, setLoading] = createSignal(false);

function shouldDisable () {
function shouldDisable() {
if (loading()) return true;
switch (loaderType()) {
case 'URL':
return !extensionURL().trim();
case 'Code':
return !extensionCode().trim();
case 'File':
return !extensionFile();
return !extensionFile(); // Ensure this returns false when a file is selected
default:
return true; // Default case to ensure safety
}
}

Expand All @@ -117,7 +125,7 @@ function LoaderForm() {
class={`${styles.loaderTab} ${type === loaderType() ? styles.active : ''}`}
onClick={() => setLoaderType(type)}
>
{formatMessage({id: `eureka.loader.${type.toLowerCase()}`, default: type})}
{formatMessage({ id: `eureka.loader.${type.toLowerCase()}`, default: type })}
</div>
))}
</div>
Expand All @@ -127,59 +135,78 @@ function LoaderForm() {
<Match when={loaderType() === 'URL'}>
<input
type="text"
placeholder={formatMessage({id: 'eureka.loader.url.placeholder', default: 'Enter extension URL here'})}
placeholder={formatMessage({ id: 'eureka.loader.url.placeholder', default: 'Enter extension URL here' })}
onChange={(e) => setURL(e.currentTarget.value)}
value={extensionURL()}
class={styles.input}
/>
</Match>
<Match when={loaderType() === 'Code'}>
<textarea
placeholder={formatMessage({id: 'eureka.loader.code.placeholder', default: 'Paste extension code here'})}
placeholder={formatMessage({ id: 'eureka.loader.code.placeholder', default: 'Paste extension code here' })}
class={styles.textarea}
onChange={(e) => setCode(e.currentTarget.value)}
value={extensionCode()} // Bind value to textarea
/>
</Match>
<Match when={loaderType() === 'File'}>
<input
type="file"
accept=".js"
class={styles.input}
placeholder={formatMessage({id: 'eureka.loader.file.placeholder', default: 'Choose a file'})}
onChange={(e) => {
const files = e.currentTarget.files;
if (files && files.length > 0) {
const file = files[0];
setFile(file); // Update signal with the selected file

// Read the file as text and store its content
const reader = new FileReader();
reader.onload = () => {
setFileContent(reader.result as string); // Store the file content
};
reader.readAsText(file); // Read the file as text
} else {
setFile(null); // Reset if no file is selected
setFileContent(null); // Reset file content if no file is selected
}
}}
/>
</Match>
</Switch>

<button
class={styles.button}
disabled={shouldDisable()}
{/* Button Element */}
<button
class={styles.button}
disabled={shouldDisable()}
onClick={async () => {
switch (loaderType()) {
case 'URL':
setLoading(true);
await eureka.load(extensionURL());
setLoading(false);
break;
case 'Code':
setLoading(true);
await eureka.load(stringToDataURL(extensionCode()));
setLoading(false);
break;
case 'File':
if (extensionFile()) {
const reader = new FileReader();
reader.onload = async () => {
setLoading(true);
eureka.load(reader.result as string);
setLoading(false);
};
reader.readAsText(extensionFile());
setLoading(true); // Set loading to true at the start of loading process
try {
switch (loaderType()) {
case 'URL':
await eureka.load(extensionURL());
break;
case 'Code':
await eureka.load(stringToDataURL(extensionCode()));
break;
case 'File':
if (fileContent()) { // Use stored file content
await eureka.load(stringToDataURL(fileContent()));
}
break;
}
break;
}
}}>

} catch (error) {
setErrorMessage("Error loading extension:" + error);
console.error("Error loading extension:", error); // Handle any errors that occur during loading
} finally {
setLoading(false); // Ensure loading is set to false after loading completes or fails
}
}}
>
<FormattedMessage id="eureka.loader.load" default="Load Extension" />
</button>
{errorMessage() && <span className='errorText'>{errorMessage()}</span>} {/* Display error message below the button */}

Check failure on line 209 in src/main/dashboard/app.tsx

View workflow job for this annotation

GitHub Actions / Validating Code

Type '{ children: string; className: string; }' is not assignable to type 'HTMLAttributes<HTMLSpanElement>'.
</div>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions src/main/dashboard/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* Note: might conflict with existing styles if not in shadow DOM */

:root {
--eureka-error-primary: rgb(255, 0, 0);
--eureka-accent: rgb(133, 92, 214);
--eureka-secondary: rgb(115, 81, 183);
--eureka-transparent-accent: rgba(133, 92, 214, 0.5);
Expand Down
5 changes: 5 additions & 0 deletions src/main/dashboard/style.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@
@apply mt-4;
}

.errorText {
font-size: 12px;
color: var(--eureka-error-primary);
}

.switch {
width: 3rem;
height: 1.5rem;
Expand Down
19 changes: 17 additions & 2 deletions src/main/patches/applier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,27 @@ const checkEureka = (eurekaFlag: string): boolean | null => {
* @param {!string} opcode The opcode to examine for extension.
* @return {?string} The extension ID, if it exists and is not a core extension.
*/
function getExtensionIdForOpcode (opcode: string) {
function getExtensionIdForOpcode(opcode) {
// Check if opcode is undefined or not a string
if (typeof opcode !== 'string') {
return ''; // Return undefined if opcode is not valid
}

// Allowed ID characters are those matching the regular expression [\w-]: A-Z, a-z, 0-9, and hyphen ("-").
const index = opcode.indexOf('_');

// If '_' is not found, return undefined
if (index === -1) {
return '';
}

const forbiddenSymbols = /[^\w-]/g;
const prefix = opcode.substring(0, index).replace(forbiddenSymbols, '-');
if (prefix !== '') return prefix;

// Return prefix only if it's not empty
if (prefix !== '') {
return prefix;
}
}

export function applyPatchesForBlocks (blocks?: DucktypedScratchBlocks) {
Expand Down

0 comments on commit 2c688a9

Please sign in to comment.