frontend: message loading
This command finalizes support for dynamic message loading. The behavior is as follows: When a user selects a channel for the first time, an "initial load" of messages will happen. When the user is scrolled all the way to the bottom of the message view, the store will continuously remove old messages to save memory. Scrolling all the way to the top loads more messages.
This commit is contained in:
parent
da7e57fe82
commit
7260525eec
6 changed files with 38 additions and 21 deletions
|
@ -49,7 +49,7 @@ import Messages from "./Messages.svelte";
|
|||
<HashIcon />
|
||||
<span class="h5 channel-heading">{ channel.name }</span>
|
||||
</div>
|
||||
<Messages channelId={ channel.id } />
|
||||
<Messages channelId="{ channel.id }" />
|
||||
<div class="message-input-container">
|
||||
<input type="text" class="message-input">
|
||||
</div>
|
||||
|
|
|
@ -3,16 +3,22 @@
|
|||
|
||||
export let channelId;
|
||||
|
||||
const messages = messagesStoreProvider.getStore(channelId);
|
||||
if (!messages.didInitialLoad)
|
||||
$: messages = messagesStoreProvider.getStore(channelId);
|
||||
$: {
|
||||
if (!messages.didDoInitialLoad) {
|
||||
messages.doInitialLoad();
|
||||
}
|
||||
}
|
||||
|
||||
const onScroll = (e) => {
|
||||
const { scrollTop, offsetHeight, scrollHeight } = e.target;
|
||||
if (scrollTop === 0) {
|
||||
messages.loadOlderMessages();
|
||||
}
|
||||
if ((scrollTop + offsetHeight) >= scrollHeight) {
|
||||
setIsCollectingOldMessages(true);
|
||||
messages.setIsCollectingOldMessages(true);
|
||||
} else {
|
||||
setIsCollectingOldMessages(false);
|
||||
messages.setIsCollectingOldMessages(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import App from './components/App.svelte';
|
||||
import gateway from './gateway';
|
||||
import { initStorageDefaults } from './storage';
|
||||
import request from './request';
|
||||
import { apiRoute, initStorageDefaults } from './storage';
|
||||
|
||||
initStorageDefaults();
|
||||
gateway.init();
|
||||
|
@ -11,6 +12,14 @@ if (loadingElement) {
|
|||
loadingElement.parentElement.removeChild(loadingElement);
|
||||
}
|
||||
|
||||
window.__testing = async () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
await request("POST", apiRoute("channels/6/messages"), true, {
|
||||
content: `test ${i}`
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const app = new App({
|
||||
target: document.body
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ export default async function(method, endpoint, auth=true, body=null) {
|
|||
};
|
||||
|
||||
if (body) {
|
||||
options.body = JSON.stringify(body);
|
||||
options.headers = {
|
||||
...options.headers || {},
|
||||
"Content-Type": "application/json"
|
||||
|
|
|
@ -141,6 +141,7 @@ class MessageStore extends Store {
|
|||
const endpoint = oldestMessage ? `channels/${this.channelId}/messages/?before=${oldestMessage.id}` : `channels/${this.channelId}/messages`;
|
||||
const res = await request("GET", apiRoute(endpoint), true, null);
|
||||
if (res.success && res.ok && res.json && res.json.length > 0) {
|
||||
res.json.reverse();
|
||||
this.value = res.json.concat(this.value);
|
||||
this.updated();
|
||||
}
|
||||
|
@ -168,10 +169,10 @@ class MessagesStoreProvider {
|
|||
}
|
||||
|
||||
getStore(channelId) {
|
||||
if (!this.storeByChannel[channelId]) {
|
||||
this.storeByChannel[channelId] = new MessageStore(channelId);
|
||||
if (!this.storeByChannel.get(channelId)) {
|
||||
this.storeByChannel.set(channelId, new MessageStore(channelId));
|
||||
}
|
||||
return this.storeByChannel[channelId];
|
||||
return this.storeByChannel.get(channelId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
22
test.rest
22
test.rest
|
@ -19,13 +19,13 @@ content-type: application/json
|
|||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/users/self HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
###
|
||||
|
||||
POST http://localhost:3000/api/v1/channels HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
{
|
||||
"name": "channel 4"
|
||||
|
@ -35,7 +35,7 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6M
|
|||
|
||||
PUT http://localhost:3000/api/v1/channels/7 HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
#Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5MjU5NDUwLCJleHAiOjE2NDk0MzIyNTB9.JmF9NujFZnln7A-ynNpeyayGBqmR5poAyACYV6RnSQY
|
||||
|
||||
{
|
||||
|
@ -45,24 +45,24 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6M
|
|||
###
|
||||
|
||||
DELETE http://localhost:3000/api/v1/channels/9 HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
#Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5MjU5NDUwLCJleHAiOjE2NDk0MzIyNTB9.JmF9NujFZnln7A-ynNpeyayGBqmR5poAyACYV6RnSQY
|
||||
|
||||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/channels/1 HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/channels HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
###
|
||||
|
||||
POST http://localhost:3000/api/v1/channels/1/messages HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
{
|
||||
"content": "i love cheese"
|
||||
|
@ -71,13 +71,13 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6M
|
|||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/channels/5/messages HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
###
|
||||
|
||||
PUT http://localhost:3000/api/v1/messages/3 HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
{
|
||||
"content": "hello again!"
|
||||
|
@ -86,9 +86,9 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6M
|
|||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/messages/3
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
||||
###
|
||||
|
||||
DELETE http://localhost:3000/api/v1/messages/2 HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwMzg2NjcyLCJleHAiOjE2NTA1NTk0NzJ9.qoBPvIwm9uFf5ZhEjlo87FUgm3qsCHq-AbcZ_WDrtWY
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwNDA4NTQ1LCJleHAiOjE2NTA1ODEzNDV9.DCt_IpukPaihSGl1N8a5ve5pd75N4aePxR4YKzw98Ss
|
||||
|
|
Loading…
Reference in a new issue