Fetch scrollback messages earlier, add them when ready

This commit is contained in:
Ken-Håvard Lieng 2017-06-07 00:04:37 +02:00
parent e5c5938414
commit b6e92d6add
8 changed files with 93 additions and 32 deletions

File diff suppressed because one or more lines are too long

View File

@ -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,21 +109,32 @@ 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) {
scrollTop < this.prevScrollTop) {
this.fetchMore();
}
if (this.loading && !this.ready) {
if (this.mouseDown) {
this.shouldFetch = true;
this.ready = true;
this.shouldAdd = true;
} else {
this.fetchMore();
this.addMore();
}
}
@ -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);
}
};

View File

@ -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}
/>

View File

@ -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,

View 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;

View File

@ -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';

View File

@ -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,

View File

@ -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
)
));