Merge branch 'develop' into hs/custom-notif-sounds

pull/21833/head
Will Hunt 2019-05-13 03:09:59 +01:00 committed by GitHub
commit e8c8762e34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 4 deletions

View File

@ -1,6 +1,7 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2018 New Vector Ltd Copyright 2018 New Vector Ltd
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -30,6 +31,8 @@ import MultiInviter from './utils/MultiInviter';
import { linkifyAndSanitizeHtml } from './HtmlUtils'; import { linkifyAndSanitizeHtml } from './HtmlUtils';
import QuestionDialog from "./components/views/dialogs/QuestionDialog"; import QuestionDialog from "./components/views/dialogs/QuestionDialog";
import WidgetUtils from "./utils/WidgetUtils"; import WidgetUtils from "./utils/WidgetUtils";
import {textToHtmlRainbow} from "./utils/colour";
import Promise from "bluebird";
class Command { class Command {
constructor({name, args='', description, runFn, hideCompletionAfterSpace=false}) { constructor({name, args='', description, runFn, hideCompletionAfterSpace=false}) {
@ -190,8 +193,8 @@ export const CommandMap = {
}, },
}), }),
roomnick: new Command({ myroomnick: new Command({
name: 'roomnick', name: 'myroomnick',
args: '<display_name>', args: '<display_name>',
description: _td('Changes your display nickname in the current room only'), description: _td('Changes your display nickname in the current room only'),
runFn: function(roomId, args) { runFn: function(roomId, args) {
@ -208,6 +211,47 @@ export const CommandMap = {
}, },
}), }),
myroomavatar: new Command({
name: 'myroomavatar',
args: '[<mxc_url>]',
description: _td('Changes your avatar in this current room only'),
runFn: function(roomId, args) {
const cli = MatrixClientPeg.get();
const room = cli.getRoom(roomId);
const userId = cli.getUserId();
let promise = Promise.resolve(args);
if (!args) {
promise = new Promise((resolve) => {
const fileSelector = document.createElement('input');
fileSelector.setAttribute('type', 'file');
fileSelector.onchange = (ev) => {
const file = ev.target.files[0];
const UploadConfirmDialog = sdk.getComponent("dialogs.UploadConfirmDialog");
Modal.createTrackedDialog('Upload Files confirmation', '', UploadConfirmDialog, {
file,
onFinished: (shouldContinue) => {
if (shouldContinue) resolve(cli.uploadContent(file));
},
});
};
fileSelector.click();
});
}
return success(promise.then((url) => {
const ev = room.currentState.getStateEvents('m.room.member', userId);
const content = {
...ev ? ev.getContent() : { membership: 'join' },
avatar_url: url,
};
return cli.sendStateEvent(roomId, 'm.room.member', content, userId);
}));
},
}),
tint: new Command({ tint: new Command({
name: 'tint', name: 'tint',
args: '<color1> [<color2>]', args: '<color1> [<color2>]',
@ -718,6 +762,26 @@ export const CommandMap = {
return success(); return success();
}, },
}), }),
rainbow: new Command({
name: "rainbow",
description: _td("Sends the given message coloured as a rainbow"),
args: '<message>',
runFn: function(roomId, args) {
if (!args) return reject(this.getUserId());
return success(MatrixClientPeg.get().sendHtmlMessage(roomId, args, textToHtmlRainbow(args)));
},
}),
rainbowme: new Command({
name: "rainbowme",
description: _td("Sends the given emote coloured as a rainbow"),
args: '<message>',
runFn: function(roomId, args) {
if (!args) return reject(this.getUserId());
return success(MatrixClientPeg.get().sendHtmlEmote(roomId, args, textToHtmlRainbow(args)));
},
}),
}; };
/* eslint-enable babel/no-invalid-this */ /* eslint-enable babel/no-invalid-this */
@ -727,6 +791,7 @@ const aliases = {
j: "join", j: "join",
newballsplease: "discardsession", newballsplease: "discardsession",
goto: "join", // because it handles event permalinks magically goto: "join", // because it handles event permalinks magically
roomnick: "myroomnick",
}; };

View File

