Skip to content

Commit

Permalink
feat: child bounty accept curator #4784 (#4809)
Browse files Browse the repository at this point in the history
* balance field support props.disabled

* stash

* use post state

* confirmed the state must be `CuratorProposed`

* fix, only curator can see this button

* move [skip ci]

* safe tx func return

* remove redundant prop.isLoading [skip ci]

* fix: get curator data from subscribed data

* fix username

* fix: if not the curator, disabled and show tooltip

* fix status

* refactor: read curator value syntax

* add result.isNone [skip ci]

* rename showpopup fn
  • Loading branch information
2nthony authored Sep 30, 2024
1 parent 30b2cd7 commit 3bff514
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 32 deletions.
3 changes: 2 additions & 1 deletion packages/next-common/components/popup/fields/balanceField.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default function BalanceField({
symbol,
title = "Balance",
titleTooltip = "",
disabled = false,
}) {
const node = useChainSettings();
return (
Expand All @@ -18,7 +19,7 @@ export default function BalanceField({
<Input
type="text"
placeholder="0.00"
disabled={isLoading}
disabled={isLoading || disabled}
value={inputBalance}
onChange={(e) => setInputBalance(e.target.value.replace("。", "."))}
symbol={symbol || node.symbol}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useOnchainData } from "next-common/context/post";
import useSubStorage from "next-common/hooks/common/useSubStorage";
import PrimaryButton from "next-common/lib/button/primary";
import useRealAddress from "next-common/utils/hooks/useRealAddress";
import { useAcceptCuratorPopup } from "./useAcceptCuratorPopup";
import Tooltip from "next-common/components/tooltip";
import { isSameAddress } from "next-common/utils";
import AddressUser from "next-common/components/user/addressUser";

export default function ChildBountyAcceptCurator() {
const address = useRealAddress();
const onchainData = useOnchainData();
const { parentBountyId, index: childBountyId } = onchainData;
const { showPopupFn, component } = useAcceptCuratorPopup();

const { result, loading } = useSubStorage("childBounties", "childBounties", [
parentBountyId,
childBountyId,
]);

if (loading || result.isNone) {
return null;
}

const { status } = result.unwrap();

if (!status.isCuratorProposed) {
return null;
}

const curator = status.asCuratorProposed.curator.toString();

const disabled = !isSameAddress(curator, address);

return (
<Tooltip
content={
disabled ? (
<div className="flex items-center gap-x-2">
Only{" "}
<AddressUser
addressClassName="!text-textPrimaryContrast"
add={curator}
noEvent
/>
can accept curator
</div>
) : null
}
>
<PrimaryButton
disabled={disabled}
className="w-full"
onClick={() => {
showPopupFn();
}}
>
Accept Curator
</PrimaryButton>

{component}
</Tooltip>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import TxSubmissionButton from "next-common/components/common/tx/txSubmissionButton";
import BalanceField from "next-common/components/popup/fields/balanceField";
import Signer from "next-common/components/popup/fields/signerField";
import PopupWithSigner from "next-common/components/popupWithSigner";
import { usePopupParams } from "next-common/components/popupWithSigner/context";
import { useContextApi } from "next-common/context/api";
import { useChainSettings } from "next-common/context/chain";
import { useOnchainData } from "next-common/context/post";
import { useSubBalanceInfo } from "next-common/hooks/balance/useSubBalanceInfo";
import { toPrecision } from "next-common/utils";
import useRealAddress from "next-common/utils/hooks/useRealAddress";
import { useCallback, useState } from "react";

export function useAcceptCuratorPopup() {
const [isOpen, setIsOpen] = useState(false);

const component = isOpen && (
<AcceptCuratorPopup
onClose={() => {
setIsOpen(false);
}}
/>
);

return {
component,
showPopupFn() {
setIsOpen(true);
},
};
}

function PopupContent() {
const onchainData = useOnchainData();
const { symbol, decimals } = useChainSettings();
const { parentBountyId, index: childBountyId, meta } = onchainData;
const { curatorDeposit } = meta || {};
const { onClose } = usePopupParams();
const api = useContextApi();
const address = useRealAddress();
const { value: balance, loading } = useSubBalanceInfo(address);

const getTxFunc = useCallback(() => {
if (!api?.tx?.childBounties) {
return null;
}

return api.tx.childBounties.acceptCurator(parentBountyId, childBountyId);
}, [api, childBountyId, parentBountyId]);

return (
<>
<Signer
balanceName="Available"
signerBalance={balance?.balance}
isSignerBalanceLoading={loading}
/>
<BalanceField
title="Curator Deposit"
disabled
inputBalance={toPrecision(curatorDeposit, decimals)}
symbol={symbol}
/>
<div className="flex justify-end">
<TxSubmissionButton
title="Confirm"
getTxFunc={getTxFunc}
onClose={onClose}
/>
</div>
</>
);
}

function AcceptCuratorPopup(props) {
return (
<PopupWithSigner title="Accept Curator" className="!w-[640px]" {...props}>
<PopupContent />
</PopupWithSigner>
);
}
44 changes: 13 additions & 31 deletions packages/next-common/components/user/username.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,4 @@
import styled, { css } from "styled-components";

const Wrapper = styled.div`
font-weight: 500;
font-size: ${(props) => props.fontSize}px;
${(p) =>
p.color
? css`
color: ${p.color} !important;
`
: css`
color: var(--textPrimary) !important;
`}
${(p) =>
p.maxWidth
? css`
max-width: ${p.maxWidth}px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`
: css`
word-break: break-all;
`}
`;
import { cn } from "next-common/utils";

export default function Username({
username,
Expand All @@ -32,13 +8,19 @@ export default function Username({
addressClassName = "",
}) {
return (
<Wrapper
fontSize={fontSize}
maxWidth={maxWidth}
color={color}
className={addressClassName}
<div
className={cn(
"text14Medium !text-textPrimary",
maxWidth ? "truncate" : "break-all",
addressClassName,
)}
style={{
fontSize,
maxWidth,
color,
}}
>
{username}
</Wrapper>
</div>
);
}
2 changes: 2 additions & 0 deletions packages/next/components/childBounty/sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Meta from "next-common/components/treasury/childBounty/metadata";
import { RightBarWrapper } from "next-common/components/layout/sidebar/rightBarWrapper";
import { usePostState } from "next-common/context/post";
import ChildBountySidebarBalance from "next-common/components/treasury/childBounty/balance";
import ChildBountyAcceptCurator from "next-common/components/treasury/childBounty/acceptCurator";

export default function ChildBountySidebar() {
const state = usePostState();
Expand All @@ -11,6 +12,7 @@ export default function ChildBountySidebar() {
return (
<RightBarWrapper>
<ChildBountySidebarBalance />
<ChildBountyAcceptCurator />
{isClaimable && (
<>
<Meta />
Expand Down

0 comments on commit 3bff514

Please sign in to comment.