From aac00db16b818d8c713a27de1fcb77179e31a9c5 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 27 Oct 2015 01:39:19 +0000 Subject: [PATCH] WIP for new lightbox viewer --- src/DateUtils.js | 45 ++++++++ src/skins/vector/css/atoms/ImageView.css | 109 ++++++++++++++++++ src/skins/vector/css/common.css | 8 +- .../vector/css/molecules/EventAsTextTile.css | 19 +++ src/skins/vector/css/molecules/EventTile.css | 5 + src/skins/vector/views/atoms/ImageView.js | 37 +++++- .../vector/views/atoms/MessageTimestamp.js | 28 +---- .../vector/views/molecules/MImageTile.js | 3 +- 8 files changed, 222 insertions(+), 32 deletions(-) create mode 100644 src/DateUtils.js create mode 100644 src/skins/vector/css/atoms/ImageView.css create mode 100644 src/skins/vector/css/molecules/EventAsTextTile.css diff --git a/src/DateUtils.js b/src/DateUtils.js new file mode 100644 index 0000000000..fe363586ab --- /dev/null +++ b/src/DateUtils.js @@ -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()); + } + } +} + diff --git a/src/skins/vector/css/atoms/ImageView.css b/src/skins/vector/css/atoms/ImageView.css new file mode 100644 index 0000000000..b9c357daee --- /dev/null +++ b/src/skins/vector/css/atoms/ImageView.css @@ -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; +} diff --git a/src/skins/vector/css/common.css b/src/skins/vector/css/common.css index 3b63aeaf31..f72aa8e67b 100644 --- a/src/skins/vector/css/common.css +++ b/src/skins/vector/css/common.css @@ -125,7 +125,7 @@ a:visited { font-size: 16px; position: relative; border-radius: 8px; - max-width: 75%; + max-width: 80%; } .mx_Dialog_lightbox .mx_Dialog_background { @@ -134,7 +134,11 @@ a:visited { .mx_Dialog_lightbox .mx_Dialog { border-radius: 0px; - background-color: #000; + background-color: transparent; + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; } .mx_Dialog_content { diff --git a/src/skins/vector/css/molecules/EventAsTextTile.css b/src/skins/vector/css/molecules/EventAsTextTile.css new file mode 100644 index 0000000000..d18fdc809c --- /dev/null +++ b/src/skins/vector/css/molecules/EventAsTextTile.css @@ -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; +} diff --git a/src/skins/vector/css/molecules/EventTile.css b/src/skins/vector/css/molecules/EventTile.css index ee3f79f30c..aa8d26f5af 100644 --- a/src/skins/vector/css/molecules/EventTile.css +++ b/src/skins/vector/css/molecules/EventTile.css @@ -66,6 +66,11 @@ limitations under the License. opacity: 0.5; } +.mx_MessageTile_content { + display: block; + margin-right: 100px; +} + .mx_EventTile_sending { color: #ddd; } diff --git a/src/skins/vector/views/atoms/ImageView.js b/src/skins/vector/views/atoms/ImageView.js index a0d69bcc03..7ef0f750ff 100644 --- a/src/skins/vector/views/atoms/ImageView.js +++ b/src/skins/vector/views/atoms/ImageView.js @@ -19,6 +19,8 @@ limitations under the License. var React = require('react'); var ImageViewController = require('../../../../controllers/atoms/ImageView') +var DateUtils = require('../../../../DateUtils'); +var filesize = require('filesize'); module.exports = React.createClass({ displayName: 'ImageView', @@ -43,8 +45,10 @@ module.exports = React.createClass({ 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 height = this.props.height || 500; @@ -68,9 +72,36 @@ module.exports = React.createClass({ width: displayWidth, height: displayHeight }; +*/ + var style; return ( - +
+
+
+
+ +
+
+ { this.props.mxEvent.getContent().body } +
+
+ Uploaded on { DateUtils.formatDate(new Date(this.props.mxEvent.getTs())) } by { this.props.mxEvent.getSender() } +
+
+ Download this file ({ filesize(this.props.mxEvent.getContent().info.size) }) +
+
+ View full screen +
+
+ Redact +
+
+
+
+
+
); } }); diff --git a/src/skins/vector/views/atoms/MessageTimestamp.js b/src/skins/vector/views/atoms/MessageTimestamp.js index a357ec237e..71951f3a28 100644 --- a/src/skins/vector/views/atoms/MessageTimestamp.js +++ b/src/skins/vector/views/atoms/MessageTimestamp.js @@ -17,43 +17,19 @@ limitations under the License. 'use strict'; var React = require('react'); +var DateUtils = require('../../../../DateUtils'); 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({ displayName: 'MessageTimestamp', 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() { var date = new Date(this.props.ts); return ( - { this.formatDate(date) } + { DateUtils.formatDate(date) } ); }, diff --git a/src/skins/vector/views/molecules/MImageTile.js b/src/skins/vector/views/molecules/MImageTile.js index 7984921d4e..f553383028 100644 --- a/src/skins/vector/views/molecules/MImageTile.js +++ b/src/skins/vector/views/molecules/MImageTile.js @@ -60,7 +60,8 @@ module.exports = React.createClass({ Modal.createDialog(ImageView, { src: httpUrl, width: content.info.w, - height: content.info.h + height: content.info.h, + mxEvent: this.props.mxEvent, }, "mx_Dialog_lightbox"); } },