mattermost-mobile/app/screens/reactions/reactions.tsx
Elias Nahum dbe565319d
BottomSheet migration to react-native-bottom-sheet (#6907)
* BottomSheet migration to react-native-bottom-sheet

* Use correct scroll view for announcement bottom sheet

* ux review

* Fix post options bottom sheet snap point

* feedback review
2023-01-05 09:51:51 +02:00

94 lines
3.3 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {Screens} from '@constants';
import {useIsTablet} from '@hooks/device';
import BottomSheet from '@screens/bottom_sheet';
import {getEmojiFirstAlias} from '@utils/emoji/helpers';
import EmojiAliases from './emoji_aliases';
import EmojiBar from './emoji_bar';
import ReactorsList from './reactors_list';
import type ReactionModel from '@typings/database/models/servers/reaction';
type Props = {
initialEmoji: string;
location: string;
reactions?: ReactionModel[];
}
const Reactions = ({initialEmoji, location, reactions}: Props) => {
const isTablet = useIsTablet();
const [sortedReactions, setSortedReactions] = useState(Array.from(new Set(reactions?.map((r) => getEmojiFirstAlias(r.emojiName)))));
const [index, setIndex] = useState(sortedReactions.indexOf(initialEmoji));
const reactionsByName = useMemo(() => {
return reactions?.reduce((acc, reaction) => {
const emojiAlias = getEmojiFirstAlias(reaction.emojiName);
if (acc.has(emojiAlias)) {
const rs = acc.get(emojiAlias);
// eslint-disable-next-line max-nested-callbacks
const present = rs!.findIndex((r) => r.userId === reaction.userId) > -1;
if (!present) {
rs!.push(reaction);
}
} else {
acc.set(emojiAlias, [reaction]);
}
return acc;
}, new Map<string, ReactionModel[]>());
}, [reactions]);
const renderContent = useCallback(() => {
const emojiAlias = sortedReactions[index];
if (!reactionsByName) {
return null;
}
return (
<>
<EmojiBar
emojiSelected={emojiAlias}
reactionsByName={reactionsByName}
setIndex={setIndex}
sortedReactions={sortedReactions}
/>
<EmojiAliases emoji={emojiAlias}/>
<ReactorsList
key={emojiAlias}
location={location}
reactions={reactionsByName.get(emojiAlias)!}
type={isTablet ? 'FlatList' : 'BottomSheetFlatList'}
/>
</>
);
}, [index, location, reactions, sortedReactions]);
useEffect(() => {
// This helps keep the reactions in the same position at all times until unmounted
const rs = reactions?.map((r) => getEmojiFirstAlias(r.emojiName));
const sorted = new Set([...sortedReactions]);
const added = rs?.filter((r) => !sorted.has(r));
added?.forEach(sorted.add, sorted);
const removed = [...sorted].filter((s) => !rs?.includes(s));
removed.forEach(sorted.delete, sorted);
setSortedReactions(Array.from(sorted));
}, [reactions]);
return (
<BottomSheet
renderContent={renderContent}
closeButtonId='close-post-reactions'
componentId={Screens.REACTIONS}
initialSnapIndex={1}
snapPoints={[1, '50%', '90%']}
testID='reactions'
/>
);
};
export default Reactions;