Skip to content

Commit

Permalink
[bug] Fix gap at bottom of chat history (#413)
Browse files Browse the repository at this point in the history
Co-authored-by: Ian Seabock (Centific Technologies Inc) <[email protected]>
  • Loading branch information
iseabock and Ian Seabock (Centific Technologies Inc) authored Dec 5, 2023
1 parent 2967b29 commit 1137d5d
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 47 deletions.
5 changes: 3 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,11 +709,12 @@ def delete_conversation():

@app.route("/history/list", methods=["GET"])
def list_conversations():
offset = request.args.get("offset", 0)
authenticated_user = get_authenticated_user_details(request_headers=request.headers)
user_id = authenticated_user['user_principal_id']

## get the conversations from cosmos
conversations = cosmos_conversation_client.get_conversations(user_id)
conversations = cosmos_conversation_client.get_conversations(user_id, offset=offset, limit=25)
if not isinstance(conversations, list):
return jsonify({"error": f"No conversations for {user_id} were found"}), 404

Expand Down Expand Up @@ -779,7 +780,7 @@ def delete_all_conversations():

# get conversations for user
try:
conversations = cosmos_conversation_client.get_conversations(user_id)
conversations = cosmos_conversation_client.get_conversations(user_id, offset=0, limit=None)
if not conversations:
return jsonify({"error": f"No conversations for {user_id} were found"}), 404

Expand Down
5 changes: 4 additions & 1 deletion backend/history/cosmosdbservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,17 @@ def delete_messages(self, conversation_id, user_id):
return response_list


def get_conversations(self, user_id, sort_order = 'DESC'):
def get_conversations(self, user_id, limit, sort_order = 'DESC', offset = 0):
parameters = [
{
'name': '@userId',
'value': user_id
}
]
query = f"SELECT * FROM c where c.userId = @userId and c.type='conversation' order by c.updatedAt {sort_order}"
if limit is not None:
query += f" offset {offset} limit {limit}"

conversations = list(self.container_client.query_items(query=query, parameters=parameters,
enable_cross_partition_query =True))
## if no conversations are found, return None
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export const fetchChatHistoryInit = (): Conversation[] | null => {
return chatHistorySampleData;
}

export const historyList = async (): Promise<Conversation[] | null> => {
const response = await fetch("/history/list", {
export const historyList = async (offset=0): Promise<Conversation[] | null> => {
const response = await fetch(`/history/list?offset=${offset}`, {
method: "GET",
}).then(async (res) => {
const payload = await res.json();
Expand Down
61 changes: 55 additions & 6 deletions frontend/src/components/ChatHistory/ChatHistoryListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as React from 'react';
import { DefaultButton, Dialog, DialogFooter, DialogType, Text, IconButton, List, PrimaryButton, Separator, Stack, TextField, ITextField } from '@fluentui/react';
import { DefaultButton, Dialog, DialogFooter, DialogType, Text, IconButton, List, PrimaryButton, Separator, Stack, TextField, ITextField, Spinner, SpinnerSize } from '@fluentui/react';

import { AppStateContext } from '../../state/AppProvider';
import { GroupedChatHistory } from './ChatHistoryList';

import styles from "./ChatHistoryPanel.module.css"
import { useBoolean } from '@fluentui/react-hooks';
import { Conversation } from '../../api/models';
import { historyDelete, historyRename } from '../../api';
import { useEffect, useRef, useState } from 'react';
import { historyDelete, historyRename, historyList } from '../../api';
import { useEffect, useRef, useState, useContext } from 'react';

interface ChatHistoryListItemCellProps {
item?: Conversation;
Expand Down Expand Up @@ -244,8 +244,14 @@ export const ChatHistoryListItemCell: React.FC<ChatHistoryListItemCellProps> = (
};

export const ChatHistoryListItemGroups: React.FC<ChatHistoryListItemGroupsProps> = ({ groupedChatHistory }) => {
const [ , setSelectedItem] = React.useState<Conversation | null>(null);

const appStateContext = useContext(AppStateContext);
const observerTarget = useRef(null);
const [ , setSelectedItem] = React.useState<Conversation | null>(null);
const [offset, setOffset] = useState<number>(25);
const [observerCounter, setObserverCounter] = useState(0);
const [showSpinner, setShowSpinner] = useState(false);
const firstRender = useRef(true);

const handleSelectHistory = (item?: Conversation) => {
if(item){
setSelectedItem(item)
Expand All @@ -258,12 +264,54 @@ export const ChatHistoryListItemGroups: React.FC<ChatHistoryListItemGroupsProps>
);
};

useEffect(() => {
if (firstRender.current) {
firstRender.current = false;
return;
}
handleFetchHistory();
setOffset((offset) => offset += 25);
}, [observerCounter]);

const handleFetchHistory = async () => {
const currentChatHistory = appStateContext?.state.chatHistory;
setShowSpinner(true);

await historyList(offset).then((response) => {
const concatenatedChatHistory = currentChatHistory && response && currentChatHistory.concat(...response)
if (response) {
appStateContext?.dispatch({ type: 'FETCH_CHAT_HISTORY', payload: concatenatedChatHistory || response });
} else {
appStateContext?.dispatch({ type: 'FETCH_CHAT_HISTORY', payload: null });
}
setShowSpinner(false);
return response
})
}

useEffect(() => {
const observer = new IntersectionObserver(
entries => {
if (entries[0].isIntersecting)
setObserverCounter((observerCounter) => observerCounter += 1);
},
{ threshold: 1 }
);

if (observerTarget.current) observer.observe(observerTarget.current);

return () => {
if (observerTarget.current) observer.unobserve(observerTarget.current);
};
}, [observerTarget]);

return (
<div className={styles.listContainer}>
<div className={styles.listContainer} data-is-scrollable>
{groupedChatHistory.map((group) => (
group.entries.length > 0 && <Stack horizontalAlign="start" verticalAlign="center" key={group.month} className={styles.chatGroup} aria-label={`chat history group: ${group.month}`}>
<Stack aria-label={group.month} className={styles.chatMonth}>{formatMonth(group.month)}</Stack>
<List aria-label={`chat history list`} items={group.entries} onRenderCell={onRenderCell} className={styles.chatList}/>
<div ref={observerTarget} />
<Separator styles={{
root: {
width: '100%',
Expand All @@ -275,6 +323,7 @@ export const ChatHistoryListItemGroups: React.FC<ChatHistoryListItemGroupsProps>
}}/>
</Stack>
))}
{showSpinner && <div className={styles.spinnerContainer}><Spinner size={SpinnerSize.small} aria-label="loading more chat history" className={styles.spinner}/></div>}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@
width: 100%;
}

.spinnerContainer {
display: flex;
justify-content: center;
align-items: center;
height: 50px;
}

.chatList {
width: 100%;
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/state/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ type AppStateProviderProps = {

useEffect(() => {
// Check for cosmosdb config and fetch initial data here
const fetchChatHistory = async (): Promise<Conversation[] | null> => {
const result = await historyList().then((response) => {
const fetchChatHistory = async (offset=0): Promise<Conversation[] | null> => {
const result = await historyList(offset).then((response) => {
if(response){
dispatch({ type: 'FETCH_CHAT_HISTORY', payload: response });
dispatch({ type: 'FETCH_CHAT_HISTORY', payload: response});
}else{
dispatch({ type: 'FETCH_CHAT_HISTORY', payload: null });
}
Expand Down
58 changes: 29 additions & 29 deletions static/assets/index-4e24bac2.js → static/assets/index-88c94d86.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Azure AI</title>
<script type="module" crossorigin src="/assets/index-4e24bac2.js"></script>
<link rel="stylesheet" href="/assets/index-5ba581b7.css">
<script type="module" crossorigin src="/assets/index-88c94d86.js"></script>
<link rel="stylesheet" href="/assets/index-ab082006.css">
</head>
<body>
<div id="root"></div>
Expand Down

0 comments on commit 1137d5d

Please sign in to comment.