Skip to content

Commit

Permalink
😢 CRT followup 2 (#6073)
Browse files Browse the repository at this point in the history
* Fix ratio slider

* Switch from active to all queries

* Add link to powered by Joystream

* Minor fixes

* Crt marketplace table fixes

* Allow to start revenue share with amm active

* Remove default isVerified true

* Prevent amm slope tx failure

* Allow holder to stake vested tokens

* Encapsulate claim rev share logic inside single component

* Avoid safe integer bloat

* Revenue share related fixes

* Change vested to unlocked for HoldersWidget.tsx

* Add revenue share to payments table

* Add revenue share button for channels with token

* Fixes 02.04

* Block amm transactions during revenue share
  • Loading branch information
WRadoslaw committed Apr 5, 2024
1 parent de2ffcd commit 8f56df4
Show file tree
Hide file tree
Showing 55 changed files with 494 additions and 205 deletions.
2 changes: 1 addition & 1 deletion packages/atlas/src/api/hooks/dataObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const useDataObjectsAvailabilityLazy = (opts?: QueryHookOptions<GetDataOb

const _getDataObjectsAvailability = useCallback(
(ids: string[]) => {
getDataObjectsAvailability({
return getDataObjectsAvailability({
variables: {
id_in: ids,
},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions packages/atlas/src/api/queries/channels.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ query GetChannelPaymentEvents($channelId: String) {
}
}
{ data: { isTypeOf_in: ["ChannelPaymentMadeEventData"], payeeChannel: { id_eq: $channelId } } }
{
data: {
isTypeOf_in: ["CreatorTokenRevenueSplitIssuedEventData"]
token: { channel: { channel: { id_eq: $channelId } } }
}
}
]
}
) {
Expand Down Expand Up @@ -290,6 +296,25 @@ query GetChannelPaymentEvents($channelId: String) {
controllerAccount
}
}
... on CreatorTokenRevenueSplitIssuedEventData {
token {
id
revenueShareRatioPermill
}
revenueShare {
id
allocation
startingAt
stakers {
account {
member {
id
}
}
earnings
}
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/atlas/src/api/schemas/orion.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export const CrtPreviewLayout = ({
<HoldersWidget
totalSupply={+(token?.totalSupply ?? 0)}
totalHolders={token?.accountsNum ?? 0}
tokenSymbol={token?.symbol ?? ''}
tokenId={token?.id ?? '-1'}
ownerId={memberId ?? ''}
/>
Expand Down
6 changes: 6 additions & 0 deletions packages/atlas/src/components/Table/Table.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import { cVar, sizes } from '@/styles'
export const Wrapper = styled.div`
background-color: ${cVar('colorBackgroundMuted')};
overflow: auto;
* {
.pointer {
cursor: pointer;
}
}
`

export const TableBase = styled.table`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { TextButton } from '@/components/_buttons/Button'
import { DialogModal } from '@/components/_overlays/DialogModal'
import { absoluteRoutes } from '@/config/routes'
import { getMemberAvatar } from '@/providers/assets/assets.helpers'
import { useUser } from '@/providers/user/user.hooks'
import { SentryLogger } from '@/utils/logs'
import { shortenString } from '@/utils/misc'

Expand Down Expand Up @@ -112,6 +113,7 @@ const Sender = ({ sender }: { sender: PaymentHistory['sender'] }) => {
skip: sender === 'council',
}
)
const { activeChannel } = useUser()
const member = memberships?.find((member) => member.controllerAccount === sender)
const { urls: avatarUrls, isLoadingAsset: avatarLoading } = getMemberAvatar(member)

Expand All @@ -128,6 +130,17 @@ const Sender = ({ sender }: { sender: PaymentHistory['sender'] }) => {
/>
)
}

if (sender === 'own-channel') {
return (
<SenderItem
nodeStart={<Avatar assetUrls={activeChannel?.avatarPhoto?.resolvedUrls} size={32} />}
label="Own channel"
isInteractive={false}
/>
)
}

if (member) {
return (
<StyledLink to={absoluteRoutes.viewer.member(member.handle)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const AllTokensSection = () => {
createdAt: new Date(createdAt),
totalRevenue: 0,
holdersNum: accountsNum,
isVerified: true,
isVerified: false,
marketCap: lastPrice && totalSupply ? hapiBnToTokenNumber(new BN(lastPrice).mul(new BN(totalSupply))) ?? 0 : 0,
status,
channelId: channel?.channel.id ?? '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type AmmModalFormTemplateProps = {
tooltipText?: string
}[]
error?: string
maxInputValue?: number
showTresholdButtons?: boolean
}

Expand All @@ -31,6 +32,7 @@ export const AmmModalFormTemplate = ({
control,
error,
showTresholdButtons,
maxInputValue,
}: AmmModalFormTemplateProps) => {
const { convertTokensToUSD } = useTokenPrice()

Expand All @@ -52,6 +54,7 @@ export const AmmModalFormTemplate = ({
value={field.value}
onChange={(value) => field.onChange(value ? Math.round(value) : value)}
placeholder="0"
maxValue={maxInputValue}
nodeEnd={
pricePerUnit ? (
<Text variant="t300" as="p" color="colorTextMuted">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState } from 'react'

import { ProtectedActionWrapper } from '@/components/_auth/ProtectedActionWrapper'
import { Button } from '@/components/_buttons/Button'
import { BuyMarketTokenModal } from '@/components/_crt/BuyMarketTokenModal'

Expand All @@ -12,9 +13,11 @@ export const BuyFromMarketButton = ({ tokenId }: BuyFromMarketButtonProps) => {
return (
<>
<BuyMarketTokenModal tokenId={tokenId} show={showModal} onClose={() => setShowModal(false)} />
<Button size="large" onClick={() => setShowModal(true)}>
Buy
</Button>
<ProtectedActionWrapper title="You want to buy tokens?" description="Sign in to buy">
<Button size="large" fullWidth onClick={() => setShowModal(true)}>
Buy
</Button>
</ProtectedActionWrapper>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const BuyMarketTokenModal = ({ tokenId, onClose: _onClose, show }: BuySal
SentryLogger.error('Error while fetching creator token', 'BuyMarketTokenModal', error)
},
})
const hasActiveRevenueShare = data?.creatorTokenById?.revenueShares.some((rS) => !rS.finalized)
const { data: memberTokenAccount } = useGetCreatorTokenHoldersQuery({
variables: {
where: {
Expand Down Expand Up @@ -185,7 +186,7 @@ export const BuyMarketTokenModal = ({ tokenId, onClose: _onClose, show }: BuySal
} else {
setActiveStep(BUY_MARKET_TOKEN_STEPS.success)
}
client.refetchQueries({ include: 'active' })
client.refetchQueries({ include: 'all' })
},
onError: () => {
setActiveStep(BUY_MARKET_TOKEN_STEPS.form)
Expand Down Expand Up @@ -296,7 +297,8 @@ export const BuyMarketTokenModal = ({ tokenId, onClose: _onClose, show }: BuySal
withDenomination="before"
/>
),
tooltipText: 'Price for a single token divided by the token amount.',
tooltipText:
'Price of each incremental unit purchased or sold depends on overall quantity of tokens transacted, the actual average price per unit for the entire purchase or sale will differ from the price displayed for the first unit transacted.',
},
{
title: 'Fee',
Expand Down Expand Up @@ -338,11 +340,19 @@ export const BuyMarketTokenModal = ({ tokenId, onClose: _onClose, show }: BuySal
if (activeStep === BUY_MARKET_TOKEN_STEPS.form) {
setPrimaryButtonProps({
text: 'Continue',
onClick: () =>
onClick: () => {
if (hasActiveRevenueShare) {
displaySnackbar({
iconType: 'error',
title: 'You cannot trade tokens during revenue share.',
})
return
}
handleSubmit((data) => {
amountRef.current = data.tokenAmount
setActiveStep(BUY_MARKET_TOKEN_STEPS.conditions)
})(),
})()
},
})
}

Expand All @@ -352,7 +362,14 @@ export const BuyMarketTokenModal = ({ tokenId, onClose: _onClose, show }: BuySal
onClick: onTransactionSubmit,
})
}
}, [activeStep, data?.creatorTokenById?.symbol, handleSubmit, onTransactionSubmit])
}, [
activeStep,
data?.creatorTokenById?.symbol,
displaySnackbar,
handleSubmit,
hasActiveRevenueShare,
onTransactionSubmit,
])

if (!loading && !currentAmm && show) {
SentryLogger.error('BuyAmmModal invoked on token without active amm', 'BuyMarketTokenModal', {
Expand Down Expand Up @@ -380,7 +397,7 @@ export const BuyMarketTokenModal = ({ tokenId, onClose: _onClose, show }: BuySal
control={control}
details={formDetails}
pricePerUnit={pricePerUnit}
maxValue={10_000_000_000}
maxInputValue={10_000_000}
error={formState.errors.tokenAmount?.message}
validation={(value) => {
if (!value || value < 1) return 'You need to buy at least one token'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useState } from 'react'

import { FullCreatorTokenFragment } from '@/api/queries/__generated__/fragments.generated'
import { Button, ButtonProps } from '@/components/_buttons/Button'
import { ClaimShareModal } from '@/components/_crt/ClaimShareModal'
import { useSnackbar } from '@/providers/snackbars'

export type ClaimRevenueShareButtonProps = {
token: FullCreatorTokenFragment
disabled?: boolean
} & Pick<ButtonProps, 'variant' | 'size' | 'fullWidth'>

export const ClaimRevenueShareButton = ({ token, ...btnProps }: ClaimRevenueShareButtonProps) => {
const [openClaimShareModal, setOpenClaimShareModal] = useState(false)
const { displaySnackbar } = useSnackbar()
const hasActiveRevenueShare = token.revenueShares.some((revenueShare) => !revenueShare.finalized)

return (
<>
<Button
{...btnProps}
onClick={() => {
if (!hasActiveRevenueShare) {
displaySnackbar({
iconType: 'info',
title: 'No active revenue share to claim',
})
return
}

setOpenClaimShareModal(true)
}}
>
Stake your tokens
</Button>
<ClaimShareModal onClose={() => setOpenClaimShareModal(false)} show={openClaimShareModal} tokenId={token.id} />
</>
)
}
Loading

0 comments on commit 8f56df4

Please sign in to comment.