MM-56071: Track multiple threads (#25775)
We can have 2 types of threads open at the same time. One from the thread view, and another from RHS. We add another variable to distinguish between the 2 states. In future, if we have the ability for more than 2 threads, then we would need to track by threadID. https://mattermost.atlassian.net/browse/MM-56071 ```release-note NONE ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
3f2351c71f
Коммит
7dcf5f85a5
@@ -441,7 +441,12 @@ func TestWebSocketPresence(t *testing.T) {
|
|||||||
require.Nil(t, resp.Error)
|
require.Nil(t, resp.Error)
|
||||||
require.Equal(t, resp.SeqReply, wsClient.Sequence-1, "bad sequence number")
|
require.Equal(t, resp.SeqReply, wsClient.Sequence-1, "bad sequence number")
|
||||||
|
|
||||||
wsClient.UpdateActiveThread("threadID")
|
wsClient.UpdateActiveThread(true, "threadID")
|
||||||
|
resp = <-wsClient.ResponseChannel
|
||||||
|
require.Nil(t, resp.Error)
|
||||||
|
require.Equal(t, resp.SeqReply, wsClient.Sequence-1, "bad sequence number")
|
||||||
|
|
||||||
|
wsClient.UpdateActiveThread(false, "threadID")
|
||||||
resp = <-wsClient.ResponseChannel
|
resp = <-wsClient.ResponseChannel
|
||||||
require.Nil(t, resp.Error)
|
require.Nil(t, resp.Error)
|
||||||
require.Equal(t, resp.SeqReply, wsClient.Sequence-1, "bad sequence number")
|
require.Equal(t, resp.SeqReply, wsClient.Sequence-1, "bad sequence number")
|
||||||
|
|||||||
@@ -105,16 +105,17 @@ type WebConn struct {
|
|||||||
// a reused connection.
|
// a reused connection.
|
||||||
// It's theoretically possible for this number to wrap around. But we
|
// It's theoretically possible for this number to wrap around. But we
|
||||||
// leave that as an edge-case.
|
// leave that as an edge-case.
|
||||||
reuseCount int
|
reuseCount int
|
||||||
sessionToken atomic.Value
|
sessionToken atomic.Value
|
||||||
session atomic.Pointer[model.Session]
|
session atomic.Pointer[model.Session]
|
||||||
connectionID atomic.Value
|
connectionID atomic.Value
|
||||||
activeChannelID atomic.Value
|
activeChannelID atomic.Value
|
||||||
activeTeamID atomic.Value
|
activeTeamID atomic.Value
|
||||||
activeThreadChannelID atomic.Value
|
activeRHSThreadChannelID atomic.Value
|
||||||
endWritePump chan struct{}
|
activeThreadViewThreadChannelID atomic.Value
|
||||||
pumpFinished chan struct{}
|
endWritePump chan struct{}
|
||||||
pluginPosted chan pluginWSPostedHook
|
pumpFinished chan struct{}
|
||||||
|
pluginPosted chan pluginWSPostedHook
|
||||||
|
|
||||||
// These counters are to suppress spammy websocket.slow
|
// These counters are to suppress spammy websocket.slow
|
||||||
// and websocket.full logs which happen continuously, if they
|
// and websocket.full logs which happen continuously, if they
|
||||||
@@ -237,7 +238,8 @@ func (ps *PlatformService) NewWebConn(cfg *WebConnConfig, suite SuiteIFace, runn
|
|||||||
wc.SetConnectionID(cfg.ConnectionID)
|
wc.SetConnectionID(cfg.ConnectionID)
|
||||||
wc.SetActiveChannelID("")
|
wc.SetActiveChannelID("")
|
||||||
wc.SetActiveTeamID("")
|
wc.SetActiveTeamID("")
|
||||||
wc.SetActiveThreadChannelID("")
|
wc.SetActiveRHSThreadChannelID("")
|
||||||
|
wc.SetActiveThreadViewThreadChannelID("")
|
||||||
|
|
||||||
ps.Go(func() {
|
ps.Go(func() {
|
||||||
runner.RunMultiHook(func(hooks plugin.Hooks) bool {
|
runner.RunMultiHook(func(hooks plugin.Hooks) bool {
|
||||||
@@ -316,14 +318,24 @@ func (wc *WebConn) GetActiveTeamID() string {
|
|||||||
return wc.activeTeamID.Load().(string)
|
return wc.activeTeamID.Load().(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetActiveThreadChannelID returns the channel id of the active thread of the connection.
|
// GetActiveRHSThreadChannelID returns the channel id of the active thread of the connection.
|
||||||
func (wc *WebConn) GetActiveThreadChannelID() string {
|
func (wc *WebConn) GetActiveRHSThreadChannelID() string {
|
||||||
return wc.activeThreadChannelID.Load().(string)
|
return wc.activeRHSThreadChannelID.Load().(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetActiveThreadChannelID sets the channel id of the active thread of the connection.
|
// SetActiveRHSThreadChannelID sets the channel id of the active thread of the connection.
|
||||||
func (wc *WebConn) SetActiveThreadChannelID(id string) {
|
func (wc *WebConn) SetActiveRHSThreadChannelID(id string) {
|
||||||
wc.activeThreadChannelID.Store(id)
|
wc.activeRHSThreadChannelID.Store(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetActiveThreadViewThreadChannelID returns the channel id of the active thread of the connection.
|
||||||
|
func (wc *WebConn) GetActiveThreadViewThreadChannelID() string {
|
||||||
|
return wc.activeThreadViewThreadChannelID.Load().(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetActiveThreadViewThreadChannelID sets the channel id of the active thread of the connection.
|
||||||
|
func (wc *WebConn) SetActiveThreadViewThreadChannelID(id string) {
|
||||||
|
wc.activeThreadViewThreadChannelID.Store(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// areAllInactive returns whether all of the connections
|
// areAllInactive returns whether all of the connections
|
||||||
|
|||||||
@@ -84,7 +84,11 @@ func (wr *WebSocketRouter) ServeWebSocket(conn *WebConn, r *model.WebSocketReque
|
|||||||
}
|
}
|
||||||
if thChannelID, ok := r.Data["thread_channel_id"].(string); ok {
|
if thChannelID, ok := r.Data["thread_channel_id"].(string); ok {
|
||||||
// Set the channelID of the active thread.
|
// Set the channelID of the active thread.
|
||||||
conn.SetActiveThreadChannelID(thChannelID)
|
if isThreadView, ok := r.Data["is_thread_view"].(bool); ok && isThreadView {
|
||||||
|
conn.SetActiveThreadViewThreadChannelID(thChannelID)
|
||||||
|
} else {
|
||||||
|
conn.SetActiveRHSThreadChannelID(thChannelID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := model.NewWebSocketResponse(model.StatusOk, r.Seq, nil)
|
resp := model.NewWebSocketResponse(model.StatusOk, r.Seq, nil)
|
||||||
|
|||||||
@@ -343,9 +343,10 @@ func (wsc *WebSocketClient) UpdateActiveTeam(teamID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateActiveThread sets the channel id of the current thread that the user is in.
|
// UpdateActiveThread sets the channel id of the current thread that the user is in.
|
||||||
func (wsc *WebSocketClient) UpdateActiveThread(channelID string) {
|
func (wsc *WebSocketClient) UpdateActiveThread(isThreadView bool, channelID string) {
|
||||||
data := map[string]any{
|
data := map[string]any{
|
||||||
"thread_channel_id": channelID,
|
"thread_channel_id": channelID,
|
||||||
|
"is_thread_view": isThreadView,
|
||||||
}
|
}
|
||||||
wsc.SendMessage(string(WebsocketPresenceIndicator), data)
|
wsc.SendMessage(string(WebsocketPresenceIndicator), data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ describe('components/threading/ThreadViewer', () => {
|
|||||||
postIds: [post.id],
|
postIds: [post.id],
|
||||||
appsEnabled: true,
|
appsEnabled: true,
|
||||||
rootPostId: post.id,
|
rootPostId: post.id,
|
||||||
|
isThreadView: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
test('should match snapshot', async () => {
|
test('should match snapshot', async () => {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export type Props = Attrs & {
|
|||||||
postIds: string[];
|
postIds: string[];
|
||||||
highlightedPostId?: Post['id'];
|
highlightedPostId?: Post['id'];
|
||||||
selectedPostFocusedAt?: number;
|
selectedPostFocusedAt?: number;
|
||||||
isThreadView?: boolean;
|
isThreadView: boolean;
|
||||||
inputPlaceholder?: string;
|
inputPlaceholder?: string;
|
||||||
rootPostId: string;
|
rootPostId: string;
|
||||||
fromSuppressed?: boolean;
|
fromSuppressed?: boolean;
|
||||||
@@ -81,7 +81,7 @@ export default class ThreadViewer extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
WebSocketClient.updateActiveThread('');
|
WebSocketClient.updateActiveThread(this.props.isThreadView, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidUpdate(prevProps: Props) {
|
public componentDidUpdate(prevProps: Props) {
|
||||||
@@ -184,7 +184,7 @@ export default class ThreadViewer extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.channel) {
|
if (this.props.channel) {
|
||||||
WebSocketClient.updateActiveThread(this.props.channel?.id);
|
WebSocketClient.updateActiveThread(this.props.isThreadView, this.props.channel?.id);
|
||||||
}
|
}
|
||||||
this.setState({isLoading: false});
|
this.setState({isLoading: false});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -396,9 +396,10 @@ export default class WebSocketClient {
|
|||||||
this.sendMessage('presence', data, callback);
|
this.sendMessage('presence', data, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateActiveThread(channelId: string, callback?: (msg: any) => void) {
|
updateActiveThread(isThreadView: boolean, channelId: string, callback?: (msg: any) => void) {
|
||||||
const data = {
|
const data = {
|
||||||
thread_channel_id: channelId,
|
thread_channel_id: channelId,
|
||||||
|
is_thread_view: isThreadView,
|
||||||
};
|
};
|
||||||
this.sendMessage('presence', data, callback);
|
this.sendMessage('presence', data, callback);
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user