From 52f84dce9ff737e2ff4f2042708eca758fba0bdc Mon Sep 17 00:00:00 2001 From: NamH Date: Sun, 3 Mar 2024 17:54:01 +0700 Subject: [PATCH] chore: clean up some redundant code (#2215) Signed-off-by: James Co-authored-by: James --- web/containers/Providers/index.tsx | 18 ++-- web/context/FeatureToggle.tsx | 104 ------------------------ web/helpers/atoms/ApiServer.atom.ts | 16 ++++ web/helpers/atoms/AppConfig.atom.ts | 18 ++++ web/hooks/useConvertHuggingFaceModel.ts | 10 +-- web/hooks/useCreateNewThread.ts | 10 +-- web/hooks/useDownloadModel.ts | 15 ++-- web/screens/Chat/ChatInput/index.tsx | 7 +- web/screens/Chat/Sidebar/index.tsx | 10 +-- web/screens/Chat/index.tsx | 7 +- web/screens/ExploreModels/index.tsx | 7 +- web/screens/LocalServer/index.tsx | 32 ++++---- web/screens/Settings/Advanced/index.tsx | 46 +++++------ 13 files changed, 109 insertions(+), 191 deletions(-) delete mode 100644 web/context/FeatureToggle.tsx create mode 100644 web/helpers/atoms/ApiServer.atom.ts diff --git a/web/containers/Providers/index.tsx b/web/containers/Providers/index.tsx index e7a179ec4..73445f10a 100644 --- a/web/containers/Providers/index.tsx +++ b/web/containers/Providers/index.tsx @@ -11,8 +11,6 @@ import EventListenerWrapper from '@/containers/Providers/EventListener' import JotaiWrapper from '@/containers/Providers/Jotai' import ThemeWrapper from '@/containers/Providers/Theme' -import FeatureToggleWrapper from '@/context/FeatureToggle' - import { setupCoreServices } from '@/services/coreService' import { isCoreExtensionInstalled, @@ -81,15 +79,13 @@ const Providers = (props: PropsWithChildren) => { {settingUp && } {setupCore && activated && ( - - - - {children} - - {!isMac && } - - - + + + {children} + + {!isMac && } + + )} diff --git a/web/context/FeatureToggle.tsx b/web/context/FeatureToggle.tsx deleted file mode 100644 index 5a63eb66e..000000000 --- a/web/context/FeatureToggle.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { createContext, ReactNode, useEffect, useState } from 'react' - -interface FeatureToggleContextType { - experimentalFeature: boolean - ignoreSSL: boolean - proxy: string - proxyEnabled: boolean - vulkanEnabled: boolean - setExperimentalFeature: (on: boolean) => void - setVulkanEnabled: (on: boolean) => void - setIgnoreSSL: (on: boolean) => void - setProxy: (value: string) => void - setProxyEnabled: (on: boolean) => void -} - -const initialContext: FeatureToggleContextType = { - experimentalFeature: false, - ignoreSSL: false, - proxy: '', - proxyEnabled: false, - vulkanEnabled: false, - setExperimentalFeature: () => {}, - setVulkanEnabled: () => {}, - setIgnoreSSL: () => {}, - setProxy: () => {}, - setProxyEnabled: () => {}, -} - -export const FeatureToggleContext = - createContext(initialContext) - -export default function FeatureToggleWrapper({ - children, -}: { - children: ReactNode -}) { - const EXPERIMENTAL_FEATURE = 'experimentalFeature' - const VULKAN_ENABLED = 'vulkanEnabled' - const IGNORE_SSL = 'ignoreSSLFeature' - const HTTPS_PROXY_FEATURE = 'httpsProxyFeature' - const PROXY_FEATURE_ENABLED = 'proxyFeatureEnabled' - - const [experimentalFeature, directSetExperimentalFeature] = - useState(false) - const [proxyEnabled, directSetProxyEnabled] = useState(false) - const [vulkanEnabled, directEnableVulkan] = useState(false) - const [ignoreSSL, directSetIgnoreSSL] = useState(false) - const [proxy, directSetProxy] = useState('') - - useEffect(() => { - directSetExperimentalFeature( - localStorage.getItem(EXPERIMENTAL_FEATURE) === 'true' - ) - directSetIgnoreSSL(localStorage.getItem(IGNORE_SSL) === 'true') - directSetProxy(localStorage.getItem(HTTPS_PROXY_FEATURE) ?? '') - directSetProxyEnabled( - localStorage.getItem(PROXY_FEATURE_ENABLED) === 'true' - ) - }, []) - - const setExperimentalFeature = (on: boolean) => { - localStorage.setItem(EXPERIMENTAL_FEATURE, on ? 'true' : 'false') - directSetExperimentalFeature(on) - } - - const setVulkanEnabled = (on: boolean) => { - localStorage.setItem(VULKAN_ENABLED, on ? 'true' : 'false') - directEnableVulkan(on) - } - - const setIgnoreSSL = (on: boolean) => { - localStorage.setItem(IGNORE_SSL, on ? 'true' : 'false') - directSetIgnoreSSL(on) - } - - const setProxy = (proxy: string) => { - localStorage.setItem(HTTPS_PROXY_FEATURE, proxy) - directSetProxy(proxy) - } - - const setProxyEnabled = (on: boolean) => { - localStorage.setItem(PROXY_FEATURE_ENABLED, on ? 'true' : 'false') - directSetProxyEnabled(on) - } - - return ( - - {children} - - ) -} diff --git a/web/helpers/atoms/ApiServer.atom.ts b/web/helpers/atoms/ApiServer.atom.ts new file mode 100644 index 000000000..2ccd2de23 --- /dev/null +++ b/web/helpers/atoms/ApiServer.atom.ts @@ -0,0 +1,16 @@ +import { atomWithStorage } from 'jotai/utils' + +export const hostOptions = ['127.0.0.1', '0.0.0.0'] + +export const apiServerPortAtom = atomWithStorage('apiServerPort', '1337') +export const apiServerHostAtom = atomWithStorage('apiServerHost', '127.0.0.1') + +export const apiServerCorsEnabledAtom = atomWithStorage( + 'apiServerCorsEnabled', + true +) + +export const apiServerVerboseLogEnabledAtom = atomWithStorage( + 'apiServerVerboseLogEnabled', + true +) diff --git a/web/helpers/atoms/AppConfig.atom.ts b/web/helpers/atoms/AppConfig.atom.ts index 9dfdfca90..75343d722 100644 --- a/web/helpers/atoms/AppConfig.atom.ts +++ b/web/helpers/atoms/AppConfig.atom.ts @@ -1,3 +1,21 @@ import { atom } from 'jotai' +import { atomWithStorage } from 'jotai/utils' + +const EXPERIMENTAL_FEATURE = 'experimentalFeature' +const PROXY_FEATURE_ENABLED = 'proxyFeatureEnabled' +const VULKAN_ENABLED = 'vulkanEnabled' +const IGNORE_SSL = 'ignoreSSLFeature' +const HTTPS_PROXY_FEATURE = 'httpsProxyFeature' export const janDataFolderPathAtom = atom('') + +export const experimentalFeatureEnabledAtom = atomWithStorage( + EXPERIMENTAL_FEATURE, + false +) + +export const proxyEnabledAtom = atomWithStorage(PROXY_FEATURE_ENABLED, false) +export const proxyAtom = atomWithStorage(HTTPS_PROXY_FEATURE, '') + +export const ignoreSslAtom = atomWithStorage(IGNORE_SSL, false) +export const vulkanEnabledAtom = atomWithStorage(VULKAN_ENABLED, false) diff --git a/web/hooks/useConvertHuggingFaceModel.ts b/web/hooks/useConvertHuggingFaceModel.ts index bbf33207b..0616c4ee7 100644 --- a/web/hooks/useConvertHuggingFaceModel.ts +++ b/web/hooks/useConvertHuggingFaceModel.ts @@ -1,5 +1,3 @@ -import { useContext } from 'react' - import { ExtensionTypeEnum, HuggingFaceExtension, @@ -7,18 +5,18 @@ import { Quantization, } from '@janhq/core' -import { useSetAtom } from 'jotai' - -import { FeatureToggleContext } from '@/context/FeatureToggle' +import { useAtomValue, useSetAtom } from 'jotai' import { extensionManager } from '@/extension/ExtensionManager' +import { ignoreSslAtom, proxyAtom } from '@/helpers/atoms/AppConfig.atom' import { conversionStatusAtom, conversionErrorAtom, } from '@/helpers/atoms/HFConverter.atom' export const useConvertHuggingFaceModel = () => { - const { ignoreSSL, proxy } = useContext(FeatureToggleContext) + const proxy = useAtomValue(proxyAtom) + const ignoreSSL = useAtomValue(ignoreSslAtom) const setConversionStatus = useSetAtom(conversionStatusAtom) const setConversionError = useSetAtom(conversionErrorAtom) diff --git a/web/hooks/useCreateNewThread.ts b/web/hooks/useCreateNewThread.ts index 722e5b7e4..247c65c55 100644 --- a/web/hooks/useCreateNewThread.ts +++ b/web/hooks/useCreateNewThread.ts @@ -1,5 +1,3 @@ -import { useContext } from 'react' - import { Assistant, ConversationalExtension, @@ -17,8 +15,6 @@ import { atom, useAtomValue, useSetAtom } from 'jotai' import { selectedModelAtom } from '@/containers/DropdownListSidebar' import { fileUploadAtom } from '@/containers/Providers/Jotai' -import { FeatureToggleContext } from '@/context/FeatureToggle' - import { generateThreadId } from '@/utils/thread' import useRecommendedModel from './useRecommendedModel' @@ -27,6 +23,7 @@ import useSetActiveThread from './useSetActiveThread' import { extensionManager } from '@/extension' +import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { threadsAtom, threadStatesAtom, @@ -59,7 +56,8 @@ export const useCreateNewThread = () => { const setFileUpload = useSetAtom(fileUploadAtom) const setSelectedModel = useSetAtom(selectedModelAtom) const setThreadModelParams = useSetAtom(setThreadModelParamsAtom) - const { experimentalFeature } = useContext(FeatureToggleContext) + + const experimentalEnabled = useAtomValue(experimentalFeatureEnabledAtom) const setIsGeneratingResponse = useSetAtom(isGeneratingResponseAtom) const { recommendedModel, downloadedModels } = useRecommendedModel() @@ -94,7 +92,7 @@ export const useCreateNewThread = () => { const assistantInfo: ThreadAssistantInfo = { assistant_id: assistant.id, assistant_name: assistant.name, - tools: experimentalFeature ? [assistantTools] : assistant.tools, + tools: experimentalEnabled ? [assistantTools] : assistant.tools, model: { id: defaultModel?.id ?? '*', settings: defaultModel?.settings ?? {}, diff --git a/web/hooks/useDownloadModel.ts b/web/hooks/useDownloadModel.ts index 59333fbde..9f6334c71 100644 --- a/web/hooks/useDownloadModel.ts +++ b/web/hooks/useDownloadModel.ts @@ -1,4 +1,4 @@ -import { useCallback, useContext } from 'react' +import { useCallback } from 'react' import { Model, @@ -10,17 +10,22 @@ import { DownloadState, } from '@janhq/core' -import { useSetAtom } from 'jotai' - -import { FeatureToggleContext } from '@/context/FeatureToggle' +import { useAtomValue, useSetAtom } from 'jotai' import { setDownloadStateAtom } from './useDownloadState' import { extensionManager } from '@/extension/ExtensionManager' +import { + ignoreSslAtom, + proxyAtom, + proxyEnabledAtom, +} from '@/helpers/atoms/AppConfig.atom' import { addDownloadingModelAtom } from '@/helpers/atoms/Model.atom' export default function useDownloadModel() { - const { ignoreSSL, proxy, proxyEnabled } = useContext(FeatureToggleContext) + const ignoreSSL = useAtomValue(ignoreSslAtom) + const proxy = useAtomValue(proxyAtom) + const proxyEnabled = useAtomValue(proxyEnabledAtom) const setDownloadState = useSetAtom(setDownloadStateAtom) const addDownloadingModel = useSetAtom(addDownloadingModelAtom) diff --git a/web/screens/Chat/ChatInput/index.tsx b/web/screens/Chat/ChatInput/index.tsx index 5b8128439..d5334cab8 100644 --- a/web/screens/Chat/ChatInput/index.tsx +++ b/web/screens/Chat/ChatInput/index.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { useContext, useEffect, useRef, useState } from 'react' +import { useEffect, useRef, useState } from 'react' import { InferenceEvent, MessageStatus, events } from '@janhq/core' @@ -24,8 +24,6 @@ import { twMerge } from 'tailwind-merge' import { currentPromptAtom, fileUploadAtom } from '@/containers/Providers/Jotai' -import { FeatureToggleContext } from '@/context/FeatureToggle' - import { useActiveModel } from '@/hooks/useActiveModel' import { useClickOutside } from '@/hooks/useClickOutside' @@ -34,6 +32,7 @@ import useSendChatMessage from '@/hooks/useSendChatMessage' import FileUploadPreview from '../FileUploadPreview' import ImageUploadPreview from '../ImageUploadPreview' +import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom' import { activeThreadAtom, @@ -58,7 +57,7 @@ const ChatInput: React.FC = () => { const fileInputRef = useRef(null) const imageInputRef = useRef(null) const [showAttacmentMenus, setShowAttacmentMenus] = useState(false) - const { experimentalFeature } = useContext(FeatureToggleContext) + const experimentalFeature = useAtomValue(experimentalFeatureEnabledAtom) const isGeneratingResponse = useAtomValue(isGeneratingResponseAtom) const threadStates = useAtomValue(threadStatesAtom) diff --git a/web/screens/Chat/Sidebar/index.tsx b/web/screens/Chat/Sidebar/index.tsx index 4f7e1bd50..2ff5a1253 100644 --- a/web/screens/Chat/Sidebar/index.tsx +++ b/web/screens/Chat/Sidebar/index.tsx @@ -1,5 +1,4 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import React, { useContext } from 'react' +import React from 'react' import { Input, @@ -24,8 +23,6 @@ import DropdownListSidebar, { selectedModelAtom, } from '@/containers/DropdownListSidebar' -import { FeatureToggleContext } from '@/context/FeatureToggle' - import { useCreateNewThread } from '@/hooks/useCreateNewThread' import { getConfigurationsData } from '@/utils/componentSettings' @@ -37,6 +34,7 @@ import ModelSetting from '../ModelSetting' import SettingComponentBuilder from '../ModelSetting/SettingComponent' +import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { activeThreadAtom, getActiveThreadModelParamsAtom, @@ -50,7 +48,7 @@ const Sidebar: React.FC = () => { const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom) const selectedModel = useAtomValue(selectedModelAtom) const { updateThreadMetadata } = useCreateNewThread() - const { experimentalFeature } = useContext(FeatureToggleContext) + const experimentalFeature = useAtomValue(experimentalFeatureEnabledAtom) const modelEngineParams = toSettingParams(activeModelParams) const modelRuntimeParams = toRuntimeParams(activeModelParams) @@ -174,7 +172,7 @@ const Sidebar: React.FC = () => {
x.name === 'prompt_template'} + selector={(x) => x.name === 'prompt_template'} />
diff --git a/web/screens/Chat/index.tsx b/web/screens/Chat/index.tsx index 125e58b3b..00bca550f 100644 --- a/web/screens/Chat/index.tsx +++ b/web/screens/Chat/index.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import React, { useContext, useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import { useDropzone } from 'react-dropzone' @@ -18,8 +18,6 @@ import { showLeftSideBarAtom } from '@/containers/Providers/KeyListener' import { snackbar } from '@/containers/Toast' -import { FeatureToggleContext } from '@/context/FeatureToggle' - import { activeModelAtom } from '@/hooks/useActiveModel' import { queuedMessageAtom, reloadModelAtom } from '@/hooks/useSendChatMessage' @@ -31,6 +29,7 @@ import ChatInput from './ChatInput' import RequestDownloadModel from './RequestDownloadModel' import Sidebar from './Sidebar' +import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { activeThreadAtom, engineParamsUpdateAtom, @@ -63,7 +62,7 @@ const ChatScreen: React.FC = () => { const reloadModel = useAtomValue(reloadModelAtom) const [dragRejected, setDragRejected] = useState({ code: '' }) const setFileUpload = useSetAtom(fileUploadAtom) - const { experimentalFeature } = useContext(FeatureToggleContext) + const experimentalFeature = useAtomValue(experimentalFeatureEnabledAtom) const activeModel = useAtomValue(activeModelAtom) diff --git a/web/screens/ExploreModels/index.tsx b/web/screens/ExploreModels/index.tsx index e7fd3a9dc..a949e9ffb 100644 --- a/web/screens/ExploreModels/index.tsx +++ b/web/screens/ExploreModels/index.tsx @@ -1,4 +1,4 @@ -import { useCallback, useContext, useState } from 'react' +import { useCallback, useState } from 'react' import { Input, @@ -15,13 +15,12 @@ import { import { useAtomValue, useSetAtom } from 'jotai' import { UploadIcon, SearchIcon } from 'lucide-react' -import { FeatureToggleContext } from '@/context/FeatureToggle' - import { setImportModelStageAtom } from '@/hooks/useImportModel' import ExploreModelList from './ExploreModelList' import { HuggingFaceModal } from './HuggingFaceModal' +import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { configuredModelsAtom, downloadedModelsAtom, @@ -38,7 +37,7 @@ const ExploreModelsScreen = () => { const [showHuggingFaceModal, setShowHuggingFaceModal] = useState(false) const setImportModelStage = useSetAtom(setImportModelStageAtom) - const { experimentalFeature } = useContext(FeatureToggleContext) + const experimentalFeature = useAtomValue(experimentalFeatureEnabledAtom) const filteredModels = configuredModels.filter((x) => { if (sortSelected === 'Downloaded') { diff --git a/web/screens/LocalServer/index.tsx b/web/screens/LocalServer/index.tsx index 3a8668770..66b6046a1 100644 --- a/web/screens/LocalServer/index.tsx +++ b/web/screens/LocalServer/index.tsx @@ -20,7 +20,7 @@ import { SelectValue, } from '@janhq/uikit' -import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai' +import { useAtom, useAtomValue, useSetAtom } from 'jotai' import { Paintbrush, CodeIcon } from 'lucide-react' import { ExternalLinkIcon, InfoIcon } from 'lucide-react' @@ -53,13 +53,15 @@ import SettingComponentBuilder from '../Chat/ModelSetting/SettingComponent' import { showRightSideBarAtom } from '../Chat/Sidebar' +import { + apiServerCorsEnabledAtom, + apiServerHostAtom, + apiServerPortAtom, + apiServerVerboseLogEnabledAtom, + hostOptions, +} from '@/helpers/atoms/ApiServer.atom' import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom' -const corsEnabledAtom = atom(true) -const verboseEnabledAtom = atom(true) -const hostAtom = atom('127.0.0.1') -const portAtom = atom('1337') - const LocalServerScreen = () => { const [errorRangePort, setErrorRangePort] = useState(false) const [serverEnabled, setServerEnabled] = useAtom(serverEnabledAtom) @@ -73,14 +75,14 @@ const LocalServerScreen = () => { const modelEngineParams = toSettingParams(selectedModel?.settings) const componentDataEngineSetting = getConfigurationsData(modelEngineParams) - const [isCorsEnabled, setIsCorsEnabled] = useAtom(corsEnabledAtom) - const [isVerboseEnabled, setIsVerboseEnabled] = useAtom(verboseEnabledAtom) - const [host, setHost] = useAtom(hostAtom) - const [port, setPort] = useAtom(portAtom) + const [isCorsEnabled, setIsCorsEnabled] = useAtom(apiServerCorsEnabledAtom) + const [isVerboseEnabled, setIsVerboseEnabled] = useAtom( + apiServerVerboseLogEnabledAtom + ) + const [host, setHost] = useAtom(apiServerHostAtom) + const [port, setPort] = useAtom(apiServerPortAtom) const [loadModelError, setLoadModelError] = useAtom(loadModelErrorAtom) - const hostOptions = ['127.0.0.1', '0.0.0.0'] - const FIRST_TIME_VISIT_API_SERVER = 'firstTimeVisitAPIServer' const [firstTimeVisitAPIServer, setFirstTimeVisitAPIServer] = @@ -88,11 +90,7 @@ const LocalServerScreen = () => { const handleChangePort = useCallback( (value: string) => { - if (Number(value) <= 0 || Number(value) >= 65536) { - setErrorRangePort(true) - } else { - setErrorRangePort(false) - } + setErrorRangePort(Number(value) <= 0 || Number(value) >= 65536) setPort(value) }, [setPort] diff --git a/web/screens/Settings/Advanced/index.tsx b/web/screens/Settings/Advanced/index.tsx index 9aa204999..a1b377024 100644 --- a/web/screens/Settings/Advanced/index.tsx +++ b/web/screens/Settings/Advanced/index.tsx @@ -1,12 +1,6 @@ 'use client' -import { - useContext, - useEffect, - useState, - useCallback, - ChangeEvent, -} from 'react' +import { useEffect, useState, useCallback, ChangeEvent } from 'react' import { openExternalUrl, fs } from '@janhq/core' @@ -29,20 +23,27 @@ import { ScrollArea, } from '@janhq/uikit' +import { useAtom } from 'jotai' import { AlertTriangleIcon, AlertCircleIcon } from 'lucide-react' import ShortcutModal from '@/containers/ShortcutModal' import { snackbar, toaster } from '@/containers/Toast' -import { FeatureToggleContext } from '@/context/FeatureToggle' - import { useActiveModel } from '@/hooks/useActiveModel' import { useSettings } from '@/hooks/useSettings' import DataFolder from './DataFolder' import FactoryReset from './FactoryReset' +import { + experimentalFeatureEnabledAtom, + ignoreSslAtom, + proxyAtom, + proxyEnabledAtom, + vulkanEnabledAtom, +} from '@/helpers/atoms/AppConfig.atom' + type GPU = { id: string vram: number | null @@ -50,22 +51,19 @@ type GPU = { } const Advanced = () => { - const { - experimentalFeature, - setExperimentalFeature, - ignoreSSL, - setIgnoreSSL, - proxy, - setProxy, - proxyEnabled, - setProxyEnabled, - vulkanEnabled, - setVulkanEnabled, - } = useContext(FeatureToggleContext) + const [experimentalEnabled, setExperimentalEnabled] = useAtom( + experimentalFeatureEnabledAtom + ) + const [vulkanEnabled, setVulkanEnabled] = useAtom(vulkanEnabledAtom) + const [proxyEnabled, setProxyEnabled] = useAtom(proxyEnabledAtom) + const [proxy, setProxy] = useAtom(proxyAtom) + const [ignoreSSL, setIgnoreSSL] = useAtom(ignoreSslAtom) + const [partialProxy, setPartialProxy] = useState(proxy) const [gpuEnabled, setGpuEnabled] = useState(false) const [gpuList, setGpuList] = useState([]) const [gpusInUse, setGpusInUse] = useState([]) + const { readSettings, saveSettings, validateSettings, setShowNotification } = useSettings() const { stopModel } = useActiveModel() @@ -169,8 +167,8 @@ const Advanced = () => {

@@ -355,7 +353,7 @@ const Advanced = () => { )} {/* Vulkan for AMD GPU/ APU and Intel Arc GPU */} - {!isMac && experimentalFeature && ( + {!isMac && experimentalEnabled && (