diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js
new file mode 100644
index 0000000000..a7ac9fb1c2
--- /dev/null
+++ b/src/components/views/dialogs/DevtoolsDialog.js
@@ -0,0 +1,276 @@
+/*
+Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
+
+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 sdk from 'matrix-react-sdk';
+import { _t } from 'matrix-react-sdk/lib/languageHandler';
+import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
+
+class SendCustomEvent extends React.Component {
+ static propTypes = {
+ roomId: React.PropTypes.string.isRequired,
+ onBack: React.PropTypes.func.isRequired,
+ };
+
+ constructor(props, context) {
+ super(props, context);
+ this._send = this._send.bind(this);
+ this.onBack = this.onBack.bind(this);
+ }
+
+ state = {
+ message: null,
+ };
+
+ onBack() {
+ if (this.state.message) {
+ this.setState({ message: null });
+ } else {
+ this.props.onBack();
+ }
+ }
+
+ _buttons() {
+ return
+ { body }
+ ;
+ }
+}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 0dc9359489..4f4a788b19 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -9,6 +9,7 @@
"All Rooms": "All Rooms",
"All notifications are currently disabled for all targets.": "All notifications are currently disabled for all targets.",
"An error occurred whilst saving your email notification preferences.": "An error occurred whilst saving your email notification preferences.",
+ "Back": "Back",
"Bug report sent": "Bug report sent",
"Call invitation": "Call invitation",
"Cancel": "Cancel",
@@ -26,6 +27,7 @@
"delete the alias.": "delete the alias.",
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?",
"Describe your problem here.": "Describe your problem here.",
+ "Developer Tools": "Developer Tools",
"Direct Chat": "Direct Chat",
"Directory": "Directory",
"Dismiss": "Dismiss",
@@ -50,6 +52,7 @@
"Failed to get public room list": "Failed to get public room list",
"Failed to join the room": "Failed to join the room",
"Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
+ "Failed to send custom event.": "Failed to send custom event.",
"Failed to send report: ": "Failed to send report: ",
"Failed to set direct chat tag": "Failed to set direct chat tag",
"Failed to set Direct Message status of room": "Failed to set Direct Message status of room",
@@ -117,6 +120,9 @@
"Search for a room": "Search for a room",
"Send": "Send",
"Send logs": "Send logs",
+ "Send Custom Event": "Send Custom Event",
+ "Send Custom State Event": "Send Custom State Event",
+ "Explore Room State": "Explore Room State",
"Settings": "Settings",
"Source URL": "Source URL",
"Sorry, your browser is not able to run Riot.": "Sorry, your browser is not able to run Riot.",
@@ -164,6 +170,10 @@
"Warning": "Warning",
"Checking for an update...": "Checking for an update...",
"Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).",
+ "Event sent!": "Event sent!",
+ "Event Type": "Event Type",
+ "Event Content": "Event Content",
+ "State Key": "State Key",
"No update available.": "No update available.",
"Downloading update...": "Downloading update...",
"You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.",
diff --git a/src/skins/vector/css/_components.scss b/src/skins/vector/css/_components.scss
index 00c19b13da..8caf15ca1c 100644
--- a/src/skins/vector/css/_components.scss
+++ b/src/skins/vector/css/_components.scss
@@ -74,6 +74,7 @@
@import "./vector-web/views/context_menus/_MessageContextMenu.scss";
@import "./vector-web/views/context_menus/_RoomTileContextMenu.scss";
@import "./vector-web/views/dialogs/_ChangelogDialog.scss";
+@import "./vector-web/views/dialogs/_DevtoolsDialog.scss";
@import "./vector-web/views/dialogs/_SetEmailDialog.scss";
@import "./vector-web/views/dialogs/_SetPasswordDialog.scss";
@import "./vector-web/views/directory/_NetworkDropdown.scss";
diff --git a/src/skins/vector/css/vector-web/views/dialogs/_DevtoolsDialog.scss b/src/skins/vector/css/vector-web/views/dialogs/_DevtoolsDialog.scss
new file mode 100644
index 0000000000..c22a38341c
--- /dev/null
+++ b/src/skins/vector/css/vector-web/views/dialogs/_DevtoolsDialog.scss
@@ -0,0 +1,19 @@
+/*
+Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
+
+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_DevTools_RoomStateExplorer_button {
+ margin-bottom: 10px;
+}