Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GAL-4417] Mobile mention #1992

Merged
merged 39 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f45f16e
update schema
jakzaizzat Oct 4, 2023
b3ccd79
search result support on select
jakzaizzat Oct 4, 2023
6f2551a
Add context
jakzaizzat Oct 4, 2023
412b3cf
user/community support on select
jakzaizzat Oct 4, 2023
b27291b
Increase fallback comment
jakzaizzat Oct 4, 2023
76c4170
Added mention link
jakzaizzat Oct 5, 2023
67fdb5c
render comment with mention on bottom sheet
jakzaizzat Oct 5, 2023
e83ab63
Removed parsedMessage
jakzaizzat Oct 5, 2023
1f1fa5b
Add mention to post
jakzaizzat Oct 5, 2023
e572efa
Remove context
jakzaizzat Oct 5, 2023
ec3a7bd
add community
jakzaizzat Oct 5, 2023
d01a2fd
rename
jakzaizzat Oct 5, 2023
399192f
Search result support only preview
jakzaizzat Oct 5, 2023
a1afc04
Exclude galleries from mention search
jakzaizzat Oct 5, 2023
5b7e46f
fix optimistic response
jakzaizzat Oct 6, 2023
2039a54
Add mention notification
jakzaizzat Oct 6, 2023
f4055ab
clean up notification
jakzaizzat Oct 6, 2023
66fc066
Merge branch 'main' of https://github.com/gallery-so/gallery into jak…
jakzaizzat Oct 6, 2023
356eb3d
Add mention support to processedtext
jakzaizzat Oct 9, 2023
9f5d650
add markdown link support to processed text
jakzaizzat Oct 9, 2023
c1a2fe8
Support markdown link
jakzaizzat Oct 9, 2023
5af2be6
Check mention state if deleted
jakzaizzat Oct 9, 2023
38e9bad
Auto open bottom sheet on comment notification
jakzaizzat Oct 9, 2023
cc79486
Merge branch 'main' of https://github.com/gallery-so/gallery into jak…
jakzaizzat Oct 9, 2023
ea889f3
add search result fallback
jakzaizzat Oct 10, 2023
00135d2
Add feature flag
jakzaizzat Oct 10, 2023
e3d8b02
Add auto scroll comment
jakzaizzat Oct 10, 2023
42c5938
Rename the processed text component
jakzaizzat Oct 10, 2023
37b81fc
Remove unused hooks
jakzaizzat Oct 10, 2023
0dbcc35
Full fallback
jakzaizzat Oct 10, 2023
d23829e
Rename processedtext props
jakzaizzat Oct 10, 2023
230cd15
fix double mentions issue
jakzaizzat Oct 11, 2023
f082182
fix multiple mention
jakzaizzat Oct 11, 2023
10c523a
Rename props
jakzaizzat Oct 11, 2023
625422b
memoizing mentions
jakzaizzat Oct 11, 2023
9d07a4b
Simplify processedText
jakzaizzat Oct 13, 2023
21fccfb
fix typo
jakzaizzat Oct 13, 2023
c843bbd
update the comment
jakzaizzat Oct 13, 2023
083b111
Merge branch 'main' of https://github.com/gallery-so/gallery into jak…
jakzaizzat Oct 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function CommentListFallback() {
<CommentCardFallback />
<CommentCardFallback />
<CommentCardFallback />
<CommentCardFallback />
</View>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import {
import { View } from 'react-native';
import { Keyboard } from 'react-native';
import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
import { graphql, useLazyLoadQuery, usePaginationFragment } from 'react-relay';
import { graphql, useFragment, useLazyLoadQuery, usePaginationFragment } from 'react-relay';
import { useEventComment } from 'src/hooks/useEventComment';
import { useMentionableMessage } from 'src/hooks/useMentionableMessage';
import { usePostComment } from 'src/hooks/usePostComment';

import { CommentsBottomSheetList } from '~/components/Feed/CommentsBottomSheet/CommentsBottomSheetList';
Expand All @@ -21,12 +22,15 @@ import {
GalleryBottomSheetModalType,
} from '~/components/GalleryBottomSheet/GalleryBottomSheetModal';
import { useSafeAreaPadding } from '~/components/SafeAreaViewWithPadding';
import { SearchResultsFallback } from '~/components/Search/SearchResultFallback';
import { SearchResults } from '~/components/Search/SearchResults';
import { Typography } from '~/components/Typography';
import { CommentsBottomSheetConnectedCommentsListFragment$key } from '~/generated/CommentsBottomSheetConnectedCommentsListFragment.graphql';
import { CommentsBottomSheetConnectedCommentsListPaginationQuery } from '~/generated/CommentsBottomSheetConnectedCommentsListPaginationQuery.graphql';
import { CommentsBottomSheetConnectedCommentsListQuery } from '~/generated/CommentsBottomSheetConnectedCommentsListQuery.graphql';
import { CommentsBottomSheetConnectedPostCommentsListFragment$key } from '~/generated/CommentsBottomSheetConnectedPostCommentsListFragment.graphql';
import { CommentsBottomSheetConnectedPostCommentsListQuery } from '~/generated/CommentsBottomSheetConnectedPostCommentsListQuery.graphql';
import { CommentsBottomSheetQueryFragment$key } from '~/generated/CommentsBottomSheetQueryFragment.graphql';
import { removeNullValues } from '~/shared/relay/removeNullValues';

import useKeyboardStatus from '../../../utils/useKeyboardStatus';
Expand All @@ -36,12 +40,29 @@ import { CommentListFallback } from './CommentListFallback';
const SNAP_POINTS = [400];

type CommentsBottomSheetProps = {
activeCommentId?: string;
feedId: string;
bottomSheetRef: ForwardedRef<GalleryBottomSheetModalType>;
type: FeedItemTypes;
queryRef: CommentsBottomSheetQueryFragment$key;
};

export function CommentsBottomSheet({ bottomSheetRef, feedId, type }: CommentsBottomSheetProps) {
export function CommentsBottomSheet({
activeCommentId,
bottomSheetRef,
feedId,
type,
queryRef,
}: CommentsBottomSheetProps) {
const query = useFragment(
graphql`
fragment CommentsBottomSheetQueryFragment on Query {
...useMentionableMessageQueryFragment
}
`,
queryRef
);

const internalRef = useRef<GalleryBottomSheetModalType | null>(null);
const [isOpen, setIsOpen] = useState(false);

Expand All @@ -58,16 +79,30 @@ export function CommentsBottomSheet({ bottomSheetRef, feedId, type }: CommentsBo
const { submitComment: postComment, isSubmittingComment: isSubmittingPostComment } =
usePostComment();

const {
aliasKeyword,
isSelectingMentions,
selectMention,
mentions,
setMessage,
message,
resetMentions,
handleSelectionChange,
} = useMentionableMessage(query);

const handleSubmit = useCallback(
(value: string) => {
if (type === 'Post') {
postComment({
feedId,
value,
mentions,
onSuccess: () => {
Keyboard.dismiss();
},
});

resetMentions();
return;
}

Expand All @@ -79,7 +114,7 @@ export function CommentsBottomSheet({ bottomSheetRef, feedId, type }: CommentsBo
},
});
},
[feedId, type, submitComment, postComment]
[feedId, type, mentions, submitComment, postComment, resetMentions]
);

const isSubmitting = useMemo(() => {
Expand Down Expand Up @@ -112,19 +147,52 @@ export function CommentsBottomSheet({ bottomSheetRef, feedId, type }: CommentsBo
onChange={() => setIsOpen(true)}
android_keyboardInputMode="adjustResize"
keyboardBlurBehavior="restore"
onDismiss={resetMentions}
>
<Animated.View style={paddingStyle} className="flex flex-1 flex-col space-y-5">
<Typography className="text-sm px-4" font={{ family: 'ABCDiatype', weight: 'Bold' }}>
Comments
</Typography>

<View className="flex-grow px-1">
<Suspense fallback={<CommentListFallback />}>
{isOpen && <ConnectedCommentsList type={type} feedId={feedId} />}
</Suspense>
<View className="flex-grow">
{isSelectingMentions ? (
<View className="flex-1 overflow-hidden">
<Suspense fallback={<SearchResultsFallback />}>
<SearchResults
keyword={aliasKeyword}
activeFilter="top"
onChangeFilter={() => {}}
blurInputFocus={() => {}}
onSelect={selectMention}
onlyShowTopResults
isMentionSearch
/>
</Suspense>
</View>
) : (
<View className="flex-1 space-y-2">
<Typography className="text-sm px-4" font={{ family: 'ABCDiatype', weight: 'Bold' }}>
Comments
</Typography>
<View className="flex-grow">
<Suspense fallback={<CommentListFallback />}>
{isOpen && (
<ConnectedCommentsList
type={type}
feedId={feedId}
activeCommentId={activeCommentId}
/>
)}
</Suspense>
</View>
</View>
)}
</View>

<CommentBox onSubmit={handleSubmit} isSubmittingComment={isSubmitting} onClose={() => {}} />
<CommentBox
value={message}
onChangeText={setMessage}
onSelectionChange={handleSelectionChange}
onSubmit={handleSubmit}
isSubmittingComment={isSubmitting}
onClose={() => {}}
/>
</Animated.View>
</GalleryBottomSheetModal>
);
Expand All @@ -133,17 +201,23 @@ export function CommentsBottomSheet({ bottomSheetRef, feedId, type }: CommentsBo
type ConnectedCommentsListProps = {
type: FeedItemTypes;
feedId: string;
activeCommentId?: string;
};

function ConnectedCommentsList({ type, feedId }: ConnectedCommentsListProps) {
function ConnectedCommentsList({ type, feedId, activeCommentId }: ConnectedCommentsListProps) {
if (type === 'Post') {
return <ConnectedPostCommentsList feedId={feedId} />;
return <ConnectedPostCommentsList feedId={feedId} activeCommentId={activeCommentId} />;
}

return <ConnectedEventCommentsList feedId={feedId} />;
return <ConnectedEventCommentsList feedId={feedId} activeCommentId={activeCommentId} />;
}

function ConnectedEventCommentsList({ feedId }: { feedId: string }) {
type ConnectedCommentsProps = {
activeCommentId?: string;
feedId: string;
};

function ConnectedEventCommentsList({ activeCommentId, feedId }: ConnectedCommentsProps) {
const queryRef = useLazyLoadQuery<CommentsBottomSheetConnectedCommentsListQuery>(
graphql`
query CommentsBottomSheetConnectedCommentsListQuery(
Expand Down Expand Up @@ -200,7 +274,11 @@ function ConnectedEventCommentsList({ feedId }: { feedId: string }) {
return (
<View className="flex-1">
{comments.length > 0 ? (
<CommentsBottomSheetList onLoadMore={handleLoadMore} commentRefs={comments} />
<CommentsBottomSheetList
onLoadMore={handleLoadMore}
commentRefs={comments}
activeCommentId={activeCommentId}
/>
) : (
<View className="flex items-center justify-center h-full">
<Typography
Expand All @@ -215,7 +293,7 @@ function ConnectedEventCommentsList({ feedId }: { feedId: string }) {
);
}

function ConnectedPostCommentsList({ feedId }: { feedId: string }) {
function ConnectedPostCommentsList({ activeCommentId, feedId }: ConnectedCommentsProps) {
const queryRef = useLazyLoadQuery<CommentsBottomSheetConnectedPostCommentsListQuery>(
graphql`
query CommentsBottomSheetConnectedPostCommentsListQuery(
Expand Down Expand Up @@ -270,7 +348,11 @@ function ConnectedPostCommentsList({ feedId }: { feedId: string }) {
return (
<View className="flex-1">
{comments.length > 0 ? (
<CommentsBottomSheetList onLoadMore={handleLoadMore} commentRefs={comments} />
<CommentsBottomSheetList
onLoadMore={handleLoadMore}
commentRefs={comments}
activeCommentId={activeCommentId}
/>
) : (
<View className="flex items-center justify-center h-full">
<Typography
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
import { useNavigation } from '@react-navigation/native';
import { useCallback } from 'react';
import clsx from 'clsx';
import { useCallback, useMemo } from 'react';
import { View } from 'react-native';
import { useFragment } from 'react-relay';
import { graphql } from 'relay-runtime';

import { GalleryTouchableOpacity } from '~/components/GalleryTouchableOpacity';
import ProcessedText from '~/components/ProcessedText/ProcessedText';
import { ProfilePicture } from '~/components/ProfilePicture/ProfilePicture';
import { Typography } from '~/components/Typography';
import { CommentsBottomSheetLineFragment$key } from '~/generated/CommentsBottomSheetLineFragment.graphql';
import { MainTabStackNavigatorProp } from '~/navigation/types';
import { removeNullValues } from '~/shared/relay/removeNullValues';
import { getTimeSince } from '~/shared/utils/time';

import ProcessedCommentText from '../Socialize/ProcessedCommentText';

type CommentLineProps = {
activeCommentId?: string;
commentRef: CommentsBottomSheetLineFragment$key;
};

export function CommentsBottomSheetLine({ commentRef }: CommentLineProps) {
export function CommentsBottomSheetLine({ activeCommentId, commentRef }: CommentLineProps) {
const comment = useFragment(
graphql`
fragment CommentsBottomSheetLineFragment on Comment {
__typename
dbid
comment
creationTime
commenter {
username

...ProfilePictureFragment
}
mentions {
...ProcessedTextFragment
}
}
`,
commentRef
Expand All @@ -44,13 +50,17 @@ export function CommentsBottomSheetLine({ commentRef }: CommentLineProps) {
}
}, [comment?.commenter?.username, navigation]);

const nonNullMentions = useMemo(() => removeNullValues(comment.mentions), [comment.mentions]);

if (!comment.comment) {
return null;
}

return (
<GalleryTouchableOpacity
className="flex flex-row space-x-2 px-2"
className={clsx('flex flex-row space-x-2 px-3 py-2', {
'bg-offWhite dark:bg-black-800': activeCommentId === comment.dbid,
})}
onPress={handleUserPress}
eventElementId={'CommentsBottomSheetLine Single User'}
eventName={'CommentsBottomSheetLine Single User'}
Expand All @@ -72,7 +82,7 @@ export function CommentsBottomSheetLine({ commentRef }: CommentLineProps) {
{timeAgo}
</Typography>
</View>
<ProcessedCommentText comment={comment.comment} />
<ProcessedText text={comment.comment} mentionsRef={nonNullMentions} />
</View>
</GalleryTouchableOpacity>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,57 @@
import { FlashList, ListRenderItem } from '@shopify/flash-list';
import { useCallback } from 'react';
import { View } from 'react-native';
import { useCallback, useEffect, useRef } from 'react';
import { graphql, useFragment } from 'react-relay';

import { CommentsBottomSheetLine } from '~/components/Feed/CommentsBottomSheet/CommentsBottomSheetLine';
import { CommentsBottomSheetList$key } from '~/generated/CommentsBottomSheetList.graphql';

type CommentsListProps = {
activeCommentId?: string;
onLoadMore: () => void;
commentRefs: CommentsBottomSheetList$key;
};

export function CommentsBottomSheetList({ commentRefs, onLoadMore }: CommentsListProps) {
export function CommentsBottomSheetList({
activeCommentId,
commentRefs,
onLoadMore,
}: CommentsListProps) {
const comments = useFragment(
graphql`
fragment CommentsBottomSheetList on Comment @relay(plural: true) {
dbid
...CommentsBottomSheetLineFragment
}
`,
commentRefs
);

const renderItem = useCallback<ListRenderItem<(typeof comments)[number]>>(({ item: comment }) => {
return (
<View className="mb-4">
<CommentsBottomSheetLine commentRef={comment} />
</View>
);
}, []);
const ref = useRef<FlashList<(typeof comments)[number]>>(null);

useEffect(() => {
if (activeCommentId && ref.current) {
const index = comments.findIndex((comment) => comment.dbid === activeCommentId);
if (index !== -1) {
setTimeout(() => {
if (!ref.current) {
return;
}
ref.current.scrollToIndex({ index, animated: true });
}, 200);
}
}
}, [activeCommentId, comments]);
Comment on lines +31 to +43
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a delay to make sure the comments was fully loaded and we can scroll to specific comment if its out of view

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is freaking sweet


const renderItem = useCallback<ListRenderItem<(typeof comments)[number]>>(
({ item: comment }) => {
return <CommentsBottomSheetLine activeCommentId={activeCommentId} commentRef={comment} />;
},
[activeCommentId]
);

return (
<FlashList
ref={ref}
onEndReached={onLoadMore}
renderItem={renderItem}
data={comments}
Expand Down
Loading