mirror of
				https://github.com/vector-im/element-web.git
				synced 2025-10-31 16:21:46 +01:00 
			
		
		
		
	Merge branch 'vector' of github.com:matrix-org/matrix-react-sdk into erikj/room_editing
This commit is contained in:
		
						commit
						813cf0481e
					
				| @ -51,3 +51,11 @@ limitations under the License. | |||||||
|     overflow: hidden; |     overflow: hidden; | ||||||
|     text-overflow: ellipsis; |     text-overflow: ellipsis; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .mx_MemberTile_unavailable { | ||||||
|  |     opacity: 0.75; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .mx_MemberTile_offline { | ||||||
|  |     opacity: 0.5; | ||||||
|  | } | ||||||
| @ -46,9 +46,21 @@ module.exports = React.createClass({ | |||||||
|             var img = "img/p/p" + Math.floor(20 * this.props.member.powerLevelNorm / 100) + ".png"; |             var img = "img/p/p" + Math.floor(20 * this.props.member.powerLevelNorm / 100) + ".png"; | ||||||
|             power = <img src={ img } className="mx_MemberTile_power" width="48" height="48" alt=""/>; |             power = <img src={ img } className="mx_MemberTile_power" width="48" height="48" alt=""/>; | ||||||
|         } |         } | ||||||
|  |         var presenceClass = "mx_MemberTile_offline"; | ||||||
|  |         var mainClassName = "mx_MemberTile "; | ||||||
|  |         if (this.props.member.user) { | ||||||
|  |             if (this.props.member.user.presence === "online") { | ||||||
|  |                 presenceClass = "mx_MemberTile_online"; | ||||||
|  |             } | ||||||
|  |             else if (this.props.member.user.presence === "unavailable") { | ||||||
|  |                 presenceClass = "mx_MemberTile_unavailable"; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         mainClassName += presenceClass; | ||||||
| 
 | 
 | ||||||
|         return ( |         return ( | ||||||
|             <div className="mx_MemberTile" onMouseEnter={ this.mouseEnter } onMouseLeave={ this.mouseLeave } > |             <div className={mainClassName} onMouseEnter={ this.mouseEnter } onMouseLeave={ this.mouseLeave } | ||||||
|  |             > | ||||||
|                 <div className="mx_MemberTile_avatar"> |                 <div className="mx_MemberTile_avatar"> | ||||||
|                     <img className="mx_MemberTile_avatarImg" |                     <img className="mx_MemberTile_avatarImg" | ||||||
|                          src={ this.props.member ? MatrixClientPeg.get().getAvatarUrlForMember(this.props.member, 40, 40, "crop") : null } |                          src={ this.props.member ? MatrixClientPeg.get().getAvatarUrlForMember(this.props.member, 40, 40, "crop") : null } | ||||||
|  | |||||||
| @ -47,7 +47,7 @@ module.exports = React.createClass({ | |||||||
|         return Object.keys(self.state.memberDict).map(function(userId) { |         return Object.keys(self.state.memberDict).map(function(userId) { | ||||||
|             var m = self.state.memberDict[userId]; |             var m = self.state.memberDict[userId]; | ||||||
|             return ( |             return ( | ||||||
|                 <MemberTile key={userId} member={m} /> |                 <MemberTile key={userId} member={m} ref={userId} /> | ||||||
|             ); |             ); | ||||||
|         }); |         }); | ||||||
|     }, |     }, | ||||||
|  | |||||||
| @ -116,6 +116,10 @@ function _setCallListeners(call) { | |||||||
|             _setCallState(call, call.roomId, "busy"); |             _setCallState(call, call.roomId, "busy"); | ||||||
|             pause("ringbackAudio"); |             pause("ringbackAudio"); | ||||||
|             play("busyAudio"); |             play("busyAudio"); | ||||||
|  |             Modal.createDialog(ErrorDialog, { | ||||||
|  |                 title: "Call Timeout", | ||||||
|  |                 description: "The remote side failed to pick up." | ||||||
|  |             }); | ||||||
|         } |         } | ||||||
|         else if (oldState === "invite_sent") { |         else if (oldState === "invite_sent") { | ||||||
|             _setCallState(call, call.roomId, "stop_ringback"); |             _setCallState(call, call.roomId, "stop_ringback"); | ||||||
|  | |||||||
| @ -22,18 +22,25 @@ var Matrix = require("matrix-js-sdk"); | |||||||
| var matrixClient = null; | var matrixClient = null; | ||||||
| 
 | 
 | ||||||
| var localStorage = window.localStorage; | var localStorage = window.localStorage; | ||||||
|  | 
 | ||||||
|  | function createClient(hs_url, is_url, user_id, access_token) { | ||||||
|  |     var opts = { | ||||||
|  |         baseUrl: hs_url, | ||||||
|  |         idBaseUrl: is_url, | ||||||
|  |         accessToken: access_token, | ||||||
|  |         userId: user_id | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     matrixClient = Matrix.createClient(opts); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| if (localStorage) { | if (localStorage) { | ||||||
|     var hs_url = localStorage.getItem("mx_hs_url"); |     var hs_url = localStorage.getItem("mx_hs_url"); | ||||||
|     var is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org'; |     var is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org'; | ||||||
|     var access_token = localStorage.getItem("mx_access_token"); |     var access_token = localStorage.getItem("mx_access_token"); | ||||||
|     var user_id = localStorage.getItem("mx_user_id"); |     var user_id = localStorage.getItem("mx_user_id"); | ||||||
|     if (access_token && user_id && hs_url) { |     if (access_token && user_id && hs_url) { | ||||||
|         matrixClient = Matrix.createClient({ |         createClient(hs_url, is_url, user_id, access_token); | ||||||
|             baseUrl: hs_url, |  | ||||||
|             idBaseUrl: is_url, |  | ||||||
|             accessToken: access_token, |  | ||||||
|             userId: user_id |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -42,8 +49,8 @@ module.exports = { | |||||||
|         return matrixClient; |         return matrixClient; | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     replace: function(cli) { |     unset: function() { | ||||||
|         matrixClient = cli; |         matrixClient = null; | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     replaceUsingUrls: function(hs_url, is_url) { |     replaceUsingUrls: function(hs_url, is_url) { | ||||||
| @ -51,6 +58,23 @@ module.exports = { | |||||||
|             baseUrl: hs_url, |             baseUrl: hs_url, | ||||||
|             idBaseUrl: is_url |             idBaseUrl: is_url | ||||||
|         }); |         }); | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     replaceUsingAccessToken: function(hs_url, is_url, user_id, access_token) { | ||||||
|  |         createClient(hs_url, is_url, user_id, access_token); | ||||||
|  |         if (localStorage) { | ||||||
|  |             try { | ||||||
|  |                 localStorage.clear(); | ||||||
|  |                 localStorage.setItem("mx_hs_url", hs_url); | ||||||
|  |                 localStorage.setItem("mx_is_url", is_url); | ||||||
|  |                 localStorage.setItem("mx_user_id", user_id); | ||||||
|  |                 localStorage.setItem("mx_access_token", access_token); | ||||||
|  |             } catch (e) { | ||||||
|  |                 console.warn("Error using local storage: can't persist session!"); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             console.warn("No local storage available: can't persist session!"); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										105
									
								
								src/Presence.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/Presence.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | |||||||
|  | /* | ||||||
|  | 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 MatrixClientPeg = require("./MatrixClientPeg"); | ||||||
|  | 
 | ||||||
|  |  // Time in ms after that a user is considered as unavailable/away
 | ||||||
|  | var UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
 | ||||||
|  | var PRESENCE_STATES = ["online", "offline", "unavailable"]; | ||||||
|  | 
 | ||||||
|  | // The current presence state
 | ||||||
|  | var state, timer; | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Start listening the user activity to evaluate his presence state. | ||||||
|  |      * Any state change will be sent to the Home Server. | ||||||
|  |      */ | ||||||
|  |     start: function() { | ||||||
|  |         var self = this; | ||||||
|  |         this.running = true; | ||||||
|  |         if (undefined === state) { | ||||||
|  |             // The user is online if they move the mouse or press a key
 | ||||||
|  |             document.onmousemove = function() { self._resetTimer(); }; | ||||||
|  |             document.onkeypress = function() { self._resetTimer(); }; | ||||||
|  |             this._resetTimer(); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Stop tracking user activity | ||||||
|  |      */ | ||||||
|  |     stop: function() { | ||||||
|  |         this.running = false; | ||||||
|  |         if (timer) { | ||||||
|  |             clearTimeout(timer); | ||||||
|  |             timer = undefined; | ||||||
|  |         } | ||||||
|  |         state = undefined; | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the current presence state. | ||||||
|  |      * @returns {string} the presence state (see PRESENCE enum) | ||||||
|  |      */ | ||||||
|  |     getState: function() { | ||||||
|  |         return state; | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Set the presence state. | ||||||
|  |      * If the state has changed, the Home Server will be notified. | ||||||
|  |      * @param {string} newState the new presence state (see PRESENCE enum) | ||||||
|  |      */ | ||||||
|  |     setState: function(newState) { | ||||||
|  |         if (newState === state) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (PRESENCE_STATES.indexOf(newState) === -1) { | ||||||
|  |             throw new Error("Bad presence state: " + newState); | ||||||
|  |         } | ||||||
|  |         if (!this.running) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         state = newState; | ||||||
|  |         MatrixClientPeg.get().setPresence(state).catch(function(err) { | ||||||
|  |             console.error("Failed to set presence: %s", err); | ||||||
|  |         }); | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Callback called when the user made no action on the page for UNAVAILABLE_TIME ms. | ||||||
|  |      * @private | ||||||
|  |      */ | ||||||
|  |     _onUnavailableTimerFire: function() { | ||||||
|  |         this.setState("unavailable"); | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Callback called when the user made an action on the page | ||||||
|  |      * @private | ||||||
|  |      */ | ||||||
|  |     _resetTimer: function() { | ||||||
|  |         var self = this; | ||||||
|  |         this.setState("online"); | ||||||
|  |         // Re-arm the timer
 | ||||||
|  |         clearTimeout(timer); | ||||||
|  |         timer = setTimeout(function() { | ||||||
|  |             self._onUnavailableTimerFire(); | ||||||
|  |         }, UNAVAILABLE_TIME_MS); | ||||||
|  |     }  | ||||||
|  | }; | ||||||
| @ -106,7 +106,7 @@ module.exports = { | |||||||
|                     // show the message
 |                     // show the message
 | ||||||
|                     this.element.value = this.data[this.position]; |                     this.element.value = this.data[this.position]; | ||||||
|                 } |                 } | ||||||
|                 else if (this.originalText) { |                 else if (this.originalText !== undefined) { | ||||||
|                     // restore the original text the user was typing.
 |                     // restore the original text the user was typing.
 | ||||||
|                     this.element.value = this.originalText; |                     this.element.value = this.originalText; | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -18,6 +18,9 @@ limitations under the License. | |||||||
| 
 | 
 | ||||||
| var React = require("react"); | var React = require("react"); | ||||||
| var MatrixClientPeg = require("../../MatrixClientPeg"); | var MatrixClientPeg = require("../../MatrixClientPeg"); | ||||||
|  | var Modal = require("../../Modal"); | ||||||
|  | var ComponentBroker = require('../../ComponentBroker'); | ||||||
|  | var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog"); | ||||||
| 
 | 
 | ||||||
| var INITIAL_LOAD_NUM_MEMBERS = 50; | var INITIAL_LOAD_NUM_MEMBERS = 50; | ||||||
| 
 | 
 | ||||||
| @ -37,6 +40,7 @@ module.exports = { | |||||||
|     componentWillUnmount: function() { |     componentWillUnmount: function() { | ||||||
|         if (MatrixClientPeg.get()) { |         if (MatrixClientPeg.get()) { | ||||||
|             MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); |             MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); | ||||||
|  |             MatrixClientPeg.get().removeListener("User.presence", this.userPresenceFn); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| @ -48,8 +52,19 @@ module.exports = { | |||||||
|                 memberDict: self.roomMembers() |                 memberDict: self.roomMembers() | ||||||
|             }); |             }); | ||||||
|         }, 50); |         }, 50); | ||||||
|     }, |  | ||||||
| 
 | 
 | ||||||
|  |         // Attach a SINGLE listener for global presence changes then locate the
 | ||||||
|  |         // member tile and re-render it. This is more efficient than every tile
 | ||||||
|  |         // evar attaching their own listener.
 | ||||||
|  |         function updateUserState(event, user) { | ||||||
|  |             var tile = self.refs[user.userId]; | ||||||
|  |             if (tile) { | ||||||
|  |                 tile.forceUpdate(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         MatrixClientPeg.get().on("User.presence", updateUserState); | ||||||
|  |         this.userPresenceFn = updateUserState; | ||||||
|  |     }, | ||||||
|     // Remember to set 'key' on a MemberList to the ID of the room it's for
 |     // Remember to set 'key' on a MemberList to the ID of the room it's for
 | ||||||
|     /*componentWillReceiveProps: function(newProps) { |     /*componentWillReceiveProps: function(newProps) { | ||||||
|     },*/ |     },*/ | ||||||
| @ -67,6 +82,10 @@ module.exports = { | |||||||
|         inputText = inputText.trim(); // react requires es5-shim so we know trim() exists
 |         inputText = inputText.trim(); // react requires es5-shim so we know trim() exists
 | ||||||
|         if (inputText[0] !== '@' || inputText.indexOf(":") === -1) { |         if (inputText[0] !== '@' || inputText.indexOf(":") === -1) { | ||||||
|             console.error("Bad user ID to invite: %s", inputText); |             console.error("Bad user ID to invite: %s", inputText); | ||||||
|  |             Modal.createDialog(ErrorDialog, { | ||||||
|  |                 title: "Invite Error", | ||||||
|  |                 description: "Malformed user ID. Should look like '@localpart:domain'" | ||||||
|  |             }); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         self.setState({ |         self.setState({ | ||||||
| @ -81,6 +100,10 @@ module.exports = { | |||||||
|             }); |             }); | ||||||
|         }, function(err) { |         }, function(err) { | ||||||
|             console.error("Failed to invite: %s", JSON.stringify(err)); |             console.error("Failed to invite: %s", JSON.stringify(err)); | ||||||
|  |             Modal.createDialog(ErrorDialog, { | ||||||
|  |                 title: "Invite Server Error", | ||||||
|  |                 description: err.message | ||||||
|  |             }); | ||||||
|             self.setState({ |             self.setState({ | ||||||
|                 inviting: false |                 inviting: false | ||||||
|             }); |             }); | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ var Loader = require("react-loader"); | |||||||
| 
 | 
 | ||||||
| var MatrixClientPeg = require("../../MatrixClientPeg"); | var MatrixClientPeg = require("../../MatrixClientPeg"); | ||||||
| var RoomListSorter = require("../../RoomListSorter"); | var RoomListSorter = require("../../RoomListSorter"); | ||||||
| 
 | var Presence = require("../../Presence"); | ||||||
| var dis = require("../../dispatcher"); | var dis = require("../../dispatcher"); | ||||||
| 
 | 
 | ||||||
| var ComponentBroker = require('../../ComponentBroker'); | var ComponentBroker = require('../../ComponentBroker'); | ||||||
| @ -89,8 +89,9 @@ module.exports = { | |||||||
|                     window.localStorage.clear(); |                     window.localStorage.clear(); | ||||||
|                 } |                 } | ||||||
|                 Notifier.stop(); |                 Notifier.stop(); | ||||||
|  |                 Presence.stop(); | ||||||
|                 MatrixClientPeg.get().removeAllListeners(); |                 MatrixClientPeg.get().removeAllListeners(); | ||||||
|                 MatrixClientPeg.replace(null); |                 MatrixClientPeg.unset(); | ||||||
|                 break; |                 break; | ||||||
|             case 'start_registration': |             case 'start_registration': | ||||||
|                 if (this.state.logged_in) return; |                 if (this.state.logged_in) return; | ||||||
| @ -187,6 +188,7 @@ module.exports = { | |||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
|         Notifier.start(); |         Notifier.start(); | ||||||
|  |         Presence.start(); | ||||||
|         cli.startClient(); |         cli.startClient(); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -75,27 +75,10 @@ module.exports = { | |||||||
|             'user': formVals.username, |             'user': formVals.username, | ||||||
|             'password': formVals.password |             'password': formVals.password | ||||||
|         }).done(function(data) { |         }).done(function(data) { | ||||||
|             // XXX: we assume this means we're logged in, but there could be a next stage
 |             MatrixClientPeg.replaceUsingAccessToken( | ||||||
|             MatrixClientPeg.replace(Matrix.createClient({ |                 self.state.hs_url, self.state.is_url, | ||||||
|                 baseUrl: self.state.hs_url, |                 data.user_id, data.access_token | ||||||
|                 idBaseUrl: self.state.is_url, |             ); | ||||||
|                 userId: data.user_id, |  | ||||||
|                 accessToken: data.access_token |  | ||||||
|             })); |  | ||||||
|             var localStorage = window.localStorage; |  | ||||||
|             if (localStorage) { |  | ||||||
|                 try { |  | ||||||
|                     localStorage.clear(); |  | ||||||
|                     localStorage.setItem("mx_hs_url", self.state.hs_url); |  | ||||||
|                     localStorage.setItem("mx_is_url", self.state.is_url); |  | ||||||
|                     localStorage.setItem("mx_user_id", data.user_id); |  | ||||||
|                     localStorage.setItem("mx_access_token", data.access_token); |  | ||||||
|                 } catch (e) { |  | ||||||
|                     console.warn("Error using local storage: can't persist session!"); |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 console.warn("No local storage available: can't persist session!"); |  | ||||||
|             } |  | ||||||
|             if (self.props.onLoggedIn) { |             if (self.props.onLoggedIn) { | ||||||
|                 self.props.onLoggedIn(); |                 self.props.onLoggedIn(); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -259,20 +259,9 @@ module.exports = { | |||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     onRegistered: function(user_id, access_token) { |     onRegistered: function(user_id, access_token) { | ||||||
|         MatrixClientPeg.replace(Matrix.createClient({ |         MatrixClientPeg.replaceUsingAccessToken( | ||||||
|             baseUrl: this.state.hs_url, |             this.state.hs_url, this.state.is_url, user_id, access_token | ||||||
|             idBaseUrl: this.state.is_url, |         ); | ||||||
|             userId: user_id, |  | ||||||
|             accessToken: access_token |  | ||||||
|         })); |  | ||||||
|         var localStorage = window.localStorage; |  | ||||||
|         if (localStorage) { |  | ||||||
|             localStorage.setItem("mx_hs_url", this.state.hs_url); |  | ||||||
|             localStorage.setItem("mx_user_id", user_id); |  | ||||||
|             localStorage.setItem("mx_access_token", access_token); |  | ||||||
|         } else { |  | ||||||
|             console.warn("No local storage available: can't persist session!"); |  | ||||||
|         } |  | ||||||
|         if (this.props.onLoggedIn) { |         if (this.props.onLoggedIn) { | ||||||
|             this.props.onLoggedIn(); |             this.props.onLoggedIn(); | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user