Spaces:
Running
Running
File size: 3,639 Bytes
6f54888 3ae777b f2bee8a 3ae777b f2bee8a 3ae777b f2bee8a 3ae777b f2bee8a 3ae777b f2bee8a 0ebf77c 3ae777b f2bee8a 0ebf77c 04fa2df 0427cbe 0ebf77c 04fa2df f2bee8a 9269047 f2bee8a 9269047 f2bee8a db39eac f2bee8a 04fa2df db39eac f2bee8a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
// グローバルな進行状況管理変数
let total = 0;
let complete = 0;
let state = 0;
let currentProgress = 0;
let progressHandler = (state, progress, complete, total) => {};
// 進行状況ハンドラを設定する関数
export const setProgressHandler = newHandler => {
progressHandler = newHandler;
progressHandler(state, currentProgress, complete, total);
};
// 進行状況更新をキューに入れる関数
const queueProgressHandlerUpdate = () => {
if (progressHandlerTimeout === null) {
progressHandlerTimeout = requestAnimationFrame(fireProgressHandler);
}
};
// 進行状況を更新する関数
const setProgress = progress => {
if (progress < 0) {
progress = 0;
}
if (progress > 1) {
progress = 1;
}
currentProgress = progress;
queueProgressHandlerUpdate();
};
// ステータスを設定する関数
const setState = newState => {
if (state === newState) {
return;
}
state = newState;
complete = 0;
total = 0;
setProgress(0);
};
// 進行状況を管理する関数
const fetchWithProgress = url => {
setState(1);
// 使用するCORSプロキシURL
const proxyUrl = `https://public-soiz1-cors-proxy.hf.space/?url=` + encodeURIComponent(url); // ここで公開されているプロキシを使用
//const proxyUrl = `https://cors-anywhere.herokuapp.com/` + encodeURIComponent(url);
// const proxyUrl = `https://cors-proxy.htmldriven.com/?url=` + encodeURIComponent(url); // 別のプロキシURLを使いたい場合はこちらを使用
// const proxyUrl = `https://api.allorigins.win/raw?url=` + encodeURIComponent(url); // 別のプロキシURLを使いたい場合はこちらを使用
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = () => {
resolve(new Response(xhr.response, {
status: xhr.status,
statusText: xhr.statusText
}));
};
xhr.onloadend = () => setProgress(1);
xhr.onerror = () => reject(new Error('[tw-progress-monitor] xhr failed with status ' + xhr.status));
xhr.onprogress = e => {
if (e.lengthComputable) {
setProgress(e.loaded / e.total);
}
};
xhr.open('GET', proxyUrl);
xhr.send();
});
};
// fetchのオーバーライド
const originalFetch = window.fetch;
window.fetch = (url, opts) => {
const isGET = typeof opts === 'object' && opts && opts.method === 'GET';
const isProjectURL = typeof url === 'string' && /^https:\/\/projects\.scratch\.mit\.edu\/\d+$/.test(url);
if (isGET && isProjectURL) {
return fetchWithProgress(url);
}
return originalFetch(url, opts);
};
// Web Workerのメッセージ処理
const handleWorkerMessage = e => {
const data = e.data;
if (Array.isArray(data)) {
complete += data.length;
setProgress(complete / total);
}
};
if (window.Worker) {
let downloadWorker = null;
const originalPostMessage = window.Worker.prototype.postMessage;
window.Worker.prototype.postMessage = function (message) {
if (downloadWorker === null) {
if (message && message.url && message.id && message.options) {
downloadWorker = this;
downloadWorker.addEventListener('message', handleWorkerMessage);
}
}
if (downloadWorker === this) {
setState(2);
total++;
}
originalPostMessage.call(this, message);
};
}
|