Merge pull request #5286 from turt2live/travis/presence
CSS/components for custom presence controlspull/5604/head
						commit
						3e72d8d969
					
				|  | @ -0,0 +1,101 @@ | |||
| /* | ||||
| Copyright 2017 Travis Ralston | ||||
| 
 | ||||
| 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. | ||||
| */ | ||||
| 
 | ||||
| import React from 'react'; | ||||
| import { _t, _td } from 'matrix-react-sdk/lib/languageHandler'; | ||||
| import sdk from 'matrix-react-sdk'; | ||||
| 
 | ||||
| const STATUS_LABELS = { | ||||
|     "online": _td("Online"), | ||||
|     "unavailable": _td("Away"), | ||||
|     "offline": _td("Appear Offline"), | ||||
| }; | ||||
| 
 | ||||
| const PresenceContextMenuOption = React.createClass({ | ||||
|     displayName: 'PresenceContextMenuOption', | ||||
| 
 | ||||
|     propTypes: { | ||||
|         forStatus: React.PropTypes.string.isRequired, | ||||
|         isCurrent: React.PropTypes.bool, | ||||
|         onChange: React.PropTypes.func.isRequired, | ||||
|     }, | ||||
| 
 | ||||
|     onClick: function() { | ||||
|         if (this.isCurrent) return; | ||||
|         this.props.onChange(this.props.forStatus); | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); | ||||
| 
 | ||||
|         const indicatorClasses = "mx_PresenceContextMenuOption_indicator " | ||||
|             + "mx_PresenceContextMenuOption_indicator_" + this.props.forStatus; | ||||
| 
 | ||||
|         let classNames = "mx_PresenceContextMenuOption"; | ||||
|         if (this.props.isCurrent) classNames += " mx_PresenceContextMenuOption_current"; | ||||
| 
 | ||||
|         return ( | ||||
|             <AccessibleButton className={classNames} element="div" onClick={this.onClick}> | ||||
|                 <div className={indicatorClasses}></div> | ||||
|                 { _t(STATUS_LABELS[this.props.forStatus]) } | ||||
|             </AccessibleButton> | ||||
|         ); | ||||
|     }, | ||||
| }); | ||||
| 
 | ||||
| module.exports = React.createClass({ | ||||
|     displayName: 'PresenceContextMenu', | ||||
| 
 | ||||
|     propTypes: { | ||||
|         // "online", "unavailable", or "offline"
 | ||||
|         currentStatus: React.PropTypes.string.isRequired, | ||||
| 
 | ||||
|         // Called when the user wants to change their status.
 | ||||
|         // Args: (newStatus:string)
 | ||||
|         onChange: React.PropTypes.func.isRequired, | ||||
| 
 | ||||
|         // callback called when the menu is dismissed
 | ||||
|         onFinished: React.PropTypes.func, | ||||
|     }, | ||||
| 
 | ||||
|     getInitialState() { | ||||
|         return { | ||||
|             currentStatus: this.props.currentStatus, | ||||
|         }; | ||||
|     }, | ||||
| 
 | ||||
|     onChange: function(newStatus) { | ||||
|         this.props.onChange(newStatus); | ||||
|         this.setState({currentStatus: newStatus}); | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         const statusElements = []; | ||||
|         for (let status of Object.keys(STATUS_LABELS)) { | ||||
|             statusElements.push(( | ||||
|                 <PresenceContextMenuOption forStatus={status} key={status} | ||||
|                                            onChange={this.onChange} | ||||
|                                            isCurrent={status === this.state.currentStatus} /> | ||||
|             )); | ||||
|         } | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
|                 { statusElements } | ||||
|             </div> | ||||
|         ); | ||||
|     }, | ||||
| }); | ||||
|  | @ -68,6 +68,8 @@ | |||
|     "What's New": "What's New", | ||||
|     "Update": "Update", | ||||
|     "What's new?": "What's new?", | ||||
|     "Appear Offline": "Appear Offline", | ||||
|     "Away": "Away", | ||||
|     "A new version of Riot is available.": "A new version of Riot is available.", | ||||
|     "To return to your account in future you need to <u>set a password</u>": "To return to your account in future you need to <u>set a password</u>", | ||||
|     "Toolbox": "Toolbox", | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ | |||
| @import "./matrix-react-sdk/structures/_UserSettings.scss"; | ||||
| @import "./matrix-react-sdk/structures/login/_Login.scss"; | ||||
| @import "./matrix-react-sdk/views/avatars/_BaseAvatar.scss"; | ||||
| @import "./matrix-react-sdk/views/avatars/_MemberPresenceAvatar.scss"; | ||||
| @import "./matrix-react-sdk/views/dialogs/_BugReportDialog.scss"; | ||||
| @import "./matrix-react-sdk/views/dialogs/_ChatCreateOrReuseChatDialog.scss"; | ||||
| @import "./matrix-react-sdk/views/dialogs/_ChatInviteDialog.scss"; | ||||
|  | @ -80,6 +81,7 @@ | |||
| @import "./vector-web/structures/_RoomSubList.scss"; | ||||
| @import "./vector-web/structures/_ViewSource.scss"; | ||||
| @import "./vector-web/views/context_menus/_MessageContextMenu.scss"; | ||||
| @import "vector-web/views/context_menus/_PresenceContextMenuOption.scss"; | ||||
| @import "./vector-web/views/context_menus/_RoomTileContextMenu.scss"; | ||||
| @import "./vector-web/views/dialogs/_ChangelogDialog.scss"; | ||||
| @import "./vector-web/views/dialogs/_DevtoolsDialog.scss"; | ||||
|  |  | |||
|  | @ -94,6 +94,60 @@ limitations under the License. | |||
|     left: 1px; | ||||
| } | ||||
| 
 | ||||
