Fix edit post scroll (#8845)

* Fix edit post scroll

* Minor improvement on readability
This commit is contained in:
Daniel Espino García 2025-05-13 17:09:25 +02:00 committed by GitHub
parent af0a7525c8
commit a5fbd66320
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 37 deletions

View file

@ -8,6 +8,7 @@ import {Alert, Keyboard, type LayoutChangeEvent, Platform, SafeAreaView, View, S
import {deletePost, editPost} from '@actions/remote/post';
import Autocomplete from '@components/autocomplete';
import Loading from '@components/loading';
import {ExtraKeyboardProvider} from '@context/extra_keyboard';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
@ -40,6 +41,9 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
},
inputContainer: {
flex: 1,
},
});
const RIGHT_BUTTON = buildNavigationButton('edit-post', 'edit_post.save.button');
@ -69,6 +73,8 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
const intl = useIntl();
const serverUrl = useServerUrl();
const shouldDeleteOnSave = !postMessage && canDelete && !hasFilesAttached;
useEffect(() => {
toggleSaveButton(false);
}, []);
@ -93,11 +99,11 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
const onClose = useCallback(() => {
Keyboard.dismiss();
dismissModal({componentId});
}, []);
}, [componentId]);
const onTextSelectionChange = useCallback((curPos: number = cursorPosition) => {
setCursorPosition(curPos);
}, [cursorPosition, postMessage]);
}, [cursorPosition]);
const toggleSaveButton = useCallback((enabled = true) => {
setButtons(componentId, {
@ -128,7 +134,7 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
setPostMessage(message);
propagateValue(message);
onChangeTextCommon(message);
}, [onChangeTextCommon]);
}, [onChangeTextCommon, propagateValue]);
const onInputChangeText = useCallback((message: string) => {
if (!shouldProcessEvent(message)) {
@ -136,7 +142,7 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
}
setPostMessage(message);
onChangeTextCommon(message);
}, [onChangeTextCommon]);
}, [onChangeTextCommon, shouldProcessEvent]);
const handleUIUpdates = useCallback((res: {error?: unknown}) => {
if (res.error) {
@ -148,7 +154,7 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
setIsUpdating(false);
onClose();
}
}, []);
}, [intl, onClose]);
const handleDeletePost = useCallback(async () => {
Alert.alert(
@ -174,21 +180,21 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
},
}],
);
}, [serverUrl, editingMessage]);
}, [intl, toggleSaveButton, editingMessage, serverUrl, post, handleUIUpdates]);
const onSavePostMessage = useCallback(async () => {
setIsUpdating(true);
setErrorLine(undefined);
setErrorExtra(undefined);
toggleSaveButton(false);
if (!postMessage && canDelete && !hasFilesAttached) {
if (shouldDeleteOnSave) {
handleDeletePost();
return;
}
const res = await editPost(serverUrl, post.id, postMessage);
handleUIUpdates(res);
}, [toggleSaveButton, serverUrl, post.id, postMessage, onClose]);
}, [toggleSaveButton, shouldDeleteOnSave, serverUrl, post.id, postMessage, handleUIUpdates, handleDeletePost]);
const onLayout = useCallback((e: LayoutChangeEvent) => {
setContainerHeight(e.nativeEvent.layout.height);
@ -202,8 +208,6 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
const autocompletePosition = overlap + AUTOCOMPLETE_SEPARATION;
const autocompleteAvailableSpace = containerHeight - autocompletePosition;
const inputHeight = containerHeight - overlap;
const [animatedAutocompletePosition, animatedAutocompleteAvailableSpace] = useAutocompleteDefaultAnimatedValues(autocompletePosition, autocompleteAvailableSpace);
if (isUpdating) {
@ -225,25 +229,28 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
onLayout={onLayout}
nativeID={SecurityManager.getShieldScreenId(componentId)}
>
<View
style={styles.body}
ref={mainView}
>
{Boolean((errorLine || errorExtra)) &&
<PostError
errorExtra={errorExtra}
errorLine={errorLine}
/>
}
<EditPostInput
inputHeight={inputHeight}
hasError={Boolean(errorLine)}
message={postMessage}
onChangeText={onInputChangeText}
onTextSelectionChange={onTextSelectionChange}
ref={postInputRef}
/>
</View>
<ExtraKeyboardProvider>
<View
style={styles.body}
ref={mainView}
>
{Boolean((errorLine || errorExtra)) &&
<PostError
errorExtra={errorExtra}
errorLine={errorLine}
/>
}
<View style={styles.inputContainer}>
<EditPostInput
hasError={Boolean(errorLine)}
message={postMessage}
onChangeText={onInputChangeText}
onTextSelectionChange={onTextSelectionChange}
ref={postInputRef}
/>
</View>
</View>
</ExtraKeyboardProvider>
</SafeAreaView>
<Autocomplete
channelId={post.channelId}

View file

@ -5,8 +5,9 @@ import {useManagedConfig} from '@mattermost/react-native-emm';
import PasteInput, {type PasteInputRef} from '@mattermost/react-native-paste-input';
import React, {forwardRef, useCallback, useImperativeHandle, useMemo, useRef} from 'react';
import {useIntl} from 'react-intl';
import {type NativeSyntheticEvent, type TextInputSelectionChangeEventData, View} from 'react-native';
import {type NativeSyntheticEvent, Platform, type TextInputSelectionChangeEventData, View} from 'react-native';
import {ExtraKeyboard, useExtraKeyboardContext} from '@context/extra_keyboard';
import {useTheme} from '@context/theme';
import {emptyFunction} from '@utils/general';
import {changeOpacity, getKeyboardAppearanceFromTheme, makeStyleSheetFromTheme} from '@utils/theme';
@ -17,11 +18,13 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => ({
color: theme.centerChannelColor,
padding: 15,
textAlignVertical: 'top',
flex: 1,
...typography('Body', 200),
},
inputContainer: {
backgroundColor: theme.centerChannelBg,
marginTop: 2,
flex: 1,
},
}));
@ -30,7 +33,6 @@ export type EditPostInputRef = {
}
type PostInputProps = {
inputHeight: number;
message: string;
hasError: boolean;
onTextSelectionChange: (curPos: number) => void;
@ -38,7 +40,6 @@ type PostInputProps = {
}
const EditPostInput = forwardRef<EditPostInputRef, PostInputProps>(({
inputHeight,
message,
onChangeText,
onTextSelectionChange,
@ -52,9 +53,19 @@ const EditPostInput = forwardRef<EditPostInputRef, PostInputProps>(({
const inputRef = useRef<PasteInputRef>();
const keyboardContext = useExtraKeyboardContext();
const onFocus = useCallback(() => {
keyboardContext?.registerTextInputFocus();
}, [keyboardContext]);
const onBlur = useCallback(() => {
keyboardContext?.registerTextInputBlur();
}, [keyboardContext]);
const inputStyle = useMemo(() => {
return [styles.input, {height: inputHeight}];
}, [inputHeight, styles]);
return [styles.input];
}, [styles]);
const onSelectionChange = useCallback((event: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => {
const curPos = event.nativeEvent.selection.end;
@ -64,12 +75,11 @@ const EditPostInput = forwardRef<EditPostInputRef, PostInputProps>(({
const containerStyle = useMemo(() => [
styles.inputContainer,
hasError && {marginTop: 0},
{height: inputHeight},
], [styles, inputHeight]);
], [styles, hasError]);
useImperativeHandle(ref, () => ({
focus: () => inputRef.current?.focus(),
}), [inputRef.current]);
}), []);
return (
<View style={containerStyle}>
@ -91,7 +101,10 @@ const EditPostInput = forwardRef<EditPostInputRef, PostInputProps>(({
testID='edit_post.message.input'
underlineColorAndroid='transparent'
value={message}
onFocus={onFocus}
onBlur={onBlur}
/>
{Platform.select({ios: <ExtraKeyboard/>})}
</View>
);
});