Update package version and add new chat button

This commit is contained in:
n4ze3m 2024-02-14 00:43:07 +05:30
parent e4011b7af6
commit 31cac3b5b7
3 changed files with 111 additions and 78 deletions

View File

@ -1,7 +1,7 @@
{
"name": "pageassist",
"displayName": "Page Assist - A Web UI for Local AI Models",
"version": "1.0.0",
"version": "1.0.1",
"description": "Use your locally running AI models to assist you in your web browsing.",
"author": "n4ze3m",
"scripts": {

View File

@ -19,7 +19,7 @@ import { Drawer, Layout, Modal, Select } from "antd"
import { useQuery } from "@tanstack/react-query"
import { fetchModels } from "~services/ollama"
import { useMessageOption } from "~hooks/useMessageOption"
import { PanelLeftIcon, Settings2 } from "lucide-react"
import { GithubIcon, PanelLeftIcon, Settings2, SquarePen } from "lucide-react"
import { Settings } from "./Settings"
import { useDarkMode } from "~hooks/useDarkmode"
@ -67,7 +67,6 @@ export default function OptionLayout({
const { selectedModel, setSelectedModel } = useMessageOption()
return (
<Layout className="bg-white dark:bg-[#171717] md:flex">
<div className="flex items-center p-3 fixed flex-row justify-between border-b border-gray-200 dark:border-gray-600 bg-white dark:bg-[#171717] w-full z-10">
@ -79,6 +78,12 @@ export default function OptionLayout({
<PanelLeftIcon className="w-6 h-6" />
</button>
</div>
<div>
<button className="inline-flex items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 ">
<SquarePen className="h-4 w-4 mr-3" />
New Chat
</button>
</div>
<div>
<Select
value={selectedModel}
@ -94,14 +99,19 @@ export default function OptionLayout({
/>
</div>
</div>
<button>
</button>
<button
onClick={() => setOpen(true)}
className="text-gray-500 dark:text-gray-400">
<CogIcon className="w-6 h-6" />
</button>
<div className="flex gap-3 items-center">
<a
href="https://github.com/n4ze3m/page-assist"
target="_blank"
className="text-gray-500 dark:text-gray-400">
<GithubIcon className="w-6 h-6" />
</a>
<button
onClick={() => setOpen(true)}
className="text-gray-500 dark:text-gray-400">
<CogIcon className="w-6 h-6" />
</button>
</div>
</div>
<Layout.Content>{children}</Layout.Content>

View File

@ -6,8 +6,9 @@ import PhotoIcon from "@heroicons/react/24/outline/PhotoIcon"
import XMarkIcon from "@heroicons/react/24/outline/XMarkIcon"
import { toBase64 } from "~libs/to-base64"
import { useMessageOption } from "~hooks/useMessageOption"
import { ArrowPathIcon } from "@heroicons/react/24/outline"
import { Tooltip } from "antd"
import { MicIcon } from "lucide-react"
import { Image } from "antd"
type Props = {
dropedFile: File | undefined
@ -30,6 +31,12 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
}
})
React.useEffect(() => {
if (textareaRef.current) {
textareaRef.current.focus()
}
}, [])
const onInputChange = async (
e: React.ChangeEvent<HTMLInputElement> | File
) => {
@ -66,35 +73,39 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
})
return (
<div className="p-3 md:p-6 md:bg-white dark:bg-[#262626] border rounded-t-xl border-black/10 dark:border-gray-600">
<div className="flex-grow space-y-6 ">
<div
className={`h-full rounded-md shadow relative ${
form.values.image.length === 0 ? "hidden" : "block"
}`}>
<div>
<img
src={form.values.image}
alt="Uploaded"
className="h-full w-auto object-cover rounded-md min-w-[50px]"
/>
<button
onClick={() => {
form.setFieldValue("image", "")
}}
className="absolute top-2 right-2 bg-white dark:bg-[#262626] p-1 rounded-full hover:bg-gray-100 dark:hover:bg-gray-600 text-black dark:text-gray-100">
<XMarkIcon className="h-5 w-5" />
</button>
</div>
<div className="px-3 pt-3 md:px-6 md:pt-6 md:bg-white dark:bg-[#262626] border rounded-t-xl border-black/10 dark:border-gray-600">
<div
className={`h-full rounded-md shadow relative ${
form.values.image.length === 0 ? "hidden" : "block"
}`}>
<div className="relative">
<Image
src={form.values.image}
alt="Uploaded Image"
width={180}
preview={false}
className="rounded-md"
/>
<button
onClick={() => {
form.setFieldValue("image", "")
}}
className="flex items-center justify-center absolute top-0 m-2 bg-white dark:bg-[#262626] p-1 rounded-full hover:bg-gray-100 dark:hover:bg-gray-600 text-black dark:text-gray-100">
<XMarkIcon className="h-5 w-5" />
</button>
</div>
</div>
{/* <div className="flex gap-3 justify-end">
<Tooltip title="New Chat">
<button
onClick={clearChat}
className="text-gray-500 dark:text-gray-100 mr-3">
<ArrowPathIcon className="h-5 w-5" />
</button>
</Tooltip>
</div> */}
<div>
<div className="flex">
<Tooltip title="New Chat">
<button
onClick={clearChat}
className="text-gray-500 dark:text-gray-100 mr-3">
<ArrowPathIcon className="h-5 w-5" />
</button>
</Tooltip>
<form
onSubmit={form.onSubmit(async (value) => {
if (!selectedModel || selectedModel.length === 0) {
@ -108,29 +119,18 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
message: value.message.trim()
})
})}
className="shrink-0 flex-grow flex items-center ">
<div className="flex items-center p-2 rounded-2xl border bg-gray-100 w-full dark:bg-[#262626] dark:border-gray-600">
<button
type="button"
onClick={() => {
inputRef.current?.click()
}}
className={`flex ml-3 items-center justify-center dark:text-gray-100 ${
chatMode === "rag" ? "hidden" : "block"
}`}>
<PhotoIcon className="h-5 w-5" />
</button>
<input
id="file-upload"
name="file-upload"
type="file"
className="sr-only"
ref={inputRef}
accept="image/*"
multiple={false}
onChange={onInputChange}
/>
className="shrink-0 flex-grow flex flex-col items-center ">
<input
id="file-upload"
name="file-upload"
type="file"
className="sr-only"
ref={inputRef}
accept="image/*"
multiple={false}
onChange={onInputChange}
/>
<div className="w-full border-x border-t flex flex-col dark:border-gray-600 rounded-t-xl p-2">
<textarea
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey && !isSending) {
@ -156,26 +156,49 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
className="px-2 py-2 w-full resize-none bg-transparent focus-within:outline-none sm:text-sm focus:ring-0 focus-visible:ring-0 ring-0 dark:ring-0 border-0 dark:text-gray-100"
required
rows={1}
style={{ minHeight: "60px" }}
tabIndex={0}
placeholder="Type a message..."
{...form.getInputProps("message")}
/>
<button
disabled={isSending || form.values.message.length === 0}
className="ml-2 flex items-center justify-center w-10 h-10 text-white bg-[#262626] rounded-xl disabled:opacity-50">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="h-6 w-6"
viewBox="0 0 24 24">
<path d="M9 10L4 15 9 20"></path>
<path d="M20 4v7a4 4 0 01-4 4H4"></path>
</svg>
</button>
<div className="flex mt-4 justify-end gap-3">
<Tooltip title="Voice Message">
<button
type="button"
className={`flex items-center justify-center dark:text-gray-300`}>
<MicIcon className="h-5 w-5" />
</button>
</Tooltip>
<Tooltip title="Upload Image">
<button
type="button"
onClick={() => {
inputRef.current?.click()
}}
className={`flex items-center justify-center dark:text-gray-300 ${
chatMode === "rag" ? "hidden" : "block"
}`}>
<PhotoIcon className="h-5 w-5" />
</button>
</Tooltip>
<button
disabled={isSending || form.values.message.length === 0}
className="inline-flex items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 ">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="h-4 w-4 mr-2"
viewBox="0 0 24 24">
<path d="M9 10L4 15 9 20"></path>
<path d="M20 4v7a4 4 0 01-4 4H4"></path>
</svg>
Send
</button>
</div>
</div>
</form>
</div>