forked from matrix/element-web
Merge branch 'develop' into matthew/notif-panel
This commit is contained in:
commit
a047f81b84
|
@ -241,3 +241,4 @@ encrypted.
|
||||||
|
|
||||||
Note that historical encrypted messages cannot currently be decoded - history
|
Note that historical encrypted messages cannot currently be decoded - history
|
||||||
is therefore lost when the page is reloaded.
|
is therefore lost when the page is reloaded.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
|
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
|
||||||
"build:compile": "babel --source-maps -d lib src",
|
"build:compile": "babel --source-maps -d lib src",
|
||||||
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
|
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
|
||||||
"build:bundle:dev": "NODE_ENV=production webpack --optimize-occurence-order lib/vector/index.js vector/bundle.js",
|
"build:bundle:dev": "webpack --optimize-occurence-order lib/vector/index.js vector/bundle.js",
|
||||||
"build:staticfiles": "cpx -v node_modules/olm/olm.js vector/",
|
"build:staticfiles": "cpx -v node_modules/olm/olm.js vector/",
|
||||||
"build": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle",
|
"build": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle",
|
||||||
"build:dev": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle:dev",
|
"build:dev": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle:dev",
|
||||||
|
@ -47,8 +47,8 @@
|
||||||
"gfm.css": "^1.1.1",
|
"gfm.css": "^1.1.1",
|
||||||
"highlight.js": "^9.0.0",
|
"highlight.js": "^9.0.0",
|
||||||
"linkifyjs": "2.0.0-beta.4",
|
"linkifyjs": "2.0.0-beta.4",
|
||||||
"matrix-js-sdk": "0.5.6",
|
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
|
||||||
"matrix-react-sdk": "0.6.5",
|
"matrix-react-sdk": "matrix-org/matrix-react-sdk#develop",
|
||||||
"modernizr": "^3.1.0",
|
"modernizr": "^3.1.0",
|
||||||
"q": "^1.4.1",
|
"q": "^1.4.1",
|
||||||
"react": "^15.2.1",
|
"react": "^15.2.1",
|
||||||
|
|
|
@ -17,15 +17,20 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
var ReactDOM = require('react-dom');
|
||||||
|
var classNames = require('classnames');
|
||||||
var DropTarget = require('react-dnd').DropTarget;
|
var DropTarget = require('react-dnd').DropTarget;
|
||||||
var sdk = require('matrix-react-sdk')
|
var sdk = require('matrix-react-sdk')
|
||||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||||
var Unread = require('matrix-react-sdk/lib/Unread');
|
var Unread = require('matrix-react-sdk/lib/Unread');
|
||||||
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||||
|
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
|
||||||
|
|
||||||
// turn this on for drop & drag console debugging galore
|
// turn this on for drop & drag console debugging galore
|
||||||
var debug = false;
|
var debug = false;
|
||||||
|
|
||||||
|
const TRUNCATE_AT = 10;
|
||||||
|
|
||||||
var roomListTarget = {
|
var roomListTarget = {
|
||||||
canDrop: function() {
|
canDrop: function() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -80,7 +85,8 @@ var RoomSubList = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
hidden: this.props.startAsHidden || false,
|
hidden: this.props.startAsHidden || false,
|
||||||
truncateAt: 20,
|
capTruncate: this.props.list.length > TRUNCATE_AT,
|
||||||
|
truncateAt: this.props.list.length > TRUNCATE_AT ? TRUNCATE_AT : -1,
|
||||||
sortedList: [],
|
sortedList: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -109,17 +115,62 @@ var RoomSubList = React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onClick: function(ev) {
|
// The header is collapsable if it is hidden or not stuck
|
||||||
var isHidden = !this.state.hidden;
|
// The dataset elements are added in the RoomList _initAndPositionStickyHeaders method
|
||||||
this.setState({ hidden : isHidden });
|
isCollapsableOnClick: function() {
|
||||||
|
var stuck = this.refs.header.dataset.stuck;
|
||||||
|
if (this.state.hidden || stuck === undefined || stuck === "none") {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
if (isHidden) {
|
onClick: function(ev) {
|
||||||
// as good a way as any to reset the truncate state
|
if (this.isCollapsableOnClick()) {
|
||||||
this.setState({ truncateAt : 20 });
|
// The header iscCollapsable, so the click is to be interpreted as collapse and truncation logic
|
||||||
this.props.onShowMoreRooms();
|
var isHidden = false;
|
||||||
|
var isTruncatable = this.props.list.length > TRUNCATE_AT;
|
||||||
|
|
||||||
|
if (this.state.hidden && (this.state.capTruncate && isTruncatable)) {
|
||||||
|
isHidden = false;
|
||||||
|
this.setState({
|
||||||
|
hidden : isHidden,
|
||||||
|
capTruncate : true,
|
||||||
|
truncateAt : TRUNCATE_AT
|
||||||
|
});
|
||||||
|
} else if ((!this.state.hidden && this.state.capTruncate)
|
||||||
|
|| (this.state.hidden && (this.state.capTruncate && !isTruncatable)))
|
||||||
|
{
|
||||||
|
isHidden = false;
|
||||||
|
this.setState({
|
||||||
|
hidden : isHidden,
|
||||||
|
capTruncate : false,
|
||||||
|
truncateAt : -1
|
||||||
|
});
|
||||||
|
} else if (!this.state.hidden && !this.state.capTruncate) {
|
||||||
|
isHidden = true;
|
||||||
|
this.setState({
|
||||||
|
hidden : isHidden,
|
||||||
|
capTruncate : true,
|
||||||
|
truncateAt : TRUNCATE_AT
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Catch any weird states the system gets into
|
||||||
|
isHidden = false;
|
||||||
|
this.setState({
|
||||||
|
hidden : isHidden,
|
||||||
|
capTruncate : true,
|
||||||
|
truncateAt : TRUNCATE_AT
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.props.onShowMoreRooms();
|
||||||
this.props.onHeaderClick(isHidden);
|
this.props.onHeaderClick(isHidden);
|
||||||
|
} else {
|
||||||
|
// The header is stuck, so the click is to be interpreted as a scroll to the header
|
||||||
|
this.props.onHeaderClick(this.state.hidden, this.refs.header.dataset.originalPosition);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
tsOfNewestEvent: function(room) {
|
tsOfNewestEvent: function(room) {
|
||||||
|
@ -186,6 +237,44 @@ var RoomSubList = React.createClass({
|
||||||
this.setState({ sortedList: list.sort(comparator) });
|
this.setState({ sortedList: list.sort(comparator) });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_shouldShowNotifBadge: function(roomNotifState) {
|
||||||
|
const showBadgeInStates = [RoomNotifs.ALL_MESSAGES, RoomNotifs.ALL_MESSAGES_LOUD];
|
||||||
|
return showBadgeInStates.indexOf(roomNotifState) > -1;
|
||||||
|
},
|
||||||
|
|
||||||
|
_shouldShowMentionBadge: function(roomNotifState) {
|
||||||
|
return roomNotifState != RoomNotifs.MUTE;
|
||||||
|
},
|
||||||
|
|
||||||
|
roomNotificationCount: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
return this.props.list.reduce(function(result, room) {
|
||||||
|
var roomNotifState = RoomNotifs.getRoomNotifsState(room.roomId);
|
||||||
|
var highlight = room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites';
|
||||||
|
var notificationCount = room.getUnreadNotificationCount();
|
||||||
|
|
||||||
|
const notifBadges = notificationCount > 0 && self._shouldShowNotifBadge(roomNotifState);
|
||||||
|
const mentionBadges = highlight && self._shouldShowMentionBadge(roomNotifState);
|
||||||
|
const badges = notifBadges || mentionBadges;
|
||||||
|
|
||||||
|
if (badges) {
|
||||||
|
result[0] += notificationCount;
|
||||||
|
if (highlight) {
|
||||||
|
result[1] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}, [0, false]);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateSubListCount: function() {
|
||||||
|
// Force an update by setting the state to the current state
|
||||||
|
// Doing it this way rather than using forceUpdate(), so that the shouldComponentUpdate()
|
||||||
|
// method is honoured
|
||||||
|
this.setState(this.state);
|
||||||
|
},
|
||||||
|
|
||||||
moveRoomTile: function(room, atIndex) {
|
moveRoomTile: function(room, atIndex) {
|
||||||
if (debug) console.log("moveRoomTile: id " + room.roomId + ", atIndex " + atIndex);
|
if (debug) console.log("moveRoomTile: id " + room.roomId + ", atIndex " + atIndex);
|
||||||
//console.log("moveRoomTile before: " + JSON.stringify(this.state.rooms));
|
//console.log("moveRoomTile before: " + JSON.stringify(this.state.rooms));
|
||||||
|
@ -293,6 +382,7 @@ var RoomSubList = React.createClass({
|
||||||
unread={ Unread.doesRoomHaveUnreadMessages(room) }
|
unread={ Unread.doesRoomHaveUnreadMessages(room) }
|
||||||
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites' }
|
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.label === 'Invites' }
|
||||||
isInvite={ self.props.label === 'Invites' }
|
isInvite={ self.props.label === 'Invites' }
|
||||||
|
refreshSubList={ self._updateSubListCount }
|
||||||
incomingCall={ self.props.incomingCall && (self.props.incomingCall.roomId === room.roomId) ? self.props.incomingCall : null } />
|
incomingCall={ self.props.incomingCall && (self.props.incomingCall.roomId === room.roomId) ? self.props.incomingCall : null } />
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -300,36 +390,48 @@ var RoomSubList = React.createClass({
|
||||||
|
|
||||||
_getHeaderJsx: function() {
|
_getHeaderJsx: function() {
|
||||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
return (
|
|
||||||
<h2 onClick={ this.onClick } className="mx_RoomSubList_label">
|
|
||||||
{ this.props.collapsed ? '' : this.props.label }
|
|
||||||
<img className="mx_RoomSubList_chevron"
|
|
||||||
src={ this.state.hidden ? "img/list-close.svg" : "img/list-open.svg" }
|
|
||||||
width="10" height="10" />
|
|
||||||
</h2>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_createOverflowTile: function(overflowCount, totalCount) {
|
var subListNotifications = this.roomNotificationCount();
|
||||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
var subListNotifCount = subListNotifications[0];
|
||||||
// XXX: this is duplicated from RoomTile - factor it out
|
var subListNotifHighlight = subListNotifications[1];
|
||||||
return (
|
|
||||||
<div className="mx_RoomTile mx_RoomTile_ellipsis" onClick={this._showFullMemberList}>
|
|
||||||
<div className="mx_RoomTile_avatar">
|
|
||||||
<BaseAvatar url="img/ellipsis.svg" name="..." width={24} height={24} />
|
|
||||||
</div>
|
|
||||||
<div className="mx_RoomTile_name">and { overflowCount } others...</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_showFullMemberList: function() {
|
var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
|
||||||
this.setState({
|
var isTruncatable = this.props.list.length > TRUNCATE_AT;
|
||||||
truncateAt: -1
|
if (!this.state.hidden && this.state.capTruncate && isTruncatable) {
|
||||||
|
roomCount = TRUNCATE_AT + " of " + roomCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
var chevronClasses = classNames({
|
||||||
|
'mx_RoomSubList_chevron': true,
|
||||||
|
'mx_RoomSubList_chevronUp': this.state.hidden,
|
||||||
|
'mx_RoomSubList_chevronRight': !this.state.hidden && this.state.capTruncate,
|
||||||
|
'mx_RoomSubList_chevronDown': !this.state.hidden && !this.state.capTruncate,
|
||||||
});
|
});
|
||||||
this.props.onShowMoreRooms();
|
|
||||||
|
var badgeClasses = classNames({
|
||||||
|
'mx_RoomSubList_badge': true,
|
||||||
|
'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
|
||||||
|
});
|
||||||
|
|
||||||
|
var badge;
|
||||||
|
if (subListNotifCount > 0) {
|
||||||
|
badge = <div className={badgeClasses}>{subListNotifCount > 99 ? "99+" : subListNotifCount}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mx_RoomSubList_labelContainer" ref="header">
|
||||||
|
<div onClick={ this.onClick } className="mx_RoomSubList_label">
|
||||||
|
{ this.props.collapsed ? '' : this.props.label }
|
||||||
|
<div className="mx_RoomSubList_roomCount">{roomCount}</div>
|
||||||
|
<div className={chevronClasses}></div>
|
||||||
|
{badge}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_createOverflowTile: function() {}, // NOP
|
||||||
|
|
||||||
// Fix any undefined order elements of a room in a manual ordered list
|
// Fix any undefined order elements of a room in a manual ordered list
|
||||||
// room.tag[tagname].order
|
// room.tag[tagname].order
|
||||||
_fixUndefinedOrder: function(list) {
|
_fixUndefinedOrder: function(list) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ limitations under the License.
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
padding-top: 24px;
|
padding-top: 24px;
|
||||||
padding-bottom: 22px;
|
padding-bottom: 22px;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
display: -webkit-flex;
|
display: -webkit-flex;
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_RoomList {
|
.mx_RoomList {
|
||||||
padding-top: 8px;
|
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
}
|
}
|
||||||
|
@ -33,3 +32,8 @@ limitations under the License.
|
||||||
overflow-x: hidden ! important;
|
overflow-x: hidden ! important;
|
||||||
overflow-y: scroll ! important;
|
overflow-y: scroll ! important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure the scrollbar is above the sticky headers from RoomList */
|
||||||
|
.mx_RoomList_scrollbar .gm-scrollbar.-vertical {
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
|
@ -109,9 +109,8 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapsed .mx_RoomTile_badge {
|
.collapsed .mx_RoomTile_badge {
|
||||||
top: -2px;
|
top: 0px;
|
||||||
min-width: 12px;
|
min-width: 12px;
|
||||||
height: 16px;
|
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 0px 4px 0px 4px;
|
padding: 0px 4px 0px 4px;
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
|
@ -129,22 +128,22 @@ limitations under the License.
|
||||||
display: block;
|
display: block;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
margin-left: 6px;
|
margin-left: 5px;
|
||||||
border-top: 8px solid #ff0064;
|
border-top: 5px solid #ff0064;
|
||||||
border-right: 10px solid transparent;
|
border-right: 7px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile_badge {
|
.mx_RoomTile_badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 19px;
|
min-width: 15px;
|
||||||
height: 17px;
|
height: 15px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 8px; /*gutter */
|
right: 8px; /*gutter */
|
||||||
top: 9px;
|
top: 9px;
|
||||||
border-radius: 14px;
|
border-radius: 8px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 11px;
|
font-size: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 1px;
|
padding-top: 1px;
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
|
@ -175,7 +174,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile_selected {
|
.mx_RoomTile_selected {
|
||||||
background-color: rgba(118,207,166,0.2);
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile .mx_RoomTile_name.mx_RoomTile_badgeShown {
|
.mx_RoomTile .mx_RoomTile_name.mx_RoomTile_badgeShown {
|
||||||
|
@ -187,5 +186,3 @@ limitations under the License.
|
||||||
right: 0px;
|
right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile:hover {
|
|
||||||
}
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ limitations under the License.
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel.collapsed .mx_BottomLeftMenu {
|
.mx_LeftPanel.collapsed .mx_BottomLeftMenu {
|
||||||
|
@ -62,7 +63,7 @@ limitations under the License.
|
||||||
-webkit-order: 3;
|
-webkit-order: 3;
|
||||||
order: 3;
|
order: 3;
|
||||||
|
|
||||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
border-top: 1px solid rgba(118, 207, 166, 0.2);
|
||||||
margin-left: 16px; /* gutter */
|
margin-left: 16px; /* gutter */
|
||||||
margin-right: 16px; /* gutter */
|
margin-right: 16px; /* gutter */
|
||||||
-webkit-flex: 0 0 60px;
|
-webkit-flex: 0 0 60px;
|
||||||
|
|
|
@ -20,23 +20,128 @@ limitations under the License.
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_RoomSubList_labelContainer {
|
||||||
|
height: 31px; /* mx_RoomSubList_label height including border */
|
||||||
|
width: 235px; /* LHS Panel width */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_RoomSubList_label {
|
.mx_RoomSubList_label {
|
||||||
|
position: relative;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: #3d3b39;
|
color: #3d3b39;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 13px;
|
font-size: 12px;
|
||||||
|
width: 203px; /* padding + width = LHS Panel width */
|
||||||
|
height: 17px; /* padding + height = 29px, same as mx_RoomSubList_stickyContainer */
|
||||||
padding-left: 16px; /* gutter */
|
padding-left: 16px; /* gutter */
|
||||||
padding-right: 16px; /* gutter */
|
padding-right: 16px; /* gutter */
|
||||||
margin-top: 8px;
|
padding-top: 6px;
|
||||||
margin-bottom: 4px;
|
padding-bottom: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
background-color: rgba(118, 207, 166, 0.2);
|
||||||
|
border-top: solid 2px #eaf5f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSubList_label.mx_RoomSubList_fixed {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
z-index: 4;
|
||||||
|
/* pointer-events: none; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .mx_RoomSubList_label {
|
||||||
|
height: 17px;
|
||||||
|
width: 28px; /* collapsed LHS Panel width */
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .mx_RoomSubList_labelContainer {
|
||||||
|
width: 28px; /* collapsed LHS Panel width */
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSubList_roomCount {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #76cfa6;
|
||||||
|
padding-left: 5px;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .mx_RoomSubList_roomCount {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSubList_badge {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
position: absolute;
|
||||||
|
right: 8px; /*gutter */
|
||||||
|
top: 7px;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 1px;
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-right: 4px;
|
||||||
|
background-color: #76cfa6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .mx_RoomSubList_badge {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSubList_badgeHighlight {
|
||||||
|
background-color: #ff0064;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the bottom of the speech bubble */
|
||||||
|
.mx_RoomSubList_badgeHighlight:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
border-top: 5px solid #ff0064;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide the bottom of speech bubble */
|
||||||
|
.collapsed .mx_RoomSubList_badgeHighlight:after {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomSubList_chevron {
|
.mx_RoomSubList_chevron {
|
||||||
padding-left: 4px;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
right: 41px;
|
||||||
|
top: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapsed .mx_RoomSubList_chevron {
|
.mx_RoomSubList_chevronDown {
|
||||||
padding-left: 12px;
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 5px solid transparent;
|
||||||
|
border-right: 5px solid transparent;
|
||||||
|
border-top: 6px solid #76cfa6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSubList_chevronUp {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 5px solid transparent;
|
||||||
|
border-right: 5px solid transparent;
|
||||||
|
border-bottom: 6px solid #76cfa6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSubList_chevronRight {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 5px solid transparent;
|
||||||
|
border-left: 6px solid #76cfa6;
|
||||||
|
border-bottom: 5px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue