Merge branch 'develop' into t3chguy/invite_in_memberinfo

This commit is contained in:
Michael Telatynski 2017-10-25 16:33:50 +01:00 committed by GitHub
commit fd7e057ec0
19 changed files with 187 additions and 170 deletions

View file

@ -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')}
/>
);

View file

@ -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({
</div>;
} 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,

View file

@ -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 = <RightPanel roomId={this.props.currentRoomId} opacity={this.props.rightOpacity} />;
if (!this.props.collapseRhs) {
right_panel = <RightPanel roomId={this.props.currentRoomId} disabled={this.props.rightDisabled} />;
}
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 = <RightPanel opacity={this.props.rightOpacity} />;
if (!this.props.collapseRhs) right_panel = <RightPanel disabled={this.props.rightDisabled} />;
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 = <RightPanel opacity={this.props.rightOpacity} />;
if (!this.props.collapseRhs) right_panel = <RightPanel disabled={this.props.rightDisabled} />;
break;
case PageTypes.RoomDirectory:
@ -294,14 +296,14 @@ export default React.createClass({
case PageTypes.UserView:
page_element = null; // deliberately null for now
right_panel = <RightPanel opacity={this.props.rightOpacity} />;
right_panel = <RightPanel disabled={this.props.rightDisabled} />;
break;
case PageTypes.GroupView:
page_element = <GroupView
groupId={this.props.currentGroupId}
collapsedRhs={this.props.collapseRhs}
/>;
if (!this.props.collapseRhs) right_panel = <RightPanel groupId={this.props.currentGroupId} opacity={this.props.rightOpacity} />;
if (!this.props.collapseRhs) right_panel = <RightPanel groupId={this.props.currentGroupId} disabled={this.props.rightDisabled} />;
break;
}
@ -334,7 +336,7 @@ export default React.createClass({
<LeftPanel
selectedRoom={this.props.currentRoomId}
collapsed={this.props.collapseLhs || false}
opacity={this.props.leftOpacity}
disabled={this.props.leftDisabled}
/>
<main className='mx_MatrixChat_middlePanel'>
{ page_element }

View file

@ -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':

View file

@ -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 (
<ScrollPanel ref="scrollPanel" className={className}

View file

@ -45,7 +45,6 @@ const NotificationPanel = React.createClass({
manageReadMarkers={false}
timelineSet={timelineSet}
showUrlPreview = {false}
opacity={this.props.opacity}
tileShape="notif"
empty={_t('You have no visible notifications')}
/>

View file

@ -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 }}
>
<li className={scrollheader_classes}></li>
{ 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 = (
<div className="mx_RoomView_topUnreadMessagesBar mx_fadable" style={{ opacity: this.props.opacity }}>
<div className="mx_RoomView_topUnreadMessagesBar">
<TopUnreadMessagesBar
onScrollUpClick={this.jumpToReadMarker}
onCloseClick={this.forgetReadMarker}
@ -1805,10 +1803,19 @@ module.exports = React.createClass({
</div>
);
}
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 (
<div className={"mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "")} ref="roomView">
@ -1827,16 +1834,18 @@ module.exports = React.createClass({
onLeaveClick={(myMember && myMember.membership === "join") ? this.onLeaveClick : null}
/>
{ auxPanel }
{ topUnreadMessagesBar }
{ messagePanel }
{ searchResultsPanel }
<div className={statusBarAreaClass} style={{opacity: this.props.opacity}}>
<div className="mx_RoomView_statusAreaBox">
<div className="mx_RoomView_statusAreaBox_line"></div>
{ statusBar }
<div className={fadableSectionClasses}>
{ topUnreadMessagesBar }
{ messagePanel }
{ searchResultsPanel }
<div className={statusBarAreaClass}>
<div className="mx_RoomView_statusAreaBox">
<div className="mx_RoomView_statusAreaBox_line"></div>
{ statusBar }
</div>
</div>
{ messageComposer }
</div>
{ messageComposer }
</div>
);
},

View file

@ -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}

View file

@ -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();

View file

@ -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);

View file

@ -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';
}

View file

@ -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 }
</div>
{ editableItems }
<EditableItem
key={-1}
initialValue={this.props.newItem}
onAdd={this.onItemAdded}
onChange={this.onNewItemChanged}
addOnChange={true}
placeholder={this.props.placeholder}
/>
{ this.props.canEdit ?
<EditableItem
key={-1}
initialValue={this.props.newItem}
onAdd={this.onItemAdded}
onChange={this.onNewItemChanged}
addOnChange={true}
placeholder={this.props.placeholder}
/> : <div />
}
</div>);
},
});

View file

@ -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}

View file

@ -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}

View file

@ -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);
},

View file

@ -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(
<RoomTile key={room.roomId} room={room}
@ -727,7 +718,7 @@ module.exports = withMatrixClient(React.createClass({
selected={false}
unread={Unread.doesRoomHaveUnreadMessages(room)}
highlight={highlight}
isInvite={me.membership == "invite"}
isInvite={me.membership === "invite"}
onClick={this.onRoomTileClick}
/>,
);
@ -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;

View file

@ -371,7 +371,7 @@ export default class MessageComposer extends React.Component {
);
return (
<div className="mx_MessageComposer mx_fadable" style={{ opacity: this.props.opacity }}>
<div className="mx_MessageComposer">
<div className="mx_MessageComposer_wrapper">
<div className="mx_MessageComposer_row">
{ 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,
};

View file

@ -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,
});
},

View file

@ -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",