Merge pull request #812 from t3chguy/forward_message
Message Forwarding
This commit is contained in:
commit
accc17a39a
8 changed files with 151 additions and 41 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -10,5 +10,5 @@ npm-debug.log
|
||||||
# test reports created by karma
|
# test reports created by karma
|
||||||
/karma-reports
|
/karma-reports
|
||||||
|
|
||||||
# ignore auto-generated component index
|
/.idea
|
||||||
/src/component-index.js
|
/src/component-index.js
|
||||||
|
|
|
@ -22,7 +22,7 @@ let isDialogOpen = false;
|
||||||
|
|
||||||
const onAction = function(payload) {
|
const onAction = function(payload) {
|
||||||
if (payload.action === 'unknown_device_error' && !isDialogOpen) {
|
if (payload.action === 'unknown_device_error' && !isDialogOpen) {
|
||||||
var UnknownDeviceDialog = sdk.getComponent("dialogs.UnknownDeviceDialog");
|
const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog');
|
||||||
isDialogOpen = true;
|
isDialogOpen = true;
|
||||||
Modal.createDialog(UnknownDeviceDialog, {
|
Modal.createDialog(UnknownDeviceDialog, {
|
||||||
devices: payload.err.devices,
|
devices: payload.err.devices,
|
||||||
|
@ -33,17 +33,17 @@ const onAction = function(payload) {
|
||||||
// https://github.com/vector-im/riot-web/issues/3148
|
// https://github.com/vector-im/riot-web/issues/3148
|
||||||
console.log('UnknownDeviceDialog closed with '+r);
|
console.log('UnknownDeviceDialog closed with '+r);
|
||||||
},
|
},
|
||||||
}, "mx_Dialog_unknownDevice");
|
}, 'mx_Dialog_unknownDevice');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
let ref = null;
|
let ref = null;
|
||||||
|
|
||||||
export function startListening () {
|
export function startListening() {
|
||||||
ref = dis.register(onAction);
|
ref = dis.register(onAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopListening () {
|
export function stopListening() {
|
||||||
if (ref) {
|
if (ref) {
|
||||||
dis.unregister(ref);
|
dis.unregister(ref);
|
||||||
ref = null;
|
ref = null;
|
||||||
|
|
|
@ -183,7 +183,7 @@ export default React.createClass({
|
||||||
ConferenceHandler={this.props.ConferenceHandler}
|
ConferenceHandler={this.props.ConferenceHandler}
|
||||||
scrollStateMap={this._scrollStateMap}
|
scrollStateMap={this._scrollStateMap}
|
||||||
/>;
|
/>;
|
||||||
if (!this.props.collapse_rhs) right_panel = <RightPanel roomId={this.props.currentRoomId} opacity={this.props.sideOpacity} />;
|
if (!this.props.collapse_rhs) right_panel = <RightPanel roomId={this.props.currentRoomId} opacity={this.props.rightOpacity} />;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PageTypes.UserSettings:
|
case PageTypes.UserSettings:
|
||||||
|
@ -195,7 +195,7 @@ export default React.createClass({
|
||||||
referralBaseUrl={this.props.config.referralBaseUrl}
|
referralBaseUrl={this.props.config.referralBaseUrl}
|
||||||
teamToken={this.props.teamToken}
|
teamToken={this.props.teamToken}
|
||||||
/>;
|
/>;
|
||||||
if (!this.props.collapse_rhs) right_panel = <RightPanel opacity={this.props.sideOpacity}/>;
|
if (!this.props.collapse_rhs) right_panel = <RightPanel opacity={this.props.rightOpacity}/>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PageTypes.CreateRoom:
|
case PageTypes.CreateRoom:
|
||||||
|
@ -203,7 +203,7 @@ export default React.createClass({
|
||||||
onRoomCreated={this.props.onRoomCreated}
|
onRoomCreated={this.props.onRoomCreated}
|
||||||
collapsedRhs={this.props.collapse_rhs}
|
collapsedRhs={this.props.collapse_rhs}
|
||||||
/>;
|
/>;
|
||||||
if (!this.props.collapse_rhs) right_panel = <RightPanel opacity={this.props.sideOpacity}/>;
|
if (!this.props.collapse_rhs) right_panel = <RightPanel opacity={this.props.rightOpacity}/>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PageTypes.RoomDirectory:
|
case PageTypes.RoomDirectory:
|
||||||
|
@ -219,12 +219,12 @@ export default React.createClass({
|
||||||
teamServerUrl={this.props.config.teamServerConfig.teamServerURL}
|
teamServerUrl={this.props.config.teamServerConfig.teamServerURL}
|
||||||
teamToken={this.props.teamToken}
|
teamToken={this.props.teamToken}
|
||||||
/>
|
/>
|
||||||
if (!this.props.collapse_rhs) right_panel = <RightPanel opacity={this.props.sideOpacity}/>
|
if (!this.props.collapse_rhs) right_panel = <RightPanel opacity={this.props.rightOpacity}/>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PageTypes.UserView:
|
case PageTypes.UserView:
|
||||||
page_element = null; // deliberately null for now
|
page_element = null; // deliberately null for now
|
||||||
right_panel = <RightPanel userId={this.props.viewUserId} opacity={this.props.sideOpacity} />;
|
right_panel = <RightPanel userId={this.props.viewUserId} opacity={this.props.rightOpacity} />;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ export default React.createClass({
|
||||||
<LeftPanel
|
<LeftPanel
|
||||||
selectedRoom={this.props.currentRoomId}
|
selectedRoom={this.props.currentRoomId}
|
||||||
collapsed={this.props.collapse_lhs || false}
|
collapsed={this.props.collapse_lhs || false}
|
||||||
opacity={this.props.sideOpacity}
|
opacity={this.props.leftOpacity}
|
||||||
teamToken={this.props.teamToken}
|
teamToken={this.props.teamToken}
|
||||||
/>
|
/>
|
||||||
<main className='mx_MatrixChat_middlePanel'>
|
<main className='mx_MatrixChat_middlePanel'>
|
||||||
|
|
|
@ -117,8 +117,9 @@ module.exports = React.createClass({
|
||||||
collapse_rhs: false,
|
collapse_rhs: false,
|
||||||
ready: false,
|
ready: false,
|
||||||
width: 10000,
|
width: 10000,
|
||||||
sideOpacity: 1.0,
|
leftOpacity: 1.0,
|
||||||
middleOpacity: 1.0,
|
middleOpacity: 1.0,
|
||||||
|
rightOpacity: 1.0,
|
||||||
|
|
||||||
version: null,
|
version: null,
|
||||||
newVersion: null,
|
newVersion: null,
|
||||||
|
@ -490,12 +491,14 @@ module.exports = React.createClass({
|
||||||
collapse_rhs: false,
|
collapse_rhs: false,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'ui_opacity':
|
case 'ui_opacity': {
|
||||||
|
const sideDefault = payload.sideOpacity >= 0.0 ? payload.sideOpacity : 1.0;
|
||||||
this.setState({
|
this.setState({
|
||||||
sideOpacity: payload.sideOpacity,
|
leftOpacity: payload.leftOpacity >= 0.0 ? payload.leftOpacity : sideDefault,
|
||||||
middleOpacity: payload.middleOpacity,
|
middleOpacity: payload.middleOpacity || 1.0,
|
||||||
|
rightOpacity: payload.rightOpacity >= 0.0 ? payload.rightOpacity : sideDefault,
|
||||||
});
|
});
|
||||||
break;
|
break; }
|
||||||
case 'set_theme':
|
case 'set_theme':
|
||||||
this._onSetTheme(payload.value);
|
this._onSetTheme(payload.value);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -125,6 +125,8 @@ module.exports = React.createClass({
|
||||||
room: null,
|
room: null,
|
||||||
roomId: null,
|
roomId: null,
|
||||||
roomLoading: true,
|
roomLoading: true,
|
||||||
|
|
||||||
|
forwardingEvent: null,
|
||||||
editingRoomSettings: false,
|
editingRoomSettings: false,
|
||||||
uploadingRoomSettings: false,
|
uploadingRoomSettings: false,
|
||||||
numUnreadMessages: 0,
|
numUnreadMessages: 0,
|
||||||
|
@ -452,6 +454,11 @@ module.exports = React.createClass({
|
||||||
callState: callState
|
callState: callState
|
||||||
});
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'forward_event':
|
||||||
|
this.setState({
|
||||||
|
forwardingEvent: payload.content,
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1195,7 +1202,10 @@ module.exports = React.createClass({
|
||||||
onCancelClick: function() {
|
onCancelClick: function() {
|
||||||
console.log("updateTint from onCancelClick");
|
console.log("updateTint from onCancelClick");
|
||||||
this.updateTint();
|
this.updateTint();
|
||||||
this.setState({editingRoomSettings: false});
|
this.setState({
|
||||||
|
editingRoomSettings: false,
|
||||||
|
forwardingEvent: null,
|
||||||
|
});
|
||||||
dis.dispatch({action: 'focus_composer'});
|
dis.dispatch({action: 'focus_composer'});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1473,16 +1483,17 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var RoomHeader = sdk.getComponent('rooms.RoomHeader');
|
const RoomHeader = sdk.getComponent('rooms.RoomHeader');
|
||||||
var MessageComposer = sdk.getComponent('rooms.MessageComposer');
|
const MessageComposer = sdk.getComponent('rooms.MessageComposer');
|
||||||
var RoomSettings = sdk.getComponent("rooms.RoomSettings");
|
const ForwardMessage = sdk.getComponent("rooms.ForwardMessage");
|
||||||
var AuxPanel = sdk.getComponent("rooms.AuxPanel");
|
const RoomSettings = sdk.getComponent("rooms.RoomSettings");
|
||||||
var SearchBar = sdk.getComponent("rooms.SearchBar");
|
const AuxPanel = sdk.getComponent("rooms.AuxPanel");
|
||||||
var ScrollPanel = sdk.getComponent("structures.ScrollPanel");
|
const SearchBar = sdk.getComponent("rooms.SearchBar");
|
||||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const ScrollPanel = sdk.getComponent("structures.ScrollPanel");
|
||||||
var RoomPreviewBar = sdk.getComponent("rooms.RoomPreviewBar");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const RoomPreviewBar = sdk.getComponent("rooms.RoomPreviewBar");
|
||||||
var TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
|
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||||
|
|
||||||
if (!this.state.room) {
|
if (!this.state.room) {
|
||||||
if (this.state.roomLoading) {
|
if (this.state.roomLoading) {
|
||||||
|
@ -1610,17 +1621,16 @@ module.exports = React.createClass({
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
var aux = null;
|
let aux = null;
|
||||||
if (this.state.editingRoomSettings) {
|
if (this.state.forwardingEvent !== null) {
|
||||||
|
aux = <ForwardMessage onCancelClick={this.onCancelClick} currentRoomId={this.state.room.roomId} mxEvent={this.state.forwardingEvent} />;
|
||||||
|
} else if (this.state.editingRoomSettings) {
|
||||||
aux = <RoomSettings ref="room_settings" onSaveClick={this.onSettingsSaveClick} onCancelClick={this.onCancelClick} room={this.state.room} />;
|
aux = <RoomSettings ref="room_settings" onSaveClick={this.onSettingsSaveClick} onCancelClick={this.onCancelClick} room={this.state.room} />;
|
||||||
}
|
} else if (this.state.uploadingRoomSettings) {
|
||||||
else if (this.state.uploadingRoomSettings) {
|
|
||||||
aux = <Loader/>;
|
aux = <Loader/>;
|
||||||
}
|
} else if (this.state.searching) {
|
||||||
else if (this.state.searching) {
|
|
||||||
aux = <SearchBar ref="search_bar" searchInProgress={this.state.searchInProgress } onCancelClick={this.onCancelSearchClick} onSearch={this.onSearch}/>;
|
aux = <SearchBar ref="search_bar" searchInProgress={this.state.searchInProgress } onCancelClick={this.onCancelSearchClick} onSearch={this.onSearch}/>;
|
||||||
}
|
} else if (!myMember || myMember.membership !== "join") {
|
||||||
else if (!myMember || myMember.membership !== "join") {
|
|
||||||
// We do have a room object for this room, but we're not currently in it.
|
// We do have a room object for this room, but we're not currently in it.
|
||||||
// We may have a 3rd party invite to it.
|
// We may have a 3rd party invite to it.
|
||||||
var inviterName = undefined;
|
var inviterName = undefined;
|
||||||
|
@ -1733,14 +1743,13 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
|
// console.log("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
|
||||||
|
|
||||||
var messagePanel = (
|
var messagePanel = (
|
||||||
<TimelinePanel ref={this._gatherTimelinePanelRef}
|
<TimelinePanel ref={this._gatherTimelinePanelRef}
|
||||||
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
||||||
manageReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
manageReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
||||||
manageReadMarkers={true}
|
manageReadMarkers={true}
|
||||||
hidden={hideMessagePanel}
|
hidden={hideMessagePanel}
|
||||||
highlightedEventId={this.props.highlightedEventId}
|
highlightedEventId={this.state.forwardingEvent ? this.state.forwardingEvent.getId() : this.props.highlightedEventId}
|
||||||
eventId={this.props.eventId}
|
eventId={this.props.eventId}
|
||||||
eventPixelOffset={this.props.eventPixelOffset}
|
eventPixelOffset={this.props.eventPixelOffset}
|
||||||
onScroll={ this.onMessageListScroll }
|
onScroll={ this.onMessageListScroll }
|
||||||
|
@ -1778,7 +1787,7 @@ module.exports = React.createClass({
|
||||||
onSearchClick={this.onSearchClick}
|
onSearchClick={this.onSearchClick}
|
||||||
onSettingsClick={this.onSettingsClick}
|
onSettingsClick={this.onSettingsClick}
|
||||||
onSaveClick={this.onSettingsSaveClick}
|
onSaveClick={this.onSettingsSaveClick}
|
||||||
onCancelClick={this.onCancelClick}
|
onCancelClick={aux ? this.onCancelClick : null}
|
||||||
onForgetClick={
|
onForgetClick={
|
||||||
(myMember && myMember.membership === "leave") ? this.onForgetClick : null
|
(myMember && myMember.membership === "leave") ? this.onForgetClick : null
|
||||||
}
|
}
|
||||||
|
|
95
src/components/views/rooms/ForwardMessage.js
Normal file
95
src/components/views/rooms/ForwardMessage.js
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 2017 Michael Telatynski
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
|
import dis from '../../../dispatcher';
|
||||||
|
import KeyCode from '../../../KeyCode';
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = React.createClass({
|
||||||
|
displayName: 'ForwardMessage',
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
currentRoomId: React.PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
/* the MatrixEvent to be forwarded */
|
||||||
|
mxEvent: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
|
onCancelClick: React.PropTypes.func.isRequired,
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillMount: function() {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'ui_opacity',
|
||||||
|
leftOpacity: 1.0,
|
||||||
|
rightOpacity: 0.3,
|
||||||
|
middleOpacity: 0.5,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount: function() {
|
||||||
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
|
document.addEventListener('keydown', this._onKeyDown);
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'ui_opacity',
|
||||||
|
sideOpacity: 1.0,
|
||||||
|
middleOpacity: 1.0,
|
||||||
|
});
|
||||||
|
dis.unregister(this.dispatcherRef);
|
||||||
|
document.removeEventListener('keydown', this._onKeyDown);
|
||||||
|
},
|
||||||
|
|
||||||
|
onAction: function(payload) {
|
||||||
|
if (payload.action === 'view_room') {
|
||||||
|
const event = this.props.mxEvent;
|
||||||
|
const Client = MatrixClientPeg.get();
|
||||||
|
Client.sendEvent(payload.room_id, event.getType(), event.getContent()).done(() => {
|
||||||
|
dis.dispatch({action: 'message_sent'});
|
||||||
|
}, (err) => {
|
||||||
|
if (err.name === "UnknownDeviceError") {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'unknown_device_error',
|
||||||
|
err: err,
|
||||||
|
room: Client.getRoom(payload.room_id),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dis.dispatch({action: 'message_send_failed'});
|
||||||
|
});
|
||||||
|
if (this.props.currentRoomId === payload.room_id) this.props.onCancelClick();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onKeyDown: function(ev) {
|
||||||
|
switch (ev.keyCode) {
|
||||||
|
case KeyCode.ESCAPE:
|
||||||
|
this.props.onCancelClick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div className="mx_ForwardMessage">
|
||||||
|
<h1>Please select the destination room for this message</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
|
@ -189,6 +189,9 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
|
|
||||||
save_button = <AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>Save</AccessibleButton>;
|
save_button = <AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>Save</AccessibleButton>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.onCancelClick) {
|
||||||
cancel_button = <CancelButton onClick={this.props.onCancelClick}/>;
|
cancel_button = <CancelButton onClick={this.props.onCancelClick}/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,13 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var flux = require("flux");
|
const flux = require("flux");
|
||||||
|
|
||||||
class MatrixDispatcher extends flux.Dispatcher {
|
class MatrixDispatcher extends flux.Dispatcher {
|
||||||
/**
|
/**
|
||||||
* @param {Object} payload Required. The payload to dispatch.
|
* @param {Object} payload Required. The payload to dispatch.
|
||||||
* Must contain at least an 'action' key.
|
* Must contain at least an 'action' key.
|
||||||
* @param {boolean} sync Optional. Pass true to dispatch
|
* @param {boolean=} sync Optional. Pass true to dispatch
|
||||||
* synchronously. This is useful for anything triggering
|
* synchronously. This is useful for anything triggering
|
||||||
* an operation that the browser requires user interaction
|
* an operation that the browser requires user interaction
|
||||||
* for.
|
* for.
|
||||||
|
|
Loading…
Reference in a new issue