diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index 6696f3cc0fc..23feb4cf30e 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -116,7 +116,6 @@ const FilePanel = React.createClass({ timelineSet={this.state.timelineSet} showUrlPreview = {false} tileShape="file_grid" - opacity={this.props.opacity} empty={_t('There are no visible files in this room')} /> ); diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 52680ea5fa2..314a36e486c 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -482,8 +482,8 @@ export default React.createClass({ profileForm: Object.assign({}, this.state.summary.profile), }); dis.dispatch({ - action: 'ui_opacity', - sideOpacity: 0.3, + action: 'panel_disable', + sideDisabled: true, }); }, @@ -492,7 +492,7 @@ export default React.createClass({ editing: false, profileForm: null, }); - dis.dispatch({action: 'ui_opacity'}); + dis.dispatch({action: 'panel_disable'}); }, _onNameChange: function(value) { @@ -549,7 +549,7 @@ export default React.createClass({ editing: false, summary: null, }); - dis.dispatch({action: 'ui_opacity'}); + dis.dispatch({action: 'panel_disable'}); this._initGroupStore(this.props.groupId); }).catch((e) => { this.setState({ @@ -787,8 +787,8 @@ export default React.createClass({ ; } else if (group.myMembership === 'join' && this.state.editing) { const leaveButtonTooltip = this.state.isUserPrivileged ? - _t("You are a member of this community") : - _t("You are an administrator of this community"); + _t("You are an administrator of this community") : + _t("You are a member of this community"); const leaveButtonClasses = classnames({ "mx_RoomHeader_textButton": true, "mx_GroupView_textButton": true, diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 7e6fc05599a..5d1d47c5b2b 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -240,11 +240,13 @@ export default React.createClass({ oobData={this.props.roomOobData} eventPixelOffset={this.props.initialEventPixelOffset} key={this.props.currentRoomId || 'roomview'} - opacity={this.props.middleOpacity} + disabled={this.props.middleDisabled} collapsedRhs={this.props.collapseRhs} ConferenceHandler={this.props.ConferenceHandler} />; - if (!this.props.collapseRhs) right_panel = ; + if (!this.props.collapseRhs) { + right_panel = ; + } break; case PageTypes.UserSettings: @@ -254,7 +256,7 @@ export default React.createClass({ referralBaseUrl={this.props.config.referralBaseUrl} teamToken={this.props.teamToken} />; - if (!this.props.collapseRhs) right_panel = ; + if (!this.props.collapseRhs) right_panel = ; break; case PageTypes.MyGroups: @@ -266,7 +268,7 @@ export default React.createClass({ onRoomCreated={this.props.onRoomCreated} collapsedRhs={this.props.collapseRhs} />; - if (!this.props.collapseRhs) right_panel = ; + if (!this.props.collapseRhs) right_panel = ; break; case PageTypes.RoomDirectory: @@ -294,14 +296,14 @@ export default React.createClass({ case PageTypes.UserView: page_element = null; // deliberately null for now - right_panel = ; + right_panel = ; break; case PageTypes.GroupView: page_element = ; - if (!this.props.collapseRhs) right_panel = ; + if (!this.props.collapseRhs) right_panel = ; break; } @@ -334,7 +336,7 @@ export default React.createClass({
{ page_element } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 3fa628b8a3c..e679276a08c 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -145,9 +145,9 @@ module.exports = React.createClass({ collapseLhs: false, collapseRhs: false, - leftOpacity: 1.0, - middleOpacity: 1.0, - rightOpacity: 1.0, + leftDisabled: false, + middleDisabled: false, + rightDisabled: false, version: null, newVersion: null, @@ -534,12 +534,11 @@ module.exports = React.createClass({ collapseRhs: false, }); break; - case 'ui_opacity': { - const sideDefault = payload.sideOpacity >= 0.0 ? payload.sideOpacity : 1.0; + case 'panel_disable': { this.setState({ - leftOpacity: payload.leftOpacity >= 0.0 ? payload.leftOpacity : sideDefault, - middleOpacity: payload.middleOpacity || 1.0, - rightOpacity: payload.rightOpacity >= 0.0 ? payload.rightOpacity : sideDefault, + leftDisabled: payload.leftDisabled || payload.sideDisabled || false, + middleDisabled: payload.middleDisabled || false, + rightDisabled: payload.rightDisabled || payload.sideDisabled || false, }); break; } case 'set_theme': diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 5ce36b4b826..2331e096c03 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import ReactDOM from 'react-dom'; +import classNames from 'classnames'; import UserSettingsStore from '../../UserSettingsStore'; import shouldHideEvent from '../../shouldHideEvent'; import dis from "../../dispatcher"; @@ -78,9 +79,6 @@ module.exports = React.createClass({ // callback which is called when more content is needed. onFillRequest: React.PropTypes.func, - // opacity for dynamic UI fading effects - opacity: React.PropTypes.number, - // className for the panel className: React.PropTypes.string.isRequired, @@ -353,7 +351,7 @@ module.exports = React.createClass({ } if (!isMembershipChange(collapsedMxEv) || - this._wantsDateSeparator(this.props.events[i], collapsedMxEv.getDate())) { + this._wantsDateSeparator(mxEv, collapsedMxEv.getDate())) { break; } @@ -376,9 +374,7 @@ module.exports = React.createClass({ // of MemberEventListSummary, render each member event as if the previous // one was itself. This way, the timestamp of the previous event === the // timestamp of the current event, and no DateSeperator is inserted. - const ret = this._getTilesForEvent(e, e, e === lastShownEvent); - prevEvent = e; - return ret; + return this._getTilesForEvent(e, e, e === lastShownEvent); }).reduce((a, b) => a.concat(b)); if (eventTiles.length === 0) { @@ -397,6 +393,7 @@ module.exports = React.createClass({ ret.push(this._getReadMarkerTile(visible)); } + prevEvent = mxEv; continue; } @@ -649,12 +646,13 @@ module.exports = React.createClass({ } const style = this.props.hidden ? { display: 'none' } : {}; - style.opacity = this.props.opacity; - let className = this.props.className + " mx_fadable"; - if (this.props.alwaysShowTimestamps) { - className += " mx_MessagePanel_alwaysShowTimestamps"; - } + const className = classNames( + this.props.className, + { + "mx_MessagePanel_alwaysShowTimestamps": this.props.alwaysShowTimestamps, + }, + ); return ( diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 83ca9872766..9b6dbb4c273 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -281,7 +281,7 @@ module.exports = React.createClass({ this.setState({ isPeeking: false, }); - + // This won't necessarily be a MatrixError, but we duck-type // here and say if it's got an 'errcode' key with the right value, // it means we can't peek. @@ -1697,7 +1697,7 @@ module.exports = React.createClass({ onResize={this.onChildResize} uploadFile={this.uploadFile} callState={this.state.callState} - opacity={this.props.opacity} + disabled={this.props.disabled} showApps={this.state.showApps} />; } @@ -1758,7 +1758,6 @@ module.exports = React.createClass({ className="mx_RoomView_messagePanel mx_RoomView_searchResultsPanel" onFillRequest={this.onSearchResultsFillRequest} onResize={this.onSearchResultsResize} - style={{ opacity: this.props.opacity }} >
  • { this.getSearchResultTiles() } @@ -1789,7 +1788,6 @@ module.exports = React.createClass({ onScroll={this.onMessageListScroll} onReadMarkerUpdated={this._updateTopUnreadMessagesBar} showUrlPreview = {this.state.showUrlPreview} - opacity={this.props.opacity} className="mx_RoomView_messagePanel" />); @@ -1797,7 +1795,7 @@ module.exports = React.createClass({ if (this.state.showTopUnreadMessagesBar) { const TopUnreadMessagesBar = sdk.getComponent('rooms.TopUnreadMessagesBar'); topUnreadMessagesBar = ( -
    +
    ); } - let statusBarAreaClass = "mx_RoomView_statusArea mx_fadable"; - if (isStatusAreaExpanded) { - statusBarAreaClass += " mx_RoomView_statusArea_expanded"; - } + const statusBarAreaClass = classNames( + "mx_RoomView_statusArea", + { + "mx_RoomView_statusArea_expanded": isStatusAreaExpanded, + }, + ); + + const fadableSectionClasses = classNames( + "mx_RoomView_body", "mx_fadable", + { + "mx_fadable_faded": this.props.disabled, + }, + ); return (
    @@ -1827,16 +1834,18 @@ module.exports = React.createClass({ onLeaveClick={(myMember && myMember.membership === "join") ? this.onLeaveClick : null} /> { auxPanel } - { topUnreadMessagesBar } - { messagePanel } - { searchResultsPanel } -
    -
    -
    - { statusBar } +
    + { topUnreadMessagesBar } + { messagePanel } + { searchResultsPanel } +
    +
    +
    + { statusBar } +
    + { messageComposer }
    - { messageComposer }
    ); }, diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index e3b3b66f97c..2bf8a08b98a 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -89,9 +89,6 @@ var TimelinePanel = React.createClass({ // callback which is called when the read-up-to mark is updated. onReadMarkerUpdated: React.PropTypes.func, - // opacity for dynamic UI fading effects - opacity: React.PropTypes.number, - // maximum number of events to show in a timeline timelineCap: React.PropTypes.number, @@ -1157,7 +1154,6 @@ var TimelinePanel = React.createClass({ onScroll={this.onMessageListScroll} onFillRequest={this.onMessageListFillRequest} onUnfillRequest={this.onMessageListUnfillRequest} - opacity={this.props.opacity} isTwelveHour={this.state.isTwelveHour} alwaysShowTimestamps={this.state.alwaysShowTimestamps} className={this.props.className} diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index b69bea92827..7704cce0c7c 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -271,9 +271,9 @@ module.exports = React.createClass({ MatrixClientPeg.get().on("RoomMember.membership", this._onInviteStateChange); dis.dispatch({ - action: 'ui_opacity', - sideOpacity: 0.3, - middleOpacity: 0.3, + action: 'panel_disable', + sideDisabled: true, + middleDisabled: true, }); this._refreshFromServer(); @@ -311,9 +311,9 @@ module.exports = React.createClass({ componentWillUnmount: function() { this._unmounted = true; dis.dispatch({ - action: 'ui_opacity', - sideOpacity: 1.0, - middleOpacity: 1.0, + action: 'panel_disable', + sideDisabled: false, + middleDisabled: false, }); dis.unregister(this.dispatcherRef); const cli = MatrixClientPeg.get(); diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index 8c6f033bdcd..5796e60cc99 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -272,20 +272,27 @@ module.exports = React.createClass({ const topicEvent = room.currentState.getStateEvents('m.room.topic', ''); const name = nameEvent ? nameEvent.getContent().name : ''; const canonicalAlias = room.getCanonicalAlias(); + const aliasEvents = room.currentState.getStateEvents('m.room.aliases'); + const aliases = aliasEvents.map((ev) => ev.getContent().aliases).reduce((a, b) => { + return a.concat(b); + }, []); const topic = topicEvent ? topicEvent.getContent().topic : ''; const nameMatch = (name || '').toLowerCase().includes(lowerCaseQuery); - const aliasMatch = (canonicalAlias || '').toLowerCase().includes(lowerCaseQuery); + const aliasMatch = aliases.some((alias) => + (alias || '').toLowerCase().includes(lowerCaseQuery), + ); const topicMatch = (topic || '').toLowerCase().includes(lowerCaseQuery); if (!(nameMatch || topicMatch || aliasMatch)) { return; } const avatarEvent = room.currentState.getStateEvents('m.room.avatar', ''); const avatarUrl = avatarEvent ? avatarEvent.getContent().url : undefined; + results.push({ room_id: room.roomId, avatar_url: avatarUrl, - name: name || canonicalAlias, + name: name || canonicalAlias || aliases[0] || _t('Unnamed Room'), }); }); this._processResults(results, query); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 3e343e098c3..0070af1fb29 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -172,18 +172,29 @@ export default React.createClass({ */ _onDeleteClick: function() { if (this._canUserModify()) { - console.log("Delete widget %s", this.props.id); - this.setState({deleting: true}); - MatrixClientPeg.get().sendStateEvent( - this.props.room.roomId, - 'im.vector.modular.widgets', - {}, // empty content - this.props.id, - ).then(() => { - console.log('Deleted widget'); - }, (e) => { - console.error('Failed to delete widget', e); - this.setState({deleting: false}); + // Show delete confirmation dialog + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Delete Widget', '', QuestionDialog, { + title: _t("Delete Widget"), + description: _t( + "Deleting a widget removes it for all users in this room." + + " Are you sure you want to delete this widget?"), + button: _t("Delete widget"), + onFinished: (confirmed) => { + if (!confirmed) { + return; + } + this.setState({deleting: true}); + MatrixClientPeg.get().sendStateEvent( + this.props.room.roomId, + 'im.vector.modular.widgets', + {}, // empty content + this.props.id, + ).catch((e) => { + console.error('Failed to delete widget', e); + this.setState({deleting: false}); + }); + }, }); } else { console.log("Revoke widget permissions - %s", this.props.id); @@ -305,7 +316,7 @@ export default React.createClass({ let deleteIcon = 'img/cancel.svg'; let deleteClasses = 'mx_filterFlipColor mx_AppTileMenuBarWidget'; if(this._canUserModify()) { - deleteIcon = 'img/cancel-red.svg'; + deleteIcon = 'img/icon-delete-pink.svg'; deleteClasses += ' mx_AppTileMenuBarWidgetDelete'; } diff --git a/src/components/views/elements/EditableItemList.js b/src/components/views/elements/EditableItemList.js index 35e207daef5..05ae6255150 100644 --- a/src/components/views/elements/EditableItemList.js +++ b/src/components/views/elements/EditableItemList.js @@ -84,7 +84,9 @@ module.exports = React.createClass({ onNewItemChanged: PropTypes.func, onItemAdded: PropTypes.func, onItemEdited: PropTypes.func, - onItemRemoved: PropTypes. func, + onItemRemoved: PropTypes.func, + + canEdit: PropTypes.bool, }, getDefaultProps: function() { @@ -136,14 +138,16 @@ module.exports = React.createClass({ { label }
    { editableItems } - + { this.props.canEdit ? + :
    + }
    ); }, }); diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index c64e876dbe2..cb897c9daf7 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -262,6 +262,7 @@ module.exports = React.createClass({ items={this.state.domainToAliases[localDomain] || []} newItem={this.state.newAlias} onNewItemChanged={this.onNewAliasChanged} + canEdit={this.props.canSetAliases} onItemAdded={this.onLocalAliasAdded} onItemEdited={this.onLocalAliasChanged} onItemRemoved={this.onLocalAliasDeleted} diff --git a/src/components/views/room_settings/RelatedGroupSettings.js b/src/components/views/room_settings/RelatedGroupSettings.js index 7227a951d7e..0a2dc3341cb 100644 --- a/src/components/views/room_settings/RelatedGroupSettings.js +++ b/src/components/views/room_settings/RelatedGroupSettings.js @@ -27,7 +27,7 @@ module.exports = React.createClass({ propTypes: { roomId: React.PropTypes.string.isRequired, - canSetRelatedRooms: React.PropTypes.bool.isRequired, + canSetRelatedGroups: React.PropTypes.bool.isRequired, relatedGroupsEvent: React.PropTypes.instanceOf(MatrixEvent), }, @@ -37,7 +37,7 @@ module.exports = React.createClass({ getDefaultProps: function() { return { - canSetRelatedRooms: false, + canSetRelatedGroups: false, }; }, @@ -110,6 +110,7 @@ module.exports = React.createClass({ items={this.state.newGroupsList} className={"mx_RelatedGroupSettings"} newItem={this.state.newGroupId} + canEdit={this.props.canSetRelatedGroups} onNewItemChanged={this.onNewGroupChanged} onItemAdded={this.onGroupAdded} onItemEdited={this.onGroupEdited} diff --git a/src/components/views/rooms/ForwardMessage.js b/src/components/views/rooms/ForwardMessage.js index 67e55101e8c..b0fba128658 100644 --- a/src/components/views/rooms/ForwardMessage.js +++ b/src/components/views/rooms/ForwardMessage.js @@ -30,10 +30,9 @@ module.exports = React.createClass({ componentWillMount: function() { dis.dispatch({ - action: 'ui_opacity', - leftOpacity: 1.0, - rightOpacity: 0.3, - middleOpacity: 0.5, + action: 'panel_disable', + rightDisabled: true, + middleDisabled: true, }); }, @@ -43,9 +42,9 @@ module.exports = React.createClass({ componentWillUnmount: function() { dis.dispatch({ - action: 'ui_opacity', - sideOpacity: 1.0, - middleOpacity: 1.0, + action: 'panel_disable', + sideDisabled: false, + middleDisabled: false, }); document.removeEventListener('keydown', this._onKeyDown); }, diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 7d64b22cb01..0a98e8821b7 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -93,7 +93,7 @@ module.exports = withMatrixClient(React.createClass({ }, componentWillReceiveProps: function(newProps) { - if (this.props.member.userId != newProps.member.userId) { + if (this.props.member.userId !== newProps.member.userId) { this._updateStateForNewMember(newProps.member); } }, @@ -125,12 +125,12 @@ module.exports = withMatrixClient(React.createClass({ _disambiguateDevices: function(devices) { const names = Object.create(null); for (let i = 0; i < devices.length; i++) { - var name = devices[i].getDisplayName(); + const name = devices[i].getDisplayName(); const indexList = names[name] || []; indexList.push(i); names[name] = indexList; } - for (name in names) { + for (const name in names) { if (names[name].length > 1) { names[name].forEach((j)=>{ devices[j].ambiguous = true; @@ -144,7 +144,7 @@ module.exports = withMatrixClient(React.createClass({ return; } - if (userId == this.props.member.userId) { + if (userId === this.props.member.userId) { // no need to re-download the whole thing; just update our copy of // the list. @@ -194,7 +194,7 @@ module.exports = withMatrixClient(React.createClass({ }, onAccountData: function(ev) { - if (ev.getType() == 'm.direct') { + if (ev.getType() === 'm.direct') { this.forceUpdate(); } }, @@ -249,7 +249,9 @@ module.exports = withMatrixClient(React.createClass({ ignoredUsers.push(this.props.member.userId); } - this.props.matrixClient.setIgnoredUsers(ignoredUsers).then(() => this.setState({isIgnoring: !this.state.isIgnoring})); + this.props.matrixClient.setIgnoredUsers(ignoredUsers).then(() => { + return this.setState({isIgnoring: !this.state.isIgnoring}); + }); }, onKick: function() { @@ -259,7 +261,7 @@ module.exports = withMatrixClient(React.createClass({ Modal.createTrackedDialog('Confirm User Action Dialog', 'onKick', ConfirmUserActionDialog, { member: this.props.member, action: kickLabel, - askReason: membership == "join", + askReason: membership === "join", danger: true, onFinished: (proceed, reason) => { if (!proceed) return; @@ -291,15 +293,15 @@ module.exports = withMatrixClient(React.createClass({ const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); Modal.createTrackedDialog('Confirm User Action Dialog', 'onBanOrUnban', ConfirmUserActionDialog, { member: this.props.member, - action: this.props.member.membership == 'ban' ? _t("Unban") : _t("Ban"), - askReason: this.props.member.membership != 'ban', - danger: this.props.member.membership != 'ban', + action: this.props.member.membership === 'ban' ? _t("Unban") : _t("Ban"), + askReason: this.props.member.membership !== 'ban', + danger: this.props.member.membership !== 'ban', onFinished: (proceed, reason) => { if (!proceed) return; this.setState({ updating: this.state.updating + 1 }); let promise; - if (this.props.member.membership == 'ban') { + if (this.props.member.membership === 'ban') { promise = this.props.matrixClient.unban( this.props.member.roomId, this.props.member.userId, ); @@ -334,15 +336,11 @@ module.exports = withMatrixClient(React.createClass({ const roomId = this.props.member.roomId; const target = this.props.member.userId; const room = this.props.matrixClient.getRoom(roomId); - if (!room) { - return; - } - const powerLevelEvent = room.currentState.getStateEvents( - "m.room.power_levels", "", - ); - if (!powerLevelEvent) { - return; - } + if (!room) return; + + const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", ""); + if (!powerLevelEvent) return; + const isMuted = this.state.muted; const powerLevels = powerLevelEvent.getContent(); const levelToSend = ( @@ -357,7 +355,7 @@ module.exports = withMatrixClient(React.createClass({ } level = parseInt(level); - if (level !== NaN) { + if (!isNaN(level)) { this.setState({ updating: this.state.updating + 1 }); this.props.matrixClient.setPowerLevel(roomId, target, level, powerLevelEvent).then( function() { @@ -382,19 +380,14 @@ module.exports = withMatrixClient(React.createClass({ const roomId = this.props.member.roomId; const target = this.props.member.userId; const room = this.props.matrixClient.getRoom(roomId); - if (!room) { - return; - } - const powerLevelEvent = room.currentState.getStateEvents( - "m.room.power_levels", "", - ); - if (!powerLevelEvent) { - return; - } + if (!room) return; + + const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", ""); + if (!powerLevelEvent) return; + const me = room.getMember(this.props.matrixClient.credentials.userId); - if (!me) { - return; - } + if (!me) return; + const defaultLevel = powerLevelEvent.getContent().users_default; let modLevel = me.powerLevel - 1; if (modLevel > 50 && defaultLevel < 50) modLevel = 50; // try to stick with the vector level defaults @@ -407,7 +400,7 @@ module.exports = withMatrixClient(React.createClass({ // get out of sync if we force setState here! console.log("Mod toggle success"); }, function(err) { - if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') { + if (err.errcode === 'M_GUEST_ACCESS_FORBIDDEN') { dis.dispatch({action: 'view_set_mxid'}); } else { console.error("Toggle moderator error:" + err); @@ -443,7 +436,6 @@ module.exports = withMatrixClient(React.createClass({ }, onPowerChange: function(powerLevel) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const roomId = this.props.member.roomId; const target = this.props.member.userId; const room = this.props.matrixClient.getRoom(roomId); @@ -504,19 +496,14 @@ module.exports = withMatrixClient(React.createClass({ modifyLevel: false, }; const room = this.props.matrixClient.getRoom(member.roomId); - if (!room) { - return defaultPerms; - } - const powerLevels = room.currentState.getStateEvents( - "m.room.power_levels", "", - ); - if (!powerLevels) { - return defaultPerms; - } + if (!room) return defaultPerms; + + const powerLevels = room.currentState.getStateEvents("m.room.power_levels", ""); + if (!powerLevels) return defaultPerms; + const me = room.getMember(this.props.matrixClient.credentials.userId); - if (!me) { - return defaultPerms; - } + if (!me) return defaultPerms; + const them = member; return { can: this._calculateCanPermissions( @@ -552,14 +539,13 @@ module.exports = withMatrixClient(React.createClass({ can.ban = me.powerLevel >= powerLevels.ban; can.mute = me.powerLevel >= editPowerLevel; can.toggleMod = me.powerLevel > them.powerLevel && them.powerLevel >= levelToSend; - can.modifyLevel = me.powerLevel > them.powerLevel; + can.modifyLevel = me.powerLevel > them.powerLevel && me.powerLevel >= editPowerLevel; return can; }, _isMuted: function(member, powerLevelContent) { - if (!powerLevelContent || !member) { - return false; - } + if (!powerLevelContent || !member) return false; + const levelToSend = ( (powerLevelContent.events ? powerLevelContent.events["m.room.message"] : null) || powerLevelContent.events_default @@ -575,14 +561,15 @@ module.exports = withMatrixClient(React.createClass({ }, onMemberAvatarClick: function() { - const avatarUrl = this.props.member.user ? this.props.member.user.avatarUrl : this.props.member.events.member.getContent().avatar_url; + const member = this.props.member; + const avatarUrl = member.user ? member.user.avatarUrl : member.events.member.getContent().avatar_url; if(!avatarUrl) return; const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl); const ImageView = sdk.getComponent("elements.ImageView"); const params = { src: httpUrl, - name: this.props.member.name, + name: member.name, }; Modal.createDialog(ImageView, params, "mx_Dialog_lightbox"); @@ -596,9 +583,7 @@ module.exports = withMatrixClient(React.createClass({ }, _renderDevices: function() { - if (!this._enableDevices) { - return null; - } + if (!this._enableDevices) return null; const devices = this.state.devices; const MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo'); @@ -705,7 +690,13 @@ module.exports = withMatrixClient(React.createClass({ }, render: function() { - let startChat, kickButton, banButton, muteButton, giveModButton, spinner; + let startChat; + let kickButton; + let banButton; + let muteButton; + let giveModButton; + let spinner; + if (this.props.member.userId !== this.props.matrixClient.credentials.userId) { const dmRoomMap = new DMRoomMap(this.props.matrixClient); const dmRooms = dmRoomMap.getDMRoomsForUserId(this.props.member.userId); @@ -719,7 +710,7 @@ module.exports = withMatrixClient(React.createClass({ const me = room.getMember(this.props.matrixClient.credentials.userId); const highlight = ( room.getUnreadNotificationCount('highlight') > 0 || - me.membership == "invite" + me.membership === "invite" ); tiles.push( , ); @@ -772,7 +763,7 @@ module.exports = withMatrixClient(React.createClass({ } if (this.state.can.ban) { let label = _t("Ban"); - if (this.props.member.membership == 'ban') { + if (this.props.member.membership === 'ban') { label = _t("Unban"); } banButton = ( @@ -815,11 +806,14 @@ module.exports = withMatrixClient(React.createClass({ const memberName = this.props.member.name; + let presenceState; + let presenceLastActiveAgo; + let presenceCurrentlyActive; + if (this.props.member.user) { - var presenceState = this.props.member.user.presence; - var presenceLastActiveAgo = this.props.member.user.lastActiveAgo; - const presenceLastTs = this.props.member.user.lastPresenceTs; - var presenceCurrentlyActive = this.props.member.user.currentlyActive; + presenceState = this.props.member.user.presence; + presenceLastActiveAgo = this.props.member.user.lastActiveAgo; + presenceCurrentlyActive = this.props.member.user.currentlyActive; } let roomMemberDetails = null; diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 8e27520d89b..93f20b8ec3f 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -371,7 +371,7 @@ export default class MessageComposer extends React.Component { ); return ( -
    +
    { controls } @@ -410,9 +410,6 @@ MessageComposer.propTypes = { // callback when a file to upload is chosen uploadFile: React.PropTypes.func.isRequired, - // opacity for dynamic UI fading effects - opacity: React.PropTypes.number, - // string representing the current room app drawer state showApps: React.PropTypes.bool, }; diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 9934456597f..dbdcdf596ad 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -19,7 +19,6 @@ import Promise from 'bluebird'; import React from 'react'; import { _t, _tJsx, _td } from '../../../languageHandler'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import SdkConfig from '../../../SdkConfig'; import sdk from '../../../index'; import Modal from '../../../Modal'; import ObjectUtils from '../../../ObjectUtils'; @@ -158,9 +157,9 @@ module.exports = React.createClass({ }); dis.dispatch({ - action: 'ui_opacity', - sideOpacity: 0.3, - middleOpacity: 0.3, + action: 'panel_disable', + sideDisabled: true, + middleDisabled: true, }); }, @@ -171,9 +170,9 @@ module.exports = React.createClass({ } dis.dispatch({ - action: 'ui_opacity', - sideOpacity: 1.0, - middleOpacity: 1.0, + action: 'panel_disable', + sideDisabled: false, + middleDisabled: false, }); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9d91c3a110d..7fa90db301c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -200,6 +200,8 @@ "Authentication": "Authentication", "Failed to delete device": "Failed to delete device", "Delete": "Delete", + "Delete Widget": "Delete Widget", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?", "Disable Notifications": "Disable Notifications", "Enable Notifications": "Enable Notifications", "Cannot add any more widgets": "Cannot add any more widgets",