* Fix autofocus on load

* Address feedback

* Fix styles lint

* Revert unintended change

* fix tests

* Update text
Этот коммит содержится в:
Daniel Espino García
2024-09-05 14:27:29 +02:00
коммит произвёл GitHub
родитель 7232feecf7
Коммит 92793928bc
9 изменённых файлов: 109 добавлений и 1 удалений

Просмотреть файл

@@ -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 {

Просмотреть файл

@@ -87,6 +87,8 @@ const useTextboxFocus = (
if (isRHS && shouldFocusRHS) {
focusTextbox();
dispatch(focusedRHS());
} else if (!isRHS && !shouldFocusRHS) {
focusTextbox();
}
}, []);

Просмотреть файл

@@ -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}
/>

Просмотреть файл

@@ -26,6 +26,7 @@ describe('components/channel_view', () => {
isFirstAdmin: false,
enableWebSocketEventScope: false,
isChannelBookmarksEnabled: false,
missingChannelRole: false,
};
it('Should match snapshot with base props', () => {

Просмотреть файл

@@ -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<Props, State> {
@@ -77,6 +80,7 @@ export default class ChannelView extends React.PureComponent<Props, State> {
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<Props, State> {
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<Props, State> {
</div>
</div>
);
} else if (this.props.missingChannelRole || this.state.waitForLoader) {
createPost = <InputLoading updateWaitForLoader={this.onUpdateInputShowLoader}/>;
} else {
createPost = (
<div

Просмотреть файл

@@ -5,8 +5,11 @@ import {connect} from 'react-redux';
import type {ConnectedProps} from 'react-redux';
import {withRouter} from 'react-router-dom';
import {getCurrentChannel, getDirectTeammate} from 'mattermost-redux/selectors/entities/channels';
import type {Channel} from '@mattermost/types/channels';
import {getCurrentChannel, getDirectTeammate, getMyChannelMembership} from 'mattermost-redux/selectors/entities/channels';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
import {getRoles} from 'mattermost-redux/selectors/entities/roles_helpers';
import {getCurrentRelativeTeamUrl} from 'mattermost-redux/selectors/entities/teams';
import {isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
@@ -24,6 +27,11 @@ function isDeactivatedChannel(state: GlobalState, channelId: string) {
return Boolean(teammate && teammate.delete_at);
}
function isMissingChannelRoles(state: GlobalState, channel?: Channel) {
const channelRoles = channel ? getMyChannelMembership(state, channel.id)?.roles || '' : '';
return !channelRoles.split(' ').some((v) => 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,
};
}

Просмотреть файл

@@ -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 (
<div
className='AdvancedTextEditor__skeleton'
>
{showMessage && (
<>
<FormattedMessage
id='center_panel.input.cannot_load_component'
defaultMessage='Something went wrong while loading the component. Please wait a moment, or try reloading the app.'
/>
<button
className='btn btn-tertiary channel-archived__close-btn'
onClick={onClickRefresh}
>
<FormattedMessage
id='center_panel.reloadPage'
defaultMessage='Reload'
/>
</button>
</>
)}
</div>
);
};
export default InputLoading;

Просмотреть файл

@@ -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.",

Просмотреть файл

@@ -79,6 +79,7 @@ describe('identifyElementRegion', () => {
[channel.id]: TestHelper.getChannelMembershipMock({
channel_id: channel.id,
user_id: user.id,
roles: 'system_admin',
}),
},
},