From bca0752535d515c2a17b1876cc62e33334b2fb78 Mon Sep 17 00:00:00 2001 From: Qolzam Date: Thu, 24 Aug 2017 21:52:34 +0700 Subject: [PATCH] Enhance load image performance --- app/actions/imageGalleryActions.jsx | 17 +-- app/actions/postActions.jsx | 1 + app/api/FileAPI.jsx | 38 +++++- app/components/EditProfile.jsx | 6 +- app/components/ImageGallery.jsx | 38 +++--- app/components/Img.jsx | 29 +---- app/components/ImgCover.jsx | 30 +---- app/components/PostWrite.jsx | 174 ++++++++++++++++------------ app/components/UserAvatar.jsx | 31 +---- 9 files changed, 178 insertions(+), 186 deletions(-) diff --git a/app/actions/imageGalleryActions.jsx b/app/actions/imageGalleryActions.jsx index c0e1849..0997d10 100644 --- a/app/actions/imageGalleryActions.jsx +++ b/app/actions/imageGalleryActions.jsx @@ -62,17 +62,18 @@ export const downloadForImageGallery = () => { /* _____________ CRUD Database_____________ */ /** - * Save image in the server - * @param {string} imageName is the name of image + * Save image URL in the server + * @param {string} imageURL is the URL of image */ -export const dbSaveImage = (imageName) => { +export const dbSaveImage = (imageURL,imageFullPath) => { return (dispatch, getState) => { var uid = getState().authorize.uid var image = { creationDate: moment().unix(), deletationDate: '', - name: imageName, + URL: imageURL, + fullPath:imageFullPath, ownerUserId: uid, lastEditDate: '', deleted: false @@ -93,7 +94,7 @@ export const dbSaveImage = (imageName) => { * Delete an image from database * @param {string} id of image */ -export const dbDeleteImage = (id) => { +export const dbDeleteImage = (fullPath) => { return (dispatch, getState) => { // Get current user id @@ -101,11 +102,11 @@ export const dbDeleteImage = (id) => { // Write the new data simultaneously in the list var updates = {}; - updates[`userFiles/${uid}/files/images/${id}`] = null; + updates[`userFiles/${uid}/files/${fullPath}`] = null; return firebaseRef.update(updates).then((result) => { - dispatch(deleteImage(id)) - console.log('image removed: ', id); + dispatch(deleteImage(fullPath)) + console.log('image removed: ', fullPath); }, (error) => { console.log(error); }); diff --git a/app/actions/postActions.jsx b/app/actions/postActions.jsx index 1291268..ebd3ea8 100644 --- a/app/actions/postActions.jsx +++ b/app/actions/postActions.jsx @@ -85,6 +85,7 @@ export var dbAddPost = (newPost,callBack) => { tags: newPost.tags || [], commentCounter: 0, image: newPost.image || '', + imageFullPath: newPost.imageFullPath || '', video:'', disableComments: newPost.disableComments ? newPost.disableComments : false, disableSharing: newPost.disableSharing ? newPost.disableSharing : false, diff --git a/app/api/FileAPI.jsx b/app/api/FileAPI.jsx index 5657950..abf2f67 100644 --- a/app/api/FileAPI.jsx +++ b/app/api/FileAPI.jsx @@ -19,6 +19,41 @@ const convertImageToCanvas = (image) => { return canvas; } +/** + * Upload image on the server + * @param {file} file + * @param {string} fileName + */ +const uploadImage = (file, fileName, progress) => { + + return new Promise((resolve, reject) => { + // Create a storage refrence + var storegeFile = storageRef.child(`images/${fileName}`) + + // Upload file + var task = storegeFile.put(file) + task.then((result) => { + resolve(result) + }).catch((error) => { + reject(error) + }) + + // Upload storage bar + task.on('state_changed', (snapshot) => { + var percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100 + progress(percentage, true) + }, (error) => { + console.log('========== Upload Image ============') + console.log(error) + console.log('====================================') + + }, (complete) => { + progress(100, false) + }) + }) + + } + /** * Constraint image size * @param {file} file @@ -103,6 +138,7 @@ export default { dataURLToBlob, convertImageToCanvas, getExtension, - constraintImage + constraintImage, + uploadImage } \ No newline at end of file diff --git a/app/components/EditProfile.jsx b/app/components/EditProfile.jsx index 196a5ad..9e20773 100644 --- a/app/components/EditProfile.jsx +++ b/app/components/EditProfile.jsx @@ -153,6 +153,9 @@ export class EditProfile extends Component { * Set banner image url */ handleRequestSetBanner = (url) => { + console.log('==========Banner=================='); + console.log(url); + console.log('===================================='); this.setState({ banner: url }) @@ -433,8 +436,7 @@ export class EditProfile extends Component { const mapDispatchToProps = (dispatch, ownProps) => { return { update: (info) => dispatch(userActions.dbUpdateUserInfo(info)), - onRequestClose: () => dispatch(userActions.closeEditProfile()), - getImage: (name) => dispatch(imageGalleryActions.dbDownloadImage(name)) + onRequestClose: () => dispatch(userActions.closeEditProfile()) } } diff --git a/app/components/ImageGallery.jsx b/app/components/ImageGallery.jsx index 1267a76..bf7eb74 100644 --- a/app/components/ImageGallery.jsx +++ b/app/components/ImageGallery.jsx @@ -17,7 +17,6 @@ import uuid from 'uuid' // - Import actions import * as imageGalleryActions from 'imageGalleryActions' -import * as fileActions from 'fileActions' import * as globalActions from 'globalActions' // - Import app components @@ -59,8 +58,8 @@ export class ImageGallery extends Component { * @param {event} evt passed by on click event on add image * @param {string} name is the name of the image */ - handleSetImage = (evt, name) => { - this.props.set(name) + handleSetImage = (evt, URL,fullPath) => { + this.props.set(URL,fullPath) this.close() } @@ -69,8 +68,8 @@ export class ImageGallery extends Component { * @param {event} evt passed by on click event on delete image * @param {integer} id is the image identifier which selected to delete */ - handleDeleteImage = (evt, id) => { - this.props.deleteImage(id) + handleDeleteImage = (evt, fullPath) => { + this.props.deleteImage(fullPath) } componentDidMount() { @@ -87,9 +86,20 @@ export class ImageGallery extends Component { * @memberof ImageGallery */ handleSendResizedImage = (event) => { - const { resizedImage, fileName } = event.detail - this.props.saveImage(resizedImage, fileName) + const { resizedImage, fileName } = event.detail + const {saveImageGallery} = this.props + + FileAPI.uploadImage(resizedImage, fileName, (percent, status) => { + console.log('============= Upload progress ==============='); + console.log(percent); + console.log('===================================='); + }).then((result) => { + + /* Add image to image gallery */ + saveImageGallery(result.downloadURL,result.metadata.fullPath) + + }) } /** @@ -116,9 +126,9 @@ export class ImageGallery extends Component { return ( this.handleDeleteImage(evt, image.id)} />} + title={ this.handleDeleteImage(evt, image.fullPath)} />} subtitle={} - actionIcon={ this.handleSetImage(evt, image.name)} />} + actionIcon={ this.handleSetImage(evt, image.URL,image.fullPath)} />} >
@@ -126,7 +136,7 @@ export class ImageGallery extends Component {
  • - +
  • @@ -214,12 +224,8 @@ export class ImageGallery extends Component { */ const mapDispatchToProps = (dispatch, ownProps) => { return { - saveImage: (file, fileName) => { - dispatch(imageGalleryActions.dbUploadImage(file, fileName)) - }, - deleteImage: (id) => { - dispatch(imageGalleryActions.dbDeleteImage(id)) - } + saveImageGallery: (imageURL,imageFullPath) => dispatch(imageGalleryActions.dbSaveImage(imageURL,imageFullPath)), + deleteImage: (fullPath) => dispatch(imageGalleryActions.dbDeleteImage(fullPath)) } } diff --git a/app/components/Img.jsx b/app/components/Img.jsx index a41510e..1c06555 100644 --- a/app/components/Img.jsx +++ b/app/components/Img.jsx @@ -43,7 +43,6 @@ export class Img extends Component { } // Binding functions to `this` - this.getImageURL = this.getImageURL.bind(this) this.handleLoadImage = this.handleLoadImage.bind(this) } @@ -59,29 +58,6 @@ export class Img extends Component { }) } - /** - * Get image url if it is not exist on redux store - * - * @memberof Img - */ - getImageURL = () => { - let { fileName } = this.props - if (fileName && fileName !== '') { - if (this.props.imageRequests.indexOf(fileName) > -1) - return - this.props.getImage(fileName) - - } - } - - componentWillMount() { - let { fileName } = this.props - - if (this.props.imageRequests.indexOf(fileName) > -1) - return - this.getImageURL() - } - /** * Reneder component DOM * @return {react element} return the DOM which rendered by component @@ -114,7 +90,7 @@ export class Img extends Component { let { isImageLoaded } = this.state return (
    - +
    @@ -136,8 +112,7 @@ export class Img extends Component { */ const mapDispatchToProps = (dispatch, ownProps) => { return { - getImage: (name) => dispatch(imageGalleryActions.dbDownloadImage(name)) - + } } diff --git a/app/components/ImgCover.jsx b/app/components/ImgCover.jsx index c1904d6..8b2575e 100644 --- a/app/components/ImgCover.jsx +++ b/app/components/ImgCover.jsx @@ -60,7 +60,6 @@ export class ImgCover extends Component { } // Binding functions to `this` - this.getImageURL = this.getImageURL.bind(this) this.handleLoadImage = this.handleLoadImage.bind(this) } @@ -75,29 +74,6 @@ export class ImgCover extends Component { }) } - /** - * Get image url if it is not exist on redux store - * - * @memberof Img - */ - getImageURL = () => { - let { fileName } = this.props - if (fileName && fileName !== '') { - if (this.props.imageRequests.indexOf(fileName) > -1) - return - this.props.getImage(fileName) - - } - } - - componentWillMount() { - let { fileName } = this.props - - if (this.props.imageRequests.indexOf(fileName) > -1) - return - this.getImageURL() - } - /** * Reneder component DOM * @return {react element} return the DOM which rendered by component @@ -112,7 +88,7 @@ export class ImgCover extends Component { */ const styles = { cover: { - backgroundImage: 'url(' + (this.props.avatarURL[fileName] || '#') + ')', + backgroundImage: 'url(' + (fileName || '') + ')', backgroundSize: 'cover', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', @@ -153,7 +129,7 @@ export class ImgCover extends Component {
    Image has not loaded
    - +
    ) } @@ -169,8 +145,6 @@ export class ImgCover extends Component { */ const mapDispatchToProps = (dispatch, ownProps) => { return { - getImage: (name) => dispatch(imageGalleryActions.dbDownloadImage(name)) - } } diff --git a/app/components/PostWrite.jsx b/app/components/PostWrite.jsx index 63370a8..4736adb 100644 --- a/app/components/PostWrite.jsx +++ b/app/components/PostWrite.jsx @@ -82,9 +82,13 @@ export class PostWrite extends Component { */ postText: this.props.edit ? this.props.text : '', /** - * The image of the post + * The URL image of the post */ image: this.props.edit ? this.props.image : '', + /** + * The path identifier of image on the server + */ + imageFullPath: this.props.edit ? this.props.imageFullPath : '', /** * If it's true gallery will be open */ @@ -116,31 +120,31 @@ export class PostWrite extends Component { } -/** - * Toggle comments of the post to disable/enable - * - * - * @memberof PostWrite - */ -handleToggleComments = () => { - this.setState({ - disableComments: !this.state.disableComments, + /** + * Toggle comments of the post to disable/enable + * + * + * @memberof PostWrite + */ + handleToggleComments = () => { + this.setState({ + disableComments: !this.state.disableComments, disabledPost: false - }) -} + }) + } -/** - * Toggle sharing of the post to disable/enable - * - * - * @memberof PostWrite - */ -handleToggleSharing = () => { - this.setState({ - disableSharing: !this.state.disableSharing, + /** + * Toggle sharing of the post to disable/enable + * + * + * @memberof PostWrite + */ + handleToggleSharing = () => { + this.setState({ + disableSharing: !this.state.disableSharing, disabledPost: false - }) -} + }) + } /** * Romove the image of post @@ -151,6 +155,7 @@ handleToggleSharing = () => { handleRemoveImage = () => { this.setState({ image: '', + imageFullPath: '', disabledPost: false }) } @@ -161,52 +166,71 @@ handleToggleSharing = () => { */ handlePost = (evt) => { - var image = this.state.image - var tags = PostAPI.getContentTags(this.state.postText) + const { + image, + imageFullPath, + disableComments, + disableSharing, + postText } = this.state + + const { + id, + avatar, + name, + edit, + onRequestClose, + post, + update } = this.props + + var tags = PostAPI.getContentTags(postText) // In edit status we should fire update if not we should fire post function - if (!this.props.edit) { + if (!edit) { if (image !== '') { - this.props.post({ - body: this.state.postText, + post({ + body: postText, tags: tags, image: image, - avatar: this.props.avatar, - name: this.props.name, - disableComments: this.state.disableComments, - disableSharing: this.state.disableSharing - }, this.props.onRequestClose) + imageFullPath: imageFullPath, + avatar: avatar, + name: name, + disableComments: disableComments, + disableSharing: disableSharing + }, onRequestClose) } else { - this.props.post({ - body: this.state.postText, + post({ + body: postText, tags: tags, - avatar: this.props.avatar, - name: this.props.name, - disableComments: this.state.disableComments, - disableSharing: this.state.disableSharing - }, this.props.onRequestClose) + avatar: avatar, + name: name, + disableComments: disableComments, + disableSharing: disableSharing + }, onRequestClose) } } + // In edit status we pass post to update functions else { - this.props.update({ - id: this.props.id, - body: this.state.postText, + update({ + id: id, + body: postText, tags: tags, image: image, - disableComments: this.state.disableComments, - disableSharing: this.state.disableSharing - }, this.props.onRequestClose) + imageFullPath: imageFullPath, + disableComments: disableComments, + disableSharing: disableSharing + }, onRequestClose) } } /** * Set post image url */ - onRequestSetImage = (url) => { + onRequestSetImage = (url, fullPath) => { this.setState({ image: url, + imageFullPath: fullPath, disabledPost: false }) } @@ -252,32 +276,32 @@ handleToggleSharing = () => { } componentWillReceiveProps(nextProps) { - if(!nextProps.open){ + if (!nextProps.open) { this.setState({ - /** - * Post text - */ - postText: this.props.edit ? this.props.text : '', - /** - * The image of the post - */ - image: this.props.edit ? this.props.image : '', - /** - * If it's true gallery will be open - */ - galleryOpen: false, - /** - * If it's true post button will be disabled - */ - disabledPost: true, - /** - * If it's true comment will be disabled on post - */ - disableComments: this.props.edit ? this.props.disableComments : false, - /** - * If it's true share will be disabled on post - */ - disableSharing: this.props.edit ? this.props.disableSharing : false, + /** + * Post text + */ + postText: this.props.edit ? this.props.text : '', + /** + * The image of the post + */ + image: this.props.edit ? this.props.image : '', + /** + * If it's true gallery will be open + */ + galleryOpen: false, + /** + * If it's true post button will be disabled + */ + disabledPost: true, + /** + * If it's true comment will be disabled on post + */ + disableComments: this.props.edit ? this.props.disableComments : false, + /** + * If it's true share will be disabled on post + */ + disableSharing: this.props.edit ? this.props.disableSharing : false, }) } @@ -364,7 +388,7 @@ handleToggleSharing = () => {
    {this.props.children} { hintStyle={{ fontWeight: 200, fontSize: "14px" }} textareaStyle={{ fontWeight: 200, fontSize: "14px" }} style={{ margin: "0 16px", flexShrink: 0, width: "initial", flexGrow: 1 }} - + /> {(this.state.image && this.state.image !== '') @@ -462,7 +486,7 @@ handleToggleSharing = () => { const mapDispatchToProps = (dispatch, ownProps) => { return { post: (post, callBack) => dispatch(postActions.dbAddImagePost(post, callBack)), - update: (post,callBack) => dispatch(postActions.dbUpdatePost(post, callBack)) + update: (post, callBack) => dispatch(postActions.dbUpdatePost(post, callBack)) } } diff --git a/app/components/UserAvatar.jsx b/app/components/UserAvatar.jsx index b010317..a901364 100644 --- a/app/components/UserAvatar.jsx +++ b/app/components/UserAvatar.jsx @@ -51,46 +51,21 @@ export class ImgCover extends Component { } // Binding functions to `this` - this.getImageURL = this.getImageURL.bind(this) } - componentWillReceiveProps(nextProps) { - const { fileName, avatarURL } = this.props - if (fileName && !avatarURL[fileName]) { - if (this.props.imageRequests.indexOf(fileName) > -1) - return - this.getImageURL() - } - } - getImageURL = () => { - let { fileName } = this.props - if (fileName && fileName !== '') { - if (this.props.imageRequests.indexOf(fileName) > -1) - return - this.props.getImage(fileName) - } - } - - componentWillMount() { - let { fileName } = this.props - - if (this.props.imageRequests.indexOf(fileName) > -1) - return - this.getImageURL() - } /** * Reneder component DOM * @return {react element} return the DOM which rendered by component */ render() { - let { fileName, style, size, onTouchTap, avatarURL } = this.props + let { fileName, style, size, onTouchTap } = this.props return ( - + ) } @@ -106,8 +81,6 @@ export class ImgCover extends Component { */ const mapDispatchToProps = (dispatch, ownProps) => { return { - getImage: (name) => dispatch(imageGalleryActions.dbDownloadImage(name)) - } }