@ -1,5 +1,6 @@
/* /*
Copyright 2019 New Vector Ltd Copyright 2019 New Vector Ltd
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -26,6 +27,7 @@ import NotificationSettingsTab from "../settings/tabs/room/NotificationSettingsT
import sdk from "../../../index"; import sdk from "../../../index";
import MatrixClientPeg from "../../../MatrixClientPeg"; import MatrixClientPeg from "../../../MatrixClientPeg";
import SettingsStore from '../../../settings/SettingsStore'; import SettingsStore from '../../../settings/SettingsStore';
import dis from "../../../dispatcher";
export default class RoomSettingsDialog extends React.Component { export default class RoomSettingsDialog extends React.Component {
static propTypes = { static propTypes = {
@ -33,6 +35,22 @@ export default class RoomSettingsDialog extends React.Component {
onFinished: PropTypes.func.isRequired, onFinished: PropTypes.func.isRequired,
}; };
componentWillMount() {
this._dispatcherRef = dis.register(this._onAction);
}
componentWillUnmount() {
dis.unregister(this._dispatcherRef);
}
_onAction = (payload) => {
// When room changes below us, close the room settings
// whilst the modal is open this can only be triggered when someone hits Leave Room
if (payload.action === 'view_next_room') {
this.props.onFinished();
}
};
_getTabs() { _getTabs() {
const tabs = []; const tabs = [];

View File

@ -735,8 +735,8 @@ module.exports = withMatrixClient(React.createClass({
// we're only inviting one user. // we're only inviting one user.
const inviter = new MultiInviter(roomId); const inviter = new MultiInviter(roomId);
await inviter.invite([member.userId]).then(() => { await inviter.invite([member.userId]).then(() => {
if (inviter.getCompletionState(userId) !== "invited") if (inviter.getCompletionState(member.userId) !== "invited")
throw new Error(inviter.getErrorText(userId)); throw new Error(inviter.getErrorText(member.userId));
}); });
} catch (err) { } catch (err) {
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');

View File

@ -146,6 +146,7 @@
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Changes your display nickname": "Changes your display nickname", "Changes your display nickname": "Changes your display nickname",
"Changes your display nickname in the current room only": "Changes your display nickname in the current room only", "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 colour scheme of current room": "Changes colour scheme of current room", "Changes colour scheme of current room": "Changes colour scheme of current room",
"Gets or sets the room topic": "Gets or sets the room topic", "Gets or sets the room topic": "Gets or sets the room topic",
"This room has no topic.": "This room has no topic.", "This room has no topic.": "This room has no topic.",
@ -178,6 +179,8 @@
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.",
"Displays action": "Displays action", "Displays action": "Displays action",
"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", "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",
"Unrecognised command:": "Unrecognised command:", "Unrecognised command:": "Unrecognised command:",
"Reason": "Reason", "Reason": "Reason",
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.",

67
src/utils/colour.js Normal file
View File

@ -0,0 +1,67 @@
/*
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.
*/
export function hueToRGB(h, s, l) {
const c = s * (1 - Math.abs(2 * l - 1));
const x = c * (1 - Math.abs((h / 60) % 2 - 1));
const m = l - c / 2;
let r = 0;
let g = 0;
let b = 0;
if (0 <= h && h < 60) {
r = c;
g = x;
b = 0;
} else if (60 <= h && h < 120) {
r = x;
g = c;
b = 0;
} else if (120 <= h && h < 180) {
r = 0;
g = c;
b = x;
} else if (180 <= h && h < 240) {
r = 0;
g = x;
b = c;
} else if (240 <= h && h < 300) {
r = x;
g = 0;
b = c;
} else if (300 <= h && h < 360) {
r = c;
g = 0;
b = x;
}
return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)];
}
export function textToHtmlRainbow(str) {
const frequency = 360 / str.length;
return str.split("").map((c, i) => {
const [r, g, b] = hueToRGB(i * frequency, 1.0, 0.5);
return '<font color="#' +
r.toString(16).padStart(2, "0") +
g.toString(16).padStart(2, "0") +
b.toString(16).padStart(2, "0") +
'">' + c + '</font>';
}).join("");
}