| .mx_ContextualMenu.mx_ContextualMenu_top { | ||||
|     top: 8px; | ||||
| } | ||||
| 
 | ||||
| .mx_ContextualMenu_chevron_top { | ||||
|     position: absolute; | ||||
|     left: 0px; | ||||
|     top: -8px; | ||||
|     width: 0; | ||||
|     height: 0; | ||||
|     border-left: 8px solid transparent; | ||||
|     border-bottom: 8px solid $menu-border-color; | ||||
|     border-right: 8px solid transparent; | ||||
| } | ||||
| 
 | ||||
| .mx_ContextualMenu_chevron_top:after{ | ||||
|     content:''; | ||||
|     width: 0; | ||||
|     height: 0; | ||||
|     border-left: 7px solid transparent; | ||||
|     border-bottom: 7px solid $menu-bg-color; | ||||
|     border-right: 7px solid transparent; | ||||
|     position:absolute; | ||||
|     left: -7px; | ||||
|     top: 1px; | ||||
| } | ||||
| 
 | ||||
| .mx_ContextualMenu.mx_ContextualMenu_bottom { | ||||
|     bottom: 8px; | ||||
| } | ||||
| 
 | ||||
| .mx_ContextualMenu_chevron_bottom { | ||||
|     position: absolute; | ||||
|     left: 0px; | ||||
|     bottom: -8px; | ||||
|     width: 0; | ||||
|     height: 0; | ||||
|     border-left: 8px solid transparent; | ||||
|     border-top: 8px solid $menu-border-color; | ||||
|     border-right: 8px solid transparent; | ||||
| } | ||||
| 
 | ||||
| .mx_ContextualMenu_chevron_bottom:after{ | ||||
|     content:''; | ||||
|     width: 0; | ||||
|     height: 0; | ||||
|     border-left: 7px solid transparent; | ||||
|     border-top: 7px solid $menu-bg-color; | ||||
|     border-right: 7px solid transparent; | ||||
|     position:absolute; | ||||
|     left: -7px; | ||||
|     bottom: 1px; | ||||
| } | ||||
| 
 | ||||
| .mx_ContextualMenu_field { | ||||
|     padding: 3px 6px 3px 6px; | ||||
|     cursor: pointer; | ||||
|  |  | |||
|  | @ -0,0 +1,43 @@ | |||
| /* | ||||
| Copyright 2017 Travis Ralston | ||||
| 
 | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
| 
 | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| 
 | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| .mx_MemberPresenceAvatar { | ||||
|     display: inline-block; | ||||
|     position: relative; | ||||
| } | ||||
| 
 | ||||
| .mx_MemberPresenceAvatar_status { | ||||
|     display: block; | ||||
|     width: 10px; | ||||
|     height: 10px; | ||||
|     border-radius: 10px; | ||||
| 
 | ||||
|     position: absolute; | ||||
|     bottom: -2px; | ||||
|     right: -3px; | ||||
| } | ||||
| 
 | ||||
| .mx_MemberPresenceAvatar_status_online { | ||||
|     background-color: $presence-online; | ||||
| } | ||||
| 
 | ||||
| .mx_MemberPresenceAvatar_status_unavailable { | ||||
|     background-color: $presence-unavailable; | ||||
| } | ||||
| 
 | ||||
| .mx_MemberPresenceAvatar_status_offline { | ||||
|     background-color: $presence-offline; | ||||
| } | ||||
|  | @ -135,6 +135,11 @@ $e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color | |||
| $e2e-unverified-color: #e8bf37; | ||||
| $e2e-warning-color: #ba6363; | ||||
| 
 | ||||
| // presence | ||||
| $presence-online: #60de00; | ||||
| $presence-unavailable: #deb800; | ||||
| $presence-offline: #b7b7b7; | ||||
| 
 | ||||
| /*** ImageView ***/ | ||||
| $lightbox-bg-color: #454545; | ||||
| $lightbox-fg-color: #ffffff; | ||||
|  |  | |||
|  | @ -0,0 +1,42 @@ | |||
| /* | ||||
| Copyright 2017 Travis Ralston | ||||
| 
 | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
| 
 | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| 
 | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
| .mx_PresenceContextMenuOption_indicator { | ||||
|     width: 10px; | ||||
|     height: 10px; | ||||
|     border-radius: 10px; | ||||
|     display: inline-block; | ||||
|     margin-right: 5px; | ||||
| } | ||||
| 
 | ||||
| .mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_online { | ||||
|     background-color: $presence-online; | ||||
| } | ||||
| 
 | ||||
| .mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_unavailable { | ||||
|     background-color: $presence-unavailable; | ||||
| } | ||||
| 
 | ||||
| .mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_offline { | ||||
|     background-color: $presence-offline; | ||||
| } | ||||
| 
 | ||||
| .mx_PresenceContextMenuOption { | ||||
|     padding: 2px; | ||||
| } | ||||
| 
 | ||||
| .mx_PresenceContextMenuOption.mx_PresenceContextMenuOption_current { | ||||
|     font-weight: 700; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	 Matthew Hodgson
						Matthew Hodgson