Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-encrypted-message-power-level.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

Allow users to send messages in encrypted rooms when they have permission to send `m.room.encrypted` events.
5 changes: 5 additions & 0 deletions .changeset/fix-two-member-channel-name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

Display the explicit room name for non-direct channels with two members.
9 changes: 2 additions & 7 deletions src/app/features/room/RoomTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,8 @@ export function RoomTimeline({

const powerLevels = usePowerLevelsContext();
const creators = useRoomCreators(room);
const isReadOnly = useMemo(() => {
const myPowerLevel = powerLevels?.users?.[mx.getUserId()!] ?? powerLevels?.users_default ?? 0;
const sendLevel = powerLevels?.events?.['m.room.message'] ?? powerLevels?.events_default ?? 0;
return myPowerLevel < sendLevel;
}, [powerLevels, mx]);
const permissions = useRoomPermissions(creators, powerLevels);
const isReadOnly = !permissions.message(room.hasEncryptionStateEvent(), mx.getSafeUserId());

const settings = useMemo(
() => ({
Expand Down Expand Up @@ -375,8 +372,6 @@ export function RoomTimeline({
const ignoredUsersSet = useMemo(() => new Set(ignoredUsersList), [ignoredUsersList]);

const getMemberPowerTag = useGetMemberPowerTag(room, creators, powerLevels);
const permissions = useRoomPermissions(creators, powerLevels);

const [unreadInfo, setUnreadInfo] = useState(() => getRoomUnreadInfo(room, true));

const readUptoEventIdRef = useRef<string | undefined>(undefined);
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/room/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function RoomView({ eventId }: { eventId?: string }) {
const creators = useRoomCreators(room);

const permissions = useRoomPermissions(creators, powerLevels);
const canMessage = permissions.event(EventType.RoomMessage, mx.getSafeUserId());
const canMessage = permissions.message(room.hasEncryptionStateEvent(), mx.getSafeUserId());

const [editorResetKey, setEditorResetKey] = useState(0);
const handleResetEditor = useCallback(() => setEditorResetKey((prev) => prev + 1), []);
Expand Down
6 changes: 1 addition & 5 deletions src/app/features/room/ThreadDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,7 @@ export function ThreadDrawer({ room, threadRootId, onClose, overlay }: ThreadDra
const canDeleteOwn = permissions.event(EventType.RoomRedaction, mx.getSafeUserId());
const canSendReaction = permissions.event(EventType.Reaction, mx.getSafeUserId());
const canPinEvent = permissions.stateEvent(EventType.RoomPinnedEvents, mx.getSafeUserId());
const isReadOnly = useMemo(() => {
const myPowerLevel = powerLevels?.users?.[mx.getUserId()!] ?? powerLevels?.users_default ?? 0;
const sendLevel = powerLevels?.events?.['m.room.message'] ?? powerLevels?.events_default ?? 0;
return myPowerLevel < sendLevel;
}, [powerLevels, mx]);
const isReadOnly = !permissions.message(room.hasEncryptionStateEvent(), mx.getSafeUserId());
const getMemberPowerTag = useGetMemberPowerTag(room, creators, powerLevels);
const parseMemberEvent = useMemberEventParser();

Expand Down
17 changes: 15 additions & 2 deletions src/app/hooks/useRoomMeta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import { mDirectAtom } from '$state/mDirectList';
import { useStateEvent } from './useStateEvent';
import { useNickname } from './useNickname';

export const getRoomDisplayName = (
roomName: string,
stateName: unknown,
isDmTagged: boolean,
dmNickname?: string
): string => {
if (isDmTagged && dmNickname) return dmNickname;
if (typeof stateName === 'string' && stateName) return stateName;
return roomName;
};

export const useRoomAvatar = (room: Room, dm?: boolean): string | undefined => {
const avatarEvent = useStateEvent(room, EventType.RoomAvatar);

Expand All @@ -24,6 +35,8 @@ export const useRoomName = (room: Room): string => {
const dmNickname = useNickname(dmUserId || '');
const mDirects = useAtomValue(mDirectAtom);
const isDmTagged = mDirects.has(room.roomId);
const nameEvent = useStateEvent(room, EventType.RoomName);
const stateName = nameEvent?.getContent().name;
const [name, setName] = useState(room.name);

useEffect(() => {
Expand All @@ -32,7 +45,7 @@ export const useRoomName = (room: Room): string => {
room.recalculate();
}

const nextName = isDmTagged && dmNickname ? dmNickname : room.name;
const nextName = getRoomDisplayName(room.name, stateName, isDmTagged, dmNickname);
setName((prev) => (prev !== nextName ? nextName : prev));
};

Expand All @@ -45,7 +58,7 @@ export const useRoomName = (room: Room): string => {
room.removeListener(RoomEvent.Name, updateName);
room.removeListener(RoomStateEvent.Members, updateName);
};
}, [room, dmNickname, isDmTagged]);
}, [room, stateName, dmNickname, isDmTagged]);

return name;
};
Expand Down
7 changes: 7 additions & 0 deletions src/app/hooks/useRoomPermissions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useMemo } from 'react';
import { EventType } from '$types/matrix-sdk';
import type {
IPowerLevels,
PowerLevelActions,
Expand All @@ -8,6 +9,7 @@ import { readPowerLevel } from './usePowerLevels';

export type RoomPermissionsAPI = {
event: (type: string, userId: string) => boolean;
message: (encrypted: boolean, userId: string) => boolean;
stateEvent: (type: string, userId: string) => boolean;
action: (action: PowerLevelActions, userId: string) => boolean;
notificationAction: (action: PowerLevelNotificationsAction, userId: string) => boolean;
Expand All @@ -24,6 +26,11 @@ export const getRoomPermissionsAPI = (
const requiredPL = readPowerLevel.event(powerLevels, type);
return userPower >= requiredPL;
},
message: (encrypted, userId) =>
api.event(
encrypted ? (EventType.RoomMessageEncrypted as string) : EventType.RoomMessage,
userId
),
stateEvent: (type, userId) => {
if (creators.has(userId)) return true;
const userPower = readPowerLevel.user(powerLevels, userId);
Expand Down
Loading