Merge remote-tracking branch 'upstream/develop' into hs/custom-notif-sounds

This commit is contained in:
Will Hunt 2019-05-12 16:55:36 +01:00
commit 2023b3d905
9 changed files with 157 additions and 78 deletions

View file

@ -115,6 +115,7 @@
@import "./views/messages/_MTextBody.scss"; @import "./views/messages/_MTextBody.scss";
@import "./views/messages/_MessageActionBar.scss"; @import "./views/messages/_MessageActionBar.scss";
@import "./views/messages/_MessageTimestamp.scss"; @import "./views/messages/_MessageTimestamp.scss";
@import "./views/messages/_ReactionDimension.scss";
@import "./views/messages/_ReactionsRow.scss"; @import "./views/messages/_ReactionsRow.scss";
@import "./views/messages/_ReactionsRowButton.scss"; @import "./views/messages/_ReactionsRowButton.scss";
@import "./views/messages/_RoomAvatarEvent.scss"; @import "./views/messages/_RoomAvatarEvent.scss";

View file

@ -18,7 +18,12 @@ limitations under the License.
margin: 10px 0; margin: 10px 0;
} }
.mx_DevTools_RoomStateExplorer_button, .mx_DevTools_RoomStateExplorer_query { .mx_DevTools_ServersInRoomList_button {
/* Set the cursor back to default as `.mx_Dialog button` sets it to pointer */
cursor: default !important;
}
.mx_DevTools_RoomStateExplorer_button, .mx_DevTools_ServersInRoomList_button, .mx_DevTools_RoomStateExplorer_query {
margin-bottom: 10px; margin-bottom: 10px;
width: 100%; width: 100%;
} }

View file

@ -72,13 +72,3 @@ limitations under the License.
.mx_MessageActionBar_optionsButton::after { .mx_MessageActionBar_optionsButton::after {
mask-image: url('$(res)/img/icon_context.svg'); mask-image: url('$(res)/img/icon_context.svg');
} }
.mx_MessageActionBar_reactionDimension {
width: 42px;
display: flex;
justify-content: space-evenly;
}
.mx_MessageActionBar_reactionDisabled {
opacity: 0.4;
}

View file

@ -0,0 +1,25 @@
/*
Copyright 2019 New Vector 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.
*/
.mx_ReactionDimension {
width: 42px;
display: flex;
justify-content: space-evenly;
}
.mx_ReactionDimension_disabled {
opacity: 0.4;
}

View file

@ -40,7 +40,7 @@ import dis from '../../dispatcher';
import Tinter from '../../Tinter'; import Tinter from '../../Tinter';
import rate_limited_func from '../../ratelimitedfunc'; import rate_limited_func from '../../ratelimitedfunc';
import ObjectUtils from '../../ObjectUtils'; import ObjectUtils from '../../ObjectUtils';
import Rooms from '../../Rooms'; import * as Rooms from '../../Rooms';
import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';

View file

