From 804af341ac4f929329d51e60d5c35fa2ba6391f1 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 5 Nov 2015 14:52:44 +0000 Subject: [PATCH 1/4] Add a 'connection lost' bar. --- src/controllers/organisms/RoomView.js | 9 ++++++++ src/skins/vector/css/organisms/RoomView.css | 24 ++++++++++++++++++++ src/skins/vector/views/organisms/RoomView.js | 19 +++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js index f5a8d28f..15d67b15 100644 --- a/src/controllers/organisms/RoomView.js +++ b/src/controllers/organisms/RoomView.js @@ -41,6 +41,7 @@ module.exports = { draggingFile: false, searching: false, searchResults: null, + syncState: MatrixClientPeg.get().getSyncState() } }, @@ -50,6 +51,7 @@ module.exports = { MatrixClientPeg.get().on("Room.name", this.onRoomName); MatrixClientPeg.get().on("RoomMember.typing", this.onRoomMemberTyping); MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember); + MatrixClientPeg.get().on("sync", this.onSyncStateChange); this.atBottom = true; }, @@ -67,6 +69,7 @@ module.exports = { MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); MatrixClientPeg.get().removeListener("RoomMember.typing", this.onRoomMemberTyping); MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); + MatrixClientPeg.get().removeListener("sync", this.onSyncStateChange); } }, @@ -102,6 +105,12 @@ module.exports = { } }, + onSyncStateChange: function(state) { + this.setState({ + syncState: state + }); + }, + // MatrixRoom still showing the messages from the old room? // Set the key to the room_id. Sadly you can no longer get at // the key from inside the component, or we'd check this in code. diff --git a/src/skins/vector/css/organisms/RoomView.css b/src/skins/vector/css/organisms/RoomView.css index d564b086..961a7945 100644 --- a/src/skins/vector/css/organisms/RoomView.css +++ b/src/skins/vector/css/organisms/RoomView.css @@ -185,6 +185,30 @@ limitations under the License. vertical-align: middle; } +.mx_RoomView_connectionLostBar { + margin-top: 5px; +} + +.mx_RoomView_connectionLostBar img { + padding-left: 10px; + padding-right: 22px; + vertical-align: middle; + float: left; +} + +.mx_RoomView_connectionLostBar_textArea { + float: left; +} + +.mx_RoomView_connectionLostBar_title { + color: #f00; +} + +.mx_RoomView_connectionLostBar_desc { + color: #ddd; + font-size: 12px; +} + .mx_RoomView_typingBar { margin-top: 10px; margin-left: 54px; diff --git a/src/skins/vector/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js index 4f15ea61..86b200cf 100644 --- a/src/skins/vector/views/organisms/RoomView.js +++ b/src/skins/vector/views/organisms/RoomView.js @@ -197,9 +197,26 @@ module.exports = React.createClass({ } else { var typingString = this.getWhoIsTypingString(); var unreadMsgs = this.getUnreadMessagesString(); + // no conn bar trumps unread count since you can't get unread messages + // without a connection! (technically may already have some but meh) + if (this.state.syncState === "ERROR") { + statusBar = ( +
+ +
+ + Internet connection has been lost. + +
+ Sent messages will be stored until your connection has resumed. +
+
+
+ ); + } // unread count trumps who is typing since the unread count is only // set when you've scrolled up - if (unreadMsgs) { + else if (unreadMsgs) { statusBar = (
From 3a8c263e8e1927caf1aa4609fe08c0f93156853d Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 5 Nov 2015 15:59:03 +0000 Subject: [PATCH 2/4] Add resending bar (and resend all option) Factor out resend logic which was in the context menu into a separate Resend file (it shouldn't be in the skin, but it also isn't really suitable for a controller given 2 different views invoke it..) --- src/Resend.js | 24 +++++++++++++++ src/controllers/organisms/RoomView.js | 30 +++++++++++++++++-- src/skins/vector/css/organisms/RoomView.css | 4 +++ .../views/molecules/MessageContextMenu.js | 16 ++-------- src/skins/vector/views/organisms/RoomView.js | 20 +++++++++++++ 5 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 src/Resend.js diff --git a/src/Resend.js b/src/Resend.js new file mode 100644 index 00000000..52b7c936 --- /dev/null +++ b/src/Resend.js @@ -0,0 +1,24 @@ +var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); +var dis = require('matrix-react-sdk/lib/dispatcher'); + +module.exports = { + resend: function(event) { + MatrixClientPeg.get().resendEvent( + event, MatrixClientPeg.get().getRoom(event.getRoomId()) + ).done(function() { + dis.dispatch({ + action: 'message_sent', + event: event + }); + }, function() { + dis.dispatch({ + action: 'message_send_failed', + event: event + }); + }); + dis.dispatch({ + action: 'message_resend_started', + event: event + }); + }, +}; \ No newline at end of file diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js index 15d67b15..1324e21f 100644 --- a/src/controllers/organisms/RoomView.js +++ b/src/controllers/organisms/RoomView.js @@ -24,6 +24,7 @@ var Modal = require("matrix-react-sdk/lib/Modal"); var sdk = require('matrix-react-sdk/lib/index'); var CallHandler = require('matrix-react-sdk/lib/CallHandler'); var VectorConferenceHandler = require('../../modules/VectorConferenceHandler'); +var Resend = require("../../Resend"); var dis = require("matrix-react-sdk/lib/dispatcher"); @@ -32,8 +33,9 @@ var INITIAL_SIZE = 20; module.exports = { getInitialState: function() { + var room = this.props.roomId ? MatrixClientPeg.get().getRoom(this.props.roomId) : null; return { - room: this.props.roomId ? MatrixClientPeg.get().getRoom(this.props.roomId) : null, + room: room, messageCap: INITIAL_SIZE, editingRoomSettings: false, uploadingRoomSettings: false, @@ -41,7 +43,8 @@ module.exports = { draggingFile: false, searching: false, searchResults: null, - syncState: MatrixClientPeg.get().getSyncState() + syncState: MatrixClientPeg.get().getSyncState(), + hasUnsentMessages: this._hasUnsentMessages(room) } }, @@ -77,6 +80,9 @@ module.exports = { switch (payload.action) { case 'message_send_failed': case 'message_sent': + this.setState({ + hasUnsentMessages: this._hasUnsentMessages(this.state.room) + }); case 'message_resend_started': this.setState({ room: MatrixClientPeg.get().getRoom(this.props.roomId) @@ -182,6 +188,19 @@ module.exports = { this._updateConfCallNotification(); }, + _hasUnsentMessages: function(room) { + return this._getUnsentMessages(room).length > 0; + }, + + _getUnsentMessages: function(room) { + if (!room) { return []; } + // TODO: It would be nice if the JS SDK provided nicer constant-time + // constructs rather than O(N) (N=num msgs) on this. + return room.timeline.filter(function(ev) { + return ev.status === Matrix.EventStatus.NOT_SENT; + }); + }, + _updateConfCallNotification: function() { var room = MatrixClientPeg.get().getRoom(this.props.roomId); if (!room) return; @@ -274,6 +293,13 @@ module.exports = { return false; }, + onResendAllClick: function() { + var eventsToResend = this._getUnsentMessages(this.state.room); + eventsToResend.forEach(function(event) { + Resend.resend(event); + }); + }, + onJoinButtonClicked: function(ev) { var self = this; MatrixClientPeg.get().joinRoom(this.props.roomId).then(function() { diff --git a/src/skins/vector/css/organisms/RoomView.css b/src/skins/vector/css/organisms/RoomView.css index 961a7945..0379a2aa 100644 --- a/src/skins/vector/css/organisms/RoomView.css +++ b/src/skins/vector/css/organisms/RoomView.css @@ -209,6 +209,10 @@ limitations under the License. font-size: 12px; } +.mx_RoomView_resend_link { + cursor: pointer; +} + .mx_RoomView_typingBar { margin-top: 10px; margin-left: 54px; diff --git a/src/skins/vector/views/molecules/MessageContextMenu.js b/src/skins/vector/views/molecules/MessageContextMenu.js index 995c2c4b..b36d4ccb 100644 --- a/src/skins/vector/views/molecules/MessageContextMenu.js +++ b/src/skins/vector/views/molecules/MessageContextMenu.js @@ -22,25 +22,13 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); var dis = require('matrix-react-sdk/lib/dispatcher'); var sdk = require('matrix-react-sdk') var Modal = require('matrix-react-sdk/lib/Modal'); +var Resend = require("../../../../Resend"); module.exports = React.createClass({ displayName: 'MessageContextMenu', onResendClick: function() { - MatrixClientPeg.get().resendEvent( - this.props.mxEvent, MatrixClientPeg.get().getRoom( - this.props.mxEvent.getRoomId() - ) - ).done(function() { - dis.dispatch({ - action: 'message_sent' - }); - }, function() { - dis.dispatch({ - action: 'message_send_failed' - }); - }); - dis.dispatch({action: 'message_resend_started'}); + Resend.resend(this.props.mxEvent); if (this.props.onFinished) this.props.onFinished(); }, diff --git a/src/skins/vector/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js index 86b200cf..1eda7b7f 100644 --- a/src/skins/vector/views/organisms/RoomView.js +++ b/src/skins/vector/views/organisms/RoomView.js @@ -199,6 +199,8 @@ module.exports = React.createClass({ var unreadMsgs = this.getUnreadMessagesString(); // no conn bar trumps unread count since you can't get unread messages // without a connection! (technically may already have some but meh) + // It also trumps the "some not sent" msg since you can't resend without + // a connection! if (this.state.syncState === "ERROR") { statusBar = (
@@ -214,6 +216,24 @@ module.exports = React.createClass({
); } + else if (this.state.hasUnsentMessages) { + statusBar = ( +
+ +
+ + Some of your messages have not been sent. + +
+ + Resend all now + or select individual messages to re-send. +
+
+
+ ); + } // unread count trumps who is typing since the unread count is only // set when you've scrolled up else if (unreadMsgs) { From 615879ffddde97b3d3aa4343ebffaa8686f4f8fd Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 9 Nov 2015 00:13:25 +0000 Subject: [PATCH 3/4] skin to match CSS (spacing will need to be fixed once matthew/ordered-roomlist lands) --- src/skins/vector/css/molecules/EventTile.css | 2 +- src/skins/vector/css/organisms/RoomView.css | 21 +++++++++-------- src/skins/vector/views/organisms/RoomView.js | 24 ++++++++++---------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/skins/vector/css/molecules/EventTile.css b/src/skins/vector/css/molecules/EventTile.css index eb59711e..f9c8551b 100644 --- a/src/skins/vector/css/molecules/EventTile.css +++ b/src/skins/vector/css/molecules/EventTile.css @@ -78,7 +78,7 @@ limitations under the License. } .mx_EventTile_notSent { - color: #f11; + color: #ddd; } .mx_EventTile_highlight { diff --git a/src/skins/vector/css/organisms/RoomView.css b/src/skins/vector/css/organisms/RoomView.css index 0379a2aa..508e3457 100644 --- a/src/skins/vector/css/organisms/RoomView.css +++ b/src/skins/vector/css/organisms/RoomView.css @@ -158,13 +158,14 @@ limitations under the License. order: 4; width: 100%; - -webkit-flex: 0 0 36px; - flex: 0 0 36px; + -webkit-flex: 0 0 auto; + flex: 0 0 auto; } .mx_RoomView_statusAreaBox { max-width: 960px; margin: auto; + min-height: 36px; } .mx_RoomView_statusAreaBox_line { @@ -186,7 +187,8 @@ limitations under the License. } .mx_RoomView_connectionLostBar { - margin-top: 5px; + margin-top: 19px; + height: 58px; } .mx_RoomView_connectionLostBar img { @@ -196,20 +198,19 @@ limitations under the License. float: left; } -.mx_RoomView_connectionLostBar_textArea { - float: left; -} - .mx_RoomView_connectionLostBar_title { - color: #f00; + color: #ff0064; } .mx_RoomView_connectionLostBar_desc { - color: #ddd; - font-size: 12px; + color: #454545; + font-size: 14px; + opacity: 0.5; } .mx_RoomView_resend_link { + color: #454545 ! important; + text-decoration: underline ! important; cursor: pointer; } diff --git a/src/skins/vector/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js index 1eda7b7f..c07a890c 100644 --- a/src/skins/vector/views/organisms/RoomView.js +++ b/src/skins/vector/views/organisms/RoomView.js @@ -204,13 +204,13 @@ module.exports = React.createClass({ if (this.state.syncState === "ERROR") { statusBar = (
- + /!\
- - Internet connection has been lost. - +
+ Connectivity to the server has been lost. +
- Sent messages will be stored until your connection has resumed. + Sent messages will be stored until your connection has returned.
@@ -219,16 +219,16 @@ module.exports = React.createClass({ else if (this.state.hasUnsentMessages) { statusBar = (
- + /!\
- - Some of your messages have not been sent. - +
+ Some of your messages have not been sent. +
- + Resend all now - or select individual messages to re-send. + or select individual messages to re-send.
From eaa2f94327ef60c3fe622f2837a6ae14ee1d8344 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 9 Nov 2015 00:13:40 +0000 Subject: [PATCH 4/4] warning png --- src/skins/vector/img/warning2.png | Bin 0 -> 1420 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/skins/vector/img/warning2.png diff --git a/src/skins/vector/img/warning2.png b/src/skins/vector/img/warning2.png new file mode 100644 index 0000000000000000000000000000000000000000..db0fd4a897de34f13f949afd4f3c73a6c48f3b4e GIT binary patch literal 1420 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1SGcvS$+jlk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuU%v{0TQqR!T z+}y-mN5ROz&{W^RSl`${*T~q)#K6kLNC66zfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7I$IMft0d=ry1 z^FV@{U|qhxR-SpqC5d^-sh%#jN= z1y1vzdQ)(_#S*7peV}9XLD7p8-7q0w8Uiuli5JL$C;!wuV45!iCT{(x|F0Ps7=L-X zIEGZ*dNa*d$2m~s_SoMzdN8xUwIh7pTfGyvAAD)s&8vFh%JCDgmwn`zK21^9%rB|YEW#l1 z$EpyYChZuxj8-xE2}P2hCOh@oY9IdJvM{`F<3F+8JZ7fXc3)KI=U=((=JUy-zU^z~ zRK53@I7^~RKKf8su{zuK`YySvj~~2RJ!z5B+i#V3ezq=_XU>@W)MNVL=6j(JGrp?n z>Ubf@n;VF)s zit7I71I~VM-hTGrca1ftdfz^JFp0bNT|-*?%{V9h-3%pR%VZfemhaSxzssQ3!*YL8 z0AJ1>;oA6YH&?xb*}H^%C+#qr5fbt0K!KRx+ADSIA|K@^vuu79^d!|`R@);PrCIAD zqm+ezec;M|qLs6)ReHPKwx55tY!OnvbvD>+_Tt(T(G&d>kDU58^B&K9`I8|gR*kC< z%vzWD$VR|bpnJdSl5HF_U+%X(CVg6As)4TEZtWEpy1waH6hCl1aaFz5$x$tf>tc-N j2bcf*ZI3#|u}Uyh-(Gi7sw~YCR6csT`njxgN@xNAYH|*X literal 0 HcmV?d00001