You want promises? I bring you commitments.
This commit is contained in:
parent
fcccccb6bc
commit
ab95a803b4
9 changed files with 379 additions and 276 deletions
68
src/ami.js/commitment.js
Normal file
68
src/ami.js/commitment.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
const Commitment = function(run) {
|
||||
if(typeof run !== 'function')
|
||||
throw 'run must be a function';
|
||||
|
||||
let success;
|
||||
let fail = ex => { console.error(ex); };
|
||||
let always;
|
||||
|
||||
const pub = {
|
||||
success(handler) {
|
||||
if(typeof handler !== 'function')
|
||||
throw 'success handler must be a function';
|
||||
|
||||
success = handler;
|
||||
return pub;
|
||||
},
|
||||
fail(handler) {
|
||||
if(typeof handler !== 'function')
|
||||
throw 'fail handler must be a function';
|
||||
|
||||
fail = handler;
|
||||
return pub;
|
||||
},
|
||||
always(handler) {
|
||||
if(typeof handler !== 'function')
|
||||
throw 'always handler must be a function';
|
||||
|
||||
always = handler;
|
||||
return pub;
|
||||
},
|
||||
};
|
||||
|
||||
const successHandler = (...args) => {
|
||||
try {
|
||||
if(typeof success === 'function')
|
||||
success(...args);
|
||||
} catch(ex) {
|
||||
fail(ex);
|
||||
} finally {
|
||||
if(typeof always === 'function')
|
||||
always();
|
||||
}
|
||||
};
|
||||
|
||||
const failHandler = (...args) => {
|
||||
try {
|
||||
fail(...args);
|
||||
} catch(ex) {
|
||||
fail(ex);
|
||||
} finally {
|
||||
if(typeof always === 'function')
|
||||
always();
|
||||
}
|
||||
};
|
||||
|
||||
pub.run = () => {
|
||||
try {
|
||||
run(successHandler, failHandler);
|
||||
} catch(ex) {
|
||||
fail(ex);
|
||||
} finally {
|
||||
if(typeof always === 'function')
|
||||
always();
|
||||
}
|
||||
};
|
||||
|
||||
return Object.freeze(pub);
|
||||
};
|
|
@ -1,3 +1,6 @@
|
|||
#include commitment.js
|
||||
#include xhr.js
|
||||
|
||||
var FutamiCommon = function(vars) {
|
||||
vars = vars || {};
|
||||
|
||||
|
@ -7,57 +10,41 @@ var FutamiCommon = function(vars) {
|
|||
|
||||
return {
|
||||
get: get,
|
||||
getJson: function(name, onload, onerror, noCache) {
|
||||
if(typeof onload !== 'function')
|
||||
throw 'onload must be specified';
|
||||
getJson: function(name, noCache) {
|
||||
return new Commitment((success, fail) => {
|
||||
const options = { type: 'json' };
|
||||
if(noCache)
|
||||
options.headers = { 'Cache-Control': 'no-cache' };
|
||||
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.onload = function() {
|
||||
onload(JSON.parse(xhr.responseText));
|
||||
};
|
||||
if(typeof onerror === 'function')
|
||||
xhr.onerror = function() { onerror(); };
|
||||
xhr.open('GET', get(name));
|
||||
if(noCache)
|
||||
xhr.setRequestHeader('Cache-Control', 'no-cache');
|
||||
xhr.send();
|
||||
$xhr.get(get(name), options)
|
||||
.success(({ body }) => { success(body); })
|
||||
.fail(fail)
|
||||
.run();
|
||||
});
|
||||
},
|
||||
getApiJson: function(path, onload, onerror, noCache) {
|
||||
if(typeof onload !== 'function')
|
||||
throw 'onload must be specified';
|
||||
getApiJson: function(path, noCache) {
|
||||
return new Commitment((success, fail) => {
|
||||
const options = { type: 'json' };
|
||||
if(noCache)
|
||||
options.headers = { 'Cache-Control': 'no-cache' };
|
||||
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.onload = function() {
|
||||
onload(JSON.parse(xhr.responseText));
|
||||
};
|
||||
if(typeof onerror === 'function')
|
||||
xhr.onerror = function() { onerror(); };
|
||||
xhr.open('GET', get('api') + path);
|
||||
if(noCache)
|
||||
xhr.setRequestHeader('Cache-Control', 'no-cache');
|
||||
xhr.send();
|
||||
$xhr.get(get('api') + path, options)
|
||||
.success(({ body }) => { success(body); })
|
||||
.fail(fail)
|
||||
.run();
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
FutamiCommon.load = function(callback, url) {
|
||||
if(typeof callback !== 'function')
|
||||
throw 'there must be a callback';
|
||||
if(typeof url !== 'string' && 'FUTAMI_URL' in window)
|
||||
url = window.FUTAMI_URL + '?t=' + Date.now().toString();
|
||||
FutamiCommon.load = function(url) {
|
||||
return new Commitment((success, fail) => {
|
||||
if(typeof url !== 'string' && 'FUTAMI_URL' in window)
|
||||
url = window.FUTAMI_URL + '?t=' + Date.now().toString();
|
||||
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.onload = function() {
|
||||
try {
|
||||
callback(new FutamiCommon(JSON.parse(xhr.responseText)));
|
||||
} catch(ex) {
|
||||
callback(false);
|
||||
}
|
||||
};
|
||||
xhr.onerror = function() {
|
||||
callback(false);
|
||||
};
|
||||
xhr.open('GET', url);
|
||||
xhr.setRequestHeader('Cache-Control', 'no-cache');
|
||||
xhr.send();
|
||||
$xhr.get(url, { type: 'json', headers: { 'Cache-Control': 'no-cache' } })
|
||||
.success(({ body }) => { success(new FutamiCommon(body)); })
|
||||
.fail(fail)
|
||||
.run();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -122,9 +122,9 @@ var AmiContext = function(title, auth, loading) {
|
|||
pub.textTriggers = textTriggers;
|
||||
settings.watch('runJokeTriggers', function(value) {
|
||||
if(!textTriggers.hasTriggers())
|
||||
futami.getJson('texttriggers', function(trigInfos) {
|
||||
textTriggers.addTriggers(trigInfos);
|
||||
});
|
||||
futami.getJson('texttriggers')
|
||||
.success(textTriggers.addTriggers)
|
||||
.run();
|
||||
});
|
||||
|
||||
var styles = new AmiStyles;
|
||||
|
@ -187,11 +187,11 @@ var AmiContext = function(title, auth, loading) {
|
|||
return;
|
||||
}
|
||||
|
||||
futami.getApiJson('/v1/emotes', function(emotes) {
|
||||
futami.getApiJson('/v1/emotes').success(emotes => {
|
||||
if(Array.isArray(emotes))
|
||||
emoticons.load(emotes);
|
||||
chat.emoticonList.render(emoticons);
|
||||
});
|
||||
}).run();
|
||||
});
|
||||
|
||||
var reconnecter = new AmiReconnecter(chat);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#include commitment.js
|
||||
#include xhr.js
|
||||
|
||||
var AmiEEPROM = function(endPoint, getAuthLine) {
|
||||
if(typeof endPoint !== 'string')
|
||||
throw 'endPoint must be a string';
|
||||
|
@ -14,16 +17,6 @@ var AmiEEPROM = function(endPoint, getAuthLine) {
|
|||
|
||||
let userAborted = false;
|
||||
let abortHandler;
|
||||
let progressHandler;
|
||||
|
||||
const reportProgress = ev => {
|
||||
if(progressHandler !== undefined)
|
||||
progressHandler({
|
||||
loaded: ev.loaded,
|
||||
total: ev.total,
|
||||
progress: ev.total <= 0 ? 0 : ev.loaded / ev.total,
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
abort: () => {
|
||||
|
@ -31,133 +24,75 @@ var AmiEEPROM = function(endPoint, getAuthLine) {
|
|||
if(typeof abortHandler === 'function')
|
||||
abortHandler();
|
||||
},
|
||||
onProgress: handler => {
|
||||
if(typeof handler !== 'function')
|
||||
throw 'handler must be a function';
|
||||
progressHandler = handler;
|
||||
},
|
||||
start: (success, error) => {
|
||||
const throwError = ex => {
|
||||
if(typeof error === 'function')
|
||||
error(ex);
|
||||
else
|
||||
console.error(ex);
|
||||
};
|
||||
|
||||
try {
|
||||
if(typeof success !== 'function')
|
||||
throw 'success must be a callback function';
|
||||
|
||||
start: progress => {
|
||||
return new Commitment((success, fail) => {
|
||||
if(userAborted)
|
||||
throw 'File upload was cancelled by the user, it cannot be restarted.';
|
||||
|
||||
try {
|
||||
const formData = new FormData;
|
||||
formData.append('src', appId);
|
||||
formData.append('file', fileInput);
|
||||
|
||||
const xhr = new XMLHttpRequest;
|
||||
abortHandler = () => { xhr.abort(); };
|
||||
xhr.upload.onloadstart = reportProgress;
|
||||
xhr.upload.onprogress = reportProgress;
|
||||
xhr.upload.onloadend = reportProgress;
|
||||
xhr.addEventListener('readystatechange', () => {
|
||||
if(xhr.readyState !== XMLHttpRequest.DONE)
|
||||
return;
|
||||
|
||||
try {
|
||||
const body = (() => {
|
||||
try {
|
||||
return JSON.parse(xhr.responseText);
|
||||
} catch(ex) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
// user cancel
|
||||
if(xhr.status === 0)
|
||||
throw '';
|
||||
|
||||
if(body === null)
|
||||
throw "The upload server didn't return the metadata for some reason.";
|
||||
|
||||
if(xhr.status !== 201)
|
||||
throw body.english ?? body.error ?? `Upload failed with status code ${xhr.status}`;
|
||||
|
||||
body.isImage = () => body.type.indexOf('image/') === 0;
|
||||
body.isVideo = () => body.type.indexOf('video/') === 0;
|
||||
body.isAudio = () => body.type.indexOf('audio/') === 0;
|
||||
body.isMedia = () => body.isImage() || body.isAudio() || body.isVideo();
|
||||
|
||||
success(Object.freeze(body));
|
||||
} catch(ex) {
|
||||
throwError(ex);
|
||||
}
|
||||
const reportProgress = typeof progress !== 'function' ? undefined : ev => {
|
||||
progress({
|
||||
loaded: ev.loaded,
|
||||
total: ev.total,
|
||||
progress: ev.total <= 0 ? 0 : ev.loaded / ev.total,
|
||||
});
|
||||
xhr.open('POST', `${endPoint}/uploads`);
|
||||
xhr.setRequestHeader('Authorization', getAuthLine());
|
||||
xhr.send(formData);
|
||||
} catch(ex) {
|
||||
if(userAborted)
|
||||
throw '';
|
||||
};
|
||||
|
||||
console.error(ex);
|
||||
throw ex;
|
||||
}
|
||||
} catch(ex) {
|
||||
throwError(ex);
|
||||
}
|
||||
const formData = new FormData;
|
||||
formData.append('src', appId);
|
||||
formData.append('file', fileInput);
|
||||
|
||||
$xhr.post(`${endPoint}/uploads`, {
|
||||
authed: true,
|
||||
type: 'json',
|
||||
upload: reportProgress,
|
||||
abort: handler => abortHandler = handler
|
||||
}, formData).fail(fail).success(({ status, body }) => {
|
||||
try {
|
||||
if(body === null)
|
||||
throw "The upload server didn't return the metadata for some reason.";
|
||||
|
||||
if(status !== 201)
|
||||
throw body.english ?? body.error ?? `Upload failed with status code ${status}`;
|
||||
|
||||
body.isImage = () => body.type.indexOf('image/') === 0;
|
||||
body.isVideo = () => body.type.indexOf('video/') === 0;
|
||||
body.isAudio = () => body.type.indexOf('audio/') === 0;
|
||||
body.isMedia = () => body.isImage() || body.isAudio() || body.isVideo();
|
||||
|
||||
success(Object.freeze(body));
|
||||
} catch(ex) {
|
||||
if(userAborted)
|
||||
throw '';
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}).run();
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
delete: (fileInfo, success, error) => {
|
||||
const throwError = ex => {
|
||||
if(typeof error === 'function')
|
||||
error(ex);
|
||||
else
|
||||
console.error(ex);
|
||||
};
|
||||
|
||||
try {
|
||||
delete: fileInfo => {
|
||||
return new Commitment((success, fail) => {
|
||||
if(typeof fileInfo !== 'object')
|
||||
throw 'fileInfo must be an object';
|
||||
if(typeof fileInfo.urlf !== 'string')
|
||||
throw 'fileInfo.urlf must be a string';
|
||||
|
||||
const xhr = new XMLHttpRequest;
|
||||
xhr.addEventListener('readystatechange', () => {
|
||||
if(xhr.readyState !== XMLHttpRequest.DONE)
|
||||
return;
|
||||
|
||||
try {
|
||||
const body = (() => {
|
||||
try {
|
||||
return JSON.parse(xhr.responseText);
|
||||
} catch(ex) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
if(xhr.status !== 204) {
|
||||
$xhr.delete(fileInfo.urlf, { authed: true, type: 'json' })
|
||||
.success(({ status, body }) => {
|
||||
if(status !== 204) {
|
||||
if(body === null)
|
||||
throw `Delete failed with status code ${xhr.status}`;
|
||||
throw `Delete failed with status code ${status}`;
|
||||
|
||||
throw body.english ?? body.error ?? `Delete failed with status code ${xhr.status}`;
|
||||
throw body.english ?? body.error ?? `Delete failed with status code ${status}`;
|
||||
}
|
||||
|
||||
if(typeof success === 'function')
|
||||
success(body);
|
||||
} catch(ex) {
|
||||
throwError(ex);
|
||||
}
|
||||
});
|
||||
xhr.open('DELETE', fileInfo.urlf);
|
||||
xhr.setRequestHeader('Authorization', getAuthLine());
|
||||
xhr.send();
|
||||
} catch(ex) {
|
||||
throwError(ex);
|
||||
}
|
||||
success();
|
||||
})
|
||||
.fail(fail)
|
||||
.run();
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -13,36 +13,37 @@
|
|||
(function() {
|
||||
var loading = new AmiLoadingOverlay(document.body, true);
|
||||
|
||||
FutamiCommon.load(function(futami) {
|
||||
if(typeof futami !== 'object') {
|
||||
alert('Failed to load environment settings!');
|
||||
return;
|
||||
}
|
||||
FutamiCommon.load()
|
||||
.success(futami => {
|
||||
window.futami = futami;
|
||||
|
||||
window.futami = futami;
|
||||
var auth = new AmiMisuzuAuth(futami.get('token'));
|
||||
var refreshInfo = function(next) {
|
||||
auth.refresh().success(token => {
|
||||
if(token.ok === false) {
|
||||
location.assign(futami.get('login') + '?legacy=1');
|
||||
return;
|
||||
}
|
||||
|
||||
var auth = new AmiMisuzuAuth(futami.get('token'));
|
||||
var refreshInfo = function(next) {
|
||||
auth.refresh(function(token) {
|
||||
if(token.ok === false) {
|
||||
location.assign(futami.get('login') + '?legacy=1');
|
||||
return;
|
||||
}
|
||||
if(typeof next === 'function')
|
||||
next(token.ok);
|
||||
}).run();
|
||||
};
|
||||
|
||||
if(typeof next === 'function')
|
||||
next(token.ok);
|
||||
var ami = new AmiContext(futami.get('title'), auth, loading);
|
||||
window.ami = ami;
|
||||
|
||||
setInterval(refreshInfo, 600000);
|
||||
refreshInfo(function() {
|
||||
Chat.Main(auth);
|
||||
|
||||
ami.sockChat.open();
|
||||
window.addEventListener('beforeunload', () => ami.sockChat.close());
|
||||
});
|
||||
};
|
||||
|
||||
var ami = new AmiContext(futami.get('title'), auth, loading);
|
||||
window.ami = ami;
|
||||
|
||||
setInterval(refreshInfo, 600000);
|
||||
refreshInfo(function() {
|
||||
Chat.Main(auth);
|
||||
|
||||
ami.sockChat.open();
|
||||
window.addEventListener('beforeunload', () => ami.sockChat.close());
|
||||
});
|
||||
});
|
||||
})
|
||||
.fail(ex => {
|
||||
console.log(ex);
|
||||
alert('Failed to load environment settings!');
|
||||
})
|
||||
.run();
|
||||
})();
|
||||
|
|
|
@ -1,39 +1,36 @@
|
|||
#include commitment.js
|
||||
#include xhr.js
|
||||
|
||||
var AmiMisuzuAuth = function(refreshUrl) {
|
||||
var userId = undefined,
|
||||
authToken = undefined;
|
||||
let userId = null;
|
||||
let authMethod = 'Misuzu';
|
||||
let authToken = null;
|
||||
|
||||
return {
|
||||
getUserId: function() { return userId; },
|
||||
getAuthToken: function() { return authToken; },
|
||||
getInfo: function() {
|
||||
hasInfo: () => userId !== null && authToken !== null,
|
||||
getUserId: () => userId,
|
||||
getAuthToken: () => authToken,
|
||||
getLine: () => `${authMethod} ${authToken}`,
|
||||
getInfo: () => {
|
||||
return {
|
||||
method: 'Misuzu',
|
||||
method: authMethod,
|
||||
token: authToken,
|
||||
};
|
||||
},
|
||||
getHttpAuth: function() {
|
||||
return 'Misuzu ' + authToken;
|
||||
},
|
||||
refresh: function(callback) {
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.onload = function() {
|
||||
if(xhr.status === 200) {
|
||||
var data = JSON.parse(xhr.responseText);
|
||||
if(data.ok === true) {
|
||||
userId = data.usr.toString();
|
||||
authToken = data.tkn;
|
||||
}
|
||||
refresh: function() {
|
||||
return new Commitment((success, fail) => {
|
||||
$xhr.get(refreshUrl, { authed: true, type: 'json' })
|
||||
.success(({ body }) => {
|
||||
if(body.ok) {
|
||||
userId = body.usr.toString();
|
||||
authToken = body.tkn;
|
||||
}
|
||||
|
||||
callback(data);
|
||||
} else
|
||||
callback({ok: null});
|
||||
};
|
||||
xhr.onerror = function() {
|
||||
callback({ok: null});
|
||||
};
|
||||
xhr.open('GET', refreshUrl);
|
||||
xhr.withCredentials = true;
|
||||
xhr.send();
|
||||
success(body);
|
||||
})
|
||||
.fail(fail)
|
||||
.run();
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -451,40 +451,41 @@ var Chat = (function () {
|
|||
ami.sound.clearPacks();
|
||||
ami.sound.clearSoundLibrary();
|
||||
|
||||
futami.getJson('sounds2', function(sounds) {
|
||||
if(typeof sounds !== 'object')
|
||||
return;
|
||||
futami.getJson('sounds2')
|
||||
.success(function(sounds) {
|
||||
if(typeof sounds !== 'object')
|
||||
return;
|
||||
|
||||
if(Array.isArray(sounds.library))
|
||||
for(var i in sounds.library)
|
||||
ami.sound.registerLibrarySound(sounds.library[i]);
|
||||
if(Array.isArray(sounds.library))
|
||||
for(var i in sounds.library)
|
||||
ami.sound.registerLibrarySound(sounds.library[i]);
|
||||
|
||||
if(Array.isArray(sounds.packs)) {
|
||||
for(var i in sounds.packs)
|
||||
ami.sound.registerSoundPack(sounds.packs[i]);
|
||||
if(Array.isArray(sounds.packs)) {
|
||||
for(var i in sounds.packs)
|
||||
ami.sound.registerSoundPack(sounds.packs[i]);
|
||||
|
||||
if(sounds.packs.length > 0 && !ami.settings.has('soundPack'))
|
||||
ami.settings.set('soundPack', sounds.packs[0].name);
|
||||
}
|
||||
if(sounds.packs.length > 0 && !ami.settings.has('soundPack'))
|
||||
ami.settings.set('soundPack', sounds.packs[0].name);
|
||||
}
|
||||
|
||||
var soundPackSetting = $id('chatSetting-spack');
|
||||
if(soundPackSetting) {
|
||||
while(soundPackSetting.options.length > 0)
|
||||
soundPackSetting.options.remove(0);
|
||||
var soundPackSetting = $id('chatSetting-spack');
|
||||
if(soundPackSetting) {
|
||||
while(soundPackSetting.options.length > 0)
|
||||
soundPackSetting.options.remove(0);
|
||||
|
||||
ami.sound.forEachPack(function(pack) {
|
||||
var opt = document.createElement('option');
|
||||
opt.value = pack.getName();
|
||||
opt.innerHTML = pack.getTitle();
|
||||
soundPackSetting.appendChild(opt);
|
||||
ami.sound.forEachPack(function(pack) {
|
||||
var opt = document.createElement('option');
|
||||
opt.value = pack.getName();
|
||||
opt.innerHTML = pack.getTitle();
|
||||
soundPackSetting.appendChild(opt);
|
||||
|
||||
if(ami.settings.get('soundPack') === '')
|
||||
ami.settings.set('soundPack', pack.getName());
|
||||
});
|
||||
if(ami.settings.get('soundPack') === '')
|
||||
ami.settings.set('soundPack', pack.getName());
|
||||
});
|
||||
|
||||
soundPackSetting.value = ami.settings.get('soundPack');
|
||||
}
|
||||
});
|
||||
soundPackSetting.value = ami.settings.get('soundPack');
|
||||
}
|
||||
}).run();
|
||||
}
|
||||
|
||||
ami.sound.setMuted(value);
|
||||
|
|
120
src/ami.js/xhr.js
Normal file
120
src/ami.js/xhr.js
Normal file
|
@ -0,0 +1,120 @@
|
|||
#include commitment.js
|
||||
|
||||
const $xhr = (function() {
|
||||
const send = function(method, url, options, body) {
|
||||
if(options === undefined)
|
||||
options = {};
|
||||
else if(typeof options !== 'object')
|
||||
throw 'options must be undefined or an object';
|
||||
|
||||
Object.freeze(options);
|
||||
|
||||
const xhr = new XMLHttpRequest;
|
||||
const requestHeaders = new Map;
|
||||
|
||||
if('headers' in options && typeof options.headers === 'object')
|
||||
for(const name in options.headers)
|
||||
if(options.headers.hasOwnProperty(name))
|
||||
requestHeaders.set(name.toLowerCase(), options.headers[name]);
|
||||
|
||||
if(typeof options.download === 'function') {
|
||||
xhr.onloadstart = ev => options.download(ev);
|
||||
xhr.onprogress = ev => options.download(ev);
|
||||
xhr.onloadend = ev => options.download(ev);
|
||||
}
|
||||
|
||||
if(typeof options.upload === 'function') {
|
||||
xhr.upload.onloadstart = ev => options.upload(ev);
|
||||
xhr.upload.onprogress = ev => options.upload(ev);
|
||||
xhr.upload.onloadend = ev => options.upload(ev);
|
||||
}
|
||||
|
||||
if(options.authed)
|
||||
xhr.withCredentials = true;
|
||||
|
||||
if(typeof options.timeout === 'number')
|
||||
xhr.timeout = options.timeout;
|
||||
|
||||
if(typeof options.abort === 'function')
|
||||
options.abort(() => xhr.abort());
|
||||
|
||||
if(typeof options.xhr === 'function')
|
||||
options.xhr(() => xhr);
|
||||
|
||||
if(typeof body === 'object') {
|
||||
if(body instanceof FormData) {
|
||||
// content-type is implicitly set
|
||||
} else if(body instanceof Blob || body instanceof ArrayBuffer
|
||||
|| body instanceof DataView || body instanceof Uint8Array) {
|
||||
if(!requestHeaders.has('content-type'))
|
||||
requestHeaders.set('content-type', 'application/octet-stream');
|
||||
} else if(!requestHeaders.has('content-type')) {
|
||||
const bodyParts = [];
|
||||
for(const name in body)
|
||||
if(body.hasOwnProperty(name))
|
||||
bodyParts.push(encodeURIComponent(name) + '=' + encodeURIComponent(body[name]));
|
||||
body = bodyParts.join('&');
|
||||
requestHeaders.set('content-type', 'application/x-www-form-urlencoded');
|
||||
}
|
||||
}
|
||||
|
||||
return new Commitment((success, fail) => {
|
||||
xhr.onload = ev => {
|
||||
const headers = (headersString => {
|
||||
const headers = new Map;
|
||||
|
||||
const raw = headersString.trim().split(/[\r\n]+/);
|
||||
for(const name in raw)
|
||||
if(raw.hasOwnProperty(name)) {
|
||||
const parts = raw[name].split(': ');
|
||||
headers.set(parts.shift(), parts.join(': '));
|
||||
}
|
||||
|
||||
return headers;
|
||||
})(xhr.getAllResponseHeaders());
|
||||
|
||||
success({
|
||||
get ev() { return ev; },
|
||||
get xhr() { return xhr; },
|
||||
|
||||
get status() { return xhr.status; },
|
||||
get headers() { return headers; },
|
||||
get body() { return xhr.response; },
|
||||
get text() { return xhr.responseText; },
|
||||
});
|
||||
};
|
||||
|
||||
xhr.onabort = ev => fail({
|
||||
abort: true,
|
||||
xhr: xhr,
|
||||
ev: ev,
|
||||
});
|
||||
|
||||
xhr.onerror = ev => fail({
|
||||
abort: false,
|
||||
xhr: xhr,
|
||||
ev: ev,
|
||||
});
|
||||
|
||||
xhr.open(method, url);
|
||||
|
||||
if(typeof options.type === 'string')
|
||||
xhr.responseType = options.type;
|
||||
|
||||
requestHeaders.forEach((value, name) => {
|
||||
xhr.setRequestHeader(name, requestHeaders[name]);
|
||||
});
|
||||
|
||||
xhr.send(body);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
send: send,
|
||||
get: (url, options, body) => send('GET', url, options, body),
|
||||
post: (url, options, body) => send('POST', url, options, body),
|
||||
delete: (url, options, body) => send('DELETE', url, options, body),
|
||||
patch: (url, options, body) => send('PATCH', url, options, body),
|
||||
put: (url, options, body) => send('PUT', url, options, body),
|
||||
};
|
||||
})();
|
|
@ -1,13 +1,9 @@
|
|||
#include common.js
|
||||
#include eeprom.js
|
||||
|
||||
var eepromAppl = 1,
|
||||
eepromSupportImageEmbed = true,
|
||||
eepromSupportAudioEmbed = true,
|
||||
eepromSupportVideoEmbed = true;
|
||||
var eepromInitialise = function(auth) {
|
||||
window.eepromHistory = {};
|
||||
window.eepromClient = new AmiEEPROM(futami.get('eeprom2'), auth.getHttpAuth);
|
||||
window.eepromClient = new AmiEEPROM(futami.get('eeprom2'), auth.getLine);
|
||||
|
||||
window.eepromUploadsTable = $id('uploadHistory');
|
||||
$id('uploadSelector').onchange = function() {
|
||||
|
@ -88,27 +84,25 @@ var eepromFileUpload = function(file) {
|
|||
|
||||
var uploadTask = window.eepromClient.create(file);
|
||||
|
||||
uploadTask.onProgress(function(progressInfo) {
|
||||
progBar.style.width = `${progressInfo.progress * 100}%`;
|
||||
});
|
||||
|
||||
name.onclick = function(ev) {
|
||||
if(ev.shiftKey) {
|
||||
ev.preventDefault();
|
||||
var fileInfo = window.eepromHistory[name.getAttribute('data-eeprom-id') || ''];
|
||||
|
||||
if(fileInfo) {
|
||||
window.eepromClient.delete(
|
||||
fileInfo,
|
||||
() => { uploadHistory.deleteRow(uploadEntryWrap.rowIndex); },
|
||||
window.alert
|
||||
);
|
||||
window.eepromClient.delete(fileInfo)
|
||||
.success(() => { window.eepromUploadsTable.deleteRow(uploadEntryWrap.rowIndex); })
|
||||
.fail(ex => {
|
||||
console.error(ex);
|
||||
window.alert(ex);
|
||||
})
|
||||
.run();
|
||||
} else uploadTask.abort();
|
||||
}
|
||||
};
|
||||
|
||||
uploadTask.start(
|
||||
fileInfo => {
|
||||
uploadTask.start(progressInfo => { progBar.style.width = `${progressInfo.progress * 100}%`; })
|
||||
.success(fileInfo => {
|
||||
window.eepromHistory[fileInfo.id] = fileInfo;
|
||||
name.style.textDecoration = null;
|
||||
name.setAttribute('data-eeprom-id', fileInfo.id);
|
||||
|
@ -117,19 +111,19 @@ var eepromFileUpload = function(file) {
|
|||
|
||||
var insertText = location.protocol + fileInfo.url;
|
||||
|
||||
if(eepromSupportImageEmbed && fileInfo.isImage())
|
||||
if(fileInfo.isImage())
|
||||
insertText = '[img]' + fileInfo.url + '[/img]';
|
||||
else if(eepromSupportAudioEmbed && fileInfo.isAudio())
|
||||
else if(fileInfo.isAudio())
|
||||
insertText = '[audio]' + fileInfo.url + '[/audio]';
|
||||
else if(eepromSupportVideoEmbed && fileInfo.isVideo())
|
||||
else if(fileInfo.isVideo())
|
||||
insertText = '[video]' + fileInfo.url + '[/video]';
|
||||
|
||||
ami.chat.inputBox.insert(insertText);
|
||||
},
|
||||
ex => {
|
||||
})
|
||||
.fail(ex => {
|
||||
if(ex !== '')
|
||||
alert(ex);
|
||||
uploadHistory.deleteRow(uploadEntryWrap.rowIndex);
|
||||
},
|
||||
);
|
||||
window.eepromUploadsTable.deleteRow(uploadEntryWrap.rowIndex);
|
||||
})
|
||||
.run();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue