Skip to content

Commit

Permalink
Merge pull request #2407 from decentdao/release/v0.3.6
Browse files Browse the repository at this point in the history
Release/v0.3.6
  • Loading branch information
adamgall authored Oct 11, 2024
2 parents eba7c44 + 462eb7d commit 8b09947
Show file tree
Hide file tree
Showing 25 changed files with 225 additions and 128 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ VITE_APP_SITE_URL="https://app.dev.decentdao.org"
VITE_APP_WALLET_CONNECT_PROJECT_ID=""

# FEATURE FLAGS (Must equal "ON")
VITE_APP_FLAG_STREAMS=""
VITE_APP_FLAG_DEVELOPMENT_MODE=""
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "decent-interface",
"version": "0.3.5",
"version": "0.3.6",
"private": true,
"dependencies": {
"@amplitude/analytics-browser": "^2.11.1",
Expand Down
2 changes: 1 addition & 1 deletion src/components/DaoCreator/formComponents/GuardDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ function GuardDetails(props: ICreationStepProps) {
<BigIntInput
isInvalid={!!errors?.freeze?.freezeVotesThreshold?.bigintValue}
value={field.value?.bigintValue}
currentValue={values.freeze.freezeVotesThreshold}
parentFormikValue={values.freeze.freezeVotesThreshold}
onChange={valuePair => {
setFieldValue('freeze.freezeVotesThreshold', valuePair);
}}
Expand Down
6 changes: 2 additions & 4 deletions src/components/pages/Roles/RoleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { CaretCircleRight, CaretRight } from '@phosphor-icons/react';
import { formatDuration, intervalToDuration } from 'date-fns';
import { useTranslation } from 'react-i18next';
import { getAddress, zeroAddress } from 'viem';
import { isFeatureEnabled } from '../../../constants/common';
import { useGetDAOName } from '../../../hooks/DAO/useGetDAOName';
import useAvatar from '../../../hooks/utils/useAvatar';
import { useNetworkConfig } from '../../../providers/NetworkConfig/NetworkConfigProvider';
Expand Down Expand Up @@ -62,7 +61,7 @@ export function AvatarAndRoleName({
>
{wearerAddress ? accountDisplayName : t('unassigned')}
</Text>
{isFeatureEnabled('STREAMS') && paymentsCount !== undefined && (
{paymentsCount !== undefined && (
<Flex
mt="1rem"
gap="0.25rem"
Expand Down Expand Up @@ -234,8 +233,7 @@ export function RoleCardEdit({
/>
</Flex>
</Flex>
{isFeatureEnabled('STREAMS') &&
payments &&
{payments &&
payments.map((payment, index) => (
<Payment
key={index}
Expand Down
4 changes: 2 additions & 2 deletions src/components/pages/Roles/RolesDetailsDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { List, PencilLine, User, X } from '@phosphor-icons/react';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Hex, getAddress } from 'viem';
import { BACKGROUND_SEMI_TRANSPARENT, isFeatureEnabled } from '../../../constants/common';
import { BACKGROUND_SEMI_TRANSPARENT } from '../../../constants/common';
import { useGetDAOName } from '../../../hooks/DAO/useGetDAOName';
import useAvatar from '../../../hooks/utils/useAvatar';
import { useFractal } from '../../../providers/App/AppProvider';
Expand Down Expand Up @@ -178,7 +178,7 @@ export default function RolesDetailsDrawer({
</Text>
</GridItem>
</Grid>
{isFeatureEnabled('STREAMS') && roleHat.payments && (
{roleHat.payments && (
<>
<Divider
variant="darker"
Expand Down
3 changes: 1 addition & 2 deletions src/components/pages/Roles/RolesDetailsDrawerMobile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { PencilLine } from '@phosphor-icons/react';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { getAddress, Hex } from 'viem';
import { isFeatureEnabled } from '../../../constants/common';
import { useFractal } from '../../../providers/App/AppProvider';
import {
paymentSorterByActiveStatus,
Expand Down Expand Up @@ -103,7 +102,7 @@ export default function RolesDetailsDrawerMobile({
px="1rem"
mb="1.5rem"
>
{isFeatureEnabled('STREAMS') && roleHat.payments && (
{roleHat.payments && (
<>
<Divider
variant="darker"
Expand Down
25 changes: 9 additions & 16 deletions src/components/pages/Roles/RolesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { PencilLine } from '@phosphor-icons/react';
import { useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
import { Address, Hex, zeroAddress } from 'viem';
import { isFeatureEnabled } from '../../../constants/common';
import useAddress from '../../../hooks/utils/useAddress';
import useAvatar from '../../../hooks/utils/useAvatar';
import useDisplayName from '../../../hooks/utils/useDisplayName';
Expand Down Expand Up @@ -39,15 +38,13 @@ function RolesHeader() {
{t('role')}
</Th>
<Th width="60%">{t('member')}</Th>
{isFeatureEnabled('STREAMS') && (
<Th
width="15%"
minWidth="140px"
textAlign="center"
>
{t('activePayments')}
</Th>
)}
<Th
width="15%"
minWidth="140px"
textAlign="center"
>
{t('activePayments')}
</Th>
</Tr>
</Thead>
);
Expand Down Expand Up @@ -195,7 +192,7 @@ export function RolesRow({
{name}
</Td>
<MemberColumn wearerAddress={wearerAddress} />
{isFeatureEnabled('STREAMS') && <PaymentsColumn paymentsCount={paymentsCount} />}
<PaymentsColumn paymentsCount={paymentsCount} />
</Tr>
);
}
Expand Down Expand Up @@ -227,11 +224,7 @@ export function RolesRowEdit({
editStatus={editStatus}
/>
<MemberColumn wearerAddress={wearerAddress} />
{isFeatureEnabled('STREAMS') && (
<PaymentsColumn
paymentsCount={payments?.filter(p => p.isStreaming()).length || undefined}
/>
)}
<PaymentsColumn paymentsCount={payments?.filter(p => p.isStreaming()).length || undefined} />
</Tr>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/components/pages/Roles/forms/RoleFormAssetSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ export function AssetSelector({ formIndex, disabled }: { formIndex: number; disa
<BigIntInput
isDisabled={inputDisabled}
value={field.value?.bigintValue}
parentFormikValue={values?.roleEditing?.payments?.[formIndex]?.amount}
onChange={valuePair => {
setFieldValue(field.name, valuePair, true);
}}
Expand Down
24 changes: 22 additions & 2 deletions src/components/pages/Roles/forms/RoleFormPaymentStream.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Alert, Box, Button, Flex, FormControl, Icon, Show, Text } from '@chakra-ui/react';
import { ArrowRight, Info, Trash } from '@phosphor-icons/react';
import { addDays } from 'date-fns';
import { addDays, addMinutes } from 'date-fns';
import { FormikErrors, useFormikContext } from 'formik';
import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { CARD_SHADOW } from '../../../../constants/common';
import { CARD_SHADOW, isDevMode } from '../../../../constants/common';
import { useRolesStore } from '../../../../store/roles';
import { BigIntValuePair } from '../../../../types';
import { ModalType } from '../../../ui/modals/ModalProvider';
import { useDecentModal } from '../../../ui/modals/useDecentModal';
import { DecentDatePicker } from '../../../ui/utils/DecentDatePicker';
Expand Down Expand Up @@ -201,6 +202,25 @@ export default function RoleFormPaymentStream({ formIndex }: { formIndex: number
{t('save')}
</Button>
)}
{isDevMode() && (
<Button
onClick={() => {
const nowDate = new Date();
setFieldValue(`roleEditing.payments[${formIndex}]`, {
...payment,
amount: {
value: '100',
bigintValue: 100000000000000000000n,
} as BigIntValuePair,
decimals: 18,
startDate: addMinutes(nowDate, 1),
endDate: addMinutes(nowDate, 10),
});
}}
>
Ze stream ends in 10!
</Button>
)}
{canBeCancelled && (
<Show above="md">
<Button
Expand Down
11 changes: 4 additions & 7 deletions src/components/pages/Roles/forms/RoleFormTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Blocker, useNavigate } from 'react-router-dom';
import { Hex } from 'viem';
import { isFeatureEnabled } from '../../../../constants/common';
import { DAO_ROUTES } from '../../../../constants/routes';
import { useFractal } from '../../../../providers/App/AppProvider';
import { useNetworkConfig } from '../../../../providers/NetworkConfig/NetworkConfigProvider';
Expand Down Expand Up @@ -67,17 +66,15 @@ export default function RoleFormTabs({
<Tabs variant="twoTone">
<TabList>
<Tab>{t('roleInfo')}</Tab>
{isFeatureEnabled('STREAMS') && <Tab>{t('payments')}</Tab>}
<Tab>{t('payments')}</Tab>
</TabList>
<TabPanels my="1.75rem">
<TabPanel>
<RoleFormInfo />
</TabPanel>
{isFeatureEnabled('STREAMS') && (
<TabPanel>
<RoleFormPaymentStreams />
</TabPanel>
)}
<TabPanel>
<RoleFormPaymentStreams />
</TabPanel>
</TabPanels>
</Tabs>
<Flex
Expand Down
29 changes: 21 additions & 8 deletions src/components/ui/forms/BigIntInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,30 @@ export interface BigIntInputProps
min?: string;
max?: string;
maxValue?: bigint;
currentValue?: BigIntValuePair;
parentFormikValue?: BigIntValuePair;
}
/**
* This component will add a chakra Input component that accepts and sets a bigint
*
* @param value input value to the control as a bigint. If undefined is set then the component will be blank.
* @param onChange event is raised whenever the component changes. Sends back a value / bigint pair. The value sent back is a string representation of the bigint as a decimal number.
* @param onChange event is raised whenever the component changes. Sends back a resulting `BigIntValuePair` from the new input.
* @param decimalPlaces number of decimal places to be used to parse the value to set the bigint
* @param min Setting a minimum value will reset the Input value to min when the component's focus is lost. Can set decimal number for minimum, but must respect the decimalPlaces value.
* @param max Setting this will cause the value of the Input control to be reset to the maximum when a number larger than it is inputted.
* @param maxValue The maximum value that can be inputted. This is used to set the max value of the Input control.
* @param currentValue This needs to be set to `values.yourFormValue` if the value of the Input control is changed outside of the component, for example via `setFieldValue`. This will update the value of the underlying Input control.
* @param parentFormikValue This needs to be set to `values.yourFormValue` if the value of the Input control is changed outside of the component, for example via `setFieldValue`. This will update the value of the underlying Input control.
* @param ...rest component accepts all properties for Input and FormControl
* @returns
*/
export function BigIntInput({
// @todo `value` can most likely either be removed, or be used for what `parentFormikValue` is currently being used for. Currently it works as nothing more than an initial value.
value,
onChange,
decimalPlaces = 18,
min,
max,
maxValue,
currentValue,
parentFormikValue = { value: '', bigintValue: undefined },
...rest
}: BigIntInputProps) {
const { t } = useTranslation('common');
Expand Down Expand Up @@ -147,10 +148,22 @@ export function BigIntInput({

// if the parent Formik value prop changes, need to update the value
useEffect(() => {
if (!inputValue || inputValue === currentValue?.value) return;
if (currentValue?.bigintValue === 0n) setInputValue('');
if (currentValue?.value !== inputValue) setInputValue(currentValue?.value || inputValue);
}, [currentValue, inputValue]);
// If parentFormikValue is set to undefined, then the input should be blank
if (parentFormikValue === undefined) {
setInputValue('');
return;
}

// If parentFormikValue is the same as the input value, nothing needs to happen.
if (inputValue === parentFormikValue.value) return;

// If parentFormikValue does not match the input value (likely because it was set outside of the input's onChange handler),
// then update the underlying input value so that the change is visible on the UI.
// But if parentFormikValue.value is false-y, default to whatever is in the input.
if (parentFormikValue.value !== inputValue) {
setInputValue(parentFormikValue?.value || inputValue);
}
}, [parentFormikValue, inputValue]);

// if the decimalPlaces change, need to update the value
useEffect(() => {
Expand Down
6 changes: 6 additions & 0 deletions src/components/ui/forms/EthAddressInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function AddressInput({ value, onChange, ...rest }: InputProps) {
const [localValue, setLocalValue] = useState<string | number | readonly string[] | undefined>(
value,
);

const debounceValue = useMemo(
() =>
debounce((event: ChangeEvent<HTMLInputElement>) => {
Expand All @@ -24,13 +25,18 @@ export function AddressInput({ value, onChange, ...rest }: InputProps) {
};
}, [debounceValue]);

useEffect(() => {
setLocalValue(value);
}, [value]);

const handleChange = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
debounceValue(event);
setLocalValue(event.target.value);
},
[debounceValue],
);

return (
<Input
// preface id with "search" to prevent showing 1password
Expand Down
5 changes: 3 additions & 2 deletions src/components/ui/modals/SendAssetsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ export function SendAssetsModal({
iconSize="1.5rem"
icon={<CaretDown />}
onChange={e => {
setFieldValue('inputAmount', { value: '0', bigintValue: 0n });
// New asset selected. First reset the form input amount
setFieldValue('inputAmount', undefined);
setFieldValue(
'selectedAsset',
fungibleAssetsWithBalance[Number(e.target.value)],
Expand Down Expand Up @@ -169,7 +170,7 @@ export function SendAssetsModal({
onChange={value => {
setFieldValue('inputAmount', value);
}}
currentValue={values.inputAmount}
parentFormikValue={values.inputAmount}
decimalPlaces={values.selectedAsset.decimals}
placeholder="0"
maxValue={BigInt(values.selectedAsset.balance)}
Expand Down
10 changes: 9 additions & 1 deletion src/constants/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ export const SIDEBAR_WIDTH = '4.25rem';

export const MAX_CONTENT_WIDTH = '80rem';

export const isFeatureEnabled = (feature: string) => {
const features = {
developmentMode: 'DEVELOPMENT_MODE',
} as const;

type FeatureFlag = (typeof features)[keyof typeof features];

export const isFeatureEnabled = (feature: FeatureFlag) => {
const featureStatus = import.meta.env[`VITE_APP_FLAG_${feature}`];
if (featureStatus === 'ON') {
return true;
Expand All @@ -62,6 +68,8 @@ export const isFeatureEnabled = (feature: string) => {
}
};

export const isDevMode = () => isFeatureEnabled(features.developmentMode);

/**
* @dev DO NOT CHANGE THE SALT
* @note This SALT is used to generate the account address for the Hats Smart Account
Expand Down
5 changes: 4 additions & 1 deletion src/hooks/DAO/loaders/governance/useERC20Claim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ export function useERC20Claim() {
.ERC20ClaimCreated({ fromBlock: 0n })
.catch(() => []);

if (!tokenClaimArray.length) return;

const childToken = tokenClaimArray[0].args.childToken;

if (!tokenClaimArray.length || !childToken || childToken === votesTokenAddress) {
if (!childToken || childToken === votesTokenAddress) {
return;
}

// action to governance
action.dispatch({
type: FractalGovernanceAction.SET_CLAIMING_CONTRACT,
Expand Down
Loading

0 comments on commit 8b09947

Please sign in to comment.