mirror of
https://github.com/mattermost/mattermost.git
synced 2026-10-28 02:36:08 +08:00
Define types for WebSocket messages and migrate WebSocket actions to TS (#34603)
* Add TS definitions for every WebSocket event * Remove unused WebSocket events * Add a few extra fields to POSTED events * Stop reusing WS event types as Redux actions * Remove now-unused WS event types from mattermost-redux * Rename some types to be clearer * Use new WebSocketEvents and WebSocketMessage type everywhere * Reorganize and export named types for WS messages * Use new types in websocket_actions.jsx the best we can * Rename websocket_actions.jsx to websocket_actions.tsx * Migrate websocket_actions.tsx to TypeScript * Break up websocket_messages.ts and group together WebSocketMessages types * Rename websocket_actions.tsx to websocket_actions.ts
This commit is contained in:
@@ -50,7 +50,6 @@ const (
|
||||
WebsocketEventReactionRemoved WebsocketEventType = "reaction_removed"
|
||||
WebsocketEventResponse WebsocketEventType = "response"
|
||||
WebsocketEventEmojiAdded WebsocketEventType = "emoji_added"
|
||||
WebsocketEventChannelViewed WebsocketEventType = "channel_viewed"
|
||||
WebsocketEventMultipleChannelsViewed WebsocketEventType = "multiple_channels_viewed"
|
||||
WebsocketEventPluginStatusesChanged WebsocketEventType = "plugin_statuses_changed"
|
||||
WebsocketEventPluginEnabled WebsocketEventType = "plugin_enabled"
|
||||
@@ -72,7 +71,6 @@ const (
|
||||
WebsocketEventSidebarCategoryUpdated WebsocketEventType = "sidebar_category_updated"
|
||||
WebsocketEventSidebarCategoryDeleted WebsocketEventType = "sidebar_category_deleted"
|
||||
WebsocketEventSidebarCategoryOrderUpdated WebsocketEventType = "sidebar_category_order_updated"
|
||||
WebsocketEventCloudPaymentStatusUpdated WebsocketEventType = "cloud_payment_status_updated"
|
||||
WebsocketEventCloudSubscriptionChanged WebsocketEventType = "cloud_subscription_changed"
|
||||
WebsocketEventThreadUpdated WebsocketEventType = "thread_updated"
|
||||
WebsocketEventThreadFollowChanged WebsocketEventType = "thread_follow_changed"
|
||||
|
||||
@@ -1,25 +1,20 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {Post} from '@mattermost/types/posts';
|
||||
import type {WebSocketMessages} from '@mattermost/client';
|
||||
|
||||
import {PostTypes} from 'mattermost-redux/action_types';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import type {DispatchFunc, GetStateFunc} from 'types/store';
|
||||
|
||||
export interface PostRevealedData {
|
||||
post?: string | Post;
|
||||
recipients?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the post_revealed websocket event for burn-on-read posts.
|
||||
* Two scenarios:
|
||||
* 1. Post author: Updates recipients list for real-time recipient count tracking
|
||||
* 2. Revealing user: Updates post with revealed content for multi-device sync
|
||||
*/
|
||||
export function handleBurnOnReadPostRevealed(data: PostRevealedData) {
|
||||
export function handleBurnOnReadPostRevealed(data: WebSocketMessages.BurnOnReadPostRevealed['data']) {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const state = getState();
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
@@ -74,16 +69,11 @@ export function handleBurnOnReadPostRevealed(data: PostRevealedData) {
|
||||
};
|
||||
}
|
||||
|
||||
export interface AllRevealedData {
|
||||
post_id: string;
|
||||
sender_expire_at: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the burn_on_read_all_revealed websocket event.
|
||||
* Sent to the post author when all recipients have revealed the message.
|
||||
*/
|
||||
export function handleBurnOnReadAllRevealed(data: AllRevealedData) {
|
||||
export function handleBurnOnReadAllRevealed(data: WebSocketMessages.BurnOnReadPostAllRevealed['data']) {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const state = getState();
|
||||
const {post_id: postId, sender_expire_at: senderExpireAt} = data;
|
||||
|
||||
@@ -32,7 +32,7 @@ import {loadProfilesForSidebar} from 'actions/user_actions';
|
||||
import {clearUserCookie} from 'actions/views/cookie';
|
||||
import {close as closeLhs} from 'actions/views/lhs';
|
||||
import {closeRightHandSide, closeMenu as closeRhsMenu, updateRhsState} from 'actions/views/rhs';
|
||||
import * as WebsocketActions from 'actions/websocket_actions.jsx';
|
||||
import * as WebsocketActions from 'actions/websocket_actions';
|
||||
import {getCurrentLocale} from 'selectors/i18n';
|
||||
import {getIsRhsOpen, getPreviousRhsState, getRhsState} from 'selectors/rhs';
|
||||
import BrowserStore from 'stores/browser_store';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type {AnyAction} from 'redux';
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
|
||||
import type {ChannelType} from '@mattermost/types/channels';
|
||||
import type {WebSocketMessages} from '@mattermost/client';
|
||||
import type {Post} from '@mattermost/types/posts';
|
||||
|
||||
import {
|
||||
@@ -33,20 +33,7 @@ import {ActionTypes} from 'utils/constants';
|
||||
|
||||
import type {DispatchFunc, GetStateFunc, ActionFunc, ActionFuncAsync} from 'types/store';
|
||||
|
||||
export type NewPostMessageProps = {
|
||||
channel_type: ChannelType;
|
||||
channel_display_name: string;
|
||||
channel_name: string;
|
||||
sender_name: string;
|
||||
set_online: boolean;
|
||||
mentions?: string;
|
||||
followers?: string;
|
||||
team_id: string;
|
||||
should_ack: boolean;
|
||||
otherFile?: 'true';
|
||||
image?: 'true';
|
||||
post: string;
|
||||
}
|
||||
export type NewPostMessageProps = Partial<WebSocketMessages.Posted['data']>;
|
||||
|
||||
export function completePostReceive(post: Post, websocketMessageProps: NewPostMessageProps, fetchedChannelMember?: boolean): ActionFuncAsync<boolean> {
|
||||
return async (dispatch, getState) => {
|
||||
@@ -146,7 +133,7 @@ export function setChannelReadAndViewed(dispatch: DispatchFunc, getState: GetSta
|
||||
return actionsToMarkChannelAsRead(getState, post.channel_id);
|
||||
}
|
||||
|
||||
return actionsToMarkChannelAsUnread(getState, websocketMessageProps.team_id, post.channel_id, websocketMessageProps.mentions || '', fetchedChannelMember, post.root_id === '', post?.metadata?.priority?.priority);
|
||||
return actionsToMarkChannelAsUnread(getState, websocketMessageProps.team_id || '', post.channel_id, websocketMessageProps.mentions || '', fetchedChannelMember, post.root_id === '', post?.metadata?.priority?.priority);
|
||||
}
|
||||
|
||||
export function setThreadRead(post: Post): ActionFunc<boolean> {
|
||||
|
||||
@@ -106,14 +106,14 @@ export function sendDesktopNotification(post: Post, msgProps: NewPostMessageProp
|
||||
return async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
|
||||
const teamId = msgProps.team_id;
|
||||
const teamId = msgProps.team_id || '';
|
||||
|
||||
const channel = makeGetChannel()(state, post.channel_id) || {
|
||||
id: post.channel_id,
|
||||
name: msgProps.channel_name,
|
||||
display_name: msgProps.channel_display_name,
|
||||
type: msgProps.channel_type,
|
||||
};
|
||||
} as Channel;
|
||||
const user = getCurrentUser(state);
|
||||
const member = getMyChannelMember(state, post.channel_id);
|
||||
const isCrtReply = isCollapsedThreadsEnabled(state) && post.root_id !== '';
|
||||
@@ -185,7 +185,7 @@ const getNotificationTitle = (channel: Pick<Channel, 'type' | 'display_name'>, m
|
||||
if (msgProps.channel_type === Constants.DM_CHANNEL) {
|
||||
title = Utils.localizeMessage({id: 'notification.dm', defaultMessage: 'Direct Message'});
|
||||
} else {
|
||||
title = msgProps.channel_display_name;
|
||||
title = msgProps.channel_display_name || '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,8 +218,7 @@ const getNotificationBody = (state: GlobalState, post: Post, msgProps: NewPostMe
|
||||
|
||||
let notifyText = post.message;
|
||||
|
||||
const msgPropsPost: Post = JSON.parse(msgProps.post);
|
||||
const attachments = isMessageAttachmentArray(msgPropsPost?.props?.attachments) ? msgPropsPost.props.attachments : [];
|
||||
const attachments = isMessageAttachmentArray(post.props?.attachments) ? post.props.attachments : [];
|
||||
let image = false;
|
||||
attachments.forEach((attachment) => {
|
||||
if (notifyText.length === 0) {
|
||||
|
||||
@@ -244,7 +244,7 @@ describe('Actions.Posts', () => {
|
||||
channelId: 'other_channel_id',
|
||||
fetchedChannelMember: false,
|
||||
onlyMentions: undefined,
|
||||
teamId: undefined,
|
||||
teamId: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -263,7 +263,7 @@ describe('Actions.Posts', () => {
|
||||
amountUrgent: 0,
|
||||
channelId: 'other_channel_id',
|
||||
fetchedChannelMember: false,
|
||||
teamId: undefined,
|
||||
teamId: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
import type {AnyAction} from 'redux';
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
|
||||
import type {WebSocketMessages} from '@mattermost/client';
|
||||
import type {FileInfo} from '@mattermost/types/files';
|
||||
import type {GroupChannel} from '@mattermost/types/groups';
|
||||
import type {Post} from '@mattermost/types/posts';
|
||||
import type {ScheduledPost} from '@mattermost/types/schedule_post';
|
||||
|
||||
@@ -58,7 +58,6 @@ import type {
|
||||
import type {PostDraft} from 'types/store/draft';
|
||||
import type {StorageItem} from 'types/store/storage';
|
||||
|
||||
import type {NewPostMessageProps} from './new_post';
|
||||
import {completePostReceive} from './new_post';
|
||||
import type {OnSubmitOptions, SubmitPostReturnType} from './views/create_comment';
|
||||
|
||||
@@ -67,7 +66,7 @@ export type CreatePostOptions = {
|
||||
ignorePostError?: boolean;
|
||||
}
|
||||
|
||||
export function handleNewPost(post: Post, msg?: {data?: NewPostMessageProps & GroupChannel}): ActionFuncAsync<boolean> {
|
||||
export function handleNewPost(post: Post, msg?: WebSocketMessages.Posted | WebSocketMessages.EphemeralPost): ActionFuncAsync<boolean> {
|
||||
return async (dispatch, getState) => {
|
||||
let websocketMessageProps = {};
|
||||
const state = getState();
|
||||
@@ -82,9 +81,9 @@ export function handleNewPost(post: Post, msg?: {data?: NewPostMessageProps & Gr
|
||||
await dispatch(getMyChannelMember(post.channel_id));
|
||||
}
|
||||
|
||||
dispatch(completePostReceive(post, websocketMessageProps as NewPostMessageProps, myChannelMemberDoesntExist));
|
||||
dispatch(completePostReceive(post, websocketMessageProps, myChannelMemberDoesntExist));
|
||||
|
||||
if (msg && msg.data) {
|
||||
if (msg && msg.data && 'channel_type' in msg.data) {
|
||||
if (msg.data.channel_type === Constants.DM_CHANNEL) {
|
||||
dispatch(loadNewDMIfNeeded(post.channel_id));
|
||||
} else if (msg.data.channel_type === Constants.GM_CHANNEL) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {WebSocketEvents} from '@mattermost/client';
|
||||
|
||||
import {CloudTypes} from 'mattermost-redux/action_types';
|
||||
import {fetchMyCategories} from 'mattermost-redux/actions/channel_categories';
|
||||
import {fetchAllMyTeamsChannels} from 'mattermost-redux/actions/channels';
|
||||
@@ -24,7 +26,7 @@ import store from 'stores/redux_store';
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import configureStore from 'tests/test_store';
|
||||
import {getHistory} from 'utils/browser_history';
|
||||
import Constants, {SocketEvents, ActionTypes, UserStatuses} from 'utils/constants';
|
||||
import Constants, {ActionTypes, UserStatuses} from 'utils/constants';
|
||||
|
||||
import {
|
||||
handleChannelUpdatedEvent,
|
||||
@@ -230,7 +232,7 @@ jest.mock('actions/views/rhs', () => ({
|
||||
|
||||
describe('handleEvent', () => {
|
||||
test('should dispatch channel updated event properly', () => {
|
||||
const msg = {event: SocketEvents.CHANNEL_UPDATED};
|
||||
const msg = {event: WebSocketEvents.ChannelUpdated};
|
||||
|
||||
handleEvent(msg);
|
||||
|
||||
@@ -861,7 +863,7 @@ describe('handleCloudSubscriptionChanged', () => {
|
||||
id: 'newsub',
|
||||
};
|
||||
const msg = {
|
||||
event: SocketEvents.CLOUD_PRODUCT_LIMITS_CHANGED,
|
||||
event: WebSocketEvents.CloudSubscriptionChanged,
|
||||
data: {
|
||||
limits: newLimits,
|
||||
subscription: newSubscription,
|
||||
@@ -900,7 +902,7 @@ describe('handleCloudSubscriptionChanged', () => {
|
||||
},
|
||||
};
|
||||
const msg = {
|
||||
event: SocketEvents.CLOUD_PRODUCT_LIMITS_CHANGED,
|
||||
event: WebSocketEvents.CloudSubscriptionChanged,
|
||||
data: {
|
||||
limits: newLimits,
|
||||
},
|
||||
@@ -934,7 +936,7 @@ describe('handleCloudSubscriptionChanged', () => {
|
||||
};
|
||||
|
||||
const msg = {
|
||||
event: SocketEvents.CLOUD_PRODUCT_LIMITS_CHANGED,
|
||||
event: WebSocketEvents.CloudSubscriptionChanged,
|
||||
data: {
|
||||
subscription: newSubscription,
|
||||
},
|
||||
@@ -1294,7 +1296,7 @@ describe('handleStatusChangedEvent', () => {
|
||||
expect(getStatusForUserId(testStore.getState(), currentUserId)).toBe(UserStatuses.ONLINE);
|
||||
|
||||
testStore.dispatch(handleStatusChangedEvent({
|
||||
event: SocketEvents.STATUS_CHANGED,
|
||||
event: WebSocketEvents.StatusChange,
|
||||
data: {
|
||||
user_id: currentUserId,
|
||||
status: UserStatuses.AWAY,
|
||||
@@ -1304,7 +1306,7 @@ describe('handleStatusChangedEvent', () => {
|
||||
expect(getStatusForUserId(testStore.getState(), currentUserId)).toBe(UserStatuses.AWAY);
|
||||
|
||||
testStore.dispatch(handleStatusChangedEvent({
|
||||
event: SocketEvents.STATUS_CHANGED,
|
||||
event: WebSocketEvents.StatusChange,
|
||||
data: {
|
||||
user_id: currentUserId,
|
||||
status: UserStatuses.ONLINE,
|
||||
@@ -1314,7 +1316,7 @@ describe('handleStatusChangedEvent', () => {
|
||||
expect(getStatusForUserId(testStore.getState(), currentUserId)).toBe(UserStatuses.ONLINE);
|
||||
|
||||
testStore.dispatch(handleStatusChangedEvent({
|
||||
event: SocketEvents.STATUS_CHANGED,
|
||||
event: WebSocketEvents.StatusChange,
|
||||
data: {
|
||||
user_id: currentUserId,
|
||||
status: UserStatuses.OFFLINE,
|
||||
@@ -1346,7 +1348,7 @@ describe('handleCustomAttributeValuesUpdated', () => {
|
||||
expect(stateUser(testStore.getState(), currentUserId)).toEqual({id: currentUserId});
|
||||
|
||||
testStore.dispatch(handleCustomAttributeValuesUpdated({
|
||||
event: SocketEvents.CPA_VALUES_UPDATED,
|
||||
event: WebSocketEvents.CPAValuesUpdated,
|
||||
data: {
|
||||
user_id: currentUserId,
|
||||
values: {field1: 'value1', field2: 'value2'},
|
||||
@@ -1359,7 +1361,7 @@ describe('handleCustomAttributeValuesUpdated', () => {
|
||||
|
||||
// update one field, add new field
|
||||
testStore.dispatch(handleCustomAttributeValuesUpdated({
|
||||
event: SocketEvents.CPA_VALUES_UPDATED,
|
||||
event: WebSocketEvents.CPAValuesUpdated,
|
||||
data: {
|
||||
user_id: currentUserId,
|
||||
values: {field1: 'valueChanged', field3: 'new field'},
|
||||
@@ -1378,7 +1380,7 @@ describe('handleCustomAttributeValuesUpdated', () => {
|
||||
expect(stateUser(testStore.getState(), currentUserId)).toEqual({id: currentUserId});
|
||||
|
||||
testStore.dispatch(handleCustomAttributeValuesUpdated({
|
||||
event: SocketEvents.CPA_VALUES_UPDATED,
|
||||
event: WebSocketEvents.CPAValuesUpdated,
|
||||
data: {
|
||||
user_id: 'nonExistantUser',
|
||||
values: {field1: 'value1', field2: 'value2'},
|
||||
@@ -1408,7 +1410,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
const testStore = realConfigureStore(makeInitialState());
|
||||
|
||||
testStore.dispatch(handleCustomAttributesCreated({
|
||||
event: SocketEvents.CPA_FIELD_CREATED,
|
||||
event: WebSocketEvents.CPAFieldCreated,
|
||||
data: {
|
||||
field: field1,
|
||||
},
|
||||
@@ -1422,7 +1424,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
|
||||
// create second field
|
||||
testStore.dispatch(handleCustomAttributesCreated({
|
||||
event: SocketEvents.CPA_FIELD_CREATED,
|
||||
event: WebSocketEvents.CPAFieldCreated,
|
||||
data: {
|
||||
field: field2,
|
||||
},
|
||||
@@ -1436,7 +1438,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
|
||||
// update field
|
||||
testStore.dispatch(handleCustomAttributesUpdated({
|
||||
event: SocketEvents.CPA_FIELD_UPDATED,
|
||||
event: WebSocketEvents.CPAFieldUpdated,
|
||||
data: {
|
||||
field: {...field1, name: 'Updated Name'},
|
||||
},
|
||||
@@ -1450,7 +1452,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
|
||||
// delete field
|
||||
testStore.dispatch(handleCustomAttributesDeleted({
|
||||
event: SocketEvents.CPA_FIELD_DELETED,
|
||||
event: WebSocketEvents.CPAFieldDeleted,
|
||||
data: {
|
||||
field_id: field1.id,
|
||||
},
|
||||
@@ -1468,7 +1470,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
|
||||
// First create a field
|
||||
testStore.dispatch(handleCustomAttributesCreated({
|
||||
event: SocketEvents.CPA_FIELD_CREATED,
|
||||
event: WebSocketEvents.CPAFieldCreated,
|
||||
data: {
|
||||
field: field1,
|
||||
},
|
||||
@@ -1482,7 +1484,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
// Update the field
|
||||
const updatedField = {...field1, name: 'Updated Field Name'};
|
||||
testStore.dispatch(handleCustomAttributesUpdated({
|
||||
event: SocketEvents.CPA_FIELD_UPDATED,
|
||||
event: WebSocketEvents.CPAFieldUpdated,
|
||||
data: {
|
||||
field: updatedField,
|
||||
},
|
||||
@@ -1514,7 +1516,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
|
||||
// First create a field
|
||||
testStore.dispatch(handleCustomAttributesCreated({
|
||||
event: SocketEvents.CPA_FIELD_CREATED,
|
||||
event: WebSocketEvents.CPAFieldCreated,
|
||||
data: {
|
||||
field: field1,
|
||||
},
|
||||
@@ -1523,7 +1525,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
// Update the field with delete_values flag
|
||||
const updatedField = {...field1, type: 'select'};
|
||||
testStore.dispatch(handleCustomAttributesUpdated({
|
||||
event: SocketEvents.CPA_FIELD_UPDATED,
|
||||
event: WebSocketEvents.CPAFieldUpdated,
|
||||
data: {
|
||||
field: updatedField,
|
||||
delete_values: true,
|
||||
@@ -1561,7 +1563,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
|
||||
// First create a field
|
||||
testStore.dispatch(handleCustomAttributesCreated({
|
||||
event: SocketEvents.CPA_FIELD_CREATED,
|
||||
event: WebSocketEvents.CPAFieldCreated,
|
||||
data: {
|
||||
field: field1,
|
||||
},
|
||||
@@ -1570,7 +1572,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
// Update the field but with delete_values flag set to false
|
||||
const updatedField = {...field1, name: 'Updated Field Name', type: 'text'};
|
||||
testStore.dispatch(handleCustomAttributesUpdated({
|
||||
event: SocketEvents.CPA_FIELD_UPDATED,
|
||||
event: WebSocketEvents.CPAFieldUpdated,
|
||||
data: {
|
||||
field: updatedField,
|
||||
delete_values: false,
|
||||
@@ -1609,7 +1611,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
|
||||
// First create a field
|
||||
testStore.dispatch(handleCustomAttributesCreated({
|
||||
event: SocketEvents.CPA_FIELD_CREATED,
|
||||
event: WebSocketEvents.CPAFieldCreated,
|
||||
data: {
|
||||
field: field1,
|
||||
},
|
||||
@@ -1618,7 +1620,7 @@ describe('handleCustomAttributeCRUD', () => {
|
||||
// Update the field without specifying delete_values
|
||||
const updatedField = {...field1, type: 'number'};
|
||||
testStore.dispatch(handleCustomAttributesUpdated({
|
||||
event: SocketEvents.CPA_FIELD_UPDATED,
|
||||
event: WebSocketEvents.CPAFieldUpdated,
|
||||
data: {
|
||||
field: updatedField,
|
||||
|
||||
|
||||
+278
-290
File diff suppressed because it is too large
Load Diff
@@ -5,11 +5,11 @@ import {useCallback, useEffect, useRef} from 'react';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import type {WebSocketMessage} from '@mattermost/client';
|
||||
import {WebSocketEvents} from '@mattermost/client';
|
||||
|
||||
import {getAgents as getAgentsAction} from 'mattermost-redux/actions/agents';
|
||||
import {getAgents} from 'mattermost-redux/selectors/entities/agents';
|
||||
|
||||
import {SocketEvents} from 'utils/constants';
|
||||
import {useWebSocket} from 'utils/use_websocket/hooks';
|
||||
|
||||
const AI_PLUGIN_ID = 'mattermost-ai';
|
||||
@@ -63,10 +63,10 @@ export default function useGetAgentsBridgeEnabled(): boolean {
|
||||
// Note: When a plugin is enabled/disabled, the backend fires CONFIG_CHANGED first,
|
||||
// then PLUGIN_ENABLED/PLUGIN_DISABLED. We debounce to avoid duplicate fetches.
|
||||
const isPluginEvent =
|
||||
(msg.event === SocketEvents.PLUGIN_ENABLED || msg.event === SocketEvents.PLUGIN_DISABLED) &&
|
||||
(msg.event === WebSocketEvents.PluginEnabled || msg.event === WebSocketEvents.PluginDisabled) &&
|
||||
msg.data?.manifest?.id === AI_PLUGIN_ID;
|
||||
|
||||
const isConfigChange = msg.event === SocketEvents.CONFIG_CHANGED;
|
||||
const isConfigChange = msg.event === WebSocketEvents.ConfigChanged;
|
||||
|
||||
if (isPluginEvent || isConfigChange) {
|
||||
debouncedRefetch();
|
||||
|
||||
@@ -14,7 +14,7 @@ import type {Props} from 'components/logged_in/logged_in';
|
||||
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
jest.mock('actions/websocket_actions.jsx', () => ({
|
||||
jest.mock('actions/websocket_actions', () => ({
|
||||
initialize: jest.fn(),
|
||||
close: jest.fn(),
|
||||
}));
|
||||
|
||||
@@ -7,7 +7,7 @@ import {Redirect} from 'react-router-dom';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import * as GlobalActions from 'actions/global_actions';
|
||||
import * as WebSocketActions from 'actions/websocket_actions.jsx';
|
||||
import * as WebSocketActions from 'actions/websocket_actions';
|
||||
import BrowserStore from 'stores/browser_store';
|
||||
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {WebSocketTypes} from 'mattermost-redux/action_types';
|
||||
import {getMissingProfilesByIds, getStatusesByIds} from 'mattermost-redux/actions/users';
|
||||
import {General, WebsocketEvents} from 'mattermost-redux/constants';
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import configureStore from 'tests/test_store';
|
||||
@@ -39,8 +40,8 @@ describe('handleUserTypingEvent', () => {
|
||||
|
||||
store.dispatch(userStartedTyping(userId, channelId, rootId, Date.now()));
|
||||
|
||||
expect(store.getActions().find((action) => action.type === WebsocketEvents.TYPING)).toMatchObject({
|
||||
type: WebsocketEvents.TYPING,
|
||||
expect(store.getActions().find((action) => action.type === WebSocketTypes.TYPING)).toMatchObject({
|
||||
type: WebSocketTypes.TYPING,
|
||||
data: {
|
||||
id: channelId + rootId,
|
||||
userId,
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
import type {GlobalState} from '@mattermost/types/store';
|
||||
|
||||
import {WebSocketTypes} from 'mattermost-redux/action_types';
|
||||
import {getMissingProfilesByIds, getStatusesByIds} from 'mattermost-redux/actions/users';
|
||||
import {General, Preferences, WebsocketEvents} from 'mattermost-redux/constants';
|
||||
import {General, Preferences} from 'mattermost-redux/constants';
|
||||
import {getIsUserStatusesConfigEnabled} from 'mattermost-redux/selectors/entities/common';
|
||||
import {getConfig, isPerformanceDebuggingEnabled} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||
@@ -30,7 +31,7 @@ export function userStartedTyping(userId: string, channelId: string, rootId: str
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: WebsocketEvents.TYPING,
|
||||
type: WebSocketTypes.TYPING,
|
||||
data: {
|
||||
id: channelId + rootId,
|
||||
userId,
|
||||
@@ -72,7 +73,7 @@ function fillInMissingInfo(userId: string): ActionFuncAsync {
|
||||
|
||||
export function userStoppedTyping(userId: string, channelId: string, rootId: string, now: number) {
|
||||
return {
|
||||
type: WebsocketEvents.STOP_TYPING,
|
||||
type: WebSocketTypes.STOPPED_TYPING,
|
||||
data: {
|
||||
id: channelId + rootId,
|
||||
userId,
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
import React, {useCallback} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import type {WebSocketMessage} from '@mattermost/client';
|
||||
import {WebSocketEvents, type WebSocketMessage} from '@mattermost/client';
|
||||
|
||||
import {SocketEvents} from 'utils/constants';
|
||||
import {useWebSocket} from 'utils/use_websocket';
|
||||
|
||||
type Props = {
|
||||
@@ -21,7 +20,7 @@ export default function MsgTyping(props: Props) {
|
||||
const {userStartedTyping, userStoppedTyping} = props;
|
||||
useWebSocket({
|
||||
handler: useCallback((msg: WebSocketMessage) => {
|
||||
if (msg.event === SocketEvents.TYPING) {
|
||||
if (msg.event === WebSocketEvents.Typing) {
|
||||
const channelId = msg.broadcast.channel_id;
|
||||
const rootId = msg.data.parent_id;
|
||||
const userId = msg.data.user_id;
|
||||
@@ -29,7 +28,7 @@ export default function MsgTyping(props: Props) {
|
||||
if (props.channelId === channelId && props.rootId === rootId) {
|
||||
userStartedTyping(userId, channelId, rootId, Date.now());
|
||||
}
|
||||
} else if (msg.event === SocketEvents.POSTED) {
|
||||
} else if (msg.event === WebSocketEvents.Posted) {
|
||||
const post = JSON.parse(msg.data.post);
|
||||
|
||||
const channelId = post.channel_id;
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
} from 'mattermost-redux/selectors/entities/content_flagging';
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
|
||||
import {reconnect} from 'actions/websocket_actions.jsx';
|
||||
import {reconnect} from 'actions/websocket_actions';
|
||||
import LocalStorageStore from 'stores/local_storage_store';
|
||||
|
||||
import {makeAsyncComponent, makeAsyncPluggableComponent} from 'components/async_load';
|
||||
|
||||
@@ -35,6 +35,7 @@ import SharedChannelTypes from './shared_channels';
|
||||
import TeamTypes from './teams';
|
||||
import ThreadTypes from './threads';
|
||||
import UserTypes from './users';
|
||||
import WebSocketTypes from './websocket';
|
||||
|
||||
export {
|
||||
ErrorTypes,
|
||||
@@ -69,6 +70,7 @@ export {
|
||||
SharedChannelTypes,
|
||||
ContentFlaggingTypes,
|
||||
AgentTypes,
|
||||
WebSocketTypes,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,6 @@ export default keyMirror({
|
||||
|
||||
RECEIVED_ROLES: null,
|
||||
RECEIVED_ROLE: null,
|
||||
ROLE_DELETED: null,
|
||||
|
||||
SET_PENDING_ROLES: null,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import keyMirror from 'mattermost-redux/utils/key_mirror';
|
||||
|
||||
export default keyMirror({
|
||||
TYPING: null,
|
||||
STOPPED_TYPING: null,
|
||||
});
|
||||
@@ -31,7 +31,7 @@ export function createSchedulePost(schedulePost: ScheduledPost, teamId: string,
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchTeamScheduledPosts(teamId: string, includeDirectChannels: boolean, prune?: false) {
|
||||
export function fetchTeamScheduledPosts(teamId: string, includeDirectChannels: boolean, prune?: boolean) {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let scheduledPosts;
|
||||
|
||||
|
||||
@@ -14,6 +14,5 @@ import Stats from './stats';
|
||||
import Teams from './teams';
|
||||
import Threads from './threads';
|
||||
import Users from './users';
|
||||
import WebsocketEvents from './websocket';
|
||||
|
||||
export {General, Preferences, Posts, Files, RequestStatus, WebsocketEvents, Teams, Stats, Permissions, Emoji, Plugins, Users, Roles, Threads};
|
||||
export {General, Preferences, Posts, Files, RequestStatus, Teams, Stats, Permissions, Emoji, Plugins, Users, Roles, Threads};
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
const WebsocketEvents = {
|
||||
POSTED: 'posted',
|
||||
POST_EDITED: 'post_edited',
|
||||
POST_DELETED: 'post_deleted',
|
||||
POST_UNREAD: 'post_unread',
|
||||
CHANNEL_CONVERTED: 'channel_converted',
|
||||
CHANNEL_CREATED: 'channel_created',
|
||||
CHANNEL_DELETED: 'channel_deleted',
|
||||
CHANNEL_UNARCHIVED: 'channel_restored',
|
||||
CHANNEL_UPDATED: 'channel_updated',
|
||||
MULTIPLE_CHANNELS_VIEWED: 'multiple_channels_viewed',
|
||||
CHANNEL_MEMBER_UPDATED: 'channel_member_updated',
|
||||
CHANNEL_SCHEME_UPDATED: 'channel_scheme_updated',
|
||||
DIRECT_ADDED: 'direct_added',
|
||||
ADDED_TO_TEAM: 'added_to_team',
|
||||
LEAVE_TEAM: 'leave_team',
|
||||
UPDATE_TEAM: 'update_team',
|
||||
USER_ADDED: 'user_added',
|
||||
USER_REMOVED: 'user_removed',
|
||||
USER_UPDATED: 'user_updated',
|
||||
USER_ROLE_UPDATED: 'user_role_updated',
|
||||
ROLE_ADDED: 'role_added',
|
||||
ROLE_REMOVED: 'role_removed',
|
||||
ROLE_UPDATED: 'role_updated',
|
||||
TYPING: 'typing',
|
||||
STOP_TYPING: 'stop_typing',
|
||||
PREFERENCE_CHANGED: 'preference_changed',
|
||||
PREFERENCES_CHANGED: 'preferences_changed',
|
||||
PREFERENCES_DELETED: 'preferences_deleted',
|
||||
EPHEMERAL_MESSAGE: 'ephemeral_message',
|
||||
STATUS_CHANGED: 'status_change',
|
||||
HELLO: 'hello',
|
||||
WEBRTC: 'webrtc',
|
||||
REACTION_ADDED: 'reaction_added',
|
||||
REACTION_REMOVED: 'reaction_removed',
|
||||
EMOJI_ADDED: 'emoji_added',
|
||||
LICENSE_CHANGED: 'license_changed',
|
||||
CONFIG_CHANGED: 'config_changed',
|
||||
PLUGIN_STATUSES_CHANGED: 'plugin_statuses_changed',
|
||||
OPEN_DIALOG: 'open_dialog',
|
||||
INCREASE_POST_VISIBILITY_BY_ONE: 'increase_post_visibility_by_one',
|
||||
RECEIVED_GROUP: 'received_group',
|
||||
RECEIVED_GROUP_ASSOCIATED_TO_TEAM: 'group_associated_to_team',
|
||||
RECEIVED_GROUP_NOT_ASSOCIATED_TO_TEAM: 'group_not_associated_to_team',
|
||||
RECEIVED_GROUP_ASSOCIATED_TO_CHANNEL: 'group_associated_to_channel',
|
||||
RECEIVED_GROUP_NOT_ASSOCIATED_TO_CHANNEL: 'group_not_associated_to_channel',
|
||||
THREAD_UPDATED: 'thread_updated',
|
||||
THREAD_FOLLOW_CHANGED: 'thread_follow_changed',
|
||||
THREAD_READ_CHANGED: 'thread_read_changed',
|
||||
FIRST_ADMIN_VISIT_MARKETPLACE_STATUS_RECEIVED: 'first_admin_visit_marketplace_status_received',
|
||||
GROUP_MEMBER_DELETED: 'group_member_deleted',
|
||||
BURN_ON_READ_POST_REVEALED: 'post_revealed',
|
||||
BURN_ON_READ_POST_BURNED: 'post_burned',
|
||||
BURN_ON_READ_ALL_REVEALED: 'burn_on_read_all_revealed',
|
||||
};
|
||||
export default WebsocketEvents;
|
||||
@@ -32,15 +32,6 @@ function roles(state: Record<string, Role> = {}, action: MMReduxAction) {
|
||||
|
||||
return state;
|
||||
}
|
||||
case RoleTypes.ROLE_DELETED: {
|
||||
if (action.data) {
|
||||
const nextState = {...state};
|
||||
Reflect.deleteProperty(nextState, action.data.name);
|
||||
return nextState;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
case RoleTypes.RECEIVED_ROLE: {
|
||||
if (action.data) {
|
||||
const nextState = {...state};
|
||||
|
||||
+13
-13
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {WebsocketEvents} from 'mattermost-redux/constants';
|
||||
import {WebSocketTypes} from 'mattermost-redux/action_types';
|
||||
import typingReducer from 'mattermost-redux/reducers/entities/typing';
|
||||
|
||||
import TestHelper from '../../../test/test_helper';
|
||||
@@ -17,7 +17,7 @@ describe('Reducers.Typing', () => {
|
||||
expect(state).toEqual({});
|
||||
});
|
||||
|
||||
it('WebsocketEvents.TYPING', async () => {
|
||||
it('WebSocketTypes.TYPING', async () => {
|
||||
let state = {};
|
||||
|
||||
const id1 = TestHelper.generateId();
|
||||
@@ -27,7 +27,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.TYPING,
|
||||
type: WebSocketTypes.TYPING,
|
||||
data: {
|
||||
id: id1,
|
||||
userId: userId1,
|
||||
@@ -49,7 +49,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.TYPING,
|
||||
type: WebSocketTypes.TYPING,
|
||||
data: {
|
||||
id: id2,
|
||||
userId: userId1,
|
||||
@@ -74,7 +74,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.TYPING,
|
||||
type: WebSocketTypes.TYPING,
|
||||
data: {
|
||||
id: id1,
|
||||
userId: userId2,
|
||||
@@ -99,7 +99,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.TYPING,
|
||||
type: WebSocketTypes.TYPING,
|
||||
data: {
|
||||
id: id2,
|
||||
userId: userId2,
|
||||
@@ -121,7 +121,7 @@ describe('Reducers.Typing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('WebsocketEvents.STOP_TYPING', async () => {
|
||||
it('WebSocketTypes.STOPPED_TYPING', async () => {
|
||||
const id1 = TestHelper.generateId();
|
||||
const id2 = TestHelper.generateId();
|
||||
|
||||
@@ -147,7 +147,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.STOP_TYPING,
|
||||
type: WebSocketTypes.STOPPED_TYPING,
|
||||
data: {
|
||||
id: id1,
|
||||
userId: userId1,
|
||||
@@ -170,7 +170,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.STOP_TYPING,
|
||||
type: WebSocketTypes.STOPPED_TYPING,
|
||||
data: {
|
||||
id: id2,
|
||||
userId: userId1,
|
||||
@@ -192,7 +192,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.STOP_TYPING,
|
||||
type: WebSocketTypes.STOPPED_TYPING,
|
||||
data: {
|
||||
id: id1,
|
||||
userId: userId2,
|
||||
@@ -212,7 +212,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.STOP_TYPING,
|
||||
type: WebSocketTypes.STOPPED_TYPING,
|
||||
data: {
|
||||
id: id2,
|
||||
userId: userId2,
|
||||
@@ -232,7 +232,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.STOP_TYPING,
|
||||
type: WebSocketTypes.STOPPED_TYPING,
|
||||
data: {
|
||||
id: id1,
|
||||
userId: userId1,
|
||||
@@ -251,7 +251,7 @@ describe('Reducers.Typing', () => {
|
||||
state = typingReducer(
|
||||
state,
|
||||
{
|
||||
type: WebsocketEvents.STOP_TYPING,
|
||||
type: WebSocketTypes.STOPPED_TYPING,
|
||||
data: {
|
||||
id: id1,
|
||||
userId: userId1,
|
||||
|
||||
@@ -5,7 +5,7 @@ import type {AnyAction} from 'redux';
|
||||
|
||||
import type {Typing} from '@mattermost/types/typing';
|
||||
|
||||
import {WebsocketEvents} from 'mattermost-redux/constants';
|
||||
import {WebSocketTypes} from 'mattermost-redux/action_types';
|
||||
|
||||
export default function typing(state: Typing = {}, action: AnyAction): Typing {
|
||||
const {
|
||||
@@ -14,7 +14,7 @@ export default function typing(state: Typing = {}, action: AnyAction): Typing {
|
||||
} = action;
|
||||
|
||||
switch (type) {
|
||||
case WebsocketEvents.TYPING: {
|
||||
case WebSocketTypes.TYPING: {
|
||||
const {
|
||||
id,
|
||||
userId,
|
||||
@@ -33,7 +33,7 @@ export default function typing(state: Typing = {}, action: AnyAction): Typing {
|
||||
|
||||
return state;
|
||||
}
|
||||
case WebsocketEvents.STOP_TYPING: {
|
||||
case WebSocketTypes.STOPPED_TYPING: {
|
||||
const {
|
||||
id,
|
||||
userId,
|
||||
|
||||
@@ -5,6 +5,8 @@ import React from 'react';
|
||||
import {isValidElementType} from 'react-is';
|
||||
import type {Reducer} from 'redux';
|
||||
|
||||
import type {WebSocketMessages} from '@mattermost/client';
|
||||
|
||||
import reducerRegistry from 'mattermost-redux/store/reducer_registry';
|
||||
|
||||
import {
|
||||
@@ -24,7 +26,7 @@ import {
|
||||
unregisterPluginWebSocketEvent,
|
||||
registerPluginReconnectHandler,
|
||||
unregisterPluginReconnectHandler,
|
||||
} from 'actions/websocket_actions.jsx';
|
||||
} from 'actions/websocket_actions';
|
||||
import store from 'stores/redux_store';
|
||||
|
||||
import {ActionTypes} from 'utils/constants';
|
||||
@@ -818,7 +820,16 @@ export default class PluginRegistry {
|
||||
* - handler - a function to handle the event, receives the event message as an argument
|
||||
* Returns undefined.
|
||||
*/
|
||||
registerWebSocketEventHandler = reArg(['event', 'handler'], ({event, handler}) => {
|
||||
registerWebSocketEventHandler = reArg([
|
||||
'event',
|
||||
'handler',
|
||||
], ({
|
||||
event,
|
||||
handler,
|
||||
}: {
|
||||
event: string;
|
||||
handler: (msg: WebSocketMessages.Unknown) => void;
|
||||
}) => {
|
||||
registerPluginWebSocketEvent(this.id, event, handler);
|
||||
});
|
||||
|
||||
@@ -827,7 +838,7 @@ export default class PluginRegistry {
|
||||
* Accepts a string event type.
|
||||
* Returns undefined.
|
||||
*/
|
||||
unregisterWebSocketEventHandler = reArg(['event'], ({event}) => {
|
||||
unregisterWebSocketEventHandler = reArg(['event'], ({event}: { event: string }) => {
|
||||
unregisterPluginWebSocketEvent(this.id, event);
|
||||
});
|
||||
|
||||
@@ -836,7 +847,7 @@ export default class PluginRegistry {
|
||||
* internet after previously disconnecting.
|
||||
* Accepts a function to handle the event. Returns undefined.
|
||||
*/
|
||||
registerReconnectHandler = reArg(['handler'], ({handler}) => {
|
||||
registerReconnectHandler = reArg(['handler'], ({handler}: {handler: () => void}) => {
|
||||
registerPluginReconnectHandler(this.id, handler);
|
||||
});
|
||||
|
||||
|
||||
@@ -612,97 +612,13 @@ export const AppEvents = {
|
||||
FOCUS_EDIT_TEXTBOX: 'focus_edit_textbox',
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use WebSocketEvents from @mattermost/client instead.
|
||||
*/
|
||||
export const SocketEvents = {
|
||||
POSTED: 'posted',
|
||||
POST_EDITED: 'post_edited',
|
||||
POST_DELETED: 'post_deleted',
|
||||
POST_UPDATED: 'post_updated',
|
||||
POST_UNREAD: 'post_unread',
|
||||
BURN_ON_READ_POST_REVEALED: 'post_revealed',
|
||||
BURN_ON_READ_POST_BURNED: 'post_burned',
|
||||
BURN_ON_READ_ALL_REVEALED: 'burn_on_read_all_revealed',
|
||||
CHANNEL_CONVERTED: 'channel_converted',
|
||||
CHANNEL_CREATED: 'channel_created',
|
||||
CHANNEL_DELETED: 'channel_deleted',
|
||||
CHANNEL_UNARCHIVED: 'channel_restored',
|
||||
CHANNEL_UPDATED: 'channel_updated',
|
||||
CHANNEL_BOOKMARK_CREATED: 'channel_bookmark_created',
|
||||
CHANNEL_BOOKMARK_DELETED: 'channel_bookmark_deleted',
|
||||
CHANNEL_BOOKMARK_UPDATED: 'channel_bookmark_updated',
|
||||
CHANNEL_BOOKMARK_SORTED: 'channel_bookmark_sorted',
|
||||
MULTIPLE_CHANNELS_VIEWED: 'multiple_channels_viewed',
|
||||
CHANNEL_MEMBER_UPDATED: 'channel_member_updated',
|
||||
CHANNEL_SCHEME_UPDATED: 'channel_scheme_updated',
|
||||
DIRECT_ADDED: 'direct_added',
|
||||
GROUP_ADDED: 'group_added',
|
||||
NEW_USER: 'new_user',
|
||||
ADDED_TO_TEAM: 'added_to_team',
|
||||
JOIN_TEAM: 'join_team',
|
||||
LEAVE_TEAM: 'leave_team',
|
||||
UPDATE_TEAM: 'update_team',
|
||||
DELETE_TEAM: 'delete_team',
|
||||
UPDATE_TEAM_SCHEME: 'update_team_scheme',
|
||||
USER_ADDED: 'user_added',
|
||||
USER_REMOVED: 'user_removed',
|
||||
USER_UPDATED: 'user_updated',
|
||||
USER_ROLE_UPDATED: 'user_role_updated',
|
||||
MEMBERROLE_UPDATED: 'memberrole_updated',
|
||||
ROLE_ADDED: 'role_added',
|
||||
ROLE_REMOVED: 'role_removed',
|
||||
ROLE_UPDATED: 'role_updated',
|
||||
TYPING: 'typing',
|
||||
PREFERENCE_CHANGED: 'preference_changed',
|
||||
PREFERENCES_CHANGED: 'preferences_changed',
|
||||
PREFERENCES_DELETED: 'preferences_deleted',
|
||||
EPHEMERAL_MESSAGE: 'ephemeral_message',
|
||||
STATUS_CHANGED: 'status_change',
|
||||
HELLO: 'hello',
|
||||
REACTION_ADDED: 'reaction_added',
|
||||
REACTION_REMOVED: 'reaction_removed',
|
||||
EMOJI_ADDED: 'emoji_added',
|
||||
PLUGIN_ENABLED: 'plugin_enabled',
|
||||
PLUGIN_DISABLED: 'plugin_disabled',
|
||||
LICENSE_CHANGED: 'license_changed',
|
||||
CONFIG_CHANGED: 'config_changed',
|
||||
PLUGIN_STATUSES_CHANGED: 'plugin_statuses_changed',
|
||||
OPEN_DIALOG: 'open_dialog',
|
||||
RECEIVED_GROUP: 'received_group',
|
||||
GROUP_MEMBER_ADD: 'group_member_add',
|
||||
GROUP_MEMBER_DELETED: 'group_member_deleted',
|
||||
RECEIVED_GROUP_ASSOCIATED_TO_TEAM: 'received_group_associated_to_team',
|
||||
RECEIVED_GROUP_NOT_ASSOCIATED_TO_TEAM: 'received_group_not_associated_to_team',
|
||||
RECEIVED_GROUP_ASSOCIATED_TO_CHANNEL: 'received_group_associated_to_channel',
|
||||
RECEIVED_GROUP_NOT_ASSOCIATED_TO_CHANNEL: 'received_group_not_associated_to_channel',
|
||||
SIDEBAR_CATEGORY_CREATED: 'sidebar_category_created',
|
||||
SIDEBAR_CATEGORY_UPDATED: 'sidebar_category_updated',
|
||||
SIDEBAR_CATEGORY_DELETED: 'sidebar_category_deleted',
|
||||
SIDEBAR_CATEGORY_ORDER_UPDATED: 'sidebar_category_order_updated',
|
||||
USER_ACTIVATION_STATUS_CHANGED: 'user_activation_status_change',
|
||||
CLOUD_PAYMENT_STATUS_UPDATED: 'cloud_payment_status_updated',
|
||||
CLOUD_SUBSCRIPTION_CHANGED: 'cloud_subscription_changed',
|
||||
APPS_FRAMEWORK_REFRESH_BINDINGS: 'custom_com.mattermost.apps_refresh_bindings',
|
||||
APPS_FRAMEWORK_PLUGIN_ENABLED: 'custom_com.mattermost.apps_plugin_enabled',
|
||||
APPS_FRAMEWORK_PLUGIN_DISABLED: 'custom_com.mattermost.apps_plugin_disabled',
|
||||
FIRST_ADMIN_VISIT_MARKETPLACE_STATUS_RECEIVED: 'first_admin_visit_marketplace_status_received',
|
||||
THREAD_UPDATED: 'thread_updated',
|
||||
THREAD_FOLLOW_CHANGED: 'thread_follow_changed',
|
||||
THREAD_READ_CHANGED: 'thread_read_changed',
|
||||
POST_ACKNOWLEDGEMENT_ADDED: 'post_acknowledgement_added',
|
||||
POST_ACKNOWLEDGEMENT_REMOVED: 'post_acknowledgement_removed',
|
||||
DRAFT_CREATED: 'draft_created',
|
||||
DRAFT_UPDATED: 'draft_updated',
|
||||
DRAFT_DELETED: 'draft_deleted',
|
||||
SCHEDULED_POST_CREATED: 'scheduled_post_created',
|
||||
SCHEDULED_POST_UPDATED: 'scheduled_post_updated',
|
||||
SCHEDULED_POST_DELETED: 'scheduled_post_deleted',
|
||||
PERSISTENT_NOTIFICATION_TRIGGERED: 'persistent_notification_triggered',
|
||||
HOSTED_CUSTOMER_SIGNUP_PROGRESS_UPDATED: 'hosted_customer_signup_progress_updated',
|
||||
CPA_FIELD_CREATED: 'custom_profile_attributes_field_created',
|
||||
CPA_FIELD_UPDATED: 'custom_profile_attributes_field_updated',
|
||||
CPA_FIELD_DELETED: 'custom_profile_attributes_field_deleted',
|
||||
CPA_VALUES_UPDATED: 'custom_profile_attributes_values_updated',
|
||||
CONTENT_FLAGGING_REPORT_VALUE_CHANGED: 'content_flagging_report_value_updated',
|
||||
RECAP_UPDATED: 'recap_updated',
|
||||
};
|
||||
|
||||
export const TutorialSteps = {
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {AppBinding, AppCallRequest, AppCallResponse} from '@mattermost/type
|
||||
import type {Audit} from '@mattermost/types/audits';
|
||||
import type {UserAutocomplete, AutocompleteSuggestion} from '@mattermost/types/autocomplete';
|
||||
import type {Bot, BotPatch} from '@mattermost/types/bots';
|
||||
import type {ChannelBookmark, ChannelBookmarkCreate, ChannelBookmarkPatch} from '@mattermost/types/channel_bookmarks';
|
||||
import type {ChannelBookmark, ChannelBookmarkCreate, ChannelBookmarkPatch, UpdateChannelBookmarkResponse} from '@mattermost/types/channel_bookmarks';
|
||||
import type {ChannelCategory, OrderedChannelCategories} from '@mattermost/types/channel_categories';
|
||||
import type {
|
||||
Channel,
|
||||
@@ -2040,7 +2040,7 @@ export default class Client4 {
|
||||
};
|
||||
|
||||
updateChannelBookmark = (channelId: string, channelBookmarkId: string, patch: ChannelBookmarkPatch, connectionId: string) => {
|
||||
return this.doFetch<{updated: ChannelBookmark; deleted: ChannelBookmark}>(
|
||||
return this.doFetch<UpdateChannelBookmarkResponse>(
|
||||
`${this.getChannelBookmarkRoute(channelId, channelBookmarkId)}`,
|
||||
{method: 'PATCH', body: JSON.stringify(patch), headers: {'Connection-Id': connectionId}},
|
||||
);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type * as WebSocketMessages from './websocket_messages';
|
||||
|
||||
export {
|
||||
default as Client4,
|
||||
ClientError,
|
||||
@@ -8,5 +10,7 @@ export {
|
||||
DEFAULT_LIMIT_BEFORE,
|
||||
} from './client4';
|
||||
|
||||
export type {WebSocketMessage} from './websocket';
|
||||
export {default as WebSocketClient} from './websocket';
|
||||
export {WebSocketEvents} from './websocket_events';
|
||||
export type {BaseWebSocketMessage, JsonEncodedValue, WebSocketBroadcast, WebSocketMessage} from './websocket_message';
|
||||
export {WebSocketMessages};
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
const WEBSOCKET_HELLO = 'hello';
|
||||
import {WebSocketEvents} from './websocket_events';
|
||||
import type {WebSocketMessage} from './websocket_message';
|
||||
|
||||
export type MessageListener = (msg: WebSocketMessage) => void;
|
||||
export type FirstConnectListener = () => void;
|
||||
@@ -362,7 +363,7 @@ export default class WebSocketClient {
|
||||
}
|
||||
} else if (this.eventCallback || this.messageListeners.size > 0) {
|
||||
// We check the hello packet, which is always the first packet in a stream.
|
||||
if (msg.event === WEBSOCKET_HELLO && (this.missedEventCallback || this.missedMessageListeners.size > 0)) {
|
||||
if (msg.event === WebSocketEvents.Hello && (this.missedEventCallback || this.missedMessageListeners.size > 0)) {
|
||||
console.log('got connection id ', msg.data.connection_id); //eslint-disable-line no-console
|
||||
// If we already have a connectionId present, and server sends a different one,
|
||||
// that means it's either a long timeout, or server restart, or sequence number is not found.
|
||||
@@ -675,17 +676,3 @@ export default class WebSocketClient {
|
||||
this.sendMessage('get_statuses_by_ids', data, callback);
|
||||
}
|
||||
}
|
||||
|
||||
export type WebSocketBroadcast = {
|
||||
omit_users: Record<string, boolean>;
|
||||
user_id: string;
|
||||
channel_id: string;
|
||||
team_id: string;
|
||||
}
|
||||
|
||||
export type WebSocketMessage<T = any> = {
|
||||
event: string;
|
||||
data: T;
|
||||
broadcast: WebSocketBroadcast;
|
||||
seq: number;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const enum WebSocketEvents {
|
||||
Typing = 'typing',
|
||||
Posted = 'posted',
|
||||
PostEdited = 'post_edited',
|
||||
PostDeleted = 'post_deleted',
|
||||
PostUnread = 'post_unread',
|
||||
BurnOnReadPostRevealed = 'post_revealed',
|
||||
BurnOnReadPostBurned = 'post_burned',
|
||||
BurnOnReadPostAllRevealed = 'burn_on_read_all_revealed',
|
||||
ChannelConverted = 'channel_converted',
|
||||
ChannelCreated = 'channel_created',
|
||||
ChannelDeleted = 'channel_deleted',
|
||||
ChannelRestored = 'channel_restored',
|
||||
ChannelUpdated = 'channel_updated',
|
||||
ChannelMemberUpdated = 'channel_member_updated',
|
||||
ChannelSchemeUpdated = 'channel_scheme_updated',
|
||||
DirectAdded = 'direct_added',
|
||||
GroupAdded = 'group_added',
|
||||
NewUser = 'new_user',
|
||||
AddedToTeam = 'added_to_team',
|
||||
LeaveTeam = 'leave_team',
|
||||
UpdateTeam = 'update_team',
|
||||
DeleteTeam = 'delete_team',
|
||||
RestoreTeam = 'restore_team', // This isn't currently used by the web app
|
||||
UpdateTeamScheme = 'update_team_scheme',
|
||||
UserAdded = 'user_added',
|
||||
UserUpdated = 'user_updated',
|
||||
UserRoleUpdated = 'user_role_updated',
|
||||
MemberRoleUpdated = 'memberrole_updated',
|
||||
UserRemoved = 'user_removed',
|
||||
PreferenceChanged = 'preference_changed',
|
||||
PreferencesChanged = 'preferences_changed',
|
||||
PreferencesDeleted = 'preferences_deleted',
|
||||
EphemeralMessage = 'ephemeral_message',
|
||||
StatusChange = 'status_change',
|
||||
Hello = 'hello',
|
||||
AuthenticationChallenge = 'authentication_challenge', // This isn't currently used by the web app, and it's a message that would be sent from a client to the server
|
||||
ReactionAdded = 'reaction_added',
|
||||
ReactionRemoved = 'reaction_removed',
|
||||
Response = 'response',
|
||||
EmojiAdded = 'emoji_added',
|
||||
MultipleChannelsViewed = 'multiple_channels_viewed',
|
||||
PluginStatusesChanged = 'plugin_statuses_changed',
|
||||
PluginEnabled = 'plugin_enabled',
|
||||
PluginDisabled = 'plugin_disabled',
|
||||
RoleUpdated = 'role_updated',
|
||||
LicenseChanged = 'license_changed',
|
||||
ConfigChanged = 'config_changed',
|
||||
OpenDialog = 'open_dialog',
|
||||
GuestsDeactivated = 'guests_deactivated', // This isn't currently used by the web app
|
||||
UserActivationStatusChange = 'user_activation_status_change',
|
||||
ReceivedGroup = 'received_group',
|
||||
ReceivedGroupAssociatedToTeam = 'received_group_associated_to_team',
|
||||
ReceivedGroupNotAssociatedToTeam = 'received_group_not_associated_to_team',
|
||||
ReceivedGroupAssociatedToChannel = 'received_group_associated_to_channel',
|
||||
ReceivedGroupNotAssociatedToChannel = 'received_group_not_associated_to_channel',
|
||||
GroupMemberDeleted = 'group_member_deleted',
|
||||
GroupMemberAdded = 'group_member_add',
|
||||
SidebarCategoryCreated = 'sidebar_category_created',
|
||||
SidebarCategoryUpdated = 'sidebar_category_updated',
|
||||
SidebarCategoryDeleted = 'sidebar_category_deleted',
|
||||
SidebarCategoryOrderUpdated = 'sidebar_category_order_updated',
|
||||
CloudSubscriptionChanged = 'cloud_subscription_changed',
|
||||
ThreadUpdated = 'thread_updated',
|
||||
ThreadFollowChanged = 'thread_follow_changed',
|
||||
ThreadReadChanged = 'thread_read_changed',
|
||||
FirstAdminVisitMarketplaceStatusReceived = 'first_admin_visit_marketplace_status_received',
|
||||
DraftCreated = 'draft_created',
|
||||
DraftUpdated = 'draft_updated',
|
||||
DraftDeleted = 'draft_deleted',
|
||||
PostAcknowledgementAdded = 'post_acknowledgement_added',
|
||||
PostAcknowledgementRemoved = 'post_acknowledgement_removed',
|
||||
PersistentNotificationTriggered = 'persistent_notification_triggered',
|
||||
HostedCustomerSignupProgressUpdated = 'hosted_customer_signup_progress_updated',
|
||||
ChannelBookmarkCreated = 'channel_bookmark_created',
|
||||
ChannelBookmarkUpdated = 'channel_bookmark_updated',
|
||||
ChannelBookmarkDeleted = 'channel_bookmark_deleted',
|
||||
ChannelBookmarkSorted = 'channel_bookmark_sorted',
|
||||
PresenceIndicator = 'presence',
|
||||
PostedNotifyAck = 'posted_notify_ack', // This isn't currently used by the web app
|
||||
ScheduledPostCreated = 'scheduled_post_created',
|
||||
ScheduledPostUpdated = 'scheduled_post_updated',
|
||||
ScheduledPostDeleted = 'scheduled_post_deleted',
|
||||
CPAFieldCreated = 'custom_profile_attributes_field_created',
|
||||
CPAFieldUpdated = 'custom_profile_attributes_field_updated',
|
||||
CPAFieldDeleted = 'custom_profile_attributes_field_deleted',
|
||||
CPAValuesUpdated = 'custom_profile_attributes_values_updated',
|
||||
ContentFlaggingReportValueUpdated = 'content_flagging_report_value_updated',
|
||||
RecapUpdated = 'recap_updated',
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {WebSocketEvents} from './websocket_events';
|
||||
import type * as Messages from './websocket_messages';
|
||||
|
||||
export type WebSocketMessage = (
|
||||
Messages.Hello |
|
||||
Messages.AuthenticationChallenge |
|
||||
Messages.Response |
|
||||
|
||||
Messages.Posted |
|
||||
Messages.PostEdited |
|
||||
Messages.PostDeleted |
|
||||
Messages.PostUnread |
|
||||
Messages.BurnOnReadPostRevealed |
|
||||
Messages.BurnOnReadPostBurned |
|
||||
Messages.BurnOnReadPostAllRevealed |
|
||||
Messages.EphemeralPost |
|
||||
Messages.PostReaction |
|
||||
Messages.PostAcknowledgement |
|
||||
Messages.PostDraft |
|
||||
Messages.PersistentNotificationTriggered |
|
||||
Messages.ScheduledPost |
|
||||
|
||||
Messages.ThreadUpdated |
|
||||
Messages.ThreadFollowedChanged |
|
||||
Messages.ThreadReadChanged |
|
||||
|
||||
Messages.ChannelCreated |
|
||||
Messages.ChannelUpdated |
|
||||
Messages.ChannelConverted |
|
||||
Messages.ChannelSchemeUpdated |
|
||||
Messages.ChannelDeleted |
|
||||
Messages.ChannelRestored |
|
||||
Messages.DirectChannelCreated |
|
||||
Messages.GroupChannelCreated |
|
||||
Messages.UserAddedToChannel |
|
||||
Messages.UserRemovedFromChannel |
|
||||
Messages.ChannelMemberUpdated |
|
||||
Messages.MultipleChannelsViewed |
|
||||
|
||||
Messages.ChannelBookmarkCreated |
|
||||
Messages.ChannelBookmarkUpdated |
|
||||
Messages.ChannelBookmarkDeleted |
|
||||
Messages.ChannelBookmarkSorted |
|
||||
|
||||
Messages.Team |
|
||||
Messages.UpdateTeamScheme |
|
||||
Messages.UserAddedToTeam |
|
||||
Messages.UserRemovedFromTeam |
|
||||
Messages.TeamMemberRoleUpdated |
|
||||
|
||||
Messages.NewUser |
|
||||
Messages.UserUpdated |
|
||||
Messages.UserActivationStatusChanged |
|
||||
Messages.UserRoleUpdated |
|
||||
Messages.StatusChanged |
|
||||
Messages.Typing |
|
||||
|
||||
Messages.ReceivedGroup |
|
||||
Messages.GroupAssociatedToTeam |
|
||||
Messages.GroupAssociatedToChannel |
|
||||
Messages.GroupMember |
|
||||
|
||||
Messages.PreferenceChanged |
|
||||
Messages.PreferencesChanged |
|
||||
|
||||
Messages.SidebarCategoryCreated |
|
||||
Messages.SidebarCategoryUpdated |
|
||||
Messages.SidebarCategoryDeleted |
|
||||
Messages.SidebarCategoryOrderUpdated |
|
||||
|
||||
Messages.EmojiAdded |
|
||||
|
||||
Messages.RoleUpdated |
|
||||
|
||||
Messages.ConfigChanged |
|
||||
Messages.GuestsDeactivated |
|
||||
Messages.LicenseChanged |
|
||||
Messages.CloudSubscriptionChanged |
|
||||
Messages.FirstAdminVisitMarketplaceStatusReceived |
|
||||
Messages.HostedCustomerSignupProgressUpdated |
|
||||
|
||||
Messages.CPAFieldCreated |
|
||||
Messages.CPAFieldUpdated |
|
||||
Messages.CPAFieldDeleted |
|
||||
Messages.CPAValuesUpdated |
|
||||
|
||||
Messages.ContentFlaggingReportValueUpdated |
|
||||
|
||||
Messages.RecapUpdated |
|
||||
|
||||
Messages.Plugin |
|
||||
Messages.PluginStatusesChanged |
|
||||
Messages.OpenDialog |
|
||||
|
||||
BaseWebSocketMessage<WebSocketEvents.PresenceIndicator, unknown> |
|
||||
BaseWebSocketMessage<WebSocketEvents.PostedNotifyAck, unknown>
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export type JsonEncodedValue<T> = string;
|
||||
|
||||
export type BaseWebSocketMessage<Event, T = Record<string, never>> = {
|
||||
event: Event;
|
||||
data: T;
|
||||
broadcast: WebSocketBroadcast;
|
||||
seq: number;
|
||||
}
|
||||
|
||||
export type WebSocketBroadcast = {
|
||||
omit_users: Record<string, boolean>;
|
||||
user_id: string;
|
||||
channel_id: string;
|
||||
team_id: string;
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {ChannelBookmarkWithFileInfo, UpdateChannelBookmarkResponse} from '@mattermost/types/channel_bookmarks';
|
||||
import type {ChannelCategory} from '@mattermost/types/channel_categories';
|
||||
import type {Channel, ChannelMembership, ChannelType} from '@mattermost/types/channels';
|
||||
import type {Limits, Subscription} from '@mattermost/types/cloud';
|
||||
import type {ClientConfig, ClientLicense} from '@mattermost/types/config';
|
||||
import type {Draft} from '@mattermost/types/drafts';
|
||||
import type {CustomEmoji} from '@mattermost/types/emojis';
|
||||
import type {Group, GroupMember as GroupMemberType} from '@mattermost/types/groups';
|
||||
import type {OpenDialogRequest} from '@mattermost/types/integrations';
|
||||
import type {PluginManifest, PluginStatus} from '@mattermost/types/plugins';
|
||||
import type {Post, PostAcknowledgement as PostAcknowledgementType} from '@mattermost/types/posts';
|
||||
import type {PreferenceType} from '@mattermost/types/preferences';
|
||||
import type {PropertyField, PropertyValue} from '@mattermost/types/properties';
|
||||
import type {Reaction} from '@mattermost/types/reactions';
|
||||
import type {Role} from '@mattermost/types/roles';
|
||||
import type {ScheduledPost as ScheduledPostType} from '@mattermost/types/schedule_post';
|
||||
import type {Team as TeamType, TeamMembership} from '@mattermost/types/teams';
|
||||
import type {UserThread} from '@mattermost/types/threads';
|
||||
import type {UserProfile, UserStatus} from '@mattermost/types/users';
|
||||
|
||||
import type {WebSocketEvents} from './websocket_events';
|
||||
import type {BaseWebSocketMessage, JsonEncodedValue} from './websocket_message';
|
||||
|
||||
// WebSocket-related messages
|
||||
|
||||
export type Hello = BaseWebSocketMessage<WebSocketEvents.Hello, {
|
||||
server_version: string;
|
||||
connection_id: string;
|
||||
server_hostname?: string;
|
||||
}>;
|
||||
|
||||
export type AuthenticationChallenge = BaseWebSocketMessage<WebSocketEvents.AuthenticationChallenge, unknown>;
|
||||
|
||||
export type Response = BaseWebSocketMessage<WebSocketEvents.Response>;
|
||||
|
||||
// Post, reactions, and acknowledgement messages
|
||||
|
||||
export type Posted = BaseWebSocketMessage<WebSocketEvents.Posted, {
|
||||
channel_type: ChannelType;
|
||||
channel_display_name: string;
|
||||
channel_name: string;
|
||||
sender_name: string;
|
||||
team_id: string;
|
||||
set_online: boolean;
|
||||
otherFile?: boolean;
|
||||
image?: boolean;
|
||||
post: JsonEncodedValue<Post>;
|
||||
|
||||
/**
|
||||
* If the current user is mentioned by this post, this field will contain the ID of that user. Otherwise,
|
||||
* it will be empty.
|
||||
*/
|
||||
mentions?: JsonEncodedValue<string[]>;
|
||||
|
||||
/**
|
||||
* If the current user is following this post, this field will contain the ID of that user. Otherwise,
|
||||
* it will be empty.
|
||||
*/
|
||||
followers?: JsonEncodedValue<string[]>;
|
||||
|
||||
should_ack?: boolean;
|
||||
}>;
|
||||
|
||||
export type PostEdited = BaseWebSocketMessage<WebSocketEvents.PostEdited, {
|
||||
post: JsonEncodedValue<Post>;
|
||||
}>;
|
||||
|
||||
export type PostDeleted = BaseWebSocketMessage<WebSocketEvents.PostDeleted, {
|
||||
post: JsonEncodedValue<Post>;
|
||||
|
||||
/** The user ID of the user who deleted the post, only sent to admin users. */
|
||||
delete_by?: string;
|
||||
}>;
|
||||
|
||||
export type PostUnread = BaseWebSocketMessage<WebSocketEvents.PostUnread, {
|
||||
msg_count: number;
|
||||
msg_count_root: number;
|
||||
mention_count: number;
|
||||
mention_count_root: number;
|
||||
urgent_mention_count: number;
|
||||
last_viewed_at: number;
|
||||
post_id: string;
|
||||
}>;
|
||||
|
||||
export type BurnOnReadPostRevealed = BaseWebSocketMessage<WebSocketEvents.BurnOnReadPostRevealed, {
|
||||
post?: string | Post;
|
||||
recipients?: string[];
|
||||
}>;
|
||||
|
||||
export type BurnOnReadPostBurned = BaseWebSocketMessage<WebSocketEvents.BurnOnReadPostBurned, {
|
||||
post_id: string;
|
||||
}>;
|
||||
|
||||
export type BurnOnReadPostAllRevealed = BaseWebSocketMessage<WebSocketEvents.BurnOnReadPostAllRevealed, {
|
||||
post_id: string;
|
||||
sender_expire_at: number;
|
||||
}>;
|
||||
|
||||
export type EphemeralPost = BaseWebSocketMessage<WebSocketEvents.EphemeralMessage, {
|
||||
post: JsonEncodedValue<Post>;
|
||||
}>;
|
||||
|
||||
export type PostReaction =
|
||||
BaseWebSocketMessage<WebSocketEvents.ReactionAdded | WebSocketEvents.ReactionRemoved, {
|
||||
reaction: JsonEncodedValue<Reaction>;
|
||||
}>;
|
||||
|
||||
export type PostAcknowledgement =
|
||||
BaseWebSocketMessage<WebSocketEvents.PostAcknowledgementAdded | WebSocketEvents.PostAcknowledgementRemoved, {
|
||||
acknowledgement: JsonEncodedValue<PostAcknowledgementType>;
|
||||
}>;
|
||||
|
||||
export type PostDraft =
|
||||
BaseWebSocketMessage<WebSocketEvents.DraftCreated | WebSocketEvents.DraftUpdated | WebSocketEvents.DraftDeleted, {
|
||||
draft: JsonEncodedValue<Draft>;
|
||||
}>;
|
||||
|
||||
export type PersistentNotificationTriggered =
|
||||
BaseWebSocketMessage<WebSocketEvents.PersistentNotificationTriggered, {
|
||||
post: JsonEncodedValue<Post>;
|
||||
channel_type: ChannelType;
|
||||
channel_display_name: string;
|
||||
channel_name: string;
|
||||
sender_name: string;
|
||||
team_id: string;
|
||||
otherFile?: boolean;
|
||||
image?: boolean;
|
||||
mentions?: JsonEncodedValue<string[]>;
|
||||
}>;
|
||||
|
||||
export type ScheduledPost =
|
||||
BaseWebSocketMessage<WebSocketEvents.ScheduledPostCreated | WebSocketEvents.ScheduledPostUpdated | WebSocketEvents.ScheduledPostDeleted, {
|
||||
scheduledPost: JsonEncodedValue<ScheduledPostType>;
|
||||
}>;
|
||||
|
||||
// Thread messages
|
||||
|
||||
export type ThreadUpdated = BaseWebSocketMessage<WebSocketEvents.ThreadUpdated, {
|
||||
thread: JsonEncodedValue<UserThread>;
|
||||
|
||||
previous_unread_mentions?: number;
|
||||
previous_unread_replies?: number;
|
||||
}>;
|
||||
|
||||
export type ThreadFollowedChanged = BaseWebSocketMessage<WebSocketEvents.ThreadFollowChanged, {
|
||||
thread_id: string;
|
||||
state: boolean;
|
||||
reply_count: number;
|
||||
}>;
|
||||
|
||||
export type ThreadReadChanged = BaseWebSocketMessage<WebSocketEvents.ThreadReadChanged, {
|
||||
thread_id?: string;
|
||||
timestamp: number;
|
||||
unread_mentions?: number;
|
||||
unread_replies?: number;
|
||||
previous_unread_mentions?: number;
|
||||
previous_unread_replies?: number;
|
||||
channel_id?: string;
|
||||
}>;
|
||||
|
||||
// Channel and channel member messages
|
||||
|
||||
export type ChannelCreated = BaseWebSocketMessage<WebSocketEvents.ChannelCreated, {
|
||||
channel_id: string;
|
||||
team_id: string;
|
||||
}>;
|
||||
|
||||
export type ChannelUpdated = BaseWebSocketMessage<WebSocketEvents.ChannelUpdated, {
|
||||
|
||||
// Normally, the channel field is sent, except in some cases where a shared channel is updated in which case
|
||||
// the channel_id field is used.
|
||||
|
||||
channel?: JsonEncodedValue<Channel>;
|
||||
channel_id?: string;
|
||||
}>;
|
||||
|
||||
export type ChannelConverted = BaseWebSocketMessage<WebSocketEvents.ChannelConverted, {
|
||||
channel_id: string;
|
||||
}>;
|
||||
|
||||
export type ChannelSchemeUpdated = BaseWebSocketMessage<WebSocketEvents.ChannelSchemeUpdated>;
|
||||
|
||||
export type ChannelDeleted = BaseWebSocketMessage<WebSocketEvents.ChannelDeleted, {
|
||||
channel_id: string;
|
||||
delete_at: number;
|
||||
}>;
|
||||
|
||||
export type ChannelRestored = BaseWebSocketMessage<WebSocketEvents.ChannelRestored, {
|
||||
channel_id: string;
|
||||
}>;
|
||||
|
||||
export type DirectChannelCreated = BaseWebSocketMessage<WebSocketEvents.DirectAdded, {
|
||||
creator_id: string;
|
||||
teammate_id: string;
|
||||
}>;
|
||||
|
||||
export type GroupChannelCreated = BaseWebSocketMessage<WebSocketEvents.GroupAdded, {
|
||||
teammate_ids: JsonEncodedValue<string[]>;
|
||||
}>;
|
||||
|
||||
export type UserAddedToChannel = BaseWebSocketMessage<WebSocketEvents.UserAdded, {
|
||||
user_id: string;
|
||||
team_id: string;
|
||||
}>;
|
||||
|
||||
export type UserRemovedFromChannel = BaseWebSocketMessage<WebSocketEvents.UserRemoved, {
|
||||
|
||||
/** The user ID of the user that was removed from the channel. It isn't sent to the user who was removed. */
|
||||
user_id?: string;
|
||||
|
||||
/** The ID of the channel that the user was removed from. It's only sent to the user who was removed. */
|
||||
channel_id?: string;
|
||||
|
||||
remover_id: string;
|
||||
}>;
|
||||
|
||||
export type ChannelMemberUpdated = BaseWebSocketMessage<WebSocketEvents.ChannelMemberUpdated, {
|
||||
channelMember: JsonEncodedValue<ChannelMembership>;
|
||||
}>;
|
||||
|
||||
export type MultipleChannelsViewed = BaseWebSocketMessage<WebSocketEvents.MultipleChannelsViewed, {
|
||||
channel_times: Record<string, number>;
|
||||
}>;
|
||||
|
||||
// Channel bookmark messages
|
||||
|
||||
export type ChannelBookmarkCreated = BaseWebSocketMessage<WebSocketEvents.ChannelBookmarkCreated, {
|
||||
bookmark: JsonEncodedValue<ChannelBookmarkWithFileInfo>;
|
||||
}>;
|
||||
|
||||
export type ChannelBookmarkUpdated = BaseWebSocketMessage<WebSocketEvents.ChannelBookmarkUpdated, {
|
||||
bookmarks: JsonEncodedValue<UpdateChannelBookmarkResponse>;
|
||||
}>;
|
||||
|
||||
export type ChannelBookmarkDeleted = BaseWebSocketMessage<WebSocketEvents.ChannelBookmarkDeleted, {
|
||||
bookmark: JsonEncodedValue<ChannelBookmarkWithFileInfo>;
|
||||
}>;
|
||||
|
||||
export type ChannelBookmarkSorted = BaseWebSocketMessage<WebSocketEvents.ChannelBookmarkSorted, {
|
||||
bookmarks: JsonEncodedValue<ChannelBookmarkWithFileInfo[]>;
|
||||
}>;
|
||||
|
||||
// Team and team member messages
|
||||
|
||||
export type Team =
|
||||
BaseWebSocketMessage<WebSocketEvents.UpdateTeam | WebSocketEvents.DeleteTeam | WebSocketEvents.RestoreTeam, {
|
||||
team: JsonEncodedValue<TeamType>;
|
||||
}>;
|
||||
|
||||
export type UserAddedToTeam = BaseWebSocketMessage<WebSocketEvents.AddedToTeam, {
|
||||
team_id: string;
|
||||
user_id: string;
|
||||
}>;
|
||||
|
||||
export type UserRemovedFromTeam = BaseWebSocketMessage<WebSocketEvents.LeaveTeam, {
|
||||
user_id: string;
|
||||
team_id: string;
|
||||
}>;
|
||||
|
||||
export type UpdateTeamScheme = BaseWebSocketMessage<WebSocketEvents.UpdateTeamScheme, {
|
||||
team: JsonEncodedValue<Team>;
|
||||
}>;
|
||||
|
||||
export type TeamMemberRoleUpdated = BaseWebSocketMessage<WebSocketEvents.MemberRoleUpdated, {
|
||||
member: JsonEncodedValue<TeamMembership>;
|
||||
}>;
|
||||
|
||||
// User and status messages
|
||||
|
||||
export type NewUser = BaseWebSocketMessage<WebSocketEvents.NewUser, {
|
||||
user_id: string;
|
||||
}>;
|
||||
|
||||
export type UserUpdated = BaseWebSocketMessage<WebSocketEvents.UserUpdated, {
|
||||
|
||||
/** This user may be missing sensitive data based on if the recipient is that user or an admin. */
|
||||
user: UserProfile;
|
||||
}>;
|
||||
|
||||
export type UserActivationStatusChanged = BaseWebSocketMessage<WebSocketEvents.UserActivationStatusChange>;
|
||||
|
||||
export type UserRoleUpdated = BaseWebSocketMessage<WebSocketEvents.UserRoleUpdated, {
|
||||
user_id: string;
|
||||
roles: string;
|
||||
}>;
|
||||
|
||||
export type StatusChanged = BaseWebSocketMessage<WebSocketEvents.StatusChange, {
|
||||
status: UserStatus['status'];
|
||||
user_id: string;
|
||||
}>;
|
||||
|
||||
export type Typing = BaseWebSocketMessage<WebSocketEvents.Typing, {
|
||||
parent_id: string;
|
||||
user_id: string;
|
||||
}>;
|
||||
|
||||
// Group-related messages
|
||||
|
||||
export type ReceivedGroup = BaseWebSocketMessage<WebSocketEvents.ReceivedGroup, {
|
||||
group: JsonEncodedValue<Group>;
|
||||
}>;
|
||||
|
||||
export type GroupAssociatedToTeam =
|
||||
BaseWebSocketMessage<WebSocketEvents.ReceivedGroupAssociatedToTeam | WebSocketEvents.ReceivedGroupNotAssociatedToTeam, {
|
||||
group_id: string;
|
||||
}>;
|
||||
|
||||
export type GroupAssociatedToChannel =
|
||||
BaseWebSocketMessage<WebSocketEvents.ReceivedGroupAssociatedToChannel | WebSocketEvents.ReceivedGroupNotAssociatedToChannel, {
|
||||
group_id: string;
|
||||
}>;
|
||||
|
||||
export type GroupMember =
|
||||
BaseWebSocketMessage<WebSocketEvents.GroupMemberAdded | WebSocketEvents.GroupMemberDeleted, {
|
||||
group_member: JsonEncodedValue<GroupMemberType>;
|
||||
}>;
|
||||
|
||||
// Preference messages
|
||||
|
||||
export type PreferenceChanged = BaseWebSocketMessage<WebSocketEvents.PreferenceChanged, {
|
||||
preference: JsonEncodedValue<PreferenceType>;
|
||||
}>;
|
||||
|
||||
export type PreferencesChanged =
|
||||
BaseWebSocketMessage<WebSocketEvents.PreferencesChanged | WebSocketEvents.PreferencesDeleted, {
|
||||
preferences: JsonEncodedValue<PreferenceType[]>;
|
||||
}>;
|
||||
|
||||
// Channel sidebar messages
|
||||
|
||||
export type SidebarCategoryCreated = BaseWebSocketMessage<WebSocketEvents.SidebarCategoryCreated, {
|
||||
category_id: string;
|
||||
}>;
|
||||
|
||||
export type SidebarCategoryUpdated = BaseWebSocketMessage<WebSocketEvents.SidebarCategoryUpdated, {
|
||||
updatedCategories: JsonEncodedValue<ChannelCategory[]>;
|
||||
}>;
|
||||
|
||||
export type SidebarCategoryDeleted = BaseWebSocketMessage<WebSocketEvents.SidebarCategoryDeleted, {
|
||||
category_id: string;
|
||||
}>;
|
||||
|
||||
export type SidebarCategoryOrderUpdated = BaseWebSocketMessage<WebSocketEvents.SidebarCategoryOrderUpdated, {
|
||||
order: string[];
|
||||
}>;
|
||||
|
||||
// Emoji messages
|
||||
|
||||
export type EmojiAdded = BaseWebSocketMessage<WebSocketEvents.EmojiAdded, {
|
||||
emoji: JsonEncodedValue<Omit<CustomEmoji, 'category'>>;
|
||||
}>;
|
||||
|
||||
// Role messages
|
||||
|
||||
export type RoleUpdated = BaseWebSocketMessage<WebSocketEvents.RoleUpdated, {
|
||||
role: JsonEncodedValue<Role>;
|
||||
}>;
|
||||
|
||||
// Configuration and license messages
|
||||
|
||||
export type ConfigChanged = BaseWebSocketMessage<WebSocketEvents.ConfigChanged, {
|
||||
config: ClientConfig;
|
||||
}>;
|
||||
|
||||
export type GuestsDeactivated = BaseWebSocketMessage<WebSocketEvents.GuestsDeactivated>;
|
||||
|
||||
export type LicenseChanged = BaseWebSocketMessage<WebSocketEvents.LicenseChanged, {
|
||||
license: ClientLicense;
|
||||
}>;
|
||||
|
||||
export type CloudSubscriptionChanged = BaseWebSocketMessage<WebSocketEvents.CloudSubscriptionChanged, {
|
||||
limits?: Limits;
|
||||
subscription: Subscription;
|
||||
}>;
|
||||
|
||||
export type FirstAdminVisitMarketplaceStatusReceived =
|
||||
BaseWebSocketMessage<WebSocketEvents.FirstAdminVisitMarketplaceStatusReceived, {
|
||||
firstAdminVisitMarketplaceStatus: JsonEncodedValue<boolean>;
|
||||
}>;
|
||||
|
||||
export type HostedCustomerSignupProgressUpdated =
|
||||
BaseWebSocketMessage<WebSocketEvents.HostedCustomerSignupProgressUpdated, {
|
||||
progress: string;
|
||||
}>
|
||||
|
||||
// Custom properties messages
|
||||
|
||||
export type CPAFieldCreated = BaseWebSocketMessage<WebSocketEvents.CPAFieldCreated, {
|
||||
field: PropertyField;
|
||||
}>;
|
||||
|
||||
export type CPAFieldUpdated = BaseWebSocketMessage<WebSocketEvents.CPAFieldUpdated, {
|
||||
field: PropertyField;
|
||||
delete_values: boolean;
|
||||
}>;
|
||||
|
||||
export type CPAFieldDeleted = BaseWebSocketMessage<WebSocketEvents.CPAFieldDeleted, {
|
||||
field_id: string;
|
||||
}>;
|
||||
|
||||
export type CPAValuesUpdated = BaseWebSocketMessage<WebSocketEvents.CPAValuesUpdated, {
|
||||
user_id: string;
|
||||
values: Array<PropertyValue<unknown>>;
|
||||
}>;
|
||||
|
||||
// Content flagging messages
|
||||
|
||||
export type ContentFlaggingReportValueUpdated =
|
||||
BaseWebSocketMessage<WebSocketEvents.ContentFlaggingReportValueUpdated, {
|
||||
property_values: JsonEncodedValue<Array<PropertyValue<unknown>>>;
|
||||
target_id: string;
|
||||
}>;
|
||||
|
||||
// Recap messages
|
||||
|
||||
export type RecapUpdated = BaseWebSocketMessage<WebSocketEvents.RecapUpdated, {
|
||||
recap_id: string;
|
||||
}>;
|
||||
|
||||
// Plugin and integration messages
|
||||
|
||||
export type Plugin = BaseWebSocketMessage<WebSocketEvents.PluginEnabled | WebSocketEvents.PluginDisabled, {
|
||||
manifest: PluginManifest;
|
||||
}>;
|
||||
|
||||
export type PluginStatusesChanged = BaseWebSocketMessage<WebSocketEvents.PluginStatusesChanged, {
|
||||
plugin_statuses: PluginStatus[];
|
||||
}>;
|
||||
|
||||
export type OpenDialog = BaseWebSocketMessage<WebSocketEvents.OpenDialog, {
|
||||
dialog: JsonEncodedValue<OpenDialogRequest>;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Unknown is used for WebSocket messages which don't come from Mattermost itself. It's primarily intended for use
|
||||
* by plugins.
|
||||
*/
|
||||
export type Unknown = BaseWebSocketMessage<string, unknown>;
|
||||
@@ -48,6 +48,11 @@ export type ChannelBookmarkPatch = {
|
||||
emoji?: string;
|
||||
}
|
||||
|
||||
export type UpdateChannelBookmarkResponse = {
|
||||
updated: ChannelBookmark;
|
||||
deleted: ChannelBookmark;
|
||||
};
|
||||
|
||||
export type ChannelBookmarkWithFileInfo = ChannelBookmark & {
|
||||
file: FileInfo;
|
||||
}
|
||||
|
||||
@@ -142,14 +142,16 @@ export type IntegrationsState = {
|
||||
commands: IDMappedObjects<Command>;
|
||||
dialogArguments?: DialogArgs;
|
||||
dialogTriggerId: string;
|
||||
dialog?: {
|
||||
url: string;
|
||||
dialog: Dialog;
|
||||
trigger_id: string;
|
||||
};
|
||||
dialog?: OpenDialogRequest;
|
||||
};
|
||||
|
||||
type Dialog = {
|
||||
export type OpenDialogRequest = {
|
||||
trigger_id: string;
|
||||
url: string;
|
||||
dialog: Dialog;
|
||||
}
|
||||
|
||||
export type Dialog = {
|
||||
callback_id?: string;
|
||||
elements?: DialogElement[];
|
||||
title: string;
|
||||
|
||||
Reference in New Issue
Block a user