From 1f3a6e408c0f262e2b5182fa8e883d1a45ab6544 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 21 Oct 2015 17:52:34 +0100 Subject: [PATCH] Factor out stuff commnon to all timeline events into EventTile: makes timestamp & edit button etc appear on everything, not just messages. --- src/controllers/organisms/RoomView.js | 22 ++- .../{MessageTile.css => EventTile.css} | 37 ++--- src/skins/vector/skindex.js | 1 + .../vector/views/molecules/EventAsTextTile.js | 11 +- src/skins/vector/views/molecules/EventTile.js | 131 ++++++++++++++++++ .../vector/views/molecules/MessageTile.js | 72 +--------- 6 files changed, 163 insertions(+), 111 deletions(-) rename src/skins/vector/css/molecules/{MessageTile.css => EventTile.css} (70%) create mode 100644 src/skins/vector/views/molecules/EventTile.js diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js index 29933d4ad8..77359c8f5c 100644 --- a/src/controllers/organisms/RoomView.js +++ b/src/controllers/organisms/RoomView.js @@ -356,23 +356,20 @@ module.exports = { }, getEventTiles: function() { - var tileTypes = { - 'm.room.message': sdk.getComponent('molecules.MessageTile'), - 'm.room.member' : sdk.getComponent('molecules.EventAsTextTile'), - 'm.call.invite' : sdk.getComponent('molecules.EventAsTextTile'), - 'm.call.answer' : sdk.getComponent('molecules.EventAsTextTile'), - 'm.call.hangup' : sdk.getComponent('molecules.EventAsTextTile'), - 'm.room.topic' : sdk.getComponent('molecules.EventAsTextTile'), - }; - var DateSeparator = sdk.getComponent('molecules.DateSeparator'); var ret = []; var count = 0; + var EventTile = sdk.getComponent('molecules.EventTile'); + for (var i = this.state.room.timeline.length-1; i >= 0 && count < this.state.messageCap; --i) { var mxEv = this.state.room.timeline[i]; - var TileType = tileTypes[mxEv.getType()]; + + if (!EventTile.supportsEventType(mxEv.getType())) { + continue; + } + var continuation = false; var last = false; var dateSeparator = null; @@ -401,13 +398,12 @@ module.exports = { if (i === 1) { // n.b. 1, not 0, as the 0th event is an m.room.create and so doesn't show on the timeline var ts1 = this.state.room.timeline[i].getTs(); - dateSeparator = ; + dateSeparator =
  • ; continuation = false; } - if (!TileType) continue; ret.unshift( -
  • +
  • ); if (dateSeparator) { ret.unshift(dateSeparator); diff --git a/src/skins/vector/css/molecules/MessageTile.css b/src/skins/vector/css/molecules/EventTile.css similarity index 70% rename from src/skins/vector/css/molecules/MessageTile.css rename to src/skins/vector/css/molecules/EventTile.css index 0732481941..1cd2fa465f 100644 --- a/src/skins/vector/css/molecules/MessageTile.css +++ b/src/skins/vector/css/molecules/EventTile.css @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_MessageTile { +.mx_EventTile { max-width: 100%; clear: both; margin-top: 32px; margin-left: 56px; } -.mx_MessageTile_avatar { +.mx_EventTile_avatar { padding-left: 12px; padding-right: 12px; margin-left: -64px; @@ -29,17 +29,17 @@ limitations under the License. float: left; } -.mx_MessageTile_avatar img { +.mx_EventTile_avatar img { background-color: #dbdbdb; border-radius: 20px; border: 0px; } -.mx_MessageTile_continuation { +.mx_EventTile_continuation { margin-top: 8px ! important; } -.mx_MessageTile .mx_SenderProfile { +.mx_EventTile .mx_SenderProfile { color: #454545; opacity: 0.5; font-size: 14px; @@ -47,35 +47,35 @@ limitations under the License. display: block; } -.mx_MessageTile .mx_MessageTimestamp { +.mx_EventTile .mx_MessageTimestamp { color: #454545; opacity: 0.5; font-size: 14px; float: right; } -.mx_MessageTile_content { +.mx_EventTile_content { padding-right: 100px; display: block; } -.mx_MessageTile_notice .mx_MessageTile_content { +.mx_EventTile_notice .mx_MessageTile_content { opacity: 0.5; } -.mx_MessageTile_sending { +.mx_EventTile_sending { color: #ddd; } -.mx_MessageTile_notSent { +.mx_EventTile_notSent { color: #f11; } -.mx_MessageTile_highlight { +.mx_EventTile_highlight { color: #FF0064; } -.mx_MessageTile_msgOption { +.mx_EventTile_msgOption { float: right; } @@ -83,29 +83,30 @@ limitations under the License. display: none; } -.mx_MessageTile_last .mx_MessageTimestamp { +.mx_EventTile_last .mx_MessageTimestamp { display: block; } -.mx_MessageTile:hover .mx_MessageTimestamp { +.mx_EventTile:hover .mx_MessageTimestamp { display: block; } -.mx_MessageTile_editButton { +.mx_EventTile_editButton { float: right; display: none; border: 0px; outline: none; + margin-right: 3px; } -.mx_MessageTile:hover .mx_MessageTile_editButton { +.mx_EventTile:hover .mx_EventTile_editButton { display: inline-block; } -.mx_MessageTile.menu .mx_MessageTile_editButton { +.mx_EventTile.menu .mx_EventTile_editButton { display: inline-block; } -.mx_MessageTile.menu .mx_MessageTimestamp { +.mx_EventTile.menu .mx_MessageTimestamp { display: inline-block; } diff --git a/src/skins/vector/skindex.js b/src/skins/vector/skindex.js index 7cd8361850..8dba10cf30 100644 --- a/src/skins/vector/skindex.js +++ b/src/skins/vector/skindex.js @@ -41,6 +41,7 @@ skin['molecules.ChangeDisplayName'] = require('./views/molecules/ChangeDisplayNa skin['molecules.ChangePassword'] = require('./views/molecules/ChangePassword'); skin['molecules.DateSeparator'] = require('./views/molecules/DateSeparator'); skin['molecules.EventAsTextTile'] = require('./views/molecules/EventAsTextTile'); +skin['molecules.EventTile'] = require('./views/molecules/EventTile'); skin['molecules.MatrixToolbar'] = require('./views/molecules/MatrixToolbar'); skin['molecules.MemberInfo'] = require('./views/molecules/MemberInfo'); skin['molecules.MemberTile'] = require('./views/molecules/MemberTile'); diff --git a/src/skins/vector/views/molecules/EventAsTextTile.js b/src/skins/vector/views/molecules/EventAsTextTile.js index e8beddf2dc..445303e4a1 100644 --- a/src/skins/vector/views/molecules/EventAsTextTile.js +++ b/src/skins/vector/views/molecules/EventAsTextTile.js @@ -36,15 +36,8 @@ module.exports = React.createClass({ var timestamp = this.props.last ? : null; var avatar = this.props.mxEvent.sender ? : null; return ( -
    -
    - { avatar } -
    - { timestamp } - - - {TextForEvent.textForEvent(this.props.mxEvent)} - +
    + {TextForEvent.textForEvent(this.props.mxEvent)}
    ); }, diff --git a/src/skins/vector/views/molecules/EventTile.js b/src/skins/vector/views/molecules/EventTile.js new file mode 100644 index 0000000000..b686ef15b6 --- /dev/null +++ b/src/skins/vector/views/molecules/EventTile.js @@ -0,0 +1,131 @@ +/* +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 React = require('react'); +var classNames = require("classnames"); + +var sdk = require('matrix-react-sdk') + +var EventTileController = require('matrix-react-sdk/lib/controllers/molecules/EventTile') +var ContextualMenu = require('../../../../ContextualMenu'); + +var eventTileTypes = { + 'm.room.message': 'molecules.MessageTile', + 'm.room.member' : 'molecules.EventAsTextTile', + 'm.call.invite' : 'molecules.EventAsTextTile', + 'm.call.answer' : 'molecules.EventAsTextTile', + 'm.call.hangup' : 'molecules.EventAsTextTile', + 'm.room.topic' : 'molecules.EventAsTextTile', +}; + +module.exports = React.createClass({ + displayName: 'EventTile', + mixins: [EventTileController], + + statics: { + supportsEventType: function(et) { + return eventTileTypes[et] !== undefined; + } + }, + + getInitialState: function() { + return {menu: false}; + }, + + onEditClicked: function(e) { + var MessageContextMenu = sdk.getComponent('molecules.MessageContextMenu'); + var buttonRect = e.target.getBoundingClientRect() + var x = window.innerWidth - buttonRect.left; + var y = buttonRect.top + (e.target.height / 2); + var self = this; + ContextualMenu.createMenu(MessageContextMenu, { + mxEvent: this.props.mxEvent, + right: x, + top: y, + onFinished: function() { + self.setState({menu: false}); + } + }); + this.setState({menu: true}); + }, + + render: function() { + var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp'); + var SenderProfile = sdk.getComponent('molecules.SenderProfile'); + var MemberAvatar = sdk.getComponent('atoms.MemberAvatar'); + + var UnknownMessageTile = sdk.getComponent('molecules.UnknownMessageTile'); + + var content = this.props.mxEvent.getContent(); + var msgtype = content.msgtype; + + var EventTileType = sdk.getComponent(eventTileTypes[this.props.mxEvent.getType()]); + // This shouldn't happen: the caller should check we support this type + // before trying to instantiate us + if (!EventTileType) { + return null; + } + + var classes = classNames({ + mx_EventTile: true, + mx_EventTile_sending: ['sending', 'queued'].indexOf( + this.props.mxEvent.status + ) !== -1, + mx_EventTile_notSent: this.props.mxEvent.status == 'not_sent', + mx_EventTile_highlight: this.shouldHighlight(), + mx_EventTile_continuation: this.props.continuation, + mx_EventTile_last: this.props.last, + menu: this.state.menu + }); + var timestamp = + var editButton = ( + + ); + + var aux = null; + if (msgtype === 'm.image') aux = "sent an image"; + else if (msgtype === 'm.video') aux = "sent a video"; + else if (msgtype === 'm.file') aux = "uploaded a file"; + + var avatar, sender; + if (!this.props.continuation) { + if (this.props.mxEvent.sender) { + avatar = ( +
    + +
    + ); + } + sender = ; + } + return ( +
    + { avatar } + { sender } +
    + { timestamp } + { editButton } + +
    +
    + ); + }, +}); diff --git a/src/skins/vector/views/molecules/MessageTile.js b/src/skins/vector/views/molecules/MessageTile.js index 425cc44b5e..5e83505029 100644 --- a/src/skins/vector/views/molecules/MessageTile.js +++ b/src/skins/vector/views/molecules/MessageTile.js @@ -28,28 +28,7 @@ module.exports = React.createClass({ displayName: 'MessageTile', mixins: [MessageTileController], - onEditClicked: function(e) { - var MessageContextMenu = sdk.getComponent('molecules.MessageContextMenu'); - var buttonRect = e.target.getBoundingClientRect() - var x = window.innerWidth - buttonRect.left; - var y = buttonRect.top + (e.target.height / 2); - var self = this; - ContextualMenu.createMenu(MessageContextMenu, { - mxEvent: this.props.mxEvent, - right: x, - top: y, - onFinished: function() { - self.setState({menu: false}); - } - }); - this.setState({menu: true}); - }, - render: function() { - var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp'); - var SenderProfile = sdk.getComponent('molecules.SenderProfile'); - var MemberAvatar = sdk.getComponent('atoms.MemberAvatar'); - var UnknownMessageTile = sdk.getComponent('molecules.UnknownMessageTile'); var tileTypes = { @@ -66,56 +45,7 @@ module.exports = React.createClass({ if (msgtype && tileTypes[msgtype]) { TileType = tileTypes[msgtype]; } - var classes = classNames({ - mx_MessageTile: true, - mx_MessageTile_sending: ['sending', 'queued'].indexOf( - this.props.mxEvent.status - ) !== -1, - mx_MessageTile_notSent: this.props.mxEvent.status == 'not_sent', - mx_MessageTile_highlight: this.shouldHighlight(), - mx_MessageTile_continuation: this.props.continuation, - mx_MessageTile_last: this.props.last, - menu: this.state.menu - }); - var timestamp = - var editButton = ( - - ); - var aux = null; - if (msgtype === 'm.image') aux = "sent an image"; - else if (msgtype === 'm.video') aux = "sent a video"; - else if (msgtype === 'm.file') aux = "uploaded a file"; - - var avatar, sender, resend; - if (!this.props.continuation) { - if (this.props.mxEvent.sender) { - avatar = ( -
    - -
    - ); - } - sender = ; - } - if (this.props.mxEvent.status === "not_sent" && !this.state.resending) { - resend = ; - } - return ( -
    - { avatar } - { sender } -
    - { timestamp } - { editButton } - -
    -
    - ); + return ; }, });