@ -551,11 +551,53 @@ class AccountDataExplorer extends DevtoolsComponent {
} }
} }
class ServersInRoomList extends DevtoolsComponent {
static getLabel() { return _t('View Servers in Room'); }
static propTypes = {
onBack: PropTypes.func.isRequired,
};
constructor(props, context) {
super(props, context);
const room = MatrixClientPeg.get().getRoom(this.context.roomId);
const servers = new Set();
room.currentState.getStateEvents("m.room.member").forEach(ev => servers.add(ev.getSender().split(":")[1]));
this.servers = Array.from(servers).map(s =>
<button key={s} className="mx_DevTools_ServersInRoomList_button">
{ s }
</button>);
this.state = {
query: '',
};
}
onQuery = (query) => {
this.setState({ query });
}
render() {
return <div>
<div className="mx_Dialog_content">
<FilteredList query={this.state.query} onChange={this.onQuery}>
{ this.servers }
</FilteredList>
</div>
<div className="mx_Dialog_buttons">
<button onClick={this.props.onBack}>{ _t('Back') }</button>
</div>
</div>;
}
}
const Entries = [ const Entries = [
SendCustomEvent, SendCustomEvent,
RoomStateExplorer, RoomStateExplorer,
SendAccountData, SendAccountData,
AccountDataExplorer, AccountDataExplorer,
ServersInRoomList,
]; ];
export default class DevtoolsDialog extends React.Component { export default class DevtoolsDialog extends React.Component {

View file

@ -16,7 +16,6 @@ limitations under the License.
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import sdk from '../../../index'; import sdk from '../../../index';
@ -35,15 +34,6 @@ export default class MessageActionBar extends React.PureComponent {
onFocusChange: PropTypes.func, onFocusChange: PropTypes.func,
}; };
constructor(props) {
super(props);
this.state = {
agreeDimension: null,
likeDimension: null,
};
}
onFocusChange = (focused) => { onFocusChange = (focused) => {
if (!this.props.onFocusChange) { if (!this.props.onFocusChange) {
return; return;
@ -59,31 +49,6 @@ export default class MessageActionBar extends React.PureComponent {
); );
} }
onAgreeClick = (ev) => {
this.toggleDimensionValue("agreeDimension", "agree");
}
onDisagreeClick = (ev) => {
this.toggleDimensionValue("agreeDimension", "disagree");
}
onLikeClick = (ev) => {
this.toggleDimensionValue("likeDimension", "like");
}
onDislikeClick = (ev) => {
this.toggleDimensionValue("likeDimension", "dislike");
}
toggleDimensionValue(dimension, value) {
const state = this.state[dimension];
const newState = state !== value ? value : null;
this.setState({
[dimension]: newState,
});
// TODO: Send the reaction event
}
onReplyClick = (ev) => { onReplyClick = (ev) => {
dis.dispatch({ dis.dispatch({
action: 'reply_to_event', action: 'reply_to_event',
@ -134,25 +99,21 @@ export default class MessageActionBar extends React.PureComponent {
return null; return null;
} }
const state = this.state.agreeDimension; const ReactionDimension = sdk.getComponent('messages.ReactionDimension');
const options = [ const options = [
{ {
key: "agree", key: "agree",
content: "👍", content: "👍",
onClick: this.onAgreeClick,
}, },
{ {
key: "disagree", key: "disagree",
content: "👎", content: "👎",
onClick: this.onDisagreeClick,
}, },
]; ];
return <ReactionDimension
return <span className="mx_MessageActionBar_reactionDimension"
title={_t("Agree or Disagree")} title={_t("Agree or Disagree")}
> options={options}
{this.renderReactionDimensionItems(state, options)} />;
</span>;
} }
renderLikeDimension() { renderLikeDimension() {
@ -160,40 +121,21 @@ export default class MessageActionBar extends React.PureComponent {
return null; return null;
} }
const state = this.state.likeDimension; const ReactionDimension = sdk.getComponent('messages.ReactionDimension');
const options = [ const options = [
{ {
key: "like", key: "like",
content: "🙂", content: "🙂",
onClick: this.onLikeClick,
}, },
{ {
key: "dislike", key: "dislike",
content: "😔", content: "😔",
onClick: this.onDislikeClick,
}, },
]; ];
return <ReactionDimension
return <span className="mx_MessageActionBar_reactionDimension"
title={_t("Like or Dislike")} title={_t("Like or Dislike")}
> options={options}
{this.renderReactionDimensionItems(state, options)} />;
</span>;
}
renderReactionDimensionItems(state, options) {
return options.map(option => {
const disabled = state && state !== option.key;
const classes = classNames({
mx_MessageActionBar_reactionDisabled: disabled,
});
return <span key={option.key}
className={classes}
onClick={option.onClick}
>
{option.content}
</span>;
});
} }
render() { render() {

View file

@ -0,0 +1,73 @@
/*
Copyright 2019 New Vector 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 PropTypes from 'prop-types';
import classNames from 'classnames';
export default class ReactionDimension extends React.PureComponent {
static propTypes = {
options: PropTypes.array.isRequired,
title: PropTypes.string,
};
constructor(props) {
super(props);
this.state = {
selected: null,
};
}
onOptionClick = (ev) => {
const { key } = ev.target.dataset;
this.toggleDimensionValue(key);
}
toggleDimensionValue(value) {
const state = this.state.selected;
const newState = state !== value ? value : null;
this.setState({
selected: newState,
});
// TODO: Send the reaction event
}
render() {
const { selected } = this.state;
const { options } = this.props;
const items = options.map(option => {
const disabled = selected && selected !== option.key;
const classes = classNames({
mx_ReactionDimension_disabled: disabled,
});
return <span key={option.key}
data-key={option.key}
className={classes}
onClick={this.onOptionClick}
>
{option.content}
</span>;
});
return <span className="mx_ReactionDimension"
title={this.props.title}
>
{items}
</span>;
}
}

View file

@ -1133,6 +1133,7 @@
"Filter results": "Filter results", "Filter results": "Filter results",
"Explore Room State": "Explore Room State", "Explore Room State": "Explore Room State",
"Explore Account Data": "Explore Account Data", "Explore Account Data": "Explore Account Data",
"View Servers in Room": "View Servers in Room",
"Toolbox": "Toolbox", "Toolbox": "Toolbox",
"Developer Tools": "Developer Tools", "Developer Tools": "Developer Tools",
"An error has occurred.": "An error has occurred.", "An error has occurred.": "An error has occurred.",