Channel.svelte 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <script lang="ts">
  2. import { getChannelMessages, sendMessage } from '$lib/apis/channels';
  3. import { toast } from 'svelte-sonner';
  4. import MessageInput from './MessageInput.svelte';
  5. import Messages from './Messages.svelte';
  6. import { socket } from '$lib/stores';
  7. import { onDestroy, onMount, tick } from 'svelte';
  8. export let id = '';
  9. let scrollEnd = true;
  10. let messagesContainerElement = null;
  11. let top = false;
  12. let page = 1;
  13. let messages = null;
  14. $: if (id) {
  15. initHandler();
  16. }
  17. const initHandler = async () => {
  18. top = false;
  19. page = 1;
  20. messages = null;
  21. messages = await getChannelMessages(localStorage.token, id, page);
  22. if (messages.length < 50) {
  23. top = true;
  24. }
  25. };
  26. const channelEventHandler = async (data) => {
  27. console.log(data);
  28. };
  29. const submitHandler = async ({ content }) => {
  30. if (!content) {
  31. return;
  32. }
  33. const res = await sendMessage(localStorage.token, id, { content: content }).catch((error) => {
  34. toast.error(error);
  35. return null;
  36. });
  37. if (res) {
  38. messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
  39. }
  40. };
  41. onMount(() => {
  42. $socket?.on('channel-events', channelEventHandler);
  43. });
  44. onDestroy(() => {
  45. $socket?.off('channel-events', channelEventHandler);
  46. });
  47. </script>
  48. <div class="h-full md:max-w-[calc(100%-260px)] w-full max-w-full flex flex-col">
  49. <div
  50. class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0 max-w-full z-10 scrollbar-hidden"
  51. id="messages-container"
  52. bind:this={messagesContainerElement}
  53. on:scroll={(e) => {
  54. scrollEnd =
  55. messagesContainerElement.scrollHeight - messagesContainerElement.scrollTop <=
  56. messagesContainerElement.clientHeight + 5;
  57. }}
  58. >
  59. {#key id}
  60. <Messages
  61. {messages}
  62. onLoad={async () => {
  63. page += 1;
  64. const newMessages = await getChannelMessages(localStorage.token, id, page);
  65. if (newMessages.length === 0) {
  66. top = true;
  67. return;
  68. }
  69. messages = [...newMessages, ...messages];
  70. }}
  71. />
  72. {/key}
  73. </div>
  74. <div class=" pb-[1rem]">
  75. <MessageInput onSubmit={submitHandler} />
  76. </div>
  77. </div>