Add room permissions
authorAjay Bura <ajbura@gmail.com>
Mon, 10 Jan 2022 15:04:54 +0000 (20:34 +0530)
committerAjay Bura <ajbura@gmail.com>
Mon, 10 Jan 2022 15:04:54 +0000 (20:34 +0530)
Signed-off-by: Ajay Bura <ajbura@gmail.com>
src/app/molecules/room-permissions/RoomPermissions.jsx [new file with mode: 0644]
src/app/molecules/room-permissions/RoomPermissions.scss [new file with mode: 0644]
src/app/organisms/profile-viewer/ProfileViewer.jsx
src/app/organisms/room/RoomSettings.jsx
src/app/organisms/room/RoomSettings.scss

diff --git a/src/app/molecules/room-permissions/RoomPermissions.jsx b/src/app/molecules/room-permissions/RoomPermissions.jsx
new file mode 100644 (file)
index 0000000..d900197
--- /dev/null
@@ -0,0 +1,208 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import './RoomPermissions.scss';
+
+import initMatrix from '../../../client/initMatrix';
+import { getPowerLabel } from '../../../util/matrixUtil';
+
+import Text from '../../atoms/text/Text';
+import Button from '../../atoms/button/Button';
+import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
+import SettingTile from '../setting-tile/SettingTile';
+
+import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
+
+const permissionsInfo = {
+  users_default: {
+    name: 'Default role',
+    description: 'Set default role for all members.',
+    default: 0,
+  },
+  events_default: {
+    name: 'Send messages',
+    description: 'Set minimum power level to send messages in room.',
+    default: 0,
+  },
+  redact: {
+    name: 'Delete messages sent by others',
+    description: 'Set minimum power level to delete messages in room.',
+    default: 50,
+  },
+  notifications: {
+    name: 'Ping room',
+    description: 'Set minimum power level to ping room.',
+    default: {
+      room: 50,
+    },
+  },
+  'm.space.child': {
+    parent: 'events',
+    name: 'Manage rooms in space',
+    description: 'Set minimum power level to manage rooms in space.',
+    default: 50,
+  },
+  invite: {
+    name: 'Invite',
+    description: 'Set minimum power level to invite members.',
+    default: 50,
+  },
+  kick: {
+    name: 'Kick',
+    description: 'Set minimum power level to kick members.',
+    default: 50,
+  },
+  ban: {
+    name: 'Ban',
+    description: 'Set minimum power level to ban members.',
+    default: 50,
+  },
+  'm.room.avatar': {
+    parent: 'events',
+    name: 'Change avatar',
+    description: 'Set minimum power level to change room/space avatar.',
+    default: 50,
+  },
+  'm.room.name': {
+    parent: 'events',
+    name: 'Change name',
+    description: 'Set minimum power level to change room/space name.',
+    default: 50,
+  },
+  'm.room.topic': {
+    parent: 'events',
+    name: 'Change topic',
+    description: 'Set minimum power level to change room/space topic.',
+    default: 50,
+  },
+  state_default: {
+    name: 'Change settings',
+    description: 'Set minimum power level to change settings.',
+    default: 50,
+  },
+  'm.room.canonical_alias': {
+    parent: 'events',
+    name: 'Change published address',
+    description: 'Set minimum power level to publish and set main address.',
+    default: 50,
+  },
+  'm.room.power_levels': {
+    parent: 'events',
+    name: 'Change permissions',
+    description: 'Set minimum power level to change permissions.',
+    default: 50,
+  },
+  'm.room.encryption': {
+    parent: 'events',
+    name: 'Enable room encryption',
+    description: 'Set minimum power level to enable room encryption.',
+    default: 50,
+  },
+  'm.room.history_visibility': {
+    parent: 'events',
+    name: 'Change history visibility',
+    description: 'Set minimum power level to change room messages history visibility.',
+    default: 50,
+  },
+  'm.room.tombstone': {
+    parent: 'events',
+    name: 'Upgrade room',
+    description: 'Set minimum power level to upgrade room.',
+    default: 50,
+  },
+  'm.room.pinned_events': {
+    parent: 'events',
+    name: 'Pin messages',
+    description: 'Set minimum power level to pin messages in room.',
+    default: 50,
+  },
+  'm.room.server_acl': {
+    parent: 'events',
+    name: 'Change server ACLs',
+    description: 'Set minimum power level to change server ACLs.',
+    default: 50,
+  },
+  'im.vector.modular.widgets': {
+    parent: 'events',
+    name: 'Modify widgets',
+    description: 'Set minimum power level to modify room widgets.',
+    default: 50,
+  },
+};
+
+const roomPermsGroups = {
+  'General Permissions': ['users_default', 'events_default', 'redact', 'notifications'],
+  'Manage members permissions': ['invite', 'kick', 'ban'],
+  'Room profile permissions': ['m.room.avatar', 'm.room.name', 'm.room.topic'],
+  'Settings permissions': ['state_default', 'm.room.canonical_alias', 'm.room.power_levels', 'm.room.encryption', 'm.room.history_visibility'],
+  'Other permissions': ['m.room.tombstone', 'm.room.pinned_events', 'm.room.server_acl', 'im.vector.modular.widgets'],
+};
+
+const spacePermsGroups = {
+  'General Permissions': ['users_default', 'm.space.child'],
+  'Manage members permissions': ['invite', 'kick', 'ban'],
+  'Space profile permissions': ['m.room.avatar', 'm.room.name', 'm.room.topic'],
+  'Settings permissions': ['state_default', 'm.room.canonical_alias', 'm.room.power_levels'],
+};
+
+function RoomPermissions({ 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());
+
+  return (
+    <div className="room-permissions">
+      {
+        Object.keys(roomPermsGroups).map((groupKey) => {
+          const groupedPermKeys = roomPermsGroups[groupKey];
+          return (
+            <div className="room-permissions__card" key={groupKey}>
+              <MenuHeader>{groupKey}</MenuHeader>
+              {
+                groupedPermKeys.map((permKey) => {
+                  const permInfo = permissionsInfo[permKey];
+
+                  let powerLevel = 0;
+                  let permValue = permInfo.parent
+                    ? permissions[permInfo.parent][permKey]
+                    : permissions[permKey];
+
+                  if (!permValue) permValue = permInfo.default;
+
+                  if (typeof permValue === 'number') {
+                    powerLevel = permValue;
+                  } else if (permKey === 'notifications') {
+                    powerLevel = permValue.room || 50;
+                  }
+                  return (
+                    <SettingTile
+                      key={permKey}
+                      title={permInfo.name}
+                      content={<Text variant="b3">{permInfo.description}</Text>}
+                      options={(
+                        <Button
+                          iconSrc={canChangePermission ? ChevronBottomIC : null}
+                        >
+                          <Text variant="b2">
+                            {`${getPowerLabel(powerLevel) || 'Member'} - ${powerLevel}`}
+                          </Text>
+                        </Button>
+                      )}
+                    />
+                  );
+                })
+              }
+            </div>
+          );
+        })
+      }
+    </div>
+  );
+}
+
+RoomPermissions.propTypes = {
+  roomId: PropTypes.string.isRequired,
+};
+
+export default RoomPermissions;
diff --git a/src/app/molecules/room-permissions/RoomPermissions.scss b/src/app/molecules/room-permissions/RoomPermissions.scss
new file mode 100644 (file)
index 0000000..81b22ca
--- /dev/null
@@ -0,0 +1,11 @@
+.room-permissions {
+  & .setting-tile {
+    margin: 0 var(--sp-normal);
+    margin-top: var(--sp-tight);
+    padding-bottom: var(--sp-tight);
+    border-bottom: 1px solid var(--bg-surface-border);
+    &:last-child {
+      border-bottom: none;
+    }
+  }
+}
\ No newline at end of file
index 3b7a07c931b69dbf2a187aadb92294598f625797..73b722e57c9efea896ec6df452e327347ed64c28 100644 (file)
@@ -261,6 +261,7 @@ function ProfileViewer() {
   function renderProfile() {
     const member = room.getMember(userId) || mx.getUser(userId) || {};
     const avatarMxc = member.getMxcAvatarUrl?.() || member.avatarUrl;
+    const powerLevel = member.powerLevel || 0;
     const canChangeRole = room.currentState.maySendEvent('m.room.power_levels', mx.getUserId());
 
     return (
@@ -278,7 +279,9 @@ function ProfileViewer() {
           </div>
           <div className="profile-viewer__user__role">
             <Text variant="b3">Role</Text>
-            <Button iconSrc={canChangeRole ? ChevronBottomIC : null}>{getPowerLabel(member.powerLevel) || 'Member'}</Button>
+            <Button iconSrc={canChangeRole ? ChevronBottomIC : null}>
+              {`${getPowerLabel(powerLevel) || 'Member'} - ${powerLevel}`}
+            </Button>
           </div>
         </div>
         <SessionInfo userId={userId} />
index 40e1d1d4903bd2fe89efc91f7056beebeba6e60d..98f49bc010e255292ddf3122f9ec9ccf3bcae062 100644 (file)
@@ -19,12 +19,12 @@ import RoomVisibility from '../../molecules/room-visibility/RoomVisibility';
 import RoomAliases from '../../molecules/room-aliases/RoomAliases';
 import RoomHistoryVisibility from '../../molecules/room-history-visibility/RoomHistoryVisibility';
 import RoomEncryption from '../../molecules/room-encryption/RoomEncryption';
+import RoomPermissions from '../../molecules/room-permissions/RoomPermissions';
 
 import SettingsIC from '../../../../public/res/ic/outlined/settings.svg';
 import SearchIC from '../../../../public/res/ic/outlined/search.svg';
 import ShieldUserIC from '../../../../public/res/ic/outlined/shield-user.svg';
 import LockIC from '../../../../public/res/ic/outlined/lock.svg';
-import InfoIC from '../../../../public/res/ic/outlined/info.svg';
 import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
 import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
 
@@ -35,7 +35,6 @@ const tabText = {
   SEARCH: 'Search',
   PERMISSIONS: 'Permissions',
   SECURITY: 'Security',
-  ADVANCED: 'Advanced',
 };
 
 const tabItems = [{
@@ -54,10 +53,6 @@ const tabItems = [{
   iconSrc: LockIC,
   text: tabText.SECURITY,
   disabled: false,
-}, {
-  iconSrc: InfoIC,
-  text: tabText.ADVANCED,
-  disabled: false,
 }];
 
 function GeneralSettings({ roomId }) {
@@ -156,6 +151,7 @@ function RoomSettings({ roomId }) {
           />
           <div className="room-settings__cards-wrapper">
             {selectedTab.text === tabText.GENERAL && <GeneralSettings roomId={roomId} />}
+            {selectedTab.text === tabText.PERMISSIONS && <RoomPermissions roomId={roomId} />}
             {selectedTab.text === tabText.SECURITY && <SecuritySettings roomId={roomId} />}
           </div>
         </div>
index 480e4c8032eb7171e5b07138410f17778b988de3..617024a9cccf954ae3a3817efce7e1863d3e4e0f 100644 (file)
     padding: 0 var(--sp-normal);
     @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight));
   }
+}
 
-  &__card {
-    margin: var(--sp-normal) 0;
-    background-color: var(--bg-surface);
-    border-radius: var(--bo-radius);
-    box-shadow: var(--bs-surface-border);
-    overflow: hidden;
+.room-settings__card {
+  margin: var(--sp-normal) 0;
+  background-color: var(--bg-surface);
+  border-radius: var(--bo-radius);
+  box-shadow: var(--bs-surface-border);
+  overflow: hidden;
 
-    & > .context-menu__header:first-child {
-      margin-top: 2px;
-    }
+  & > .context-menu__header:first-child {
+    margin-top: 2px;
   }
+}
+
+.room-settings .room-permissions__card {
+  @extend .room-settings__card;
 }
\ No newline at end of file