Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T3chguy/devtools 1 #5074

Merged
merged 4 commits into from Sep 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
114 changes: 94 additions & 20 deletions src/components/views/dialogs/DevtoolsDialog.js
Expand Up @@ -23,17 +23,28 @@ class SendCustomEvent extends React.Component {
static propTypes = {
roomId: React.PropTypes.string.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) {
super(props, context);
this._send = this._send.bind(this);
this.onBack = this.onBack.bind(this);
}
this._onChange = this._onChange.bind(this);

state = {
message: null,
};
this.state = {
message: null,
input_eventType: this.props.eventType,
input_evContent: this.props.evContent,
};
}

onBack() {
if (this.state.message) {
Expand All @@ -51,13 +62,18 @@ class SendCustomEvent extends React.Component {
}

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() {
if (this.state.input_eventType === '') {
this.setState({ message: _t('You must specify an event type!') });
return;
}

let message;
try {
const content = JSON.parse(this.refs.evContent.value);
const content = JSON.parse(this.state.input_evContent);
await this.send(content);
message = _t('Event sent!');
} catch (e) {
Expand All @@ -67,7 +83,11 @@ class SendCustomEvent extends React.Component {
}

_additionalFields() {
return <div></div>;
return <div/>;
}

_onChange(e) {
this.setState({[`input_${e.target.id}`]: e.target.value});
}

render() {
Expand All @@ -87,14 +107,14 @@ class SendCustomEvent extends React.Component {
<label htmlFor="eventType"> { _t('Event Type') } </label>
</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 className="mx_TextInputDialog_label">
<label htmlFor="evContent"> { _t('Event Content') } </label>
</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>
{this._buttons()}
Expand All @@ -103,9 +123,29 @@ class SendCustomEvent extends React.Component {
}

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) {
return MatrixClientPeg.get().sendStateEvent(this.props.roomId, this.refs.eventType.value, content,
this.refs.stateKey.value);
const cli = MatrixClientPeg.get();
return cli.sendStateEvent(this.props.roomId, this.state.input_eventType, content, this.state.input_stateKey);
}

_additionalFields() {
Expand All @@ -114,14 +154,15 @@ class SendCustomStateEvent extends SendCustomEvent {
<label htmlFor="stateKey"> { _t('State Key') } </label>
</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>;
}
}

class RoomStateExplorer extends React.Component {
static propTypes = {
setMode: React.PropTypes.func.isRequired,
roomId: React.PropTypes.string.isRequired,
onBack: React.PropTypes.func.isRequired,
};
Expand All @@ -133,9 +174,12 @@ class RoomStateExplorer extends React.Component {
this.roomStateEvents = room.currentState.events;

this.onBack = this.onBack.bind(this);
this.editEv = this.editEv.bind(this);
this.onQuery = this.onQuery.bind(this);
}

state = {
query: '',
eventType: null,
event: null,
};
Expand All @@ -148,7 +192,7 @@ class RoomStateExplorer extends React.Component {

onViewSourceClick(event) {
return () => {
this.setState({ event: event.event });
this.setState({ event });
};
}

Expand All @@ -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() {
if (this.state.event) {
return <div className="mx_ViewSource">
<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 className="mx_Dialog_buttons">
<button onClick={this.onBack}>{ _t('Back') }</button>
<button onClick={this.editEv}>{ _t('Edit') }</button>
</div>
</div>;
}
Expand All @@ -178,6 +236,9 @@ class RoomStateExplorer extends React.Component {

if (this.state.eventType === null) {
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 stateKeys = Object.keys(stateGroup);

Expand All @@ -196,6 +257,9 @@ class RoomStateExplorer extends React.Component {
const evType = this.state.eventType;
const stateGroup = this.roomStateEvents[evType];
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];
rows.push(<button className="mx_DevTools_RoomStateExplorer_button" key={stateKey}
onClick={this.onViewSourceClick(ev)}>
Expand All @@ -206,6 +270,7 @@ class RoomStateExplorer extends React.Component {

return <div>
<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}
</div>
<div className="mx_Dialog_buttons">
Expand All @@ -223,11 +288,13 @@ export default class DevtoolsDialog extends React.Component {

state = {
mode: null,
modeArgs: {},
};

constructor(props, context) {
super(props, context);
this.onBack = this.onBack.bind(this);
this.setMode = this.setMode.bind(this);
this.onCancel = this.onCancel.bind(this);
}

Expand All @@ -237,10 +304,14 @@ export default class DevtoolsDialog extends React.Component {

_setMode(mode) {
return () => {
this.setState({ mode });
this.setMode(mode);
};
}

setMode(mode, modeArgs={}) {
this.setState({ mode, modeArgs });
}

onBack() {
this.setState({ mode: null });
}
Expand All @@ -253,7 +324,8 @@ export default class DevtoolsDialog extends React.Component {
let body;

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 {
body = <div>
<div className="mx_Dialog_content">
Expand All @@ -268,9 +340,11 @@ export default class DevtoolsDialog extends React.Component {
}

const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return <BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished} title={_t('Developer Tools')}>
<div>Room ID: {this.props.roomId}</div>
{ body }
</BaseDialog>;
return (
<BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished} title={_t('Developer Tools')}>
<div>Room ID: { this.props.roomId }</div>
{ body }
</BaseDialog>
);
}
}
2 changes: 2 additions & 0 deletions src/i18n/strings/en_EN.json
Expand Up @@ -59,6 +59,7 @@
"Favourite": "Favourite",
"Fetching third party location failed": "Fetching third party location failed",
"Files": "Files",
"Filter results": "Filter results",
"Filter room names": "Filter room names",
"Forget": "Forget",
"Forward Message": "Forward Message",
Expand Down Expand Up @@ -156,6 +157,7 @@
"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 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!",
"Sunday": "Sunday",
"Monday": "Monday",
Expand Down
Expand Up @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_DevTools_RoomStateExplorer_button {
.mx_DevTools_RoomStateExplorer_button, .mx_DevTools_RoomStateExplorer_query {
margin-bottom: 10px;
}