mirror of
https://github.com/element-hq/element-web.git
synced 2024-12-12 01:05:53 +03:00
Merge branch 'develop' into luke/feature-mention-pill
This commit is contained in:
commit
5d1b33d2a8
5 changed files with 24 additions and 26 deletions
|
@ -118,7 +118,7 @@ export default class EmojiProvider extends AutocompleteProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||||
return <div className="mx_Autocomplete_Completion_container_pill mx_Autocomplete_Completion_container_truncate">
|
return <div className="mx_Autocomplete_Completion_container_pill">
|
||||||
{completions}
|
{completions}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
||||||
import _at from 'lodash/at';
|
import _at from 'lodash/at';
|
||||||
import _flatMap from 'lodash/flatMap';
|
import _flatMap from 'lodash/flatMap';
|
||||||
import _sortBy from 'lodash/sortBy';
|
import _sortBy from 'lodash/sortBy';
|
||||||
import _sortedUniq from 'lodash/sortedUniq';
|
import _uniq from 'lodash/uniq';
|
||||||
import _keys from 'lodash/keys';
|
import _keys from 'lodash/keys';
|
||||||
|
|
||||||
class KeyMap {
|
class KeyMap {
|
||||||
|
@ -101,7 +101,7 @@ export default class QueryMatcher {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return _sortedUniq(_flatMap(_sortBy(results, (candidate) => {
|
return _uniq(_flatMap(_sortBy(results, (candidate) => {
|
||||||
return candidate.index;
|
return candidate.index;
|
||||||
}).map((candidate) => {
|
}).map((candidate) => {
|
||||||
// return an array of objects (those given to setObjects) that have the given
|
// return an array of objects (those given to setObjects) that have the given
|
||||||
|
|
|
@ -178,27 +178,27 @@ module.exports = React.createClass({
|
||||||
const href = node.getAttribute("href");
|
const href = node.getAttribute("href");
|
||||||
// HtmlUtils transforms `matrix.to` links to local links, so match against
|
// HtmlUtils transforms `matrix.to` links to local links, so match against
|
||||||
// user or room app links.
|
// user or room app links.
|
||||||
const match = /^#\/(user|room)\/(.*)$/.exec(href);
|
const match = /^#\/(user|room)\/(.*)$/.exec(href) || [];
|
||||||
if (match) {
|
const resourceType = match[1]; // "user" or "room"
|
||||||
|
const resourceId = match[2]; // user ID or room ID
|
||||||
|
if (match && resourceType && resourceId) {
|
||||||
let avatar;
|
let avatar;
|
||||||
let roomId;
|
let roomId;
|
||||||
let room;
|
let room;
|
||||||
let userId;
|
|
||||||
let member;
|
let member;
|
||||||
switch (match[1]) {
|
switch (resourceType) {
|
||||||
case "user":
|
case "user":
|
||||||
roomId = this.props.mxEvent.getRoomId();
|
roomId = this.props.mxEvent.getRoomId();
|
||||||
room = MatrixClientPeg.get().getRoom(roomId);
|
room = MatrixClientPeg.get().getRoom(roomId);
|
||||||
userId = match[2];
|
member = room.getMember(resourceId) ||
|
||||||
member = room.getMember(userId) ||
|
new RoomMember(null, resourceId);
|
||||||
new RoomMember(null, userId);
|
avatar = <MemberAvatar member={member} width={16} height={16} name={resourceId}/>;
|
||||||
avatar = <MemberAvatar member={member} width={16} height={16} name={match[2]}/>;
|
|
||||||
break;
|
break;
|
||||||
case "room":
|
case "room":
|
||||||
room = match[2][0] === '#' ?
|
room = resourceId[0] === '#' ?
|
||||||
MatrixClientPeg.get().getRooms().find((r) => {
|
MatrixClientPeg.get().getRooms().find((r) => {
|
||||||
return r.getCanonicalAlias() === match[2];
|
return r.getCanonicalAlias() === resourceId;
|
||||||
}) : MatrixClientPeg.get().getRoom(match[2]);
|
}) : MatrixClientPeg.get().getRoom(resourceId);
|
||||||
if (room) {
|
if (room) {
|
||||||
avatar = <RoomAvatar room={room} width={16} height={16}/>;
|
avatar = <RoomAvatar room={room} width={16} height={16}/>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,16 +535,19 @@ export default class MessageComposerInput extends React.Component {
|
||||||
if (this.state.isRichtextEnabled) {
|
if (this.state.isRichtextEnabled) {
|
||||||
// These are block types, not handled by RichUtils by default.
|
// These are block types, not handled by RichUtils by default.
|
||||||
const blockCommands = ['code-block', 'blockquote', 'unordered-list-item', 'ordered-list-item'];
|
const blockCommands = ['code-block', 'blockquote', 'unordered-list-item', 'ordered-list-item'];
|
||||||
|
const currentBlockType = RichUtils.getCurrentBlockType(this.state.editorState);
|
||||||
|
|
||||||
if (blockCommands.includes(command)) {
|
if (blockCommands.includes(command)) {
|
||||||
this.setState({
|
newState = RichUtils.toggleBlockType(this.state.editorState, command);
|
||||||
editorState: RichUtils.toggleBlockType(this.state.editorState, command),
|
|
||||||
});
|
|
||||||
} else if (command === 'strike') {
|
} else if (command === 'strike') {
|
||||||
// this is the only inline style not handled by Draft by default
|
// this is the only inline style not handled by Draft by default
|
||||||
this.setState({
|
newState = RichUtils.toggleInlineStyle(this.state.editorState, 'STRIKETHROUGH');
|
||||||
editorState: RichUtils.toggleInlineStyle(this.state.editorState, 'STRIKETHROUGH'),
|
} else if (command === 'backspace' && currentBlockType !== 'unstyled') {
|
||||||
});
|
const currentStartOffset = this.state.editorState.getSelection().getStartOffset();
|
||||||
|
if (currentStartOffset === 0) {
|
||||||
|
// Toggle current block type (setting it to 'unstyled')
|
||||||
|
newState = RichUtils.toggleBlockType(this.state.editorState, currentBlockType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let contentState = this.state.editorState.getCurrentContent();
|
let contentState = this.state.editorState.getCurrentContent();
|
||||||
|
@ -651,6 +654,7 @@ export default class MessageComposerInput extends React.Component {
|
||||||
// By returning false, we allow the default draft-js key binding to occur,
|
// By returning false, we allow the default draft-js key binding to occur,
|
||||||
// which in this case invokes "split-block". This creates a new block of the
|
// which in this case invokes "split-block". This creates a new block of the
|
||||||
// same type, allowing the user to delete it with backspace.
|
// same type, allowing the user to delete it with backspace.
|
||||||
|
// See handleKeyCommand (when command === 'backspace')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,6 @@ export default class MultiInviter {
|
||||||
* Invite users to this room. This may only be called once per
|
* Invite users to this room. This may only be called once per
|
||||||
* instance of the class.
|
* instance of the class.
|
||||||
*
|
*
|
||||||
* The promise is given progress when each address completes, with an
|
|
||||||
* object argument with each completed address with value either
|
|
||||||
* 'invited' or 'error'.
|
|
||||||
*
|
|
||||||
* @param {array} addresses Array of addresses to invite
|
* @param {array} addresses Array of addresses to invite
|
||||||
* @returns {Promise} Resolved when all invitations in the queue are complete
|
* @returns {Promise} Resolved when all invitations in the queue are complete
|
||||||
*/
|
*/
|
||||||
|
@ -111,7 +107,6 @@ export default class MultiInviter {
|
||||||
if (this._canceled) { return; }
|
if (this._canceled) { return; }
|
||||||
|
|
||||||
this.completionStates[addr] = 'invited';
|
this.completionStates[addr] = 'invited';
|
||||||
this.deferred.notify(this.completionStates);
|
|
||||||
|
|
||||||
this._inviteMore(nextIndex + 1);
|
this._inviteMore(nextIndex + 1);
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
|
@ -136,7 +131,6 @@ export default class MultiInviter {
|
||||||
this.busy = !fatal;
|
this.busy = !fatal;
|
||||||
|
|
||||||
if (!fatal) {
|
if (!fatal) {
|
||||||
this.deferred.notify(this.completionStates);
|
|
||||||
this._inviteMore(nextIndex + 1);
|
this._inviteMore(nextIndex + 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue