Merge branch 'experimental' of github.com:matrix-org/matrix-react-sdk into erikj/state_counters
This commit is contained in:
commit
cbf9ff6aee
58 changed files with 1168 additions and 320 deletions
|
@ -39,7 +39,6 @@ import Unread from '../../../Unread';
|
|||
import { findReadReceiptFromUserId } from '../../../utils/Receipt';
|
||||
import withMatrixClient from '../../../wrappers/withMatrixClient';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||
import SdkConfig from '../../../SdkConfig';
|
||||
import MultiInviter from "../../../utils/MultiInviter";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
@ -50,6 +49,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
propTypes: {
|
||||
matrixClient: PropTypes.object.isRequired,
|
||||
member: PropTypes.object.isRequired,
|
||||
roomId: PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -713,8 +713,8 @@ module.exports = withMatrixClient(React.createClass({
|
|||
}
|
||||
|
||||
if (!member || !member.membership || member.membership === 'leave') {
|
||||
const roomId = member && member.roomId ? member.roomId : RoomViewStore.getRoomId();
|
||||
const onInviteUserButton = async() => {
|
||||
const roomId = member && member.roomId ? member.roomId : this.props.roomId;
|
||||
const onInviteUserButton = async () => {
|
||||
try {
|
||||
// We use a MultiInviter to re-use the invite logic, even though
|
||||
// we're only inviting one user.
|
||||
|
|
|
@ -22,7 +22,6 @@ import MatrixClientPeg from '../../../MatrixClientPeg';
|
|||
import Modal from '../../../Modal';
|
||||
import sdk from '../../../index';
|
||||
import dis from '../../../dispatcher';
|
||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import Stickerpicker from './Stickerpicker';
|
||||
import { makeRoomPermalink } from '../../../matrix-to';
|
||||
|
@ -63,7 +62,7 @@ export default class MessageComposer extends React.Component {
|
|||
isRichTextEnabled: SettingsStore.getValue('MessageComposerInput.isRichTextEnabled'),
|
||||
},
|
||||
showFormatting: SettingsStore.getValue('MessageComposer.showFormatting'),
|
||||
isQuoting: Boolean(RoomViewStore.getQuotingEvent()),
|
||||
isQuoting: Boolean(this.props.roomViewStore.getQuotingEvent()),
|
||||
tombstone: this._getRoomTombstone(),
|
||||
};
|
||||
}
|
||||
|
@ -75,7 +74,7 @@ export default class MessageComposer extends React.Component {
|
|||
// XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something.
|
||||
MatrixClientPeg.get().on("event", this.onEvent);
|
||||
MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents);
|
||||
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
this._roomStoreToken = this.props.roomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
this._waitForOwnMember();
|
||||
}
|
||||
|
||||
|
@ -124,14 +123,14 @@ export default class MessageComposer extends React.Component {
|
|||
}
|
||||
|
||||
_onRoomViewStoreUpdate() {
|
||||
const isQuoting = Boolean(RoomViewStore.getQuotingEvent());
|
||||
const isQuoting = Boolean(this.props.roomViewStore.getQuotingEvent());
|
||||
if (this.state.isQuoting === isQuoting) return;
|
||||
this.setState({ isQuoting });
|
||||
}
|
||||
|
||||
onUploadClick(ev) {
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
dis.dispatch({action: 'require_registration'});
|
||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'require_registration'});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -165,7 +164,7 @@ export default class MessageComposer extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const isQuoting = Boolean(RoomViewStore.getQuotingEvent());
|
||||
const isQuoting = Boolean(this.props.roomViewStore.getQuotingEvent());
|
||||
let replyToWarning = null;
|
||||
if (isQuoting) {
|
||||
replyToWarning = <p>{
|
||||
|
@ -229,7 +228,7 @@ export default class MessageComposer extends React.Component {
|
|||
if (!call) {
|
||||
return;
|
||||
}
|
||||
dis.dispatch({
|
||||
this.props.roomViewStore.getDispatcher().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)
|
||||
|
@ -238,7 +237,7 @@ export default class MessageComposer extends React.Component {
|
|||
}
|
||||
|
||||
onCallClick(ev) {
|
||||
dis.dispatch({
|
||||
this.props.roomViewStore.getDispatcher().dispatch({
|
||||
action: 'place_call',
|
||||
type: ev.shiftKey ? "screensharing" : "video",
|
||||
room_id: this.props.room.roomId,
|
||||
|
@ -246,7 +245,7 @@ export default class MessageComposer extends React.Component {
|
|||
}
|
||||
|
||||
onVoiceCallClick(ev) {
|
||||
dis.dispatch({
|
||||
this.props.roomViewStore.getDispatcher().dispatch({
|
||||
action: 'place_call',
|
||||
type: "voice",
|
||||
room_id: this.props.room.roomId,
|
||||
|
@ -282,7 +281,7 @@ export default class MessageComposer extends React.Component {
|
|||
ev.preventDefault();
|
||||
|
||||
const replacementRoomId = this.state.tombstone.getContent()['replacement_room'];
|
||||
dis.dispatch({
|
||||
this.props.roomViewStore.getDispatcher().dispatch({
|
||||
action: 'view_room',
|
||||
highlighted: true,
|
||||
room_id: replacementRoomId,
|
||||
|
@ -421,8 +420,10 @@ export default class MessageComposer extends React.Component {
|
|||
|
||||
controls.push(
|
||||
<MessageComposerInput
|
||||
roomViewStore={this.props.roomViewStore}
|
||||
ref={(c) => this.messageComposerInput = c}
|
||||
key="controls_input"
|
||||
isGrid={this.props.isGrid}
|
||||
onResize={this.props.onResize}
|
||||
room={this.props.room}
|
||||
placeholder={placeholderText}
|
||||
|
@ -529,5 +530,6 @@ MessageComposer.propTypes = {
|
|||
uploadAllowed: PropTypes.func.isRequired,
|
||||
|
||||
// string representing the current room app drawer state
|
||||
showApps: PropTypes.bool
|
||||
showApps: PropTypes.bool,
|
||||
roomViewStore: PropTypes.object.isRequired,
|
||||
};
|
||||
|
|
|
@ -41,8 +41,6 @@ import sdk from '../../../index';
|
|||
import { _t, _td } from '../../../languageHandler';
|
||||
import Analytics from '../../../Analytics';
|
||||
|
||||
import dis from '../../../dispatcher';
|
||||
|
||||
import * as RichText from '../../../RichText';
|
||||
import * as HtmlUtils from '../../../HtmlUtils';
|
||||
import Autocomplete from './Autocomplete';
|
||||
|
@ -58,7 +56,6 @@ import {asciiRegexp, unicodeRegexp, shortnameToUnicode, emojioneList, asciiList,
|
|||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import {makeUserPermalink} from "../../../matrix-to";
|
||||
import ReplyPreview from "./ReplyPreview";
|
||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||
import ReplyThread from "../elements/ReplyThread";
|
||||
import {ContentHelpers} from 'matrix-js-sdk';
|
||||
|
||||
|
@ -121,7 +118,7 @@ function onSendMessageFailed(err, room) {
|
|||
// XXX: temporary logging to try to diagnose
|
||||
// https://github.com/vector-im/riot-web/issues/3148
|
||||
console.log('MessageComposer got send failure: ' + err.name + '('+err+')');
|
||||
dis.dispatch({
|
||||
this.props.roomViewStore.getDispatcher().dispatch({
|
||||
action: 'message_send_failed',
|
||||
});
|
||||
}
|
||||
|
@ -135,6 +132,18 @@ function rangeEquals(a: Range, b: Range): boolean {
|
|||
&& a.isBackward === b.isBackward);
|
||||
}
|
||||
|
||||
class NoopHistoryManager {
|
||||
getItem() {}
|
||||
save() {}
|
||||
|
||||
get currentIndex() { return 0; }
|
||||
set currentIndex(_) {}
|
||||
|
||||
get history() { return []; }
|
||||
set history(_) {}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The textInput part of the MessageComposer
|
||||
*/
|
||||
|
@ -150,6 +159,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
onFilesPasted: PropTypes.func,
|
||||
|
||||
onInputStateChanged: PropTypes.func,
|
||||
roomViewStore: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
client: MatrixClient;
|
||||
|
@ -344,12 +354,16 @@ export default class MessageComposerInput extends React.Component {
|
|||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
this.historyManager = new ComposerHistoryManager(this.props.room.roomId, 'mx_slate_composer_history_');
|
||||
this.dispatcherRef = this.props.roomViewStore.getDispatcher().register(this.onAction);
|
||||
if (this.props.isGrid) {
|
||||
this.historyManager = new NoopHistoryManager();
|
||||
} else {
|
||||
this.historyManager = new ComposerHistoryManager(this.props.room.roomId, 'mx_slate_composer_history_');
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
this.props.roomViewStore.getDispatcher().unregister(this.dispatcherRef);
|
||||
}
|
||||
|
||||
_collectEditor = (e) => {
|
||||
|
@ -1120,7 +1134,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
return true;
|
||||
}
|
||||
|
||||
const replyingToEv = RoomViewStore.getQuotingEvent();
|
||||
const replyingToEv = this.props.roomViewStore.getQuotingEvent();
|
||||
const mustSendHTML = Boolean(replyingToEv);
|
||||
|
||||
if (this.state.isRichTextEnabled) {
|
||||
|
@ -1208,14 +1222,14 @@ export default class MessageComposerInput extends React.Component {
|
|||
|
||||
// Clear reply_to_event as we put the message into the queue
|
||||
// if the send fails, retry will handle resending.
|
||||
dis.dispatch({
|
||||
this.props.roomViewStore.getDispatcher().dispatch({
|
||||
action: 'reply_to_event',
|
||||
event: null,
|
||||
});
|
||||
}
|
||||
|
||||
this.client.sendMessage(this.props.room.roomId, content).then((res) => {
|
||||
dis.dispatch({
|
||||
this.props.roomViewStore.getDispatcher().dispatch({
|
||||
action: 'message_sent',
|
||||
});
|
||||
}).catch((e) => {
|
||||
|
@ -1260,7 +1274,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
}
|
||||
};
|
||||
|
||||
selectHistory = async(up) => {
|
||||
selectHistory = async (up) => {
|
||||
const delta = up ? -1 : 1;
|
||||
|
||||
// True if we are not currently selecting history, but composing a message
|
||||
|
@ -1308,7 +1322,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
return true;
|
||||
};
|
||||
|
||||
onTab = async(e) => {
|
||||
onTab = async (e) => {
|
||||
this.setState({
|
||||
someCompletions: null,
|
||||
});
|
||||
|
@ -1330,7 +1344,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
up ? this.autocomplete.onUpArrow() : this.autocomplete.onDownArrow();
|
||||
};
|
||||
|
||||
onEscape = async(e) => {
|
||||
onEscape = async (e) => {
|
||||
e.preventDefault();
|
||||
if (this.autocomplete) {
|
||||
this.autocomplete.onEscape(e);
|
||||
|
@ -1349,7 +1363,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
/* If passed null, restores the original editor content from state.originalEditorState.
|
||||
* If passed a non-null displayedCompletion, modifies state.originalEditorState to compute new state.editorState.
|
||||
*/
|
||||
setDisplayedCompletion = async(displayedCompletion: ?Completion): boolean => {
|
||||
setDisplayedCompletion = async (displayedCompletion: ?Completion): boolean => {
|
||||
const activeEditorState = this.state.originalEditorState || this.state.editorState;
|
||||
|
||||
if (displayedCompletion == null) {
|
||||
|
@ -1589,7 +1603,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
return (
|
||||
<div className="mx_MessageComposer_input_wrapper" onClick={this.focusComposer}>
|
||||
<div className="mx_MessageComposer_autocomplete_wrapper">
|
||||
<ReplyPreview />
|
||||
<ReplyPreview roomViewStore={this.props.roomViewStore} />
|
||||
<Autocomplete
|
||||
ref={(e) => this.autocomplete = e}
|
||||
room={this.props.room}
|
||||
|
|
|
@ -18,7 +18,6 @@ import React from 'react';
|
|||
import dis from '../../../dispatcher';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
||||
function cancelQuoting() {
|
||||
|
@ -38,7 +37,7 @@ export default class ReplyPreview extends React.Component {
|
|||
|
||||
this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this);
|
||||
|
||||
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
this._roomStoreToken = this.props.roomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
this._onRoomViewStoreUpdate();
|
||||
}
|
||||
|
||||
|
@ -50,7 +49,7 @@ export default class ReplyPreview extends React.Component {
|
|||
}
|
||||
|
||||
_onRoomViewStoreUpdate() {
|
||||
const event = RoomViewStore.getQuotingEvent();
|
||||
const event = this.props.roomViewStore.getQuotingEvent();
|
||||
if (this.state.event !== event) {
|
||||
this.setState({ event });
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { _t } from '../../../languageHandler';
|
|||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import Modal from "../../../Modal";
|
||||
import RateLimitedFunc from '../../../ratelimitedfunc';
|
||||
import dis from '../../../dispatcher';
|
||||
|
||||
import * as linkify from 'linkifyjs';
|
||||
import linkifyElement from 'linkifyjs/element';
|
||||
|
@ -152,6 +153,14 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
onToggleRightPanelClick: function(ev) {
|
||||
if (this.props.collapsedRhs) {
|
||||
dis.dispatch({action: "show_right_panel"});
|
||||
} else {
|
||||
dis.dispatch({action: "hide_right_panel"});
|
||||
}
|
||||
},
|
||||
|
||||
_hasUnreadPins: function() {
|
||||
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
|
||||
if (!currentPinEvent) return false;
|
||||
|
@ -409,6 +418,17 @@ module.exports = React.createClass({
|
|||
</div>;
|
||||
}
|
||||
|
||||
let toggleRightPanelButton;
|
||||
if (this.props.isGrid) {
|
||||
toggleRightPanelButton =
|
||||
<AccessibleButton
|
||||
className="mx_RoomHeader_button"
|
||||
onClick={this.onToggleRightPanelClick}
|
||||
title={_t('Toggle right panel')}>
|
||||
<TintableSvg src="img/feather-icons/toggle-right-panel.svg" width="20" height="20" />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={"mx_RoomHeader light-panel " + (this.props.editing ? "mx_RoomHeader_editing" : "")}>
|
||||
<div className="mx_RoomHeader_wrapper">
|
||||
|
@ -419,7 +439,8 @@ module.exports = React.createClass({
|
|||
{ saveButton }
|
||||
{ cancelButton }
|
||||
{ rightRow }
|
||||
<RoomHeaderButtons collapsedRhs={this.props.collapsedRhs} />
|
||||
{ !this.props.isGrid ? <RoomHeaderButtons collapsedRhs={this.props.collapsedRhs} /> : undefined }
|
||||
{ toggleRightPanelButton }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2018, 2019 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -20,10 +20,16 @@ import sdk from "../../../index";
|
|||
import { _t } from "../../../languageHandler";
|
||||
import Modal from "../../../Modal";
|
||||
import MatrixClientPeg from "../../../MatrixClientPeg";
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
|
||||
export default class RoomRecoveryReminder extends React.PureComponent {
|
||||
static propTypes = {
|
||||
onFinished: PropTypes.func.isRequired,
|
||||
// called if the user sets the option to suppress this reminder in the future
|
||||
onDontAskAgainSet: PropTypes.func,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
onDontAskAgainSet: function() {},
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -82,7 +88,6 @@ export default class RoomRecoveryReminder extends React.PureComponent {
|
|||
Modal.createTrackedDialog('Device Verify Dialog', '', DeviceVerifyDialog, {
|
||||
userId: MatrixClientPeg.get().credentials.userId,
|
||||
device: this.state.unverifiedDevice,
|
||||
onFinished: this.props.onFinished,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -91,9 +96,6 @@ export default class RoomRecoveryReminder extends React.PureComponent {
|
|||
// we'll show the create key backup flow.
|
||||
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
|
||||
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"),
|
||||
{
|
||||
onFinished: this.props.onFinished,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -103,10 +105,14 @@ export default class RoomRecoveryReminder extends React.PureComponent {
|
|||
Modal.createTrackedDialogAsync("Ignore Recovery Reminder", "Ignore Recovery Reminder",
|
||||
import("../../../async-components/views/dialogs/keybackup/IgnoreRecoveryReminderDialog"),
|
||||
{
|
||||
onDontAskAgain: () => {
|
||||
// Report false to the caller, who should prevent the
|
||||
// reminder from appearing in the future.
|
||||
this.props.onFinished(false);
|
||||
onDontAskAgain: async () => {
|
||||
await SettingsStore.setValue(
|
||||
"showRoomRecoveryReminder",
|
||||
null,
|
||||
SettingLevel.ACCOUNT,
|
||||
false,
|
||||
);
|
||||
this.props.onDontAskAgainSet();
|
||||
},
|
||||
onSetup: () => {
|
||||
this.showSetupDialog();
|
||||
|
|
|
@ -29,7 +29,6 @@ import * as RoomNotifs from '../../../RoomNotifs';
|
|||
import * as FormattingUtils from '../../../utils/FormattingUtils';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import ActiveRoomObserver from '../../../ActiveRoomObserver';
|
||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -62,7 +61,7 @@ module.exports = React.createClass({
|
|||
roomName: this.props.room.name,
|
||||
notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId),
|
||||
notificationCount: this.props.room.getUnreadNotificationCount(),
|
||||
selected: this.props.room.roomId === RoomViewStore.getRoomId(),
|
||||
selected: this.props.room.roomId === ActiveRoomObserver.getActiveRoomId(),
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -117,9 +116,9 @@ module.exports = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
_onActiveRoomChange: function() {
|
||||
_onActiveRoomChange: function(activeRoomId) {
|
||||
this.setState({
|
||||
selected: this.props.room.roomId === RoomViewStore.getRoomId(),
|
||||
selected: this.props.room.roomId === activeRoomId,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue