start at twitter renderer.. pretty ugly right now. still working on it...

Change-Id: I7e4940d05bf0eb03f2eb68fb330a8fbe77c38173
This commit is contained in:
Aaron Boodman 2014-06-20 05:24:44 -07:00
parent 3f1d8c14bc
commit 1138db00cd
7 changed files with 241 additions and 32 deletions

View File

@ -21,6 +21,7 @@ goog.require('goog.math.Size');
goog.require('goog.object');
goog.require('goog.string');
goog.require('cam.dateUtils');
goog.require('cam.math');
goog.require('cam.permanodeUtils');
goog.require('cam.Thumber');
@ -55,38 +56,10 @@ cam.BlobItemFoursquareContent = React.createClass({
)
)
),
React.DOM.div({className:'cam-blobitem-fs-checkin-when'}, this.formatDate_())
React.DOM.div({className:'cam-blobitem-fs-checkin-when'}, cam.dateUtils.formatDateShort(this.props.date))
)
);
},
formatDate_: function() {
var seconds = Math.floor((Date.now() - this.props.date) / 1000);
var interval = Math.floor(seconds / 31536000);
return (function() {
if (interval > 1) {
return interval + ' years';
}
interval = Math.floor(seconds / 2592000);
if (interval > 1) {
return interval + ' months';
}
interval = Math.floor(seconds / 86400);
if (interval > 1) {
return interval + ' days';
}
interval = Math.floor(seconds / 3600);
if (interval > 1) {
return interval + ' hours';
}
interval = Math.floor(seconds / 60);
if (interval > 1) {
return interval + ' minutes';
}
return Math.floor(seconds) + ' seconds';
})() + ' ago';
},
});
// Blech, we need this to prevent images from flashing when data changes server-side.

View File

@ -0,0 +1,63 @@
/*
Copyright 2014 The Camlistore Authors
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.
*/
.cam-blobitem-twitter-tweet {
color: black;
display: block;
font-size: 90%;
position: relative;
overflow: hidden;
white-space: normal;
border-radius: 7%;
}
.cam-blobitem-twitter-tweet table {
border-spacing: 0;
background-color: #e1e8ed;
width: 100%;
height: 100%;
}
.cam-blobitem-twitter-tweet-icon {
position: absolute;
width: 100%;
bottom: 0;
}
.cam-blobitem-twitter-tweet-icon img {
width: 4em;
height: 4em;
position: absolute;
bottom: 1em;
right: 1em;
opacity: 1;
}
.cam-blobitem-twitter-tweet-meta {
text-align: left;
vertical-align: top;
padding: 0.8em;
}
.cam-blobitem-twitter-tweet-date {
color: #aaa;
}
.cam-blobitem-twitter-tweet-image {
background-position: top;
background-size: cover;
height: 100%;
}

View File

