diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js new file mode 100644 index 0000000000..76724d88fd --- /dev/null +++ b/src/components/views/rooms/RoomHeader.js @@ -0,0 +1,273 @@ +/* +Copyright 2015 OpenMarket Ltd + +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. +*/ + +'use strict'; + +/* + * State vars: + * this.state.call_state = the UI state of the call (see CallHandler) + */ + +var React = require('react'); +var sdk = require('../../../index'); +var dis = require("../../../dispatcher"); +var CallHandler = require("../../../CallHandler"); +var MatrixClientPeg = require('../../../MatrixClientPeg'); + +module.exports = React.createClass({ + displayName: 'RoomHeader', + + propTypes: { + room: React.PropTypes.object, + editing: React.PropTypes.bool, + onSettingsClick: React.PropTypes.func, + onSaveClick: React.PropTypes.func, + }, + + getDefaultProps: function() { + return { + editing: false, + onSettingsClick: function() {}, + onSaveClick: function() {}, + }; + }, + + componentDidMount: function() { + this.dispatcherRef = dis.register(this.onAction); + if (this.props.room) { + var call = CallHandler.getCallForRoom(this.props.room.roomId); + var callState = call ? call.call_state : "ended"; + this.setState({ + call_state: callState + }); + } + }, + + componentWillUnmount: function() { + dis.unregister(this.dispatcherRef); + }, + + onAction: function(payload) { + // don't filter out payloads for room IDs other than props.room because + // we may be interested in the conf 1:1 room + if (payload.action !== 'call_state' || !payload.room_id) { + return; + } + var call = CallHandler.getCallForRoom(payload.room_id); + var callState = call ? call.call_state : "ended"; + this.setState({ + call_state: callState + }); + }, + + onVideoClick: function(e) { + dis.dispatch({ + action: 'place_call', + type: e.shiftKey ? "screensharing" : "video", + room_id: this.props.room.roomId + }); + }, + onVoiceClick: function() { + dis.dispatch({ + action: 'place_call', + type: "voice", + room_id: this.props.room.roomId + }); + }, + onHangupClick: function() { + var call = CallHandler.getCallForRoom(this.props.room.roomId); + if (!call) { return; } + dis.dispatch({ + action: 'hangup', + // hangup the call for this room, which may not be the room in props + // (e.g. conferences which will hangup the 1:1 room instead) + room_id: call.roomId + }); + }, + onMuteAudioClick: function() { + var call = CallHandler.getCallForRoom(this.props.room.roomId); + if (!call) { + return; + } + var newState = !call.isMicrophoneMuted(); + call.setMicrophoneMuted(newState); + this.setState({ + audioMuted: newState + }); + }, + onMuteVideoClick: function() { + var call = CallHandler.getCallForRoom(this.props.room.roomId); + if (!call) { + return; + } + var newState = !call.isLocalVideoMuted(); + call.setLocalVideoMuted(newState); + this.setState({ + videoMuted: newState + }); + }, + + onNameChange: function(new_name) { + if (this.props.room.name != new_name && new_name) { + MatrixClientPeg.get().setRoomName(this.props.room.roomId, new_name); + } + }, + + getRoomName: function() { + return this.refs.name_edit.value; + }, + + onFullscreenClick: function() { + dis.dispatch({action: 'video_fullscreen', fullscreen: true}, true); + }, + + render: function() { + var EditableText = sdk.getComponent("elements.EditableText"); + var RoomAvatar = sdk.getComponent('avatars.RoomAvatar'); + + var header; + if (this.props.simpleHeader) { + header = +
+
+ { this.props.simpleHeader } +
+
+ } + else { + var topic = this.props.room.currentState.getStateEvents('m.room.topic', ''); + + var call_buttons; + if (this.state && this.state.call_state != 'ended') { + //var muteVideoButton; + var activeCall = ( + CallHandler.getCallForRoom(this.props.room.roomId) + ); +/* + if (activeCall && activeCall.type === "video") { + muteVideoButton = ( +
+ { + (activeCall.isLocalVideoMuted() ? + "Unmute" : "Mute") + " video" + } +
+ ); + } + {muteVideoButton} +
+ { + (activeCall && activeCall.isMicrophoneMuted() ? + "Unmute" : "Mute") + " audio" + } +
+*/ + + call_buttons = ( +
+ End call +
+ ); + } + + var name = null; + var topic_el = null; + var cancel_button = null; + var save_button = null; + var settings_button = null; + var actual_name = this.props.room.currentState.getStateEvents('m.room.name', ''); + if (actual_name) actual_name = actual_name.getContent().name; + if (this.props.editing) { + name = +
+ +
+ // if (topic) topic_el =
+ cancel_button =
Cancel
+ save_button =
Save Changes
+ } else { + // + name = +
+
{ this.props.room.name }
+
+ +
+
+ if (topic) topic_el =
{ topic.getContent().topic }
; + } + + var roomAvatar = null; + if (this.props.room) { + roomAvatar = ( + + ); + } + + var zoom_button, video_button, voice_button; + if (activeCall) { + if (activeCall.type == "video") { + zoom_button = ( +
+ Fullscreen +
+ ); + } + video_button = +
+ Video call +
; + voice_button = +
+ VoIP call +
; + } + + header = +
+
+
+ { roomAvatar } +
+
+ { name } + { topic_el } +
+
+ {call_buttons} + {cancel_button} + {save_button} +
+ { video_button } + { voice_button } + { zoom_button } +
+ Search +
+
+
+ } + + return ( +
+ { header } +
+ ); + }, +}); diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js new file mode 100644 index 0000000000..eb9bfd90c8 --- /dev/null +++ b/src/components/views/rooms/RoomSettings.js @@ -0,0 +1,237 @@ +/* +Copyright 2015 OpenMarket Ltd + +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. +*/ + +var React = require('react'); +var MatrixClientPeg = require('../../../MatrixClientPeg'); +var sdk = require('../../../index'); + +module.exports = React.createClass({ + displayName: 'RoomSettings', + + propTypes: { + room: React.PropTypes.object.isRequired, + }, + + getInitialState: function() { + return { + power_levels_changed: false + }; + }, + + getTopic: function() { + return this.refs.topic.value; + }, + + getJoinRules: function() { + return this.refs.is_private.checked ? "invite" : "public"; + }, + + getHistoryVisibility: function() { + return this.refs.share_history.checked ? "shared" : "invited"; + }, + + getPowerLevels: function() { + if (!this.state.power_levels_changed) return undefined; + + var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); + power_levels = power_levels.getContent(); + + var new_power_levels = { + ban: parseInt(this.refs.ban.value), + kick: parseInt(this.refs.kick.value), + redact: parseInt(this.refs.redact.value), + invite: parseInt(this.refs.invite.value), + events_default: parseInt(this.refs.events_default.value), + state_default: parseInt(this.refs.state_default.value), + users_default: parseInt(this.refs.users_default.value), + users: power_levels.users, + events: power_levels.events, + }; + + return new_power_levels; + }, + + onPowerLevelsChanged: function() { + this.setState({ + power_levels_changed: true + }); + }, + + render: function() { + var ChangeAvatar = sdk.getComponent('settings.ChangeAvatar'); + + var topic = this.props.room.currentState.getStateEvents('m.room.topic', ''); + if (topic) topic = topic.getContent().topic; + + var join_rule = this.props.room.currentState.getStateEvents('m.room.join_rules', ''); + if (join_rule) join_rule = join_rule.getContent().join_rule; + + var history_visibility = this.props.room.currentState.getStateEvents('m.room.history_visibility', ''); + if (history_visibility) history_visibility = history_visibility.getContent().history_visibility; + + var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); + + var events_levels = power_levels.events || {}; + + if (power_levels) { + power_levels = power_levels.getContent(); + + var ban_level = parseInt(power_levels.ban); + var kick_level = parseInt(power_levels.kick); + var redact_level = parseInt(power_levels.redact); + var invite_level = parseInt(power_levels.invite || 0); + var send_level = parseInt(power_levels.events_default || 0); + var state_level = parseInt(power_levels.state_default || 0); + var default_user_level = parseInt(power_levels.users_default || 0); + + if (power_levels.ban == undefined) ban_level = 50; + if (power_levels.kick == undefined) kick_level = 50; + if (power_levels.redact == undefined) redact_level = 50; + + var user_levels = power_levels.users || {}; + + var user_id = MatrixClientPeg.get().credentials.userId; + + var current_user_level = user_levels[user_id]; + if (current_user_level == undefined) current_user_level = default_user_level; + + var power_level_level = events_levels["m.room.power_levels"]; + if (power_level_level == undefined) { + power_level_level = state_level; + } + + var can_change_levels = current_user_level >= power_level_level; + } else { + var ban_level = 50; + var kick_level = 50; + var redact_level = 50; + var invite_level = 0; + var send_level = 0; + var state_level = 0; + var default_user_level = 0; + + var user_levels = []; + var events_levels = []; + + var current_user_level = 0; + + var power_level_level = 0; + + var can_change_levels = false; + } + + var room_avatar_level = parseInt(power_levels.state_default || 0); + if (events_levels['m.room.avatar'] !== undefined) { + room_avatar_level = events_levels['m.room.avatar']; + } + var can_set_room_avatar = current_user_level >= room_avatar_level; + + var change_avatar; + if (can_set_room_avatar) { + change_avatar =
+

Room Icon

+ +
; + } + + var banned = this.props.room.getMembersWithMembership("ban"); + + return ( +
+