Skip to content

Commit 527a9c8

Browse files
Sravan SHoonBaek
andauthored
fix: ChannelList blink when when message is send (#535)
Condition to reproduce: * Implement two channel list(A, B) with different filters * When a message is send from A, the Channel is shows in B for a second Reason: * CHANNEL_REPLACED_TO_TOP is broadcasted to all ChannelLists * channelListQuery filter was not applied on CHANNEL_REPLACED_TO_TOP reducer --- Remove unused reducer SHOW_CHANNEL_SETTINGS, HIDE_CHANNEL_SETTINGS Fixes: https://sendbird.atlassian.net/browse/UIKIT-3824 Co-authored-by: HoonBaek <[email protected]>
1 parent 0cb76de commit 527a9c8

File tree

7 files changed

+107
-32
lines changed

7 files changed

+107
-32
lines changed

src/modules/ChannelList/context/ChannelListProvider.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export interface ChannelListProviderInterface extends ChannelListProviderProps {
100100
loading: boolean;
101101
allChannels: GroupChannel[];
102102
currentChannel: GroupChannel;
103-
showSettings: boolean;
104103
channelListQuery: GroupChannelListQuery;
105104
currentUserId: string;
106105
channelListDispatcher: CustomUseReducerDispatcher;
@@ -112,7 +111,6 @@ interface ChannelListStoreInterface {
112111
loading: boolean;
113112
allChannels: GroupChannel[];
114113
currentChannel: GroupChannel;
115-
showSettings: boolean;
116114
channelListQuery: GroupChannelListQuery;
117115
currentUserId: string;
118116
disableAutoSelect: boolean;
@@ -131,7 +129,6 @@ const ChannelListContext = React.createContext<ChannelListProviderInterface | nu
131129
loading: false,
132130
allChannels: [],
133131
currentChannel: null,
134-
showSettings: false,
135132
channelListQuery: {},
136133
currentUserId: null,
137134
channelListDispatcher: null,
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { channel1, channel0 } from '../data.mock';
2+
import * as actionTypes from '../actionTypes';
3+
import reducers from '../reducers';
4+
import initialState from '../initialState';
5+
6+
const CUSTOM_FILTER = 'GROUP_CHAT';
7+
const channelListQuery = {
8+
includeEmpty: true,
9+
customTypesFilter: [CUSTOM_FILTER],
10+
};
11+
12+
describe('Channels-Reducers/CHANNEL_REPLACED_TO_TOP', () => {
13+
it('should move existing channel to top of the list', () => {
14+
const state = {
15+
...initialState,
16+
allChannels: [channel0, channel1],
17+
};
18+
const action = {
19+
type: actionTypes.CHANNEL_REPLACED_TO_TOP,
20+
payload: channel1,
21+
};
22+
const expectedState = {
23+
...state,
24+
allChannels: [channel1, channel0],
25+
};
26+
27+
const nextState = reducers(state, action);
28+
29+
expect(nextState).toEqual(expectedState);
30+
});
31+
32+
it('should move channel to top of the list if doesnt exist', () => {
33+
const state = {
34+
...initialState,
35+
allChannels: [channel0],
36+
};
37+
const action = {
38+
type: actionTypes.CHANNEL_REPLACED_TO_TOP,
39+
payload: channel1,
40+
};
41+
const expectedState = {
42+
...state,
43+
allChannels: [channel1, channel0],
44+
};
45+
46+
const nextState = reducers(state, action);
47+
48+
expect(nextState).toEqual(expectedState);
49+
});
50+
51+
it('should not prepend channel if channelListQuery doesnt pass', () => {
52+
const state = {
53+
...initialState,
54+
channelListQuery,
55+
allChannels: [channel0],
56+
};
57+
const action = {
58+
type: actionTypes.CHANNEL_REPLACED_TO_TOP,
59+
payload: channel1,
60+
};
61+
const expectedState = {
62+
...state,
63+
allChannels: [channel0],
64+
};
65+
66+
const nextState = reducers(state, action);
67+
68+
expect(nextState).toEqual(expectedState);
69+
});
70+
71+
it('should prepend channel if channelListQuery pass', () => {
72+
const state = {
73+
...initialState,
74+
channelListQuery,
75+
allChannels: [channel0],
76+
};
77+
const customChannel = {
78+
...channel1,
79+
customType: CUSTOM_FILTER,
80+
};
81+
const action = {
82+
type: actionTypes.CHANNEL_REPLACED_TO_TOP,
83+
payload: customChannel,
84+
};
85+
const expectedState = {
86+
...state,
87+
allChannels: [customChannel, channel0],
88+
};
89+
90+
const nextState = reducers(state, action);
91+
92+
expect(nextState).toEqual(expectedState);
93+
});
94+
});

src/modules/ChannelList/dux/__tests__/reducers.spec.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,6 @@ describe('Channels-Reducers', () => {
9696
expect(nextState.currentChannel).toEqual(mockData.allChannels[0].url);
9797
});
9898

99-
it('should handle SHOW_CHANNEL_SETTINGS', () => {
100-
const nextState = reducers(initialState, {
101-
type: actionTypes.SHOW_CHANNEL_SETTINGS,
102-
});
103-
expect(nextState.showSettings).toEqual(true);
104-
});
105-
106-
it('should handle HIDE_CHANNEL_SETTINGS', () => {
107-
const nextState = reducers(initialState, {
108-
type: actionTypes.HIDE_CHANNEL_SETTINGS,
109-
});
110-
expect(nextState.showSettings).toEqual(false);
111-
});
112-
11399
it('should attach more channels on FETCH_CHANNELS_SUCCESS', () => {
114100
const nextState = reducers(mockData, {
115101
type: actionTypes.FETCH_CHANNELS_SUCCESS,

src/modules/ChannelList/dux/actionTypes.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ export const LEAVE_CHANNEL_SUCCESS = 'LEAVE_CHANNEL_SUCCESS';
77

88
export const SET_CURRENT_CHANNEL = 'SET_CURRENT_CHANNEL';
99

10-
export const SHOW_CHANNEL_SETTINGS = 'SHOW_CHANNEL_SETTINGS';
11-
export const HIDE_CHANNEL_SETTINGS = 'HIDE_CHANNEL_SETTINGS';
12-
1310
export const FETCH_CHANNELS_START = 'FETCH_CHANNELS_START';
1411
export const FETCH_CHANNELS_SUCCESS = 'FETCH_CHANNELS_SUCCESS';
1512
export const FETCH_CHANNELS_FAILURE = 'FETCH_CHANNELS_FAILURE';

src/modules/ChannelList/dux/initialState.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export default {
44
loading: true,
55
allChannels: [],
66
currentChannel: null,
7-
showSettings: false,
87
channelListQuery: null,
98
currentUserId: '',
109
disableAutoSelect: false,

src/modules/ChannelList/dux/reducers.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,6 @@ export default function reducer(state, action) {
194194
...state,
195195
currentChannel: action.payload,
196196
};
197-
case actions.SHOW_CHANNEL_SETTINGS:
198-
return {
199-
...state,
200-
showSettings: true,
201-
};
202-
case actions.HIDE_CHANNEL_SETTINGS:
203-
return {
204-
...state,
205-
showSettings: false,
206-
};
207197
case actions.ON_LAST_MESSAGE_UPDATED: {
208198
return {
209199
...state,
@@ -274,6 +264,18 @@ export default function reducer(state, action) {
274264
};
275265
}
276266
case actions.CHANNEL_REPLACED_TO_TOP: {
267+
if (state.channelListQuery) {
268+
if (filterChannelListParams(state.channelListQuery, action.payload, state.currentUserId)) {
269+
return {
270+
...state,
271+
allChannels: [
272+
action.payload,
273+
...state.allChannels.filter((channel) => channel?.url !== action.payload.url),
274+
],
275+
};
276+
}
277+
return state;
278+
}
277279
return {
278280
...state,
279281
allChannels: [

src/utils/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ export const filterChannelListParams = (params: GroupChannelListQuery, channel:
378378
return false;
379379
}
380380
const searchFilter = params?.searchFilter;
381-
if (searchFilter?.query && searchFilter.fields?.length > 0) {
381+
if (searchFilter?.query && (searchFilter?.fields?.length ?? 0) > 0) {
382382
const searchQuery = searchFilter.query;
383383
const searchFields = searchFilter.fields;
384384
if (searchQuery && searchFields && searchFields.length > 0) {

0 commit comments

Comments
 (0)