mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-08-14 00:35:24 -04:00
Merge branch 'develop' of github.com:matrix-org/synapse into develop
Conflicts: synapse/http/client.py
This commit is contained in:
commit
d72ce4da64
168 changed files with 1898 additions and 789 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -97,23 +97,28 @@ angular.module('matrixWebClient')
|
|||
// Else, build the name from its users
|
||||
var room = $rootScope.events.rooms[room_id];
|
||||
if (room) {
|
||||
if (room.members) {
|
||||
var room_name_event = room["m.room.name"];
|
||||
|
||||
if (room_name_event) {
|
||||
roomName = room_name_event.content.name;
|
||||
}
|
||||
else if (room.members) {
|
||||
// Limit the room renaming to 1:1 room
|
||||
if (2 === Object.keys(room.members).length) {
|
||||
for (var i in room.members) {
|
||||
var member = room.members[i];
|
||||
if (member.user_id !== matrixService.config().user_id) {
|
||||
if (member.state_key !== matrixService.config().user_id) {
|
||||
|
||||
if (member.user_id in $rootScope.presence) {
|
||||
if (member.state_key in $rootScope.presence) {
|
||||
// If the user is available in presence, use the displayname there
|
||||
// as it is the most uptodate
|
||||
roomName = $rootScope.presence[member.user_id].content.displayname;
|
||||
roomName = $rootScope.presence[member.state_key].content.displayname;
|
||||
}
|
||||
else if (member.content.displayname) {
|
||||
roomName = member.content.displayname;
|
||||
}
|
||||
else {
|
||||
roomName = member.user_id;
|
||||
roomName = member.state_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +145,7 @@ angular.module('matrixWebClient')
|
|||
roomName = $rootScope.presence[userID].content.displayname;
|
||||
}
|
||||
else {
|
||||
roomName = member.user_id;
|
||||
roomName = userID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -32,7 +32,9 @@ angular.module('eventHandlerService', [])
|
|||
var MSG_EVENT = "MSG_EVENT";
|
||||
var MEMBER_EVENT = "MEMBER_EVENT";
|
||||
var PRESENCE_EVENT = "PRESENCE_EVENT";
|
||||
var POWERLEVEL_EVENT = "POWERLEVEL_EVENT";
|
||||
var CALL_EVENT = "CALL_EVENT";
|
||||
var NAME_EVENT = "NAME_EVENT";
|
||||
|
||||
var InitialSyncDeferred = $q.defer();
|
||||
|
||||
|
@ -95,7 +97,7 @@ angular.module('eventHandlerService', [])
|
|||
}
|
||||
}
|
||||
|
||||
$rootScope.events.rooms[event.room_id].members[event.user_id] = event;
|
||||
$rootScope.events.rooms[event.room_id].members[event.state_key] = event;
|
||||
$rootScope.$broadcast(MEMBER_EVENT, event, isLiveEvent);
|
||||
};
|
||||
|
||||
|
@ -107,10 +109,20 @@ angular.module('eventHandlerService', [])
|
|||
var handlePowerLevels = function(event, isLiveEvent) {
|
||||
initRoom(event.room_id);
|
||||
|
||||
$rootScope.events.rooms[event.room_id][event.type] = event;
|
||||
// Keep the latest data. Do not care of events that come when paginating back
|
||||
if (!$rootScope.events.rooms[event.room_id][event.type] || isLiveEvent) {
|
||||
$rootScope.events.rooms[event.room_id][event.type] = event;
|
||||
$rootScope.$broadcast(POWERLEVEL_EVENT, event, isLiveEvent);
|
||||
}
|
||||
};
|
||||
|
||||
//TODO
|
||||
//$rootScope.$broadcast(PRESENCE_EVENT, event, isLiveEvent);
|
||||
var handleRoomName = function(event, isLiveEvent) {
|
||||
console.log("handleRoomName " + isLiveEvent);
|
||||
|
||||
initRoom(event.room_id);
|
||||
|
||||
$rootScope.events.rooms[event.room_id][event.type] = event;
|
||||
$rootScope.$broadcast(NAME_EVENT, event, isLiveEvent);
|
||||
};
|
||||
|
||||
var handleCallEvent = function(event, isLiveEvent) {
|
||||
|
@ -122,7 +134,9 @@ angular.module('eventHandlerService', [])
|
|||
MSG_EVENT: MSG_EVENT,
|
||||
MEMBER_EVENT: MEMBER_EVENT,
|
||||
PRESENCE_EVENT: PRESENCE_EVENT,
|
||||
POWERLEVEL_EVENT: POWERLEVEL_EVENT,
|
||||
CALL_EVENT: CALL_EVENT,
|
||||
NAME_EVENT: NAME_EVENT,
|
||||
|
||||
|
||||
handleEvent: function(event, isLiveEvent) {
|
||||
|
@ -146,7 +160,9 @@ angular.module('eventHandlerService', [])
|
|||
case 'm.room.power_levels':
|
||||
handlePowerLevels(event, isLiveEvent);
|
||||
break;
|
||||
|
||||
case 'm.room.name':
|
||||
handleRoomName(event, isLiveEvent);
|
||||
break;
|
||||
default:
|
||||
console.log("Unable to handle event type " + event.type);
|
||||
console.log(JSON.stringify(event, undefined, 4));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -167,6 +167,29 @@ angular.module('matrixService', [])
|
|||
return doRequest("POST", path, undefined, data);
|
||||
},
|
||||
|
||||
// Change the membership of an another user
|
||||
setMembership: function(room_id, user_id, membershipValue) {
|
||||
// The REST path spec
|
||||
var path = "/rooms/$room_id/state/m.room.member/$user_id";
|
||||
path = path.replace("$room_id", encodeURIComponent(room_id));
|
||||
path = path.replace("$user_id", user_id);
|
||||
|
||||
return doRequest("PUT", path, undefined, {
|
||||
membership: membershipValue
|
||||
});
|
||||
},
|
||||
|
||||
// Bans a user from from a room
|
||||
ban: function(room_id, user_id, reason) {
|
||||
var path = "/rooms/$room_id/ban";
|
||||
path = path.replace("$room_id", encodeURIComponent(room_id));
|
||||
|
||||
return doRequest("POST", path, undefined, {
|
||||
user_id: user_id,
|
||||
reason: reason
|
||||
});
|
||||
},
|
||||
|
||||
// Retrieves the room ID corresponding to a room alias
|
||||
resolveRoomAlias:function(room_alias) {
|
||||
var path = "/_matrix/client/api/v1/directory/room/$room_alias";
|
||||
|
@ -253,7 +276,7 @@ angular.module('matrixService', [])
|
|||
|
||||
// get a list of public rooms on your home server
|
||||
publicRooms: function() {
|
||||
var path = "/publicRooms"
|
||||
var path = "/publicRooms";
|
||||
return doRequest("GET", path);
|
||||
},
|
||||
|
||||
|
@ -309,7 +332,7 @@ angular.module('matrixService', [])
|
|||
|
||||
// hit the Identity Server for a 3PID request.
|
||||
linkEmail: function(email, clientSecret, sendAttempt) {
|
||||
var path = "/_matrix/identity/api/v1/validate/email/requestToken"
|
||||
var path = "/_matrix/identity/api/v1/validate/email/requestToken";
|
||||
var data = "clientSecret="+clientSecret+"&email=" + encodeURIComponent(email)+"&sendAttempt="+sendAttempt;
|
||||
var headers = {};
|
||||
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
||||
|
@ -414,7 +437,8 @@ angular.module('matrixService', [])
|
|||
state: presence
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
/****** Permanent storage of user information ******/
|
||||
|
||||
// Returns the current config
|
||||
|
@ -514,6 +538,35 @@ angular.module('matrixService', [])
|
|||
}
|
||||
}
|
||||
return powerLevel;
|
||||
},
|
||||
|
||||
/**
|
||||
* Change or reset the power level of a user
|
||||
* @param {String} room_id the room id
|
||||
* @param {String} user_id the user id
|
||||
* @param {Number} powerLevel a value between 0 and 10
|
||||
* If undefined, the user power level will be reset, ie he will use the default room user power level
|
||||
* @returns {promise} an $http promise
|
||||
*/
|
||||
setUserPowerLevel: function(room_id, user_id, powerLevel) {
|
||||
|
||||
// Hack: currently, there is no home server API so do it by hand by updating
|
||||
// the current m.room.power_levels of the room and send it to the server
|
||||
var room = $rootScope.events.rooms[room_id];
|
||||
if (room && room["m.room.power_levels"]) {
|
||||
var content = angular.copy(room["m.room.power_levels"].content);
|
||||
content[user_id] = powerLevel;
|
||||
|
||||
var path = "/rooms/$room_id/state/m.room.power_levels";
|
||||
path = path.replace("$room_id", encodeURIComponent(room_id));
|
||||
|
||||
return doRequest("PUT", path, undefined, content);
|
||||
}
|
||||
|
||||
// The room does not exist or does not contain power_levels data
|
||||
var deferred = $q.defer();
|
||||
deferred.reject({data:{error: "Invalid room: " + room_id}});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<div ng-hide="room.membership === 'invite'" ng-switch="room.lastMsg.type" >
|
||||
<div ng-switch-when="m.room.member">
|
||||
{{ room.lastMsg.user_id }}
|
||||
{{ {"join": "joined", "leave": "left", "invite": "invited"}[room.lastMsg.content.membership] }}
|
||||
{{ room.lastMsg.content.membership === "invite" ? (room.lastMsg.state_key || '') : '' }}
|
||||
{{ {"join": "joined", "leave": "left", "invite": "invited", "ban": "banned"}[msg.content.membership] }}
|
||||
{{ (msg.content.membership === "invite" || msg.content.membership === "ban") ? (msg.state_key || '') : '' }}
|
||||
</div>
|
||||
|
||||
<div ng-switch-when="m.room.message">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -85,6 +85,14 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput'])
|
|||
updatePresence(event);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on(eventHandlerService.POWERLEVEL_EVENT, function(ngEvent, event, isLive) {
|
||||
if (isLive && event.room_id === $scope.room_id) {
|
||||
for (var user_id in event.content) {
|
||||
updateUserPowerLevel(user_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.memberCount = function() {
|
||||
return Object.keys($scope.members).length;
|
||||
|
@ -161,6 +169,11 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput'])
|
|||
var updateMemberList = function(chunk) {
|
||||
if (chunk.room_id != $scope.room_id) return;
|
||||
|
||||
// Ignore banned people
|
||||
if ("ban" === chunk.membership) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set target_user_id to keep things clear
|
||||
var target_user_id = chunk.state_key;
|
||||
|
||||
|
@ -240,6 +253,29 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput'])
|
|||
var member = $scope.members[user_id];
|
||||
if (member) {
|
||||
member.powerLevel = matrixService.getUserPowerLevel($scope.room_id, user_id);
|
||||
|
||||
normaliseMembersPowerLevels();
|
||||
}
|
||||
}
|
||||
|
||||
// Normalise users power levels so that the user with the higher power level
|
||||
// will have a bar covering 100% of the width of his avatar
|
||||
var normaliseMembersPowerLevels = function() {
|
||||
// Find the max power level
|
||||
var maxPowerLevel = 0;
|
||||
for (var i in $scope.members) {
|
||||
var member = $scope.members[i];
|
||||
if (member.powerLevel) {
|
||||
maxPowerLevel = Math.max(maxPowerLevel, member.powerLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Normalized them on a 0..100% scale to be use in css width
|
||||
if (maxPowerLevel) {
|
||||
for (var i in $scope.members) {
|
||||
var member = $scope.members[i];
|
||||
member.powerLevelNorm = (member.powerLevel * 100) / maxPowerLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,28 +286,93 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput'])
|
|||
|
||||
$scope.state.sending = true;
|
||||
|
||||
// Send the text message
|
||||
var promise;
|
||||
// FIXME: handle other commands too
|
||||
if ($scope.textInput.indexOf("/me") === 0) {
|
||||
promise = matrixService.sendEmoteMessage($scope.room_id, $scope.textInput.substr(4));
|
||||
|
||||
// Check for IRC style commands first
|
||||
if ($scope.textInput.indexOf("/") === 0) {
|
||||
var args = $scope.textInput.split(' ');
|
||||
var cmd = args[0];
|
||||
|
||||
switch (cmd) {
|
||||
case "/me":
|
||||
var emoteMsg = args.slice(1).join(' ');
|
||||
promise = matrixService.sendEmoteMessage($scope.room_id, emoteMsg);
|
||||
break;
|
||||
|
||||
case "/nick":
|
||||
// Change user display name
|
||||
if (2 === args.length) {
|
||||
promise = matrixService.setDisplayName(args[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case "/kick":
|
||||
// Kick a user from the room
|
||||
if (2 === args.length) {
|
||||
var user_id = args[1];
|
||||
|
||||
// Set his state in the room as leave
|
||||
promise = matrixService.setMembership($scope.room_id, user_id, "leave");
|
||||
}
|
||||
break;
|
||||
|
||||
case "/ban":
|
||||
// Ban a user from the room
|
||||
if (2 <= args.length) {
|
||||
// TODO: The user may have entered the display name
|
||||
// Need display name -> user_id resolution. Pb: how to manage user with same display names?
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case "/unban":
|
||||
// Unban a user from the room
|
||||
if (2 === args.length) {
|
||||
var user_id = args[1];
|
||||
|
||||
// Reset the user membership to leave to unban him
|
||||
promise = matrixService.setMembership($scope.room_id, user_id, "leave");
|
||||
}
|
||||
break;
|
||||
|
||||
case "/op":
|
||||
// Define the power level of a user
|
||||
if (3 === args.length) {
|
||||
var user_id = args[1];
|
||||
var powerLevel = parseInt(args[2]);
|
||||
promise = matrixService.setUserPowerLevel($scope.room_id, user_id, powerLevel);
|
||||
}
|
||||
break;
|
||||
|
||||
case "/deop":
|
||||
// Reset the power level of a user
|
||||
if (2 === args.length) {
|
||||
var user_id = args[1];
|
||||
promise = matrixService.setUserPowerLevel($scope.room_id, user_id, undefined);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ($scope.textInput.indexOf("/nick ") === 0) {
|
||||
// Change user display name
|
||||
promise = matrixService.setDisplayName($scope.textInput.substr(6));
|
||||
}
|
||||
else {
|
||||
|
||||
if (!promise) {
|
||||
// Send the text message
|
||||
promise = matrixService.sendTextMessage($scope.room_id, $scope.textInput);
|
||||
}
|
||||
|
||||
promise.then(
|
||||
function() {
|
||||
console.log("Sent message");
|
||||
console.log("Request successfully sent");
|
||||
$scope.textInput = "";
|
||||
$scope.state.sending = false;
|
||||
},
|
||||
function(error) {
|
||||
$scope.feedback = "Failed to send: " + error.data.error;
|
||||
$scope.feedback = "Request failed: " + error.data.error;
|
||||
$scope.state.sending = false;
|
||||
});
|
||||
};
|
||||
|
@ -363,7 +464,8 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput'])
|
|||
onInit3();
|
||||
},
|
||||
function(reason) {
|
||||
$scope.feedback = "Can't join room: " + reason;
|
||||
console.log("Can't join room: " + JSON.stringify(reason));
|
||||
$scope.feedback = "You do not have permission to join this room";
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
title="{{ member.id }}"
|
||||
width="80" height="80"/>
|
||||
<img class="userAvatarGradient" src="img/gradient.png" title="{{ member.id }}" width="80" height="24"/>
|
||||
<div class="userPowerLevel" ng-style="{'width': (10 * member.powerLevel) +'%'}"></div>
|
||||
<div class="userPowerLevel" ng-style="{'width': member.powerLevelNorm +'%'}"></div>
|
||||
<div class="userName">{{ member.displayname || member.id.substr(0, member.id.indexOf(':')) }}<br/>{{ member.displayname ? "" : member.id.substr(member.id.indexOf(':')) }}</div>
|
||||
</td>
|
||||
<td class="userPresence" ng-class="(member.presence === 'online' ? 'online' : (member.presence === 'unavailable' ? 'unavailable' : '')) + ' ' + (member.membership == 'invite' ? 'invited' : '')">
|
||||
|
@ -50,8 +50,9 @@
|
|||
<div class="bubble">
|
||||
<span ng-show='msg.type === "m.room.member"'>
|
||||
{{ members[msg.user_id].displayname || msg.user_id }}
|
||||
{{ {"join": "joined", "leave": "left", "invite": "invited"}[msg.content.membership] }}
|
||||
{{ msg.content.membership === "invite" ? (msg.state_key || '') : '' }}
|
||||
{{ {"join": "joined", "leave": "left", "invite": "invited", "ban": "banned"}[msg.content.membership] }}
|
||||
{{ (msg.content.membership === "invite" || msg.content.membership === "ban") ? (msg.state_key || '') : '' }}
|
||||
|
||||
</span>
|
||||
<span ng-show='msg.content.msgtype === "m.emote"' ng-bind-html="'* ' + (members[msg.user_id].displayname || msg.user_id) + ' ' + msg.content.body | linky:'_blank'"/>
|
||||
<span ng-show='msg.content.msgtype === "m.text"' ng-bind-html="((msg.content.msgtype === 'm.text') ? msg.content.body : '') | linky:'_blank'"/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -74,6 +74,21 @@
|
|||
<div>Access token: {{ config.access_token }} </div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<h3>Commands</h3>
|
||||
<div class="section">
|
||||
The following commands are available in the room chat:
|
||||
<ul>
|
||||
<li>/nick <display_name>: change your display name</li>
|
||||
<li>/me <action>: send the action you are doing. /me will be replaced by your display name</li>
|
||||
<li>/kick <user_id>: kick the user</li>
|
||||
<li>/ban <user_id> [<reason>]: ban the user</li>
|
||||
<li>/unban <user_id>: unban the user</li>
|
||||
<li>/op <user_id> <power_level>: set user power level</li>
|
||||
<li>/deop <user_id>: reset user power level to the room default value</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
{{ feedback }}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 matrix.org
|
||||
Copyright 2014 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue