moved publish emitter into channel

This commit is contained in:
bill bittner 2018-03-01 16:36:42 -08:00
parent 54f342cd5e
commit 4c050503ab
2 changed files with 74 additions and 44 deletions

52
react/channels/publish.js Normal file
View file

@ -0,0 +1,52 @@
import {buffers, END, eventChannel} from 'redux-saga';
export const makePublishRequestChannel = (fd) => {
console.log('making publish request');
return eventChannel(emitter => {
const uri = '/api/claim/publish';
const xhr = new XMLHttpRequest();
// add event listeners
const onLoadStart = () => {
console.log('load started');
emitter({loadStart: true});
};
const onProgress = (event) => {
if (event.lengthComputable) {
const percentage = Math.round((event.loaded * 100) / event.total);
console.log('progress:', percentage);
emitter({progress: percentage});
}
};
const onLoad = () => {
console.log('load completed');
emitter({load: true});
};
xhr.upload.addEventListener('loadstart', onLoadStart);
xhr.upload.addEventListener('progress', onProgress);
xhr.upload.addEventListener('load', onLoad);
// set state change handler
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
const response = JSON.parse(xhr.response);
if ((xhr.status === 200) && response.success) {
emitter({success: response});
emitter(END);
} else {
emitter({error: new Error(response.message)});
emitter(END);
}
}
};
// open and send
xhr.open('POST', uri, true);
xhr.send(fd);
// clean up
return () => {
xhr.upload.removeEventListener('loadstart', onLoadStart);
xhr.upload.removeEventListener('progress', onProgress);
xhr.upload.removeEventListener('load', onLoad);
xhr.onreadystatechange = null;
xhr.abort();
};
}, buffers.sliding(2));
};

View file

@ -1,4 +1,4 @@
import { call, put, select, takeLatest } from 'redux-saga/effects'; import { call, put, select, take, takeLatest } from 'redux-saga/effects';
import * as actions from 'constants/publish_action_types'; import * as actions from 'constants/publish_action_types';
import * as publishStates from 'constants/publish_claim_states'; import * as publishStates from 'constants/publish_claim_states';
import { updateError, updatePublishStatus, clearFile } from 'actions/publish'; import { updateError, updatePublishStatus, clearFile } from 'actions/publish';
@ -6,42 +6,7 @@ import { selectPublishState } from 'selectors/publish';
import { selectChannelState } from 'selectors/channel'; import { selectChannelState } from 'selectors/channel';
import { validateChannelSelection, validatePublishParams } from 'utils/validate'; import { validateChannelSelection, validatePublishParams } from 'utils/validate';
import { createPublishMetadata, createPublishFormData } from 'utils/publish'; import { createPublishMetadata, createPublishFormData } from 'utils/publish';
import { makePublishRequestChannel } from 'channels/publish';
const makePublishRequest = (fd) => {
console.log('making publish request');
return new Promise((resolve, reject) => {
const uri = '/api/claim/publish';
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('loadstart', () => {
put(updatePublishStatus(publishStates.LOAD_START, 'upload started'));
});
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
const percentage = Math.round((e.loaded * 100) / e.total);
console.log('progress:', percentage);
put(updatePublishStatus(publishStates.LOADING, `${percentage}%`));
}
}, false);
xhr.upload.addEventListener('load', () => {
console.log('loaded 100%');
put(updatePublishStatus(publishStates.PUBLISHING, null));
}, false);
xhr.open('POST', uri, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
const response = JSON.parse(xhr.response);
// console.log('publish response:', response);
if ((xhr.status === 200) && response.success) {
resolve(response);
} else {
reject(new Error(response.message));
}
}
};
// Initiate a multipart/form-data upload
xhr.send(fd);
});
};
function * publishFile (action) { function * publishFile (action) {
const { history } = action.data; const { history } = action.data;
@ -65,14 +30,27 @@ function * publishFile (action) {
// create form data // create form data
const publishFormData = createPublishFormData(file, publishMetadata); const publishFormData = createPublishFormData(file, publishMetadata);
// make the publish request // make the publish request
let response; const channel = yield call(makePublishRequestChannel, publishFormData);
try { while (true) {
response = yield call(makePublishRequest, publishFormData); const {loadStart, progress, load, success, error} = yield take(channel);
yield put(clearFile()); console.log('emitted:', loadStart, progress, load, success, error);
history.push(`/${response.data.claimId}/${response.data.name}`); if (error) {
} catch (error) {
return yield put(updatePublishStatus(publishStates.FAILED, error.message)); return yield put(updatePublishStatus(publishStates.FAILED, error.message));
} }
if (success) {
yield put(clearFile());
return history.push(`/${success.data.claimId}/${success.data.name}`);
}
if (loadStart) {
yield put(updatePublishStatus(publishStates.LOAD_START, 'upload started'));
}
if (progress) {
yield put(updatePublishStatus(publishStates.LOADING, `${progress}%`));
}
if (load) {
yield put(updatePublishStatus(publishStates.PUBLISHING, null));
}
}
}; };
export function * watchPublishStart () { export function * watchPublishStart () {