1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-19 16:42:09 +03:00
Files
matrix-js-sdk/lib/models/room-state.js
2015-06-10 14:42:40 +01:00

150 lines
5.3 KiB
JavaScript

"use strict";
/**
* @module models/room-state
*/
var utils = require("../utils");
var RoomMember = require("./room-member");
/**
* Construct room state.
* @constructor
* @param {string} roomId Required. The ID of the room which has this state.
* @prop {Object.<string, RoomMember>} members The room member dictionary, keyed
* on the user's ID.
* @prop {Object.<string, Object.<string, MatrixEvent>>} events The state
* events dictionary, keyed on the event type and then the state_key value.
* @prop {string} paginationToken The pagination token for this state.
*/
function RoomState(roomId) {
this.roomId = roomId;
this.members = {
// userId: RoomMember
};
this.events = {
// eventType: { stateKey: MatrixEvent }
};
this.paginationToken = null;
}
RoomState.prototype = {
/**
* Get all RoomMembers in this room.
* @return {Array<RoomMember>} A list of RoomMembers.
*/
getMembers: function() {
return utils.values(this.members);
},
/**
* Get state events from the state of the room.
* @param {string} eventType The event type of the state event.
* @param {string} stateKey Optional. The state_key of the state event. If
* this is <code>undefined</code> then all matching state events will be
* returned.
* @return {MatrixEvent[]|MatrixEvent} A list of events if state_key was
* <code>undefined</code>, else a single event (or null if no match found).
*/
getStateEvents: function(eventType, stateKey) {
if (!this.events[eventType]) {
// no match
return stateKey === undefined ? [] : null;
}
if (stateKey === undefined) { // return all values
return utils.values(this.events[eventType]);
}
var event = this.events[eventType][stateKey];
return event ? event : null;
},
/**
* Add an array of one or more state MatrixEvents, overwriting
* any existing state with the same {type, stateKey} tuple.
* @param {MatrixEvent[]} stateEvents a list of state events for this room.
*/
setStateEvents: function(stateEvents) {
var self = this;
utils.forEach(stateEvents, function(event) {
if (event.getRoomId() !== self.roomId) { return; }
if (!event.isState()) { return; }
if (self.events[event.getType()] === undefined) {
self.events[event.getType()] = {};
}
self.events[event.getType()][event.getStateKey()] = event;
if (event.getType() === "m.room.member") {
var member = new RoomMember(event);
member.calculateDisplayName(self);
self.members[event.getStateKey()] = member;
// this member may have a power level already, so set it.
var pwrLvlEvent = self.getStateEvents("m.room.power_levels", "");
if (pwrLvlEvent) {
self._setPowerLevel(pwrLvlEvent, member);
}
}
else if (event.getType() === "m.room.power_levels") {
var members = utils.values(self.members);
utils.forEach(members, function(member) {
self._setPowerLevel(event, member);
});
}
});
},
/**
* (Internal) Set 'powerLevel' and 'powerLevelNorm' for the given member.
* @param {MatrixEvent} powerLevelEvent <code>m.room.power_levels</code>
* @param {RoomMember} roomMember The room member to set properties on.
*/
_setPowerLevel: function(powerLevelEvent, roomMember) {
var maxLevel = powerLevelEvent.getContent().users_default || 0;
utils.forEach(utils.values(powerLevelEvent.getContent().users), function(lvl) {
maxLevel = Math.max(maxLevel, lvl);
});
roomMember.powerLevel = (
powerLevelEvent.getContent().users[roomMember.userId] ||
powerLevelEvent.getContent().users_default ||
0
);
roomMember.powerLevelNorm = 0;
if (maxLevel > 0) {
roomMember.powerLevelNorm = (roomMember.powerLevel * 100) / maxLevel;
}
},
/**
* Set the current typing event for this room.
* @param {MatrixEvent} event The typing event
* @throws If the provided event type isn't 'm.typing'.
*/
setTypingEvent: function(event) {
if (event.getType() !== "m.typing") {
throw new Error("Not a typing event -> " + event.getType());
}
// typing events clobber and specify only those who are typing, so
// reset all users to say they are not typing then selectively set
// the specified users to be typing.
var self = this;
var members = utils.values(this.members);
utils.forEach(members, function(member) {
member.typing = false;
});
var typingList = event.getContent().user_ids;
if (!utils.isArray(typingList)) {
// malformed event :/ bail early. TODO: whine?
return;
}
utils.forEach(typingList, function(userId) {
if (!self.members[userId]) {
// user_id in typing list but not member list, TODO: whine?
return;
}
self.members[userId].typing = true;
});
}
};
/**
* The RoomState class.
*/
module.exports = RoomState;