diff --git a/src/components/views/room_settings/RoomProfileSettings.tsx b/src/components/views/room_settings/RoomProfileSettings.tsx index 6533028e8c..8cc7a620f8 100644 --- a/src/components/views/room_settings/RoomProfileSettings.tsx +++ b/src/components/views/room_settings/RoomProfileSettings.tsx @@ -35,7 +35,7 @@ interface IState { avatarFile: File; originalTopic: string; topic: string; - enableProfileSave: boolean; + profileFieldsTouched: Record; canSetName: boolean; canSetTopic: boolean; canSetAvatar: boolean; @@ -71,7 +71,7 @@ export default class RoomProfileSettings extends React.Component avatarFile: null, originalTopic: topic, topic: topic, - enableProfileSave: false, + profileFieldsTouched: {}, canSetName: room.currentState.maySendStateEvent('m.room.name', client.getUserId()), canSetTopic: room.currentState.maySendStateEvent('m.room.topic', client.getUserId()), canSetAvatar: room.currentState.maySendStateEvent('m.room.avatar', client.getUserId()), @@ -88,17 +88,24 @@ export default class RoomProfileSettings extends React.Component this.setState({ avatarUrl: null, avatarFile: null, - enableProfileSave: true, + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + avatar: true, + }, }); }; + private isSaveEnabled = () => { + return Boolean(Object.values(this.state.profileFieldsTouched).length); + }; + private cancelProfileChanges = async (e: React.MouseEvent): Promise => { e.stopPropagation(); e.preventDefault(); - if (!this.state.enableProfileSave) return; + if (!this.isSaveEnabled()) return; this.setState({ - enableProfileSave: false, + profileFieldsTouched: {}, displayName: this.state.originalDisplayName, topic: this.state.originalTopic, avatarUrl: this.state.originalAvatarUrl, @@ -110,8 +117,8 @@ export default class RoomProfileSettings extends React.Component e.stopPropagation(); e.preventDefault(); - if (!this.state.enableProfileSave) return; - this.setState({ enableProfileSave: false }); + if (!this.isSaveEnabled()) return; + this.setState({ profileFieldsTouched: {} }); const client = MatrixClientPeg.get(); @@ -156,18 +163,38 @@ export default class RoomProfileSettings extends React.Component private onDisplayNameChanged = (e: React.ChangeEvent): void => { this.setState({ displayName: e.target.value }); if (this.state.originalDisplayName === e.target.value) { - this.setState({ enableProfileSave: false }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + name: false, + }, + }); } else { - this.setState({ enableProfileSave: true }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + name: true, + }, + }); } }; private onTopicChanged = (e: React.ChangeEvent): void => { this.setState({ topic: e.target.value }); if (this.state.originalTopic === e.target.value) { - this.setState({ enableProfileSave: false }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + topic: false, + }, + }); } else { - this.setState({ enableProfileSave: true }); + this.setState({ + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + topic: true, + }, + }); } }; @@ -176,7 +203,10 @@ export default class RoomProfileSettings extends React.Component this.setState({ avatarUrl: this.state.originalAvatarUrl, avatarFile: null, - enableProfileSave: false, + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + avatar: false, + }, }); return; } @@ -187,7 +217,10 @@ export default class RoomProfileSettings extends React.Component this.setState({ avatarUrl: String(ev.target.result), avatarFile: file, - enableProfileSave: true, + profileFieldsTouched: { + ...this.state.profileFieldsTouched, + avatar: true, + }, }); }; reader.readAsDataURL(file); @@ -205,14 +238,14 @@ export default class RoomProfileSettings extends React.Component { _t("Cancel") } { _t("Save") }