From 92793928bc9efa0915035e2f84dd78f38ac25f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Thu, 5 Sep 2024 14:27:29 +0200 Subject: [PATCH] Fix autofocus on load (#28090) * Fix autofocus on load * Address feedback * Fix styles lint * Revert unintended change * fix tests * Update text --- .../advanced_text_editor.scss | 15 +++++ .../use_textbox_focus.tsx | 2 + .../__snapshots__/channel_view.test.tsx.snap | 3 + .../channel_view/channel_view.test.tsx | 1 + .../components/channel_view/channel_view.tsx | 10 +++ .../src/components/channel_view/index.ts | 13 +++- .../components/channel_view/input_loading.tsx | 63 +++++++++++++++++++ webapp/channels/src/i18n/en.json | 2 + .../element_identification.test.tsx | 1 + 9 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 webapp/channels/src/components/channel_view/input_loading.tsx diff --git a/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.scss b/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.scss index 67c4a88a43..d282680a9d 100644 --- a/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.scss +++ b/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.scss @@ -1,5 +1,20 @@ @import 'utils/variables'; +.AdvancedTextEditor__skeleton { + display: flex; + height: 122px; + align-items: center; + justify-content: center; + padding-left: 10px; + border: 2px solid rgba(var(--center-channel-color-rgb), 0.16); + border-radius: 4px; + margin: 0 24px 24px; + color: rgba(var(--center-channel-color-rgb), 0.75); + .btn { + margin: 10px + } +} + .AdvancedTextEditor { &__ctr { form { diff --git a/webapp/channels/src/components/advanced_text_editor/use_textbox_focus.tsx b/webapp/channels/src/components/advanced_text_editor/use_textbox_focus.tsx index 7ea038f01d..01ef01da4d 100644 --- a/webapp/channels/src/components/advanced_text_editor/use_textbox_focus.tsx +++ b/webapp/channels/src/components/advanced_text_editor/use_textbox_focus.tsx @@ -87,6 +87,8 @@ const useTextboxFocus = ( if (isRHS && shouldFocusRHS) { focusTextbox(); dispatch(focusedRHS()); + } else if (!isRHS && !shouldFocusRHS) { + focusTextbox(); } }, []); diff --git a/webapp/channels/src/components/channel_view/__snapshots__/channel_view.test.tsx.snap b/webapp/channels/src/components/channel_view/__snapshots__/channel_view.test.tsx.snap index 949b3f6838..06777bb416 100644 --- a/webapp/channels/src/components/channel_view/__snapshots__/channel_view.test.tsx.snap +++ b/webapp/channels/src/components/channel_view/__snapshots__/channel_view.test.tsx.snap @@ -26,6 +26,7 @@ exports[`components/channel_view Should match snapshot if channel is archived 1` "url": "/team/channel/channelId", } } + missingChannelRole={false} teamUrl="/team" viewArchivedChannels={false} /> @@ -84,6 +85,7 @@ exports[`components/channel_view Should match snapshot if channel is deactivated "url": "/team/channel/channelId", } } + missingChannelRole={false} teamUrl="/team" viewArchivedChannels={false} /> @@ -141,6 +143,7 @@ exports[`components/channel_view Should match snapshot with base props 1`] = ` "url": "/team/channel/channelId", } } + missingChannelRole={false} teamUrl="/team" viewArchivedChannels={false} /> diff --git a/webapp/channels/src/components/channel_view/channel_view.test.tsx b/webapp/channels/src/components/channel_view/channel_view.test.tsx index 337ce4948e..29484c0686 100644 --- a/webapp/channels/src/components/channel_view/channel_view.test.tsx +++ b/webapp/channels/src/components/channel_view/channel_view.test.tsx @@ -26,6 +26,7 @@ describe('components/channel_view', () => { isFirstAdmin: false, enableWebSocketEventScope: false, isChannelBookmarksEnabled: false, + missingChannelRole: false, }; it('Should match snapshot with base props', () => { diff --git a/webapp/channels/src/components/channel_view/channel_view.tsx b/webapp/channels/src/components/channel_view/channel_view.tsx index 176d2f35ff..c878609a81 100644 --- a/webapp/channels/src/components/channel_view/channel_view.tsx +++ b/webapp/channels/src/components/channel_view/channel_view.tsx @@ -12,6 +12,8 @@ import PostView from 'components/post_view'; import WebSocketClient from 'client/web_websocket_client'; +import InputLoading from './input_loading'; + import type {PropsFromRedux} from './index'; const ChannelHeader = makeAsyncComponent('ChannelHeader', lazy(() => import('components/channel_header'))); @@ -28,6 +30,7 @@ type State = { url: string; focusedPostId?: string; deferredPostView: any; + waitForLoader: boolean; }; export default class ChannelView extends React.PureComponent { @@ -77,6 +80,7 @@ export default class ChannelView extends React.PureComponent { channelId: props.channelId, focusedPostId: props.match.params.postid, deferredPostView: ChannelView.createDeferredPostView(), + waitForLoader: false, }; this.channelViewRef = React.createRef(); @@ -86,6 +90,10 @@ export default class ChannelView extends React.PureComponent { this.props.goToLastViewedChannel(); }; + onUpdateInputShowLoader = (v: boolean) => { + this.setState({waitForLoader: v}); + }; + componentDidUpdate(prevProps: Props) { // TODO: debounce if (prevProps.channelId !== this.props.channelId && this.props.enableWebSocketEventScope) { @@ -151,6 +159,8 @@ export default class ChannelView extends React.PureComponent { ); + } else if (this.props.missingChannelRole || this.state.waitForLoader) { + createPost = ; } else { createPost = (
Boolean(getRoles(state)[v])); +} + function mapStateToProps(state: GlobalState) { const channel = getCurrentChannel(state); @@ -33,6 +41,8 @@ function mapStateToProps(state: GlobalState) { const enableOnboardingFlow = config.EnableOnboardingFlow === 'true'; const enableWebSocketEventScope = config.FeatureFlagWebSocketEventScope === 'true'; + const missingChannelRole = isMissingChannelRoles(state, channel); + return { channelId: channel ? channel.id : '', deactivatedChannel: channel ? isDeactivatedChannel(state, channel.id) : false, @@ -44,6 +54,7 @@ function mapStateToProps(state: GlobalState) { isFirstAdmin: isFirstAdmin(state), enableWebSocketEventScope, isChannelBookmarksEnabled: getIsChannelBookmarksEnabled(state), + missingChannelRole, }; } diff --git a/webapp/channels/src/components/channel_view/input_loading.tsx b/webapp/channels/src/components/channel_view/input_loading.tsx new file mode 100644 index 0000000000..5a8bffda50 --- /dev/null +++ b/webapp/channels/src/components/channel_view/input_loading.tsx @@ -0,0 +1,63 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useEffect, useState} from 'react'; +import {FormattedMessage} from 'react-intl'; + +const onClickRefresh = () => { + location.reload(); +}; + +const TIME_TO_SHOW = 5000; +const TIME_TO_DISMISS = 2000; + +type Props = { + updateWaitForLoader: (v: boolean) => void; +} + +const InputLoading = ({ + updateWaitForLoader, +}: Props) => { + const [showMessage, setShowMessage] = useState(false); + + useEffect(() => { + let timeout = setTimeout(() => { + setShowMessage(true); + updateWaitForLoader(true); + timeout = setTimeout(() => { + updateWaitForLoader(false); + }, TIME_TO_DISMISS); + }, TIME_TO_SHOW); + + return () => { + clearTimeout(timeout); + updateWaitForLoader(false); + }; + }, []); + + return ( +
+ {showMessage && ( + <> + + + + )} +
+ ); +}; + +export default InputLoading; diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 6c07079a00..40b87d549c 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -3037,6 +3037,8 @@ "center_panel.archived.closeChannel": "Close Channel", "center_panel.direct.closeDirectMessage": "Close Direct Message", "center_panel.direct.closeGroupMessage": "Close Group Message", + "center_panel.input.cannot_load_component": "Something went wrong while loading the component. Please wait a moment, or try reloading the app.", + "center_panel.reloadPage": "Reload", "change_url.endWithLetter": "URLs must end with a lowercase letter or number.", "change_url.helpText": "You can use lowercase letters, numbers, dashes, and underscores.", "change_url.invalidDirectMessage": "User IDs are not allowed in channel URLs.", diff --git a/webapp/channels/src/utils/performance_telemetry/element_identification.test.tsx b/webapp/channels/src/utils/performance_telemetry/element_identification.test.tsx index 542dc973df..5bd4ce7f3a 100644 --- a/webapp/channels/src/utils/performance_telemetry/element_identification.test.tsx +++ b/webapp/channels/src/utils/performance_telemetry/element_identification.test.tsx @@ -79,6 +79,7 @@ describe('identifyElementRegion', () => { [channel.id]: TestHelper.getChannelMembershipMock({ channel_id: channel.id, user_id: user.id, + roles: 'system_admin', }), }, },