+
diff --git a/src/services/matrix.service.js b/src/services/matrix.service.js
index 2fed98a..102df72 100644
--- a/src/services/matrix.service.js
+++ b/src/services/matrix.service.js
@@ -2,12 +2,21 @@ import olm from "@matrix-org/olm/olm";
global.Olm = olm;
import * as sdk from "matrix-js-sdk";
import { TimelineWindow, EventTimeline, EventStatus } from "matrix-js-sdk";
-import util, { STATE_EVENT_ROOM_DELETED } from "../plugins/utils";
+import util, { STATE_EVENT_ROOM_DELETED, STATE_EVENT_ROOM_TYPE, ROOM_TYPE_CHANNEL, ROOM_TYPE_FILE_MODE, ROOM_TYPE_VOICE_MODE, ROOM_TYPE_DEFAULT } from "../plugins/utils";
import User from "../models/user";
const LocalStorageCryptoStore =
require("matrix-js-sdk/lib/crypto/store/localStorage-crypto-store").LocalStorageCryptoStore;
+export const CHANNEL_POWER_LEVELS = {
+ "m.room.encrypted": 0, // NOTE! Since practically all events in encrypted rooms get sent as "m.room.encrypted" we need to set
+ // power to 0 here. Otherwise we would not be able to send quick reactions or poll responses...
+ "m.poll.response": 0,
+ "org.matrix.msc3381.poll.response": 0,
+ "m.reaction": 0,
+ "m.room.redaction": 0,
+};
+
export default {
install(Vue, options) {
if (!options || !options.store) {
@@ -37,7 +46,8 @@ export default {
userDisplayName: null,
userAvatar: null,
currentRoom: null,
- currentRoomIsReadOnlyForUser: false,
+ userCanSendMessageInCurrentRoom: true,
+ userCanSendReactionAndAnswerPollInCurrentRoom: true,
currentRoomBeingPurged: false,
notificationCount: 0,
};
@@ -106,9 +116,11 @@ export default {
immediate: true,
handler(room) {
if (room) {
- this.currentRoomIsReadOnlyForUser = this.isReadOnlyRoomForUser(room.roomId, this.currentUserId);
+ this.userCanSendMessageInCurrentRoom = this.userCanSendMessageInRoom(room.roomId, this.currentUserId);
+ this.userCanSendReactionAndAnswerPollInCurrentRoom = this.userCanSendReactionAndAnswerPollInRoom(room.roomId, this.currentUserId);
} else {
- this.currentRoomIsReadOnlyForUser = false;
+ this.userCanSendMessageInCurrentRoom = true;
+ this.userCanSendReactionAndAnswerPollInCurrentRoom = true;
}
},
},
@@ -388,7 +400,8 @@ export default {
case "m.room.power_levels":
{
if (this.currentRoom && event.getRoomId() == this.currentRoom.roomId) {
- this.currentRoomIsReadOnlyForUser = this.isReadOnlyRoomForUser(event.getRoomId(), this.currentUserId);
+ this.userCanSendMessageInCurrentRoom = this.userCanSendMessageInRoom(event.getRoomId(), this.currentUserId);
+ this.userCanSendReactionAndAnswerPollInCurrentRoom = this.userCanSendReactionAndAnswerPollInRoom(event.getRoomId(), this.currentUserId);
}
}
break;
@@ -673,6 +686,9 @@ export default {
if (room && room.currentState) {
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
if (powerLevelEvent) {
+ if (this.roomType(roomId) == ROOM_TYPE_CHANNEL) {
+ return Object.keys(powerLevelEvent.getContent().events).length == 0;
+ }
return powerLevelEvent.getContent().events_default > 0;
}
}
@@ -680,16 +696,6 @@ export default {
return false;
},
- isReadOnlyRoomForUser(roomId, userId) {
- if (this.matrixClient && roomId && userId) {
- const room = this.getRoom(roomId);
- if (room && room.currentState) {
- return !room.currentState.maySendMessage(userId);
- }
- }
- return false;
- },
-
setReadOnlyRoom(roomId, readOnly) {
if (this.matrixClient && roomId) {
const room = this.getRoom(roomId);
@@ -697,13 +703,55 @@ export default {
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
if (powerLevelEvent) {
let content = powerLevelEvent.getContent();
- content.events_default = readOnly ? 50 : 0;
+ if (this.roomType(roomId) == ROOM_TYPE_CHANNEL) {
+ content.events = readOnly ? {} : CHANNEL_POWER_LEVELS
+ } else {
+ content.events_default = readOnly ? 50 : 0;
+ }
this.matrixClient.sendStateEvent(room.roomId, "m.room.power_levels", content);
}
}
}
},
+ userCanSendMessageInRoom(roomId, userId) {
+ if (this.matrixClient && roomId && userId) {
+ const room = this.getRoom(roomId);
+ if (room && room.currentState) {
+ let isAdmin = room.currentState.maySendEvent("m.room.power_levels", this.currentUserId);
+ return isAdmin || (this.roomType(roomId) != ROOM_TYPE_CHANNEL && !this.isReadOnlyRoom(roomId));
+ }
+ }
+ return true;
+ },
+
+ userCanSendReactionAndAnswerPollInRoom(roomId, userId) {
+ if (this.matrixClient && roomId && userId) {
+ const room = this.getRoom(roomId);
+ if (room && room.currentState) {
+ let isAdmin = room.currentState.maySendEvent("m.room.power_levels", this.currentUserId);
+ return isAdmin || !this.isReadOnlyRoom(roomId);
+ }
+ }
+ return true;
+ },
+
+ roomType(roomId) {
+ if (this.matrixClient && roomId) {
+ const room = this.getRoom(roomId);
+ if (room && room.currentState) {
+ const roomTypeEvent = room.currentState.getStateEvents(STATE_EVENT_ROOM_TYPE, "") || room.currentState.getStateEvents("m.room.create", "");
+ if (roomTypeEvent) {
+ const roomType = roomTypeEvent.getContent().type;
+ if ([ROOM_TYPE_FILE_MODE, ROOM_TYPE_VOICE_MODE, ROOM_TYPE_CHANNEL].includes(roomType)) {
+ return roomType;
+ }
+ }
+ }
+ }
+ return ROOM_TYPE_DEFAULT;
+ },
+
/**
* Purge the room with the given id! This means:
* - Make room invite only