From ae834f8d05f920d59b0a5491016200025656e270 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 6 Aug 2019 18:03:38 +0100 Subject: [PATCH] Split out SlashCommandHelpDialog, group by category and style it Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/_components.scss | 1 + .../dialogs/_SlashCommandHelpDialog.scss | 42 +++++++++++++ src/SlashCommands.js | 62 +++++++++++------- src/components/views/dialogs/InfoDialog.js | 4 +- .../views/dialogs/SlashCommandHelpDialog.js | 63 +++++++++++++++++++ src/i18n/strings/en_EN.json | 9 ++- 6 files changed, 156 insertions(+), 25 deletions(-) create mode 100644 res/css/views/dialogs/_SlashCommandHelpDialog.scss create mode 100644 src/components/views/dialogs/SlashCommandHelpDialog.js diff --git a/res/css/_components.scss b/res/css/_components.scss index 4c2829b68c1..dff174e9431 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -70,6 +70,7 @@ @import "./views/dialogs/_SetPasswordDialog.scss"; @import "./views/dialogs/_SettingsDialog.scss"; @import "./views/dialogs/_ShareDialog.scss"; +@import "./views/dialogs/_SlashCommandHelpDialog.scss"; @import "./views/dialogs/_TermsDialog.scss"; @import "./views/dialogs/_UnknownDeviceDialog.scss"; @import "./views/dialogs/_UploadConfirmDialog.scss"; diff --git a/res/css/views/dialogs/_SlashCommandHelpDialog.scss b/res/css/views/dialogs/_SlashCommandHelpDialog.scss new file mode 100644 index 00000000000..a0a64f6bec8 --- /dev/null +++ b/res/css/views/dialogs/_SlashCommandHelpDialog.scss @@ -0,0 +1,42 @@ +/*! + * + * Copyright 2019 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. + * / + */ + +/* +Copyright 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_SlashCommandHelpDialog .mx_SlashCommandHelpDialog_headerRow h2 { + margin-bottom: 2px; +} + +.mx_SlashCommandHelpDialog .mx_Dialog_content { + margin-top: 12px; + margin-bottom: 34px; +} diff --git a/src/SlashCommands.js b/src/SlashCommands.js index ec3028cb013..ff5bde06f85 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -20,11 +20,9 @@ limitations under the License. import React from 'react'; import MatrixClientPeg from './MatrixClientPeg'; import dis from './dispatcher'; -import Tinter from './Tinter'; import sdk from './index'; import {_t, _td} from './languageHandler'; import Modal from './Modal'; -import SettingsStore, {SettingLevel} from './settings/SettingsStore'; import {MATRIXTO_URL_PATTERN} from "./linkify-matrix"; import * as querystring from "querystring"; import MultiInviter from './utils/MultiInviter'; @@ -54,12 +52,21 @@ const singleMxcUpload = async () => { }); }; +export const CommandCategories = { + "messages": _td("Messages"), + "actions": _td("Actions"), + "admin": _td("Admin"), + "advanced": _td("Advanced"), + "other": _td("Other"), +}; + class Command { - constructor({name, args='', description, runFn, hideCompletionAfterSpace=false}) { + constructor({name, args='', description, runFn, category=CommandCategories.other, hideCompletionAfterSpace=false}) { this.command = '/' + name; this.args = args; this.description = description; this.runFn = runFn; + this.category = category; this.hideCompletionAfterSpace = hideCompletionAfterSpace; } @@ -106,6 +113,7 @@ export const CommandMap = { } return success(MatrixClientPeg.get().sendTextMessage(roomId, message)); }, + category: CommandCategories.messages, }), ddg: new Command({ @@ -121,6 +129,7 @@ export const CommandMap = { }); return success(); }, + category: CommandCategories.actions, hideCompletionAfterSpace: true, }), @@ -199,6 +208,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.admin, }), nick: new Command({ @@ -211,6 +221,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.actions, }), myroomnick: new Command({ @@ -229,6 +240,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.actions, }), myroomavatar: new Command({ @@ -255,6 +267,7 @@ export const CommandMap = { return cli.sendStateEvent(roomId, 'm.room.member', content, userId); })); }, + category: CommandCategories.actions, }), myavatar: new Command({ @@ -272,6 +285,7 @@ export const CommandMap = { return MatrixClientPeg.get().setAvatarUrl(url); })); }, + category: CommandCategories.actions, }), // Room Tint has been unsupported since the redesign @@ -298,6 +312,7 @@ export const CommandMap = { // } // return reject(this.getUsage()); // }, + // category: CommandCategories.actions, // }), topic: new Command({ @@ -323,6 +338,7 @@ export const CommandMap = { }); return success(); }, + category: CommandCategories.admin, }), roomname: new Command({ @@ -335,6 +351,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.admin, }), invite: new Command({ @@ -358,6 +375,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.actions, }), join: new Command({ @@ -462,6 +480,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.actions, }), part: new Command({ @@ -509,6 +528,7 @@ export const CommandMap = { }), ); }, + category: CommandCategories.actions, }), kick: new Command({ @@ -524,6 +544,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.admin, }), // Ban a user from the room with an optional reason @@ -540,6 +561,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.admin, }), // Unban a user from ythe room @@ -557,6 +579,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.admin, }), ignore: new Command({ @@ -587,6 +610,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.actions, }), unignore: new Command({ @@ -618,6 +642,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.actions, }), // Define the power level of a user @@ -646,6 +671,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.admin, }), // Reset the power level of a user @@ -667,6 +693,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.admin, }), devtools: new Command({ @@ -677,6 +704,7 @@ export const CommandMap = { Modal.createDialog(DevtoolsDialog, {roomId}); return success(); }, + category: CommandCategories.advanced, }), addwidget: new Command({ @@ -697,6 +725,7 @@ export const CommandMap = { return reject(_t("You cannot modify widgets in this room.")); } }, + category: CommandCategories.admin, }), // Verify a user, device, and pubkey tuple @@ -766,6 +795,7 @@ export const CommandMap = { } return reject(this.getUsage()); }, + category: CommandCategories.advanced, }), // Command definitions for autocompletion ONLY: @@ -775,6 +805,7 @@ export const CommandMap = { name: 'me', args: '', description: _td('Displays action'), + category: CommandCategories.messages, hideCompletionAfterSpace: true, }), @@ -789,6 +820,7 @@ export const CommandMap = { } return success(); }, + category: CommandCategories.advanced, }), rainbow: new Command({ @@ -799,6 +831,7 @@ export const CommandMap = { if (!args) return reject(this.getUserId()); return success(MatrixClientPeg.get().sendHtmlMessage(roomId, args, textToHtmlRainbow(args))); }, + category: CommandCategories.messages, }), rainbowme: new Command({ @@ -809,32 +842,19 @@ export const CommandMap = { if (!args) return reject(this.getUserId()); return success(MatrixClientPeg.get().sendHtmlEmote(roomId, args, textToHtmlRainbow(args))); }, + category: CommandCategories.messages, }), help: new Command({ name: "help", description: _td("Displays list of commands with usages and descriptions"), runFn: function() { - const InfoDialog = sdk.getComponent('dialogs.InfoDialog'); - Modal.createTrackedDialog('Slash Commands', 'Help', InfoDialog, { - title: _t("Command Help"), - description: - - { - Object.values(CommandMap).map(cmd => { - return - - - - ; - }) - } - -
{cmd.command}{cmd.args}{cmd.description}
, - hasCloseButton: true, - }); + const SlashCommandHelpDialog = sdk.getComponent('dialogs.SlashCommandHelpDialog'); + + Modal.createTrackedDialog('Slash Commands', 'Help', SlashCommandHelpDialog); return success(); }, + category: CommandCategories.advanced, }), }; /* eslint-enable babel/no-invalid-this */ diff --git a/src/components/views/dialogs/InfoDialog.js b/src/components/views/dialogs/InfoDialog.js index ff2f53cad79..d01b737309f 100644 --- a/src/components/views/dialogs/InfoDialog.js +++ b/src/components/views/dialogs/InfoDialog.js @@ -20,10 +20,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import classNames from "classnames"; export default React.createClass({ displayName: 'InfoDialog', propTypes: { + className: PropTypes.string, title: PropTypes.string, description: PropTypes.node, button: PropTypes.string, @@ -52,7 +54,7 @@ export default React.createClass({ contentId='mx_Dialog_content' hasCancel={this.props.hasCloseButton} > -
+
{ this.props.description }
+ +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 {_t} from "../../../languageHandler"; +import {CommandCategories, CommandMap} from "../../../SlashCommands"; +import sdk from "../../../index"; + +export default ({onFinished}) => { + const InfoDialog = sdk.getComponent('dialogs.InfoDialog'); + + const categories = {}; + Object.values(CommandMap).forEach(cmd => { + if (!categories[cmd.category]) { + categories[cmd.category] = []; + } + categories[cmd.category].push(cmd); + }); + + const body = Object.values(CommandCategories).filter(c => categories[c]).map((category) => { + const rows = [ + + +

{_t(category)}

+ + , + ]; + + categories[category].forEach(cmd => { + rows.push( + {cmd.command} + {cmd.args} + {cmd.description} + ); + }); + + return rows; + }); + + return + + {body} + + } + hasCloseButton={true} + onFinished={onFinished} />; +}; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index c5ef2fd9894..b53b5932185 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -131,6 +131,10 @@ "Missing room_id in request": "Missing room_id in request", "Room %(roomId)s not visible": "Room %(roomId)s not visible", "Missing user_id in request": "Missing user_id in request", + "Messages": "Messages", + "Actions": "Actions", + "Advanced": "Advanced", + "Other": "Other", "Usage": "Usage", "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Prepends ¯\\_(ツ)_/¯ to a plain-text message", "Searches DuckDuckGo for results": "Searches DuckDuckGo for results", @@ -148,7 +152,6 @@ "Changes your display nickname in the current room only": "Changes your display nickname in the current room only", "Changes your avatar in this current room only": "Changes your avatar in this current room only", "Changes your avatar in all rooms": "Changes your avatar in all rooms", - "Changes colour scheme of current room": "Changes colour scheme of current room", "Gets or sets the room topic": "Gets or sets the room topic", "This room has no topic.": "This room has no topic.", "Sets the room name": "Sets the room name", @@ -182,6 +185,8 @@ "Forces the current outbound group session in an encrypted room to be discarded": "Forces the current outbound group session in an encrypted room to be discarded", "Sends the given message coloured as a rainbow": "Sends the given message coloured as a rainbow", "Sends the given emote coloured as a rainbow": "Sends the given emote coloured as a rainbow", + "Displays list of commands with usages and descriptions": "Displays list of commands with usages and descriptions", + "Command Help": "Command Help", "Unrecognised command:": "Unrecognised command:", "Reason": "Reason", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.", @@ -509,7 +514,6 @@ "Backup has an invalid signature from unverified device ": "Backup has an invalid signature from unverified device ", "Backup is not signed by any of your devices": "Backup is not signed by any of your devices", "This backup is trusted because it has been restored on this device": "This backup is trusted because it has been restored on this device", - "Advanced": "Advanced", "Backup version: ": "Backup version: ", "Algorithm: ": "Algorithm: ", "Your keys are not being backed up from this device.": "Your keys are not being backed up from this device.", @@ -1417,7 +1421,6 @@ "Join millions for free on the largest public server": "Join millions for free on the largest public server", "Premium": "Premium", "Premium hosting for organisations Learn more": "Premium hosting for organisations Learn more", - "Other": "Other", "Find other public servers or use a custom server": "Find other public servers or use a custom server", "Sorry, your browser is not able to run Riot.": "Sorry, your browser is not able to run Riot.", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.",