switch IRC-style command parser to use regexps rather than split(" ") so that it doesn't choke on consecutive whitespaces
yield better errors for invalid commands don't pass invalid commands through as messages support kick reasons
This commit is contained in:
parent
9c82276760
commit
3bc7bba262
2 changed files with 96 additions and 55 deletions
|
@ -169,14 +169,19 @@ angular.module('matrixService', [])
|
||||||
|
|
||||||
// Change the membership of an another user
|
// Change the membership of an another user
|
||||||
setMembership: function(room_id, user_id, membershipValue) {
|
setMembership: function(room_id, user_id, membershipValue) {
|
||||||
|
return this.setMemberShipObject(room_id, user_id, {
|
||||||
|
membership : membershipValue
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Change the membership of an another user
|
||||||
|
setMembershipObject: function(room_id, user_id, membershipObject) {
|
||||||
// The REST path spec
|
// The REST path spec
|
||||||
var path = "/rooms/$room_id/state/m.room.member/$user_id";
|
var path = "/rooms/$room_id/state/m.room.member/$user_id";
|
||||||
path = path.replace("$room_id", encodeURIComponent(room_id));
|
path = path.replace("$room_id", encodeURIComponent(room_id));
|
||||||
path = path.replace("$user_id", user_id);
|
path = path.replace("$user_id", user_id);
|
||||||
|
|
||||||
return doRequest("PUT", path, undefined, {
|
return doRequest("PUT", path, undefined, membershipObject);
|
||||||
membership: membershipValue
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Bans a user from from a room
|
// Bans a user from from a room
|
||||||
|
|
|
@ -287,84 +287,116 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
$scope.state.sending = true;
|
$scope.state.sending = true;
|
||||||
|
|
||||||
var promise;
|
var promise;
|
||||||
|
var isCmd = false;
|
||||||
|
|
||||||
// Check for IRC style commands first
|
// Check for IRC style commands first
|
||||||
if ($scope.textInput.indexOf("/") === 0) {
|
var line = $scope.textInput;
|
||||||
var args = $scope.textInput.split(' ');
|
|
||||||
var cmd = args[0];
|
// trim any trailing whitespace, as it can confuse the parser for IRC-style commands
|
||||||
|
line = line.replace(/\s+$/, "");
|
||||||
|
|
||||||
|
if (line[0] === "/" && line[1] !== "/") {
|
||||||
|
isCmd = true;
|
||||||
|
|
||||||
|
var bits = line.match(/^(\S+?)( +(.*))?$/);
|
||||||
|
var cmd = bits[1];
|
||||||
|
var args = bits[3];
|
||||||
|
|
||||||
|
console.log("cmd: " + cmd + ", args: " + args);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case "/me":
|
case "/me":
|
||||||
var emoteMsg = args.slice(1).join(' ');
|
promise = matrixService.sendEmoteMessage($scope.room_id, args);
|
||||||
promise = matrixService.sendEmoteMessage($scope.room_id, emoteMsg);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/nick":
|
case "/nick":
|
||||||
// Change user display name
|
// Change user display name
|
||||||
if (2 === args.length) {
|
promise = matrixService.setDisplayName(args);
|
||||||
promise = matrixService.setDisplayName(args[1]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/kick":
|
case "/kick":
|
||||||
// Kick a user from the room
|
var matches = args.match(/^(\S+?)( +(.*))?$/);
|
||||||
if (2 === args.length) {
|
if (matches.length === 2) {
|
||||||
var user_id = args[1];
|
promise = matrixService.setMembership($scope.room_id, matches[1], "leave");
|
||||||
|
}
|
||||||
// Set his state in the room as leave
|
else if (matches.length === 4) {
|
||||||
promise = matrixService.setMembership($scope.room_id, user_id, "leave");
|
promise = matrixService.setMembershipObject($scope.room_id, matches[1], {
|
||||||
|
membership: "leave",
|
||||||
|
reason: matches[3] // TODO: we need to specify resaon in the spec
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.feedback = "Usage: /kick <userId> [<reason>]";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/ban":
|
case "/ban":
|
||||||
// Ban a user from the room
|
// Ban a user from the room with optional reason
|
||||||
if (2 <= args.length) {
|
var matches = args.match(/^(\S+?)( +(.*))?$/);
|
||||||
// TODO: The user may have entered the display name
|
if (matches) {
|
||||||
// Need display name -> user_id resolution. Pb: how to manage user with same display names?
|
promise = matrixService.ban($scope.room_id, matches[1], matches[3]);
|
||||||
var user_id = args[1];
|
|
||||||
|
|
||||||
// Does the user provide a reason?
|
|
||||||
if (3 <= args.length) {
|
|
||||||
var reason = args.slice(2).join(' ');
|
|
||||||
}
|
}
|
||||||
promise = matrixService.ban($scope.room_id, user_id, reason);
|
else {
|
||||||
|
$scope.feedback = "Usage: /ban <userId> [<reason>]";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/unban":
|
case "/unban":
|
||||||
// Unban a user from the room
|
// Unban a user from the room
|
||||||
if (2 === args.length) {
|
// FIXME: this feels horribly asymmetrical - why are we banning via RPC
|
||||||
var user_id = args[1];
|
// and unbanning by editing the membership list?
|
||||||
|
// Why can't we specify a reason?
|
||||||
// Reset the user membership to leave to unban him
|
var matches = args.match(/^(\S+)$/);
|
||||||
promise = matrixService.setMembership($scope.room_id, user_id, "leave");
|
if (matches) {
|
||||||
|
// Reset the user membership to "leave" to unban him
|
||||||
|
promise = matrixService.setMembership($scope.room_id, args, "leave");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.feedback = "Usage: /unban <userId>";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/op":
|
case "/op":
|
||||||
// Define the power level of a user
|
// Define the power level of a user
|
||||||
if (3 === args.length) {
|
var matches = args.match(/^(\S+?)( +(\d+))?$/);
|
||||||
var user_id = args[1];
|
var powerLevel = 50; // default power level for op
|
||||||
var powerLevel = parseInt(args[2]);
|
if (matches) {
|
||||||
|
var user_id = matches[1];
|
||||||
|
if (matches.length == 4) {
|
||||||
|
powerLevel = parseInt(matches[3]);
|
||||||
|
}
|
||||||
|
if (powerLevel !== NaN) {
|
||||||
promise = matrixService.setUserPowerLevel($scope.room_id, user_id, powerLevel);
|
promise = matrixService.setUserPowerLevel($scope.room_id, user_id, powerLevel);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!promise) {
|
||||||
|
$scope.feedback = "Usage: /op <userId> [<power level>]";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/deop":
|
case "/deop":
|
||||||
// Reset the power level of a user
|
// Reset the power level of a user
|
||||||
if (2 === args.length) {
|
var matches = args.match(/^(\S+)$/);
|
||||||
var user_id = args[1];
|
if (matches) {
|
||||||
promise = matrixService.setUserPowerLevel($scope.room_id, user_id, undefined);
|
promise = matrixService.setUserPowerLevel($scope.room_id, args, undefined);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$scope.feedback = "Usage: /deop <userId>";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$scope.feedback = ("Unrecognised IRC-style command: " + cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!promise) {
|
// By default send this as a message unless it's an IRC-style command
|
||||||
// Send the text message
|
if (!promise && !isCmd) {
|
||||||
promise = matrixService.sendTextMessage($scope.room_id, $scope.textInput);
|
promise = matrixService.sendTextMessage($scope.room_id, $scope.textInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (promise) {
|
||||||
promise.then(
|
promise.then(
|
||||||
function() {
|
function() {
|
||||||
console.log("Request successfully sent");
|
console.log("Request successfully sent");
|
||||||
|
@ -375,6 +407,10 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
$scope.feedback = "Request failed: " + error.data.error;
|
$scope.feedback = "Request failed: " + error.data.error;
|
||||||
$scope.state.sending = false;
|
$scope.state.sending = false;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.state.sending = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.onInit = function() {
|
$scope.onInit = function() {
|
||||||
|
|
Loading…
Reference in a new issue