-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathContactNameV2.tsx
107 lines (96 loc) · 2.92 KB
/
ContactNameV2.tsx
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
import { RawText } from '@tloncorp/ui';
import React, { useMemo } from 'react';
import { useCalm } from '../contexts';
import { useContact } from '../contexts/appDataContext';
import { formatUserId } from '../utils/user';
// This file is temporary -- it uses the new text, and I want to make sure it works across all callsites before swapping it in
type ContactNameOptions = {
contactId: string;
expandLongIds?: boolean;
mode?: 'contactId' | 'nickname' | 'both' | 'auto';
};
export const useContactNameProps = ({
contactId,
expandLongIds = false,
mode = 'auto',
}: ContactNameOptions) => {
const calm = useCalm();
const contact = useContact(contactId);
const showNickname =
contact?.nickname &&
(calm.disableNicknames ? mode === 'nickname' : mode !== 'contactId');
const showContactId =
(mode === 'auto' && !showNickname) ||
mode === 'both' ||
mode === 'contactId';
return useMemo(() => {
const idMeta = showContactId
? formatUserId(contactId, expandLongIds)
: null;
return {
children: [
showContactId ? idMeta?.display : null,
showNickname ? contact?.nickname : null,
]
.filter((i) => !!i)
.join(' '),
['aria-label']: idMeta?.ariaLabel,
};
}, [
contact?.nickname,
contactId,
expandLongIds,
showContactId,
showNickname,
]);
};
export function useContactName(options: string | ContactNameOptions): string;
export function useContactName(
options: string | ContactNameOptions | null
): string | null;
export function useContactName(
options: string | ContactNameOptions | null
): string | null {
const resolvedOptions = useMemo(() => {
return typeof options === 'string' || options == null
? { contactId: options ?? '' }
: options;
}, [options]);
return useContactNameProps(resolvedOptions).children;
}
const BaseContactName = RawText.styleable<{
contactId: string;
expandLongIds?: boolean;
mode?: 'contactId' | 'nickname' | 'both' | 'auto';
}>(
({ contactId, mode = 'auto', expandLongIds, ...props }, ref) => {
const calm = useCalm();
const contact = useContact(contactId);
const showNickname =
contact?.nickname &&
(calm.disableNicknames ? mode === 'nickname' : mode !== 'contactId');
const showContactId =
(mode === 'auto' && !showNickname) ||
mode === 'both' ||
mode === 'contactId';
const formattedId = useMemo(() => {
return showContactId ? formatUserId(contactId, expandLongIds) : null;
}, [contactId, expandLongIds, showContactId]);
if (showContactId && !formattedId) {
console.error('unable to display invalid id', contactId);
return null;
}
return (
<RawText
{...useContactNameProps({ contactId, expandLongIds, mode })}
{...props}
></RawText>
);
},
{
staticConfig: {
componentName: 'ContactName',
},
}
);
export const ContactName = React.memo(BaseContactName);