@ -0,0 +1,122 @@
/*
Copyright 2014 The Camlistore Authors
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.provide('cam.BlobItemTwitterContent');
goog.require('goog.math.Size');
goog.require('cam.dateUtils');
goog.require('cam.math');
goog.require('cam.permanodeUtils');
goog.require('cam.Thumber');
cam.BlobItemTwitterContent = React.createClass({
propTypes: {
date: React.PropTypes.number.isRequired,
href: React.PropTypes.string.isRequired,
image: React.PropTypes.string,
size: React.PropTypes.instanceOf(goog.math.Size).isRequired,
username: React.PropTypes.string.isRequired,
},
getImageRow_: function() {
if (!this.props.image) {
return null;
}
return React.DOM.tr(null,
React.DOM.td({
className: 'cam-blobitem-twitter-tweet-image',
colSpan: 2,
src: 'twitter-icon.png',
style: {
backgroundImage: 'url(' + this.props.image + ')',
},
})
);
},
render: function() {
return React.DOM.a({
href: this.props.href,
className: 'cam-blobitem-twitter-tweet',
style: {
width: this.props.size.width,
height: this.props.size.height,
},
},
React.DOM.table({height: this.props.image ? '100%' : ''},
React.DOM.tr(null,
React.DOM.td({className: 'cam-blobitem-twitter-tweet-meta'},
React.DOM.span({className: 'cam-blobitem-twitter-tweet-date'}, cam.dateUtils.formatDateShort(this.props.date)),
React.DOM.br(),
React.DOM.span({className: ' cam-blobitem-twitter-tweet-content'}, this.props.content)
)
),
this.getImageRow_(),
React.DOM.tr(null,
React.DOM.td({className: 'cam-blobitem-twitter-tweet-icon'},
React.DOM.img({src: 'twitter-logo.png'})
)
)
)
);
},
});
cam.BlobItemTwitterContent.getHandler = function(blobref, searchSession, href) {
var m = searchSession.getMeta(blobref);
if (m.camliType != 'permanode') {
return null;
}
if (cam.permanodeUtils.getSingleAttr(m.permanode, 'camliNodeType') != 'twitter.com:tweet') {
return null;
}
var content = cam.permanodeUtils.getSingleAttr(m.permanode, 'content');
var date = cam.permanodeUtils.getSingleAttr(m.permanode, 'startDate');
var username = cam.permanodeUtils.getSingleAttr(m.permanode, 'url').match(/^https:\/\/twitter.com\/(.+?)\//)[1];
var imageMeta = cam.permanodeUtils.getSingleAttr(m.permanode, 'camliContentImage');
if (imageMeta) {
imageMeta = searchSession.getResolvedMeta(imageMeta);
}
return new cam.BlobItemTwitterContent.Handler(content, Date.parse(date), href, imageMeta, username);
};
cam.BlobItemTwitterContent.Handler = function(content, date, href, imageMeta, username) {
this.content_ = content;
this.date_ = date;
this.href_ = href;
this.username_ = username;
this.thumber_ = imageMeta ? new cam.Thumber.fromImageMeta(imageMeta) : null;
};
cam.BlobItemTwitterContent.Handler.prototype.getAspectRatio = function() {
return 1.0;
};
cam.BlobItemTwitterContent.Handler.prototype.createContent = function(size) {
return cam.BlobItemTwitterContent({
content: this.content_,
date: this.date_,
href: this.href_,
image: this.thumber_ ? this.thumber_.getSrc(size) : null,
size: size,
username: this.username_,
});
};

View File

@ -0,0 +1,47 @@
/*
Copyright 2014 The Camlistore Authors
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.provide('cam.dateUtils');
cam.dateUtils.formatDateShort = function(date) {
// TODO(aa): Do something better based on Closure date/i18n utils.
// I think I would prefer this to return (in en-us) either '11:18 PM', 'Jun 11', or 'June 11 1952', depending on how far back it is. I don't find '5 hours ago' that useful.
var seconds = Math.floor((Date.now() - date) / 1000);
var interval = Math.floor(seconds / 31536000);
return (function() {
if (interval > 1) {
return interval + ' years';
}
interval = Math.floor(seconds / 2592000);
if (interval > 1) {
return interval + ' months';
}
interval = Math.floor(seconds / 86400);
if (interval > 1) {
return interval + ' days';
}
interval = Math.floor(seconds / 3600);
if (interval > 1) {
return interval + ' hours';
}
interval = Math.floor(seconds / 60);
if (interval > 1) {
return interval + ' minutes';
}
return Math.floor(seconds) + ' seconds';
})() + ' ago';
};

View File

@ -40,6 +40,7 @@ limitations under the License.
<link rel="stylesheet" href="blob_item_video.css" type="text/css">
<link rel="stylesheet" href="blob_item_container.css" type="text/css">
<link rel="stylesheet" href="blob_item_foursquare.css" type="text/css">
<link rel="stylesheet" href="blob_item_twitter.css" type="text/css">
<link rel="stylesheet" href="detail.css" type="text/css">
<link rel="stylesheet" href="index.css" type="text/css">
<link rel="stylesheet" href="nav.css" type="text/css">

View File

@ -26,11 +26,12 @@ goog.require('goog.Uri');
goog.require('cam.BlobDetail');
goog.require('cam.BlobItemContainerReact');
goog.require('cam.BlobItemDemoContent');
goog.require('cam.BlobItemFoursquareContent');
goog.require('cam.BlobItemGenericContent');
goog.require('cam.BlobItemVideoContent');
goog.require('cam.BlobItemImageContent');
goog.require('cam.BlobItemDemoContent');
goog.require('cam.BlobItemTwitterContent');
goog.require('cam.BlobItemVideoContent');
goog.require('cam.ContainerDetail');
goog.require('cam.DetailView');
goog.require('cam.DirectoryDetail');
@ -53,12 +54,14 @@ cam.IndexPage = React.createClass({
RAW: 'raw'
},
// Note that these are ordered by priority.
BLOB_ITEM_HANDLERS_: [
cam.BlobItemDemoContent.getHandler,
cam.BlobItemFoursquareContent.getHandler,
cam.BlobItemTwitterContent.getHandler,
cam.BlobItemImageContent.getHandler,
cam.BlobItemVideoContent.getHandler,
cam.BlobItemGenericContent.getHandler // must be last
cam.BlobItemGenericContent.getHandler
],
propTypes: {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB