From 659fc8fcfb1073427f101884764fb5903744737f Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 14:24:21 +0000 Subject: [PATCH 1/8] Point to new Spinner location --- src/controllers/molecules/MemberInfo.js | 2 +- src/controllers/molecules/MemberTile.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/molecules/MemberInfo.js b/src/controllers/molecules/MemberInfo.js index d822a87f48..913e36a4ce 100644 --- a/src/controllers/molecules/MemberInfo.js +++ b/src/controllers/molecules/MemberInfo.js @@ -228,7 +228,7 @@ module.exports = { var d = MatrixClientPeg.get().leave(roomId); // FIXME: controller shouldn't be loading a view :( - var Loader = sdk.getComponent("atoms.Spinner"); + var Loader = sdk.getComponent("elements.Spinner"); var modal = Modal.createDialog(Loader); d.then(function() { diff --git a/src/controllers/molecules/MemberTile.js b/src/controllers/molecules/MemberTile.js index 222ebca145..057bc82497 100644 --- a/src/controllers/molecules/MemberTile.js +++ b/src/controllers/molecules/MemberTile.js @@ -39,7 +39,7 @@ module.exports = { var d = MatrixClientPeg.get().leave(roomId); // FIXME: controller shouldn't be loading a view :( - var Loader = sdk.getComponent("atoms.Spinner"); + var Loader = sdk.getComponent("elements.Spinner"); var modal = Modal.createDialog(Loader); d.then(function() { From c2ae6238b95e25da64f40e4bef03657fdfc977b1 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 14:48:02 +0000 Subject: [PATCH 2/8] Nuke LogoutButton; nothing used it. --- src/controllers/atoms/LogoutButton.js | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/controllers/atoms/LogoutButton.js diff --git a/src/controllers/atoms/LogoutButton.js b/src/controllers/atoms/LogoutButton.js deleted file mode 100644 index 87cf814801..0000000000 --- a/src/controllers/atoms/LogoutButton.js +++ /dev/null @@ -1,27 +0,0 @@ -/* -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'; - -var dis = require("../../dispatcher"); - -module.exports = { - onClick: function() { - dis.dispatch({ - action: 'logout' - }); - }, -}; From 8bde761a8afe8d5c417bc8f0e73c4af04f085f74 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 15:11:08 +0000 Subject: [PATCH 3/8] Add EnableNotificationButton component --- .../settings}/EnableNotificationsButton.js | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) rename src/{controllers/atoms => components/views/settings}/EnableNotificationsButton.js (69%) diff --git a/src/controllers/atoms/EnableNotificationsButton.js b/src/components/views/settings/EnableNotificationsButton.js similarity index 69% rename from src/controllers/atoms/EnableNotificationsButton.js rename to src/components/views/settings/EnableNotificationsButton.js index 3c399484e8..de43a578f7 100644 --- a/src/controllers/atoms/EnableNotificationsButton.js +++ b/src/components/views/settings/EnableNotificationsButton.js @@ -15,10 +15,12 @@ limitations under the License. */ 'use strict'; -var sdk = require('../../index'); -var dis = require("../../dispatcher"); +var React = require("react"); +var sdk = require('../../../index'); +var dis = require("../../../dispatcher"); -module.exports = { +module.exports = React.createClass({ + displayName: 'EnableNotificationsButton', componentDidMount: function() { this.dispatcherRef = dis.register(this.onAction); @@ -55,4 +57,20 @@ module.exports = { } this.forceUpdate(); }, -}; + + render: function() { + if (this.enabled()) { + return ( + + ); + } else { + return ( + + ); + } + } +}); From 17d789eb971121b0a1ff2181b1d24b34b834adc6 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 15:16:50 +0000 Subject: [PATCH 4/8] Merge EditableText component --- .../views/elements}/EditableText.js | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) rename src/{controllers/atoms => components/views/elements}/EditableText.js (58%) diff --git a/src/controllers/atoms/EditableText.js b/src/components/views/elements/EditableText.js similarity index 58% rename from src/controllers/atoms/EditableText.js rename to src/components/views/elements/EditableText.js index 5ea4ce8c4a..63d8fe1877 100644 --- a/src/controllers/atoms/EditableText.js +++ b/src/components/views/elements/EditableText.js @@ -18,7 +18,8 @@ limitations under the License. var React = require('react'); -module.exports = { +module.exports = React.createClass({ + displayName: 'EditableText', propTypes: { onValueChanged: React.PropTypes.func, initialValue: React.PropTypes.string, @@ -85,4 +86,54 @@ module.exports = { onValueChanged: function(shouldSubmit) { this.props.onValueChanged(this.state.value, shouldSubmit); }, + + onKeyUp: function(ev) { + if (ev.key == "Enter") { + this.onFinish(ev); + } else if (ev.key == "Escape") { + this.cancelEdit(); + } + }, + + onClickDiv: function() { + this.setState({ + phase: this.Phases.Edit, + }) + }, + + onFocus: function(ev) { + ev.target.setSelectionRange(0, ev.target.value.length); + }, + + onFinish: function(ev) { + if (ev.target.value) { + this.setValue(ev.target.value, ev.key === "Enter"); + } else { + this.cancelEdit(); + } + }, + + render: function() { + var editable_el; + + if (this.state.phase == this.Phases.Display) { + if (this.state.value) { + editable_el =
{this.state.value}
; + } else { + editable_el =
{this.props.label}
; + } + } else if (this.state.phase == this.Phases.Edit) { + editable_el = ( +
+ +
+ ); + } + + return ( +
+ {editable_el} +
+ ); + } }; From 4fda0ce0c99c19a47be73161c5afc5ae63ba5ee7 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 15:17:34 +0000 Subject: [PATCH 5/8] Fix typo --- src/components/views/elements/EditableText.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/EditableText.js b/src/components/views/elements/EditableText.js index 63d8fe1877..0ed443fbae 100644 --- a/src/components/views/elements/EditableText.js +++ b/src/components/views/elements/EditableText.js @@ -136,4 +136,4 @@ module.exports = React.createClass({ ); } -}; +}); From e55ecfeacb71937767499b9e1988d3eaf1176dfa Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 15:20:57 +0000 Subject: [PATCH 6/8] Add VideoFeed component --- src/components/views/voip/VideoFeed.js | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/components/views/voip/VideoFeed.js diff --git a/src/components/views/voip/VideoFeed.js b/src/components/views/voip/VideoFeed.js new file mode 100644 index 0000000000..9cf28d1ba4 --- /dev/null +++ b/src/components/views/voip/VideoFeed.js @@ -0,0 +1,31 @@ +/* +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'; + +var React = require('react'); + +module.exports = React.createClass({ + displayName: 'VideoFeed', + + render: function() { + return ( + + ); + }, +}); + From 172735a8379b817063cff477b0d4631f083fcff0 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 15:44:42 +0000 Subject: [PATCH 7/8] Move create_room atoms to components --- .../views}/create_room/CreateRoomButton.js | 11 +- .../views}/create_room/Presets.js | 19 +++- src/components/views/create_room/RoomAlias.js | 101 ++++++++++++++++++ .../atoms/create_room/RoomAlias.js | 47 -------- .../atoms/create_room/RoomNameTextbox.js | 41 ------- src/controllers/organisms/CreateRoom.js | 6 +- 6 files changed, 132 insertions(+), 93 deletions(-) rename src/{controllers/atoms => components/views}/create_room/CreateRoomButton.js (78%) rename src/{controllers/atoms => components/views}/create_room/Presets.js (62%) create mode 100644 src/components/views/create_room/RoomAlias.js delete mode 100644 src/controllers/atoms/create_room/RoomAlias.js delete mode 100644 src/controllers/atoms/create_room/RoomNameTextbox.js diff --git a/src/controllers/atoms/create_room/CreateRoomButton.js b/src/components/views/create_room/CreateRoomButton.js similarity index 78% rename from src/controllers/atoms/create_room/CreateRoomButton.js rename to src/components/views/create_room/CreateRoomButton.js index f03dd56c97..95ba4ac366 100644 --- a/src/controllers/atoms/create_room/CreateRoomButton.js +++ b/src/components/views/create_room/CreateRoomButton.js @@ -18,7 +18,8 @@ limitations under the License. var React = require('react'); -module.exports = { +module.exports = React.createClass({ + displayName: 'CreateRoomButton', propTypes: { onCreateRoom: React.PropTypes.func, }, @@ -32,4 +33,10 @@ module.exports = { onClick: function() { this.props.onCreateRoom(); }, -}; + + render: function() { + return ( + + ); + } +}); diff --git a/src/controllers/atoms/create_room/Presets.js b/src/components/views/create_room/Presets.js similarity index 62% rename from src/controllers/atoms/create_room/Presets.js rename to src/components/views/create_room/Presets.js index bcc2f51481..ee0d19c357 100644 --- a/src/controllers/atoms/create_room/Presets.js +++ b/src/components/views/create_room/Presets.js @@ -24,7 +24,8 @@ var Presets = { Custom: "custom", }; -module.exports = { +module.exports = React.createClass({ + displayName: 'CreateRoomPresets', propTypes: { onChange: React.PropTypes.func, preset: React.PropTypes.string @@ -37,4 +38,18 @@ module.exports = { onChange: function() {}, }; }, -}; + + onValueChanged: function(ev) { + this.props.onChange(ev.target.value) + }, + + render: function() { + return ( + + ); + } +}); diff --git a/src/components/views/create_room/RoomAlias.js b/src/components/views/create_room/RoomAlias.js new file mode 100644 index 0000000000..9a30d3fbff --- /dev/null +++ b/src/components/views/create_room/RoomAlias.js @@ -0,0 +1,101 @@ +/* +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'); + +module.exports = React.createClass({ + displayName: 'RoomAlias', + propTypes: { + // Specifying a homeserver will make magical things happen when you, + // e.g. start typing in the room alias box. + homeserver: React.PropTypes.string, + alias: React.PropTypes.string, + onChange: React.PropTypes.func, + }, + + getDefaultProps: function() { + return { + onChange: function() {}, + alias: '', + }; + }, + + getAliasLocalpart: function() { + var room_alias = this.props.alias; + + if (room_alias && this.props.homeserver) { + var suffix = ":" + this.props.homeserver; + if (room_alias.startsWith("#") && room_alias.endsWith(suffix)) { + room_alias = room_alias.slice(1, -suffix.length); + } + } + + return room_alias; + }, + + onValueChanged: function(ev) { + this.props.onChange(ev.target.value); + }, + + onFocus: function(ev) { + var target = ev.target; + var curr_val = ev.target.value; + + if (this.props.homeserver) { + if (curr_val == "") { + setTimeout(function() { + target.value = "#:" + this.props.homeserver; + target.setSelectionRange(1, 1); + }, 0); + } else { + var suffix = ":" + this.props.homeserver; + setTimeout(function() { + target.setSelectionRange( + curr_val.startsWith("#") ? 1 : 0, + curr_val.endsWith(suffix) ? (target.value.length - suffix.length) : target.value.length + ); + }, 0); + } + } + }, + + onBlur: function(ev) { + var curr_val = ev.target.value; + + if (this.props.homeserver) { + if (curr_val == "#:" + this.props.homeserver) { + ev.target.value = ""; + return; + } + + if (curr_val != "") { + var new_val = ev.target.value; + var suffix = ":" + this.props.homeserver; + if (!curr_val.startsWith("#")) new_val = "#" + new_val; + if (!curr_val.endsWith(suffix)) new_val = new_val + suffix; + ev.target.value = new_val; + } + } + }, + + render: function() { + return ( + + ); + } +}); diff --git a/src/controllers/atoms/create_room/RoomAlias.js b/src/controllers/atoms/create_room/RoomAlias.js deleted file mode 100644 index b1176a2ab5..0000000000 --- a/src/controllers/atoms/create_room/RoomAlias.js +++ /dev/null @@ -1,47 +0,0 @@ -/* -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'); - -module.exports = { - propTypes: { - // Specifying a homeserver will make magical things happen when you, - // e.g. start typing in the room alias box. - homeserver: React.PropTypes.string, - alias: React.PropTypes.string, - onChange: React.PropTypes.func, - }, - - getDefaultProps: function() { - return { - onChange: function() {}, - alias: '', - }; - }, - - getAliasLocalpart: function() { - var room_alias = this.props.alias; - - if (room_alias && this.props.homeserver) { - var suffix = ":" + this.props.homeserver; - if (room_alias.startsWith("#") && room_alias.endsWith(suffix)) { - room_alias = room_alias.slice(1, -suffix.length); - } - } - - return room_alias; - }, -}; diff --git a/src/controllers/atoms/create_room/RoomNameTextbox.js b/src/controllers/atoms/create_room/RoomNameTextbox.js deleted file mode 100644 index e78692d992..0000000000 --- a/src/controllers/atoms/create_room/RoomNameTextbox.js +++ /dev/null @@ -1,41 +0,0 @@ -/* -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'; - -var React = require('react'); - -module.exports = { - propTypes: { - default_name: React.PropTypes.string - }, - - getDefaultProps: function() { - return { - default_name: '', - }; - }, - - getInitialState: function() { - return { - room_name: this.props.default_name, - } - }, - - getName: function() { - return this.state.room_name; - }, -}; diff --git a/src/controllers/organisms/CreateRoom.js b/src/controllers/organisms/CreateRoom.js index 3c48e43f74..b39b734480 100644 --- a/src/controllers/organisms/CreateRoom.js +++ b/src/controllers/organisms/CreateRoom.js @@ -18,7 +18,11 @@ limitations under the License. var React = require("react"); var MatrixClientPeg = require("../../MatrixClientPeg"); -var PresetValues = require('../atoms/create_room/Presets').Presets; +var PresetValues = { + PrivateChat: "private_chat", + PublicChat: "public_chat", + Custom: "custom", +}; var q = require('q'); var encryption = require("../../encryption"); From 6c9f3303c6dfc84488a8605e66e7bb5fa85e7ad7 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 16:38:56 +0000 Subject: [PATCH 8/8] Convert voip molecules to components Don't pull in VectorConferenceHandler; instead accept a prop which meets a conference handler interface. --- .../views}/voip/CallView.js | 64 +++++++-- src/components/views/voip/IncomingCallBox.js | 122 ++++++++++++++++++ src/components/views/voip/VideoView.js | 93 +++++++++++++ .../molecules/voip/IncomingCallBox.js | 73 ----------- 4 files changed, 266 insertions(+), 86 deletions(-) rename src/{controllers/molecules => components/views}/voip/CallView.js (51%) create mode 100644 src/components/views/voip/IncomingCallBox.js create mode 100644 src/components/views/voip/VideoView.js delete mode 100644 src/controllers/molecules/voip/IncomingCallBox.js diff --git a/src/controllers/molecules/voip/CallView.js b/src/components/views/voip/CallView.js similarity index 51% rename from src/controllers/molecules/voip/CallView.js rename to src/components/views/voip/CallView.js index 4dd488c2dc..fbaed1dcd7 100644 --- a/src/controllers/molecules/voip/CallView.js +++ b/src/components/views/voip/CallView.js @@ -13,9 +13,11 @@ 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 dis = require("../../../dispatcher"); var CallHandler = require("../../../CallHandler"); +var sdk = require('../../../index'); +var MatrixClientPeg = require("../../../MatrixClientPeg"); /* * State vars: @@ -23,14 +25,31 @@ var CallHandler = require("../../../CallHandler"); * * Props: * this.props.room = Room (JS SDK) + * this.props.ConferenceHandler = A Conference Handler implementation + * Must have a function signature: + * getConferenceCallForRoom(roomId: string): MatrixCall */ -module.exports = { +module.exports = React.createClass({ + displayName: 'CallView', componentDidMount: function() { this.dispatcherRef = dis.register(this.onAction); + this._trackedRoom = null; if (this.props.room) { - this.showCall(this.props.room.roomId); + this._trackedRoom = this.props.room; + this.showCall(this._trackedRoom.roomId); + } + else { + var call = CallHandler.getAnyActiveCall(); + if (call) { + console.log( + "Global CallView is now tracking active call in room %s", + call.roomId + ); + this._trackedRoom = MatrixClientPeg.get().getRoom(call.roomId); + this.showCall(call.roomId); + } } }, @@ -39,19 +58,22 @@ module.exports = { }, onAction: function(payload) { - // if we were given a room_id to track, don't handle anything else. - if (payload.room_id && this.props.room && - this.props.room.roomId !== payload.room_id) { - return; - } - if (payload.action !== 'call_state') { + // 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; } this.showCall(payload.room_id); }, showCall: function(roomId) { - var call = CallHandler.getCall(roomId); + var call = ( + CallHandler.getCallForRoom(roomId) || + (this.props.ConferenceHandler ? + this.props.ConferenceHandler.getConferenceCallForRoom(roomId) : + null + ) + ); if (call) { call.setLocalVideoElement(this.getVideoView().getLocalVideoElement()); call.setRemoteVideoElement(this.getVideoView().getRemoteVideoElement()); @@ -60,13 +82,29 @@ module.exports = { call.setRemoteAudioElement(this.getVideoView().getRemoteAudioElement()); } if (call && call.type === "video" && call.state !== 'ended') { - this.getVideoView().getLocalVideoElement().style.display = "initial"; + // if this call is a conf call, don't display local video as the + // conference will have us in it + this.getVideoView().getLocalVideoElement().style.display = ( + call.confUserId ? "none" : "initial" + ); this.getVideoView().getRemoteVideoElement().style.display = "initial"; } else { this.getVideoView().getLocalVideoElement().style.display = "none"; this.getVideoView().getRemoteVideoElement().style.display = "none"; + dis.dispatch({action: 'video_fullscreen', fullscreen: false}); } - } -}; + }, + + getVideoView: function() { + return this.refs.video; + }, + + render: function(){ + var VideoView = sdk.getComponent('voip.VideoView'); + return ( + + ); + } +}); diff --git a/src/components/views/voip/IncomingCallBox.js b/src/components/views/voip/IncomingCallBox.js new file mode 100644 index 0000000000..263bbf543c --- /dev/null +++ b/src/components/views/voip/IncomingCallBox.js @@ -0,0 +1,122 @@ +/* +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 dis = require("../../../dispatcher"); +var CallHandler = require("../../../CallHandler"); + +module.exports = React.createClass({ + displayName: 'IncomingCallBox', + + componentDidMount: function() { + this.dispatcherRef = dis.register(this.onAction); + }, + + componentWillUnmount: function() { + dis.unregister(this.dispatcherRef); + }, + + getInitialState: function() { + return { + incomingCall: null + } + }, + + onAction: function(payload) { + if (payload.action !== 'call_state') { + return; + } + var call = CallHandler.getCall(payload.room_id); + if (!call || call.call_state !== 'ringing') { + this.setState({ + incomingCall: null, + }); + this.getRingAudio().pause(); + return; + } + if (call.call_state === "ringing") { + this.getRingAudio().load(); + this.getRingAudio().play(); + } + else { + this.getRingAudio().pause(); + } + + this.setState({ + incomingCall: call + }); + }, + + onAnswerClick: function() { + dis.dispatch({ + action: 'answer', + room_id: this.state.incomingCall.roomId + }); + }, + + onRejectClick: function() { + dis.dispatch({ + action: 'hangup', + room_id: this.state.incomingCall.roomId + }); + }, + + getRingAudio: function() { + return this.refs.ringAudio; + }, + + render: function() { + // NB: This block MUST have a "key" so React doesn't clobber the elements + // between in-call / not-in-call. + var audioBlock = ( + + ); + + if (!this.state.incomingCall || !this.state.incomingCall.roomId) { + return ( +
+ {audioBlock} +
+ ); + } + var caller = MatrixClientPeg.get().getRoom(this.state.incomingCall.roomId).name; + return ( +
+ {audioBlock} + +
+ Incoming { this.state.incomingCall ? this.state.incomingCall.type : '' } call from { caller } +
+
+
+
+ Decline +
+
+
+
+ Accept +
+
+
+
+ ); + } +}); + diff --git a/src/components/views/voip/VideoView.js b/src/components/views/voip/VideoView.js new file mode 100644 index 0000000000..0a95e0d0c8 --- /dev/null +++ b/src/components/views/voip/VideoView.js @@ -0,0 +1,93 @@ +/* +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'; + +var React = require('react'); +var ReactDOM = require('react-dom'); + +var sdk = require('../../../index'); +var dis = require('../../../dispatcher'); + +module.exports = React.createClass({ + displayName: 'VideoView', + + componentWillMount: function() { + dis.register(this.onAction); + }, + + getRemoteVideoElement: function() { + return ReactDOM.findDOMNode(this.refs.remote); + }, + + getRemoteAudioElement: function() { + return this.refs.remoteAudio; + }, + + getLocalVideoElement: function() { + return ReactDOM.findDOMNode(this.refs.local); + }, + + setContainer: function(c) { + this.container = c; + }, + + onAction: function(payload) { + switch (payload.action) { + case 'video_fullscreen': + if (!this.container) { + return; + } + var element = this.container; + if (payload.fullscreen) { + var requestMethod = ( + element.requestFullScreen || + element.webkitRequestFullScreen || + element.mozRequestFullScreen || + element.msRequestFullscreen + ); + requestMethod.call(element); + } + else { + var exitMethod = ( + document.exitFullscreen || + document.mozCancelFullScreen || + document.webkitExitFullscreen || + document.msExitFullscreen + ); + if (exitMethod) { + exitMethod.call(document); + } + } + break; + } + }, + + render: function() { + var VideoFeed = sdk.getComponent('voip.VideoFeed'); + return ( +
+
+ +
+
+ +
+
+ ); + } +}); diff --git a/src/controllers/molecules/voip/IncomingCallBox.js b/src/controllers/molecules/voip/IncomingCallBox.js deleted file mode 100644 index 9ecced56c5..0000000000 --- a/src/controllers/molecules/voip/IncomingCallBox.js +++ /dev/null @@ -1,73 +0,0 @@ -/* -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 dis = require("../../../dispatcher"); -var CallHandler = require("../../../CallHandler"); - -module.exports = { - componentDidMount: function() { - this.dispatcherRef = dis.register(this.onAction); - }, - - componentWillUnmount: function() { - dis.unregister(this.dispatcherRef); - }, - - getInitialState: function() { - return { - incomingCall: null - } - }, - - onAction: function(payload) { - if (payload.action !== 'call_state') { - return; - } - var call = CallHandler.getCall(payload.room_id); - if (!call || call.call_state !== 'ringing') { - this.setState({ - incomingCall: null, - }); - this.getRingAudio().pause(); - return; - } - if (call.call_state === "ringing") { - this.getRingAudio().load(); - this.getRingAudio().play(); - } - else { - this.getRingAudio().pause(); - } - - this.setState({ - incomingCall: call - }); - }, - - onAnswerClick: function() { - dis.dispatch({ - action: 'answer', - room_id: this.state.incomingCall.roomId - }); - }, - onRejectClick: function() { - dis.dispatch({ - action: 'hangup', - room_id: this.state.incomingCall.roomId - }); - } -}; -