Merge pull request #5074 from vector-im/t3chguy/devtools-1

T3chguy/devtools 1
This commit is contained in:
Matthew Hodgson 2017-09-19 22:14:52 +01:00 committed by GitHub
commit fbe1c82dfa
3 changed files with 97 additions and 21 deletions

View file

@ -23,17 +23,28 @@ class SendCustomEvent extends React.Component {
static propTypes = { static propTypes = {
roomId: React.PropTypes.string.isRequired, roomId: React.PropTypes.string.isRequired,
onBack: React.PropTypes.func.isRequired, onBack: React.PropTypes.func.isRequired,
eventType: React.PropTypes.string.isRequired,
evContent: React.PropTypes.string.isRequired,
};
static defaultProps = {
eventType: '',
evContent: '{\n\n}',
}; };
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
this._send = this._send.bind(this); this._send = this._send.bind(this);
this.onBack = this.onBack.bind(this); this.onBack = this.onBack.bind(this);
} this._onChange = this._onChange.bind(this);
state = { this.state = {
message: null, message: null,
input_eventType: this.props.eventType,
input_evContent: this.props.evContent,
}; };
}
onBack() { onBack() {
if (this.state.message) { if (this.state.message) {
@ -51,13 +62,18 @@ class SendCustomEvent extends React.Component {
} }
send(content) { send(content) {
return MatrixClientPeg.get().sendEvent(this.props.roomId, this.refs.eventType.value, content); return MatrixClientPeg.get().sendEvent(this.props.roomId, this.state.input_eventType, content);
} }
async _send() { async _send() {
if (this.state.input_eventType === '') {
this.setState({ message: _t('You must specify an event type!') });
return;
}
let message; let message;
try { try {
const content = JSON.parse(this.refs.evContent.value); const content = JSON.parse(this.state.input_evContent);
await this.send(content); await this.send(content);
message = _t('Event sent!'); message = _t('Event sent!');
} catch (e) { } catch (e) {
@ -67,7 +83,11 @@ class SendCustomEvent extends React.Component {
} }
_additionalFields() { _additionalFields() {
return <div></div>; return <div/>;
}
_onChange(e) {
this.setState({[`input_${e.target.id}`]: e.target.value});
} }
render() { render() {
@ -87,14 +107,14 @@ class SendCustomEvent extends React.Component {
<label htmlFor="eventType"> { _t('Event Type') } </label> <label htmlFor="eventType"> { _t('Event Type') } </label>
</div> </div>
<div> <div>
<input id="eventType" ref="eventType" className="mx_TextInputDialog_input" size="64" /> <input id="eventType" onChange={this._onChange} value={this.state.input_eventType} className="mx_TextInputDialog_input" size="64" />
</div> </div>
<div className="mx_TextInputDialog_label"> <div className="mx_TextInputDialog_label">
<label htmlFor="evContent"> { _t('Event Content') } </label> <label htmlFor="evContent"> { _t('Event Content') } </label>
</div> </div>
<div> <div>
<textarea id="evContent" ref="evContent" className="mx_TextInputDialog_input" defaultValue={"{\n\n}"} cols="63" rows="5" /> <textarea id="evContent" onChange={this._onChange} value={this.state.input_evContent} className="mx_TextInputDialog_input" cols="63" rows="5" />
</div> </div>
</div> </div>
{this._buttons()} {this._buttons()}
@ -103,9 +123,29 @@ class SendCustomEvent extends React.Component {
} }
class SendCustomStateEvent extends SendCustomEvent { class SendCustomStateEvent extends SendCustomEvent {
static propTypes = {
roomId: React.PropTypes.string.isRequired,
onBack: React.PropTypes.func.isRequired,
eventType: React.PropTypes.string.isRequired,
evContent: React.PropTypes.string.isRequired,
stateKey: React.PropTypes.string.isRequired,
};
static defaultProps = {
eventType: '',
evContent: '{\n\n}',
stateKey: '',
};
constructor(props, context) {
super(props, context);
this.state['input_stateKey'] = this.props.stateKey;
}
send(content) { send(content) {
return MatrixClientPeg.get().sendStateEvent(this.props.roomId, this.refs.eventType.value, content, const cli = MatrixClientPeg.get();
this.refs.stateKey.value); return cli.sendStateEvent(this.props.roomId, this.state.input_eventType, content, this.state.input_stateKey);
} }
_additionalFields() { _additionalFields() {
@ -114,7 +154,7 @@ class SendCustomStateEvent extends SendCustomEvent {
<label htmlFor="stateKey"> { _t('State Key') } </label> <label htmlFor="stateKey"> { _t('State Key') } </label>
</div> </div>
<div> <div>
<input id="stateKey" ref="stateKey" className="mx_TextInputDialog_input" size="64" /> <input id="stateKey" onChange={this._onChange} value={this.state.input_stateKey} className="mx_TextInputDialog_input" size="64" />
</div> </div>
</div>; </div>;
} }
@ -122,6 +162,7 @@ class SendCustomStateEvent extends SendCustomEvent {
class RoomStateExplorer extends React.Component { class RoomStateExplorer extends React.Component {
static propTypes = { static propTypes = {
setMode: React.PropTypes.func.isRequired,
roomId: React.PropTypes.string.isRequired, roomId: React.PropTypes.string.isRequired,
onBack: React.PropTypes.func.isRequired, onBack: React.PropTypes.func.isRequired,
}; };
@ -133,9 +174,12 @@ class RoomStateExplorer extends React.Component {
this.roomStateEvents = room.currentState.events; this.roomStateEvents = room.currentState.events;
this.onBack = this.onBack.bind(this); this.onBack = this.onBack.bind(this);
this.editEv = this.editEv.bind(this);
this.onQuery = this.onQuery.bind(this);
} }
state = { state = {
query: '',
eventType: null, eventType: null,
event: null, event: null,
}; };
@ -148,7 +192,7 @@ class RoomStateExplorer extends React.Component {
onViewSourceClick(event) { onViewSourceClick(event) {
return () => { return () => {
this.setState({ event: event.event }); this.setState({ event });
}; };
} }
@ -162,14 +206,28 @@ class RoomStateExplorer extends React.Component {
} }
} }
editEv() {
const ev = this.state.event;
this.props.setMode(SendCustomStateEvent, {
eventType: ev.getType(),
evContent: JSON.stringify(ev.getContent(), null, '\t'),
stateKey: ev.getStateKey(),
});
}
onQuery(ev) {
this.setState({ query: ev.target.value });
}
render() { render() {
if (this.state.event) { if (this.state.event) {
return <div className="mx_ViewSource"> return <div className="mx_ViewSource">
<div className="mx_Dialog_content"> <div className="mx_Dialog_content">
<pre>{JSON.stringify(this.state.event, null, 2)}</pre> <pre>{JSON.stringify(this.state.event.event, null, 2)}</pre>
</div> </div>
<div className="mx_Dialog_buttons"> <div className="mx_Dialog_buttons">
<button onClick={this.onBack}>{ _t('Back') }</button> <button onClick={this.onBack}>{ _t('Back') }</button>
<button onClick={this.editEv}>{ _t('Edit') }</button>
</div> </div>
</div>; </div>;
} }
@ -178,6 +236,9 @@ class RoomStateExplorer extends React.Component {
if (this.state.eventType === null) { if (this.state.eventType === null) {
Object.keys(this.roomStateEvents).forEach((evType) => { Object.keys(this.roomStateEvents).forEach((evType) => {
// Skip this entry if does not contain search query
if (this.state.query && !evType.includes(this.state.query)) return;
const stateGroup = this.roomStateEvents[evType]; const stateGroup = this.roomStateEvents[evType];
const stateKeys = Object.keys(stateGroup); const stateKeys = Object.keys(stateGroup);
@ -196,6 +257,9 @@ class RoomStateExplorer extends React.Component {
const evType = this.state.eventType; const evType = this.state.eventType;
const stateGroup = this.roomStateEvents[evType]; const stateGroup = this.roomStateEvents[evType];
Object.keys(stateGroup).forEach((stateKey) => { Object.keys(stateGroup).forEach((stateKey) => {
// Skip this entry if does not contain search query
if (this.state.query && !stateKey.includes(this.state.query)) return;
const ev = stateGroup[stateKey]; const ev = stateGroup[stateKey];
rows.push(<button className="mx_DevTools_RoomStateExplorer_button" key={stateKey} rows.push(<button className="mx_DevTools_RoomStateExplorer_button" key={stateKey}
onClick={this.onViewSourceClick(ev)}> onClick={this.onViewSourceClick(ev)}>
@ -206,6 +270,7 @@ class RoomStateExplorer extends React.Component {
return <div> return <div>
<div className="mx_Dialog_content"> <div className="mx_Dialog_content">
<input onChange={this.onQuery} placeholder={_t('Filter results')} size="64" className="mx_TextInputDialog_input mx_DevTools_RoomStateExplorer_query" value={this.state.query} />
{rows} {rows}
</div> </div>
<div className="mx_Dialog_buttons"> <div className="mx_Dialog_buttons">
@ -223,11 +288,13 @@ export default class DevtoolsDialog extends React.Component {
state = { state = {
mode: null, mode: null,
modeArgs: {},
}; };
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
this.onBack = this.onBack.bind(this); this.onBack = this.onBack.bind(this);
this.setMode = this.setMode.bind(this);
this.onCancel = this.onCancel.bind(this); this.onCancel = this.onCancel.bind(this);
} }
@ -237,10 +304,14 @@ export default class DevtoolsDialog extends React.Component {
_setMode(mode) { _setMode(mode) {
return () => { return () => {
this.setState({ mode }); this.setMode(mode);
}; };
} }
setMode(mode, modeArgs={}) {
this.setState({ mode, modeArgs });
}
onBack() { onBack() {
this.setState({ mode: null }); this.setState({ mode: null });
} }
@ -253,7 +324,8 @@ export default class DevtoolsDialog extends React.Component {
let body; let body;
if (this.state.mode) { if (this.state.mode) {
body = <this.state.mode {...this.props} onBack={this.onBack} />; body =
<this.state.mode {...this.props} {...this.state.modeArgs} onBack={this.onBack} setMode={this.setMode} />;
} else { } else {
body = <div> body = <div>
<div className="mx_Dialog_content"> <div className="mx_Dialog_content">
@ -268,9 +340,11 @@ export default class DevtoolsDialog extends React.Component {
} }
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return <BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished} title={_t('Developer Tools')}> return (
<BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished} title={_t('Developer Tools')}>
<div>Room ID: { this.props.roomId }</div> <div>Room ID: { this.props.roomId }</div>
{ body } { body }
</BaseDialog>; </BaseDialog>
);
} }
} }

View file

@ -59,6 +59,7 @@
"Favourite": "Favourite", "Favourite": "Favourite",
"Fetching third party location failed": "Fetching third party location failed", "Fetching third party location failed": "Fetching third party location failed",
"Files": "Files", "Files": "Files",
"Filter results": "Filter results",
"Filter room names": "Filter room names", "Filter room names": "Filter room names",
"Forget": "Forget", "Forget": "Forget",
"Forward Message": "Forward Message", "Forward Message": "Forward Message",
@ -156,6 +157,7 @@
"You are not receiving desktop notifications": "You are not receiving desktop notifications", "You are not receiving desktop notifications": "You are not receiving desktop notifications",
"You are Rioting as a guest. <a>Register</a> or <a>sign in</a> to access more rooms and features!": "You are Rioting as a guest. <a>Register</a> or <a>sign in</a> to access more rooms and features!", "You are Rioting as a guest. <a>Register</a> or <a>sign in</a> to access more rooms and features!": "You are Rioting as a guest. <a>Register</a> or <a>sign in</a> to access more rooms and features!",
"You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply",
"You must specify an event type!": "You must specify an event type!",
"Thank you!": "Thank you!", "Thank you!": "Thank you!",
"Sunday": "Sunday", "Sunday": "Sunday",
"Monday": "Monday", "Monday": "Monday",

View file

@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
.mx_DevTools_RoomStateExplorer_button { .mx_DevTools_RoomStateExplorer_button, .mx_DevTools_RoomStateExplorer_query {
margin-bottom: 10px; margin-bottom: 10px;
} }