Fetch scrollback messages earlier, add them when ready
This commit is contained in:
parent
e5c5938414
commit
b6e92d6add
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@ import debounce from 'lodash/debounce';
|
|||||||
import Message from './Message';
|
import Message from './Message';
|
||||||
import { getScrollPos, saveScrollPos } from '../util/scrollPosition';
|
import { getScrollPos, saveScrollPos } from '../util/scrollPosition';
|
||||||
|
|
||||||
const fetchThreshold = 100;
|
const fetchThreshold = 500;
|
||||||
|
|
||||||
export default class MessageBox extends PureComponent {
|
export default class MessageBox extends PureComponent {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -39,6 +39,7 @@ export default class MessageBox extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
this.ready = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,22 +109,33 @@ export default class MessageBox extends PureComponent {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchMore = debounce(() => {
|
fetchMore = () => {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.props.onFetchMore();
|
this.props.onFetchMore();
|
||||||
|
};
|
||||||
|
|
||||||
|
addMore = debounce(() => {
|
||||||
|
const { tab, onAddMore } = this.props;
|
||||||
|
this.ready = true;
|
||||||
|
onAddMore(tab.server, tab.name);
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
handleScroll = ({ scrollTop, clientHeight, scrollHeight }) => {
|
handleScroll = ({ scrollTop, clientHeight, scrollHeight }) => {
|
||||||
if (this.mounted) {
|
if (this.mounted) {
|
||||||
if (this.props.hasMoreMessages &&
|
if (!this.loading &&
|
||||||
|
this.props.hasMoreMessages &&
|
||||||
scrollTop <= fetchThreshold &&
|
scrollTop <= fetchThreshold &&
|
||||||
scrollTop < this.prevScrollTop &&
|
scrollTop < this.prevScrollTop) {
|
||||||
!this.loading) {
|
|
||||||
if (this.mouseDown) {
|
|
||||||
this.shouldFetch = true;
|
|
||||||
} else {
|
|
||||||
this.fetchMore();
|
this.fetchMore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.loading && !this.ready) {
|
||||||
|
if (this.mouseDown) {
|
||||||
|
this.ready = true;
|
||||||
|
this.shouldAdd = true;
|
||||||
|
} else {
|
||||||
|
this.addMore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bottom = scrollTop + clientHeight >= scrollHeight - 10;
|
this.bottom = scrollTop + clientHeight >= scrollHeight - 10;
|
||||||
@ -138,10 +150,10 @@ export default class MessageBox extends PureComponent {
|
|||||||
handleMouseUp = () => {
|
handleMouseUp = () => {
|
||||||
this.mouseDown = false;
|
this.mouseDown = false;
|
||||||
|
|
||||||
if (this.shouldFetch) {
|
if (this.shouldAdd) {
|
||||||
this.shouldFetch = false;
|
const { tab, onAddMore } = this.props;
|
||||||
this.loading = true;
|
this.shouldAdd = false;
|
||||||
this.props.onFetchMore();
|
onAddMore(tab.server, tab.name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ export default class Chat extends Component {
|
|||||||
title,
|
title,
|
||||||
users,
|
users,
|
||||||
|
|
||||||
|
addFetchedMessages,
|
||||||
fetchMessages,
|
fetchMessages,
|
||||||
inputActions,
|
inputActions,
|
||||||
runCommand,
|
runCommand,
|
||||||
@ -79,6 +80,7 @@ export default class Chat extends Component {
|
|||||||
hasMoreMessages={hasMoreMessages}
|
hasMoreMessages={hasMoreMessages}
|
||||||
messages={messages}
|
messages={messages}
|
||||||
tab={tab}
|
tab={tab}
|
||||||
|
onAddMore={addFetchedMessages}
|
||||||
onFetchMore={fetchMessages}
|
onFetchMore={fetchMessages}
|
||||||
onNickClick={this.handleNickClick}
|
onNickClick={this.handleNickClick}
|
||||||
/>
|
/>
|
||||||
|
@ -7,7 +7,7 @@ import { getSelectedChannel, getSelectedChannelUsers, part } from '../state/chan
|
|||||||
import { getCurrentInputHistoryEntry, addInputHistory, resetInputHistory,
|
import { getCurrentInputHistoryEntry, addInputHistory, resetInputHistory,
|
||||||
incrementInputHistory, decrementInputHistory } from '../state/input';
|
incrementInputHistory, decrementInputHistory } from '../state/input';
|
||||||
import { getSelectedMessages, getHasMoreMessages,
|
import { getSelectedMessages, getHasMoreMessages,
|
||||||
runCommand, sendMessage, fetchMessages } from '../state/messages';
|
runCommand, sendMessage, fetchMessages, addFetchedMessages } from '../state/messages';
|
||||||
import { openPrivateChat, closePrivateChat } from '../state/privateChats';
|
import { openPrivateChat, closePrivateChat } from '../state/privateChats';
|
||||||
import { getSearch, searchMessages, toggleSearch } from '../state/search';
|
import { getSearch, searchMessages, toggleSearch } from '../state/search';
|
||||||
import { getCurrentNick, disconnect } from '../state/servers';
|
import { getCurrentNick, disconnect } from '../state/servers';
|
||||||
@ -29,6 +29,7 @@ const mapState = createStructuredSelector({
|
|||||||
|
|
||||||
const mapDispatch = dispatch => ({
|
const mapDispatch = dispatch => ({
|
||||||
...bindActionCreators({
|
...bindActionCreators({
|
||||||
|
addFetchedMessages,
|
||||||
closePrivateChat,
|
closePrivateChat,
|
||||||
disconnect,
|
disconnect,
|
||||||
fetchMessages,
|
fetchMessages,
|
||||||
|
35
client/src/js/middleware/message.js
Normal file
35
client/src/js/middleware/message.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import * as actions from '../state/actions';
|
||||||
|
|
||||||
|
//
|
||||||
|
// This middleware handles waiting until MessageBox
|
||||||
|
// is ready before adding messages to the top
|
||||||
|
//
|
||||||
|
const message = store => next => {
|
||||||
|
const ready = {};
|
||||||
|
const cache = {};
|
||||||
|
|
||||||
|
return action => {
|
||||||
|
if (action.type === actions.ADD_MESSAGES && action.prepend) {
|
||||||
|
const key = `${action.server} ${action.channel}`;
|
||||||
|
|
||||||
|
if (ready[key]) {
|
||||||
|
ready[key] = false;
|
||||||
|
return next(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache[key] = action;
|
||||||
|
} else if (action.type === actions.ADD_FETCHED_MESSAGES) {
|
||||||
|
const key = `${action.server} ${action.channel}`;
|
||||||
|
ready[key] = true;
|
||||||
|
|
||||||
|
if (cache[key]) {
|
||||||
|
store.dispatch(cache[key]);
|
||||||
|
cache[key] = undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return next(action);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default message;
|
@ -11,6 +11,7 @@ export const INPUT_HISTORY_DECREMENT = 'INPUT_HISTORY_DECREMENT';
|
|||||||
export const INPUT_HISTORY_INCREMENT = 'INPUT_HISTORY_INCREMENT';
|
export const INPUT_HISTORY_INCREMENT = 'INPUT_HISTORY_INCREMENT';
|
||||||
export const INPUT_HISTORY_RESET = 'INPUT_HISTORY_RESET';
|
export const INPUT_HISTORY_RESET = 'INPUT_HISTORY_RESET';
|
||||||
|
|
||||||
|
export const ADD_FETCHED_MESSAGES = 'ADD_FETCHED_MESSAGES';
|
||||||
export const ADD_MESSAGE = 'ADD_MESSAGE';
|
export const ADD_MESSAGE = 'ADD_MESSAGE';
|
||||||
export const ADD_MESSAGES = 'ADD_MESSAGES';
|
export const ADD_MESSAGES = 'ADD_MESSAGES';
|
||||||
export const COMMAND = 'COMMAND';
|
export const COMMAND = 'COMMAND';
|
||||||
|
@ -152,6 +152,14 @@ export function fetchMessages() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addFetchedMessages(server, tab) {
|
||||||
|
return {
|
||||||
|
type: actions.ADD_FETCHED_MESSAGES,
|
||||||
|
server,
|
||||||
|
tab
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function updateMessageHeight(wrapWidth, charWidth, windowWidth) {
|
export function updateMessageHeight(wrapWidth, charWidth, windowWidth) {
|
||||||
return {
|
return {
|
||||||
type: actions.UPDATE_MESSAGE_HEIGHT,
|
type: actions.UPDATE_MESSAGE_HEIGHT,
|
||||||
|
@ -2,6 +2,7 @@ import { createStore, applyMiddleware, compose } from 'redux';
|
|||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
import createReducer from './state';
|
import createReducer from './state';
|
||||||
import { routeReducer, routeMiddleware } from './util/router';
|
import { routeReducer, routeMiddleware } from './util/router';
|
||||||
|
import message from './middleware/message';
|
||||||
import createSocketMiddleware from './middleware/socket';
|
import createSocketMiddleware from './middleware/socket';
|
||||||
import commands from './commands';
|
import commands from './commands';
|
||||||
|
|
||||||
@ -13,9 +14,10 @@ export default function configureStore(socket) {
|
|||||||
|
|
||||||
const store = createStore(reducer, composeEnhancers(
|
const store = createStore(reducer, composeEnhancers(
|
||||||
applyMiddleware(
|
applyMiddleware(
|
||||||
routeMiddleware,
|
|
||||||
thunk,
|
thunk,
|
||||||
|
routeMiddleware,
|
||||||
createSocketMiddleware(socket),
|
createSocketMiddleware(socket),
|
||||||
|
message,
|
||||||
commands
|
commands
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
Loading…
Reference in New Issue
Block a user