improve caching

This commit is contained in:
Jing Hua 2023-03-05 23:56:26 +08:00
parent 16caec5076
commit 6222bb58f3
6 changed files with 42 additions and 52 deletions

View file

@ -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();
} }
}, []); }, []);

View file

@ -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);
} }
}, []); }, []);

View file

@ -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 ? (

View file

@ -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,
}));
},
}); });

View file

@ -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
View file

@ -0,0 +1 @@
export type Theme = 'light' | 'dark';