Commit 21100886 authored by Kenrick's avatar Kenrick Committed by Michael Henretty
Browse files

Change code style to async/await in web folder (#430)

* Change code style to async/await in web/src/lib/api.ts
parent cf60736d
......@@ -59,11 +59,9 @@ export default class API {
});
}
private fetchText(path: string): Promise<any> {
return this.fetch(path, { responseType: 'text' })
.then((req: XMLHttpRequest) => {
private async fetchText(path: string): Promise<any> {
const req = await this.fetch(path, { responseType: 'text' });
return req.responseText;
});
}
private requestResourceText(resource): Promise<string> {
......@@ -78,11 +76,9 @@ export default class API {
return API.DEFAULT_BASE + resource;
}
getRandomSentences(count?: number): Promise<string[]> {
return this.requestResourceText('sentence' + (count ? '/' + count : ''))
.then(sentencesText => {
async getRandomSentences(count?: number): Promise<string[]> {
const sentencesText = await this.requestResourceText('sentence' + (count ? '/' + count : ''));
return sentencesText.split('\n');
});
}
getTextFromUrl(url): Promise<string> {
......@@ -92,25 +88,22 @@ export default class API {
/**
* Ask the server for a clip
*/
getRandomClip(): Promise<Clip> {
return this.fetch('upload/random/', { responseType: 'blob', headers: {'uid': this.user.getId()}})
.then((req: XMLHttpRequest) => {
async getRandomClip(): Promise<Clip> {
const req = await this.fetch('upload/random/', { responseType: 'blob', headers: {'uid': this.user.getId()}})
let src = window.URL.createObjectURL(req.response);
let glob = decodeURIComponent(req.getResponseHeader('glob'));
let sentence = decodeURIComponent(req.getResponseHeader('sentence'));
return Promise.resolve({ glob: glob, audio: src, sentence: sentence });
});
return { glob: glob, audio: src, sentence: sentence };
}
/**
* Ask the server for a clip
*/
getRandomClipJson(): Promise<ClipJson> {
return this.fetch('upload/random.json', { responseType: 'json', headers: {'uid': this.user.getId()}})
.then((req: XMLHttpRequest) => {
async getRandomClipJson(): Promise<ClipJson> {
const req = await this.fetch('upload/random.json', { responseType: 'json', headers: {'uid': this.user.getId()}});
let response = req.response as ClipJson;
return Promise.resolve(response);
});
return response;
}
castVote(glob: string, vote: boolean): Promise<Event> {
......
......@@ -157,7 +157,7 @@ export default class App {
), document.body, document.body.firstElementChild);
}
init(): Promise<void> {
async init(): Promise<void> {
// Always force page to be ready after a specified time.
setTimeout(() => {
......@@ -165,19 +165,18 @@ export default class App {
document.body.classList.add('loaded');
}, LOAD_TIMEOUT);
return this.loadImages(progress => {
await this.loadImages(progress => {
if (this.progressMeter) {
// TODO: find something performant here. (ie not this)
// let whatsLeft = 1 - progress;
// this.progressMeter.style.cssText =
// `transform: scale(${whatsLeft});`;
}
}).then(() => {
});
this.loaded = true;
setTimeout(() => {
document.body.classList.add('loaded');
}, LOAD_DELAY);
});
}
/**
......
......@@ -237,47 +237,31 @@ export default class Pages extends Component<PagesProps, PagesState> {
});
}
private uploadRecordings(recordings: any[],
private async uploadRecordings(recordings: any[],
sentences: string[],
progressCb: Function): Promise<void> {
await this.ensurePrivacyAgreement();
const originalTotal = recordings.length;
return new Promise<void>((res, rej) => {
this.ensurePrivacyAgreement().then(() => {
let runningTotal = 0;
let originalTotal = recordings.length;
// This function calls itself recursively until
// all recordings are uploaded.
let uploadNext = () => {
if (recordings.length === 0) {
this.props.api.uploadDemographicInfo().then(() => {
return;
});
res();
return;
}
for (let runningTotal = 1; runningTotal <= originalTotal; runningTotal++) {
const recording = recordings.pop();
const blob = recording.blob;
const sentence = sentences.pop();
let recording = recordings.pop();
let blob = recording.blob;
let sentence = sentences.pop();
await this.props.api.uploadAudio(blob, sentence);
this.props.api.uploadAudio(blob, sentence).then(() => {
runningTotal++;
if (recordings.length !== 0) {
let percentage = Math.floor((runningTotal / originalTotal) * 100);
progressCb && progressCb(percentage);
this.props.user.tallyRecording();
uploadNext();
});
};
}
}
await this.props.api.uploadDemographicInfo();
// Start the recursive chain to upload the recordings serially.
uploadNext();
}).catch(rej);
}).then(() => {
// Reset robot state to initial state
this.setState({
robot: ''
});
});
}
componentDidMount() {
......
......@@ -96,11 +96,9 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
this.onProgress = this.onProgress.bind(this);
}
private refillSentenceCache() {
return this.props.api.getRandomSentences(CACHE_SET_COUNT)
.then(newSentences => {
private async refillSentenceCache() {
const newSentences = await this.props.api.getRandomSentences(CACHE_SET_COUNT)
this.sentenceCache = this.sentenceCache.concat(newSentences);
});
}
private processRecording(info: AudioInfo) {
......@@ -165,7 +163,7 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
this.props.onVolume(volume);
}
private onSubmit() {
private async onSubmit() {
if (this.state.uploading) {
return;
}
......@@ -174,22 +172,20 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
uploading: true
});
this.props.onSubmit(this.state.recordings, this.state.sentences, this.onProgress)
.then(() => {
try {
await this.props.onSubmit(this.state.recordings, this.state.sentences, this.onProgress);
this.reset();
this.tracker.trackSubmitRecordings();
})
.catch(() => {
} catch (e) {
this.setState({
uploading: false
});
confirm('You did not agree to our Terms of Service. Do you want to delete your recordings?', 'Keep the recordings', 'Delete my recordings').then((keep) => {
const keep = await confirm('Upload aborted. Do you want to delete your recordings?', 'Keep the recordings', 'Delete my recordings')
if (!keep) {
this.reset();
this.props.navigate('/');
}
})
});
}
}
private isFull(): boolean {
......@@ -227,7 +223,7 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
this.newSentenceSet();
}
onRecordClick(evt?: any) {
async onRecordClick(evt?: any) {
evt.preventDefault();
evt.stopImmediatePropagation();
......@@ -236,9 +232,8 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
// Don't start a new recording when full.
} else if (!this.isFull()) {
this.audio.init().then(() => {
await this.audio.init();
this.startRecording();
});
}
}
......@@ -268,12 +263,11 @@ export default class RecordPage extends Component<RecordProps, RecordState> {
this.props.onRecordStop && this.props.onRecordStop();
}
newSentenceSet() {
// If we don't have any sentences in our cache, fill it and try again.
if (this.sentenceCache.length < SET_COUNT) {
private async newSentenceSet() {
// If we don't have enough sentences in our cache, fill it before continuing.
while (this.sentenceCache.length < SET_COUNT) {
console.error('slow path for getting new sentences');
this.refillSentenceCache().then(this.newSentenceSet.bind(this));
return;
await this.refillSentenceCache();
}
let newOnes = this.sentenceCache.splice(0, SET_COUNT);
......
......@@ -189,7 +189,7 @@ export default class AudioWeb {
});
}
stop() {
stop(): Promise<AudioInfo | {}> {
if (!this.ready) {
console.error('Cannot stop audio before microhphone is ready.');
return Promise.resolve({});
......
......@@ -29,29 +29,30 @@ export default class Validator extends Component<Props, State> {
this.loadClip();
}
private onVote(vote: boolean) {
this.props.api.castVote(this.state.glob, vote).then(() => {
private async onVote(vote: boolean) {
try {
await this.props.api.castVote(this.state.glob, vote);
this.props.onVote && this.props.onVote(vote);
this.loadClip();
}).catch((err) => {
} catch (err) {
console.error('could not vote on clip from validator', err);
});
}
}
private loadClip() {
private async loadClip() {
this.setState({ loading: true });
this.props.api.getRandomClipJson().then((clipJson: ClipJson) => {
try {
const clipJson = await this.props.api.getRandomClipJson();
this.setState({
loading: false,
glob: clipJson.glob,
sentence: decodeURIComponent(clipJson.text),
audioSrc: clipJson.sound
});
}, (err) => {
} catch (err) {
console.error('could not fetch random clip for validator', err);
this.setState({ loading: false, sentence: null, audioSrc: null });
});
}
}
render() {
......
......@@ -6,10 +6,9 @@ define('preact', () => { return preact; })
document.addEventListener("touchstart", function(){}, true);
// Start the app when DOM is ready.
document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('DOMContentLoaded', async () => {
let App = require('./lib/app').default;
let app = new App();
app.init().then(() => {
await app.init();
app.run();
});
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment