mirror of
https://github.com/NovaOSS/nova-betterchat.git
synced 2024-11-26 00:13:59 +01:00
improve caching
This commit is contained in:
parent
16caec5076
commit
6222bb58f3
27
src/App.tsx
27
src/App.tsx
|
@ -1,39 +1,18 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import useStore from '@store/store';
|
import useStore from '@store/store';
|
||||||
|
|
||||||
import Chat from './components/Chat';
|
import Chat from './components/Chat';
|
||||||
import Menu from './components/Menu';
|
import Menu from './components/Menu';
|
||||||
import ConfigMenu from './components/ConfigMenu';
|
import ConfigMenu from './components/ConfigMenu';
|
||||||
|
|
||||||
import useSaveToLocalStorage from '@hooks/useSaveToLocalStorage';
|
|
||||||
import useInitialiseNewChat from '@hooks/useInitialiseNewChat';
|
import useInitialiseNewChat from '@hooks/useInitialiseNewChat';
|
||||||
|
|
||||||
import { ChatInterface } from '@type/chat';
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
useSaveToLocalStorage();
|
|
||||||
const initialiseNewChat = useInitialiseNewChat();
|
const initialiseNewChat = useInitialiseNewChat();
|
||||||
|
|
||||||
const setChats = useStore((state) => state.setChats);
|
|
||||||
const setCurrentChatIndex = useStore((state) => state.setCurrentChatIndex);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedChats = localStorage.getItem('chats');
|
const chats = useStore.getState().chats;
|
||||||
if (storedChats) {
|
if (!chats || chats.length === 0) {
|
||||||
try {
|
|
||||||
const chats: ChatInterface[] = JSON.parse(storedChats);
|
|
||||||
if (chats.length > 0) {
|
|
||||||
setChats(chats);
|
|
||||||
setCurrentChatIndex(0);
|
|
||||||
} else {
|
|
||||||
initialiseNewChat();
|
|
||||||
}
|
|
||||||
} catch (e: unknown) {
|
|
||||||
setChats([]);
|
|
||||||
setCurrentChatIndex(-1);
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initialiseNewChat();
|
initialiseNewChat();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
@ -23,7 +23,6 @@ const ConfigMenu = () => {
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
setApiKey(_apiKey);
|
setApiKey(_apiKey);
|
||||||
localStorage.setItem('apiKey', _apiKey);
|
|
||||||
setError(false);
|
setError(false);
|
||||||
setOpenConfig(false);
|
setOpenConfig(false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,11 +39,9 @@ const ConfigMenu = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedApiKey = localStorage.getItem('apiKey');
|
if (apiKey) {
|
||||||
if (storedApiKey) {
|
|
||||||
setApiFree(false);
|
setApiFree(false);
|
||||||
setApiKey(storedApiKey);
|
_setApiKey(apiKey);
|
||||||
_setApiKey(storedApiKey);
|
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
import useStore from '@store/store';
|
||||||
import SunIcon from '@icon/SunIcon';
|
import SunIcon from '@icon/SunIcon';
|
||||||
import MoonIcon from '@icon/MoonIcon';
|
import MoonIcon from '@icon/MoonIcon';
|
||||||
|
import { Theme } from '@type/theme';
|
||||||
type Theme = 'light' | 'dark';
|
|
||||||
|
|
||||||
const getOppositeTheme = (theme: Theme): Theme => {
|
const getOppositeTheme = (theme: Theme): Theme => {
|
||||||
if (theme === 'dark') {
|
if (theme === 'dark') {
|
||||||
|
@ -12,26 +12,15 @@ const getOppositeTheme = (theme: Theme): Theme => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const ThemeSwitcher = () => {
|
const ThemeSwitcher = () => {
|
||||||
const [theme, setTheme] = useState<Theme>();
|
const theme = useStore((state) => state.theme);
|
||||||
|
const setTheme = useStore((state) => state.setTheme);
|
||||||
|
|
||||||
const switchTheme = () => {
|
const switchTheme = () => {
|
||||||
setTheme(getOppositeTheme(theme!));
|
setTheme(getOppositeTheme(theme!));
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const _theme = localStorage.getItem('theme');
|
document.documentElement.className = theme;
|
||||||
if (_theme === 'light' || _theme === 'dark') {
|
|
||||||
setTheme(_theme);
|
|
||||||
} else {
|
|
||||||
setTheme('dark');
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (theme) {
|
|
||||||
document.documentElement.className = theme;
|
|
||||||
localStorage.setItem('theme', theme);
|
|
||||||
}
|
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
|
|
||||||
return theme ? (
|
return theme ? (
|
||||||
|
|
|
@ -1,16 +1,26 @@
|
||||||
import { StoreSlice } from './store';
|
import { StoreSlice } from './store';
|
||||||
|
import { Theme } from '@type/theme';
|
||||||
|
|
||||||
export interface ConfigSlice {
|
export interface ConfigSlice {
|
||||||
openConfig: boolean;
|
openConfig: boolean;
|
||||||
|
theme: Theme;
|
||||||
setOpenConfig: (openConfig: boolean) => void;
|
setOpenConfig: (openConfig: boolean) => void;
|
||||||
|
setTheme: (theme: Theme) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createConfigSlice: StoreSlice<ConfigSlice> = (set, get) => ({
|
export const createConfigSlice: StoreSlice<ConfigSlice> = (set, get) => ({
|
||||||
openConfig: false,
|
openConfig: false,
|
||||||
|
theme: 'dark',
|
||||||
setOpenConfig: (openConfig: boolean) => {
|
setOpenConfig: (openConfig: boolean) => {
|
||||||
set((prev: ConfigSlice) => ({
|
set((prev: ConfigSlice) => ({
|
||||||
...prev,
|
...prev,
|
||||||
openConfig: openConfig,
|
openConfig: openConfig,
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
setTheme: (theme: Theme) => {
|
||||||
|
set((prev: ConfigSlice) => ({
|
||||||
|
...prev,
|
||||||
|
theme: theme,
|
||||||
|
}));
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import create, { SetState, GetState } from 'zustand';
|
import create, { SetState, GetState } from 'zustand';
|
||||||
|
import { persist } from 'zustand/middleware';
|
||||||
import { ChatSlice, createChatSlice } from './chat-slice';
|
import { ChatSlice, createChatSlice } from './chat-slice';
|
||||||
import { InputSlice, createInputSlice } from './input-slice';
|
import { InputSlice, createInputSlice } from './input-slice';
|
||||||
import { AuthSlice, createAuthSlice } from './auth-slice';
|
import { AuthSlice, createAuthSlice } from './auth-slice';
|
||||||
|
@ -11,11 +12,24 @@ export type StoreSlice<T> = (
|
||||||
get: GetState<StoreState>
|
get: GetState<StoreState>
|
||||||
) => T;
|
) => T;
|
||||||
|
|
||||||
const useStore = create<StoreState>((set, get) => ({
|
const useStore = create<StoreState>()(
|
||||||
...createChatSlice(set, get),
|
persist(
|
||||||
...createInputSlice(set, get),
|
(set, get) => ({
|
||||||
...createAuthSlice(set, get),
|
...createChatSlice(set, get),
|
||||||
...createConfigSlice(set, get),
|
...createInputSlice(set, get),
|
||||||
}));
|
...createAuthSlice(set, get),
|
||||||
|
...createConfigSlice(set, get),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: 'free-chat-gpt',
|
||||||
|
partialize: (state) => ({
|
||||||
|
chats: state.chats,
|
||||||
|
currentChatIndex: state.currentChatIndex,
|
||||||
|
apiKey: state.apiKey,
|
||||||
|
theme: state.theme,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
export default useStore;
|
export default useStore;
|
||||||
|
|
1
src/types/theme.ts
Normal file
1
src/types/theme.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export type Theme = 'light' | 'dark';
|
Loading…
Reference in a new issue