v0.2.0
This commit is contained in:
33
app/src/store/api-keys.ts
Normal file
33
app/src/store/api-keys.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import type { RootState } from '.';
|
||||
|
||||
const initialState: {
|
||||
openAIApiKey?: string | null | undefined;
|
||||
elevenLabsApiKey?: string | null | undefined;
|
||||
} = {
|
||||
openAIApiKey: localStorage.getItem('openai-api-key'),
|
||||
elevenLabsApiKey: localStorage.getItem('elevenlabs-api-key'),
|
||||
};
|
||||
|
||||
export const apiKeysSlice = createSlice({
|
||||
name: 'apiKeys',
|
||||
initialState,
|
||||
reducers: {
|
||||
setOpenAIApiKey: (state, action: PayloadAction<string>) => {
|
||||
state.openAIApiKey = action.payload;
|
||||
},
|
||||
setElevenLabsApiKey: (state, action: PayloadAction<string>) => {
|
||||
state.elevenLabsApiKey = action.payload;
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export const { setOpenAIApiKey, setElevenLabsApiKey } = apiKeysSlice.actions;
|
||||
|
||||
export const setOpenAIApiKeyFromEvent = (event: React.ChangeEvent<HTMLInputElement>) => apiKeysSlice.actions.setOpenAIApiKey(event.target.value);
|
||||
export const setElevenLabsApiKeyFromEvent = (event: React.ChangeEvent<HTMLInputElement>) => apiKeysSlice.actions.setElevenLabsApiKey(event.target.value);
|
||||
|
||||
export const selectOpenAIApiKey = (state: RootState) => state.apiKeys.openAIApiKey;
|
||||
export const selectElevenLabsApiKey = (state: RootState) => state.apiKeys.elevenLabsApiKey;
|
||||
|
||||
export default apiKeysSlice.reducer;
|
44
app/src/store/index.ts
Normal file
44
app/src/store/index.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { persistReducer, persistStore } from 'redux-persist';
|
||||
import messageReducer from './message';
|
||||
import parametersReducer from './parameters';
|
||||
import apiKeysReducer from './api-keys';
|
||||
import voiceReducer from './voices';
|
||||
import settingsUIReducer from './settings-ui';
|
||||
import uiReducer from './ui';
|
||||
import sidebarReducer from './sidebar';
|
||||
|
||||
const persistConfig = {
|
||||
key: 'root',
|
||||
storage,
|
||||
}
|
||||
|
||||
const persistSidebarConfig = {
|
||||
key: 'sidebar',
|
||||
storage,
|
||||
}
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
// auth: authReducer,
|
||||
apiKeys: persistReducer(persistConfig, apiKeysReducer),
|
||||
settingsUI: settingsUIReducer,
|
||||
voices: persistReducer(persistConfig, voiceReducer),
|
||||
parameters: persistReducer(persistConfig, parametersReducer),
|
||||
message: messageReducer,
|
||||
ui: uiReducer,
|
||||
sidebar: persistReducer(persistSidebarConfig, sidebarReducer),
|
||||
},
|
||||
})
|
||||
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
|
||||
export const useAppDispatch: () => AppDispatch = useDispatch;
|
||||
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||
|
||||
export const persistor = persistStore(store);
|
||||
|
||||
export default store;
|
22
app/src/store/message.ts
Normal file
22
app/src/store/message.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import type { RootState } from '.';
|
||||
|
||||
const initialState = {
|
||||
message: '',
|
||||
};
|
||||
|
||||
export const messageSlice = createSlice({
|
||||
name: 'message',
|
||||
initialState,
|
||||
reducers: {
|
||||
setMessage: (state, action: PayloadAction<string>) => {
|
||||
state.message = action.payload;
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setMessage } = messageSlice.actions;
|
||||
|
||||
export const selectMessage = (state: RootState) => state.message.message;
|
||||
|
||||
export default messageSlice.reducer;
|
30
app/src/store/parameters.ts
Normal file
30
app/src/store/parameters.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
import type { RootState } from '.';
|
||||
import { defaultSystemPrompt } from '../openai';
|
||||
import { defaultParameters } from '../parameters';
|
||||
import { Parameters } from '../types';
|
||||
|
||||
const initialState: Parameters = defaultParameters;
|
||||
|
||||
export const parametersSlice = createSlice({
|
||||
name: 'parameters',
|
||||
initialState,
|
||||
reducers: {
|
||||
setSystemPrompt: (state, action: PayloadAction<string>) => {
|
||||
state.initialSystemPrompt = action.payload;
|
||||
},
|
||||
resetSystemPrompt: (state) => {
|
||||
state.initialSystemPrompt = defaultSystemPrompt;
|
||||
},
|
||||
setTemperature: (state, action: PayloadAction<number>) => {
|
||||
state.temperature = action.payload;
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setSystemPrompt, setTemperature, resetSystemPrompt } = parametersSlice.actions;
|
||||
|
||||
export const selectSystemPrompt = (state: RootState) => state.parameters.initialSystemPrompt;
|
||||
export const selectTemperature = (state: RootState) => state.parameters.temperature;
|
||||
|
||||
export default parametersSlice.reducer;
|
38
app/src/store/settings-ui.ts
Normal file
38
app/src/store/settings-ui.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
import type { RootState } from '.';
|
||||
|
||||
const initialState = {
|
||||
tab: '',
|
||||
option: '',
|
||||
};
|
||||
|
||||
export const settingsUISlice = createSlice({
|
||||
name: 'settingsUI',
|
||||
initialState,
|
||||
reducers: {
|
||||
setTab: (state, action: PayloadAction<string|null>) => {
|
||||
state.tab = action.payload || '';
|
||||
},
|
||||
setOption: (state, action: PayloadAction<string|null>) => {
|
||||
state.option = action.payload || '';
|
||||
},
|
||||
setTabAndOption: (state, action: PayloadAction<{ tab: string | null, option: string | null }>) => {
|
||||
state.tab = action.payload.tab || '';
|
||||
state.option = action.payload.option || '';
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setTab, setOption, setTabAndOption } = settingsUISlice.actions;
|
||||
|
||||
export const closeSettingsUI = () => settingsUISlice.actions.setTabAndOption({ tab: '', option: '' });
|
||||
|
||||
export const selectSettingsTab = (state: RootState) => state.settingsUI.tab;
|
||||
export const selectSettingsOption = (state: RootState) => state.settingsUI.option;
|
||||
|
||||
export const openOpenAIApiKeyPanel = () => settingsUISlice.actions.setTabAndOption({ tab: 'user', option: 'openai-api-key' });
|
||||
export const openElevenLabsApiKeyPanel = () => settingsUISlice.actions.setTabAndOption({ tab: 'speech', option: 'elevenlabs-api-key' });
|
||||
export const openSystemPromptPanel = () => settingsUISlice.actions.setTabAndOption({ tab: 'options', option: 'system-prompt' });
|
||||
export const openTemperaturePanel = () => settingsUISlice.actions.setTabAndOption({ tab: 'options', option: 'temperature' });
|
||||
|
||||
export default settingsUISlice.reducer;
|
28
app/src/store/sidebar.ts
Normal file
28
app/src/store/sidebar.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
import type { RootState } from '.';
|
||||
|
||||
const initialState = {
|
||||
open: false,
|
||||
};
|
||||
|
||||
export const uiSlice = createSlice({
|
||||
name: 'sidebar',
|
||||
initialState,
|
||||
reducers: {
|
||||
openSidebar(state) {
|
||||
state.open = true;
|
||||
},
|
||||
closeSidebar(state) {
|
||||
state.open = false;
|
||||
},
|
||||
toggleSidebar(state) {
|
||||
state.open = !state.open;
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { openSidebar, closeSidebar, toggleSidebar } = uiSlice.actions;
|
||||
|
||||
export const selectSidebarOpen = (state: RootState) => state.sidebar.open;
|
||||
|
||||
export default uiSlice.reducer;
|
28
app/src/store/ui.ts
Normal file
28
app/src/store/ui.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
import type { RootState } from '.';
|
||||
|
||||
const initialState = {
|
||||
modal: '',
|
||||
};
|
||||
|
||||
export const uiSlice = createSlice({
|
||||
name: 'ui',
|
||||
initialState,
|
||||
reducers: {
|
||||
openLoginModal(state) {
|
||||
state.modal = 'login';
|
||||
},
|
||||
openSignupModal(state) {
|
||||
state.modal = 'signup';
|
||||
},
|
||||
closeModals(state) {
|
||||
state.modal = '';
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { openLoginModal, openSignupModal, closeModals } = uiSlice.actions;
|
||||
|
||||
export const selectModal = (state: RootState) => state.ui.modal;
|
||||
|
||||
export default uiSlice.reducer;
|
23
app/src/store/voices.ts
Normal file
23
app/src/store/voices.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import type { RootState } from '.';
|
||||
import { defaultElevenLabsVoiceID } from '../tts/defaults';
|
||||
|
||||
const initialState = {
|
||||
voice: defaultElevenLabsVoiceID,
|
||||
};
|
||||
|
||||
export const voicesSlice = createSlice({
|
||||
name: 'voices',
|
||||
initialState,
|
||||
reducers: {
|
||||
setVoice: (state, action: PayloadAction<string|null>) => {
|
||||
state.voice = action.payload || '';
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setVoice } = voicesSlice.actions;
|
||||
|
||||
export const selectVoice = (state: RootState) => state.voices.voice;
|
||||
|
||||
export default voicesSlice.reducer;
|
Reference in New Issue
Block a user