Skip to content

Commit

Permalink
use getImageAbsoluteURI inside Avatar-like components
Browse files Browse the repository at this point in the history
  • Loading branch information
gitstart-twenty committed Jul 26, 2024
1 parent ca8d756 commit 0b00ae0
Show file tree
Hide file tree
Showing 19 changed files with 84 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { Card } from '@/ui/layout/card/components/Card';
import { CardContent } from '@/ui/layout/card/components/CardContent';
import { TimelineCalendarEvent } from '~/generated-metadata/graphql';
import { CalendarChannelVisibility } from '~/generated/graphql';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';
import { isDefined } from '~/utils/isDefined';

type CalendarEventRowProps = {
Expand Down Expand Up @@ -163,7 +162,7 @@ export const CalendarEventRow = ({
key={[participant.workspaceMemberId, participant.displayName]
.filter(isDefined)
.join('-')}
avatarUrl={getImageAbsoluteURI(participant.avatarUrl)}
avatarUrl={participant.avatarUrl}
placeholder={
participant.firstName && participant.lastName
? `${participant.firstName} ${participant.lastName}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
beautifyExactDateTime,
beautifyPastDateRelativeToNow,
} from '~/utils/date-utils';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

const StyledContainer = styled.div`
align-items: center;
Expand Down Expand Up @@ -60,7 +59,7 @@ export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
<StyledContainer>
<StyledLeftContainer>
<Avatar
avatarUrl={getImageAbsoluteURI(avatarUrl)}
avatarUrl={avatarUrl}
size="md"
placeholderColorSeed={author?.id}
placeholder={authorName}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Avatar } from 'twenty-ui';
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { RecordChip } from '@/object-record/components/RecordChip';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

const StyledAvatar = styled(Avatar)`
margin-right: ${({ theme }) => theme.spacing(1)};
Expand Down Expand Up @@ -74,7 +73,7 @@ export const ParticipantChip = ({
) : (
<StyledChip>
<StyledAvatar
avatarUrl={getImageAbsoluteURI(avatarUrl)}
avatarUrl={avatarUrl}
type="rounded"
placeholder={displayName}
size="sm"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { CardContent } from '@/ui/layout/card/components/CardContent';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
import { MessageChannelVisibility, TimelineThread } from '~/generated/graphql';
import { formatToHumanReadableDate } from '~/utils/date-utils';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

const StyledCardContent = styled(CardContent)<{
visibility: MessageChannelVisibility;
Expand Down Expand Up @@ -154,22 +153,20 @@ export const EmailThreadPreview = ({
<StyledHeading unread={!thread.read}>
<StyledParticipantsContainer>
<Avatar
avatarUrl={getImageAbsoluteURI(thread?.firstParticipant?.avatarUrl)}
avatarUrl={thread?.firstParticipant?.avatarUrl}
placeholder={thread.firstParticipant.displayName}
type="rounded"
/>
{thread?.lastTwoParticipants?.[0] && (
<StyledAvatar
avatarUrl={getImageAbsoluteURI(
thread.lastTwoParticipants[0].avatarUrl,
)}
avatarUrl={thread.lastTwoParticipants[0].avatarUrl}
placeholder={thread.lastTwoParticipants[0].displayName}
type="rounded"
/>
)}
{finalDisplayedName && (
<StyledAvatar
avatarUrl={getImageAbsoluteURI(finalAvatarUrl)}
avatarUrl={finalAvatarUrl}
placeholder={finalDisplayedName}
type="rounded"
color={isCountIcon ? GRAY_SCALE.gray50 : undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
beautifyExactDateTime,
beautifyPastDateRelativeToNow,
} from '~/utils/date-utils';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

const StyledAvatarContainer = styled.div`
align-items: center;
Expand Down Expand Up @@ -154,9 +153,7 @@ export const TimelineActivity = ({
<StyledTimelineItemContainer>
<StyledAvatarContainer>
<Avatar
avatarUrl={getImageAbsoluteURI(
activityForTimeline.author?.avatarUrl,
)}
avatarUrl={activityForTimeline.author?.avatarUrl}
placeholder={activityForTimeline.author?.name.firstName ?? ''}
size="sm"
type="rounded"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/componen
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle';
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

import { useFavorites } from '../hooks/useFavorites';

Expand Down Expand Up @@ -81,7 +80,7 @@ export const Favorites = () => {
Icon={() => (
<StyledAvatar
placeholderColorSeed={recordId}
avatarUrl={getImageAbsoluteURI(avatarUrl)}
avatarUrl={avatarUrl}
type={avatarType}
placeholder={labelIdentifier}
className="fav-avatar"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { AvatarChip, IconComponent } from 'twenty-ui';

import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

import { Filter } from '../types/Filter';

type GenericEntityFilterChipProps = {
Expand All @@ -17,7 +15,7 @@ export const GenericEntityFilterChip = ({
placeholderColorSeed={filter.value}
name={filter.displayValue}
avatarType="rounded"
avatarUrl={getImageAbsoluteURI(filter.displayAvatarUrl) || ''}
avatarUrl={filter.displayAvatarUrl}
LeftIcon={Icon}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { SelectableItem } from '@/ui/layout/selectable-list/components/Selectabl
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';
import { isDefined } from '~/utils/isDefined';

export const StyledSelectableItem = styled(SelectableItem)`
Expand Down Expand Up @@ -65,7 +64,7 @@ export const MultipleObjectRecordSelectItem = ({
selected={selected}
avatar={
<Avatar
avatarUrl={getImageAbsoluteURI(recordIdentifier.avatarUrl)}
avatarUrl={recordIdentifier.avatarUrl}
placeholderColorSeed={objectRecordId}
placeholder={recordIdentifier.name}
size="md"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { EntityForSelect } from '@/object-record/relation-picker/types/EntityFor
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

type SelectableMenuItemSelectProps = {
entity: EntityForSelect;
Expand Down Expand Up @@ -40,7 +39,7 @@ export const SelectableMenuItemSelect = ({
hovered={isSelectedItemId}
avatar={
<Avatar
avatarUrl={getImageAbsoluteURI(entity.avatarUrl)}
avatarUrl={entity.avatarUrl}
placeholderColorSeed={entity.id}
placeholder={entity.name}
size="md"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

export const MultipleRecordSelectDropdown = ({
recordsToSelect,
Expand Down Expand Up @@ -69,7 +68,7 @@ export const MultipleRecordSelectDropdown = ({
}
avatar={
<Avatar
avatarUrl={getImageAbsoluteURI(record.avatarUrl)}
avatarUrl={record.avatarUrl}
placeholderColorSeed={record.id}
placeholder={record.name}
size="md"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { ImageInput } from '@/ui/input/components/ImageInput';
import { useUploadProfilePictureMutation } from '~/generated/graphql';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';

Expand Down Expand Up @@ -101,7 +100,7 @@ export const ProfilePictureUploader = () => {

return (
<ImageInput
picture={getImageAbsoluteURI(currentWorkspaceMember?.avatarUrl)}
picture={currentWorkspaceMember?.avatarUrl}
onUpload={handleUpload}
onRemove={handleRemove}
onAbort={handleAbort}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
useUpdateWorkspaceMutation,
useUploadWorkspaceLogoMutation,
} from '~/generated/graphql';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';

export const WorkspaceLogoUploader = () => {
Expand Down Expand Up @@ -57,7 +56,7 @@ export const WorkspaceLogoUploader = () => {

return (
<ImageInput
picture={getImageAbsoluteURI(currentWorkspace?.logo)}
picture={currentWorkspace?.logo}
onUpload={onUpload}
onRemove={onRemove}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import React, { useMemo } from 'react';
import { IconFileUpload, IconTrash, IconUpload, IconX } from 'twenty-ui';

import { Button } from '@/ui/input/button/components/Button';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';
import { isDefined } from '~/utils/isDefined';

const StyledContainer = styled.div`
Expand Down Expand Up @@ -105,16 +106,18 @@ export const ImageInput = ({
hiddenFileInput.current?.click();
};

const pictureURI = useMemo(() => getImageAbsoluteURI(picture), [picture]);

return (
<StyledContainer className={className}>
<StyledPicture
withPicture={!!picture}
withPicture={!!pictureURI}
disabled={disabled}
onClick={onUploadButtonClick}
>
{picture ? (
{pictureURI ? (
<img
src={picture || '/images/default-profile-picture.png'}
src={pictureURI || '/images/default-profile-picture.png'}
alt="profile"
/>
) : (
Expand All @@ -139,7 +142,7 @@ export const ImageInput = ({
onClick={onAbort}
variant="secondary"
title="Abort"
disabled={!picture || disabled}
disabled={!pictureURI || disabled}
fullWidth
/>
) : (
Expand All @@ -157,7 +160,7 @@ export const ImageInput = ({
onClick={onRemove}
variant="secondary"
title="Remove"
disabled={!picture || disabled}
disabled={!pictureURI || disabled}
fullWidth
/>
</StyledButtonContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { AvatarChip } from 'twenty-ui';

import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

export type UserChipProps = {
id: string;
name: string;
Expand All @@ -13,6 +11,6 @@ export const UserChip = ({ id, name, avatarUrl }: UserChipProps) => (
placeholderColorSeed={id}
name={name}
avatarType="rounded"
avatarUrl={getImageAbsoluteURI(avatarUrl) || ''}
avatarUrl={avatarUrl}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import styled from '@emotion/styled';
import { Avatar, OverflowingTextWithTooltip } from 'twenty-ui';

import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { getImageAbsoluteURI } from '~/utils/image/getImageAbsoluteURI';

const StyledContainer = styled.div`
background: ${({ theme }) => theme.background.secondary};
Expand Down Expand Up @@ -39,7 +38,7 @@ export const WorkspaceMemberCard = ({
}: WorkspaceMemberCardProps) => (
<StyledContainer>
<Avatar
avatarUrl={getImageAbsoluteURI(workspaceMember.avatarUrl)}
avatarUrl={workspaceMember.avatarUrl}
placeholderColorSeed={workspaceMember.id}
placeholder={workspaceMember.name.firstName || ''}
type="squared"
Expand Down
20 changes: 13 additions & 7 deletions packages/twenty-ui/src/display/avatar/components/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { styled } from '@linaria/react';
import { isNonEmptyString, isUndefined } from '@sniptt/guards';
import { useContext } from 'react';
import { useContext, useMemo } from 'react';
import { useRecoilState } from 'recoil';

import { invalidAvatarUrlsState } from '@ui/display/avatar/components/states/isInvalidAvatarUrlState';
import { AVATAR_PROPERTIES_BY_SIZE } from '@ui/display/avatar/constants/AvatarPropertiesBySize';
import { AvatarSize } from '@ui/display/avatar/types/AvatarSize';
import { AvatarType } from '@ui/display/avatar/types/AvatarType';
import { ThemeContext } from '@ui/theme';
import { Nullable, stringToHslColor } from '@ui/utilities';
import { Nullable, getImageAbsoluteURI, stringToHslColor } from '@ui/utilities';

const StyledAvatar = styled.div<{
size: AvatarSize;
Expand Down Expand Up @@ -73,15 +73,21 @@ export const Avatar = ({
invalidAvatarUrlsState,
);

const noAvatarUrl = !isNonEmptyString(avatarUrl);
const avatarImageURI = useMemo(
() => getImageAbsoluteURI(avatarUrl),
[avatarUrl],
);

const noAvatarUrl = !isNonEmptyString(avatarImageURI);

const placeholderChar = placeholder?.[0]?.toLocaleUpperCase();

const showPlaceholder = noAvatarUrl || invalidAvatarUrls.includes(avatarUrl);
const showPlaceholder =
noAvatarUrl || invalidAvatarUrls.includes(avatarImageURI);

const handleImageError = () => {
if (isNonEmptyString(avatarUrl)) {
setInvalidAvatarUrls((prev) => [...prev, avatarUrl]);
if (isNonEmptyString(avatarImageURI)) {
setInvalidAvatarUrls((prev) => [...prev, avatarImageURI]);
}
};

Expand All @@ -105,7 +111,7 @@ export const Avatar = ({
{showPlaceholder ? (
placeholderChar
) : (
<StyledImage src={avatarUrl} onError={handleImageError} alt="" />
<StyledImage src={avatarImageURI} onError={handleImageError} alt="" />
)}
</StyledAvatar>
);
Expand Down
30 changes: 30 additions & 0 deletions packages/twenty-ui/src/utilities/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
declare global {
interface Window {
_env_?: Record<string, string>;
__APOLLO_CLIENT__?: any;
}
}

const getDefaultUrl = () => {
if (
window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1'
) {
// In development environment front and backend usually run on separate ports
// we set the default value to localhost:3000.
// It dev context, we use env vars to overwrite it
return 'http://localhost:3000';
} else {
// Outside of localhost we assume that they run on the same port
// because the backend will serve the frontend
// It prod context, we use env-config.js + window var to ovewrite it
return `${window.location.protocol}//${window.location.hostname}${
window.location.port ? `:${window.location.port}` : ''
}`;
}
};

export const REACT_APP_SERVER_BASE_URL =
window._env_?.REACT_APP_SERVER_BASE_URL ||
process.env.REACT_APP_SERVER_BASE_URL ||
getDefaultUrl();
Loading

0 comments on commit 0b00ae0

Please sign in to comment.