Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
e79d502972
5 changed files with 105 additions and 17 deletions
|
@ -35,6 +35,7 @@ const TagOrderActions = {};
|
||||||
TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) {
|
TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) {
|
||||||
// Only commit tags if the state is ready, i.e. not null
|
// Only commit tags if the state is ready, i.e. not null
|
||||||
let tags = TagOrderStore.getOrderedTags();
|
let tags = TagOrderStore.getOrderedTags();
|
||||||
|
let removedTags = TagOrderStore.getRemovedTagsAccountData();
|
||||||
if (!tags) {
|
if (!tags) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -42,17 +43,19 @@ TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) {
|
||||||
tags = tags.filter((t) => t !== tag);
|
tags = tags.filter((t) => t !== tag);
|
||||||
tags = [...tags.slice(0, destinationIx), tag, ...tags.slice(destinationIx)];
|
tags = [...tags.slice(0, destinationIx), tag, ...tags.slice(destinationIx)];
|
||||||
|
|
||||||
|
removedTags = removedTags.filter((t) => t !== tag);
|
||||||
|
|
||||||
const storeId = TagOrderStore.getStoreId();
|
const storeId = TagOrderStore.getStoreId();
|
||||||
|
|
||||||
return asyncAction('TagOrderActions.moveTag', () => {
|
return asyncAction('TagOrderActions.moveTag', () => {
|
||||||
Analytics.trackEvent('TagOrderActions', 'commitTagOrdering');
|
Analytics.trackEvent('TagOrderActions', 'commitTagOrdering');
|
||||||
return matrixClient.setAccountData(
|
return matrixClient.setAccountData(
|
||||||
'im.vector.web.tag_ordering',
|
'im.vector.web.tag_ordering',
|
||||||
{tags, _storeId: storeId},
|
{tags, removedTags, _storeId: storeId},
|
||||||
);
|
);
|
||||||
}, () => {
|
}, () => {
|
||||||
// For an optimistic update
|
// For an optimistic update
|
||||||
return {tags};
|
return {tags, removedTags};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ limitations under the License.
|
||||||
import * as Matrix from 'matrix-js-sdk';
|
import * as Matrix from 'matrix-js-sdk';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { DragDropContext } from 'react-beautiful-dnd';
|
||||||
|
|
||||||
import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';
|
import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';
|
||||||
import Notifier from '../../Notifier';
|
import Notifier from '../../Notifier';
|
||||||
|
@ -30,6 +31,9 @@ import sessionStore from '../../stores/SessionStore';
|
||||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||||
import SettingsStore from "../../settings/SettingsStore";
|
import SettingsStore from "../../settings/SettingsStore";
|
||||||
|
|
||||||
|
import TagOrderActions from '../../actions/TagOrderActions';
|
||||||
|
import RoomListActions from '../../actions/RoomListActions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is what our MatrixChat shows when we are logged in. The precise view is
|
* This is what our MatrixChat shows when we are logged in. The precise view is
|
||||||
* determined by the page_type property.
|
* determined by the page_type property.
|
||||||
|
@ -207,6 +211,50 @@ const LoggedInView = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onDragEnd: function(result) {
|
||||||
|
// Dragged to an invalid destination, not onto a droppable
|
||||||
|
if (!result.destination) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dest = result.destination.droppableId;
|
||||||
|
|
||||||
|
if (dest === 'tag-panel-droppable') {
|
||||||
|
// Could be "GroupTile +groupId:domain"
|
||||||
|
const draggableId = result.draggableId.split(' ').pop();
|
||||||
|
|
||||||
|
// Dispatch synchronously so that the TagPanel receives an
|
||||||
|
// optimistic update from TagOrderStore before the previous
|
||||||
|
// state is shown.
|
||||||
|
dis.dispatch(TagOrderActions.moveTag(
|
||||||
|
this._matrixClient,
|
||||||
|
draggableId,
|
||||||
|
result.destination.index,
|
||||||
|
), true);
|
||||||
|
} else if (dest.startsWith('room-sub-list-droppable_')) {
|
||||||
|
this._onRoomTileEndDrag(result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onRoomTileEndDrag: function(result) {
|
||||||
|
let newTag = result.destination.droppableId.split('_')[1];
|
||||||
|
let prevTag = result.source.droppableId.split('_')[1];
|
||||||
|
if (newTag === 'undefined') newTag = undefined;
|
||||||
|
if (prevTag === 'undefined') prevTag = undefined;
|
||||||
|
|
||||||
|
const roomId = result.draggableId.split('_')[1];
|
||||||
|
|
||||||
|
const oldIndex = result.source.index;
|
||||||
|
const newIndex = result.destination.index;
|
||||||
|
|
||||||
|
dis.dispatch(RoomListActions.tagRoom(
|
||||||
|
this._matrixClient,
|
||||||
|
this._matrixClient.getRoom(roomId),
|
||||||
|
prevTag, newTag,
|
||||||
|
oldIndex, newIndex,
|
||||||
|
), true);
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const LeftPanel = sdk.getComponent('structures.LeftPanel');
|
const LeftPanel = sdk.getComponent('structures.LeftPanel');
|
||||||
const RightPanel = sdk.getComponent('structures.RightPanel');
|
const RightPanel = sdk.getComponent('structures.RightPanel');
|
||||||
|
@ -328,16 +376,18 @@ const LoggedInView = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className='mx_MatrixChat_wrapper'>
|
<div className='mx_MatrixChat_wrapper'>
|
||||||
{ topBar }
|
{ topBar }
|
||||||
<div className={bodyClasses}>
|
<DragDropContext onDragEnd={this._onDragEnd}>
|
||||||
<LeftPanel
|
<div className={bodyClasses}>
|
||||||
collapsed={this.props.collapseLhs || false}
|
<LeftPanel
|
||||||
disabled={this.props.leftDisabled}
|
collapsed={this.props.collapseLhs || false}
|
||||||
/>
|
disabled={this.props.leftDisabled}
|
||||||
<main className='mx_MatrixChat_middlePanel'>
|
/>
|
||||||
{ page_element }
|
<main className='mx_MatrixChat_middlePanel'>
|
||||||
</main>
|
{ page_element }
|
||||||
{ right_panel }
|
</main>
|
||||||
</div>
|
{ right_panel }
|
||||||
|
</div>
|
||||||
|
</DragDropContext>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -73,8 +73,10 @@ export default withMatrixClient(React.createClass({
|
||||||
});
|
});
|
||||||
contentHeader = groupNodes.length > 0 ? <h3>{ _t('Your Communities') }</h3> : <div />;
|
contentHeader = groupNodes.length > 0 ? <h3>{ _t('Your Communities') }</h3> : <div />;
|
||||||
content = groupNodes.length > 0 ?
|
content = groupNodes.length > 0 ?
|
||||||
<GeminiScrollbar className="mx_MyGroups_joinedGroups">
|
<GeminiScrollbar>
|
||||||
{ groupNodes }
|
<div className="mx_MyGroups_joinedGroups">
|
||||||
|
{ groupNodes }
|
||||||
|
</div>
|
||||||
</GeminiScrollbar> :
|
</GeminiScrollbar> :
|
||||||
<div className="mx_MyGroups_placeholder">
|
<div className="mx_MyGroups_placeholder">
|
||||||
{ _t(
|
{ _t(
|
||||||
|
|
|
@ -17,10 +17,12 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {MatrixClient} from 'matrix-js-sdk';
|
import {MatrixClient} from 'matrix-js-sdk';
|
||||||
|
import { Draggable, Droppable } from 'react-beautiful-dnd';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
import FlairStore from '../../../stores/FlairStore';
|
import FlairStore from '../../../stores/FlairStore';
|
||||||
|
|
||||||
|
|
||||||
const GroupTile = React.createClass({
|
const GroupTile = React.createClass({
|
||||||
displayName: 'GroupTile',
|
displayName: 'GroupTile',
|
||||||
|
|
||||||
|
@ -78,9 +80,39 @@ const GroupTile = React.createClass({
|
||||||
profile.avatarUrl, avatarHeight, avatarHeight, "crop",
|
profile.avatarUrl, avatarHeight, avatarHeight, "crop",
|
||||||
) : null;
|
) : null;
|
||||||
return <AccessibleButton className="mx_GroupTile" onClick={this.onClick}>
|
return <AccessibleButton className="mx_GroupTile" onClick={this.onClick}>
|
||||||
<div className="mx_GroupTile_avatar">
|
<Droppable droppableId="my-groups-droppable" type="draggable-TagTile">
|
||||||
<BaseAvatar name={name} url={httpUrl} width={avatarHeight} height={avatarHeight} />
|
{ (droppableProvided, droppableSnapshot) => (
|
||||||
</div>
|
<div ref={droppableProvided.innerRef}>
|
||||||
|
<Draggable
|
||||||
|
key={"GroupTile " + this.props.groupId}
|
||||||
|
draggableId={"GroupTile " + this.props.groupId}
|
||||||
|
index={this.props.groupId}
|
||||||
|
type="draggable-TagTile"
|
||||||
|
>
|
||||||
|
{ (provided, snapshot) => (
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
ref={provided.innerRef}
|
||||||
|
{...provided.draggableProps}
|
||||||
|
{...provided.dragHandleProps}
|
||||||
|
>
|
||||||
|
<div className="mx_GroupTile_avatar">
|
||||||
|
<BaseAvatar name={name} url={httpUrl} width={avatarHeight} height={avatarHeight} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{ /* Instead of a blank placeholder, use a copy of the avatar itself. */ }
|
||||||
|
{ provided.placeholder ?
|
||||||
|
<div className="mx_GroupTile_avatar">
|
||||||
|
<BaseAvatar name={name} url={httpUrl} width={avatarHeight} height={avatarHeight} />
|
||||||
|
</div> :
|
||||||
|
<div />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
</Draggable>
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
</Droppable>
|
||||||
<div className="mx_GroupTile_profile">
|
<div className="mx_GroupTile_profile">
|
||||||
<div className="mx_GroupTile_name">{ name }</div>
|
<div className="mx_GroupTile_name">{ name }</div>
|
||||||
{ descElement }
|
{ descElement }
|
||||||
|
|
|
@ -89,6 +89,7 @@ class TagOrderStore extends Store {
|
||||||
// Optimistic update of a moved tag
|
// Optimistic update of a moved tag
|
||||||
this._setState({
|
this._setState({
|
||||||
orderedTags: payload.request.tags,
|
orderedTags: payload.request.tags,
|
||||||
|
removedTagsAccountData: payload.request.removedTags,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue