mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-48670] Fix persistence of placeholder text (#22820)
Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
committed by
GitHub
parent
b200a07881
commit
0c375e1ebd
@@ -18,7 +18,7 @@ import {
|
||||
makeOnSubmit,
|
||||
makeOnEditLatestPost,
|
||||
} from 'actions/views/create_comment';
|
||||
import {removeDraft} from 'actions/views/drafts';
|
||||
import {removeDraft, setGlobalDraftSource} from 'actions/views/drafts';
|
||||
import {setGlobalItem, actionOnGlobalItemsWithPrefix} from 'actions/storage';
|
||||
import * as PostActions from 'actions/post_actions';
|
||||
import {executeCommand} from 'actions/command';
|
||||
@@ -205,12 +205,13 @@ describe('rhs view actions', () => {
|
||||
|
||||
const testStore = mockStore(initialState);
|
||||
|
||||
testStore.dispatch(setGlobalItem(`${StoragePrefixes.COMMENT_DRAFT}${rootId}`, {
|
||||
const expectedKey = `${StoragePrefixes.COMMENT_DRAFT}${rootId}`;
|
||||
testStore.dispatch(setGlobalItem(expectedKey, {
|
||||
...draft,
|
||||
createAt: 42,
|
||||
updateAt: 42,
|
||||
remote: false,
|
||||
}));
|
||||
testStore.dispatch(setGlobalDraftSource(expectedKey, false));
|
||||
|
||||
expect(store.getActions()).toEqual(testStore.getActions());
|
||||
jest.useRealTimers();
|
||||
|
||||
@@ -13,7 +13,7 @@ import {getPreferenceKey} from 'mattermost-redux/utils/preference_utils';
|
||||
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {removeDraft, updateDraft} from './drafts';
|
||||
import {removeDraft, setGlobalDraftSource, updateDraft} from './drafts';
|
||||
|
||||
jest.mock('mattermost-redux/client', () => {
|
||||
const original = jest.requireActual('mattermost-redux/client');
|
||||
@@ -146,12 +146,13 @@ describe('draft actions', () => {
|
||||
|
||||
const testStore = mockStore(initialState);
|
||||
|
||||
testStore.dispatch(setGlobalItem(StoragePrefixes.DRAFT + channelId, {
|
||||
const expectedKey = StoragePrefixes.DRAFT + channelId;
|
||||
testStore.dispatch(setGlobalItem(expectedKey, {
|
||||
...draft,
|
||||
createAt: 42,
|
||||
updateAt: 42,
|
||||
remote: false,
|
||||
}));
|
||||
testStore.dispatch(setGlobalDraftSource(expectedKey, false));
|
||||
|
||||
expect(store.getActions()).toEqual(testStore.getActions());
|
||||
jest.useRealTimers();
|
||||
|
||||
@@ -15,7 +15,7 @@ import {PostDraft} from 'types/store/draft';
|
||||
import {getGlobalItem} from 'selectors/storage';
|
||||
import {makeGetDrafts} from 'selectors/drafts';
|
||||
|
||||
import {StoragePrefixes} from 'utils/constants';
|
||||
import {ActionTypes, StoragePrefixes} from 'utils/constants';
|
||||
|
||||
import type {Draft as ServerDraft} from '@mattermost/types/drafts';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
@@ -101,11 +101,10 @@ export function updateDraft(key: string, value: PostDraft|null, rootId = '', sav
|
||||
...value,
|
||||
createAt: data.createAt || timestamp,
|
||||
updateAt: timestamp,
|
||||
remote: false,
|
||||
};
|
||||
}
|
||||
|
||||
dispatch(setGlobalItem(key, updatedValue));
|
||||
dispatch(setGlobalDraft(key, updatedValue, false));
|
||||
|
||||
if (syncedDraftsAreAllowedAndEnabled(state) && save && updatedValue) {
|
||||
const connectionId = getConnectionId(state);
|
||||
@@ -153,6 +152,24 @@ export function setDraftsTourTipPreference(initializationState: Record<string, b
|
||||
};
|
||||
}
|
||||
|
||||
export function setGlobalDraft(key: string, value: PostDraft|null, isRemote: boolean) {
|
||||
return (dispatch: DispatchFunc) => {
|
||||
dispatch(setGlobalItem(key, value));
|
||||
dispatch(setGlobalDraftSource(key, isRemote));
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function setGlobalDraftSource(key: string, isRemote: boolean) {
|
||||
return {
|
||||
type: ActionTypes.SET_DRAFT_SOURCE,
|
||||
data: {
|
||||
key,
|
||||
isRemote,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function transformServerDraft(draft: ServerDraft): Draft {
|
||||
let key: Draft['key'] = `${StoragePrefixes.DRAFT}${draft.channel_id}`;
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ import {
|
||||
} from 'mattermost-redux/actions/users';
|
||||
import {removeNotVisibleUsers} from 'mattermost-redux/actions/websocket';
|
||||
import {setGlobalItem} from 'actions/storage';
|
||||
import {transformServerDraft} from 'actions/views/drafts';
|
||||
import {setGlobalDraft, transformServerDraft} from 'actions/views/drafts';
|
||||
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {getCurrentUser, getCurrentUserId, getUser, getIsManualStatusForUserId, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||
@@ -89,7 +89,6 @@ import {getStandardAnalytics} from 'mattermost-redux/actions/admin';
|
||||
|
||||
import {fetchAppBindings, fetchRHSAppsBindings} from 'mattermost-redux/actions/apps';
|
||||
|
||||
import {getConnectionId} from 'selectors/general';
|
||||
import {getSelectedChannelId, getSelectedPost} from 'selectors/rhs';
|
||||
import {isThreadOpen, isThreadManuallyUnread} from 'selectors/views/threads';
|
||||
|
||||
@@ -1700,20 +1699,12 @@ function handlePostAcknowledgementRemoved(msg) {
|
||||
}
|
||||
|
||||
function handleUpsertDraftEvent(msg) {
|
||||
return async (doDispatch, doGetState) => {
|
||||
const state = doGetState();
|
||||
const connectionId = getConnectionId(state);
|
||||
|
||||
return async (doDispatch) => {
|
||||
const draft = JSON.parse(msg.data.draft);
|
||||
const {key, value} = transformServerDraft(draft);
|
||||
value.show = true;
|
||||
value.remote = false;
|
||||
|
||||
if (msg.broadcast.omit_connection_id !== connectionId) {
|
||||
value.remote = true;
|
||||
}
|
||||
|
||||
doDispatch(setGlobalItem(key, value));
|
||||
doDispatch(setGlobalDraft(key, value, true));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1722,7 +1713,11 @@ function handleDeleteDraftEvent(msg) {
|
||||
const draft = JSON.parse(msg.data.draft);
|
||||
const {key} = transformServerDraft(draft);
|
||||
|
||||
doDispatch(setGlobalItem(key, {message: '', fileInfos: [], uploadsInProgress: [], remote: true}));
|
||||
doDispatch(setGlobalItem(key, {
|
||||
message: '',
|
||||
fileInfos: [],
|
||||
uploadsInProgress: [],
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ describe('components/AdvancedCreateComment', () => {
|
||||
uploadsInProgress: [{}],
|
||||
fileInfos: [{}, {}, {}],
|
||||
},
|
||||
isRemoteDraft: false,
|
||||
enableAddButton: true,
|
||||
ctrlSend: false,
|
||||
latestPostId,
|
||||
@@ -84,9 +85,10 @@ describe('components/AdvancedCreateComment', () => {
|
||||
|
||||
test('should match snapshot, empty comment', () => {
|
||||
const draft = emptyDraft;
|
||||
const isRemoteDraft = false;
|
||||
const enableAddButton = false;
|
||||
const ctrlSend = true;
|
||||
const props = {...baseProps, draft, enableAddButton, ctrlSend};
|
||||
const props = {...baseProps, draft, isRemoteDraft, enableAddButton, ctrlSend};
|
||||
|
||||
const wrapper = shallow(
|
||||
<AdvancedCreateComment {...props}/>,
|
||||
@@ -104,8 +106,9 @@ describe('components/AdvancedCreateComment', () => {
|
||||
uploadsInProgress: [],
|
||||
fileInfos: [],
|
||||
};
|
||||
const isRemoteDraft = false;
|
||||
const ctrlSend = true;
|
||||
const props = {...baseProps, ctrlSend, draft, clearCommentDraftUploads, onResetHistoryIndex, getChannelMemberCountsByGroup};
|
||||
const props = {...baseProps, ctrlSend, draft, isRemoteDraft, clearCommentDraftUploads, onResetHistoryIndex, getChannelMemberCountsByGroup};
|
||||
|
||||
const wrapper = shallow(
|
||||
<AdvancedCreateComment {...props}/>,
|
||||
|
||||
@@ -74,6 +74,9 @@ type Props = {
|
||||
// The current draft of the comment
|
||||
draft: PostDraft;
|
||||
|
||||
// Data used for knowing if the draft came from a WS event
|
||||
isRemoteDraft: boolean;
|
||||
|
||||
// Determines if the submit button should be rendered
|
||||
enableAddButton?: boolean;
|
||||
|
||||
@@ -233,8 +236,14 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
||||
|
||||
const rootChanged = props.rootId !== state.rootId;
|
||||
const messageInHistoryChanged = props.messageInHistory !== state.messageInHistory;
|
||||
if (rootChanged || messageInHistoryChanged || props.draft.remote) {
|
||||
updatedState = {...updatedState, draft: {...props.draft, uploadsInProgress: rootChanged ? [] : props.draft.uploadsInProgress}};
|
||||
if (rootChanged || messageInHistoryChanged || (props.isRemoteDraft && props.draft.message !== state.draft?.message)) {
|
||||
updatedState = {
|
||||
...updatedState,
|
||||
draft: {
|
||||
...props.draft,
|
||||
uploadsInProgress: rootChanged ? [] : props.draft.uploadsInProgress,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return updatedState;
|
||||
@@ -252,6 +261,7 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
||||
serverError: null,
|
||||
showFormat: false,
|
||||
isFormattingBarHidden: props.isFormattingBarHidden,
|
||||
caretPosition: props.draft.caretPosition,
|
||||
};
|
||||
|
||||
this.textboxRef = React.createRef();
|
||||
@@ -343,7 +353,6 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
||||
const updatedDraft = {
|
||||
...this.state.draft,
|
||||
show: !isDraftEmpty(this.state.draft),
|
||||
remote: false,
|
||||
} as PostDraft;
|
||||
|
||||
this.props.onUpdateCommentDraft(updatedDraft, true);
|
||||
@@ -356,7 +365,6 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
||||
draft: {
|
||||
...prev.draft,
|
||||
show: !isDraftEmpty(prev.draft),
|
||||
remote: false,
|
||||
} as PostDraft,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ function makeMapStateToProps() {
|
||||
const err = state.requests.posts.createPost.error || {};
|
||||
|
||||
const draft = getPostDraft(state, StoragePrefixes.COMMENT_DRAFT, ownProps.rootId);
|
||||
const isRemoteDraft = state.views.drafts.remotes[`${StoragePrefixes.COMMENT_DRAFT}${ownProps.rootId}`] || false;
|
||||
|
||||
const channelMembersCount = getAllChannelStats(state)[ownProps.channelId] ? getAllChannelStats(state)[ownProps.channelId].member_count : 1;
|
||||
const messageInHistory = getMessageInHistoryItem(state);
|
||||
@@ -91,6 +92,7 @@ function makeMapStateToProps() {
|
||||
return {
|
||||
currentTeamId,
|
||||
draft,
|
||||
isRemoteDraft,
|
||||
messageInHistory,
|
||||
channelMembersCount,
|
||||
currentUserId,
|
||||
@@ -121,11 +123,11 @@ function makeMapStateToProps() {
|
||||
}
|
||||
|
||||
function makeOnUpdateCommentDraft(rootId: string, channelId: string) {
|
||||
return (draft?: PostDraft, save = false) => updateCommentDraft(rootId, draft ? {...draft, channelId, remote: false} : draft, save);
|
||||
return (draft?: PostDraft, save = false) => updateCommentDraft(rootId, draft ? {...draft, channelId} : draft, save);
|
||||
}
|
||||
|
||||
function makeUpdateCommentDraftWithRootId(channelId: string) {
|
||||
return (rootId: string, draft?: PostDraft, save = false) => updateCommentDraft(rootId, draft ? {...draft, channelId, remote: false} : draft, save);
|
||||
return (rootId: string, draft?: PostDraft, save = false) => updateCommentDraft(rootId, draft ? {...draft, channelId} : draft, save);
|
||||
}
|
||||
|
||||
type Actions = {
|
||||
|
||||
@@ -115,6 +115,7 @@ function advancedCreatePost({
|
||||
fullWidthTextBox={fullWidthTextBox}
|
||||
currentChannelMembersCount={currentChannelMembersCount}
|
||||
draft={draft}
|
||||
isRemoteDraft={false}
|
||||
recentPostIdInChannel={recentPostIdInChannel}
|
||||
latestReplyablePostId={latestReplyablePostId}
|
||||
locale={locale}
|
||||
|
||||
@@ -124,6 +124,9 @@ type Props = {
|
||||
// Data used for populating message state from previous draft
|
||||
draft: PostDraft;
|
||||
|
||||
// Data used for knowing if the draft came from a WS event
|
||||
isRemoteDraft: boolean;
|
||||
|
||||
// Data used dispatching handleViewAction ex: edit post
|
||||
latestReplyablePostId?: string;
|
||||
locale: string;
|
||||
@@ -279,7 +282,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
||||
};
|
||||
if (
|
||||
props.currentChannel.id !== state.currentChannel.id ||
|
||||
(props.draft.remote && props.draft.message !== state.message)
|
||||
(props.isRemoteDraft && props.draft.message !== state.message)
|
||||
) {
|
||||
updatedState = {
|
||||
...updatedState,
|
||||
@@ -294,8 +297,8 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
message: this.props.draft.message,
|
||||
caretPosition: this.props.draft.message.length,
|
||||
message: props.draft.message,
|
||||
caretPosition: props.draft.message.length,
|
||||
submitting: false,
|
||||
showEmojiPicker: false,
|
||||
uploadsProgressPercent: {},
|
||||
@@ -387,7 +390,6 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
||||
this.draftsForChannel[channelId] = {
|
||||
...draft,
|
||||
show: !isDraftEmpty(draft),
|
||||
remote: false,
|
||||
} as PostDraft;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ function makeMapStateToProps() {
|
||||
const currentChannel = getCurrentChannel(state) || {};
|
||||
const currentChannelTeammateUsername = getUser(state, currentChannel.teammate_id || '')?.username;
|
||||
const draft = getChannelDraft(state, currentChannel.id);
|
||||
const isRemoteDraft = state.views.drafts.remotes[`${StoragePrefixes.DRAFT}${currentChannel.id}`] || false;
|
||||
const latestReplyablePostId = getLatestReplyablePostId(state);
|
||||
const currentChannelMembersCount = getCurrentChannelStats(state) ? getCurrentChannelStats(state).member_count : 1;
|
||||
const enableEmojiPicker = config.EnableEmojiPicker === 'true';
|
||||
@@ -117,6 +118,7 @@ function makeMapStateToProps() {
|
||||
showSendTutorialTip,
|
||||
messageInHistoryItem: getMessageInHistoryItem(state),
|
||||
draft,
|
||||
isRemoteDraft,
|
||||
latestReplyablePostId,
|
||||
locale: getCurrentLocale(state),
|
||||
currentUsersLatestPost: getCurrentUsersLatestPost(state, ''),
|
||||
@@ -181,12 +183,7 @@ function setDraft(key: string, value: PostDraft, draftChannelId: string, save =
|
||||
const channelId = draftChannelId || getCurrentChannelId(getState());
|
||||
let updatedValue = null;
|
||||
if (value) {
|
||||
updatedValue = {...value};
|
||||
updatedValue = {
|
||||
...value,
|
||||
channelId,
|
||||
remote: false,
|
||||
};
|
||||
updatedValue = {...value, channelId};
|
||||
}
|
||||
if (updatedValue) {
|
||||
return dispatch(updateDraft(key, updatedValue, '', save));
|
||||
|
||||
@@ -39,6 +39,7 @@ exports[`components/drafts/drafts_row should match snapshot for channel draft 1`
|
||||
"type": "channel",
|
||||
}
|
||||
}
|
||||
isRemote={false}
|
||||
status={Object {}}
|
||||
user={Object {}}
|
||||
/>
|
||||
@@ -84,6 +85,7 @@ exports[`components/drafts/drafts_row should match snapshot for thread draft 1`]
|
||||
"type": "thread",
|
||||
}
|
||||
}
|
||||
isRemote={false}
|
||||
status={Object {}}
|
||||
user={Object {}}
|
||||
/>
|
||||
|
||||
@@ -34,6 +34,7 @@ exports[`components/drafts/drafts should match snapshot 1`] = `
|
||||
>
|
||||
<Memo(Drafts)
|
||||
displayName="display_name"
|
||||
draftRemotes={Object {}}
|
||||
drafts={Array []}
|
||||
localDraftsAreEnabled={true}
|
||||
status={Object {}}
|
||||
@@ -76,6 +77,7 @@ exports[`components/drafts/drafts should match snapshot for local drafts disable
|
||||
>
|
||||
<Memo(Drafts)
|
||||
displayName="display_name"
|
||||
draftRemotes={Object {}}
|
||||
drafts={Array []}
|
||||
localDraftsAreEnabled={false}
|
||||
status={Object {}}
|
||||
|
||||
@@ -42,6 +42,7 @@ exports[`components/drafts/drafts_row should match snapshot for channel draft 1`
|
||||
displayName=""
|
||||
draftId=""
|
||||
id={Object {}}
|
||||
isRemote={false}
|
||||
status={Object {}}
|
||||
type="channel"
|
||||
user={Object {}}
|
||||
@@ -88,6 +89,7 @@ exports[`components/drafts/drafts_row should match snapshot for undefined channe
|
||||
displayName=""
|
||||
draftId=""
|
||||
id={Object {}}
|
||||
isRemote={false}
|
||||
status={Object {}}
|
||||
type="channel"
|
||||
user={Object {}}
|
||||
|
||||
@@ -26,6 +26,7 @@ describe('components/drafts/drafts_row', () => {
|
||||
type: 'channel' as 'channel' | 'thread',
|
||||
user: {} as UserProfile,
|
||||
value: {} as PostDraft,
|
||||
isRemote: false,
|
||||
};
|
||||
|
||||
it('should match snapshot for channel draft', () => {
|
||||
|
||||
@@ -29,6 +29,7 @@ type Props = {
|
||||
type: 'channel' | 'thread';
|
||||
user: UserProfile;
|
||||
value: PostDraft;
|
||||
isRemote: boolean;
|
||||
}
|
||||
|
||||
function ChannelDraft({
|
||||
@@ -40,6 +41,7 @@ function ChannelDraft({
|
||||
type,
|
||||
user,
|
||||
value,
|
||||
isRemote,
|
||||
}: Props) {
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
@@ -101,7 +103,7 @@ function ChannelDraft({
|
||||
/>
|
||||
)}
|
||||
timestamp={value.updateAt}
|
||||
remote={value.remote || false}
|
||||
remote={isRemote || false}
|
||||
/>
|
||||
<PanelBody
|
||||
channelId={channel.id}
|
||||
|
||||
@@ -21,6 +21,7 @@ describe('components/drafts/drafts_row', () => {
|
||||
user: {} as UserProfile,
|
||||
status: {} as UserStatus['status'],
|
||||
displayName: 'test',
|
||||
isRemote: false,
|
||||
};
|
||||
|
||||
it('should match snapshot for channel draft', () => {
|
||||
|
||||
@@ -14,9 +14,10 @@ type Props = {
|
||||
status: UserStatus['status'];
|
||||
displayName: string;
|
||||
draft: Draft;
|
||||
isRemote: boolean;
|
||||
}
|
||||
|
||||
function DraftRow({draft, user, status, displayName}: Props) {
|
||||
function DraftRow({draft, user, status, displayName, isRemote}: Props) {
|
||||
switch (draft.type) {
|
||||
case 'channel':
|
||||
return (
|
||||
@@ -26,6 +27,7 @@ function DraftRow({draft, user, status, displayName}: Props) {
|
||||
user={user}
|
||||
status={status}
|
||||
displayName={displayName}
|
||||
isRemote={isRemote}
|
||||
/>
|
||||
);
|
||||
case 'thread':
|
||||
@@ -37,6 +39,7 @@ function DraftRow({draft, user, status, displayName}: Props) {
|
||||
user={user}
|
||||
status={status}
|
||||
displayName={displayName}
|
||||
isRemote={isRemote}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
|
||||
@@ -20,6 +20,7 @@ describe('components/drafts/drafts', () => {
|
||||
displayName: 'display_name',
|
||||
status: {} as UserStatus['status'],
|
||||
localDraftsAreEnabled: true,
|
||||
draftRemotes: {},
|
||||
};
|
||||
|
||||
it('should match snapshot', () => {
|
||||
|
||||
@@ -27,11 +27,13 @@ type Props = {
|
||||
displayName: string;
|
||||
status: UserStatus['status'];
|
||||
localDraftsAreEnabled: boolean;
|
||||
draftRemotes: Record<string, boolean>;
|
||||
}
|
||||
|
||||
function Drafts({
|
||||
displayName,
|
||||
drafts,
|
||||
draftRemotes,
|
||||
status,
|
||||
user,
|
||||
localDraftsAreEnabled,
|
||||
@@ -75,6 +77,7 @@ function Drafts({
|
||||
key={d.key}
|
||||
displayName={displayName}
|
||||
draft={d}
|
||||
isRemote={draftRemotes[d.key]}
|
||||
user={user}
|
||||
status={status}
|
||||
/>
|
||||
|
||||
@@ -22,6 +22,7 @@ function makeMapStateToProps() {
|
||||
return {
|
||||
displayName: displayUsername(user, getTeammateNameDisplaySetting(state)),
|
||||
drafts: getDrafts(state),
|
||||
draftRemotes: state.views.drafts.remotes,
|
||||
status,
|
||||
user,
|
||||
localDraftsAreEnabled: localDraftsAreEnabled(state),
|
||||
|
||||
@@ -42,6 +42,7 @@ exports[`components/drafts/drafts_row should match snapshot for channel draft 1`
|
||||
displayName=""
|
||||
draftId=""
|
||||
id={Object {}}
|
||||
isRemote={false}
|
||||
rootId=""
|
||||
status={Object {}}
|
||||
thread={
|
||||
@@ -98,6 +99,7 @@ exports[`components/drafts/drafts_row should match snapshot for undefined thread
|
||||
displayName=""
|
||||
draftId=""
|
||||
id={Object {}}
|
||||
isRemote={false}
|
||||
rootId=""
|
||||
status={Object {}}
|
||||
thread={null}
|
||||
|
||||
@@ -31,6 +31,7 @@ describe('components/drafts/drafts_row', () => {
|
||||
type: 'thread' as 'channel' | 'thread',
|
||||
user: {} as UserProfile,
|
||||
value: {} as PostDraft,
|
||||
isRemote: false,
|
||||
};
|
||||
|
||||
it('should match snapshot for channel draft', () => {
|
||||
|
||||
@@ -33,6 +33,7 @@ type Props = {
|
||||
type: 'channel' | 'thread';
|
||||
user: UserProfile;
|
||||
value: PostDraft;
|
||||
isRemote: boolean;
|
||||
}
|
||||
|
||||
function ThreadDraft({
|
||||
@@ -45,6 +46,7 @@ function ThreadDraft({
|
||||
type,
|
||||
user,
|
||||
value,
|
||||
isRemote,
|
||||
}: Props) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
@@ -107,7 +109,7 @@ function ThreadDraft({
|
||||
/>
|
||||
)}
|
||||
timestamp={value.updateAt}
|
||||
remote={value.remote || false}
|
||||
remote={isRemote || false}
|
||||
/>
|
||||
<PanelBody
|
||||
channelId={channel.id}
|
||||
|
||||
@@ -144,7 +144,6 @@ function migrateDrafts(state: any) {
|
||||
createAt: timestamp.getTime(),
|
||||
updateAt: timestamp.getTime(),
|
||||
show: true,
|
||||
remote: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
25
webapp/channels/src/reducers/views/drafts.ts
Normal file
25
webapp/channels/src/reducers/views/drafts.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {combineReducers} from 'redux';
|
||||
import {GenericAction} from 'mattermost-redux/types/actions';
|
||||
import {ActionTypes} from 'utils/constants';
|
||||
|
||||
function remotes(state: Record<string, boolean> = {}, action: GenericAction) {
|
||||
switch (action.type) {
|
||||
case ActionTypes.SET_DRAFT_SOURCE:
|
||||
return {
|
||||
...state,
|
||||
[action.data.key]: action.data.isRemote,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default combineReducers({
|
||||
|
||||
// object that stores global draft keys indicating whether the draft came from a WebSocket event.
|
||||
remotes,
|
||||
|
||||
});
|
||||
@@ -28,6 +28,7 @@ import addChannelDropdown from './add_channel_dropdown';
|
||||
import addChannelCtaDropdown from './add_channel_cta_dropdown';
|
||||
import threads from './threads';
|
||||
import onboardingTasks from './onboarding_tasks';
|
||||
import drafts from './drafts';
|
||||
|
||||
export default combineReducers({
|
||||
admin,
|
||||
@@ -55,4 +56,5 @@ export default combineReducers({
|
||||
onboardingTasks,
|
||||
threads,
|
||||
productMenu,
|
||||
drafts,
|
||||
});
|
||||
|
||||
@@ -20,7 +20,6 @@ export type PostDraft = {
|
||||
createAt: number;
|
||||
updateAt: number;
|
||||
show?: boolean;
|
||||
remote?: boolean;
|
||||
metadata?: {
|
||||
priority?: {
|
||||
priority: PostPriority|'';
|
||||
|
||||
@@ -62,6 +62,12 @@ export type ViewsState = {
|
||||
toastStatus: boolean;
|
||||
};
|
||||
|
||||
drafts: {
|
||||
remotes: {
|
||||
[storageKey: string]: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
rhs: RhsViewState;
|
||||
|
||||
rhsSuppressed: boolean;
|
||||
|
||||
@@ -337,6 +337,8 @@ export const ActionTypes = keyMirror({
|
||||
RECEIVED_PLUGIN_INSIGHT: null,
|
||||
SET_EDIT_CHANNEL_MEMBERS: null,
|
||||
NEEDS_LOGGED_IN_LIMIT_REACHED_CHECK: null,
|
||||
|
||||
SET_DRAFT_SOURCE: null,
|
||||
});
|
||||
|
||||
export const PostRequestTypes = keyMirror({
|
||||
|
||||
Reference in New Issue
Block a user