Merge branch 'develop' into hs/custom-notif-sounds
This commit is contained in:
commit
e8c8762e34
5 changed files with 157 additions and 4 deletions
|
@ -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",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 = [];
|
||||||
|
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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
67
src/utils/colour.js
Normal 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("");
|
||||||
|
}
|
Loading…
Reference in a new issue