mirror of
https://github.com/filecoin-project/slate.git
synced 2024-11-23 22:12:19 +03:00
file-utilities: adds reusable upload method
This commit is contained in:
parent
ba470a6fde
commit
b836735d82
93
common/file-utilities.js
Normal file
93
common/file-utilities.js
Normal file
@ -0,0 +1,93 @@
|
||||
export const upload = async ({ file, slate, setState }) => {
|
||||
let formData = new FormData();
|
||||
const HEIC2ANY = require("heic2any");
|
||||
|
||||
// TODO(jim): Put this somewhere else to handle conversion cases.
|
||||
if (file.type.startsWith("image/heic")) {
|
||||
const converted = await HEIC2ANY({
|
||||
blob: file,
|
||||
toType: "image/png",
|
||||
quality: 1,
|
||||
});
|
||||
|
||||
formData.append("data", converted);
|
||||
} else {
|
||||
formData.append("data", file);
|
||||
}
|
||||
|
||||
const upload = (path) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const XHR = new XMLHttpRequest();
|
||||
XHR.open("post", path, true);
|
||||
XHR.onerror = (event) => {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
// NOTE(jim): UPLOADS ONLY.
|
||||
XHR.upload.addEventListener(
|
||||
"progress",
|
||||
(event) => {
|
||||
if (event.lengthComputable) {
|
||||
console.log("FILE UPLOAD PROGRESS", event);
|
||||
setState({
|
||||
fileLoading: {
|
||||
...this.state.fileLoading,
|
||||
[`${file.lastModified}-${file.name}`]: {
|
||||
name: file.name,
|
||||
loaded: event.loaded,
|
||||
total: event.total,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
XHR.onloadend = (event) => {
|
||||
console.log("FILE UPLOAD END", event);
|
||||
try {
|
||||
return resolve(JSON.parse(event.target.response));
|
||||
} catch (e) {
|
||||
return resolve({
|
||||
error: "SERVER_UPLOAD_ERROR",
|
||||
});
|
||||
}
|
||||
};
|
||||
XHR.send(formData);
|
||||
});
|
||||
|
||||
const json = await upload(`/api/data/${file.name}`);
|
||||
console.log(json);
|
||||
|
||||
if (!json || json.error || !json.data) {
|
||||
setState({
|
||||
fileLoading: {
|
||||
...this.state.fileLoading,
|
||||
[`${file.lastModified}-${file.name}`]: {
|
||||
name: file.name,
|
||||
failed: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
return !json ? { error: "NO_RESPONSE" } : json;
|
||||
}
|
||||
|
||||
if (slate) {
|
||||
const addResponse = await fetch(`/api/slates/add-url`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ slate, data: { ...json.data } }),
|
||||
});
|
||||
|
||||
if (!addResponse || addResponse.error) {
|
||||
console.log(addResponse.error);
|
||||
alert("TODO: Adding an image to Slate went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
};
|
@ -4,6 +4,7 @@ import * as Actions from "~/common/actions";
|
||||
import * as State from "~/common/state";
|
||||
import * as Credentials from "~/common/credentials";
|
||||
import * as Validations from "~/common/validations";
|
||||
import * as FileUtilities from "~/common/file-utilities";
|
||||
import * as System from "~/components/system";
|
||||
|
||||
// NOTE(jim):
|
||||
@ -102,106 +103,16 @@ export default class ApplicationPage extends React.Component {
|
||||
this.setState({ online: navigator.onLine });
|
||||
};
|
||||
|
||||
_handleRegisterFile = ({ fileLoading }) => {
|
||||
_handleUploadFile = async ({ file, slate }) => {
|
||||
return await FileUtilities.upload({ file, slate, setState: this.setState });
|
||||
};
|
||||
|
||||
_handleRegisterFileLoading = ({ fileLoading }) => {
|
||||
return this.setState({
|
||||
fileLoading,
|
||||
});
|
||||
};
|
||||
|
||||
_handleUploadFile = async ({ file, slate }) => {
|
||||
let formData = new FormData();
|
||||
const HEIC2ANY = require("heic2any");
|
||||
|
||||
// TODO(jim): Put this somewhere else to handle conversion cases.
|
||||
if (file.type.startsWith("image/heic")) {
|
||||
const converted = await HEIC2ANY({
|
||||
blob: file,
|
||||
toType: "image/png",
|
||||
quality: 1,
|
||||
});
|
||||
|
||||
formData.append("data", converted);
|
||||
} else {
|
||||
formData.append("data", file);
|
||||
}
|
||||
|
||||
const upload = (path) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const XHR = new XMLHttpRequest();
|
||||
XHR.open("post", path, true);
|
||||
XHR.onerror = (event) => {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
// NOTE(jim): UPLOADS ONLY.
|
||||
XHR.upload.addEventListener(
|
||||
"progress",
|
||||
(event) => {
|
||||
if (event.lengthComputable) {
|
||||
console.log("FILE UPLOAD PROGRESS", event);
|
||||
this.setState({
|
||||
fileLoading: {
|
||||
...this.state.fileLoading,
|
||||
[`${file.lastModified}-${file.name}`]: {
|
||||
name: file.name,
|
||||
loaded: event.loaded,
|
||||
total: event.total,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
XHR.onloadend = (event) => {
|
||||
console.log("FILE UPLOAD END", event);
|
||||
try {
|
||||
return resolve(JSON.parse(event.target.response));
|
||||
} catch (e) {
|
||||
return resolve({
|
||||
error: "SERVER_UPLOAD_ERROR",
|
||||
});
|
||||
}
|
||||
};
|
||||
XHR.send(formData);
|
||||
});
|
||||
|
||||
const json = await upload(`/api/data/${file.name}`);
|
||||
console.log(json);
|
||||
|
||||
if (!json || json.error || !json.data) {
|
||||
this.setState({
|
||||
fileLoading: {
|
||||
...this.state.fileLoading,
|
||||
[`${file.lastModified}-${file.name}`]: {
|
||||
name: file.name,
|
||||
failed: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
return !json ? { error: "NO_RESPONSE" } : json;
|
||||
}
|
||||
|
||||
if (slate) {
|
||||
const addResponse = await fetch(`/api/slates/add-url`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ slate, data: { ...json.data } }),
|
||||
});
|
||||
|
||||
if (!addResponse || addResponse.error) {
|
||||
console.log(addResponse.error);
|
||||
alert("TODO: Adding an image to Slate went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
};
|
||||
|
||||
_handleDragEnter = (e) => {
|
||||
if (this.state.sidebar) {
|
||||
return;
|
||||
@ -272,7 +183,7 @@ export default class ApplicationPage extends React.Component {
|
||||
}
|
||||
|
||||
// NOTE(jim): Stages each file.
|
||||
this._handleRegisterFile({ fileLoading });
|
||||
this._handleRegisterFileLoading({ fileLoading });
|
||||
|
||||
// NOTE(jim): Uploads each file.
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
@ -517,9 +428,6 @@ export default class ApplicationPage extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
// TODO(colin): Populate this.
|
||||
console.log({ analytics: this.props.analytics });
|
||||
|
||||
// NOTE(jim): Not authenticated.
|
||||
if (!this.state.viewer) {
|
||||
return (
|
||||
@ -594,7 +502,7 @@ export default class ApplicationPage extends React.Component {
|
||||
onSelectedChange: this._handleSelectedChange,
|
||||
onSubmit: this._handleSubmit,
|
||||
onCancel: this._handleCancel,
|
||||
onRegisterFile: this._handleRegisterFile,
|
||||
onRegisterFileLoading: this._handleRegisterFileLoading,
|
||||
onUploadFile: this._handleUploadFile,
|
||||
onSidebarLoading: this._handleSidebarLoading,
|
||||
onAction: this._handleAction,
|
||||
|
@ -83,11 +83,14 @@ export default class SidebarAddFileToBucket extends React.Component {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onRegisterFile({ fileLoading });
|
||||
this.props.onRegisterFileLoading({ fileLoading });
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
const slate = this.props.data && this.props.data.slateId ? { id: this.props.data.slateId } : null;
|
||||
const slate =
|
||||
this.props.data && this.props.data.slateId
|
||||
? { id: this.props.data.slateId }
|
||||
: null;
|
||||
|
||||
const response = await this.props.onUploadFile({
|
||||
file,
|
||||
@ -111,12 +114,20 @@ export default class SidebarAddFileToBucket extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<System.P style={{ fontFamily: Constants.font.semiBold }}>Upload data</System.P>
|
||||
<input css={STYLES_FILE_HIDDEN} type="file" id="file" onChange={this._handleUpload} />
|
||||
<System.P style={{ fontFamily: Constants.font.semiBold }}>
|
||||
Upload data
|
||||
</System.P>
|
||||
<input
|
||||
css={STYLES_FILE_HIDDEN}
|
||||
type="file"
|
||||
id="file"
|
||||
onChange={this._handleUpload}
|
||||
/>
|
||||
|
||||
{this.props.data && this.props.data.decorator === "SLATE" ? (
|
||||
<System.P style={{ marginTop: 24 }}>
|
||||
This will add data to your Slate named <strong>{this.props.data.slatename}</strong>.
|
||||
This will add data to your Slate named{" "}
|
||||
<strong>{this.props.data.slatename}</strong>.
|
||||
</System.P>
|
||||
) : null}
|
||||
|
||||
@ -125,12 +136,17 @@ export default class SidebarAddFileToBucket extends React.Component {
|
||||
type="label"
|
||||
htmlFor="file"
|
||||
style={{ marginTop: 24 }}
|
||||
loading={!!this.props.fileLoading}>
|
||||
loading={!!this.props.fileLoading}
|
||||
>
|
||||
Add file
|
||||
</System.ButtonPrimary>
|
||||
|
||||
{!this.props.fileLoading ? (
|
||||
<System.ButtonSecondary full style={{ marginTop: 16 }} onClick={this.props.onCancel}>
|
||||
<System.ButtonSecondary
|
||||
full
|
||||
style={{ marginTop: 16 }}
|
||||
onClick={this.props.onCancel}
|
||||
>
|
||||
Cancel
|
||||
</System.ButtonSecondary>
|
||||
) : null}
|
||||
|
Loading…
Reference in New Issue
Block a user