// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import React, {useCallback, useLayoutEffect, useMemo, useRef, useState} from 'react'; import {defineMessages, useIntl} from 'react-intl'; import { InteractionManager, Platform, View, } from 'react-native'; import {storeProfileLongPressTutorial} from '@actions/app/global'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; import TutorialHighlight from '@components/tutorial_highlight'; import TutorialLongPress from '@components/tutorial_highlight/long_press'; import UserItem from '@components/user_item'; import {useTheme} from '@context/theme'; import {useIsTablet} from '@hooks/device'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; import {typography} from '@utils/typography'; import type UserModel from '@typings/database/models/servers/user'; type Props = { highlight?: boolean; id: string; includeMargin?: boolean; isChannelAdmin: boolean; manageMode: boolean; onLongPress: (user: UserProfile | UserModel) => void; onPress?: (user: UserProfile | UserModel) => void; selectable: boolean; disabled?: boolean; selected: boolean; showManageMode: boolean; testID: string; tutorialWatched?: boolean; user: UserProfile; } const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { selector: { alignItems: 'center', justifyContent: 'center', marginLeft: 12, }, selectorManage: { alignItems: 'center', flexDirection: 'row', justifyContent: 'center', marginLeft: 12, }, manageText: { color: changeOpacity(theme.centerChannelColor, 0.64), ...typography('Body', 100, 'Regular'), }, tutorial: { top: Platform.select({ios: -74, default: -94}), }, tutorialTablet: { top: -84, }, }; }); const DEFAULT_ICON_OPACITY = 0.32; const messages = defineMessages({ admin: { id: 'mobile.manage_members.admin', defaultMessage: 'Admin', }, member: { id: 'mobile.manage_members.member', defaultMessage: 'Member', }, }); function UserListRow({ id, includeMargin, highlight, isChannelAdmin, onPress, onLongPress, manageMode = false, selectable, disabled, selected, showManageMode = false, testID, tutorialWatched = false, user, }: Props) { const theme = useTheme(); const isTablet = useIsTablet(); const [showTutorial, setShowTutorial] = useState(false); const [itemBounds, setItemBounds] = useState({startX: 0, startY: 0, endX: 0, endY: 0}); const viewRef = useRef(null); const style = getStyleFromTheme(theme); const {formatMessage} = useIntl(); const tutorialShown = useRef(false); const startTutorial = () => { viewRef.current?.measureInWindow((x, y, w, h) => { const bounds: TutorialItemBounds = { startX: x, startY: y, endX: x + w, endY: y + h, }; if (viewRef.current) { setItemBounds(bounds); } }); }; const handleDismissTutorial = useCallback(() => { setShowTutorial(false); storeProfileLongPressTutorial(); }, []); const handlePress = useCallback((u: UserModel | UserProfile) => { onPress?.(u); }, [onPress]); const manageModeIcon = useMemo(() => { if (!showManageMode) { return null; } const color = changeOpacity(theme.centerChannelColor, 0.64); const message = isChannelAdmin ? messages.admin : messages.member; return ( ); }, [isChannelAdmin, showManageMode, style.manageText, style.selectorManage, theme.centerChannelColor]); const onLayout = useCallback(() => { if (highlight && !tutorialWatched) { if (isTablet) { setShowTutorial(true); return; } InteractionManager.runAfterInteractions(() => { setShowTutorial(true); }); } }, [highlight, isTablet, tutorialWatched]); useLayoutEffect(() => { if (showTutorial && !tutorialShown.current) { tutorialShown.current = true; startTutorial(); } }); const icon = useMemo(() => { if (!selectable && !selected) { return null; } const color = selected ? theme.buttonBg : changeOpacity(theme.centerChannelColor, DEFAULT_ICON_OPACITY); return ( ); }, [selectable, selected, theme.buttonBg, theme.centerChannelColor, style.selector]); const userItemTestID = `${testID}.${id}`; return ( <> {showTutorial && {Boolean(itemBounds.endX) && } } ); } export default React.memo(UserListRow);