diff --git a/frontend/src/components/pages/main/ChannelView.svelte b/frontend/src/components/pages/main/ChannelView.svelte index cab88f7..f5824d2 100644 --- a/frontend/src/components/pages/main/ChannelView.svelte +++ b/frontend/src/components/pages/main/ChannelView.svelte @@ -49,7 +49,7 @@ import Messages from "./Messages.svelte"; { channel.name } - +
diff --git a/frontend/src/components/pages/main/Messages.svelte b/frontend/src/components/pages/main/Messages.svelte index d2a2ded..788df5a 100644 --- a/frontend/src/components/pages/main/Messages.svelte +++ b/frontend/src/components/pages/main/Messages.svelte @@ -3,16 +3,22 @@ export let channelId; - const messages = messagesStoreProvider.getStore(channelId); - if (!messages.didInitialLoad) - messages.doInitialLoad(); + $: 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); } }; diff --git a/frontend/src/main.js b/frontend/src/main.js index 5f0c8a7..d695566 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -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 }); diff --git a/frontend/src/request.js b/frontend/src/request.js index e1ac6d5..9b15169 100644 --- a/frontend/src/request.js +++ b/frontend/src/request.js @@ -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" diff --git a/frontend/src/stores.js b/frontend/src/stores.js index 647ce1c..8e11a7d 100644 --- a/frontend/src/stores.js +++ b/frontend/src/stores.js @@ -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); } } diff --git a/test.rest b/test.rest index 2c263be..7830699 100644 --- a/test.rest +++ b/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