Skip to content

Commit

Permalink
Simplified upload file objects; Added base chat provider implementati…
Browse files Browse the repository at this point in the history
…ons; Base UI work for a chat screen;
  • Loading branch information
stef-coenen committed Nov 16, 2023
1 parent 4290113 commit e3b6c20
Show file tree
Hide file tree
Showing 19 changed files with 575 additions and 46 deletions.
6 changes: 3 additions & 3 deletions packages/chat-app/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { Helmet, HelmetProvider } from 'react-helmet-async';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

import Layout, { MinimalLayout } from '../components/ui/Layout/Layout';
import Layout, { MinimalLayout, NoLayout } from '../components/ui/Layout/Layout';

const About = lazy(() => import('../templates/About/About'));
const Auth = lazy(() => import('../templates/Auth/Auth'));
Expand Down Expand Up @@ -53,9 +53,9 @@ function App() {
path=""
element={
<RootRoute>
<Layout>
<NoLayout>
<Outlet />
</Layout>
</NoLayout>
</RootRoute>
}
>
Expand Down
23 changes: 23 additions & 0 deletions packages/chat-app/src/hooks/chat/useChatMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useDotYouClient } from '@youfoundation/common-app';
import { useInfiniteQuery } from '@tanstack/react-query';
import { getChatMessages } from '../../providers/ChatProvider';

const PAGE_SIZE = 100;
export const useChatMessages = ({ conversationId }: { conversationId: string | undefined }) => {
const dotYouClient = useDotYouClient().getDotYouClient();

const fetchMessages = async (conversationId: string, cursorState: string | undefined) => {
return await getChatMessages(dotYouClient, conversationId, cursorState, PAGE_SIZE);
};

return {
all: useInfiniteQuery({
queryKey: ['chat', conversationId],
initialPageParam: undefined as string | undefined,
queryFn: ({ pageParam }) => fetchMessages(conversationId as string, pageParam),
getNextPageParam: (lastPage) =>
lastPage.searchResults?.length >= PAGE_SIZE ? lastPage.cursorState : undefined,
enabled: !!conversationId,
}),
};
};
22 changes: 22 additions & 0 deletions packages/chat-app/src/hooks/chat/useConversations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useDotYouClient } from '@youfoundation/common-app';
import { getConversations } from '../../providers/ConversationProvider';
import { useInfiniteQuery } from '@tanstack/react-query';

const PAGE_SIZE = 100;
export const useConversations = () => {
const dotYouClient = useDotYouClient().getDotYouClient();

const fetchConversations = async (cursorState: string | undefined) => {
return await getConversations(dotYouClient, cursorState, PAGE_SIZE);
};

return {
all: useInfiniteQuery({
queryKey: ['conversations'],
initialPageParam: undefined as string | undefined,
queryFn: ({ pageParam }) => fetchConversations(pageParam),
getNextPageParam: (lastPage) =>
lastPage.searchResults?.length >= PAGE_SIZE ? lastPage.cursorState : undefined,
}),
};
};
132 changes: 129 additions & 3 deletions packages/chat-app/src/providers/ChatProvider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,131 @@
import { DotYouClient } from '@youfoundation/js-lib/core';
import {
DotYouClient,
DriveSearchResult,
FileQueryParams,
GetBatchQueryResultOptions,
NewDriveSearchResult,
ScheduleOptions,
SecurityGroupType,
SendContents,
TargetDrive,
UploadFileMetadata,
UploadInstructionSet,
getContentFromHeaderOrPayload,
queryBatch,
uploadFile,
} from '@youfoundation/js-lib/core';
import { ChatDrive, ChatMessage } from './ConversationProvider';
import { jsonStringify64 } from '@youfoundation/js-lib/helpers';

export const getChatMessages = (dotYouClient: DotYouClient, conversationId: string) => {
// ...
export const getChatMessages = async (
dotYouClient: DotYouClient,
conversationId: string,
cursorState: string | undefined,
pageSize: number
) => {
const params: FileQueryParams = {
targetDrive: ChatDrive,
groupId: [conversationId],
};

const ro: GetBatchQueryResultOptions = {
maxRecords: pageSize,
cursorState: cursorState,
includeMetadataHeader: true,
};

const response = await queryBatch(dotYouClient, params, ro);
return {
...response,
searchResults: await Promise.all(
response.searchResults.map(
async (result) => await dsrToMessage(dotYouClient, result, ChatDrive, true)
)
),
};
};

export const dsrToMessage = async (
dotYouClient: DotYouClient,
dsr: DriveSearchResult,
targetDrive: TargetDrive,
includeMetadataHeader: boolean
): Promise<DriveSearchResult<ChatMessage> | null> => {
try {
const attrContent = await getContentFromHeaderOrPayload<ChatMessage>(
dotYouClient,
targetDrive,
dsr,
includeMetadataHeader
);
if (!attrContent) return null;

const chatMessage: DriveSearchResult<ChatMessage> = {
...dsr,
fileMetadata: {
...dsr.fileMetadata,
appData: {
...dsr.fileMetadata.appData,
content: attrContent,
},
},
};

return chatMessage;
} catch (ex) {
console.error('[DotYouCore-js] failed to get the chatMessage payload of a dsr', dsr, ex);
return null;
}
};

export const uploadChatMessage = async (
dotYouClient: DotYouClient,
message: NewDriveSearchResult<ChatMessage>,
onVersionConflict?: () => void
) => {
const messageContent = message.fileMetadata.appData.content;

const uploadInstructions: UploadInstructionSet = {
storageOptions: {
drive: ChatDrive,
overwriteFileId: message.fileId,
},
transitOptions:
messageContent.recipients?.length > 0
? {
recipients: messageContent.recipients,
schedule: ScheduleOptions.SendNowAwaitResponse,
sendContents: SendContents.All,
useGlobalTransitId: true,
}
: undefined,
};

messageContent.recipients = [];
const payloadJson: string = jsonStringify64({ ...messageContent });

const uploadMetadata: UploadFileMetadata = {
versionTag: message?.fileMetadata.versionTag,
allowDistribution: false,
appData: {
uniqueId: messageContent.id,
groupId: messageContent.conversationId,
fileType: messageContent.messageType,
content: payloadJson,
},
isEncrypted: true,
accessControlList: message.serverMetadata?.accessControlList || {
requiredSecurityGroup: SecurityGroupType.Owner,
},
};

return await uploadFile(
dotYouClient,
uploadInstructions,
uploadMetadata,
undefined,
undefined,
undefined,
onVersionConflict
);
};
Loading

0 comments on commit e3b6c20

Please sign in to comment.