Add location to basename profile / TextRecords (#1153)

This commit is contained in:
Léo Galley
2024-10-25 11:53:39 -04:00
committed by GitHub
parent c053f0ae1f
commit a2ddd5f166
6 changed files with 124 additions and 27 deletions

View File

@@ -0,0 +1,52 @@
import Fieldset from 'apps/web/src/components/Fieldset';
import Input from 'apps/web/src/components/Input';
import Label from 'apps/web/src/components/Label';
import {
textRecordsKeysPlaceholderForDisplay,
USERNAME_LOCATION_MAX_LENGTH,
UsernameTextRecordKeys,
} from 'apps/web/src/utils/usernames';
import { ChangeEvent, ReactNode, useCallback, useId } from 'react';
export type UsernameLocationFieldProps = {
labelChildren?: ReactNode;
onChange: (key: UsernameTextRecordKeys, value: string) => void;
value: string;
disabled?: boolean;
};
export default function UsernameLocationField({
labelChildren = 'Location',
onChange,
value,
disabled = false,
}: UsernameLocationFieldProps) {
const onChangeLocation = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
const location = event.target.value;
if (location.length > USERNAME_LOCATION_MAX_LENGTH) {
event.preventDefault();
} else {
if (onChange) onChange(UsernameTextRecordKeys.Location, location);
}
},
[onChange],
);
const usernameLocationFieldId = useId();
return (
<Fieldset>
{labelChildren && <Label htmlFor={usernameLocationFieldId}>{labelChildren}</Label>}
<Input
id={usernameLocationFieldId}
placeholder={textRecordsKeysPlaceholderForDisplay[UsernameTextRecordKeys.Location]}
maxLength={USERNAME_LOCATION_MAX_LENGTH}
onChange={onChangeLocation}
disabled={disabled}
value={value}
className="flex-1 rounded-md border border-gray-40/20 p-2 text-black"
/>
</Fieldset>
);
}

View File

@@ -20,6 +20,7 @@ export default function UsernameProfileCard() {
});
const textRecordDescription = existingTextRecords[UsernameTextRecordKeys.Description];
const textRecordLocation = existingTextRecords[UsernameTextRecordKeys.Location];
const textRecordsSocial = textRecordsSocialFieldsEnabled.reduce(
(previousValue, textRecordKey) => {
@@ -29,9 +30,11 @@ export default function UsernameProfileCard() {
{} as UsernameTextRecords,
);
const hasTextRecordsSocials = Object.values(textRecordsSocial).filter((v) => !!v).length > 0;
// TODO: Empty state / CTA to edit if owner
const hasTextRecordsToDisplay =
!!textRecordDescription || Object.values(textRecordsSocial).filter((v) => !!v).length > 0;
!!textRecordDescription || !!textRecordLocation || hasTextRecordsSocials;
if (!hasTextRecordsToDisplay) {
return;
@@ -47,32 +50,45 @@ export default function UsernameProfileCard() {
<p className="break-words font-bold text-illoblack">{textRecordDescription}</p>
)}
<ul className="flex flex-col gap-2">
{textRecordsSocialFieldsEnabled.map(
(textRecordKey) =>
!!existingTextRecords[textRecordKey] && (
<li key={textRecordKey}>
<Link
href={formatSocialFieldUrl(textRecordKey, existingTextRecords[textRecordKey])}
target="_blank"
className="flex items-center gap-2 text-palette-foregroundMuted hover:text-blue-500"
>
<span>
<Icon
name={textRecordsSocialFieldsEnabledIcons[textRecordKey]}
height="1rem"
width="1rem"
color="currentColor"
/>
</span>
<span className="overflow-hidden text-ellipsis">
{formatSocialFieldForDisplay(textRecordKey, existingTextRecords[textRecordKey])}
</span>
</Link>
</li>
),
)}
</ul>
{!!textRecordLocation && (
<p className="flex items-center gap-2 text-palette-foregroundMuted ">
<span>
<Icon name="map" height="1rem" width="1rem" color="currentColor" />
</span>
<span className="overflow-hidden text-ellipsis">{textRecordLocation}</span>
</p>
)}
{hasTextRecordsSocials && (
<ul className="flex flex-col gap-2">
{textRecordsSocialFieldsEnabled.map(
(textRecordKey) =>
!!existingTextRecords[textRecordKey] && (
<li key={textRecordKey}>
<Link
href={formatSocialFieldUrl(textRecordKey, existingTextRecords[textRecordKey])}
target="_blank"
className="flex items-center gap-2 text-palette-foregroundMuted hover:text-blue-500"
>
<span>
<Icon
name={textRecordsSocialFieldsEnabledIcons[textRecordKey]}
height="1rem"
width="1rem"
color="currentColor"
/>
</span>
<span className="overflow-hidden text-ellipsis">
{formatSocialFieldForDisplay(
textRecordKey,
existingTextRecords[textRecordKey],
)}
</span>
</Link>
</li>
),
)}
</ul>
)}
</div>
);
}

View File

