mirror of
https://github.com/lux-tel/websites.git
synced 2026-10-30 20:31:36 +00:00
105 lines
3.7 KiB
TypeScript
105 lines
3.7 KiB
TypeScript
'use client';
|
|
|
|
import { CopyToClipboardButton } from './CopyToClipboardButton';
|
|
import { cn } from '../lib/utils';
|
|
import { Tooltip } from './ui/tooltip';
|
|
import { collapseString } from '@session/util-crypto/string';
|
|
import { forwardRef, HTMLAttributes, useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { ButtonDataTestId } from '../data-test-ids';
|
|
|
|
type CollapseStringsParams = Parameters<typeof collapseString>;
|
|
|
|
type PubKeyType = HTMLAttributes<HTMLDivElement> & {
|
|
pubKey: string;
|
|
leadingChars?: CollapseStringsParams[1];
|
|
trailingChars?: CollapseStringsParams[2];
|
|
expandOnHover?: boolean;
|
|
expandOnHoverDesktopOnly?: boolean;
|
|
alwaysShowCopyButton?: boolean;
|
|
force?: 'expand' | 'collapse';
|
|
copyToClipboardAriaLabel?: string;
|
|
copyToClipboardToastMessage?: string;
|
|
};
|
|
|
|
export const PubKey = forwardRef<HTMLDivElement, PubKeyType>((props, ref) => {
|
|
const {
|
|
className,
|
|
pubKey,
|
|
leadingChars,
|
|
trailingChars,
|
|
expandOnHover,
|
|
expandOnHoverDesktopOnly,
|
|
alwaysShowCopyButton,
|
|
copyToClipboardAriaLabel,
|
|
copyToClipboardToastMessage,
|
|
force,
|
|
...rest
|
|
} = props;
|
|
const [isExpanded, setIsExpanded] = useState(force === 'expand');
|
|
const collapsedPubKey = useMemo(
|
|
() => (pubKey ? collapseString(pubKey, leadingChars ?? 6, trailingChars ?? 6) : ''),
|
|
[pubKey]
|
|
);
|
|
|
|
const handleSelectionChange = useCallback(() => {
|
|
if (force === 'expand' || force === 'collapse') return;
|
|
setIsExpanded(window.getSelection()?.toString() === pubKey);
|
|
}, [pubKey, force]);
|
|
|
|
useEffect(() => {
|
|
/**
|
|
* Keeps the full pubkey visible when selected.
|
|
*/
|
|
document.addEventListener('selectionchange', handleSelectionChange);
|
|
return () => {
|
|
document.removeEventListener('selectionchange', handleSelectionChange);
|
|
};
|
|
}, [handleSelectionChange]);
|
|
|
|
return (
|
|
<span ref={ref} className={cn('group flex select-all items-center', className)} {...rest}>
|
|
{!isExpanded ? (
|
|
<Tooltip tooltipContent={pubKey} triggerProps={{ disabled: expandOnHover }}>
|
|
<span
|
|
className={cn(
|
|
'select-all break-all',
|
|
force !== 'collapse' && expandOnHover && 'group-hover:hidden',
|
|
force !== 'collapse' && expandOnHover && isExpanded ? 'hidden' : 'block',
|
|
force !== 'collapse' && expandOnHoverDesktopOnly && 'md:group-hover:hidden',
|
|
force !== 'collapse' && expandOnHoverDesktopOnly && isExpanded
|
|
? 'md:hidden'
|
|
: 'md:block'
|
|
)}
|
|
>
|
|
{collapsedPubKey}
|
|
</span>
|
|
</Tooltip>
|
|
) : null}
|
|
<div
|
|
className={cn(
|
|
'select-all break-all',
|
|
force !== 'collapse' && expandOnHover && 'group-hover:block',
|
|
(force !== 'collapse' && expandOnHover && isExpanded) || isExpanded ? 'block' : 'hidden',
|
|
force !== 'collapse' && expandOnHoverDesktopOnly && 'md:group-hover:block',
|
|
(force !== 'collapse' && expandOnHoverDesktopOnly && isExpanded) || isExpanded
|
|
? 'md:block'
|
|
: 'md:hidden'
|
|
)}
|
|
>
|
|
{pubKey}
|
|
</div>
|
|
<CopyToClipboardButton
|
|
className={cn(
|
|
'group-hover:bg-session-green group-hover:text-session-black *:group-hover:fill-session-black mx-1 p-0.5 duration-0 group-hover:opacity-100',
|
|
alwaysShowCopyButton || isExpanded ? 'opacity-100' : 'opacity-0'
|
|
)}
|
|
textToCopy={pubKey}
|
|
data-testid={ButtonDataTestId.Copy_Pub_Key_To_Clipboard}
|
|
aria-label={copyToClipboardAriaLabel ?? 'Copy to Clipboard'}
|
|
copyToClipboardToastMessage={copyToClipboardToastMessage ?? 'Copied to clipboard!'}
|
|
/>
|
|
</span>
|
|
);
|
|
});
|
|
PubKey.displayName = 'PubKey';
|