Finalize ux rework (#3720)

* colors

* nit

* finalize chat ux

* fix seeding waiting

* update chat input bar icons

* k

* Revert "fix seeding waiting"

This reverts commit e1aa93ff0c3c4a6bf77e6875ef5fa1d03dd73359.
This commit is contained in:
pablonyx 2025-01-20 17:09:16 -08:00 committed by GitHub
parent 8ddd95d0d4
commit 4ca7325d1a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 107 additions and 108 deletions

View File

@ -59,7 +59,7 @@ function SummaryRow({
return (
<TableRow
onClick={onToggle}
className="border-border bg-white py-4 rounded-sm !border cursor-pointer"
className="border-border group hover:bg-background-settings-hover bg-background-sidebar py-4 rounded-sm !border cursor-pointer"
>
<TableCell>
<div className="text-xl flex items-center truncate ellipsis gap-x-2 font-semibold">
@ -86,7 +86,7 @@ function SummaryRow({
<Tooltip>
<TooltipTrigger asChild>
<div className="flex items-center mt-1">
<div className="w-full bg-gray-200 rounded-full h-2 mr-2">
<div className="w-full bg-white rounded-full h-2 mr-2">
<div
className="bg-green-500 h-2 rounded-full"
style={{ width: `${activePercentage}%` }}

View File

@ -64,7 +64,7 @@ const AssistantCard: React.FC<{
}> = ({ persona, pinned, closeModal }) => {
const { user, toggleAssistantPinnedStatus } = useUser();
const router = useRouter();
const { refreshAssistants } = useAssistants();
const { refreshAssistants, pinnedAssistants } = useAssistants();
const isOwnedByUser = checkUserOwnsAssistant(user, persona);
@ -319,7 +319,7 @@ const AssistantCard: React.FC<{
<div
onClick={async () => {
await toggleAssistantPinnedStatus(
user?.preferences.pinned_assistants || [],
pinnedAssistants.map((a) => a.id),
persona.id,
!pinned
);

View File

@ -65,11 +65,8 @@ export default function AssistantModal({
}: {
hideModal: () => void;
}) {
const [showAllFeaturedAssistants, setShowAllFeaturedAssistants] =
useState(false);
const { assistants, visibleAssistants } = useAssistants();
const { assistantFilters, toggleAssistantFilter, setAssistantFilters } =
useAssistantFilter();
const { assistants, pinnedAssistants } = useAssistants();
const { assistantFilters, toggleAssistantFilter } = useAssistantFilter();
const router = useRouter();
const { user } = useUser();
const [searchQuery, setSearchQuery] = useState("");
@ -208,11 +205,9 @@ export default function AssistantModal({
featuredAssistants.map((assistant, index) => (
<div key={index}>
<AssistantCard
pinned={
user?.preferences?.pinned_assistants?.includes(
assistant.id
) ?? false
}
pinned={pinnedAssistants
.map((a) => a.id)
.includes(assistant.id)}
persona={assistant}
closeModal={hideModal}
/>

View File

@ -304,11 +304,7 @@ export function ChatPage({
const [presentingDocument, setPresentingDocument] =
useState<OnyxDocument | null>(null);
const {
visibleAssistants: assistants,
recentAssistants,
refreshRecentAssistants,
} = useAssistants();
const { recentAssistants, refreshRecentAssistants } = useAssistants();
const liveAssistant: Persona | undefined =
alternativeAssistant ||

View File

@ -653,92 +653,101 @@ export function ChatInputBar({
</div>
)}
<div className="flex items-center space-x-1 mr-12 overflow-hidden px-4 pb-2">
<ChatInputOption
flexPriority="stiff"
name="File"
Icon={FiPlusCircle}
onClick={() => {
const input = document.createElement("input");
input.type = "file";
input.multiple = true;
input.onchange = (event: any) => {
const files = Array.from(
event?.target?.files || []
) as File[];
if (files.length > 0) {
handleFileUpload(files);
}
};
input.click();
}}
tooltipContent={"Upload files"}
/>
<LLMPopover
llmProviders={llmProviders}
llmOverrideManager={llmOverrideManager}
requiresImageGeneration={false}
currentAssistant={selectedAssistant}
/>
{retrievalEnabled && (
<FilterPopup
availableSources={availableSources}
availableDocumentSets={availableDocumentSets}
availableTags={availableTags}
filterManager={filterManager}
trigger={
<ChatInputOption
flexPriority="stiff"
name="Filters"
Icon={FiFilter}
tooltipContent="Filter your search"
/>
}
<div className="flex justify-between items-center overflow-hidden px-4 mb-2">
<div className="flex gap-x-1">
<ChatInputOption
flexPriority="stiff"
name="File"
Icon={FiPlusCircle}
onClick={() => {
const input = document.createElement("input");
input.type = "file";
input.multiple = true;
input.onchange = (event: any) => {
const files = Array.from(
event?.target?.files || []
) as File[];
if (files.length > 0) {
handleFileUpload(files);
}
};
input.click();
}}
tooltipContent={"Upload files"}
/>
)}
</div>
<div className="absolute bottom-2.5 mobile:right-4 desktop:right-10">
{chatState == "streaming" ||
chatState == "toolBuilding" ||
chatState == "loading" ? (
<LLMPopover
llmProviders={llmProviders}
llmOverrideManager={llmOverrideManager}
requiresImageGeneration={false}
currentAssistant={selectedAssistant}
/>
{retrievalEnabled && (
<FilterPopup
availableSources={availableSources}
availableDocumentSets={availableDocumentSets}
availableTags={availableTags}
filterManager={filterManager}
trigger={
<ChatInputOption
flexPriority="stiff"
name="Filters"
Icon={FiFilter}
tooltipContent="Filter your search"
/>
}
/>
)}
</div>
<div className="flex my-auto">
<button
className={`cursor-pointer ${
chatState != "streaming"
? "bg-background-400"
: "bg-background-800"
} h-[28px] w-[28px] rounded-full`}
onClick={stopGenerating}
disabled={chatState != "streaming"}
>
<StopGeneratingIcon
size={10}
className={`text-emphasis m-auto text-white flex-none
}`}
/>
</button>
) : (
<button
className="cursor-pointer"
chatState == "streaming" ||
chatState == "toolBuilding" ||
chatState == "loading"
? chatState != "streaming"
? "bg-background-400"
: "bg-background-800"
: ""
} h-[28px] w-[28px] rounded-full`}
onClick={() => {
if (message) {
if (
chatState == "streaming" ||
chatState == "toolBuilding" ||
chatState == "loading"
) {
stopGenerating();
} else if (message) {
onSubmit();
}
}}
disabled={chatState != "input"}
disabled={
(chatState == "streaming" ||
chatState == "toolBuilding" ||
chatState == "loading") &&
chatState != "streaming"
}
>
<SendIcon
size={26}
className={`text-emphasis text-white p-1 rounded-full ${
chatState == "input" && message
? "bg-submit-background"
: "bg-disabled-submit-background"
} `}
/>
{chatState == "streaming" ||
chatState == "toolBuilding" ||
chatState == "loading" ? (
<StopGeneratingIcon
size={10}
className="text-emphasis m-auto text-white flex-none"
/>
) : (
<SendIcon
size={26}
className={`text-emphasis text-white p-1 my-auto rounded-full ${
chatState == "input" && message
? "bg-submit-background"
: "bg-disabled-submit-background"
}`}
/>
)}
</button>
)}
</div>
</div>
</div>
</div>

View File

@ -326,13 +326,6 @@
/* Handle color on hover */
}
::-webkit-scrollbar {
width: 0px;
/* Vertical scrollbar width */
height: 8px;
/* Horizontal scrollbar height */
}
/* Used to create alternatie to React Markdown */
.preserve-lines {
white-space: pre-wrap;

View File

@ -57,15 +57,20 @@ export const AssistantsProvider: React.FC<{
const [allAssistants, setAllAssistants] = useState<Persona[]>([]);
const [pinnedAssistants, setPinnedAssistants] = useState<Persona[]>(
assistants.filter((assistant) =>
user?.preferences?.pinned_assistants?.includes(assistant.id)
)
user?.preferences.pinned_assistants
? assistants.filter((assistant) =>
user?.preferences?.pinned_assistants?.includes(assistant.id)
)
: assistants.filter((a) => a.builtin_persona)
);
useEffect(() => {
setPinnedAssistants(
assistants.filter((assistant) =>
user?.preferences?.pinned_assistants?.includes(assistant.id)
)
user?.preferences.pinned_assistants
? assistants.filter((assistant) =>
user?.preferences?.pinned_assistants?.includes(assistant.id)
)
: assistants.filter((a) => a.builtin_persona)
);
}, [user?.preferences?.pinned_assistants, assistants]);

View File

@ -177,6 +177,7 @@ export const getCurrentUserSS = async (): Promise<User | null> => {
if (!response.ok) {
return null;
}
const user = await response.json();
return user;
} catch (e) {