You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.1 KiB
TypeScript
117 lines
3.1 KiB
TypeScript
import { clone, noop } from 'lodash';
|
|
import React from 'react';
|
|
import styled from 'styled-components';
|
|
|
|
import { Flex } from './Flex';
|
|
|
|
import { useConversationsUsernameWithQuoteOrShortPk } from '../../hooks/useParamSelector';
|
|
import { SessionIcon, SessionIconType } from '../icon';
|
|
import { SessionHtmlRenderer } from './SessionHTMLRenderer';
|
|
|
|
// NOTE We don't change the color strip on the left based on the type. 16/09/2022
|
|
export enum SessionToastType {
|
|
Info = 'info',
|
|
Success = 'success',
|
|
Warning = 'warning',
|
|
Error = 'error',
|
|
}
|
|
|
|
type Props = {
|
|
description: string;
|
|
|
|
id?: string;
|
|
type?: SessionToastType;
|
|
icon?: SessionIconType;
|
|
closeToast?: any;
|
|
onToastClick?: () => void;
|
|
};
|
|
|
|
const DescriptionDiv = styled.div`
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary-color);
|
|
text-overflow: ellipsis;
|
|
font-family: var(--font-default);
|
|
padding-top: var(--margins-xs);
|
|
`;
|
|
|
|
const IconDiv = styled.div`
|
|
flex-shrink: 0;
|
|
padding-inline-end: var(--margins-xs);
|
|
margin: 0 var(--margins-sm) 0 var(--margins-xs);
|
|
`;
|
|
|
|
function useReplacePkInTextWithNames(description: string) {
|
|
const pubkeysToLookup = [...description.matchAll(/0[3,5][0-9a-fA-F]{64}/g)] || [];
|
|
const memberNames = useConversationsUsernameWithQuoteOrShortPk(pubkeysToLookup.map(m => m[0]));
|
|
|
|
let replacedWithNames = clone(description);
|
|
for (let index = 0; index < memberNames.length; index++) {
|
|
const name = memberNames[index];
|
|
const pk = pubkeysToLookup[index][0];
|
|
replacedWithNames = replacedWithNames.replace(pk, name);
|
|
}
|
|
|
|
return replacedWithNames;
|
|
}
|
|
|
|
function DescriptionPubkeysReplaced({ description }: { description: string }) {
|
|
const replacedWithNames = useReplacePkInTextWithNames(description);
|
|
return (
|
|
<DescriptionDiv>
|
|
<SessionHtmlRenderer html={replacedWithNames} />
|
|
</DescriptionDiv>
|
|
);
|
|
}
|
|
|
|
export const SessionToast = (props: Props) => {
|
|
const { description, type, icon } = props;
|
|
|
|
const toastDesc = description || '';
|
|
const toastIconSize = toastDesc ? 'huge' : 'medium';
|
|
|
|
// Set a custom icon or allow the theme to define the icon
|
|
let toastIcon = icon || undefined;
|
|
if (!toastIcon) {
|
|
switch (type) {
|
|
case SessionToastType.Info:
|
|
toastIcon = 'info';
|
|
break;
|
|
case SessionToastType.Success:
|
|
toastIcon = 'check';
|
|
break;
|
|
case SessionToastType.Error:
|
|
toastIcon = 'error';
|
|
break;
|
|
case SessionToastType.Warning:
|
|
toastIcon = 'warning';
|
|
break;
|
|
default:
|
|
toastIcon = 'info';
|
|
}
|
|
}
|
|
|
|
const onToastClick = props?.onToastClick || noop;
|
|
|
|
return (
|
|
<Flex
|
|
container={true}
|
|
alignItems="center"
|
|
onClick={onToastClick}
|
|
data-testid="session-toast"
|
|
padding="var(--margins-sm) 0"
|
|
>
|
|
<IconDiv>
|
|
<SessionIcon iconType={toastIcon} iconSize={toastIconSize} />
|
|
</IconDiv>
|
|
<Flex
|
|
container={true}
|
|
justifyContent="flex-start"
|
|
flexDirection="column"
|
|
className="session-toast"
|
|
>
|
|
<DescriptionPubkeysReplaced description={toastDesc} />
|
|
</Flex>
|
|
</Flex>
|
|
);
|
|
};
|