Skip to content

Commit

Permalink
Merge pull request #415 from alleslabs/feat/icns
Browse files Browse the repository at this point in the history
feat: icns
  • Loading branch information
evilpeach committed Jul 18, 2023
2 parents 562111e + 1539d6e commit bc89f47
Show file tree
Hide file tree
Showing 13 changed files with 441 additions and 138 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- [#415](https://github.com/alleslabs/celatone-frontend/pull/415) Search by icns names feature and Show registered icns names on account details page
- [#438](https://github.com/alleslabs/celatone-frontend/pull/438) Add new home page
- [#437](https://github.com/alleslabs/celatone-frontend/pull/437) Add first landing prompt for dev mode
- [#436](https://github.com/alleslabs/celatone-frontend/pull/436) Implement merge navigation
Expand Down
6 changes: 6 additions & 0 deletions src/lib/app-provider/hooks/useBaseApiRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const useBaseApiRoute = (
| "codes"
| "accounts"
| "rest"
| "icns_names"
| "icns_address"
| "native_tokens"
| "cosmwasm"
): string => {
Expand Down Expand Up @@ -43,6 +45,10 @@ export const useBaseApiRoute = (
return `${api}/accounts/${chain}/${currentChainId}`;
case "rest":
return `${api}/rest/${chain}/${currentChainId}`;
case "icns_names":
return `${api}/icns/names`;
case "icns_address":
return `${api}/icns/address`;
case "native_tokens":
return `${api}/native-assets/${chain}/${currentChainId}`;
case "cosmwasm":
Expand Down
20 changes: 12 additions & 8 deletions src/lib/components/CopyLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ interface CopyLinkProps extends FlexProps {
value: string;
amptrackSection?: string;
type: string;
withoutIcon?: boolean;
showCopyOnHover?: boolean;
}

export const CopyLink = ({
value,
amptrackSection,
type,
withoutIcon,
showCopyOnHover = false,
...flexProps
}: CopyLinkProps) => {
Expand Down Expand Up @@ -69,14 +71,16 @@ export const CopyLink = ({
>
{value === address ? `${value} (Me)` : value}
</Text>
<CustomIcon
display={displayIcon}
cursor="pointer"
marginLeft={2}
name="copy"
boxSize={3}
color="gray.600"
/>
{!withoutIcon && (
<CustomIcon
display={displayIcon}
cursor="pointer"
marginLeft={2}
name="copy"
boxSize={3}
color="gray.600"
/>
)}
</Flex>
</Tooltip>
);
Expand Down
10 changes: 10 additions & 0 deletions src/lib/components/PrimaryNameMark.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { CustomIcon } from "lib/components/icon";
import { Tooltip } from "lib/components/Tooltip";

export const PrimaryNameMark = () => (
<Tooltip label="Primary name">
<div style={{ display: "flex" }}>
<CustomIcon name="star-solid" color="accent.main" boxSize={3} m={0} />
</div>
</Tooltip>
);
11 changes: 11 additions & 0 deletions src/lib/components/icon/CustomIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,17 @@ export const ICONS = {
),
viewBox: "0.5 1 16 16",
},
"star-solid": {
svg: (
<path
d="M6.09706 3.2465L6.98381 3.27723L6.56704 4.06055C6.25457 4.64785 6.25457 5.35207 6.56704 5.93937L6.98381 6.72268L6.09706 6.75341C5.4322 6.77645 4.82233 7.12857 4.46995 7.69283L3.99996 8.44541L3.52997 7.69283C3.17759 7.12857 2.56771 6.77645 1.90286 6.75341L1.01611 6.72268L1.43287 5.93937C1.74535 5.35207 1.74535 4.64785 1.43287 4.06055L1.01611 3.27723L1.90286 3.2465C2.56771 3.22346 3.17759 2.87135 3.52997 2.30709L2.68178 1.7774L3.52997 2.30709L3.99996 1.55451L4.46995 2.30709L5.31813 1.7774L4.46995 2.30709C4.82233 2.87135 5.4322 3.22346 6.09706 3.2465Z"
fill="#C6E141"
stroke="#C6E141"
strokeWidth="2"
/>
),
viewBox: "0 0 8 10",
},
"submit-proposal": {
svg: (
<path
Expand Down
3 changes: 1 addition & 2 deletions src/lib/hooks/useLocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export const useLocalStorage = <T>(
const value = window.localStorage.getItem(key);
return value ? (JSON.parse(value) as T) : defaultValue;
} catch (e) {
console.warn(`Error reading localStorage key “${key}”:`, e);
return defaultValue as T;
}
});
Expand All @@ -22,7 +21,7 @@ export const useLocalStorage = <T>(
try {
window.localStorage.setItem(key, JSON.stringify(storedValue));
} catch (e) {
console.warn(`Error setting localStorage key “${key}”:`, e);
// I want application to not crush, but don't care about the message
}
}, [key, storedValue]);

Expand Down
57 changes: 46 additions & 11 deletions src/lib/layout/Searchbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ import {
useMobile,
} from "lib/app-provider";
import { CustomIcon } from "lib/components/icon";
import { PrimaryNameMark } from "lib/components/PrimaryNameMark";
import { AmpTrackUseMainSearch } from "lib/services/amplitude";
import type { SearchResultType } from "lib/services/searchService";
import type {
ResultMetadata,
SearchResultType,
} from "lib/services/searchService";
import { useSearchHandler } from "lib/services/searchService";
import type { Option } from "lib/types";

Expand All @@ -48,6 +52,7 @@ interface ResultItemProps {
type: SearchResultType;
value: string;
cursor: Option<number>;
metadata: ResultMetadata;
setCursor: (index: Option<number>) => void;
handleSelectResult: (type?: SearchResultType, isClick?: boolean) => void;
onClose?: () => void;
Expand Down Expand Up @@ -83,20 +88,20 @@ const ResultItem = ({
type,
value,
cursor,
metadata,
setCursor,
handleSelectResult,
onClose,
}: ResultItemProps) => {
const route = getRouteOptions(type)?.pathname;

return (
<StyledListItem id={`item-${index}`}>
<Text variant="body2" fontWeight={500} color="text.dark" p={2}>
{type}
</Text>
{route && (
<Text
variant="body2"
<Flex
direction="column"
p={2}
borderRadius="8px"
_hover={{ bg: "gray.800", cursor: "pointer" }}
Expand All @@ -109,8 +114,33 @@ const ResultItem = ({
onClose?.();
}}
>
{value}
</Text>
<Text variant="body2">{metadata.icns.address || value}</Text>
{metadata.icns.icnsNames?.primary_name && (
<Flex gap={1} align="center" flexWrap="wrap">
<Flex gap={1} align="center">
<PrimaryNameMark />
<Text variant="body3" color="text.dark">
{metadata.icns.icnsNames.primary_name}
</Text>
</Flex>
{value !== metadata.icns.address &&
value !== metadata.icns.icnsNames?.primary_name && (
<Text
variant="body3"
color="text.dark"
_before={{
content: '"/"',
fontSize: "12px",
color: "text.dark",
mr: 1,
}}
>
{value}
</Text>
)}
</Flex>
)}
</Flex>
)}
</StyledListItem>
);
Expand All @@ -120,13 +150,15 @@ const ResultRender = ({
results,
keyword,
cursor,
metadata,
setCursor,
handleSelectResult,
onClose,
}: {
results: SearchResultType[];
keyword: string;
cursor: Option<number>;
metadata: ResultMetadata;
setCursor: (index: Option<number>) => void;
handleSelectResult: (type?: SearchResultType, isClick?: boolean) => void;
onClose?: () => void;
Expand All @@ -146,6 +178,7 @@ const ResultRender = ({
type={type}
value={keyword}
cursor={cursor}
metadata={metadata}
setCursor={setCursor}
handleSelectResult={handleSelectResult}
onClose={onClose}
Expand Down Expand Up @@ -193,7 +226,7 @@ const Searchbar = () => {
},
} = useCelatoneApp();
const navigate = useInternalNavigate();
const { results, isLoading } = useSearchHandler(keyword, () =>
const { results, isLoading, metadata } = useSearchHandler(keyword, () =>
setIsTyping(false)
);
const boxRef = useRef<HTMLDivElement>(null);
Expand All @@ -213,13 +246,13 @@ const Searchbar = () => {
if (routeOptions) {
navigate({
pathname: routeOptions.pathname,
query: { [routeOptions.query]: keyword },
query: { [routeOptions.query]: metadata.icns.address || keyword },
});
setDisplayResults(false);
setKeyword("");
}
},
[keyword, navigate]
[metadata.icns.address, keyword, navigate]
);

const handleOnKeyEnter = useCallback(
Expand Down Expand Up @@ -313,6 +346,7 @@ const Searchbar = () => {
keyword={keyword}
handleSelectResult={handleSelectResult}
onClose={onClose}
metadata={metadata}
/>
)}
</List>
Expand Down Expand Up @@ -374,10 +408,11 @@ const Searchbar = () => {
</StyledListItem>
) : (
<ResultRender
cursor={cursor}
setCursor={setCursor}
results={results}
keyword={keyword}
cursor={cursor}
metadata={metadata}
setCursor={setCursor}
handleSelectResult={handleSelectResult}
/>
)}
Expand Down
90 changes: 90 additions & 0 deletions src/lib/pages/account-details/components/AccountHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Flex, Heading, Image, Text } from "@chakra-ui/react";

import { CopyLink } from "lib/components/CopyLink";
import { CustomIcon } from "lib/components/icon";
import { PrimaryNameMark } from "lib/components/PrimaryNameMark";
import type { ICNSNamesResponse } from "lib/services/ns";
import type { HumanAddr, Option, PublicDetail } from "lib/types";

interface AccounHeaderProps {
publicName: Option<string>;
publicDetail: Option<PublicDetail>;
icnsName: Option<ICNSNamesResponse>;
accountAddress: HumanAddr;
}

export const AccountHeader = ({
publicName,
publicDetail,
icnsName,
accountAddress,
}: AccounHeaderProps) => {
const displayName = icnsName?.primary_name || "Account Details";

return (
<Flex direction="column" gap={2}>
<Flex gap={1} minH="36px" align="center">
{publicDetail?.logo || icnsName?.primary_name ? (
<Image
src={
publicDetail?.logo ??
"https://celatone-api.alleslabs.dev/images/entities/icns"
}
borderRadius="full"
alt={publicDetail?.name ?? icnsName?.primary_name}
width={7}
height={7}
/>
) : (
<CustomIcon name="wallet" boxSize={5} color="secondary.main" />
)}
<Heading as="h5" variant={{ base: "h6", md: "h5" }}>
{publicName ?? displayName}
</Heading>
</Flex>
<Flex
gap={{ base: 0, md: 2 }}
mt={{ base: 1, md: 0 }}
direction={{ base: "column", md: "row" }}
>
<Text fontWeight={500} color="text.dark" variant="body2">
Wallet Address:
</Text>
<CopyLink
value={accountAddress}
amptrackSection="account_top"
type="user_address"
/>
</Flex>
{icnsName?.primary_name && (
<Flex gap={2} align="center">
<Text fontWeight={500} color="text.dark" variant="body2">
Registered ICNS names:
</Text>
<Flex gap={1} align="center">
{icnsName.names.map((name) => (
<div key={name}>
{name === icnsName.primary_name && <PrimaryNameMark />}
<CopyLink
value={name}
type="icns_names"
withoutIcon
_after={{
content: '"/"',
fontSize: "14px",
ml: 1,
}}
_last={{
_after: {
display: "none",
},
}}
/>
</div>
))}
</Flex>
</Flex>
)}
</Flex>
);
};
Loading

2 comments on commit bc89f47

@vercel
Copy link

@vercel vercel bot commented on bc89f47 Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on bc89f47 Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.