diff --git a/README.md b/README.md
index dfc8933473..20853f6392 100644
--- a/README.md
+++ b/README.md
@@ -57,12 +57,13 @@ Here are my planned/recently finished features.
- [x] AI model change handling (start new convos within existing convo)
- [x] Server convo pagination (limit fetch and load more with 'show more' button)
- [ ] Config file for easy startup
+- [ ] Conversation Search (by title)
+- [ ] Resubmit/edit sent messages
+- [ ] Semantic Search Option (requires more tokens)
- [ ] Bing AI Styling (for suggested responses, convo end, etc.)
-- [ ] Prompt Templates
-- [ ] Conversation/Prompt Search
+- [ ] Prompt Templates/Search
- [ ] Refactor/clean up code (tech debt)
- [ ] Mobile styling (half-finished)
-- [ ] Semantic Search Option (requires more tokens)
### Features
@@ -79,12 +80,18 @@ Here are my planned/recently finished features.
## Use Cases ##
- 
- One stop shop for all conversational AIs, with the added bonus of searching past conversations.
- Using the official API, you'd have to generate 7.5 million words to expense the same cost as ChatGPT Plus ($20).
- - ChatGPT Free is down.
- ChatGPT/Google Bard/Bing AI conversations are lost in space or
cannot be searched past a certain timeframe.
+ - ChatGPT Free (at [chat.openai.com](https://chat.openai.com/chat)) is more limited than the API
+
+ 
+
+ - ChatGPT Free is down.
+
+ 
+
## Origin ##
This project was originally created as a Minimum Viable Product (or MVP) for the [@HackReactor](https://github.com/hackreactor/) Bootcamp. It was built with OpenAI response streaming and most of the UI completed in under 20 hours. During the end of that time, I had most of the UI and basic functionality done. This was created without using any boilerplates or templates, including create-react-app and other toolchains. I didn't follow any 'un-official chatgpt' video tutorials, and simply referenced the official site for the UI. The purpose of the exercise was to learn setting up a full stack project from scratch. Please feel free to give feedback, suggestions, or fork the project for your own use.
diff --git a/models/Conversation.js b/models/Conversation.js
index e45ab68000..32adac4654 100644
--- a/models/Conversation.js
+++ b/models/Conversation.js
@@ -75,13 +75,14 @@ module.exports = {
},
// getConvos: async () => await Conversation.find({}).sort({ created: -1 }).exec(),
getConvos: async (pageNumber = 1, pageSize = 12) => {
- // const skip = (pageNumber - 1) * pageSize;
- const limit = pageNumber * pageSize;
+ const skip = (pageNumber - 1) * pageSize;
+ // const limit = pageNumber * pageSize;
const conversations = await Conversation.find({})
.sort({ created: -1 })
- // .skip(skip)
- .limit(limit)
+ .skip(skip)
+ // .limit(limit)
+ .limit(pageSize)
.exec();
return conversations;
diff --git a/package.json b/package.json
index d6fab9eb41..e9d791cb4e 100644
--- a/package.json
+++ b/package.json
@@ -5,8 +5,10 @@
"main": "index.js",
"scripts": {
"start": "webpack-dev-server .",
- "build": "Webpack . --watch",
- "server": "npx nodemon server/index.js",
+ "build": "Webpack .",
+ "server": "npx node server/index.js",
+ "build-dev": "Webpack . --watch",
+ "server-dev": "npx nodemon server/index.js",
"test": "test"
},
"repository": {
diff --git a/public/use_case2.png b/public/use_case2.png
new file mode 100644
index 0000000000..cd1d715c10
Binary files /dev/null and b/public/use_case2.png differ
diff --git a/src/components/Models/ModelDialog.jsx b/src/components/Models/ModelDialog.jsx
index b613734248..3de7370a26 100644
--- a/src/components/Models/ModelDialog.jsx
+++ b/src/components/Models/ModelDialog.jsx
@@ -16,7 +16,7 @@ import {
DialogTitle
} from '../ui/Dialog.tsx';
-export default function ModelDialog({ mutate }) {
+export default function ModelDialog({ mutate, modelMap }) {
const dispatch = useDispatch();
const [chatGptLabel, setChatGptLabel] = useState('');
const [promptPrefix, setPromptPrefix] = useState('');
@@ -50,7 +50,7 @@ export default function ModelDialog({ mutate }) {
updateCustomGpt.trigger({ value, chatGptLabel, promptPrefix });
mutate();
- setSaveText('Saved!');
+ setSaveText((prev) => prev + 'd!');
setTimeout(() => {
setSaveText('Save');
}, 2500);
@@ -60,6 +60,10 @@ export default function ModelDialog({ mutate }) {
// dispatch(setDisabled(false));
};
+ if (modelMap[chatGptLabel.toLowerCase()] && saveText === 'Save') {
+ setSaveText('Update');
+ }
+
const requiredProp = required ? { required: true } : {};
return (
diff --git a/src/components/Models/ModelMenu.jsx b/src/components/Models/ModelMenu.jsx
index 180354c51d..a53472f9fb 100644
--- a/src/components/Models/ModelMenu.jsx
+++ b/src/components/Models/ModelMenu.jsx
@@ -40,15 +40,12 @@ export default function ModelMenu() {
});
useEffect(() => {
+ trigger();
const lastSelected = JSON.parse(localStorage.getItem('model'));
if (lastSelected && lastSelected !== 'chatgptCustom' && initial[lastSelected]) {
dispatch(setModel(lastSelected));
}
- const cachedModels = JSON.parse(localStorage.getItem('models'));
- if (cachedModels) {
- dispatch(setModels(cachedModels));
- }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@@ -56,10 +53,6 @@ export default function ModelMenu() {
localStorage.setItem('model', JSON.stringify(model));
}, [model]);
- useEffect(() => {
- localStorage.setItem('models', JSON.stringify(models.slice(4)));
- }, [models]);
-
const onChange = (value) => {
if (!value) {
return;
@@ -140,7 +133,7 @@ export default function ModelMenu() {
-
+
);
}
diff --git a/src/components/Nav/index.jsx b/src/components/Nav/index.jsx
index db85b7076c..6316973680 100644
--- a/src/components/Nav/index.jsx
+++ b/src/components/Nav/index.jsx
@@ -6,15 +6,19 @@ import NavLinks from './NavLinks';
import useDidMountEffect from '~/hooks/useDidMountEffect';
import { swr } from '~/utils/fetchers';
import { useDispatch, useSelector } from 'react-redux';
-import { incrementPage } from '~/store/convoSlice';
+import { incrementPage, setConvos } from '~/store/convoSlice';
export default function Nav() {
const dispatch = useDispatch();
const [isHovering, setIsHovering] = useState(false);
- const { conversationId, pageNumber } = useSelector((state) => state.convo);
+ const { conversationId, convos, pageNumber } = useSelector((state) => state.convo);
+ const onSuccess = (data) => {
+ dispatch(setConvos(data));
+ };
+
const { data, isLoading, mutate } = swr(
`http://localhost:3050/convos?pageNumber=${pageNumber}`
- );
+ , onSuccess);
const containerRef = useRef(null);
const scrollPositionRef = useRef(null);
@@ -63,7 +67,7 @@ export default function Nav() {
) : (
- {!showingTemplates && (
+ {/* {!showingTemplates && (
)}
- {!!showingTemplates && }
+ {!!showingTemplates && } */}
diff --git a/src/store/convoSlice.js b/src/store/convoSlice.js
index 15e73c1119..5918dfec7b 100644
--- a/src/store/convoSlice.js
+++ b/src/store/convoSlice.js
@@ -27,8 +27,10 @@ const currentSlice = createSlice({
},
incrementPage: (state) => {
state.pageNumber = state.pageNumber + 1;
- }
- // setConvos: (state, action) => state.convos = action.payload,
+ },
+ setConvos: (state, action) => {
+ state.convos = [...state.convos, ...action.payload];
+ },
}
});