Add ability to change room permissions
authorAjay Bura <ajbura@gmail.com>
Thu, 13 Jan 2022 07:56:38 +0000 (13:26 +0530)
committerAjay Bura <ajbura@gmail.com>
Thu, 13 Jan 2022 07:56:38 +0000 (13:26 +0530)
Signed-off-by: Ajay Bura <ajbura@gmail.com>
src/app/molecules/room-permissions/RoomPermissions.jsx
src/app/organisms/profile-viewer/ProfileViewer.scss
src/app/organisms/room/RoomView.scss

index d900197370311d484533bee114a7b5b4219cc1fa..d1a652c93ead0ebbadd5251cee5324d8984d6e37 100644 (file)
@@ -1,17 +1,22 @@
-import React from 'react';
+import React, { useEffect } from 'react';
 import PropTypes from 'prop-types';
 import './RoomPermissions.scss';
 
 import initMatrix from '../../../client/initMatrix';
 import { getPowerLabel } from '../../../util/matrixUtil';
+import { openReusableContextMenu } from '../../../client/action/navigation';
+import { getEventCords } from '../../../util/common';
 
 import Text from '../../atoms/text/Text';
 import Button from '../../atoms/button/Button';
 import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
+import PowerLevelSelector from '../power-level-selector/PowerLevelSelector';
 import SettingTile from '../setting-tile/SettingTile';
 
 import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
 
+import { useForceUpdate } from '../../hooks/useForceUpdate';
+
 const permissionsInfo = {
   users_default: {
     name: 'Default role',
@@ -144,13 +149,69 @@ const spacePermsGroups = {
   'Settings permissions': ['state_default', 'm.room.canonical_alias', 'm.room.power_levels'],
 };
 
+function useRoomStateUpdate(roomId) {
+  const [, forceUpdate] = useForceUpdate();
+  const mx = initMatrix.matrixClient;
+
+  useEffect(() => {
+    const handleStateEvent = (event) => {
+      if (event.getRoomId() !== roomId) return;
+      forceUpdate();
+    };
+
+    mx.on('RoomState.events', handleStateEvent);
+    return () => {
+      mx.removeListener('RoomState.events', handleStateEvent);
+    };
+  }, [roomId]);
+}
+
 function RoomPermissions({ roomId }) {
+  useRoomStateUpdate(roomId);
   const mx = initMatrix.matrixClient;
   const room = mx.getRoom(roomId);
   const pLEvent = room.currentState.getStateEvents('m.room.power_levels')[0];
   const permissions = pLEvent.getContent();
   const canChangePermission = room.currentState.maySendStateEvent('m.room.power_levels', mx.getUserId());
 
+  const handlePowerSelector = (e, permKey, parentKey, powerLevel) => {
+    const handlePowerLevelChange = (newPowerLevel) => {
+      if (powerLevel === newPowerLevel) return;
+
+      const newPermissions = { ...permissions };
+      if (parentKey) {
+        newPermissions[parentKey] = {
+          ...permissions[parentKey],
+          [permKey]: newPowerLevel,
+        };
+      } else if (permKey === 'notifications') {
+        newPermissions[permKey] = {
+          ...permissions[permKey],
+          room: newPowerLevel,
+        };
+      } else {
+        newPermissions[permKey] = newPowerLevel;
+      }
+
+      mx.sendStateEvent(roomId, 'm.room.power_levels', newPermissions);
+    };
+
+    openReusableContextMenu(
+      'bottom',
+      getEventCords(e, '.btn-surface'),
+      (closeMenu) => (
+        <PowerLevelSelector
+          value={powerLevel}
+          max={100}
+          onSelect={(pl) => {
+            closeMenu();
+            handlePowerLevelChange(pl);
+          }}
+        />
+      ),
+    );
+  };
+
   return (
     <div className="room-permissions">
       {
@@ -182,6 +243,11 @@ function RoomPermissions({ roomId }) {
                       content={<Text variant="b3">{permInfo.description}</Text>}
                       options={(
                         <Button
+                          onClick={
+                            canChangePermission
+                              ? (e) => handlePowerSelector(e, permKey, permInfo.parent, powerLevel)
+                              : null
+                          }
                           iconSrc={canChangePermission ? ChevronBottomIC : null}
                         >
                           <Text variant="b2">
index 35119b92232f8a4df7c4dd35d2898fb24c816ec8..1401b7779f9feaab945239b0078980f6c00b3a3d 100644 (file)
   box-shadow: var(--bs-surface-border);
   border-radius: var(--bo-radius);
   overflow: hidden;
+
+  & .context-menu__item button {
+    padding: var(--sp-extra-tight);
+    & .ic-raw {
+      @include dir.side(margin, 0, var(--sp-extra-tight));
+    }
+  }
   
   &__chips {
     border-top: 1px solid var(--bg-surface-border);
index dcf3edda9172b05f3299ac2d17aa74fed4622bae..2eda3ea7b4bb8418bc6943a41311691be0dc2ad9 100644 (file)
@@ -15,7 +15,7 @@
   &--dropped {
     transform: translateY(calc(100% - var(--header-height)));
     border-radius: var(--bo-radius) var(--bo-radius) 0 0;
-    box-shadow: 0 0 0 1px var(--bg-surface-border);
+    box-shadow: var(--bs-popup);
   }
 
   &__content-wrapper {