diff --git a/res/css/_components.scss b/res/css/_components.scss index 4884b0a036..002f95119d 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -110,7 +110,6 @@ @import "./views/elements/_EventListSummary.scss"; @import "./views/elements/_Field.scss"; @import "./views/elements/_FormButton.scss"; -@import "./views/elements/_IconButton.scss"; @import "./views/elements/_ImageView.scss"; @import "./views/elements/_InfoTooltip.scss"; @import "./views/elements/_InlineSpinner.scss"; diff --git a/res/css/views/elements/_IconButton.scss b/res/css/views/elements/_IconButton.scss deleted file mode 100644 index d8ebbeb65e..0000000000 --- a/res/css/views/elements/_IconButton.scss +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2019 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.mx_IconButton { - width: 32px; - height: 32px; - border-radius: 100%; - background-color: $accent-bg-color; - // don't shrink or grow if in a flex container - flex: 0 0 auto; - - &.mx_AccessibleButton_disabled { - background-color: none; - - &::before { - background-color: lightgrey; - } - } - - &:hover { - opacity: 90%; - } - - &::before { - content: ""; - display: block; - width: 100%; - height: 100%; - mask-repeat: no-repeat; - mask-position: center; - mask-size: 55%; - background-color: $accent-color; - } - - &.mx_IconButton_icon_check::before { - mask-image: url('$(res)/img/feather-customised/check.svg'); - } - - &.mx_IconButton_icon_edit::before { - mask-image: url('$(res)/img/feather-customised/edit.svg'); - } -} diff --git a/res/css/views/right_panel/_UserInfo.scss b/res/css/views/right_panel/_UserInfo.scss index f20c9b7868..87420ae4e7 100644 --- a/res/css/views/right_panel/_UserInfo.scss +++ b/res/css/views/right_panel/_UserInfo.scss @@ -173,26 +173,12 @@ limitations under the License. margin: 6px 0; - .mx_IconButton, .mx_Spinner { - margin-left: 20px; - width: 16px; - height: 16px; - - &::before { - mask-size: 80%; - } - } - .mx_UserInfo_roleDescription { display: flex; justify-content: center; align-items: center; // try to make it the same height as the dropdown margin: 11px 0 12px 0; - - .mx_IconButton { - margin-left: 6px; - } } .mx_Field { diff --git a/src/components/views/elements/IconButton.js b/src/components/views/elements/IconButton.js deleted file mode 100644 index ef7b4a8399..0000000000 --- a/src/components/views/elements/IconButton.js +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2019 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import PropTypes from 'prop-types'; -import AccessibleButton from "./AccessibleButton"; - -export default function IconButton(props) { - const {icon, className, ...restProps} = props; - - let newClassName = (className || "") + " mx_IconButton"; - newClassName = newClassName + " mx_IconButton_icon_" + icon; - - const allProps = Object.assign({}, restProps, {className: newClassName}); - - return React.createElement(AccessibleButton, allProps); -} - -IconButton.propTypes = Object.assign({ - icon: PropTypes.string, -}, AccessibleButton.propTypes); diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index f8be6327bf..66b689ddb9 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -51,7 +51,6 @@ import BaseCard from "./BaseCard"; import {E2EStatus} from "../../../utils/ShieldUtils"; import ImageView from "../elements/ImageView"; import Spinner from "../elements/Spinner"; -import IconButton from "../elements/IconButton"; import PowerSelector from "../elements/PowerSelector"; import MemberAvatar from "../avatars/MemberAvatar"; import PresenceLabel from "../rooms/PresenceLabel"; @@ -1028,24 +1027,15 @@ const PowerLevelSection: React.FC<{ roomPermissions: IRoomPermissions; powerLevels: IPowerLevelsContent; }> = ({user, room, roomPermissions, powerLevels}) => { - const [isEditing, setEditing] = useState(false); - if (isEditing) { - return ( setEditing(false)} />); + if (roomPermissions.canEdit) { + return (); } else { const powerLevelUsersDefault = powerLevels.users_default || 0; const powerLevel = parseInt(user.powerLevel, 10); - const modifyButton = roomPermissions.canEdit ? - ( setEditing(true)} />) : null; const role = textualPowerLevel(powerLevel, powerLevelUsersDefault); - const label = _t("%(role)s in %(roomName)s", - {role, roomName: room.name}, - {strong: label => {label}}, - ); return (
-
{label}{modifyButton}
+
{role}
); } @@ -1055,20 +1045,15 @@ const PowerLevelEditor: React.FC<{ user: User; room: Room; roomPermissions: IRoomPermissions; - onFinished(): void; -}> = ({user, room, roomPermissions, onFinished}) => { +}> = ({user, room, roomPermissions}) => { const cli = useContext(MatrixClientContext); - const [isUpdating, setIsUpdating] = useState(false); const [selectedPowerLevel, setSelectedPowerLevel] = useState(parseInt(user.powerLevel, 10)); - const [isDirty, setIsDirty] = useState(false); - const onPowerChange = useCallback((powerLevel) => { - setIsDirty(true); - setSelectedPowerLevel(parseInt(powerLevel, 10)); - }, [setSelectedPowerLevel, setIsDirty]); + const onPowerChange = useCallback(async (powerLevelStr: string) => { + const powerLevel = parseInt(powerLevelStr, 10); + setSelectedPowerLevel(powerLevel); - const changePowerLevel = useCallback(async () => { - const _applyPowerChange = (roomId, target, powerLevel, powerLevelEvent) => { + const applyPowerChange = (roomId, target, powerLevel, powerLevelEvent) => { return cli.setPowerLevel(roomId, target, parseInt(powerLevel), powerLevelEvent).then( function() { // NO-OP; rely on the m.room.member event coming down else we could @@ -1084,64 +1069,42 @@ const PowerLevelEditor: React.FC<{ ); }; - try { - if (!isDirty) { - return; - } + const roomId = user.roomId; + const target = user.userId; - setIsUpdating(true); + const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", ""); + if (!powerLevelEvent) return; - const powerLevel = selectedPowerLevel; + const myUserId = cli.getUserId(); + const myPower = powerLevelEvent.getContent().users[myUserId]; + if (myPower && parseInt(myPower) === powerLevel) { + const {finished} = Modal.createTrackedDialog('Promote to PL100 Warning', '', QuestionDialog, { + title: _t("Warning!"), + description: +
+ { _t("You will not be able to undo this change as you are promoting the user " + + "to have the same power level as yourself.") }
+ { _t("Are you sure?") } +
, + button: _t("Continue"), + }); - const roomId = user.roomId; - const target = user.userId; - - const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", ""); - if (!powerLevelEvent) return; - - if (!powerLevelEvent.getContent().users) { - _applyPowerChange(roomId, target, powerLevel, powerLevelEvent); - return; - } - - const myUserId = cli.getUserId(); + const [confirmed] = await finished; + if (!confirmed) return; + } else if (myUserId === target) { // If we are changing our own PL it can only ever be decreasing, which we cannot reverse. - if (myUserId === target) { - try { - if (!(await warnSelfDemote())) return; - } catch (e) { - console.error("Failed to warn about self demotion: ", e); - } - await _applyPowerChange(roomId, target, powerLevel, powerLevelEvent); - return; + try { + if (!(await warnSelfDemote())) return; + } catch (e) { + console.error("Failed to warn about self demotion: ", e); } - - const myPower = powerLevelEvent.getContent().users[myUserId]; - if (parseInt(myPower) === powerLevel) { - const {finished} = Modal.createTrackedDialog('Promote to PL100 Warning', '', QuestionDialog, { - title: _t("Warning!"), - description: -
- { _t("You will not be able to undo this change as you are promoting the user " + - "to have the same power level as yourself.") }
- { _t("Are you sure?") } -
, - button: _t("Continue"), - }); - - const [confirmed] = await finished; - if (!confirmed) return; - } - await _applyPowerChange(roomId, target, powerLevel, powerLevelEvent); - } finally { - onFinished(); } - }, [user.roomId, user.userId, cli, selectedPowerLevel, isDirty, setIsUpdating, onFinished, room]); + + await applyPowerChange(roomId, target, powerLevel, powerLevelEvent); + }, [user.roomId, user.userId, cli, room]); const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", ""); const powerLevelUsersDefault = powerLevelEvent ? powerLevelEvent.getContent().users_default : 0; - const buttonOrSpinner = isUpdating ? : - ; return (
@@ -1151,9 +1114,7 @@ const PowerLevelEditor: React.FC<{ maxValue={roomPermissions.modifyLevelMax} usersDefault={powerLevelUsersDefault} onChange={onPowerChange} - disabled={isUpdating} /> - {buttonOrSpinner}
); }; @@ -1343,13 +1304,17 @@ const BasicUserInfo: React.FC<{ } let memberDetails; - if (room && member.roomId) { - memberDetails = ; + // hide the Roles section for DMs as it doesn't make sense there + if (room && member.roomId && !DMRoomMap.shared().getUserIdForRoomId(member.roomId)) { + memberDetails =
+

{ _t("Role") }

+ +
; } // only display the devices list if our client supports E2E @@ -1419,12 +1384,7 @@ const BasicUserInfo: React.FC<{ ); return - { memberDetails && -
-
- { memberDetails } -
-
} + { memberDetails } { securitySection } %(role)s in %(roomName)s": "%(role)s in %(roomName)s", "Failed to change power level": "Failed to change power level", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.", "Are you sure?": "Are you sure?", @@ -1606,6 +1605,7 @@ "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?", "Deactivate user": "Deactivate user", "Failed to deactivate user": "Failed to deactivate user", + "Role": "Role", "This client does not support end-to-end encryption.": "This client does not support end-to-end encryption.", "Security": "Security", "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.",