Merge pull request #2224 from matrix-org/bwindels/removedndmore
Redesign: remove room list truncation and DND
This commit is contained in:
commit
f2ee8307dc
4 changed files with 15 additions and 242 deletions
|
@ -127,81 +127,6 @@ limitations under the License.
|
||||||
transform: rotateZ(-90deg);
|
transform: rotateZ(-90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The overflow section */
|
|
||||||
.mx_RoomSubList_ellipsis {
|
|
||||||
display: block;
|
|
||||||
line-height: 11px;
|
|
||||||
height: 18px;
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
background-color: $secondary-accent-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomSubList_line {
|
|
||||||
display: inline-block;
|
|
||||||
width: 159px;
|
|
||||||
border-top: dotted 2px $accent-color;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomSubList_more {
|
|
||||||
display: inline-block;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: 10px;
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: left;
|
|
||||||
color: $accent-color;
|
|
||||||
padding-left: 7px;
|
|
||||||
padding-right: 7px;
|
|
||||||
padding-left: 7px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomSubList_moreBadge {
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 15px;
|
|
||||||
height: 13px;
|
|
||||||
position: absolute;
|
|
||||||
right: 8px; /*gutter */
|
|
||||||
top: -2px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: solid 1px $accent-color;
|
|
||||||
color: $accent-fg-color;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 10px;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 1px;
|
|
||||||
padding-left: 3px;
|
|
||||||
padding-right: 3px;
|
|
||||||
background-color: $primary-bg-color;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomSubList_moreBadge.mx_RoomSubList_moreBadgeNotify {
|
|
||||||
background-color: $accent-color;
|
|
||||||
border: 0;
|
|
||||||
padding-top: 3px;
|
|
||||||
padding-left: 4px;
|
|
||||||
padding-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomSubList_moreBadge.mx_RoomSubList_moreBadgeHighlight {
|
|
||||||
background-color: $warning-color;
|
|
||||||
border: 0;
|
|
||||||
padding-top: 3px;
|
|
||||||
padding-left: 4px;
|
|
||||||
padding-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomSubList_ellipsis .mx_RoomSubList_chevronDown {
|
|
||||||
position: relative;
|
|
||||||
top: 4px;
|
|
||||||
left: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.collapsed {
|
.collapsed {
|
||||||
.mx_RoomSubList_label {
|
.mx_RoomSubList_label {
|
||||||
height: 17px;
|
height: 17px;
|
||||||
|
|
|
@ -33,8 +33,6 @@ import PropTypes from 'prop-types';
|
||||||
// turn this on for drop & drag console debugging galore
|
// turn this on for drop & drag console debugging galore
|
||||||
const debug = false;
|
const debug = false;
|
||||||
|
|
||||||
const TRUNCATE_AT = 10;
|
|
||||||
|
|
||||||
const RoomSubList = React.createClass({
|
const RoomSubList = React.createClass({
|
||||||
displayName: 'RoomSubList',
|
displayName: 'RoomSubList',
|
||||||
|
|
||||||
|
@ -44,7 +42,6 @@ const RoomSubList = React.createClass({
|
||||||
list: PropTypes.arrayOf(PropTypes.object).isRequired,
|
list: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
label: PropTypes.string.isRequired,
|
label: PropTypes.string.isRequired,
|
||||||
tagName: PropTypes.string,
|
tagName: PropTypes.string,
|
||||||
editable: PropTypes.bool,
|
|
||||||
|
|
||||||
order: PropTypes.string.isRequired,
|
order: PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
@ -68,7 +65,6 @@ const RoomSubList = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
hidden: this.props.startAsHidden || false,
|
hidden: this.props.startAsHidden || false,
|
||||||
truncateAt: -1, // TRUNCATE_AT,
|
|
||||||
sortedList: [],
|
sortedList: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -144,12 +140,6 @@ const RoomSubList = React.createClass({
|
||||||
// The header isCollapsable, so the click is to be interpreted as collapse and truncation logic
|
// The header isCollapsable, so the click is to be interpreted as collapse and truncation logic
|
||||||
const isHidden = !this.state.hidden;
|
const isHidden = !this.state.hidden;
|
||||||
this.setState({hidden: isHidden});
|
this.setState({hidden: isHidden});
|
||||||
|
|
||||||
if (isHidden) {
|
|
||||||
// as good a way as any to reset the truncate state
|
|
||||||
this.setState({truncateAt: TRUNCATE_AT});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.onShowMoreRooms();
|
this.props.onShowMoreRooms();
|
||||||
this.props.onHeaderClick(isHidden);
|
this.props.onHeaderClick(isHidden);
|
||||||
} else {
|
} else {
|
||||||
|
@ -178,10 +168,9 @@ const RoomSubList = React.createClass({
|
||||||
/**
|
/**
|
||||||
* Total up all the notification counts from the rooms
|
* Total up all the notification counts from the rooms
|
||||||
*
|
*
|
||||||
* @param {Number} truncateAt If supplied will only total notifications for rooms outside the truncation number
|
|
||||||
* @returns {Array} The array takes the form [total, highlight] where highlight is a bool
|
* @returns {Array} The array takes the form [total, highlight] where highlight is a bool
|
||||||
*/
|
*/
|
||||||
roomNotificationCount: function(truncateAt) {
|
roomNotificationCount: function() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
if (this.props.isInvite) {
|
if (this.props.isInvite) {
|
||||||
|
@ -189,20 +178,18 @@ const RoomSubList = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.props.list.reduce(function(result, room, index) {
|
return this.props.list.reduce(function(result, room, index) {
|
||||||
if (truncateAt === undefined || index >= truncateAt) {
|
const roomNotifState = RoomNotifs.getRoomNotifsState(room.roomId);
|
||||||
const roomNotifState = RoomNotifs.getRoomNotifsState(room.roomId);
|
const highlight = room.getUnreadNotificationCount('highlight') > 0;
|
||||||
const highlight = room.getUnreadNotificationCount('highlight') > 0;
|
const notificationCount = room.getUnreadNotificationCount();
|
||||||
const notificationCount = room.getUnreadNotificationCount();
|
|
||||||
|
|
||||||
const notifBadges = notificationCount > 0 && self._shouldShowNotifBadge(roomNotifState);
|
const notifBadges = notificationCount > 0 && self._shouldShowNotifBadge(roomNotifState);
|
||||||
const mentionBadges = highlight && self._shouldShowMentionBadge(roomNotifState);
|
const mentionBadges = highlight && self._shouldShowMentionBadge(roomNotifState);
|
||||||
const badges = notifBadges || mentionBadges;
|
const badges = notifBadges || mentionBadges;
|
||||||
|
|
||||||
if (badges) {
|
if (badges) {
|
||||||
result[0] += notificationCount;
|
result[0] += notificationCount;
|
||||||
if (highlight) {
|
if (highlight) {
|
||||||
result[1] = true;
|
result[1] = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -217,15 +204,9 @@ const RoomSubList = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
makeRoomTiles: function() {
|
makeRoomTiles: function() {
|
||||||
const DNDRoomTile = sdk.getComponent("rooms.DNDRoomTile");
|
|
||||||
const RoomTile = sdk.getComponent("rooms.RoomTile");
|
const RoomTile = sdk.getComponent("rooms.RoomTile");
|
||||||
return this.state.sortedList.map((room, index) => {
|
return this.state.sortedList.map((room, index) => {
|
||||||
// XXX: is it evil to pass in this as a prop to RoomTile? Yes.
|
return <RoomTile
|
||||||
|
|
||||||
// We should only use <DNDRoomTile /> when editable
|
|
||||||
const RoomTileComponent = this.props.editable ? DNDRoomTile : RoomTile;
|
|
||||||
return <RoomTileComponent
|
|
||||||
index={index} // For DND
|
|
||||||
room={room}
|
room={room}
|
||||||
roomSubList={this}
|
roomSubList={this}
|
||||||
tagName={this.props.tagName}
|
tagName={this.props.tagName}
|
||||||
|
@ -356,44 +337,7 @@ const RoomSubList = React.createClass({
|
||||||
// <div className="mx_RoomSubList_roomCount">{ roomCount }</div>
|
// <div className="mx_RoomSubList_roomCount">{ roomCount }</div>
|
||||||
},
|
},
|
||||||
|
|
||||||
_createOverflowTile: function(overflowCount, totalCount) {
|
|
||||||
let content = <div className="mx_RoomSubList_chevronDown" />;
|
|
||||||
|
|
||||||
const overflowNotifications = this.roomNotificationCount(TRUNCATE_AT);
|
|
||||||
const overflowNotifCount = overflowNotifications[0];
|
|
||||||
const overflowNotifHighlight = overflowNotifications[1];
|
|
||||||
if (overflowNotifCount && !this.props.collapsed) {
|
|
||||||
content = FormattingUtils.formatCount(overflowNotifCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
const badgeClasses = classNames({
|
|
||||||
'mx_RoomSubList_moreBadge': true,
|
|
||||||
'mx_RoomSubList_moreBadgeNotify': overflowNotifCount && !this.props.collapsed,
|
|
||||||
'mx_RoomSubList_moreBadgeHighlight': overflowNotifHighlight && !this.props.collapsed,
|
|
||||||
});
|
|
||||||
|
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
|
||||||
return (
|
|
||||||
<AccessibleButton className="mx_RoomSubList_ellipsis" onClick={this._showFullMemberList}>
|
|
||||||
<div className="mx_RoomSubList_line" />
|
|
||||||
<div className="mx_RoomSubList_more">{_t("more")}</div>
|
|
||||||
<div className={badgeClasses}>{content}</div>
|
|
||||||
</AccessibleButton>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_showFullMemberList: function() {
|
|
||||||
this.setState({
|
|
||||||
truncateAt: -1,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.props.onShowMoreRooms();
|
|
||||||
this.props.onHeaderClick(false);
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const TruncatedList = sdk.getComponent('elements.TruncatedList');
|
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
|
|
||||||
if (this.props.showEmpty) {
|
if (this.props.showEmpty) {
|
||||||
|
@ -420,36 +364,14 @@ const RoomSubList = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.sortedList.length > 0 || this.props.extraTiles.length > 0 || this.props.editable) {
|
if (this.state.sortedList.length > 0 || this.props.extraTiles.length > 0) {
|
||||||
let subList;
|
|
||||||
const classes = "mx_RoomSubList";
|
|
||||||
|
|
||||||
if (!this.state.hidden) {
|
const subList = this.state.hidden ? undefined : content;
|
||||||
subList = <TruncatedList className={classes} truncateAt={this.state.truncateAt}
|
|
||||||
createOverflowElement={this._createOverflowTile}>
|
|
||||||
{content}
|
|
||||||
</TruncatedList>;
|
|
||||||
} else {
|
|
||||||
subList = <TruncatedList className={classes}>
|
|
||||||
</TruncatedList>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const subListContent = <div>
|
return <div className={"mx_RoomSubList"}>
|
||||||
{this._getHeaderJsx()}
|
{this._getHeaderJsx()}
|
||||||
{subList}
|
{subList}
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
return this.props.editable ?
|
|
||||||
<Droppable
|
|
||||||
droppableId={"room-sub-list-droppable_" + this.props.tagName}
|
|
||||||
type="draggable-RoomTile"
|
|
||||||
>
|
|
||||||
{(provided, snapshot) => (
|
|
||||||
<div ref={provided.innerRef}>
|
|
||||||
{subListContent}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Droppable> : subListContent;
|
|
||||||
} else {
|
} else {
|
||||||
const Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
if (this.props.showSpinner) {
|
if (this.props.showSpinner) {
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2015, 2016 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { Draggable } from 'react-beautiful-dnd';
|
|
||||||
import RoomTile from '../../../components/views/rooms/RoomTile';
|
|
||||||
|
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
export default class DNDRoomTile extends React.PureComponent {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.getClassName = this.getClassName.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
getClassName(isDragging) {
|
|
||||||
return classNames({
|
|
||||||
"mx_DNDRoomTile": true,
|
|
||||||
"mx_DNDRoomTile_dragging": isDragging,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const props = this.props;
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
<Draggable
|
|
||||||
key={props.room.roomId}
|
|
||||||
draggableId={props.tagName + '_' + props.room.roomId}
|
|
||||||
index={props.index}
|
|
||||||
type="draggable-RoomTile"
|
|
||||||
>
|
|
||||||
{ (provided, snapshot) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
ref={provided.innerRef}
|
|
||||||
{...provided.draggableProps}
|
|
||||||
{...provided.dragHandleProps}
|
|
||||||
>
|
|
||||||
<div className={this.getClassName(snapshot.isDragging)}>
|
|
||||||
<RoomTile {...props} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{ provided.placeholder }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} }
|
|
||||||
</Draggable>
|
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -631,7 +631,6 @@ module.exports = React.createClass({
|
||||||
<RoomSubList list={[]}
|
<RoomSubList list={[]}
|
||||||
extraTiles={this._makeGroupInviteTiles(self.props.searchFilter)}
|
extraTiles={this._makeGroupInviteTiles(self.props.searchFilter)}
|
||||||
label={_t('Community Invites')}
|
label={_t('Community Invites')}
|
||||||
editable={false}
|
|
||||||
order="recent"
|
order="recent"
|
||||||
isInvite={true}
|
isInvite={true}
|
||||||
collapsed={self.props.collapsed}
|
collapsed={self.props.collapsed}
|
||||||
|
@ -643,7 +642,6 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
<RoomSubList list={self.state.lists['im.vector.fake.invite']}
|
<RoomSubList list={self.state.lists['im.vector.fake.invite']}
|
||||||
label={_t('Invites')}
|
label={_t('Invites')}
|
||||||
editable={false}
|
|
||||||
order="recent"
|
order="recent"
|
||||||
isInvite={true}
|
isInvite={true}
|
||||||
incomingCall={self.state.incomingCall}
|
incomingCall={self.state.incomingCall}
|
||||||
|
@ -658,7 +656,6 @@ module.exports = React.createClass({
|
||||||
label={_t('Favourites')}
|
label={_t('Favourites')}
|
||||||
tagName="m.favourite"
|
tagName="m.favourite"
|
||||||
emptyContent={this._getEmptyContent('m.favourite')}
|
emptyContent={this._getEmptyContent('m.favourite')}
|
||||||
editable={true}
|
|
||||||
order="manual"
|
order="manual"
|
||||||
incomingCall={self.state.incomingCall}
|
incomingCall={self.state.incomingCall}
|
||||||
collapsed={self.props.collapsed}
|
collapsed={self.props.collapsed}
|
||||||
|
@ -672,7 +669,6 @@ module.exports = React.createClass({
|
||||||
tagName="im.vector.fake.direct"
|
tagName="im.vector.fake.direct"
|
||||||
emptyContent={this._getEmptyContent('im.vector.fake.direct')}
|
emptyContent={this._getEmptyContent('im.vector.fake.direct')}
|
||||||
headerItems={this._getHeaderItems('im.vector.fake.direct')}
|
headerItems={this._getHeaderItems('im.vector.fake.direct')}
|
||||||
editable={true}
|
|
||||||
order="recent"
|
order="recent"
|
||||||
incomingCall={self.state.incomingCall}
|
incomingCall={self.state.incomingCall}
|
||||||
collapsed={self.props.collapsed}
|
collapsed={self.props.collapsed}
|
||||||
|
@ -684,7 +680,6 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
<RoomSubList list={self.state.lists['im.vector.fake.recent']}
|
<RoomSubList list={self.state.lists['im.vector.fake.recent']}
|
||||||
label={_t('Rooms')}
|
label={_t('Rooms')}
|
||||||
editable={true}
|
|
||||||
emptyContent={this._getEmptyContent('im.vector.fake.recent')}
|
emptyContent={this._getEmptyContent('im.vector.fake.recent')}
|
||||||
headerItems={this._getHeaderItems('im.vector.fake.recent')}
|
headerItems={this._getHeaderItems('im.vector.fake.recent')}
|
||||||
order="recent"
|
order="recent"
|
||||||
|
@ -702,7 +697,6 @@ module.exports = React.createClass({
|
||||||
label={labelForTagName(tagName)}
|
label={labelForTagName(tagName)}
|
||||||
tagName={tagName}
|
tagName={tagName}
|
||||||
emptyContent={this._getEmptyContent(tagName)}
|
emptyContent={this._getEmptyContent(tagName)}
|
||||||
editable={true}
|
|
||||||
order="manual"
|
order="manual"
|
||||||
incomingCall={self.state.incomingCall}
|
incomingCall={self.state.incomingCall}
|
||||||
collapsed={self.props.collapsed}
|
collapsed={self.props.collapsed}
|
||||||
|
@ -717,7 +711,6 @@ module.exports = React.createClass({
|
||||||
label={_t('Low priority')}
|
label={_t('Low priority')}
|
||||||
tagName="m.lowpriority"
|
tagName="m.lowpriority"
|
||||||
emptyContent={this._getEmptyContent('m.lowpriority')}
|
emptyContent={this._getEmptyContent('m.lowpriority')}
|
||||||
editable={true}
|
|
||||||
order="recent"
|
order="recent"
|
||||||
incomingCall={self.state.incomingCall}
|
incomingCall={self.state.incomingCall}
|
||||||
collapsed={self.props.collapsed}
|
collapsed={self.props.collapsed}
|
||||||
|
@ -735,7 +728,6 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
label={_t('Historical')}
|
label={_t('Historical')}
|
||||||
editable={false}
|
|
||||||
order="recent"
|
order="recent"
|
||||||
collapsed={self.props.collapsed}
|
collapsed={self.props.collapsed}
|
||||||
alwaysShowHeader={true}
|
alwaysShowHeader={true}
|
||||||
|
@ -750,7 +742,6 @@ module.exports = React.createClass({
|
||||||
<RoomSubList list={self.state.lists['m.server_notice']}
|
<RoomSubList list={self.state.lists['m.server_notice']}
|
||||||
label={_t('System Alerts')}
|
label={_t('System Alerts')}
|
||||||
tagName="m.lowpriority"
|
tagName="m.lowpriority"
|
||||||
editable={false}
|
|
||||||
order="recent"
|
order="recent"
|
||||||
incomingCall={self.state.incomingCall}
|
incomingCall={self.state.incomingCall}
|
||||||
collapsed={self.props.collapsed}
|
collapsed={self.props.collapsed}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue