Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type Option = { label: string; value: string };
export function MultiNetworkSelector(props: {
selectedChainIds: number[];
onChange: (chainIds: number[]) => void;
disableChainId?: boolean;
className?: string;
}) {
const { allChains, idToChain } = useAllChainsData();

Expand Down Expand Up @@ -53,16 +55,24 @@ export function MultiNetworkSelector(props: {
return (
<div className="flex justify-between gap-4">
<span className="flex grow gap-2 truncate text-left">
<ChainIcon
className="size-5"
ipfsSrc={chain.icon?.url}
loading="lazy"
/>
{cleanChainName(chain.name)}
</span>
<Badge variant="outline" className="gap-2">
<span className="text-muted-foreground">Chain ID</span>
{chain.chainId}
</Badge>

{!props.disableChainId && (
<Badge variant="outline" className="gap-2">
<span className="text-muted-foreground">Chain ID</span>
{chain.chainId}
</Badge>
)}
</div>
);
},
[idToChain],
[idToChain, props.disableChainId],
);

return (
Expand All @@ -79,6 +89,7 @@ export function MultiNetworkSelector(props: {
disabled={allChains.length === 0}
overrideSearchFn={searchFn}
renderOption={renderOption}
className={props.className}
/>
);
}
Expand Down Expand Up @@ -143,7 +154,7 @@ export function SingleNetworkSelector(props: {
ipfsSrc={chain.icon?.url}
loading="lazy"
/>
{chain.name}
{cleanChainName(chain.name)}
</span>

{!props.disableChainId && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ function SessionCard(props: {
<Link
className="before:absolute before:inset-0"
href={`/chat/${props.session.id}`}
prefetch={false}
>
{props.session.title || "Untitled"}
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type { ExecuteConfig, SessionInfo } from "../api/types";
import { newChatPageUrlStore, newSessionsStore } from "../stores";
import { ChatBar } from "./ChatBar";
import { type ChatMessage, Chats } from "./Chats";
import ContextFiltersButton from "./ContextFilters";
import ContextFiltersButton, { ContextFiltersForm } from "./ContextFilters";
import { EmptyStateChatPageContent } from "./EmptyStateChatPageContent";

export function ChatPageContent(props: {
Expand Down Expand Up @@ -362,69 +362,92 @@ export function ChatPageContent(props: {

const showEmptyState = !userHasSubmittedMessage && messages.length === 0;

const handleUpdateContextFilters = async (
values: ContextFilters | undefined,
) => {
// if session is not yet created, don't need to update sessions - starting a chat will create a session with the context filters
if (sessionId) {
await updateSession({
authToken: props.authToken,
config,
sessionId,
contextFilters: values,
});
}
};

return (
<div className="flex grow flex-col overflow-hidden">
<WalletDisconnectedDialog
open={showConnectModal}
onOpenChange={setShowConnectModal}
/>
<header className="flex justify-start border-b bg-background p-4">
<header className="flex justify-between border-b bg-background p-4 xl:hidden">
<ContextFiltersButton
contextFilters={contextFilters}
setContextFilters={setContextFilters}
updateContextFilters={async (values) => {
// if session is not yet created, don't need to update sessions - starting a chat will create a session with the context filters
if (sessionId) {
await updateSession({
authToken: props.authToken,
config,
sessionId,
contextFilters: values,
});
}
}}
updateContextFilters={handleUpdateContextFilters}
/>
</header>
<div className="relative flex grow flex-col overflow-hidden rounded-lg pb-6">
{showEmptyState ? (
<div className="fade-in-0 container flex max-w-[800px] grow animate-in flex-col justify-center">
<EmptyStateChatPageContent sendMessage={handleSendMessage} />
</div>
) : (
<div className="fade-in-0 relative z-[0] flex max-h-full flex-1 animate-in flex-col overflow-hidden">
<Chats
messages={messages}
isChatStreaming={isChatStreaming}
authToken={props.authToken}
sessionId={sessionId}
className="min-w-0 pt-6 pb-32"
twAccount={props.account}
client={client}
enableAutoScroll={enableAutoScroll}
setEnableAutoScroll={setEnableAutoScroll}
/>

<div className="container max-w-[800px]">
<ChatBar
sendMessage={handleSendMessage}

<div className="flex grow overflow-hidden">
<div className="relative flex grow flex-col overflow-hidden rounded-lg pb-6">
{showEmptyState ? (
<div className="fade-in-0 container flex max-w-[800px] grow animate-in flex-col justify-center">
<EmptyStateChatPageContent sendMessage={handleSendMessage} />
</div>
) : (
<div className="fade-in-0 relative z-[0] flex max-h-full flex-1 animate-in flex-col overflow-hidden">
<Chats
messages={messages}
isChatStreaming={isChatStreaming}
abortChatStream={() => {
chatAbortController?.abort();
setChatAbortController(undefined);
setIsChatStreaming(false);
// if last message is presence, remove it
if (messages[messages.length - 1]?.type === "presence") {
setMessages((prev) => prev.slice(0, -1));
}
}}
authToken={props.authToken}
sessionId={sessionId}
className="min-w-0 pt-6 pb-32"
twAccount={props.account}
client={client}
enableAutoScroll={enableAutoScroll}
setEnableAutoScroll={setEnableAutoScroll}
/>

<div className="container max-w-[800px]">
<ChatBar
sendMessage={handleSendMessage}
isChatStreaming={isChatStreaming}
abortChatStream={() => {
chatAbortController?.abort();
setChatAbortController(undefined);
setIsChatStreaming(false);
// if last message is presence, remove it
if (messages[messages.length - 1]?.type === "presence") {
setMessages((prev) => prev.slice(0, -1));
}
}}
/>
</div>
</div>
</div>
)}
)}

<p className="mt-4 text-center text-muted-foreground text-xs opacity-75 lg:text-sm">
Nebula may make mistakes. Please use with discretion
</p>
<p className="mt-4 text-center text-muted-foreground text-xs opacity-75 lg:text-sm">
Nebula may make mistakes. Please use with discretion
</p>
</div>
<aside className="hidden w-[360px] flex-col border-l bg-card pt-4 xl:flex">
<div className="px-4">
<h3 className="font-semibold text-lg tracking-tight">Context</h3>
<p className="mb-5 text-muted-foreground text-sm">
Provide context to Nebula for your prompts
</p>
</div>
<ContextFiltersForm
contextFilters={contextFilters}
setContextFilters={setContextFilters}
modal={undefined}
updateContextFilters={handleUpdateContextFilters}
formBodyClassName="px-4"
formActionContainerClassName="px-4 border-t-0 pt-0 bg-transparent"
/>
</aside>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
import {
FileCode2Icon,
MessageSquareShareIcon,
MessagesSquareIcon,
SquareDashedBottomCodeIcon,
TextIcon,
Expand All @@ -29,8 +31,11 @@ export function ChatSidebar(props: {
return (
<div className="flex h-full flex-col p-2">
<div className="flex items-center justify-start gap-3 p-2 lg:justify-between">
<Link href="/">
<NebulaIcon className="size-8 text-foreground" />
<Link href="/" className="flex items-center gap-2">
<NebulaIcon className="size-8 text-foreground" aria-label="Nebula" />
<span className="font-semibold text-lg tracking-tight">
Playground
</span>
</Link>

<Badge variant="secondary" className="gap-1 py-1">
Expand All @@ -48,6 +53,13 @@ export function ChatSidebar(props: {

<div className="h-3" />

<SidebarIconLink
href="https://portal.thirdweb.com/nebula/api-reference"
icon={FileCode2Icon}
label="API Reference"
target="_blank"
/>

<SidebarIconLink
href="/chat/history"
icon={MessagesSquareIcon}
Expand Down Expand Up @@ -79,7 +91,14 @@ export function ChatSidebar(props: {
</ScrollShadow>
)}

<div className="mb-3 border-b border-dashed pt-2 pb-3">
<div className="mb-3 border-y border-dashed py-3">
<SidebarIconLink
href="https://docs.google.com/forms/d/e/1FAIpQLSeM3fJRyywihRZUF1fiTNKEpJ_AzAcohRwXPpLr_3zxQ6W-tg/viewform?usp=sharing"
icon={MessageSquareShareIcon}
label="Take our quick survey!"
target="_blank"
/>

<SidebarIconLink
href="https://portal.thirdweb.com/changelog"
icon={TextIcon}
Expand Down Expand Up @@ -116,6 +135,7 @@ function SidebarIconLink(props: {
href={props.href}
target={props.target}
className="!justify-start !px-3 w-full gap-2.5 rounded-lg text-left"
prefetch={false}
>
<props.icon className="size-4" />
{props.label}
Expand Down
Loading
Loading