Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 3x 45x 45x 45x 45x 45x 99x 45x 45x 1x 3x 3x 273x 45x | import { Stack } from "@mui/material";
import GiveText from "@shared/Text/GiveText";
import GiveTruncateText from "@shared/Text/GiveTruncateText";
import { styled } from "@theme/v2/Provider";
import { ConversationCounterVariant, User } from "../types";
import { Box } from "@mui/material";
import CounterCircle from "./CounterCircle";
import { useConversationContext } from "../ConversationProvider";
import { usePreciseTimeFormat } from "@utils/date.helpers";
import { every, isEmpty } from "lodash";
import { ParsedTextRenderer } from "./ParsedTextRenderer";
import { getFallbackString } from "../utils";
import FloatingAvatars from "./FloatingAvatars";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
const textCommonProps = { fontSize: "14px" };
interface Props {
title: string;
body: string;
date: number;
id: number;
primaryUser: User;
secondaryUser?: User;
count?: number;
counterVariant?: ConversationCounterVariant;
taskID?: number;
}
export default function ThreadItem({
primaryUser,
secondaryUser,
title,
body,
date,
id,
count,
counterVariant,
taskID,
}: Props) {
const { openThread, searchState } = useConversationContext();
const { formatPreciseTime } = usePreciseTimeFormat();
const { isMobileView } = useCustomThemeV2();
const primaryFallbackString = getFallbackString(primaryUser);
const secondaryFallbackString = secondaryUser
? getFallbackString(secondaryUser)
: "";
const areAllValuesEmpty = every(secondaryUser, (value) => isEmpty(value));
//if is a conversation without a message body => is a document uploaded without message
const usedBody = body ? body : "Documents Attached";
return (
<Wrapper
direction="row"
onClick={() => openThread(id, title, taskID, count || 0)}
id={`thread-${id?.toString()}`}
data-testid="give-conversation-thread-list-item"
isMobileView={isMobileView}
>
<FloatingAvatars
primaryImageURL={primaryUser.imageURL}
primaryFallbackString={primaryFallbackString}
{...(!areAllValuesEmpty && {
secondaryFallbackString: secondaryFallbackString,
secondaryImageURL: secondaryUser?.imageURL,
})}
/>
<Stack gap="8px" flex={1}>
<GiveTruncateText variant="bodyS" fontWeight={500} lineClamp={1}>
<ParsedTextRenderer
text={title}
searchWord={searchState.searchValue}
sx={{ ...textCommonProps, fontWeight: 500 }}
mentionedTextSx={{ ...textCommonProps, fontWeight: 500 }}
searchMatchTextSx={textCommonProps}
id={id}
/>
</GiveTruncateText>
<GiveTruncateText useParse lineClamp={2} variant="bodyS">
<ParsedTextRenderer
text={usedBody}
sx={textCommonProps}
mentionedTextSx={textCommonProps}
searchMatchTextSx={textCommonProps}
/>
</GiveTruncateText>
<GiveText variant="bodyXS" color="secondary">
{date && formatPreciseTime(date * 1000)}
</GiveText>
</Stack>
{!!count && !!counterVariant && (
<CounterCircle count={count} variant={counterVariant} capped />
)}
</Wrapper>
);
}
const FloatingImageWrapper = styled(Box)(({ theme }) => ({
position: "absolute",
zIndex: 2,
top: "8px",
left: "8px",
borderRadius: "40px",
border: `1px solid ${theme.palette.surface?.primary}`,
}));
const Wrapper = styled(Stack, {
shouldForwardProp: (prop) => prop !== "isMobileView",
})<{ isMobileView?: boolean }>(({ theme, isMobileView }) => ({
padding: isMobileView ? "16px 20px" : "16px 12px",
gap: "12px",
borderBottom: `1px solid ${theme.palette.border?.primary}`,
"&:hover": {
backgroundColor: theme.palette.primitive?.transparent["darken-2"],
cursor: "pointer",
},
}));
|