123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- <script lang="ts">
- import { toast } from 'svelte-sonner';
- import dayjs from 'dayjs';
- import relativeTime from 'dayjs/plugin/relativeTime';
- import isToday from 'dayjs/plugin/isToday';
- import isYesterday from 'dayjs/plugin/isYesterday';
- dayjs.extend(relativeTime);
- dayjs.extend(isToday);
- dayjs.extend(isYesterday);
- import { tick, getContext, onMount, createEventDispatcher } from 'svelte';
- import { settings, user } from '$lib/stores';
- import Message from './Messages/Message.svelte';
- import Loader from '../common/Loader.svelte';
- import Spinner from '../common/Spinner.svelte';
- import { addReaction, deleteMessage, removeReaction, updateMessage } from '$lib/apis/channels';
- const i18n = getContext('i18n');
- export let id = null;
- export let channel = null;
- export let messages = [];
- export let top = false;
- export let thread = false;
- export let onLoad: Function = () => {};
- export let onThread: Function = () => {};
- let messagesLoading = false;
- const loadMoreMessages = async () => {
- // scroll slightly down to disable continuous loading
- const element = document.getElementById('messages-container');
- element.scrollTop = element.scrollTop + 100;
- messagesLoading = true;
- await onLoad();
- await tick();
- messagesLoading = false;
- };
- </script>
- {#if messages}
- {@const messageList = messages.slice().reverse()}
- <div>
- {#if !top}
- <Loader
- on:visible={(e) => {
- console.log('visible');
- if (!messagesLoading) {
- loadMoreMessages();
- }
- }}
- >
- <div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
- <Spinner className=" size-4" />
- <div class=" ">Loading...</div>
- </div>
- </Loader>
- {:else if !thread}
- <div
- class="px-5
-
- {($settings?.widescreenMode ?? null) ? 'max-w-full' : 'max-w-5xl'} mx-auto"
- >
- {#if channel}
- <div class="flex flex-col gap-1.5 pb-5 pt-10">
- <div class="text-2xl font-medium capitalize">{channel.name}</div>
- <div class=" text-gray-500">
- This channel was created on {dayjs(channel.created_at / 1000000).format(
- 'MMMM D, YYYY'
- )}. This is the very beginning of the {channel.name}
- channel.
- </div>
- </div>
- {:else}
- <div class="flex justify-center text-xs items-center gap-2 py-5">
- <div class=" ">Start of the channel</div>
- </div>
- {/if}
- {#if messageList.length > 0}
- <hr class=" border-gray-50 dark:border-gray-700/20 py-2.5 w-full" />
- {/if}
- </div>
- {/if}
- {#each messageList as message, messageIdx (id ? `${id}-${message.id}` : message.id)}
- <Message
- {message}
- {thread}
- showUserProfile={messageIdx === 0 ||
- messageList.at(messageIdx - 1)?.user_id !== message.user_id}
- onDelete={() => {
- messages = messages.filter((m) => m.id !== message.id);
- const res = deleteMessage(localStorage.token, message.channel_id, message.id).catch(
- (error) => {
- toast.error(error);
- return null;
- }
- );
- }}
- onEdit={(content) => {
- messages = messages.map((m) => {
- if (m.id === message.id) {
- m.content = content;
- }
- return m;
- });
- const res = updateMessage(localStorage.token, message.channel_id, message.id, {
- content: content
- }).catch((error) => {
- toast.error(error);
- return null;
- });
- }}
- onThread={(id) => {
- onThread(id);
- }}
- onReaction={(name) => {
- if (
- (message?.reactions ?? [])
- .find((reaction) => reaction.name === name)
- ?.user_ids?.includes($user.id) ??
- false
- ) {
- messages = messages.map((m) => {
- if (m.id === message.id) {
- const reaction = m.reactions.find((reaction) => reaction.name === name);
- if (reaction) {
- reaction.user_ids = reaction.user_ids.filter((id) => id !== $user.id);
- reaction.count = reaction.user_ids.length;
- if (reaction.count === 0) {
- m.reactions = m.reactions.filter((r) => r.name !== name);
- }
- }
- }
- return m;
- });
- const res = removeReaction(
- localStorage.token,
- message.channel_id,
- message.id,
- name
- ).catch((error) => {
- toast.error(error);
- return null;
- });
- } else {
- messages = messages.map((m) => {
- if (m.id === message.id) {
- if (m.reactions) {
- const reaction = m.reactions.find((reaction) => reaction.name === name);
- if (reaction) {
- reaction.user_ids.push($user.id);
- reaction.count = reaction.user_ids.length;
- } else {
- m.reactions.push({
- name: name,
- user_ids: [$user.id],
- count: 1
- });
- }
- }
- }
- return m;
- });
- const res = addReaction(localStorage.token, message.channel_id, message.id, name).catch(
- (error) => {
- toast.error(error);
- return null;
- }
- );
- }
- }}
- />
- {/each}
- <div class="pb-6" />
- </div>
- {/if}
|