@@ -17,6 +17,7 @@ import {
UsernameTextRecordKeys,
} from 'apps/web/src/utils/usernames';
import UsernameCastsField from 'apps/web/src/components/Basenames/UsernameCastsField';
import UsernameLocationField from 'apps/web/src/components/Basenames/UsernameLocationField';
const settingTabClass = classNames(
'flex flex-col justify-between gap-8 text-gray/60 md:items-center p-4 md:p-8',
@@ -72,6 +73,11 @@ export default function UsernameProfileSettingsManageProfile() {
value={updatedTextRecords[UsernameTextRecordKeys.Description]}
disabled={writeTextRecordsIsPending}
/>
<UsernameLocationField
onChange={onChangeTextRecord}
value={updatedTextRecords[UsernameTextRecordKeys.Location]}
disabled={writeTextRecordsIsPending}
/>
<Fieldset>
<Label>Socials</Label>
{textRecordsSocialFieldsEnabled.map((textRecordKey) => (

View File

@@ -521,6 +521,23 @@ const ICONS: Record<string, (props: SvgProps) => JSX.Element> = {
/>
</svg>
),
map: ({ color, width, height }: SvgProps) => (
<svg
width={width}
height={height}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M11.4424 23.8252L11.5273 23.8726L11.5612 23.8916C11.6958 23.9627 11.8464 24 11.9994 24C12.1524 24 12.303 23.9627 12.4376 23.8916L12.4715 23.8738L12.5576 23.8252C13.0317 23.5503 13.4943 23.2569 13.9442 22.9457C15.1092 22.1415 16.1976 21.2362 17.1964 20.2409C19.5527 17.8822 22 14.3383 22 9.77851C22 7.18509 20.9464 4.69789 19.0711 2.86406C17.1957 1.03023 14.6522 0 12 0C9.34784 0 6.8043 1.03023 4.92893 2.86406C3.05357 4.69789 2 7.18509 2 9.77851C2 14.3371 4.44848 17.8822 6.80364 20.2409C7.80199 21.2362 8.89003 22.1414 10.0545 22.9457C10.5049 23.2569 10.9679 23.5503 11.4424 23.8252ZM12 13.3343C12.9644 13.3343 13.8893 12.9597 14.5713 12.2929C15.2532 11.626 15.6364 10.7216 15.6364 9.77851C15.6364 8.83545 15.2532 7.93101 14.5713 7.26416C13.8893 6.59732 12.9644 6.22269 12 6.22269C11.0356 6.22269 10.1107 6.59732 9.4287 7.26416C8.74675 7.93101 8.36364 8.83545 8.36364 9.77851C8.36364 10.7216 8.74675 11.626 9.4287 12.2929C10.1107 12.9597 11.0356 13.3343 12 13.3343Z"
fill={color}
/>
</svg>
),
};
export function Icon({ name, color = 'white', width = '24', height = '24' }: IconProps) {

View File

@@ -38,6 +38,7 @@ export default function useReadBaseEnsTextRecords({
[UsernameTextRecordKeys.Github]: '',
[UsernameTextRecordKeys.Email]: '',
[UsernameTextRecordKeys.Phone]: '',
[UsernameTextRecordKeys.Location]: '',
[UsernameTextRecordKeys.Avatar]: '',
[UsernameTextRecordKeys.Frames]: '',
[UsernameTextRecordKeys.Casts]: '',

View File

@@ -63,6 +63,7 @@ export const USERNAME_MIN_CHARACTER_LENGTH = 3;
export const USERNAME_MAX_CHARACTER_LENGTH = 20;
export const USERNAME_DESCRIPTION_MAX_LENGTH = 200;
export const USERNAME_LOCATION_MAX_LENGTH = 100;
// DANGER: Changing this post-mainnet launch means the stored data won't be accessible via the updated key
export enum UsernameTextRecordKeys {
@@ -75,6 +76,7 @@ export enum UsernameTextRecordKeys {
Email = 'email',
Phone = 'phone',
Avatar = 'avatar',
Location = 'location',
// Socials
Github = 'com.github',
@@ -177,6 +179,7 @@ export const textRecordsKeysEnabled = [
UsernameTextRecordKeys.Github,
UsernameTextRecordKeys.Email,
UsernameTextRecordKeys.Phone,
UsernameTextRecordKeys.Location,
UsernameTextRecordKeys.Twitter,
UsernameTextRecordKeys.Farcaster,
UsernameTextRecordKeys.Lens,
@@ -196,6 +199,7 @@ export const textRecordsKeysForDisplay = {
[UsernameTextRecordKeys.Github]: 'Github',
[UsernameTextRecordKeys.Email]: 'Email',
[UsernameTextRecordKeys.Phone]: 'Phone',
[UsernameTextRecordKeys.Location]: 'Location',
[UsernameTextRecordKeys.Twitter]: 'Twitter / X',
[UsernameTextRecordKeys.Farcaster]: 'Farcaster',
[UsernameTextRecordKeys.Lens]: 'Lens',
@@ -215,6 +219,7 @@ export const textRecordsKeysPlaceholderForDisplay = {
[UsernameTextRecordKeys.Github]: 'Username',
[UsernameTextRecordKeys.Email]: 'Personal email',
[UsernameTextRecordKeys.Phone]: '+1 415 ..',
[UsernameTextRecordKeys.Location]: 'New York, NY, USA',
[UsernameTextRecordKeys.Twitter]: 'Username',
[UsernameTextRecordKeys.Farcaster]: 'Username',
[UsernameTextRecordKeys.Lens]: 'name.lens',