2013-12-30 05:14:35 +00:00
|
|
|
/*
|
|
|
|
Copyright 2013 Google Inc.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
goog.require('camlistore.AnimationLoop');
|
|
|
|
goog.require('camlistore.ServerConnection');
|
2013-12-31 23:25:19 +00:00
|
|
|
goog.require('SpritedAnimation');
|
2013-12-30 05:14:35 +00:00
|
|
|
|
|
|
|
goog.require('goog.math.Size');
|
2013-12-31 23:25:19 +00:00
|
|
|
goog.require('goog.object');
|
2013-12-30 05:14:35 +00:00
|
|
|
|
|
|
|
var DetailView = React.createClass({
|
2013-12-31 23:25:19 +00:00
|
|
|
IMG_MARGIN: 20,
|
|
|
|
PIGGY_WIDTH: 88,
|
|
|
|
PIGGY_HEIGHT: 62,
|
|
|
|
|
|
|
|
getInitialState: function() {
|
2014-01-01 01:15:34 +00:00
|
|
|
this.imgSize_ = null;
|
|
|
|
this.lastImageHeight_ = 0;
|
|
|
|
|
2013-12-31 23:25:19 +00:00
|
|
|
return {
|
|
|
|
description: null,
|
2014-01-01 01:15:34 +00:00
|
|
|
imgHasLoaded: false
|
2013-12-31 23:25:19 +00:00
|
|
|
};
|
|
|
|
},
|
2013-12-30 05:14:35 +00:00
|
|
|
|
|
|
|
componentDidMount: function(root) {
|
|
|
|
var imageSize = 100; // We won't use this exact value; we only care about the aspect ratio.
|
|
|
|
var connection = new camlistore.ServerConnection(this.props.config);
|
|
|
|
connection.describeWithThumbnails(this.props.blobref, imageSize, function(description) {
|
2013-12-31 23:25:19 +00:00
|
|
|
this.setState({
|
2013-12-30 05:14:35 +00:00
|
|
|
description: description
|
|
|
|
});
|
|
|
|
}.bind(this));
|
|
|
|
},
|
|
|
|
|
2014-01-01 01:15:34 +00:00
|
|
|
componentDidUpdate: function(prevProps, prevState) {
|
|
|
|
if (this.refs.img) {
|
|
|
|
this.refs.img.getDOMNode().addEventListener('load', this.setState.bind(this, {imgHasLoaded:true}, null));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-12-30 05:14:35 +00:00
|
|
|
render: function() {
|
2013-12-31 23:25:19 +00:00
|
|
|
this.imgSize_ = this.getImgSize_();
|
2013-12-30 05:14:35 +00:00
|
|
|
return (
|
|
|
|
React.DOM.div({className:'detail-view', style: this.getStyle_()},
|
2013-12-31 23:25:19 +00:00
|
|
|
this.getImg_(),
|
|
|
|
this.getPiggy_(),
|
2013-12-30 05:14:35 +00:00
|
|
|
React.DOM.div({className:'detail-view-sidebar', key:'sidebar', style: this.getSidebarStyle_()},
|
2013-12-31 23:25:19 +00:00
|
|
|
React.DOM.pre({key:'sidebar-pre'}, JSON.stringify(this.state.description || '', null, 2)))));
|
2013-12-30 05:14:35 +00:00
|
|
|
},
|
|
|
|
|
2013-12-31 23:25:19 +00:00
|
|
|
getImg_: function() {
|
|
|
|
if (this.state.description) {
|
2014-01-01 01:15:34 +00:00
|
|
|
this.img_ = React.DOM.img({
|
|
|
|
className: React.addons.classSet({
|
|
|
|
'detail-view-img': true,
|
|
|
|
'detail-view-img-loaded': this.state.imgHasLoaded
|
|
|
|
}),
|
|
|
|
key: 'img',
|
|
|
|
ref: 'img',
|
|
|
|
src: this.getSrc_(),
|
|
|
|
style: this.getCenteredProps_(this.imgSize_.width, this.imgSize_.height)
|
|
|
|
});
|
2013-12-31 23:25:19 +00:00
|
|
|
}
|
2014-01-01 01:15:34 +00:00
|
|
|
return this.img_;
|
2013-12-31 23:25:19 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
getPiggy_: function() {
|
|
|
|
var transition = React.addons.TransitionGroup({transitionName: 'detail-piggy'}, []);
|
2014-01-01 01:15:34 +00:00
|
|
|
if (!this.state.imgHasLoaded) {
|
2013-12-31 23:25:19 +00:00
|
|
|
transition.props.children.push(
|
|
|
|
SpritedAnimation({
|
|
|
|
src: 'glitch/npc_piggy__x1_walk_png_1354829432.png',
|
|
|
|
className: 'detail-view-piggy',
|
|
|
|
spriteWidth: this.PIGGY_WIDTH,
|
|
|
|
spriteHeight: this.PIGGY_HEIGHT,
|
|
|
|
sheetWidth: 8,
|
|
|
|
sheetHeight: 3,
|
|
|
|
interval: 30,
|
|
|
|
style: this.getCenteredProps_(this.PIGGY_WIDTH, this.PIGGY_HEIGHT)
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
return transition;
|
|
|
|
},
|
|
|
|
|
|
|
|
getCenteredProps_: function(w, h) {
|
|
|
|
var avail = new goog.math.Size(this.props.width - this.getSidebarWidth_(), this.props.height);
|
|
|
|
return {
|
|
|
|
top: (avail.height - h) / 2,
|
|
|
|
left: (avail.width - w) / 2,
|
|
|
|
width: w,
|
|
|
|
height: h
|
2013-12-30 05:14:35 +00:00
|
|
|
}
|
2013-12-31 23:25:19 +00:00
|
|
|
},
|
2013-12-30 05:14:35 +00:00
|
|
|
|
2013-12-31 23:25:19 +00:00
|
|
|
getSrc_: function() {
|
2013-12-30 05:14:35 +00:00
|
|
|
// Only re-request the image if we're increasing in size. Otherwise, let the browser resample.
|
2014-01-01 01:15:34 +00:00
|
|
|
if (this.imgSize_.height < this.lastImageHeight_) {
|
2013-12-30 05:14:35 +00:00
|
|
|
console.log('Not re-requesting image becasue new size is smaller than existing...');
|
|
|
|
} else {
|
|
|
|
// If we re-request, ask for one bigger than we need right now, so that we're not constantly re-requesting as the browser resizes.
|
2014-01-01 01:15:34 +00:00
|
|
|
this.lastImageHeight_ = this.imgSize_.height * 1.25;
|
|
|
|
console.log('Requesting new image with size: ' + this.lastImageHeight_);
|
2013-12-30 05:14:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var uri = new goog.Uri(this.getPermanodeMeta_().thumbnailSrc);
|
2014-01-01 01:15:34 +00:00
|
|
|
uri.setParameterValue('mh', this.lastImageHeight_);
|
2013-12-30 05:14:35 +00:00
|
|
|
return uri.toString();
|
|
|
|
},
|
|
|
|
|
2013-12-31 23:25:19 +00:00
|
|
|
getImgSize_: function() {
|
|
|
|
if (!this.state.description) {
|
|
|
|
return null;
|
2013-12-30 05:14:35 +00:00
|
|
|
}
|
|
|
|
|
2013-12-31 23:25:19 +00:00
|
|
|
var meta = this.getPermanodeMeta_();
|
|
|
|
var aspect = new goog.math.Size(meta.thumbnailWidth, meta.thumbnailHeight);
|
|
|
|
var available = new goog.math.Size(
|
|
|
|
this.props.width - this.getSidebarWidth_() - this.IMG_MARGIN * 2,
|
|
|
|
this.props.height - this.IMG_MARGIN * 2);
|
|
|
|
return aspect.scaleToFit(available);
|
|
|
|
},
|
2013-12-30 05:14:35 +00:00
|
|
|
|
2013-12-31 23:25:19 +00:00
|
|
|
getStyle_: function() {
|
2013-12-30 05:14:35 +00:00
|
|
|
return {
|
2013-12-31 23:25:19 +00:00
|
|
|
width: this.props.width,
|
|
|
|
height: this.props.height
|
2013-12-30 05:14:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
getSidebarStyle_: function() {
|
|
|
|
return {
|
|
|
|
width: this.getSidebarWidth_()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
getSidebarWidth_: function() {
|
|
|
|
return Math.max(this.props.width * 0.2, 300);
|
|
|
|
},
|
|
|
|
|
|
|
|
getPermanodeMeta_: function() {
|
|
|
|
return this.state.description.meta[this.props.blobref];
|
2013-12-31 23:25:19 +00:00
|
|
|
},
|
2013-12-30 05:14:35 +00:00
|
|
|
});
|