mirror of
				https://github.com/vector-im/element-web.git
				synced 2025-10-31 00:01:23 +01:00 
			
		
		
		
	Merge branch 'develop' into kegan/delete-empty-files
Conflicts: src/skins/vector/views/molecules/EventAsTextTile.js
This commit is contained in:
		
						commit
						c91b642a8b
					
				
							
								
								
									
										25
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								README.md
									
									
									
									
									
								
							| @ -22,14 +22,27 @@ into the `vector` directory and run your own server. | |||||||
| 
 | 
 | ||||||
| Development | Development | ||||||
| =========== | =========== | ||||||
| You can work on any of the source files within Vector with the setup above, |  | ||||||
| and your changes will cause an instant rebuild. If you also need to make |  | ||||||
| changes to the react sdk, you can: |  | ||||||
| 
 | 
 | ||||||
| 1. Link the react sdk package into the example: | For simple tweaks, you can work on any of the source files within Vector with the | ||||||
|  | setup above, and your changes will cause an instant rebuild. | ||||||
|  | 
 | ||||||
|  | However, all serious development on Vector happens on the `develop` branch.  This typically | ||||||
|  | depends on the `develop` snapshot versions of `matrix-react-sdk` and `matrix-js-sdk` | ||||||
|  | too, which isn't expressed in Vector's `package.json`.  To do this, check out | ||||||
|  | the `develop` branches of these libraries and then use `npm link` to tell Vector | ||||||
|  | about them: | ||||||
|  | 
 | ||||||
|  | 1. `git clone git@github.com:matrix-org/matrix-react-sdk.git` | ||||||
|  | 2. `cd matrix-react-sdk` | ||||||
|  | 3. `git checkout develop` | ||||||
|  | 4. `npm install` | ||||||
|  | 5. `npm start` (to start the dev rebuilder) | ||||||
|  | 6. `cd ../vector-web` | ||||||
|  | 7. Link the react sdk package into the example: | ||||||
|    `npm link path/to/your/react/sdk` |    `npm link path/to/your/react/sdk` | ||||||
| 2. Start the development rebuilder in your react SDK directory: | 
 | ||||||
|    `npm start` | Similarly, you may need to `npm link path/to/your/js/sdk` in your `matrix-react-sdk` | ||||||
|  | directory. | ||||||
| 
 | 
 | ||||||
