Merge branch 'feat-resubmit' into refactors

This commit is contained in:
Danny Avila 2023-03-14 16:09:25 -04:00 committed by GitHub
commit c230fe41f4
8 changed files with 84 additions and 46 deletions

View file

@ -91,19 +91,17 @@ module.exports = {
}
},
// getConvos: async () => await Conversation.find({}).sort({ createdAt: -1 }).exec(),
getConvos: async (pageNumber = 1, pageSize = 12) => {
getConvosByPage: async (pageNumber = 1, pageSize = 12) => {
try {
const skip = (pageNumber - 1) * pageSize;
// const limit = pageNumber * pageSize;
const conversations = await Conversation.find({})
const totalConvos = await Conversation.countDocuments();
const totalPages = Math.ceil(totalConvos / pageSize);
const convos = await Conversation.find()
.sort({ createdAt: -1, created: -1 })
.skip(skip)
// .limit(limit)
.skip((pageNumber - 1) * pageSize)
.limit(pageSize)
.exec();
return conversations;
return { conversations: convos, pages: totalPages, pageNumber, pageSize };
} catch (error) {
console.log(error);
return { message: 'Error getting conversations' };

View file

@ -2,12 +2,12 @@ const express = require('express');
const router = express.Router();
const { titleConvo } = require('../../app/');
const { getConvo, saveConvo, getConvoTitle } = require('../../models');
const { getConvos, deleteConvos, updateConvo } = require('../../models/Conversation');
const { getConvosByPage, deleteConvos, updateConvo } = require('../../models/Conversation');
const { getMessages } = require('../../models/Message');
router.get('/', async (req, res) => {
const pageNumber = req.query.pageNumber || 1;
res.status(200).send(await getConvos(pageNumber));
res.status(200).send(await getConvosByPage(pageNumber));
});
router.post('/gen_title', async (req, res) => {

View file

@ -1,10 +1,10 @@
import React from 'react';
import Conversation from './Conversation';
export default function Conversations({ conversations, conversationId, showMore }) {
const clickHandler = async (e) => {
export default function Conversations({ conversations, conversationId, pageNumber, pages, nextPage, previousPage, moveToTop }) {
const clickHandler = (func) => async (e) => {
e.preventDefault();
await showMore();
await func();
};
return (
@ -33,18 +33,29 @@ export default function Conversations({ conversations, conversationId, showMore
chatGptLabel={convo.chatGptLabel}
promptPrefix={convo.promptPrefix}
bingData={bingData}
retainView={showMore.bind(null, false)}
retainView={moveToTop}
/>
);
})}
{conversations?.length >= 12 && (
<button
onClick={clickHandler}
className="btn btn-dark btn-small m-auto mb-2 flex justify-center gap-2"
>
Show more
</button>
)}
<div className="m-auto mt-4 mb-2 flex justify-center items-center gap-2">
<button
onClick={clickHandler(previousPage)}
className={"flex btn btn-small transition bg-transition dark:text-white disabled:text-gray-300 dark:disabled:text-gray-400 m-auto gap-2 hover:bg-gray-800" + (pageNumber<=1?" hidden-visibility":"")}
disabled={pageNumber<=1}
>
&lt;&lt;
</button>
<span className="flex-none text-gray-400">
{pageNumber} / {pages}
</span>
<button
onClick={clickHandler(nextPage)}
className={"flex btn btn-small transition bg-transition dark:text-white disabled:text-gray-300 dark:disabled:text-gray-400 m-auto gap-2 hover:bg-gray-800" + (pageNumber>=pages?" hidden-visibility":"")}
disabled={pageNumber>=pages}
>
&gt;&gt;
</button>
</div>
</>
);
}

View file

@ -7,7 +7,7 @@ import { setText } from '~/store/textSlice';
export default function MobileNav({ setNavVisible }) {
const dispatch = useDispatch();
const { conversationId, convos } = useSelector((state) => state.convo);
const { conversationId, convos, title } = useSelector((state) => state.convo);
const toggleNavVisible = () => {
setNavVisible((prev) => {
@ -22,8 +22,6 @@ export default function MobileNav({ setNavVisible }) {
dispatch(setSubmission({}));
}
const title = convos?.find(element => element?.conversationId == conversationId)?.title || 'New Chat';
return (
<div className="sticky top-0 z-10 flex items-center border-b border-white/20 bg-gray-800 pl-1 pt-1 text-gray-200 sm:pl-3 md:hidden">
<button
@ -64,7 +62,7 @@ export default function MobileNav({ setNavVisible }) {
/>
</svg>
</button>
<h1 className="flex-1 text-center text-base font-normal">{title}</h1>
<h1 className="flex-1 text-center text-base font-normal">{title || 'New Chat'}</h1>
<button
type="button"
className="px-3"

View file

@ -6,37 +6,53 @@ import NavLinks from './NavLinks';
import useDidMountEffect from '~/hooks/useDidMountEffect';
import { swr } from '~/utils/fetchers';
import { useDispatch, useSelector } from 'react-redux';
import { incrementPage, setConvos } from '~/store/convoSlice';
import { increasePage, decreasePage, setPage, setConvos, setPages } from '~/store/convoSlice';
export default function Nav({ navVisible, setNavVisible }) {
const dispatch = useDispatch();
const [isHovering, setIsHovering] = useState(false);
const { conversationId, convos, pageNumber, refreshConvoHint } = useSelector((state) => state.convo);
const { conversationId, convos, pages, pageNumber, refreshConvoHint } = useSelector((state) => state.convo);
const onSuccess = (data) => {
dispatch(setConvos(data));
const { conversations, pages } = data;
if (pageNumber > pages)
dispatch(setPage(pages));
else
dispatch(setConvos(conversations));
dispatch(setPages(pages));
};
const { data, isLoading, mutate } = swr(
`/api/convos?pageNumber=${pageNumber}`,
onSuccess
onSuccess,
{revalidateOnMount: false}
);
const containerRef = useRef(null);
const scrollPositionRef = useRef(null);
const showMore = async (increment = true) => {
const moveToTop = () => {
const container = containerRef.current;
if (container) {
scrollPositionRef.current = container.scrollTop;
}
}
if (increment) {
dispatch(incrementPage());
await mutate();
}
const nextPage = async () => {
moveToTop()
dispatch(increasePage());
await mutate();
};
useDidMountEffect(() => mutate(), [conversationId, refreshConvoHint]);
const previousPage = async () => {
moveToTop()
dispatch(decreasePage());
await mutate();
};
useEffect(() => {mutate()}, [pageNumber, conversationId, refreshConvoHint]);
useEffect(() => {
const container = containerRef.current;
@ -86,8 +102,11 @@ export default function Nav({ navVisible, setNavVisible }) {
<Conversations
conversations={convos}
conversationId={conversationId}
showMore={showMore}
nextPage={nextPage}
previousPage={previousPage}
moveToTop={moveToTop}
pageNumber={pageNumber}
pages={pages}
/>
)}
</div>

View file

@ -13,8 +13,9 @@ const initialState = {
promptPrefix: null,
convosLoading: false,
pageNumber: 1,
pages: 1,
refreshConvoHint: 0,
convos: []
convos: [],
};
const currentSlice = createSlice({
@ -30,12 +31,18 @@ const currentSlice = createSlice({
setError: (state, action) => {
state.error = action.payload;
},
incrementPage: (state) => {
increasePage: (state) => {
state.pageNumber = state.pageNumber + 1;
},
decreasePage: (state) => {
state.pageNumber = state.pageNumber - 1;
},
setPage: (state, action) => {
state.pageNumber = action.payload;
},
setNewConvo: (state) => {
state.error = false;
state.title = 'New Chat';
state.title = 'ChatGPT Clone';
state.conversationId = null;
state.parentMessageId = null;
state.jailbreakConversationId = null;
@ -45,13 +52,15 @@ const currentSlice = createSlice({
state.chatGptLabel = null;
state.promptPrefix = null;
state.convosLoading = false;
state.pageNumber = 1;
},
setConvos: (state, action) => {
state.convos = action.payload.sort(
(a, b) => new Date(b.createdAt) - new Date(a.createdAt)
);
},
setPages: (state, action) => {
state.pages = action.payload;
},
removeConvo: (state, action) => {
state.convos = state.convos.filter((convo) => convo.conversationId !== action.payload);
},
@ -61,7 +70,7 @@ const currentSlice = createSlice({
}
});
export const { refreshConversation, setConversation, setConvos, setNewConvo, setError, incrementPage, removeConvo, removeAll } =
export const { refreshConversation, setConversation, setPages, setConvos, setNewConvo, setError, increasePage, decreasePage, setPage, removeConvo, removeAll } =
currentSlice.actions;
export default currentSlice.reducer;

View file

@ -1876,3 +1876,6 @@ button.scroll-convo {
background-color:hsla(0,0%,100%,.4)
}
}
.hidden-visibility {
visibility: hidden;
}

View file

@ -9,14 +9,14 @@ const postRequest = async (url, { arg }) => {
return await axios.post(url, { arg });
};
export const swr = (path, successCallback) => {
const options = {};
export const swr = (path, successCallback, options) => {
const _options = {...options};
if (successCallback) {
options.onSuccess = successCallback;
_options.onSuccess = successCallback;
}
return useSWR(path, fetcher, options);
return useSWR(path, fetcher, _options);
}
export default function manualSWR(path, type, successCallback) {