WIP for new lightbox viewer

This commit is contained in:
Matthew Hodgson 2015-10-27 01:39:19 +00:00
parent 7c445cc108
commit aac00db16b
8 changed files with 222 additions and 32 deletions

45
src/DateUtils.js Normal file
View File

@ -0,0 +1,45 @@
/*
Copyright 2015 OpenMarket Ltd
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.
*/
'use strict';
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
module.exports = {
formatDate: function(date) {
// date.toLocaleTimeString is completely system dependent.
// just go 24h for now
function pad(n) {
return (n < 10 ? '0' : '') + n;
}
var now = new Date();
if (date.toDateString() === now.toDateString()) {
return pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else if (now.getTime() - date.getTime() < 6 * 24 * 60 * 60 * 1000) {
return days[date.getDay()] + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else if (now.getFullYear() === date.getFullYear()) {
return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else {
return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + date.getFullYear() + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
}
}

View File

@ -0,0 +1,109 @@
/*
Copyright 2015 OpenMarket Ltd
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.
*/
/* This has got to be the most fragile piece of CSS ever written.
But empirically it works on Chrome/FF/Safari
*/
.mx_ImageView {
display: -webkit-flex;
display: flex;
width: 100%;
height: 100%;
-webkit-align-items: center;
align-items: center;
}
.mx_ImageView_lhs {
-webkit-box-ordinal-group: 1;
order: 1;
-webkit-flex: 1;
flex: 1 1 0;
min-width: 60px;
}
.mx_ImageView_content {
-webkit-box-ordinal-group: 2;
order: 2;
/* min-width hack needed for FF */
min-width: 0px;
height: 90%;
-webkit-flex: 5;
flex: 5 5 0;
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
-webkit-justify-content: center;
align-items: center;
justify-content: center;
}
.mx_ImageView_content img {
max-width: 100%;
/* can't use max-height as it interacts badly with flex on Chrome and doesn't relayout properly until you refresh */
height: 100%;
/* object-fit hack needed for Chrome */
object-fit: contain;
}
.mx_ImageView_label {
text-align: left;
display: inline-block;
width: 300px;
height: 300px;
top: 50%;
margin-top: -150px;
position: absolute;
color: #fff;
padding: 60px;
}
.mx_ImageView_name {
font-size: 20px;
margin-bottom: 6px;
}
.mx_ImageView_metadata {
font-size: 16px;
opacity: 0.5;
}
.mx_ImageView_download {
display: inline-block;
margin-top: 28px;
border-radius: 5px;
background-color: #454545;
font-size: 16px;
padding: 9px;
border: 1px solid #fff;
cursor: pointer;
}
.mx_ImageView_button {
font-size: 16px;
opacity: 0.5;
margin-top: 24px;
cursor: pointer;
}
.mx_ImageView_rhs {
-webkit-box-ordinal-group: 3;
order: 3;
-webkit-flex: 1;
flex: 1 1 0;
min-width: 300px;
}

View File

@ -125,7 +125,7 @@ a:visited {
font-size: 16px; font-size: 16px;
position: relative; position: relative;
border-radius: 8px; border-radius: 8px;
max-width: 75%; max-width: 80%;
} }
.mx_Dialog_lightbox .mx_Dialog_background { .mx_Dialog_lightbox .mx_Dialog_background {
@ -134,7 +134,11 @@ a:visited {
.mx_Dialog_lightbox .mx_Dialog { .mx_Dialog_lightbox .mx_Dialog {
border-radius: 0px; border-radius: 0px;
background-color: #000; background-color: transparent;
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
} }
.mx_Dialog_content { .mx_Dialog_content {

View File

@ -0,0 +1,19 @@
/*
Copyright 2015 OpenMarket Ltd
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.
*/
.mx_EventAsTextTile {
opacity: 0.5;
}

View File

@ -66,6 +66,11 @@ limitations under the License.
opacity: 0.5; opacity: 0.5;
} }
.mx_MessageTile_content {
display: block;
margin-right: 100px;
}
.mx_EventTile_sending { .mx_EventTile_sending {
color: #ddd; color: #ddd;
} }

View File

@ -19,6 +19,8 @@ limitations under the License.
var React = require('react'); var React = require('react');
var ImageViewController = require('../../../../controllers/atoms/ImageView') var ImageViewController = require('../../../../controllers/atoms/ImageView')
var DateUtils = require('../../../../DateUtils');
var filesize = require('filesize');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'ImageView', displayName: 'ImageView',
@ -43,8 +45,10 @@ module.exports = React.createClass({
render: function() { render: function() {
// XXX: can't we just do max-width: 80%, max-height: 80% on the CSS? /*
// In theory max-width: 80%, max-height: 80% on the CSS should work
// but in practice, it doesn't, so do it manually:
var width = this.props.width || 500; var width = this.props.width || 500;
var height = this.props.height || 500; var height = this.props.height || 500;
@ -68,9 +72,36 @@ module.exports = React.createClass({
width: displayWidth, width: displayWidth,
height: displayHeight height: displayHeight
}; };
*/
var style;
return ( return (
<img className="mx_ImageView" src={this.props.src} style={style} /> <div className="mx_ImageView">
<div className="mx_ImageView_lhs">
</div>
<div className="mx_ImageView_content">
<img src={this.props.src} style={style}/>
<div className="mx_ImageView_label">
<div className="mx_ImageView_name">
{ this.props.mxEvent.getContent().body }
</div>
<div className="mx_ImageView_metadata">
Uploaded on { DateUtils.formatDate(new Date(this.props.mxEvent.getTs())) } by { this.props.mxEvent.getSender() }
</div>
<div className="mx_ImageView_download">
Download this file ({ filesize(this.props.mxEvent.getContent().info.size) })
</div>
<div className="mx_ImageView_button">
View full screen
</div>
<div className="mx_ImageView_button">
Redact
</div>
</div>
</div>
<div className="mx_ImageView_rhs">
</div>
</div>
); );
} }
}); });

View File

@ -17,43 +17,19 @@ limitations under the License.
'use strict'; 'use strict';
var React = require('react'); var React = require('react');
var DateUtils = require('../../../../DateUtils');
var MessageTimestampController = require('matrix-react-sdk/lib/controllers/atoms/MessageTimestamp') var MessageTimestampController = require('matrix-react-sdk/lib/controllers/atoms/MessageTimestamp')
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MessageTimestamp', displayName: 'MessageTimestamp',
mixins: [MessageTimestampController], mixins: [MessageTimestampController],
formatDate: function(date) {
// date.toLocaleTimeString is completely system dependent.
// just go 24h for now
function pad(n) {
return (n < 10 ? '0' : '') + n;
}
var now = new Date();
if (date.toDateString() === now.toDateString()) {
return pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else if (now.getTime() - date.getTime() < 6 * 24 * 60 * 60 * 1000) {
return days[date.getDay()] + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else if (now.getFullYear() === date.getFullYear()) {
return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
else {
return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + date.getFullYear() + " " + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
},
render: function() { render: function() {
var date = new Date(this.props.ts); var date = new Date(this.props.ts);
return ( return (
<span className="mx_MessageTimestamp"> <span className="mx_MessageTimestamp">
{ this.formatDate(date) } { DateUtils.formatDate(date) }
</span> </span>
); );
}, },

View File

@ -60,7 +60,8 @@ module.exports = React.createClass({
Modal.createDialog(ImageView, { Modal.createDialog(ImageView, {
src: httpUrl, src: httpUrl,
width: content.info.w, width: content.info.w,
height: content.info.h height: content.info.h,
mxEvent: this.props.mxEvent,
}, "mx_Dialog_lightbox"); }, "mx_Dialog_lightbox");
} }
}, },