Spaces:
Runtime error
Runtime error
File size: 3,696 Bytes
9e93b10 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | <script lang="ts">
import { getContext } from "svelte";
import dayjs from "dayjs";
import calendar from "dayjs/plugin/calendar";
import { REXPRO_API_BASE_URL } from "$lib/constants";
import Spinner from "$lib/components/common/Spinner.svelte";
import Loader from "$lib/components/common/Loader.svelte";
dayjs.extend(calendar);
const i18n = getContext("i18n");
export let chatList: Array<{
id: string;
title: string;
updated_at: number;
user_id?: string;
user_name?: string;
time_range?: string;
}> | null = null;
export let loading = false;
export let allLoaded = false;
export let showUserInfo = false;
export let shareUrl = false;
export let emptyMessage = "No chats found";
export let onLoadMore: (() => void) | null = null;
export let onChatClick: ((chatId: string) => void) | null = null;
</script>
<div>
{#if chatList && chatList.length > 0}
<div class="flex text-xs font-medium mb-1.5">
{#if showUserInfo}
<div class="px-1.5 py-1 w-32">
{$i18n.t("User")}
</div>
{/if}
<div class="px-1.5 py-1 {showUserInfo ? 'flex-1' : 'basis-3/5'}">
{$i18n.t("Title")}
</div>
<div
class="px-1.5 py-1 hidden sm:flex {showUserInfo
? 'w-28'
: 'basis-2/5'} justify-end"
>
{$i18n.t("Updated at")}
</div>
</div>
{/if}
<div class="max-h-[22rem] overflow-y-scroll">
{#if loading && (!chatList || chatList.length === 0)}
<div class="flex justify-center py-8">
<Spinner />
</div>
{:else if !chatList || chatList.length === 0}
<div class="text-center text-gray-500 text-sm py-8">
{$i18n.t(emptyMessage)}
</div>
{:else}
{#each chatList as chat, idx (chat.id)}
{#if chat.time_range && (idx === 0 || chat.time_range !== chatList[idx - 1]?.time_range)}
<div
class="w-full text-xs text-gray-500 dark:text-gray-500 font-medium {idx ===
0
? ''
: 'pt-5'} pb-2 px-2"
>
{$i18n.t(chat.time_range)}
</div>
{/if}
<div
class="w-full flex items-center rounded-lg text-sm py-2 px-3 hover:bg-gray-50 dark:hover:bg-gray-850"
>
{#if showUserInfo && chat.user_id}
<div class="w-32 shrink-0 flex items-center gap-2">
<img
src="{REXPRO_API_BASE_URL}/users/{chat.user_id}/profile/image"
alt={chat.user_name || "User"}
class="size-5 rounded-full object-cover shrink-0"
/>
<span
class="text-xs text-gray-600 dark:text-gray-400 truncate"
>{chat.user_name || "Unknown"}</span
>
</div>
{/if}
<a
class={showUserInfo ? "flex-1" : "basis-3/5"}
href={shareUrl ? `/s/${chat.id}` : `/c/${chat.id}`}
on:click={() => onChatClick?.(chat.id)}
>
<div class="text-ellipsis line-clamp-1 w-full">
{chat.title
.replace(/^\p{Extended_Pictographic}\s*/gu, "")
.trim()}
</div>
</a>
<div
class="{showUserInfo
? 'w-28'
: 'basis-2/5'} flex items-center justify-end"
>
<div
class="hidden sm:flex text-gray-500 dark:text-gray-400 text-xs"
>
{dayjs(chat.updated_at * 1000).calendar(null, {
sameDay: "[Today] h:mm A",
lastDay: "[Yesterday] h:mm A",
lastWeek: "MMM D",
sameElse: "MMM D, YYYY",
})}
</div>
</div>
</div>
{/each}
{#if !allLoaded && onLoadMore}
<Loader
on:visible={() => {
if (!loading) {
onLoadMore();
}
}}
>
<div
class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2"
>
<Spinner className="size-4" />
<div>{$i18n.t("Loading...")}</div>
</div>
</Loader>
{/if}
{/if}
</div>
</div>
|