Skip to content

Commit

Permalink
Fix logic for InitialMessages OlderThan
Browse files Browse the repository at this point in the history
- It is possible that InitialMessages should spawn new requests for
  fetching messages.
- For example Mr. A has sent Mr. B 23 messages. If B fetches initially
  10, it should also fetch the 13 unread!
  • Loading branch information
rottabonus committed May 4, 2024
1 parent c0939e9 commit cbb4c84
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 74 deletions.
48 changes: 1 addition & 47 deletions e2e/chatTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import accountFixtures from './fixtures/accounts.json';
import {
APISignUpMentee,
APISignUpMentor,
APIGetSendInfo,
APISendMessage,
APIDeleteAccounts,
APIDeleteAccount,
waitAndTypeText,
signIn,
forceLogout,
Expand All @@ -24,7 +21,7 @@ describe('Chat', () => {
await device.reloadReactNative();
});

xit('with new mentor', async () => {
it('with new mentor', async () => {
const mentee = accountFixtures.mentees[0];
await APISignUpMentee(mentee);
const mentor = accountFixtures.mentors[0];
Expand Down Expand Up @@ -62,47 +59,4 @@ describe('Chat', () => {
await expect(element(by.text(message_from_mentee))).toBeVisible();
await expect(element(by.text(message_from_mentor))).toBeVisible();
});

it('if buddy with most recent message deletes account, can receive still messages from other users', async () => {
const mentee = accountFixtures.mentees[0];
await APISignUpMentee(mentee);
const mentor = accountFixtures.mentors[0];
await APISignUpMentor(mentor);

// mentee sends a msg to mentor
const {
sender_id: menteeId,
sender_info: mentee_info,
recipient_id: mentorId,
senderHeaders: menteeHeaders,
} = await APIGetSendInfo(mentee, mentor);
await APISendMessage({
sender_id: menteeId,
recipient_id: mentorId,
content: 'Hi first',
headers: menteeHeaders,
});

await signIn(mentor);
await element(by.id('tabs.chats')).tap();
await element(by.text(mentee.displayName)).tap();
await element(by.id('chat.back.button')).tap();

// delete mentee account
await APIDeleteAccount(mentee_info.account_id, menteeHeaders)

// new mentee
const newMentee = accountFixtures.mentees[1];
await APISignUpMentee(newMentee);
const {
sender_id: newMenteeId,
senderHeaders: newMenteeHeaders,
} = await APIGetSendInfo(newMentee, mentor);
await APISendMessage({
sender_id: newMenteeId,
recipient_id: mentorId,
content: 'Hi second',
headers: newMenteeHeaders,
});
});
});
36 changes: 28 additions & 8 deletions src/api/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,34 @@ const sortSentTime = (a: Message, b: Message) => {
return a.sentTime < b.sentTime ? -1 : 1;
};

export const getIsOldestFetchedMessageUnread = (
fetchedBuddyMessages: Record<string, Message>,
) => {
const sorted = Object.keys(fetchedBuddyMessages)
.map(msgId => fetchedBuddyMessages[msgId])
.sort(sortSentTime);

return !sorted[sorted.length - 1].isSeen;
// TODO: this should return array of params!
// If OlderThan-params, then it will check if latest message is unread. If yes, then it will need to update the previousMsg!
// If InitialMessages-params, then it will check all of the buddies responses. if latestg message is unread, it will add new OlderThan-params (and it will calculate previousMsg)
// If no need to fetch again, return empty array
export const getParamsForUnreadMessages = (
messages: MessageMapping,
params: PollingParams,
): Array<PollingParams> => {
switch (params.type) {
case 'OlderThan': {
const fetchedBuddyMessages = messages[params.buddyId];
const sorted = Object.keys(fetchedBuddyMessages)

Check failure on line 219 in src/api/messages.ts

View workflow job for this annotation

GitHub Actions / Lint

Expected blank line before this statement
.map(msgId => fetchedBuddyMessages[msgId])
.sort(sortSentTime);
const isOldestUnread = !sorted[sorted.length - 1].isSeen;

Check failure on line 222 in src/api/messages.ts

View workflow job for this annotation

GitHub Actions / Lint

'isOldestUnread' is assigned a value but never used
// if is unread, update the previousMsg and return valid pollingParam for type 'OlderThan'
return [];

Check failure on line 224 in src/api/messages.ts

View workflow job for this annotation

GitHub Actions / Lint

Expected blank line before this statement
}

case 'InitialMessages': {
// for every buddy-messages, check if oldest is unread and return an array for type 'OlderThan' so it will get added
return [];
}

default: {
return [];
}
}
};

export const extractMostRecentId = (messages: MessageMapping) => {
Expand Down
4 changes: 4 additions & 0 deletions src/state/reducers/markSeen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export const reducer: automaton.Reducer<State, actions.Action> = (
type: 'messages/markSeen',
payload: { messages },
})),
// {
// type: 'messages/markSeen',
// payload: { messages },
// },
);
}

Expand Down
28 changes: 9 additions & 19 deletions src/state/reducers/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,32 +93,22 @@ export const reducer: automaton.Reducer<State, actions.Action> = (

const previousMsgId = messageApi.extractMostRecentId(nextMessages);

const isFetchingOlderMessagesAndIsOldestFetchedUnread =
state.currentParams.type === 'OlderThan'
? messageApi.getIsOldestFetchedMessageUnread(
newMessages[state.currentParams.buddyId],
)
: false;

const [first, rest] = messageApi.getNextParams(
const newOlderThanParams = messageApi.getParamsForUnreadMessages(
newMessages,
state.currentParams,
);

// TODO: Previous func will return an array of params. Either an empty array ( no need to retry ) or then more params. Add them to the getNextParams func
const [nextCurrent, nextQueue] = messageApi.getNextParams(
action.payload,
state.pollingQueue,
state.currentParams,
previousMsgId,
);

const { nextFetch, nextCurrent, nextQueue } =
isFetchingOlderMessagesAndIsOldestFetchedUnread
? {
nextCurrent: state.currentParams,
nextFetch: state.currentParams,
nextQueue: [first, ...rest],
}
: { nextCurrent: first, nextFetch: first, nextQueue: rest };

const nextCmd = withToken(
flow(
messageApi.fetchMessages(nextFetch),
messageApi.fetchMessages(nextCurrent),
T.delay(config.messageFetchDelay),
),
actions.make('messages/get/completed'),
Expand All @@ -129,8 +119,8 @@ export const reducer: automaton.Reducer<State, actions.Action> = (
...state,
messages: RD.success(nextMessages),
previousMsgId,
pollingQueue: nextQueue,
currentParams: nextCurrent,
pollingQueue: [...nextQueue, ...newOlderThanParams],
},
nextCmd,
);
Expand Down

0 comments on commit cbb4c84

Please sign in to comment.