Skip to content

Commit

Permalink
[feat] Add edit comment
Browse files Browse the repository at this point in the history
  • Loading branch information
gkasdorf committed Oct 25, 2023
1 parent c048532 commit ed78fb2
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Toast added to both reply and post screen

### Added

- Added edit comments

## [Version 1.0 (46)] - 2023-10-23T11:20:39Z

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const useCommentContextMenu = (
};

const edit = (): void => {
navigation.push('Reply', { commentId: itemId, edit: true });
navigation.push('EditReply', { commentId: itemId });
};

const delet = (): void => {
Expand Down
6 changes: 6 additions & 0 deletions src/components/Navigation/MainScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ReplyScreen from '@components/Reply/screens/ReplyScreen';
import ProfileScreen from '@components/Profile/screens/ProfileScreen';
import NewPostScreen from '@components/NewPost/screens/NewPostScreen';
import WebViewScreen from '@components/WebViewer/WebViewScreen';
import EditReplyScreen from '@components/Reply/screens/EditReplyScreen';

export default function MainScreens(
stack: TypedNavigator<
Expand Down Expand Up @@ -73,6 +74,11 @@ export default function MainScreens(
component={NewPostScreen}
options={{ gestureEnabled: false, headerTitle: 'New Post' }}
/>
<stack.Screen
name="EditReply"
component={EditReplyScreen}
options={{ gestureEnabled: false, headerTitle: 'Edit Comment' }}
/>
<stack.Screen
name="WebView"
component={WebViewScreen}
Expand Down
100 changes: 100 additions & 0 deletions src/components/Reply/hooks/useEditReplyScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, {
SetStateAction,
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import { useNavigation, useRoute } from '@react-navigation/core';
import { ITextSelection, useLoadData } from '@src/hooks';
import instance from '@src/Instance';
import { updateCommentContent, useCommentContent } from '@src/state';
import {
NativeSyntheticEvent,
TextInput,
TextInputSelectionChangeEventData,
} from 'react-native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import HeaderButton from '@components/Common/Button/HeaderButton';

interface UseEditReplyScreen {
text: string;
setText: React.Dispatch<SetStateAction<string>>;
selection: ITextSelection;
onSelectionChange: (
e: NativeSyntheticEvent<TextInputSelectionChangeEventData>,
) => void;
isLoading: boolean;
inputRef: React.MutableRefObject<TextInput | undefined>;
}

export const useEditReplyScreen = (): UseEditReplyScreen => {
const navigation = useNavigation<NativeStackNavigationProp<any>>();
const { commentId } = useRoute<any>().params;

const commentContent = useCommentContent(commentId);

const [text, setText] = useState(commentContent ?? '');
const [selection, setSelection] = useState<ITextSelection>({
start: 0,
end: 0,
});

const { isLoading, refresh: submit } = useLoadData();

const inputRef = useRef<TextInput>();

const onSubmitPress = (): void => {
submit(async () => {
await instance.editComment(commentId, text);

updateCommentContent(commentId, text);

navigation.pop();
});
};

const onSelectionChange = useCallback(
(e: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => {
setSelection({
start: e.nativeEvent.selection.start,
end: e.nativeEvent.selection.end,
});
},
[setSelection],
);

useEffect(() => {
navigation.setOptions({
headerLeft: () => (
<HeaderButton
title="Back"
onPress={() => {
navigation.pop();
}}
/>
),
});

inputRef.current?.setNativeProps({
text,
});
}, []);

useEffect(() => {
navigation.setOptions({
headerRight: () => (
<HeaderButton title="Submit" onPress={onSubmitPress} />
),
});
}, [text]);

return {
text,
setText,
onSelectionChange,
selection,
isLoading,
inputRef,
};
};
52 changes: 52 additions & 0 deletions src/components/Reply/screens/EditReplyScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useCallback, useRef } from 'react';
import { INavigationProps } from '@src/types';
import { ScrollView, YStack } from 'tamagui';
import AppToast from '@components/Common/Toast/AppToast';
import LoadingOverlay from '@components/Common/Loading/LoadingOverlay';
import TextInput from '@components/Common/Form/TextInput';
import KeyboardAccessoryView from '@components/Common/Keyboard/KeyboardAccesoryView';
import { useEditReplyScreen } from '@components/Reply/hooks/useEditReplyScreen';
import { ScrollView as RNScrollView } from 'react-native';

export default function EditReplyScreen({
navigation,
route,
}: INavigationProps): React.JSX.Element {
const editReplyScreen = useEditReplyScreen();

const viewRef = useRef<RNScrollView>();

const onLayout = useCallback(() => {
viewRef.current?.scrollToEnd({ animated: false });
}, []);

return (
<>
{/* @ts-expect-error - this is valid */}
<ScrollView automaticallyAdjustKeyboardInsets={true} ref={viewRef}>
<AppToast translate={100} />
<LoadingOverlay visible={editReplyScreen.isLoading} />
<YStack space="$2" mb="$2">
<TextInput
inputAccessoryViewID="accessory"
onSelectionChange={editReplyScreen.onSelectionChange}
onChangeText={editReplyScreen.setText}
fontSize={16}
ref={editReplyScreen.inputRef}
autoFocus={true}
multiline={true}
scrollEnabled={false}
onLayout={onLayout}
placeholder="What do you want to say?"
/>
</YStack>
</ScrollView>
<KeyboardAccessoryView
text={editReplyScreen.text}
setText={editReplyScreen.setText}
selection={editReplyScreen.selection}
inputRef={editReplyScreen.inputRef}
/>
</>
);
}
5 changes: 5 additions & 0 deletions src/helpers/comments/getParentId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const getParentId = (path: string): number => {
const pathArr = path.split('.');

return Number(pathArr[pathArr.length - 2]);
};
1 change: 1 addition & 0 deletions src/helpers/comments/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './buildCommentChains';
export * from './createCommentReplyComponents';
export * from './getParentId';
13 changes: 13 additions & 0 deletions src/state/comment/actions/updateComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,16 @@ export const updateComment = (comment: CommentView): void => {
current.view.comment.deleted = comment.comment.deleted;
});
};

export const updateCommentContent = (
commentId: number,
content: string,
): void => {
useCommentStore.setState((state) => {
const current = state.comments.get(commentId);

if (current == null) return;

current.view.comment.content = content;
});
};

0 comments on commit ed78fb2

Please sign in to comment.