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 { getScrollPos, saveScrollPos } from '../util/scrollPosition';
|
||||
|
||||
const fetchThreshold = 100;
|
||||
const fetchThreshold = 500;
|
||||
|
||||
export default class MessageBox extends PureComponent {
|
||||
componentWillMount() {
|
||||
@ -39,6 +39,7 @@ export default class MessageBox extends PureComponent {
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
this.ready = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,22 +109,33 @@ export default class MessageBox extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
fetchMore = debounce(() => {
|
||||
fetchMore = () => {
|
||||
this.loading = true;
|
||||
this.props.onFetchMore();
|
||||
};
|
||||
|
||||
addMore = debounce(() => {
|
||||
const { tab, onAddMore } = this.props;
|
||||
this.ready = true;
|
||||
onAddMore(tab.server, tab.name);
|
||||
}, 100);
|
||||
|
||||
handleScroll = ({ scrollTop, clientHeight, scrollHeight }) => {
|
||||
if (this.mounted) {
|
||||
if (this.props.hasMoreMessages &&
|
||||
if (!this.loading &&
|
||||
this.props.hasMoreMessages &&
|
||||
scrollTop <= fetchThreshold &&
|
||||
scrollTop < this.prevScrollTop &&
|
||||
!this.loading) {
|
||||
if (this.mouseDown) {
|
||||
this.shouldFetch = true;
|
||||
} else {
|
||||
scrollTop < this.prevScrollTop) {
|
||||
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;
|
||||
@ -138,10 +150,10 @@ export default class MessageBox extends PureComponent {
|
||||
handleMouseUp = () => {
|
||||
this.mouseDown = false;
|
||||
|
||||
if (this.shouldFetch) {
|
||||
this.shouldFetch = false;
|
||||
this.loading = true;
|
||||
this.props.onFetchMore();
|
||||
if (this.shouldAdd) {
|
||||
const { tab, onAddMore } = this.props;
|
||||
this.shouldAdd = false;
|
||||
onAddMore(tab.server, tab.name);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -44,6 +44,7 @@ export default class Chat extends Component {
|
||||
title,
|
||||
users,
|
||||
|
||||
addFetchedMessages,
|
||||
fetchMessages,
|
||||
inputActions,
|
||||
runCommand,
|
||||
@ -79,6 +80,7 @@ export default class Chat extends Component {
|
||||
hasMoreMessages={hasMoreMessages}
|
||||
messages={messages}
|
||||
tab={tab}
|
||||
onAddMore={addFetchedMessages}
|
||||
onFetchMore={fetchMessages}
|
||||
onNickClick={this.handleNickClick}
|
||||
/>
|
||||
|
@ -7,7 +7,7 @@ import { getSelectedChannel, getSelectedChannelUsers, part } from '../state/chan
|
||||
import { getCurrentInputHistoryEntry, addInputHistory, resetInputHistory,
|
||||
incrementInputHistory, decrementInputHistory } from '../state/input';
|
||||
import { getSelectedMessages, getHasMoreMessages,
|
||||
runCommand, sendMessage, fetchMessages } from '../state/messages';
|
||||
runCommand, sendMessage, fetchMessages, addFetchedMessages } from '../state/messages';
|
||||
import { openPrivateChat, closePrivateChat } from '../state/privateChats';
|
||||
import { getSearch, searchMessages, toggleSearch } from '../state/search';
|
||||
import { getCurrentNick, disconnect } from '../state/servers';
|
||||
@ -29,6 +29,7 @@ const mapState = createStructuredSelector({
|
||||
|
||||
const mapDispatch = dispatch => ({
|
||||
...bindActionCreators({
|
||||
addFetchedMessages,
|
||||
closePrivateChat,
|
||||
disconnect,
|
||||
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_RESET = 'INPUT_HISTORY_RESET';
|
||||
|
||||
export const ADD_FETCHED_MESSAGES = 'ADD_FETCHED_MESSAGES';
|
||||
export const ADD_MESSAGE = 'ADD_MESSAGE';
|
||||
export const ADD_MESSAGES = 'ADD_MESSAGES';
|
||||
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) {
|
||||
return {
|
||||
type: actions.UPDATE_MESSAGE_HEIGHT,
|
||||
|
@ -2,6 +2,7 @@ import { createStore, applyMiddleware, compose } from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
import createReducer from './state';
|
||||
import { routeReducer, routeMiddleware } from './util/router';
|
||||
import message from './middleware/message';
|
||||
import createSocketMiddleware from './middleware/socket';
|
||||
import commands from './commands';
|
||||
|
||||
@ -13,9 +14,10 @@ export default function configureStore(socket) {
|
||||
|
||||
const store = createStore(reducer, composeEnhancers(
|
||||
applyMiddleware(
|
||||
routeMiddleware,
|
||||
thunk,
|
||||
routeMiddleware,
|
||||
createSocketMiddleware(socket),
|
||||
message,
|
||||
commands
|
||||
)
|
||||
));
|
||||
|
Loading…
Reference in New Issue
Block a user