mirror of
https://github.com/ItzCrazyKns/Perplexica.git
synced 2025-12-16 08:38:15 +00:00
feat(message-input-actions): add sources
This commit is contained in:
93
src/components/MessageInputActions/Sources.tsx
Normal file
93
src/components/MessageInputActions/Sources.tsx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import { useChat } from '@/lib/hooks/useChat';
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverButton,
|
||||||
|
PopoverPanel,
|
||||||
|
Switch,
|
||||||
|
} from '@headlessui/react';
|
||||||
|
import {
|
||||||
|
GlobeIcon,
|
||||||
|
GraduationCapIcon,
|
||||||
|
NetworkIcon,
|
||||||
|
} from '@phosphor-icons/react';
|
||||||
|
import { AnimatePresence, motion } from 'motion/react';
|
||||||
|
|
||||||
|
const sourcesList = [
|
||||||
|
{
|
||||||
|
name: 'Web',
|
||||||
|
key: 'web',
|
||||||
|
icon: <GlobeIcon className="h-[16px] w-auto" />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Academic',
|
||||||
|
key: 'academic',
|
||||||
|
icon: <GraduationCapIcon className="h-[16px] w-auto" />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Social',
|
||||||
|
key: 'social',
|
||||||
|
icon: <NetworkIcon className="h-[16px] w-auto" />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Sources = () => {
|
||||||
|
const { sources, setSources } = useChat();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover className="relative">
|
||||||
|
{({ open }) => (
|
||||||
|
<>
|
||||||
|
<PopoverButton className="flex items-center justify-center active:border-none hover:bg-light-200 hover:dark:bg-dark-200 p-2 rounded-lg focus:outline-none text-black/50 dark:text-white/50 active:scale-95 transition duration-200 hover:text-black dark:hover:text-white">
|
||||||
|
<GlobeIcon className="h-[18px] w-auto" />
|
||||||
|
</PopoverButton>
|
||||||
|
<AnimatePresence>
|
||||||
|
{open && (
|
||||||
|
<PopoverPanel
|
||||||
|
static
|
||||||
|
className="absolute z-10 w-64 md:w-[225px] right-0"
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
exit={{ opacity: 0, scale: 0.9 }}
|
||||||
|
transition={{ duration: 0.1, ease: 'easeOut' }}
|
||||||
|
className="origin-top-right flex flex-col bg-light-primary dark:bg-dark-primary border rounded-lg border-light-200 dark:border-dark-200 w-full p-1 max-h-[200px] md:max-h-none overflow-y-auto shadow-md shadow-dark-50"
|
||||||
|
>
|
||||||
|
{sourcesList.map((source, i) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className="flex flex-row justify-between hover:bg-white-100 hover:dark:bg-dark-100 rounded-md py-3 px-2 cursor-pointer"
|
||||||
|
onClick={() => {
|
||||||
|
if (!sources.includes(source.key)) {
|
||||||
|
setSources([...sources, source.key]);
|
||||||
|
} else {
|
||||||
|
setSources(sources.filter((s) => s !== source.key));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex flex-row space-x-1.5 text-white/80">
|
||||||
|
{source.icon}
|
||||||
|
<p className="text-xs">{source.name}</p>
|
||||||
|
</div>
|
||||||
|
<Switch
|
||||||
|
checked={sources.includes(source.key)}
|
||||||
|
className="group relative flex h-4 w-7 shrink-0 cursor-pointer rounded-full bg-white/10 p-0.5 duration-200 ease-in-out focus:outline-none transition-colors disabled:opacity-60 disabled:cursor-not-allowed data-[checked]:bg-sky-500"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
className="pointer-events-none inline-block size-3 translate-x-[1px] group-data-[checked]:translate-x-3 rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out"
|
||||||
|
/>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
</PopoverPanel>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Sources;
|
||||||
Reference in New Issue
Block a user