[MM-58108] Posts missing channel_id in handleThreadReadChanged, handleAllThreadsInChannelMarkedRead, getThreadItemsInChannel (#27006)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
f0110e361e
Коммит
7d7b203567
@@ -1632,9 +1632,9 @@ function handleThreadReadChanged(msg) {
|
||||
),
|
||||
);
|
||||
} else if (msg.broadcast.channel_id) {
|
||||
handleAllThreadsInChannelMarkedRead(doDispatch, doGetState, msg.broadcast.channel_id, msg.data.timestamp);
|
||||
doDispatch(handleAllThreadsInChannelMarkedRead(msg.broadcast.channel_id, msg.data.timestamp));
|
||||
} else {
|
||||
handleAllMarkedRead(doDispatch, msg.broadcast.team_id);
|
||||
doDispatch(handleAllMarkedRead(msg.broadcast.team_id));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import {getChannel} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {makeGetPostsForThread} from 'mattermost-redux/selectors/entities/posts';
|
||||
import {isCollapsedThreadsEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getThread as getThreadSelector, getThreadItemsInChannel} from 'mattermost-redux/selectors/entities/threads';
|
||||
import {getThread as getThreadSelector, getThreadsInChannel} from 'mattermost-redux/selectors/entities/threads';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {DispatchFunc, GetStateFunc, ActionFunc, ActionFuncAsync} from 'mattermost-redux/types/actions';
|
||||
|
||||
@@ -248,13 +248,13 @@ export function getThread(userId: string, teamId: string, threadId: string, exte
|
||||
};
|
||||
}
|
||||
|
||||
export function handleAllMarkedRead(dispatch: DispatchFunc, teamId: string) {
|
||||
dispatch({
|
||||
export function handleAllMarkedRead(teamId: string) {
|
||||
return {
|
||||
type: ThreadTypes.ALL_TEAM_THREADS_READ,
|
||||
data: {
|
||||
team_id: teamId,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function markAllThreadsInTeamRead(userId: string, teamId: string): ActionFuncAsync {
|
||||
@@ -267,7 +267,7 @@ export function markAllThreadsInTeamRead(userId: string, teamId: string): Action
|
||||
return {error};
|
||||
}
|
||||
|
||||
handleAllMarkedRead(dispatch, teamId);
|
||||
dispatch(handleAllMarkedRead(teamId));
|
||||
|
||||
return {};
|
||||
};
|
||||
@@ -395,32 +395,38 @@ export function setThreadFollow(userId: string, teamId: string, threadId: string
|
||||
};
|
||||
}
|
||||
|
||||
export function handleAllThreadsInChannelMarkedRead(dispatch: DispatchFunc, getState: GetStateFunc, channelId: string, lastViewedAt: number) {
|
||||
const state = getState();
|
||||
const threadsInChannel = getThreadItemsInChannel(state, channelId);
|
||||
const channel = getChannel(state, channelId);
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
const teamId = channel.team_id;
|
||||
const actions = [];
|
||||
export function handleAllThreadsInChannelMarkedRead(channelId: string, lastViewedAt: number): ActionFunc<boolean> {
|
||||
return (dispatch, getState) => {
|
||||
const state = getState();
|
||||
|
||||
for (const thread of threadsInChannel) {
|
||||
actions.push({
|
||||
type: ThreadTypes.READ_CHANGED_THREAD,
|
||||
data: {
|
||||
id: thread.id,
|
||||
channelId,
|
||||
teamId,
|
||||
lastViewedAt,
|
||||
newUnreadMentions: 0,
|
||||
newUnreadReplies: 0,
|
||||
isUrgent: thread.is_urgent,
|
||||
},
|
||||
});
|
||||
}
|
||||
const channel = getChannel(state, channelId);
|
||||
if (channel == null) {
|
||||
return {data: false};
|
||||
}
|
||||
|
||||
dispatch(batchActions(actions));
|
||||
const teamId = channel.team_id;
|
||||
const threadsInChannel = getThreadsInChannel(state, channelId);
|
||||
|
||||
const actions = [];
|
||||
for (const thread of threadsInChannel) {
|
||||
actions.push({
|
||||
type: ThreadTypes.READ_CHANGED_THREAD,
|
||||
data: {
|
||||
id: thread.id,
|
||||
channelId,
|
||||
teamId,
|
||||
lastViewedAt,
|
||||
newUnreadMentions: 0,
|
||||
newUnreadReplies: 0,
|
||||
isUrgent: thread.is_urgent,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
dispatch(batchActions(actions));
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function decrementThreadCounts(post: ExtendedPost): ActionFunc {
|
||||
|
||||
@@ -189,6 +189,10 @@ describe('Selectors.Threads.getThreadsInChannel', () => {
|
||||
|
||||
it('should return threads in channel', () => {
|
||||
const user = TestHelper.fakeUserWithId();
|
||||
const thread1 = TestHelper.fakeThread(user.id, channel1.id);
|
||||
const thread2 = TestHelper.fakeThread(user.id, channel1.id);
|
||||
const thread3 = TestHelper.fakeThread(user.id, channel2.id);
|
||||
const thread4 = TestHelper.fakeThread(user.id, channel3.id);
|
||||
|
||||
const profiles = {
|
||||
[user.id]: user,
|
||||
@@ -205,36 +209,20 @@ describe('Selectors.Threads.getThreadsInChannel', () => {
|
||||
},
|
||||
threads: {
|
||||
threads: {
|
||||
a: {
|
||||
post: {
|
||||
channel_id: channel1.id,
|
||||
},
|
||||
},
|
||||
b: {
|
||||
post: {
|
||||
channel_id: channel1.id,
|
||||
},
|
||||
},
|
||||
c: {
|
||||
post: {
|
||||
channel_id: channel2.id,
|
||||
},
|
||||
},
|
||||
d: {
|
||||
post: {
|
||||
channel_id: channel3.id,
|
||||
},
|
||||
},
|
||||
[thread1.id]: thread1,
|
||||
[thread2.id]: thread2,
|
||||
[thread3.id]: thread3,
|
||||
[thread4.id]: thread4,
|
||||
},
|
||||
threadsInTeam: {
|
||||
[team1.id]: ['a', 'b', 'c'],
|
||||
[team2.id]: ['d'],
|
||||
[team1.id]: [thread1.id, thread2.id, thread3.id],
|
||||
[team2.id]: [thread4.id],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(Selectors.getThreadsInChannel(testState, channel1.id)).toEqual(['a', 'b']);
|
||||
expect(Selectors.getThreadsInChannel(testState, channel1.id)).toEqual([thread1, thread2]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -176,25 +176,20 @@ function sortByLastReply(ids: Array<UserThread['id']>, threads: ReturnType<typeo
|
||||
export const getThreadsInChannel: (
|
||||
state: GlobalState,
|
||||
channelID: string,
|
||||
) => Array<UserThread['id']> = createSelector(
|
||||
) => UserThread[] = createSelector(
|
||||
'getThreadsInChannel',
|
||||
getThreads,
|
||||
(state: GlobalState, channelID: string) => channelID,
|
||||
(allThreads: IDMappedObjects<UserThread>, channelID: string) => {
|
||||
return Object.keys(allThreads).filter((id) => allThreads[id].post.channel_id === channelID);
|
||||
},
|
||||
);
|
||||
(_: GlobalState, channelID: string) => channelID,
|
||||
(threads: IDMappedObjects<UserThread>, channelID: Channel['id']) => {
|
||||
const allThreads = Object.values(threads);
|
||||
|
||||
export const getThreadItemsInChannel: (
|
||||
state: GlobalState,
|
||||
channelID: string,
|
||||
) => UserThread[] = createSelector(
|
||||
'getThreadItemsInChannel',
|
||||
getThreads,
|
||||
(state: GlobalState, channelID: string) => channelID,
|
||||
(allThreads: IDMappedObjects<UserThread>, channelID: Channel['id']) => {
|
||||
return Object.keys(allThreads).
|
||||
map((id) => allThreads[id]).
|
||||
filter((item) => item.post.channel_id === channelID);
|
||||
const threadsInChannel: UserThread[] = [];
|
||||
for (const thread of allThreads) {
|
||||
if (thread && thread.post && thread.post.channel_id && thread.post.channel_id === channelID) {
|
||||
threadsInChannel.push(thread);
|
||||
}
|
||||
}
|
||||
|
||||
return threadsInChannel;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {Reaction} from '@mattermost/types/reactions';
|
||||
import type {Role} from '@mattermost/types/roles';
|
||||
import type {Scheme} from '@mattermost/types/schemes';
|
||||
import type {Team, TeamMembership} from '@mattermost/types/teams';
|
||||
import type {UserThread} from '@mattermost/types/threads';
|
||||
import type {UserProfile, UserNotifyProps} from '@mattermost/types/users';
|
||||
|
||||
export const DEFAULT_SERVER = 'http://localhost:8065';
|
||||
@@ -553,6 +554,23 @@ class TestHelper {
|
||||
};
|
||||
};
|
||||
|
||||
fakeThread = (userId: string, channelId: string, override?: Partial<UserThread>): UserThread => {
|
||||
return {
|
||||
id: this.generateId(),
|
||||
reply_count: 0,
|
||||
last_reply_at: 0,
|
||||
last_viewed_at: 0,
|
||||
participants: [],
|
||||
unread_replies: 0,
|
||||
unread_mentions: 0,
|
||||
is_following: true,
|
||||
post: {
|
||||
channel_id: channelId,
|
||||
user_id: userId,
|
||||
},
|
||||
...override,
|
||||
};
|
||||
};
|
||||
getFileInfoMock = (override: Partial<FileInfo>): FileInfo => {
|
||||
return {
|
||||
id: '',
|
||||
|
||||
Ссылка в новой задаче
Block a user