| If you add or remove any components from the Vector skin, you will need to rebuild | If you add or remove any components from the Vector skin, you will need to rebuild | ||||||
| the skin's index by running, `npm run reskindex`. | the skin's index by running, `npm run reskindex`. | ||||||
|  | |||||||
| @ -49,15 +49,25 @@ module.exports = { | |||||||
| 
 | 
 | ||||||
|         var position = { |         var position = { | ||||||
|             top: props.top - 20, |             top: props.top - 20, | ||||||
|             right: props.right + 8, |  | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         var chevron = null; | ||||||
|  |         if (props.left) { | ||||||
|  |             chevron = <img className="mx_ContextualMenu_chevron_left" src="img/chevron-left.png" width="9" height="16" /> | ||||||
|  |             position.left = props.left + 8; | ||||||
|  |         } else { | ||||||
|  |             chevron = <img className="mx_ContextualMenu_chevron_right" src="img/chevron-right.png" width="9" height="16" /> | ||||||
|  |             position.right = props.right + 8; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         var className = 'mx_ContextualMenu_wrapper'; | ||||||
|  | 
 | ||||||
|         // FIXME: If a menu uses getDefaultProps it clobbers the onFinished
 |         // FIXME: If a menu uses getDefaultProps it clobbers the onFinished
 | ||||||
|         // property set here so you can't close the menu from a button click!
 |         // property set here so you can't close the menu from a button click!
 | ||||||
|         var menu = ( |         var menu = ( | ||||||
|             <div className="mx_ContextualMenu_wrapper"> |             <div className={className}> | ||||||
|                 <div className="mx_ContextualMenu" style={position}> |                 <div className="mx_ContextualMenu" style={position}> | ||||||
|                     <img className="mx_ContextualMenu_chevron" src="img/chevron-right.png" width="9" height="16" /> |                     {chevron} | ||||||
|                     <Element {...props} onFinished={closeMenu}/> |                     <Element {...props} onFinished={closeMenu}/> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div className="mx_ContextualMenu_background" onClick={closeMenu}></div> |                 <div className="mx_ContextualMenu_background" onClick={closeMenu}></div> | ||||||
|  | |||||||
| @ -33,6 +33,7 @@ module.exports = { | |||||||
|         cli.on("Room", this.onRoom); |         cli.on("Room", this.onRoom); | ||||||
|         cli.on("Room.timeline", this.onRoomTimeline); |         cli.on("Room.timeline", this.onRoomTimeline); | ||||||
|         cli.on("Room.name", this.onRoomName); |         cli.on("Room.name", this.onRoomName); | ||||||
|  |         cli.on("RoomState.events", this.onRoomStateEvents); | ||||||
| 
 | 
 | ||||||
|         var rooms = this.getRoomList(); |         var rooms = this.getRoomList(); | ||||||
|         this.setState({ |         this.setState({ | ||||||
| @ -66,6 +67,7 @@ module.exports = { | |||||||
|             MatrixClientPeg.get().removeListener("Room", this.onRoom); |             MatrixClientPeg.get().removeListener("Room", this.onRoom); | ||||||
|             MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); |             MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); | ||||||
|             MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); |             MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); | ||||||
|  |             MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| @ -110,6 +112,11 @@ module.exports = { | |||||||
|         this.refreshRoomList(); |         this.refreshRoomList(); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  |     onRoomStateEvents: function(ev, state) { | ||||||
|  |         setTimeout(this.refreshRoomList, 0); | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     refreshRoomList: function() { |     refreshRoomList: function() { | ||||||
|         var rooms = this.getRoomList(); |         var rooms = this.getRoomList(); | ||||||
|         this.setState({ |         this.setState({ | ||||||
|  | |||||||
| @ -63,6 +63,7 @@ module.exports = { | |||||||
|             MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); |             MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); | ||||||
|             MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); |             MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); | ||||||
|             MatrixClientPeg.get().removeListener("RoomMember.typing", this.onRoomMemberTyping); |             MatrixClientPeg.get().removeListener("RoomMember.typing", this.onRoomMemberTyping); | ||||||
|  |             MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| @ -356,23 +357,20 @@ module.exports = { | |||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     getEventTiles: function() { |     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 DateSeparator = sdk.getComponent('molecules.DateSeparator'); | ||||||
| 
 | 
 | ||||||
|         var ret = []; |         var ret = []; | ||||||
|         var count = 0; |         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) { |         for (var i = this.state.room.timeline.length-1; i >= 0 && count < this.state.messageCap; --i) { | ||||||
|             var mxEv = this.state.room.timeline[i]; |             var mxEv = this.state.room.timeline[i]; | ||||||
|             var TileType = tileTypes[mxEv.getType()]; | 
 | ||||||
|  |             if (!EventTile.supportsEventType(mxEv.getType())) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             var continuation = false; |             var continuation = false; | ||||||
|             var last = false; |             var last = false; | ||||||
|             var dateSeparator = null; |             var dateSeparator = null; | ||||||
| @ -401,13 +399,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
 |             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(); |                 var ts1 = this.state.room.timeline[i].getTs(); | ||||||
|                 dateSeparator = <DateSeparator key={ts1} ts={ts1}/>; |                 dateSeparator = <li key={ts1}><DateSeparator ts={ts1}/></li>; | ||||||
|                 continuation = false; |                 continuation = false; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (!TileType) continue; |  | ||||||
|             ret.unshift( |             ret.unshift( | ||||||
|                 <li key={mxEv.getId()}><TileType mxEvent={mxEv} continuation={continuation} last={last}/></li> |                 <li key={mxEv.getId()}><EventTile mxEvent={mxEv} continuation={continuation} last={last}/></li> | ||||||
|             ); |             ); | ||||||
|             if (dateSeparator) { |             if (dateSeparator) { | ||||||
|                 ret.unshift(dateSeparator); |                 ret.unshift(dateSeparator); | ||||||
|  | |||||||
| @ -67,13 +67,20 @@ a:visited { | |||||||
|     padding: 6px; |     padding: 6px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_ContextualMenu_chevron { | .mx_ContextualMenu_chevron_right { | ||||||
|     padding: 12px; |     padding: 12px; | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     right: -21px; |     right: -21px; | ||||||
|     top: 0px; |     top: 0px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .mx_ContextualMenu_chevron_left { | ||||||
|  |     padding: 12px; | ||||||
|  |     position: absolute; | ||||||
|  |     left: -21px; | ||||||
|  |     top: 0px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .mx_ContextualMenu_field { | .mx_ContextualMenu_field { | ||||||
|     padding: 3px 6px 3px 6px; |     padding: 3px 6px 3px 6px; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|  | |||||||
| @ -14,14 +14,14 @@ See the License for the specific language governing permissions and | |||||||
| limitations under the License. | limitations under the License. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile { | .mx_EventTile { | ||||||
|     max-width: 100%; |     max-width: 100%; | ||||||
|     clear: both; |     clear: both; | ||||||
|     margin-top: 32px; |     margin-top: 32px; | ||||||
|     margin-left: 56px; |     margin-left: 56px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_avatar { | .mx_EventTile_avatar { | ||||||
|     padding-left: 12px; |     padding-left: 12px; | ||||||
|     padding-right: 12px; |     padding-right: 12px; | ||||||
|     margin-left: -64px; |     margin-left: -64px; | ||||||
| @ -29,17 +29,17 @@ limitations under the License. | |||||||
|     float: left; |     float: left; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_avatar img { | .mx_EventTile_avatar img { | ||||||
|     background-color: #dbdbdb; |     background-color: #dbdbdb; | ||||||
|     border-radius: 20px; |     border-radius: 20px; | ||||||
|     border: 0px; |     border: 0px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_continuation { | .mx_EventTile_continuation { | ||||||
|     margin-top: 8px ! important; |     margin-top: 8px ! important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile .mx_SenderProfile { | .mx_EventTile .mx_SenderProfile { | ||||||
|     color: #454545; |     color: #454545; | ||||||
|     opacity: 0.5; |     opacity: 0.5; | ||||||
|     font-size: 14px; |     font-size: 14px; | ||||||
| @ -47,35 +47,35 @@ limitations under the License. | |||||||
|     display: block; |     display: block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile .mx_MessageTimestamp { | .mx_EventTile .mx_MessageTimestamp { | ||||||
|     color: #454545; |     color: #454545; | ||||||
|     opacity: 0.5; |     opacity: 0.5; | ||||||
|     font-size: 14px; |     font-size: 14px; | ||||||
|     float: right; |     float: right; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_content { | .mx_EventTile_content { | ||||||
|     padding-right: 100px; |     padding-right: 100px; | ||||||
|     display: block; |     display: block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_notice .mx_MessageTile_content { | .mx_EventTile_notice .mx_MessageTile_content { | ||||||
|     opacity: 0.5; |     opacity: 0.5; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_sending { | .mx_EventTile_sending { | ||||||
|     color: #ddd; |     color: #ddd; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_notSent { | .mx_EventTile_notSent { | ||||||
|     color: #f11; |     color: #f11; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_highlight { | .mx_EventTile_highlight { | ||||||
|     color: #FF0064; |     color: #FF0064; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_msgOption { | .mx_EventTile_msgOption { | ||||||
|     float: right; |     float: right; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -83,29 +83,30 @@ limitations under the License. | |||||||
|     display: none; |     display: none; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_last .mx_MessageTimestamp { | .mx_EventTile_last .mx_MessageTimestamp { | ||||||
|     display: block; |     display: block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile:hover .mx_MessageTimestamp { | .mx_EventTile:hover .mx_MessageTimestamp { | ||||||
|     display: block; |     display: block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile_editButton { | .mx_EventTile_editButton { | ||||||
|     float: right; |     float: right; | ||||||
|     display: none; |     display: none; | ||||||
|     border: 0px; |     border: 0px; | ||||||
|     outline: none; |     outline: none; | ||||||
|  |     margin-right: 3px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile:hover .mx_MessageTile_editButton { | .mx_EventTile:hover .mx_EventTile_editButton { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile.menu .mx_MessageTile_editButton { | .mx_EventTile.menu .mx_EventTile_editButton { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .mx_MessageTile.menu .mx_MessageTimestamp { | .mx_EventTile.menu .mx_MessageTimestamp { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
| } | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								src/skins/vector/img/50e2c2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/skins/vector/img/50e2c2.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 146 B | 
							
								
								
									
										
											BIN
										
									
								
								src/skins/vector/img/80cef4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/skins/vector/img/80cef4.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 146 B | 
							
								
								
									
										
											BIN
										
									
								
								src/skins/vector/img/f4c371.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/skins/vector/img/f4c371.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 146 B | 
| @ -41,6 +41,7 @@ skin['molecules.ChangeDisplayName'] = require('./views/molecules/ChangeDisplayNa | |||||||
| skin['molecules.ChangePassword'] = require('./views/molecules/ChangePassword'); | skin['molecules.ChangePassword'] = require('./views/molecules/ChangePassword'); | ||||||
| skin['molecules.DateSeparator'] = require('./views/molecules/DateSeparator'); | skin['molecules.DateSeparator'] = require('./views/molecules/DateSeparator'); | ||||||
| skin['molecules.EventAsTextTile'] = require('./views/molecules/EventAsTextTile'); | skin['molecules.EventAsTextTile'] = require('./views/molecules/EventAsTextTile'); | ||||||
|  | skin['molecules.EventTile'] = require('./views/molecules/EventTile'); | ||||||
| skin['molecules.MatrixToolbar'] = require('./views/molecules/MatrixToolbar'); | skin['molecules.MatrixToolbar'] = require('./views/molecules/MatrixToolbar'); | ||||||
| skin['molecules.MemberInfo'] = require('./views/molecules/MemberInfo'); | skin['molecules.MemberInfo'] = require('./views/molecules/MemberInfo'); | ||||||
| skin['molecules.MemberTile'] = require('./views/molecules/MemberTile'); | skin['molecules.MemberTile'] = require('./views/molecules/MemberTile'); | ||||||
|  | |||||||
| @ -42,7 +42,7 @@ module.exports = React.createClass({ | |||||||
|             return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + pad(date.getHours()) + ':' + pad(date.getMinutes()); |             return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + pad(date.getHours()) + ':' + pad(date.getMinutes()); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + date().getFullYear() + " " + pad(date.getHours()) + ':' + pad(date.getMinutes()); |             return days[date.getDay()] + ", " + months[date.getMonth()] + " " + (date.getDay()+1) + " " + date.getFullYear() + " " + pad(date.getHours()) + ':' + pad(date.getMinutes()); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ limitations under the License. | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| var React = require('react'); | var React = require('react'); | ||||||
|  | var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); | ||||||
| 
 | 
 | ||||||
| var RoomAvatarController = require('matrix-react-sdk/lib/controllers/atoms/RoomAvatar') | var RoomAvatarController = require('matrix-react-sdk/lib/controllers/atoms/RoomAvatar') | ||||||
| 
 | 
 | ||||||
| @ -24,10 +25,31 @@ module.exports = React.createClass({ | |||||||
|     displayName: 'RoomAvatar', |     displayName: 'RoomAvatar', | ||||||
|     mixins: [RoomAvatarController], |     mixins: [RoomAvatarController], | ||||||
| 
 | 
 | ||||||
|  |     getUrlList: function() { | ||||||
|  |         return [ | ||||||
|  |             this.roomAvatarUrl(), | ||||||
|  |             this.getOneToOneAvatar(), | ||||||
|  |             this.getFallbackAvatar() | ||||||
|  |         ]; | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     getFallbackAvatar: function() { | ||||||
|  |         var images = [ '80cef4', '50e2c2', 'f4c371' ]; | ||||||
|  |         var total = 0; | ||||||
|  |         for (var i = 0; i < this.props.room.roomId.length; ++i) { | ||||||
|  |             total += this.props.room.roomId.charCodeAt(i); | ||||||
|  |         } | ||||||
|  |         return 'img/' + images[total % images.length] + '.png'; | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|     render: function() { |     render: function() { | ||||||
|  |         var style = { | ||||||
|  |             maxWidth: this.props.width, | ||||||
|  |             maxHeight: this.props.height, | ||||||
|  |         }; | ||||||
|         return ( |         return ( | ||||||
|             <img className="mx_RoomAvatar" src={this.state.imageUrl} onError={this.onError} |             <img className="mx_RoomAvatar" src={this.state.imageUrl} onError={this.onError} | ||||||
|                 width={this.props.width} height={this.props.height} |                 style={style} | ||||||
|             /> |             /> | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ limitations under the License. | |||||||
| 
 | 
 | ||||||
| var React = require('react'); | var React = require('react'); | ||||||
| 
 | 
 | ||||||
|  | var sdk = require('matrix-react-sdk') | ||||||
| var ChangeAvatarController = require('matrix-react-sdk/lib/controllers/molecules/ChangeAvatar') | var ChangeAvatarController = require('matrix-react-sdk/lib/controllers/molecules/ChangeAvatar') | ||||||
| 
 | 
 | ||||||
| var Loader = require("react-loader"); | var Loader = require("react-loader"); | ||||||
| @ -28,6 +29,7 @@ module.exports = React.createClass({ | |||||||
|     mixins: [ChangeAvatarController], |     mixins: [ChangeAvatarController], | ||||||
| 
 | 
 | ||||||
|     onFileSelected: function(ev) { |     onFileSelected: function(ev) { | ||||||
|  |         this.avatarSet = true; | ||||||
|         this.setAvatarFromFile(ev.target.files[0]); |         this.setAvatarFromFile(ev.target.files[0]); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| @ -38,13 +40,27 @@ module.exports = React.createClass({ | |||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     render: function() { |     render: function() { | ||||||
|  |         var RoomAvatar = sdk.getComponent('atoms.RoomAvatar'); | ||||||
|  |         var avatarImg; | ||||||
|  |         // Having just set an avatar we just display that since it will take a little
 | ||||||
|  |         // time to propagate through to the RoomAvatar.
 | ||||||
|  |         if (this.props.room && !this.avatarSet) { | ||||||
|  |             avatarImg = <RoomAvatar room={this.props.room} width='320' height='240' resizeMethod='scale' />; | ||||||
|  |         } else { | ||||||
|  |             var style = { | ||||||
|  |                 maxWidth: 320, | ||||||
|  |                 maxHeight: 240, | ||||||
|  |             }; | ||||||
|  |             avatarImg = <img src={this.state.avatarUrl} style={style} />; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         switch (this.state.phase) { |         switch (this.state.phase) { | ||||||
|             case this.Phases.Display: |             case this.Phases.Display: | ||||||
|             case this.Phases.Error: |             case this.Phases.Error: | ||||||
|                 return ( |                 return ( | ||||||
|                     <div> |                     <div> | ||||||
|                         <div className="mx_Dialog_content"> |                         <div className="mx_Dialog_content"> | ||||||
|                             <img src={this.state.avatarUrl}/> |                             {avatarImg} | ||||||
|                         </div> |                         </div> | ||||||
|                         <div className="mx_Dialog_content"> |                         <div className="mx_Dialog_content"> | ||||||
|                             Upload new: |                             Upload new: | ||||||
|  | |||||||
| @ -24,25 +24,19 @@ var TextForEvent = require('matrix-react-sdk/lib/TextForEvent'); | |||||||
| module.exports = React.createClass({ | module.exports = React.createClass({ | ||||||
|     displayName: 'EventAsTextTile', |     displayName: 'EventAsTextTile', | ||||||
| 
 | 
 | ||||||
|     render: function() { |     statics: { | ||||||
|         var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp'); |         needsSenderProfile: function() { | ||||||
|         var MemberAvatar = sdk.getComponent('atoms.MemberAvatar'); |             return false; | ||||||
|  |         } | ||||||
|  |     }, | ||||||
| 
 | 
 | ||||||
|  |     render: function() { | ||||||
|         var text = TextForEvent.textForEvent(this.props.mxEvent); |         var text = TextForEvent.textForEvent(this.props.mxEvent); | ||||||
|         if (text == null || text.length == 0) return null; |         if (text == null || text.length == 0) return null; | ||||||
| 
 | 
 | ||||||
|         var timestamp = this.props.last ? <MessageTimestamp ts={this.props.mxEvent.getTs()} /> : null; |  | ||||||
|         var avatar = this.props.mxEvent.sender ? <MemberAvatar member={this.props.mxEvent.sender} /> : null; |  | ||||||
|         return ( |         return ( | ||||||
|             <div className="mx_MessageTile mx_MessageTile_notice"> |             <div className="mx_EventAsTextTile"> | ||||||
|                 <div className="mx_MessageTile_avatar"> |                 {TextForEvent.textForEvent(this.props.mxEvent)} | ||||||
|                     { avatar } |  | ||||||
|                 </div>             |  | ||||||
|                 { timestamp } |  | ||||||
|                 <span className="mx_SenderProfile"></span> |  | ||||||
|                 <span className="mx_MessageTile_content"> |  | ||||||
|                     {TextForEvent.textForEvent(this.props.mxEvent)} |  | ||||||
|                 </span> |  | ||||||
|             </div> |             </div> | ||||||
|         ); |         ); | ||||||
|     }, |     }, | ||||||
|  | |||||||
							
								
								
									
										133
									
								
								src/skins/vector/views/molecules/EventTile.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/skins/vector/views/molecules/EventTile.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | |||||||
|  | /* | ||||||
|  | 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 = buttonRect.right; | ||||||
|  |         var y = buttonRect.top + (e.target.height / 2); | ||||||
|  |         var self = this; | ||||||
|  |         ContextualMenu.createMenu(MessageContextMenu, { | ||||||
|  |             mxEvent: this.props.mxEvent, | ||||||
|  |             left: 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 = <MessageTimestamp ts={this.props.mxEvent.getTs()} /> | ||||||
|  |         var editButton = ( | ||||||
|  |             <input | ||||||
|  |                 type="image" src="img/edit.png" alt="Edit" | ||||||
|  |                 className="mx_EventTile_editButton" onClick={this.onEditClicked} | ||||||
|  |             /> | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         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 = ( | ||||||
|  |                     <div className="mx_EventTile_avatar"> | ||||||
|  |                         <MemberAvatar member={this.props.mxEvent.sender} /> | ||||||
|  |                     </div> | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             if (EventTileType.needsSenderProfile()) { | ||||||
|  |                 sender = <SenderProfile mxEvent={this.props.mxEvent} aux={aux} />; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return ( | ||||||
|  |             <div className={classes}> | ||||||
|  |                 { avatar } | ||||||
|  |                 { sender } | ||||||
|  |                 <div> | ||||||
|  |                     { timestamp } | ||||||
|  |                     { editButton } | ||||||
|  |                     <EventTileType mxEvent={this.props.mxEvent} /> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         ); | ||||||
|  |     }, | ||||||
|  | }); | ||||||
| @ -52,9 +52,27 @@ module.exports = React.createClass({ | |||||||
|         if (this.props.onFinished) this.props.onFinished(); |         if (this.props.onFinished) this.props.onFinished(); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  |     onRedactClick: function() { | ||||||
|  |         MatrixClientPeg.get().redactEvent( | ||||||
|  |             this.props.mxEvent.getRoomId(), this.props.mxEvent.getId() | ||||||
|  |         ).done(function() { | ||||||
|  |             // message should disappear by itself
 | ||||||
|  |         }, function(e) { | ||||||
|  |             var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); | ||||||
|  |             // display error message stating you couldn't delete this.
 | ||||||
|  |             var code = e.errcode || e.statusCode; | ||||||
|  |             Modal.createDialog(ErrorDialog, { | ||||||
|  |                 title: "Error", | ||||||
|  |                 description: "You cannot delete this message. (" + code + ")" | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |         if (this.props.onFinished) this.props.onFinished(); | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|     render: function() { |     render: function() { | ||||||
|         var resendButton; |         var resendButton; | ||||||
|         var viewSourceButton; |         var viewSourceButton; | ||||||
|  |         var redactButton; | ||||||
| 
 | 
 | ||||||
|         if (this.props.mxEvent.status == 'not_sent') { |         if (this.props.mxEvent.status == 'not_sent') { | ||||||
|             resendButton = ( |             resendButton = ( | ||||||
| @ -63,6 +81,13 @@ module.exports = React.createClass({ | |||||||
|                 </div> |                 </div> | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|  |         else { | ||||||
|  |             redactButton = ( | ||||||
|  |                 <div className="mx_ContextualMenu_field" onClick={this.onRedactClick}> | ||||||
|  |                     Delete | ||||||
|  |                 </div> | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|         viewSourceButton = ( |         viewSourceButton = ( | ||||||
|             <div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}> |             <div className="mx_ContextualMenu_field" onClick={this.onViewSourceClick}> | ||||||
|                 View Source |                 View Source | ||||||
| @ -72,6 +97,7 @@ module.exports = React.createClass({ | |||||||
|         return ( |         return ( | ||||||
|             <div> |             <div> | ||||||
|                 {resendButton} |                 {resendButton} | ||||||
|  |                 {redactButton} | ||||||
|                 {viewSourceButton} |                 {viewSourceButton} | ||||||
|             </div> |             </div> | ||||||
|         ); |         ); | ||||||
|  | |||||||
| @ -28,28 +28,13 @@ module.exports = React.createClass({ | |||||||
|     displayName: 'MessageTile', |     displayName: 'MessageTile', | ||||||
|     mixins: [MessageTileController], |     mixins: [MessageTileController], | ||||||
| 
 | 
 | ||||||
|     onEditClicked: function(e) { |     statics: { | ||||||
|         var MessageContextMenu = sdk.getComponent('molecules.MessageContextMenu'); |         needsSenderProfile: function() { | ||||||
|         var buttonRect = e.target.getBoundingClientRect() |             return true; | ||||||
|         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() { |     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 UnknownMessageTile = sdk.getComponent('molecules.UnknownMessageTile'); | ||||||
| 
 | 
 | ||||||
|         var tileTypes = { |         var tileTypes = { | ||||||
| @ -66,56 +51,7 @@ module.exports = React.createClass({ | |||||||
|         if (msgtype && tileTypes[msgtype]) { |         if (msgtype && tileTypes[msgtype]) { | ||||||
|             TileType = 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 = <MessageTimestamp ts={this.props.mxEvent.getTs()} /> |  | ||||||
|         var editButton = ( |  | ||||||
|             <input |  | ||||||
|                 type="image" src="img/edit.png" alt="Edit" |  | ||||||
|                 className="mx_MessageTile_editButton" onClick={this.onEditClicked} |  | ||||||
|             /> |  | ||||||
|         ); |  | ||||||
| 
 | 
 | ||||||
|         var aux = null; |         return <TileType mxEvent={this.props.mxEvent} />; | ||||||
|         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 = ( |  | ||||||
|                     <div className="mx_MessageTile_avatar"> |  | ||||||
|                         <MemberAvatar member={this.props.mxEvent.sender} /> |  | ||||||
|                     </div> |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             sender = <SenderProfile mxEvent={this.props.mxEvent} aux={aux} />; |  | ||||||
|         } |  | ||||||
|         if (this.props.mxEvent.status === "not_sent" && !this.state.resending) { |  | ||||||
|             resend = <button className="mx_MessageTile_msgOption" onClick={this.onResend}> |  | ||||||
|                 Resend |  | ||||||
|             </button>; |  | ||||||
|         } |  | ||||||
|         return ( |  | ||||||
|             <div className={classes}> |  | ||||||
|                 { avatar } |  | ||||||
|                 { sender } |  | ||||||
|                 <div> |  | ||||||
|                     { timestamp } |  | ||||||
|                     { editButton } |  | ||||||
|                     <TileType mxEvent={this.props.mxEvent} /> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         ); |  | ||||||
|     }, |     }, | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ limitations under the License. | |||||||
| 
 | 
 | ||||||
| var React = require('react'); | var React = require('react'); | ||||||
| var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); | var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); | ||||||
|  | var sdk = require('matrix-react-sdk'); | ||||||
| 
 | 
 | ||||||
| var RoomSettingsController = require('matrix-react-sdk/lib/controllers/molecules/RoomSettings') | var RoomSettingsController = require('matrix-react-sdk/lib/controllers/molecules/RoomSettings') | ||||||
| 
 | 
 | ||||||
| @ -65,6 +66,8 @@ module.exports = React.createClass({ | |||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     render: function() { |     render: function() { | ||||||
|  |         var ChangeAvatar = sdk.getComponent('molecules.ChangeAvatar'); | ||||||
|  | 
 | ||||||
|         var topic = this.props.room.currentState.getStateEvents('m.room.topic', ''); |         var topic = this.props.room.currentState.getStateEvents('m.room.topic', ''); | ||||||
|         if (topic) topic = topic.getContent().topic; |         if (topic) topic = topic.getContent().topic; | ||||||
| 
 | 
 | ||||||
| @ -76,6 +79,8 @@ module.exports = React.createClass({ | |||||||
| 
 | 
 | ||||||
|         var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); |         var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); | ||||||
| 
 | 
 | ||||||
|  |         var events_levels = power_levels.events || {}; | ||||||
|  | 
 | ||||||
|         if (power_levels) { |         if (power_levels) { | ||||||
|             power_levels = power_levels.getContent(); |             power_levels = power_levels.getContent(); | ||||||
| 
 | 
 | ||||||
| @ -91,8 +96,7 @@ module.exports = React.createClass({ | |||||||
|             if (power_levels.kick == undefined) kick_level = 50; |             if (power_levels.kick == undefined) kick_level = 50; | ||||||
|             if (power_levels.redact == undefined) redact_level = 50; |             if (power_levels.redact == undefined) redact_level = 50; | ||||||
| 
 | 
 | ||||||
|             var user_levels = power_levels.users || []; |             var user_levels = power_levels.users || {}; | ||||||
|             var events_levels = power_levels.events || []; |  | ||||||
| 
 | 
 | ||||||
|             var user_id = MatrixClientPeg.get().credentials.userId; |             var user_id = MatrixClientPeg.get().credentials.userId; | ||||||
| 
 | 
 | ||||||
| @ -124,7 +128,21 @@ module.exports = React.createClass({ | |||||||
|             var can_change_levels = false; |             var can_change_levels = false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         var banned = this.props.room.getMembersWithMemership("ban"); |         var room_avatar_level = parseInt(power_levels.state_default || 0); | ||||||
|  |         if (events_levels['m.room.avatar'] !== undefined) { | ||||||
|  |             room_avatar_level = events_levels['m.room.avatar']; | ||||||
|  |         } | ||||||
|  |         var can_set_room_avatar = current_user_level >= room_avatar_level; | ||||||
|  | 
 | ||||||
|  |         var change_avatar; | ||||||
|  |         if (can_set_room_avatar) { | ||||||
|  |             change_avatar = <div> | ||||||
|  |                 <h3>Room Icon</h3> | ||||||
|  |                 <ChangeAvatar room={this.props.room} /> | ||||||
|  |             </div>; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         var banned = this.props.room.getMembersWithMembership("ban"); | ||||||
| 
 | 
 | ||||||
|         return ( |         return ( | ||||||
|             <div className="mx_RoomSettings"> |             <div className="mx_RoomSettings"> | ||||||
| @ -207,6 +225,7 @@ module.exports = React.createClass({ | |||||||
|                         ); |                         ); | ||||||
|                     })} |                     })} | ||||||
|                 </div> |                 </div> | ||||||
|  |                 {change_avatar} | ||||||
|             </div> |             </div> | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -58,15 +58,16 @@ var NotifierView = { | |||||||
|             if (ev.getContent().body) msg = ev.getContent().body; |             if (ev.getContent().body) msg = ev.getContent().body; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         var avatarUrl = Avatar.avatarUrlForMember( |         var avatarUrl = ev.sender ? Avatar.avatarUrlForMember( | ||||||
|             ev.sender, 40, 40, 'crop' |             ev.sender, 40, 40, 'crop' | ||||||
|         ); |         ) : null; | ||||||
| 
 | 
 | ||||||
|         var notification = new global.Notification( |         var notification = new global.Notification( | ||||||
|             title, |             title, | ||||||
|             { |             { | ||||||
|                 "body": msg, |                 "body": msg, | ||||||
|                 "icon": avatarUrl |                 "icon": avatarUrl, | ||||||
|  |                 "tag": "vector" | ||||||
|             } |             } | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -149,6 +149,11 @@ module.exports = React.createClass({ | |||||||
|                 var innerProgressStyle = { |                 var innerProgressStyle = { | ||||||
|                     width: ((this.state.upload.uploadedBytes / this.state.upload.totalBytes) * 100) + '%' |                     width: ((this.state.upload.uploadedBytes / this.state.upload.totalBytes) * 100) + '%' | ||||||
|                 }; |                 }; | ||||||
|  |                 var uploadedSize = filesize(this.state.upload.uploadedBytes); | ||||||
|  |                 var totalSize = filesize(this.state.upload.totalBytes); | ||||||
|  |                 if (uploadedSize.replace(/^.* /,'') === totalSize.replace(/^.* /,'')) { | ||||||
|  |                     uploadedSize = uploadedSize.replace(/ .*/, ''); | ||||||
|  |                 } | ||||||
|                 statusBar = ( |                 statusBar = ( | ||||||
|                     <div className="mx_RoomView_uploadBar"> |                     <div className="mx_RoomView_uploadBar"> | ||||||
|                         <div className="mx_RoomView_uploadProgressOuter"> |                         <div className="mx_RoomView_uploadProgressOuter"> | ||||||
| @ -157,7 +162,7 @@ module.exports = React.createClass({ | |||||||
|                         <img className="mx_RoomView_uploadIcon" src="img/fileicon.png" width="40" height="40"/> |                         <img className="mx_RoomView_uploadIcon" src="img/fileicon.png" width="40" height="40"/> | ||||||
|                         <img className="mx_RoomView_uploadCancel" src="img/cancel.png" width="40" height="40"/> |                         <img className="mx_RoomView_uploadCancel" src="img/cancel.png" width="40" height="40"/> | ||||||
|                         <div className="mx_RoomView_uploadBytes"> |                         <div className="mx_RoomView_uploadBytes"> | ||||||
|                             {filesize(this.state.upload.uploadedBytes).replace(/ .*/, '')} / {filesize(this.state.upload.totalBytes)} |                             { uploadedSize } / { totalSize } | ||||||
|                         </div> |                         </div> | ||||||
|                         <div className="mx_RoomView_uploadFilename">Uploading {this.state.upload.fileName}</div> |                         <div className="mx_RoomView_uploadFilename">Uploading {this.state.upload.fileName}</div> | ||||||
|                     </div> |                     </div> | ||||||
|  | |||||||
| @ -26,7 +26,6 @@ var Loader = require("react-loader"); | |||||||
| 
 | 
 | ||||||
| var dis = require('matrix-react-sdk/lib/dispatcher'); | var dis = require('matrix-react-sdk/lib/dispatcher'); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| module.exports = React.createClass({ | module.exports = React.createClass({ | ||||||
|     displayName: 'MatrixChat', |     displayName: 'MatrixChat', | ||||||
|     mixins: [MatrixChatController], |     mixins: [MatrixChatController], | ||||||
| @ -40,6 +39,23 @@ module.exports = React.createClass({ | |||||||
|     componentDidMount: function() { |     componentDidMount: function() { | ||||||
|         window.addEventListener('resize', this.handleResize); |         window.addEventListener('resize', this.handleResize); | ||||||
|         this.handleResize(); |         this.handleResize(); | ||||||
|  | 
 | ||||||
|  |         matrixLinkify.onUserClick = function(e, userId) { | ||||||
|  |             // this can really go anywhere..
 | ||||||
|  |             // sprout a MemberInfo context menu.
 | ||||||
|  |             console.log("Context => %s => %s", userId, e.target); | ||||||
|  | 
 | ||||||
|  |             var MemberInfo = sdk.getComponent('molecules.MemberInfo'); | ||||||
|  |             var member = new RoomMember(null, href); | ||||||
|  |             ContextualMenu.createMenu(MemberInfo, { | ||||||
|  |                 member: member, | ||||||
|  |                 right: window.innerWidth - e.pageX, | ||||||
|  |                 top: e.pageY, | ||||||
|  |                 onFinished: function() { | ||||||
|  |                     console.log("^_^ All done!"); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         }; | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     componentWillUnmount: function() { |     componentWillUnmount: function() { | ||||||
|  | |||||||
| @ -25,10 +25,9 @@ var Loader = require("react-loader"); | |||||||
| 
 | 
 | ||||||
| var RegisterController = require('../../../../controllers/templates/Register') | var RegisterController = require('../../../../controllers/templates/Register') | ||||||
| 
 | 
 | ||||||
| module.exports = React.createClass({ | var config = require('../../../../../config.json'); | ||||||
|     DEFAULT_HS_URL: 'https://matrix.org', |  | ||||||
|     DEFAULT_IS_URL: 'https://vector.im', |  | ||||||
| 
 | 
 | ||||||
|  | module.exports = React.createClass({ | ||||||
|     displayName: 'Register', |     displayName: 'Register', | ||||||
|     mixins: [RegisterController], |     mixins: [RegisterController], | ||||||
| 
 | 
 | ||||||
| @ -39,8 +38,8 @@ module.exports = React.createClass({ | |||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     componentWillMount: function() { |     componentWillMount: function() { | ||||||
|         this.customHsUrl = this.DEFAULT_HS_URL; |         this.customHsUrl = config.default_hs_url; | ||||||
|         this.customIsUrl = this.DEFAULT_IS_URL; |         this.customIsUrl = config.default_is_url; | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     getRegFormVals: function() { |     getRegFormVals: function() { | ||||||
| @ -56,7 +55,7 @@ module.exports = React.createClass({ | |||||||
|         if (this.state.serverConfigVisible) { |         if (this.state.serverConfigVisible) { | ||||||
|             return this.customHsUrl; |             return this.customHsUrl; | ||||||
|         } else { |         } else { | ||||||
|             return this.DEFAULT_HS_URL; |             return config.default_hs_url; | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| @ -64,7 +63,7 @@ module.exports = React.createClass({ | |||||||
|         if (this.state.serverConfigVisible) { |         if (this.state.serverConfigVisible) { | ||||||
|             return this.customIsUrl; |             return this.customIsUrl; | ||||||
|         } else { |         } else { | ||||||
|             return this.DEFAULT_IS_URL; |             return config.default_is_url; | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| @ -173,6 +172,12 @@ module.exports = React.createClass({ | |||||||
|                 case this.FieldErrors.InUse: |                 case this.FieldErrors.InUse: | ||||||
|                     strings.push(keys[i]+" is already taken"); |                     strings.push(keys[i]+" is already taken"); | ||||||
|                     break; |                     break; | ||||||
|  |                 case this.FieldErrors.Length: | ||||||
|  |                     strings.push(keys[i] + " is not long enough."); | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     console.error("Unhandled FieldError: %s", bad[keys[i]]); | ||||||
|  |                     break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         var errtxt = strings.join(', '); |         var errtxt = strings.join(', '); | ||||||
|  | |||||||
| @ -20,7 +20,8 @@ module.exports = { | |||||||
|             // removed which gives a tree with matrix-react-sdk and vector
 |             // removed which gives a tree with matrix-react-sdk and vector
 | ||||||
|             // trees smashed together, but this fixes everything being under
 |             // trees smashed together, but this fixes everything being under
 | ||||||
|             // various levels of '.' and '..'
 |             // various levels of '.' and '..'
 | ||||||
|             return info.resourcePath.replace(/^[\/\.]*/, ''); |             // Also, sometimes the resource path is absolute.
 | ||||||
|  |             return path.relative(process.cwd(), info.resourcePath).replace(/^[\/\.]*/, ''); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|     resolve: { |     resolve: { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user