summaryrefslogtreecommitdiffstats
path: root/web/react/components/view_image.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'web/react/components/view_image.jsx')
-rw-r--r--web/react/components/view_image.jsx189
1 files changed, 189 insertions, 0 deletions
diff --git a/web/react/components/view_image.jsx b/web/react/components/view_image.jsx
new file mode 100644
index 000000000..7d0f0d8a9
--- /dev/null
+++ b/web/react/components/view_image.jsx
@@ -0,0 +1,189 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+var Client = require('../utils/client.jsx');
+var utils = require('../utils/utils.jsx');
+
+module.exports = React.createClass({
+ handleNext: function() {
+ var id = this.state.imgId + 1;
+ if (id > this.props.filenames.length-1) {
+ id = 0;
+ }
+ this.setState({ imgId: id });
+ this.loadImage(id);
+ },
+ handlePrev: function() {
+ var id = this.state.imgId - 1;
+ if (id < 0) {
+ id = this.props.filenames.length-1;
+ }
+ this.setState({ imgId: id });
+ this.loadImage(id);
+ },
+ componentWillReceiveProps: function(nextProps) {
+ this.setState({ imgId: nextProps.startId });
+ },
+ loadImage: function(id) {
+ if (this.state.loaded[id] || this.state.images[id]) return;
+
+ var src = "";
+ if (this.props.imgCount > 0) {
+ src = this.props.filenames[id];
+ } else {
+ var fileInfo = utils.splitFileLocation(this.props.filenames[id]);
+ src = fileInfo['path'] + '_preview.jpg';
+ }
+
+ var self = this;
+ var img = new Image();
+ img.load(src,
+ function(){
+ var progress = self.state.progress;
+ progress[id] = img.completedPercentage;
+ self.setState({ progress: progress });
+ });
+ img.onload = function(imgid) {
+ return function() {
+ var loaded = self.state.loaded;
+ loaded[imgid] = true;
+ self.setState({ loaded: loaded });
+ };
+ }(id);
+ var images = this.state.images;
+ images[id] = img;
+ this.setState({ images: images });
+ },
+ componentDidUpdate: function() {
+ if (this.refs.image) {
+ var height = $(window).height()-100;
+ if (this.state.loaded[this.state.imgId]) {
+ $(this.refs.imageWrap.getDOMNode()).removeClass("default");
+ $(this.refs.image.getDOMNode()).css("max-height",height);
+ }
+ }
+ },
+ componentDidMount: function() {
+ var self = this;
+ $("#"+this.props.modalId).on('shown.bs.modal', function() {
+ self.setState({ viewed: true });
+ self.loadImage(self.state.imgId);
+ })
+
+ $(this.refs.modal.getDOMNode()).click(function(e){
+ if (e.target == this || e.target == self.refs.imageBody.getDOMNode()) {
+ $('.image_modal').modal('hide');
+ }
+ });
+
+ $(this.refs.imageWrap.getDOMNode()).hover(
+ function() {
+ $(self.refs.imageFooter.getDOMNode()).addClass("footer--show");
+ }, function() {
+ $(self.refs.imageFooter.getDOMNode()).removeClass("footer--show");
+ }
+ );
+ },
+ getPublicLink: function(e) {
+ data = {};
+ data["channel_id"] = this.props.channelId;
+ data["user_id"] = this.props.userId;
+ data["filename"] = this.props.filenames[this.state.imgId];
+ Client.getPublicLink(data,
+ function(data) {
+ window.open(data["public_link"]);
+ }.bind(this),
+ function(err) {
+ }.bind(this)
+ );
+ },
+ getInitialState: function() {
+ var loaded = [];
+ var progress = [];
+ for (var i = 0; i < this.props.filenames.length; i ++) {
+ loaded.push(false);
+ progress.push(0);
+ }
+ return { imgId: this.props.startId, viewed: false, loaded: loaded, progress: progress, images: {} };
+ },
+ render: function() {
+ if (this.props.filenames.length < 1 || this.props.filenames.length-1 < this.state.imgId) {
+ return <div/>;
+ }
+
+ var fileInfo = utils.splitFileLocation(this.props.filenames[this.state.imgId]);
+
+ var name = fileInfo['name'] + '.' + fileInfo['ext'];
+
+ var loading = "";
+ var bgClass = "";
+ var img = {};
+ if (!this.state.loaded[this.state.imgId]) {
+ var percentage = Math.floor(this.state.progress[this.state.imgId]);
+ loading = (
+ <div key={name+"_loading"}>
+ <img ref="placeholder" className="loader-image" src="/static/images/load.gif" />
+ { percentage > 0 ?
+ <span className="loader-percent" >{"Downloading " + percentage + "%"}</span>
+ : ""}
+ </div>
+ );
+ bgClass = "black-bg";
+ } else if (this.state.viewed) {
+ for (var id in this.state.images) {
+ var info = utils.splitFileLocation(this.props.filenames[id]);
+ var preview_filename = "";
+ if (this.props.imgCount > 0) {
+ preview_filename = this.props.filenames[this.state.imgId];
+ } else {
+ preview_filename = info['path'] + '_preview.jpg';
+ }
+
+ var imgClass = "hidden";
+ if (this.state.loaded[id] && this.state.imgId == id) imgClass = "";
+
+ img[info['path']] = <a key={info['path']} className={imgClass} href={this.props.filenames[id]} target="_blank"><img ref="image" src={preview_filename}/></a>;
+ }
+ }
+
+ var imgFragment = React.addons.createFragment(img);
+
+ return (
+ <div className="modal fade image_modal" ref="modal" id={this.props.modalId} tabIndex="-1" role="dialog" aria-hidden="true">
+ <div className="modal-dialog modal-image">
+ <div className="modal-content image-content">
+ <div ref="imageBody" className="modal-body image-body">
+ <div ref="imageWrap" className={"image-wrapper default " + bgClass}>
+ <div className="modal-close" data-dismiss="modal"></div>
+ {imgFragment}
+ <div ref="imageFooter" className="modal-button-bar">
+ <span className="pull-left text">{"Image "+(this.state.imgId+1)+" of "+this.props.filenames.length}</span>
+ <div className="image-links">
+ { config.AllowPublicLink ?
+ <div>
+ <a href="#" className="text" data-title="Public Image" onClick={this.getPublicLink}>Get Public Link</a>
+ <span className="text"> | </span>
+ </div>
+ : "" }
+ <a href={this.props.filenames[id]} download={name} className="text">Download</a>
+ </div>
+ </div>
+ {loading}
+ </div>
+ { this.props.filenames.length > 1 ?
+ <a className="modal-prev-bar" href="#" onClick={this.handlePrev}>
+ <i className="image-control image-prev"/>
+ </a>
+ : "" }
+ { this.props.filenames.length > 1 ?
+ <a className="modal-next-bar" href="#" onClick={this.handleNext}>
+ <i className="image-control image-next"/>
+ </a>
+ : "" }
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+});