Skip to content

Commit

Permalink
Merge pull request #119 from n4ze3m/next
Browse files Browse the repository at this point in the history
v1.1.12
  • Loading branch information
n4ze3m committed Jun 12, 2024
2 parents 8bcd4ec + f131069 commit d198b87
Show file tree
Hide file tree
Showing 20 changed files with 457 additions and 120 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-i18next": "^14.1.0",
"react-icons": "^5.2.1",
"react-markdown": "8.0.0",
"react-router-dom": "6.10.0",
"react-syntax-highlighter": "^15.5.0",
"react-toastify": "^10.0.4",
"rehype-katex": "6.0.3",
"rehype-mathjax": "4.0.3",
"remark-gfm": "3.0.1",
"remark-math": "5.1.1",
Expand Down
Binary file added src/assets/fonts/Arimo.ttf
Binary file not shown.
Binary file removed src/assets/inter.ttf
Binary file not shown.
Binary file removed src/assets/onest.ttf
Binary file not shown.
92 changes: 41 additions & 51 deletions src/assets/tailwind.css
Original file line number Diff line number Diff line change
@@ -1,77 +1,67 @@
@font-face {
font-family: "Inter";
src: url("inter.ttf") format("truetype");
font-family: "Arimo";
src: url("fonts/Arimo.ttf");
font-display: swap;
}

@font-face {
font-family: "Onest";
src: url("onest.ttf") format("truetype");
}

.inter {
font-family: "Inter", sans-serif !important;
}

