Skip to content

Commit

Permalink
Call openConversation rather than just setting state (#1352)
Browse files Browse the repository at this point in the history
  • Loading branch information
dalefukami authored Jan 5, 2024
1 parent b45bd9d commit 6e21e83
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 57 deletions.
4 changes: 2 additions & 2 deletions src/store/channels-list/saga.createConversation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
MessagesFetchState,
denormalize as denormalizeChannel,
} from '../channels';
import { setactiveConversationId } from '../chat';
import { StoreBuilder } from '../test/store';
import { AdminMessageType } from '../messages';
import { chat } from '../../lib/chat';
import { openConversation } from '../channels/saga';

describe(createConversation, () => {
it('creates the conversation - full success flow', async () => {
Expand All @@ -42,7 +42,7 @@ describe(createConversation, () => {
.next(true)
.call(createOptimisticConversation, otherUserIds, name, image)
.next(stubOptimisticConversation)
.put(setactiveConversationId(stubOptimisticConversation.id))
.call(openConversation, stubOptimisticConversation.id)
.next()
.select(userSelector, otherUserIds)
.next([{ userId: 'user-1' }])
Expand Down
34 changes: 4 additions & 30 deletions src/store/channels-list/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { receive as receiveUser } from '../users';

import { AsyncListStatus } from '../normalized';
import { toLocalChannel, filterChannelsList, mapChannelMembers, mapChannelMessages } from './utils';
import { setactiveConversationId } from '../chat';
import { clearChannels } from '../channels/saga';
import { clearChannels, openConversation, openFirstConversation } from '../channels/saga';
import { ConversationEvents, getConversationsBus } from './channels';
import { Events, getAuthChannel } from '../authentication/channels';
import { takeEveryFromBus } from '../../lib/saga';
Expand All @@ -24,8 +23,6 @@ import { rawChannel } from '../channels/selectors';
import { getZEROUsers } from './api';
import { union } from 'lodash';
import { uniqNormalizedList } from '../utils';
import { compareDatesDesc } from '../../lib/date';
import cloneDeep from 'lodash/cloneDeep';

const rawAsyncListStatus = () => (state) => getDeepProperty(state, 'channelsList.status', 'idle');
const rawChannelsList = () => (state) => filterChannelsList(state, ChannelType.Channel);
Expand Down Expand Up @@ -110,7 +107,7 @@ export function* createConversation(userIds: string[], name: string = null, imag
let optimisticConversation = { id: '', optimisticId: '' };
if (yield call(chatClient.supportsOptimisticCreateConversation)) {
optimisticConversation = yield call(createOptimisticConversation, userIds, name, image);
yield put(setactiveConversationId(optimisticConversation.id));
yield call(openConversation, optimisticConversation.id);
}

try {
Expand Down Expand Up @@ -215,7 +212,7 @@ export function* receiveCreatedConversation(conversation, optimisticConversation
])
);

yield put(setactiveConversationId(conversation.id));
yield call(openConversation, conversation.id);
}

export function* clearChannelsAndConversations() {
Expand Down Expand Up @@ -297,37 +294,14 @@ export function* userLeftChannel(channelId, matrixId) {
}
}

// TODO: we can remove this function and simply use the "lastMessage.createdAt" property
// look into https://github.com/zer0-os/zOS/pull/1063
const conversationWithLatestMessage = (conversations) => {
conversations = cloneDeep(conversations);
for (const conversation of conversations) {
const sortedMessages =
(conversation.messages || [])?.sort((a, b) => compareDatesDesc(a.createdAt, b.createdAt)) || [];
conversation.lastMessage = sortedMessages[0];
}

const sortedConversations = conversations.sort((a, b) =>
compareDatesDesc(a.lastMessage?.createdAt, b.lastMessage?.createdAt)
);
return sortedConversations[0];
};

function* currentUserLeftChannel(channelId) {
const channelIdList = yield select((state) => getDeepProperty(state, 'channelsList.value', []));
const newList = channelIdList.filter((id) => id !== channelId);
yield put(receive(newList));

const activeConversationId = yield select((state) => getDeepProperty(state, 'chat.activeConversationId', ''));
if (activeConversationId === channelId) {
const conversations = yield select(denormalizeConversations);
if (conversations.length > 0) {
const latestConversation = conversationWithLatestMessage(conversations);
yield put(setactiveConversationId(latestConversation.id));
} else {
// Probably not possible but handled just in case
yield put(setactiveConversationId(null));
}
yield call(openFirstConversation);
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/store/channels/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Events as ChatEvents, getChatBus } from '../chat/bus';
import { currentUserSelector } from '../authentication/saga';
import { setActiveChannelId, setactiveConversationId } from '../chat';
import { chat } from '../../lib/chat';
import { mostRecentConversation } from '../channels-list/selectors';

export const rawChannelSelector = (channelId) => (state) => {
return getDeepProperty(state, `normalized.channels['${channelId}']`, null);
Expand Down Expand Up @@ -73,6 +74,15 @@ export function* openChannel(channelId) {
yield spawn(markChannelAsRead, channelId);
}

export function* openFirstConversation() {
const conversation = yield select(mostRecentConversation);
if (conversation) {
yield call(openConversation, conversation.id);
} else {
yield put(setactiveConversationId(''));
}
}

export function* openConversation(conversationId) {
if (!conversationId) {
return;
Expand Down
3 changes: 1 addition & 2 deletions src/store/create-conversation/saga.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { put, call, select, race, take, fork, spawn } from 'redux-saga/effects';
import { SagaActionTypes, Stage, setFetchingConversations, setGroupCreating, setGroupUsers, setStage } from '.';
import { channelsReceived, createConversation as performCreateConversation } from '../channels-list/saga';
import { setactiveConversationId } from '../chat';
import { Events, getAuthChannel } from '../authentication/channels';
import { currentUserSelector } from '../authentication/selectors';
import { Chat, chat } from '../../lib/chat';
Expand Down Expand Up @@ -44,7 +43,7 @@ export function* performGroupMembersSelected(userSelections: { value: string; la
} else {
const selectedConversation = existingConversations[0];
yield call(channelsReceived, { payload: { channels: [selectedConversation] } });
yield put(setactiveConversationId(selectedConversation.id));
yield call(openConversation, selectedConversation.id);
return Stage.None;
}
}
Expand Down
15 changes: 1 addition & 14 deletions src/store/login/saga.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { expectSaga } from 'redux-saga-test-plan';

import { emailLogin, openFirstConversation, validateEmailLogin } from './saga';
import { emailLogin, validateEmailLogin } from './saga';

import { call } from 'redux-saga/effects';

import { EmailLoginErrors, LoginStage, LoginState, initialState as initialRegistrationState } from '.';

import { rootReducer } from '../reducer';
import { throwError } from 'redux-saga-test-plan/providers';
import { setactiveConversationId } from '../chat';
import { authenticateByEmail } from '../authentication/saga';
import { StoreBuilder } from '../test/store';

describe('emailLogin', () => {
it('logs the user in', async () => {
Expand Down Expand Up @@ -137,17 +135,6 @@ describe('validateEmailLogin', () => {
});
});

describe(openFirstConversation, () => {
it('opens the first conversation', async () => {
const initialState = new StoreBuilder().withConversationList({ id: '1234' });

await expectSaga(openFirstConversation)
.withReducer(rootReducer, initialState.build())
.put(setactiveConversationId('1234'))
.run();
});
});

function initialState(attrs: Partial<LoginState> = {}) {
return {
login: {
Expand Down
10 changes: 1 addition & 9 deletions src/store/login/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import { setWalletModalOpen } from '../web3';
import { Events as AuthEvents, getAuthChannel } from '../authentication/channels';
import { Web3Events, getWeb3Channel } from '../web3/channels';
import { ConversationEvents, getConversationsBus } from '../channels-list/channels';
import { openConversation } from '../channels/saga';
import { mostRecentConversation } from '../channels-list/selectors';
import { openFirstConversation } from '../channels/saga';

export function* emailLogin(action) {
const { email, password } = action.payload;
Expand Down Expand Up @@ -153,13 +152,6 @@ function* listenForUserLogin() {
}
}

export function* openFirstConversation() {
const conversation = yield select(mostRecentConversation);
if (conversation) {
yield call(openConversation, conversation.id);
}
}

export function* openFirstConversationAfterChannelsLoaded() {
const channel = yield call(getConversationsBus);
yield take(channel, ConversationEvents.ConversationsLoaded);
Expand Down

0 comments on commit 6e21e83

Please sign in to comment.