feat(front): improve logo component (#8720)

This commit is contained in:
Antoine Moreaux 2024-11-27 19:26:45 +01:00 committed by GitHub
parent 3ad1113173
commit 2fab2266d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 35 deletions

View File

@ -3,65 +3,62 @@ import styled from '@emotion/styled';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI'; import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';
type LogoProps = { type LogoProps = {
workspaceLogo?: string | null; primaryLogo?: string | null;
secondaryLogo?: string | null;
}; };
const StyledContainer = styled.div` const StyledContainer = styled.div`
height: 48px; height: ${({ theme }) => theme.spacing(12)};
margin-bottom: ${({ theme }) => theme.spacing(4)}; margin-bottom: ${({ theme }) => theme.spacing(4)};
margin-top: ${({ theme }) => theme.spacing(4)}; margin-top: ${({ theme }) => theme.spacing(4)};
position: relative; position: relative;
width: 48px; width: ${({ theme }) => theme.spacing(12)};
`; `;
const StyledTwentyLogo = styled.img` const StyledSecondaryLogo = styled.img`
border-radius: ${({ theme }) => theme.border.radius.xs}; border-radius: ${({ theme }) => theme.border.radius.xs};
height: 24px; height: ${({ theme }) => theme.spacing(6)};
width: 24px; width: ${({ theme }) => theme.spacing(6)};
`; `;
const StyledTwentyLogoContainer = styled.div` const StyledSecondaryLogoContainer = styled.div`
align-items: center; align-items: center;
background-color: ${({ theme }) => theme.background.primary}; background-color: ${({ theme }) => theme.background.primary};
border-radius: ${({ theme }) => theme.border.radius.sm}; border-radius: ${({ theme }) => theme.border.radius.sm};
bottom: ${({ theme }) => `-${theme.spacing(3)}`}; bottom: ${({ theme }) => `-${theme.spacing(3)}`};
display: flex; display: flex;
height: 28px; height: ${({ theme }) => theme.spacing(7)};
justify-content: center; justify-content: center;
position: absolute; position: absolute;
right: ${({ theme }) => `-${theme.spacing(3)}`}; right: ${({ theme }) => `-${theme.spacing(3)}`};
width: 28px; width: ${({ theme }) => theme.spacing(7)};
`; `;
type StyledMainLogoProps = { const StyledPrimaryLogo = styled.div<{ src: string }>`
logo?: string | null; background: url(${(props) => props.src});
};
const StyledMainLogo = styled.div<StyledMainLogoProps>`
background: url(${(props) => props.logo});
background-size: cover; background-size: cover;
height: 100%; height: 100%;
width: 100%; width: 100%;
`; `;
export const Logo = ({ workspaceLogo }: LogoProps) => { export const Logo = (props: LogoProps) => {
if (!workspaceLogo) { const defaultPrimaryLogoUrl = `${window.location.origin}/icons/android/android-launchericon-192-192.png`;
return (
<StyledContainer> const primaryLogoUrl = getImageAbsoluteURI(
<StyledMainLogo logo="/icons/android/android-launchericon-192-192.png" /> props.primaryLogo ?? defaultPrimaryLogoUrl,
</StyledContainer> );
); const secondaryLogoUrl = getImageAbsoluteURI(props.secondaryLogo);
}
return ( return (
<StyledContainer> <StyledContainer>
<StyledMainLogo logo={getImageAbsoluteURI(workspaceLogo)} /> <StyledPrimaryLogo src={primaryLogoUrl} />
<StyledTwentyLogoContainer> {secondaryLogoUrl && (
<StyledTwentyLogo src="/icons/android/android-launchericon-192-192.png" /> <StyledSecondaryLogoContainer>
</StyledTwentyLogoContainer> <StyledSecondaryLogo src={secondaryLogoUrl} />
</StyledSecondaryLogoContainer>
)}
</StyledContainer> </StyledContainer>
); );
}; };

View File

@ -74,7 +74,7 @@ export const Invite = () => {
return ( return (
<> <>
<AnimatedEaseIn> <AnimatedEaseIn>
<Logo workspaceLogo={workspaceFromInviteHash?.logo} /> <Logo secondaryLogo={workspaceFromInviteHash?.logo} />
</AnimatedEaseIn> </AnimatedEaseIn>
<Title animate>{title}</Title> <Title animate>{title}</Title>
{isDefined(currentWorkspace) ? ( {isDefined(currentWorkspace) ? (

View File

@ -1,15 +1,26 @@
import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { REACT_APP_SERVER_BASE_URL } from '~/config';
export const getImageAbsoluteURI = (imageUrl?: string | null) => { type ImageAbsoluteURI<T extends string | null | undefined> = T extends string
? string
: null;
export const getImageAbsoluteURI = <T extends string | null | undefined>(
imageUrl: T,
): ImageAbsoluteURI<T> => {
if (!imageUrl) { if (!imageUrl) {
return null; return null as ImageAbsoluteURI<T>;
} }
if (imageUrl?.startsWith('https:') || imageUrl?.startsWith('http:')) { if (imageUrl.startsWith('https:') || imageUrl.startsWith('http:')) {
return imageUrl; return imageUrl as ImageAbsoluteURI<T>;
} }
const serverFilesUrl = REACT_APP_SERVER_BASE_URL; const serverFilesUrl = new URL(REACT_APP_SERVER_BASE_URL);
return `${serverFilesUrl}/files/${imageUrl}`; serverFilesUrl.pathname = `/files/`;
serverFilesUrl.pathname += imageUrl.startsWith('/')
? imageUrl.slice(1)
: imageUrl;
return serverFilesUrl.toString() as ImageAbsoluteURI<T>;
}; };