Skip to content

Commit

Permalink
feat: ✨ Finally finished with scroll to load more... I think
Browse files Browse the repository at this point in the history
  • Loading branch information
SupertigerDev committed Jan 4, 2023
1 parent 7f09d9e commit d6a5372
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 30 deletions.
60 changes: 60 additions & 0 deletions public/assets/spinner.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions src/chat-api/services/MessageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import Endpoints from './ServiceEndpoints';



export const fetchMessages = async (channelId: string, limit = 50, afterMessageId?: string) => {
export const fetchMessages = async (channelId: string, limit = 50, afterMessageId?: string, beforeMessageId?: string) => {
const data = await request<RawMessage[]>({
method: 'GET',
url: env.SERVER_URL + "/api" + Endpoints.messages(channelId),
params: {limit, ...(afterMessageId ? {after: afterMessageId}: undefined)},
params: {
limit,
...(afterMessageId ? {after: afterMessageId}: undefined),
...(beforeMessageId ? {before: beforeMessageId}: undefined)
},
useToken: true
});
return data;
Expand Down
40 changes: 30 additions & 10 deletions src/chat-api/store/useMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export type Message = RawMessage & {
}

const [messages, setMessages] = createStore<Record<string, Message[] | undefined>>({});
const fetchAndStoreMessages = async (channelId: string) => {
if (getMessagesByChannelId(channelId)) return;
const fetchAndStoreMessages = async (channelId: string, force = false) => {
if (!force && getMessagesByChannelId(channelId)) return;

const channelProperties = useChannelProperties();
channelProperties.setMoreTopToLoad(channelId, true);
Expand All @@ -33,7 +33,7 @@ const fetchAndStoreMessages = async (channelId: string) => {
});
}

const loadMoreAndStoreMessages = async (channelId: string, beforeSet: () => void, afterSet: (data: {hasMore: boolean}) => void) => {
const loadMoreTopAndStoreMessages = async (channelId: string, beforeSet: () => void, afterSet: (data: {hasMore: boolean}) => void) => {
const channelMessages = messages[channelId]!;
const newMessages = await fetchMessages(channelId, env.MESSAGE_LIMIT, channelMessages[0].id);
const clamp = sliceEnd([...newMessages, ...channelMessages]);
Expand All @@ -46,12 +46,25 @@ const loadMoreAndStoreMessages = async (channelId: string, beforeSet: () => void
afterSet({ hasMore });
}

const loadMoreBottomAndStoreMessages = async (channelId: string, beforeSet: () => void, afterSet: (data: {hasMore: boolean}) => void) => {
const channelMessages = messages[channelId]!;
const newMessages = await fetchMessages(channelId, env.MESSAGE_LIMIT, undefined, channelMessages[channelMessages.length - 1].id);
const clamp = sliceBeginning([...channelMessages, ...newMessages]);
const hasMore = newMessages.length === env.MESSAGE_LIMIT

beforeSet();
setMessages({
[channelId]: clamp
});
afterSet({ hasMore });
}

function sliceEnd(arr: any[]) {
return arr.slice(0, env.MESSAGE_LIMIT * 3);
return arr.slice(0, env.MESSAGE_LIMIT * 4);
}

function sliceBeginning(arr: any[]) {
return arr.slice(-(env.MESSAGE_LIMIT * 3), arr.length);
return arr.slice(-(env.MESSAGE_LIMIT * 4), arr.length);
}


Expand Down Expand Up @@ -84,6 +97,8 @@ const updateLocalMessage = async (message: Partial<RawMessage & {sentStatus: Mes

const sendAndStoreMessage = async (channelId: string, content: string) => {
const channels = useChannels();
const channelProperties = useChannelProperties();
const properties = channelProperties.get(channelId);
const tempMessageId = `${Date.now()}-${Math.random()}`;
const channel = channels.get(channelId);

Expand All @@ -107,7 +122,7 @@ const sendAndStoreMessage = async (channelId: string, content: string) => {
},
};

setMessages({
!properties?.moreBottomToLoad && setMessages({
[channelId]: sliceBeginning([...messages[channelId]!, localMessage])
})

Expand All @@ -126,18 +141,22 @@ const sendAndStoreMessage = async (channelId: string, content: string) => {
const index = messages[channelId]?.findIndex(m => m.tempId === tempMessageId);

if (!message) {
setMessages(channelId, index!, 'sentStatus', MessageSentStatus.FAILED);
!properties?.moreBottomToLoad && setMessages(channelId, index!, 'sentStatus', MessageSentStatus.FAILED);
return;
}
message.tempId = tempMessageId;

setMessages(channelId, index!, reconcile(message, {key: "tempId"}));
!properties?.moreBottomToLoad && setMessages(channelId, index!, reconcile(message, {key: "tempId"}));
}


const pushMessage = (channelId: string, message: Message) => {
if (!messages[channelId]) return;
setMessages(channelId, messages[channelId]?.length!, message);
const channelProperties = useChannelProperties();
const properties = channelProperties.get(channelId);
!properties?.moreBottomToLoad && setMessages({
[channelId]: sliceBeginning([...messages[channelId]!, message])
});
};

const locallyRemoveMessage = (channelId: string, messageId: string) => {
Expand All @@ -159,7 +178,8 @@ export default function useMessages() {
return {
getMessagesByChannelId,
fetchAndStoreMessages,
loadMoreAndStoreMessages,
loadMoreTopAndStoreMessages,
loadMoreBottomAndStoreMessages,
editAndStoreMessage,
sendAndStoreMessage,
locallyRemoveMessage,
Expand Down
1 change: 1 addition & 0 deletions src/components/Markup.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
&.no-wrap {
.content {
word-break: keep-all;
white-space: pre;
overflow: auto;
}
}
Expand Down
Loading

0 comments on commit d6a5372

Please sign in to comment.