Fix room settings roles tab getting confused if power level change fails (#31768)
* Fix room settings roles tab getting confused if power level change fails Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import Field from "./Field";
|
|||||||
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
||||||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||||
import { objectHasDiff } from "../../../utils/objects";
|
import { objectHasDiff } from "../../../utils/objects";
|
||||||
|
import { arrayHasDiff } from "../../../utils/arrays.ts";
|
||||||
|
|
||||||
const CUSTOM_VALUE = "SELECT_VALUE_CUSTOM";
|
const CUSTOM_VALUE = "SELECT_VALUE_CUSTOM";
|
||||||
|
|
||||||
@@ -38,7 +39,6 @@ interface Props<K extends undefined | string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
levelRoleMap: Partial<Record<number | "undefined", string>>;
|
|
||||||
// List of power levels to show in the drop-down
|
// List of power levels to show in the drop-down
|
||||||
options: number[];
|
options: number[];
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ interface IState {
|
|||||||
custom?: boolean;
|
custom?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class PowerSelector<K extends undefined | string> extends React.Component<Props<K>, IState> {
|
export default class PowerSelector<K extends undefined | string> extends React.PureComponent<Props<K>, IState> {
|
||||||
public static defaultProps: Partial<Props<any>> = {
|
public static defaultProps: Partial<Props<any>> = {
|
||||||
maxValue: Infinity,
|
maxValue: Infinity,
|
||||||
usersDefault: 0,
|
usersDefault: 0,
|
||||||
@@ -58,7 +58,6 @@ export default class PowerSelector<K extends undefined | string> extends React.C
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
levelRoleMap: {},
|
|
||||||
// List of power levels to show in the drop-down
|
// List of power levels to show in the drop-down
|
||||||
options: [],
|
options: [],
|
||||||
|
|
||||||
@@ -85,6 +84,7 @@ export default class PowerSelector<K extends undefined | string> extends React.C
|
|||||||
private initStateFromProps(): void {
|
private initStateFromProps(): void {
|
||||||
// This needs to be done now because levelRoleMap has translated strings
|
// This needs to be done now because levelRoleMap has translated strings
|
||||||
const levelRoleMap = Roles.levelRoleMap(this.props.usersDefault);
|
const levelRoleMap = Roles.levelRoleMap(this.props.usersDefault);
|
||||||
|
|
||||||
const options = Object.keys(levelRoleMap)
|
const options = Object.keys(levelRoleMap)
|
||||||
.filter((level) => {
|
.filter((level) => {
|
||||||
return (
|
return (
|
||||||
@@ -93,11 +93,13 @@ export default class PowerSelector<K extends undefined | string> extends React.C
|
|||||||
})
|
})
|
||||||
.map((level) => parseInt(level));
|
.map((level) => parseInt(level));
|
||||||
|
|
||||||
|
if (arrayHasDiff(options, this.state.options)) {
|
||||||
|
this.setState({ options });
|
||||||
|
}
|
||||||
|
|
||||||
const isCustom = levelRoleMap[this.props.value] === undefined;
|
const isCustom = levelRoleMap[this.props.value] === undefined;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
levelRoleMap,
|
|
||||||
options,
|
|
||||||
custom: isCustom,
|
custom: isCustom,
|
||||||
customValue: this.props.value,
|
customValue: this.props.value,
|
||||||
selectValue: isCustom ? CUSTOM_VALUE : this.props.value,
|
selectValue: isCustom ? CUSTOM_VALUE : this.props.value,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ interface PowerLevelSelectorProps {
|
|||||||
*/
|
*/
|
||||||
canChangeLevels: boolean;
|
canChangeLevels: boolean;
|
||||||
/**
|
/**
|
||||||
* The current user power level
|
* The current user's own power level
|
||||||
*/
|
*/
|
||||||
currentUserLevel: number;
|
currentUserLevel: number;
|
||||||
/**
|
/**
|
||||||
@@ -105,6 +105,7 @@ export function PowerLevelSelector({
|
|||||||
disabled={!canChange}
|
disabled={!canChange}
|
||||||
label={userId}
|
label={userId}
|
||||||
key={userId}
|
key={userId}
|
||||||
|
maxValue={currentUserLevel}
|
||||||
onChange={async (value) => {
|
onChange={async (value) => {
|
||||||
const userLevelsTmp = Object.assign({}, userLevels);
|
const userLevelsTmp = Object.assign({}, userLevels);
|
||||||
userLevelsTmp[userId] = value;
|
userLevelsTmp[userId] = value;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import { SettingsSection } from "../../shared/SettingsSection";
|
|||||||
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
|
||||||
import { PowerLevelSelector } from "../../PowerLevelSelector";
|
import { PowerLevelSelector } from "../../PowerLevelSelector";
|
||||||
import { ElementCallEventType, ElementCallMemberEventType } from "../../../../../call-types";
|
import { ElementCallEventType, ElementCallMemberEventType } from "../../../../../call-types";
|
||||||
|
import { objectClone } from "../../../../../utils/objects.ts";
|
||||||
|
|
||||||
interface IEventShowOpts {
|
interface IEventShowOpts {
|
||||||
isState?: boolean;
|
isState?: boolean;
|
||||||
@@ -221,12 +222,9 @@ export default class RolesRoomSettingsTab extends React.Component<IProps, RolesR
|
|||||||
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
|
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
|
||||||
let plContent = plEvent?.getContent<RoomPowerLevelsEventContent>() ?? {};
|
let plContent = plEvent?.getContent<RoomPowerLevelsEventContent>() ?? {};
|
||||||
|
|
||||||
// Clone the power levels just in case
|
// Clone the power levels so we can modify it without clobbering the js-sdk
|
||||||
plContent = Object.assign({}, plContent);
|
plContent = objectClone({ users: {}, ...plContent });
|
||||||
|
plContent["users"]![powerLevelKey] = value;
|
||||||
// powerLevelKey should be a user ID
|
|
||||||
if (!plContent["users"]) plContent["users"] = {};
|
|
||||||
plContent["users"][powerLevelKey] = value;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.sendStateEvent(this.props.room.roomId, EventType.RoomPowerLevels, plContent);
|
await client.sendStateEvent(this.props.room.roomId, EventType.RoomPowerLevels, plContent);
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ describe("RolesRoomSettingsTab", () => {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
mocked(room.currentState.mayClientSendStateEvent).mockReturnValue(true);
|
mocked(room.currentState.mayClientSendStateEvent).mockReturnValue(true);
|
||||||
|
mocked(room.getMember).mockReturnValue({ powerLevel: 100 } as any);
|
||||||
const { container } = await renderTab();
|
const { container } = await renderTab();
|
||||||
|
|
||||||
const selector = container.querySelector(`[placeholder="${cli.getUserId()}"]`)!;
|
const selector = container.querySelector(`[placeholder="${cli.getUserId()}"]`)!;
|
||||||
|
|||||||
Reference in New Issue
Block a user