Improved project loading progress bar

This commit is contained in:
Thomas Weber committed 2021-06-24 14:08:59 -05:00
1 parent 2a9b327a42
commit e50b476734
2 files changed
+105 -68

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
<script>
export let progress = 0;
export let text = '';
</script>
<style>
.outer {
width: 200px;
height: 10px;
border: 1px solid black;
background: white;
}
.inner {
height: 100%;
width: 0;
background: black;
}
</style>
<div class="outer">
<div class="inner" style={`width:${progress*100}%`}></div>
</div>
{text}
+81 -68
View File
@@ -1,4 +1,5 @@
<script>
import Progress from './Progress.svelte';
import writablePersistentStore from './persistent-store';
import {error} from './stores';
@@ -7,80 +8,88 @@
const projectId = writablePersistentStore('SelectProject.id', '1');
let files = null;
const withErrorHandling = (fn) => () => fn().catch((e) => {
$error = e
});
const reset = () => {
projectData = null;
};
let progressVisible = false;
let progress = 0;
let progressText = '';
// Reset project whenever an input changes
$: files, $projectId, $type, reset();
const load = withErrorHandling(async () => {
reset();
const {
VirtualMachine,
Storage
} = await import(/* webpackChunkName: "scratch" */ './large-scratch-packages');
let vm = new VirtualMachine();
vm.extensionManager.loadExtensionURL = () => Promise.resolve();
class StorageWithProgress extends Storage {
constructor (...args) {
super(...args);
this.totalAssets = 0;
this.loadedAssets = 0;
}
load (...args) {
this.totalAssets++;
// progress.text = `Downloading assets (${this.loadedAssets}/${this.totalAssets})`;
// progress.visible = true
// progress.value = this.loadedAssets / this.totalAssets;
return super.load(...args)
.then((r) => {
this.loadedAssets++;
// progress.text = `Downloading assets (${this.loadedAssets}/${this.totalAssets})`;
// progress.value = this.loadedAssets / this.totalAssets;
return r;
});
}
}
const storage = new StorageWithProgress();
storage.addWebStore(
[storage.AssetType.ImageVector, storage.AssetType.ImageBitmap, storage.AssetType.Sound],
(asset) => `https://assets.scratch.mit.edu/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`
);
vm.attachStorage(storage);
const readAsArrayBuffer = blob => new Promise((resolve, reject) => {
const fr = new FileReader();
fr.onload = () => resolve(fr.result);
fr.onerror = () => reject(new Error('Can not read blob'));
fr.readAsArrayBuffer(blob);
});
const newProjectData = {
vm
};
if ($type === 'id') {
newProjectData.uniqueId = `#${$projectId}`;
newProjectData.projectId = $projectId;
const res = await fetch('https://projects.scratch.mit.edu/' + $projectId);
const data = await res.arrayBuffer();
await vm.loadProject(data);
} else {
const file = files[0];
newProjectData.projectId = null;
newProjectData.uniqueId = `@${file.name}`;
const data = await readAsArrayBuffer(file);
await vm.loadProject(data);
}
projectData = newProjectData
const readAsArrayBuffer = blob => new Promise((resolve, reject) => {
const fr = new FileReader();
fr.onload = () => resolve(fr.result);
fr.onerror = () => reject(new Error('Can not read blob'));
fr.readAsArrayBuffer(blob);
});
const load = async () => {
try {
reset();
progressVisible = true;
progress = 0;
progressText = 'Loading Scratch';
const {
VirtualMachine,
Storage
} = await import(/* webpackChunkName: "scratch" */ './large-scratch-packages');
progressText = 'Loading project';
let vm = new VirtualMachine();
vm.extensionManager.loadExtensionURL = () => Promise.resolve();
class StorageWithProgress extends Storage {
constructor (...args) {
super(...args);
this.totalAssets = 0;
this.loadedAssets = 0;
}
load (...args) {
this.totalAssets++;
progress = this.loadedAssets / this.totalAssets;
progressText = `Loading assets (${this.loadedAssets}/${this.totalAssets})`;
return super.load(...args)
.then((r) => {
this.loadedAssets++;
progress = this.loadedAssets / this.totalAssets;
progressText = `Loading assets (${this.loadedAssets}/${this.totalAssets})`;
return r;
});
}
}
const storage = new StorageWithProgress();
storage.addWebStore(
[storage.AssetType.ImageVector, storage.AssetType.ImageBitmap, storage.AssetType.Sound],
(asset) => `https://assets.scratch.mit.edu/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`
);
vm.attachStorage(storage);
const newProjectData = {
vm
};
if ($type === 'id') {
newProjectData.uniqueId = `#${$projectId}`;
newProjectData.projectId = $projectId;
const res = await fetch('https://projects.scratch.mit.edu/' + $projectId);
const data = await res.arrayBuffer();
await vm.loadProject(data);
} else {
const file = files[0];
newProjectData.projectId = null;
newProjectData.uniqueId = `@${file.name}`;
const data = await readAsArrayBuffer(file);
await vm.loadProject(data);
}
projectData = newProjectData
} catch (e) {
$error = e;
}
progressVisible = false;
};
</script>
<style>
@@ -107,5 +116,9 @@
</div>
<div>
<button on:click={load}>Load Project</button>
<button on:click={load} disabled={progressVisible}>Load Project</button>
</div>
{#if progressVisible}
<Progress progress={progress} text={progressText} />
{/if}