This commit is contained in:
Timothy Jaeryang Baek 2025-11-28 10:04:06 -05:00
parent aae2fce173
commit 7b1895ec8a
3 changed files with 83 additions and 59 deletions

View file

@ -274,7 +274,20 @@
> >
<PaneGroup direction="horizontal" class="w-full h-full"> <PaneGroup direction="horizontal" class="w-full h-full">
<Pane defaultSize={50} minSize={50} class="h-full flex flex-col w-full relative"> <Pane defaultSize={50} minSize={50} class="h-full flex flex-col w-full relative">
<Navbar {channel} /> <Navbar
{channel}
onPin={(messageId, pinned) => {
messages = messages.map((message) => {
if (message.id === messageId) {
return {
...message,
is_pinned: pinned
};
}
return message;
});
}}
/>
<div class="flex-1 overflow-y-auto"> <div class="flex-1 overflow-y-auto">
{#if channel} {#if channel}

View file

@ -27,9 +27,11 @@
let showChannelInfoModal = false; let showChannelInfoModal = false;
export let channel; export let channel;
export let onPin = (messageId, pinned) => {};
</script> </script>
<PinnedMessagesModal bind:show={showChannelPinnedMessagesModal} {channel} /> <PinnedMessagesModal bind:show={showChannelPinnedMessagesModal} {channel} {onPin} />
<ChannelInfoModal bind:show={showChannelInfoModal} {channel} /> <ChannelInfoModal bind:show={showChannelInfoModal} {channel} />
<nav class="sticky top-0 z-30 w-full px-1.5 py-1 -mb-8 flex items-center drag-region flex flex-col"> <nav class="sticky top-0 z-30 w-full px-1.5 py-1 -mb-8 flex items-center drag-region flex flex-col">
<div <div

View file

@ -3,26 +3,21 @@
import { getContext, onMount } from 'svelte'; import { getContext, onMount } from 'svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
import { getChannelPinnedMessages, pinMessage } from '$lib/apis/channels';
import Spinner from '$lib/components/common/Spinner.svelte'; import Spinner from '$lib/components/common/Spinner.svelte';
import Modal from '$lib/components/common/Modal.svelte'; import Modal from '$lib/components/common/Modal.svelte';
import UserPlusSolid from '$lib/components/icons/UserPlusSolid.svelte';
import WrenchSolid from '$lib/components/icons/WrenchSolid.svelte';
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import XMark from '$lib/components/icons/XMark.svelte'; import XMark from '$lib/components/icons/XMark.svelte';
import Hashtag from '../icons/Hashtag.svelte';
import Lock from '../icons/Lock.svelte';
import UserList from './ChannelInfoModal/UserList.svelte';
import { getChannelPinnedMessages, pinMessage } from '$lib/apis/channels';
import Message from './Messages/Message.svelte'; import Message from './Messages/Message.svelte';
import { user } from '$lib/stores';
import Loader from '../common/Loader.svelte'; import Loader from '../common/Loader.svelte';
export let show = false; export let show = false;
export let channel = null; export let channel = null;
export let onPin = (messageId, pinned) => {};
let page = 1; let page = 1;
let pinnedMessages = []; let pinnedMessages = null;
let allItemsLoaded = false; let allItemsLoaded = false;
let loading = false; let loading = false;
@ -41,7 +36,7 @@
); );
if (res) { if (res) {
pinnedMessages = [...pinnedMessages, ...res]; pinnedMessages = [...(pinnedMessages ?? []), ...res];
} }
if (res.length === 0) { if (res.length === 0) {
@ -56,7 +51,8 @@
const init = () => { const init = () => {
page = 1; page = 1;
pinnedMessages = []; pinnedMessages = null;
allItemsLoaded = false;
getPinnedMessages(); getPinnedMessages();
}; };
@ -92,56 +88,69 @@
<div class="flex flex-col md:flex-row w-full px-4 pb-4 md:space-x-4 dark:text-gray-200"> <div class="flex flex-col md:flex-row w-full px-4 pb-4 md:space-x-4 dark:text-gray-200">
<div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6"> <div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6">
<div class="flex flex-col w-full h-full pb-2 gap-1"> <div class="flex flex-col w-full h-full pb-2 gap-1">
<div {#if pinnedMessages === null}
class="flex flex-col gap-2 max-h-[60vh] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-300 dark:scrollbar-thumb-gray-700 scrollbar-track-transparent py-2" <div class="my-10">
> <Spinner className="size-5" />
{#each pinnedMessages as message, messageIdx (message.id)} </div>
<Message {:else}
className="rounded-xl px-2" <div
{message} class="flex flex-col gap-2 max-h-[60vh] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-300 dark:scrollbar-thumb-gray-700 scrollbar-track-transparent py-2"
{channel} >
onPin={async (message) => { {#if pinnedMessages.length === 0}
pinnedMessages = pinnedMessages.filter((m) => m.id !== message.id); <div class=" text-center text-sm text-gray-500 dark:text-gray-400 py-6">
{$i18n.t('No pinned messages')}
</div>
{:else}
{#each pinnedMessages as message, messageIdx (message.id)}
<Message
className="rounded-xl px-2"
{message}
{channel}
onPin={async (message) => {
pinnedMessages = pinnedMessages.filter((m) => m.id !== message.id);
onPin(message.id, !message.is_pinned);
const updatedMessage = await pinMessage( const updatedMessage = await pinMessage(
localStorage.token, localStorage.token,
message.channel_id, message.channel_id,
message.id, message.id,
!message.is_pinned !message.is_pinned
).catch((error) => { ).catch((error) => {
toast.error(`${error}`); toast.error(`${error}`);
return null; return null;
}); });
init(); init();
}} }}
onReaction={false} onReaction={false}
onThread={false} onThread={false}
onReply={false} onReply={false}
onEdit={false} onEdit={false}
onDelete={false} onDelete={false}
/> />
{#if messageIdx === pinnedMessages.length - 1 && !allItemsLoaded} {#if messageIdx === pinnedMessages.length - 1 && !allItemsLoaded}
<Loader <Loader
on:visible={(e) => { on:visible={(e) => {
console.log('visible'); console.log('visible');
if (!loading) { if (!loading) {
page += 1; page += 1;
getPinnedMessages(); getPinnedMessages();
} }
}} }}
> >
<div <div
class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2" class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2"
> >
<Spinner className=" size-4" /> <Spinner className=" size-4" />
<div class=" ">{$i18n.t('Loading...')}</div> <div class=" ">{$i18n.t('Loading...')}</div>
</div> </div>
</Loader> </Loader>
{/if}
{/each}
{/if} {/if}
{/each} </div>
</div> {/if}
</div> </div>
</div> </div>
</div> </div>