mirror of https://github.com/vector-im/riot-web
Implement MessageComposerStore to persist composer state across room switching
This behaviour was present in the old composer but implemented using local storage. This is unecessary as we don't really care about our drafts across clients, the important thing is that our draft is kept when switching rooms. As a bonus, ifnore vertical arrow key presses when a modifier key is pressed so that the room switching keys (alt + up/down arrow) don't also cause history browsing (or autocomplete browsing).pull/21833/head
parent
0af77e8913
commit
084a933dbd
|
@ -43,6 +43,8 @@ import Markdown from '../../../Markdown';
|
|||
import ComposerHistoryManager from '../../../ComposerHistoryManager';
|
||||
import {onSendMessageFailed} from './MessageComposerInputOld';
|
||||
|
||||
import MessageComposerStore from '../../../stores/MessageComposerStore';
|
||||
|
||||
const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000;
|
||||
|
||||
const ZWS_CODE = 8203;
|
||||
|
@ -170,6 +172,11 @@ export default class MessageComposerInput extends React.Component {
|
|||
componentDidMount() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
this.historyManager = new ComposerHistoryManager(this.props.room.roomId);
|
||||
|
||||
// Reinstate the editor state for this room
|
||||
this.setState({
|
||||
editorState: MessageComposerStore.getEditorState(this.props.room.roomId),
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -336,6 +343,14 @@ export default class MessageComposerInput extends React.Component {
|
|||
this.onFinishedTyping();
|
||||
}
|
||||
|
||||
// Record the editor state for this room so that it can be retrieved after
|
||||
// switching to another room and back
|
||||
dis.dispatch({
|
||||
action: 'editor_state',
|
||||
room_id: this.props.room.roomId,
|
||||
editor_state: state.editorState,
|
||||
});
|
||||
|
||||
if (!state.hasOwnProperty('originalEditorState')) {
|
||||
state.originalEditorState = null;
|
||||
}
|
||||
|
@ -632,6 +647,10 @@ export default class MessageComposerInput extends React.Component {
|
|||
};
|
||||
|
||||
onVerticalArrow = (e, up) => {
|
||||
if (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Select history only if we are not currently auto-completing
|
||||
if (this.autocomplete.state.completionList.length === 0) {
|
||||
// Don't go back in history if we're in the middle of a multi-line message
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations 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.
|
||||
*/
|
||||
import dis from '../dispatcher';
|
||||
import {Store} from 'flux/utils';
|
||||
|
||||
const INITIAL_STATE = {
|
||||
editorStateMap: {},
|
||||
};
|
||||
|
||||
/**
|
||||
* A class for storing application state to do with the message composer. This is a simple
|
||||
* flux store that listens for actions and updates its state accordingly, informing any
|
||||
* listeners (views) of state changes.
|
||||
*/
|
||||
class MessageComposerStore extends Store {
|
||||
constructor() {
|
||||
super(dis);
|
||||
|
||||
// Initialise state
|
||||
this._state = INITIAL_STATE;
|
||||
}
|
||||
|
||||
_setState(newState) {
|
||||
this._state = Object.assign(this._state, newState);
|
||||
this.__emitChange();
|
||||
}
|
||||
|
||||
__onDispatch(payload) {
|
||||
switch (payload.action) {
|
||||
case 'editor_state':
|
||||
this._editorState(payload);
|
||||
break;
|
||||
case 'on_logged_out':
|
||||
this.reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_editorState(payload) {
|
||||
const editorStateMap = this._state.editorStateMap;
|
||||
editorStateMap[payload.room_id] = payload.editor_state;
|
||||
this._setState({
|
||||
editorStateMap: editorStateMap,
|
||||
});
|
||||
}
|
||||
|
||||
getEditorState(roomId) {
|
||||
return this._state.editorStateMap[roomId];
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._state = Object.assign({}, INITIAL_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
let singletonMessageComposerStore = null;
|
||||
if (!singletonMessageComposerStore) {
|
||||
singletonMessageComposerStore = new MessageComposerStore();
|
||||
}
|
||||
module.exports = singletonMessageComposerStore;
|
Loading…
Reference in New Issue