.onest {
font-family: "Onest", sans-serif !important;
.arimo {
font-family: "Arimo", sans-serif;
font-weight: 500;
font-style: normal;
}

@tailwind base;
@tailwind components;
@tailwind utilities;



.ant-select-selection-search-input {
border: none !important;
box-shadow: none !important;
}

.gradient-border {
--borderWidth: 3px;
position: relative;
border-radius: var(--borderWidth);
/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.gradient-border:after {
content: "";
position: absolute;
top: calc(-1 * var(--borderWidth));
left: calc(-1 * var(--borderWidth));
height: calc(100% + var(--borderWidth) * 2);
width: calc(100% + var(--borderWidth) * 2);
background: linear-gradient(
60deg,
#f79533,
#f37055,
#ef4e7b,
#a166ab,
#5073b8,
#1098ad,
#07b39b,
#6fba82
);
border-radius: calc(2 * var(--borderWidth));
z-index: -1;
animation: animatedgradient 3s ease alternate infinite;
background-size: 300% 300%;

/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}

@keyframes animatedgradient {
@keyframes gradient-border {
0% {
background-position: 0% 50%;
border-image-source: linear-gradient(
45deg,
#f79533,
#f37055,
#ef4e7b,
#a166ab
);
}
50% {
background-position: 100% 50%;
border-image-source: linear-gradient(45deg, #ef4e7b, #a166ab);
}
74% {
border-image-source: linear-gradient(60deg, #5073b8, #1098ad);
}
100% {
background-position: 0% 50%;
border-image-source: linear-gradient(
45deg,
#f79533,
#f37055,
#ef4e7b,
#a166ab
);
}
}
/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {
display: none;
}

/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
.animated-gradient-border {
border: 3px solid;
border-image-slice: 1;
animation: gradient-border 3s infinite;
border-radius: 10px;
}
11 changes: 5 additions & 6 deletions src/components/Common/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import remarkGfm from "remark-gfm"
import remarkMath from "remark-math"
import ReactMarkdown from "react-markdown"

import "property-information"
import React from "react"
import { CodeBlock } from "./CodeBlock"


export default function Markdown({ message }: { message: string }) {

return (
<React.Fragment>
<ReactMarkdown
Expand All @@ -17,10 +16,10 @@ export default function Markdown({ message }: { message: string }) {
code({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || "")
return !inline ? (
<CodeBlock
language={match ? match[1] : ""}
value={String(children).replace(/\n$/, "")}
/>
<CodeBlock
language={match ? match[1] : ""}
value={String(children).replace(/\n$/, "")}
/>
) : (
<code className={`${className} font-semibold`} {...props}>
{children}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Common/Playground/WebSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next"
export const WebSearch = () => {
const {t} = useTranslation('common')
return (
<div className="gradient-border mt-4 flex w-56 items-center gap-4 rounded-lg bg-neutral-100 p-1ccc text-slate-900 dark:bg-neutral-800 dark:text-slate-50">
<div className="animated-gradient-border mt-4 flex w-56 items-center gap-4 !rounded-lg bg-neutral-100 p-1 text-slate-900 dark:bg-neutral-800 dark:text-slate-50">
<div className="rounded p-1">
<Globe className="w-6 h-6" />
</div>
Expand Down
17 changes: 3 additions & 14 deletions src/components/Option/Playground/PlaygroundForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from "react"
import useDynamicTextareaSize from "~/hooks/useDynamicTextareaSize"
import { toBase64 } from "~/libs/to-base64"
import { useMessageOption } from "~/hooks/useMessageOption"
import { Checkbox, Dropdown, Select, Switch, Tooltip } from "antd"
import { Checkbox, Dropdown, Switch, Tooltip } from "antd"
import { Image } from "antd"
import { useWebUI } from "~/store/webui"
import { defaultEmbeddingModelForRag } from "~/services/ollama"
Expand All @@ -13,6 +13,7 @@ import { getVariable } from "~/utils/select-varaible"
import { useTranslation } from "react-i18next"
import { KnowledgeSelect } from "../Knowledge/KnowledgeSelect"
import { useSpeechRecognition } from "@/hooks/useSpeechRecognition"
import { PiGlobe } from "react-icons/pi"

type Props = {
dropedFile: File | undefined
Expand Down Expand Up @@ -250,19 +251,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
{!selectedKnowledge && (
<Tooltip title={t("tooltip.searchInternet")}>
<div className="inline-flex items-center gap-2">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-5 h-5 dark:text-gray-300">
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418"
/>
</svg>
<PiGlobe className="h-5 w-5 dark:text-gray-300" />
<Switch
value={webSearch}
onChange={(e) => setWebSearch(e)}
Expand Down
31 changes: 23 additions & 8 deletions src/components/Sidepanel/Chat/body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@ import { PlaygroundMessage } from "~/components/Common/Playground/Message"
import { useMessage } from "~/hooks/useMessage"
import { EmptySidePanel } from "../Chat/empty"
import { useWebUI } from "@/store/webui"
import { MessageSourcePopup } from "@/components/Common/Playground/MessageSourcePopup"

export const SidePanelBody = () => {
const { messages, streaming, regenerateLastMessage, editMessage } =
useMessage()
const {
messages,
streaming,
regenerateLastMessage,
editMessage,
isSearchingInternet
} = useMessage()
const divRef = React.useRef<HTMLDivElement>(null)
const [isSourceOpen, setIsSourceOpen] = React.useState(false)
const [source, setSource] = React.useState<any>(null)
const { ttsEnabled } = useWebUI()
React.useEffect(() => {
if (divRef.current) {
Expand All @@ -27,19 +35,26 @@ export const SidePanelBody = () => {
currentMessageIndex={index}
totalMessages={messages.length}
onRengerate={regenerateLastMessage}
isProcessing={streaming}
isSearchingInternet={isSearchingInternet}
sources={message.sources}
onEditFormSubmit={(value) => {
editMessage(index, value, !message.isBot)
}}
isProcessing={streaming}
onSourceClick={(data) => {
setSource(data)
setIsSourceOpen(true)
}}
isTTSEnabled={ttsEnabled}
/>
))}
{import.meta.env.BROWSER === "chrome" ? (
<div className="w-full h-32 md:h-48 flex-shrink-0"></div>
) : (
<div className="w-full h-48 flex-shrink-0"></div>
)}
<div className="w-full h-48 flex-shrink-0"></div>
<div ref={divRef} />
<MessageSourcePopup
open={isSourceOpen}
setOpen={setIsSourceOpen}
source={source}
/>
</div>
)
}
59 changes: 57 additions & 2 deletions src/components/Sidepanel/Chat/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import React from "react"
import useDynamicTextareaSize from "~/hooks/useDynamicTextareaSize"
import { useMessage } from "~/hooks/useMessage"
import { toBase64 } from "~/libs/to-base64"
import { Checkbox, Dropdown, Image, Tooltip } from "antd"
import { Checkbox, Dropdown, Image, Switch, Tooltip } from "antd"
import { useWebUI } from "~/store/webui"
import { defaultEmbeddingModelForRag } from "~/services/ollama"
import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react"
import { useTranslation } from "react-i18next"
import { ModelSelect } from "@/components/Common/ModelSelect"
import { useSpeechRecognition } from "@/hooks/useSpeechRecognition"
import { PiGlobeX, PiGlobe } from "react-icons/pi"

type Props = {
dropedFile: File | undefined
Expand Down Expand Up @@ -88,6 +89,13 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
return
}
}
if (webSearch) {
const defaultEM = await defaultEmbeddingModelForRag()
if (!defaultEM) {
form.setFieldError("message", t("formError.noEmbeddingModel"))
return
}
}
form.reset()
textAreaFocus()
await sendMessage({
Expand All @@ -111,7 +119,9 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
speechToTextLanguage,
stopStreamingRequest,
streaming,
setChatMode
setChatMode,
webSearch,
setWebSearch
} = useMessage()

React.useEffect(() => {
Expand All @@ -137,6 +147,30 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
}
})

React.useEffect(() => {
const handleDrop = (e: DragEvent) => {
e.preventDefault()
if (e.dataTransfer?.items) {
for (let i = 0; i < e.dataTransfer.items.length; i++) {
if (e.dataTransfer.items[i].type === "text/plain") {
e.dataTransfer.items[i].getAsString((text) => {
form.setFieldValue("message", text)
})
}
}
}
}
const handleDragOver = (e: DragEvent) => {
e.preventDefault()
}
textareaRef.current?.addEventListener("drop", handleDrop)
textareaRef.current?.addEventListener("dragover", handleDragOver)
return () => {
textareaRef.current?.removeEventListener("drop", handleDrop)
textareaRef.current?.removeEventListener("dragover", handleDragOver)
}
}, [])

return (
<div className="px-3 pt-3 md:px-6 md:pt-6 bg-gray-50 dark:bg-[#262626] border rounded-t-xl border-black/10 dark:border-gray-600">
<div
Expand Down Expand Up @@ -175,6 +209,13 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
return
}
}
if (webSearch) {
const defaultEM = await defaultEmbeddingModelForRag()
if (!defaultEM) {
form.setFieldError("message", t("formError.noEmbeddingModel"))
return
}
}
await stopListening()
form.reset()
textAreaFocus()
Expand Down Expand Up @@ -210,6 +251,20 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
{...form.getInputProps("message")}
/>
<div className="flex mt-4 justify-end gap-3">
<Tooltip title={t("tooltip.searchInternet")}>
<button
type="button"
onClick={() => setWebSearch(!webSearch)}
className={`inline-flex items-center gap-2 ${
chatMode === "rag" ? "hidden" : "block"
}`}>
{webSearch ? (
<PiGlobe className="h-5 w-5 dark:text-gray-300" />
) : (
<PiGlobeX className="h-5 w-5 text-gray-600 dark:text-gray-400" />
)}
</button>
</Tooltip>
<ModelSelect />
{browserSupportsSpeechRecognition && (
<Tooltip title={t("tooltip.speechToText")}>
Expand Down
2 changes: 1 addition & 1 deletion src/entries/options/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function IndexOption() {
algorithm:
mode === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm,
token: {
fontFamily: i18n.language === "ru" ? "Onest" : "Inter"
fontFamily: "Arimo"
}
}}
renderEmpty={() => (
Expand Down
2 changes: 1 addition & 1 deletion src/entries/options/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html>
<head>
<title>Page Assist - A Web UI for Local AI Models</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="manifest.type" content="browser_action" />
<link href="~/assets/tailwind.css" rel="stylesheet" />
<meta charset="utf-8" />
Expand Down
2 changes: 1 addition & 1 deletion src/entries/sidepanel/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function IndexSidepanel() {
algorithm:
mode === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm,
token: {
fontFamily: i18n.language === "ru" ? "Onest" : "Inter"
fontFamily: "Arimo"
}
}}
renderEmpty={() => (
Expand Down
Loading

0 comments on commit d198b87

Please sign in to comment.