feat(meta): add update method to meta context

This commit is contained in:
shotgunofdeath 2021-09-16 14:50:42 +03:00
parent bf39727cc9
commit a2ff5f9fb2
3 changed files with 34 additions and 278 deletions

View File

@ -7,10 +7,13 @@ import { MetaContextState, MetaState } from './types';
import { useConnection } from '../connection';
import { useStore } from '../store';
import { useQuerySearch } from '../../hooks';
import { AuctionData, BidderMetadata, BidderPot } from "../../actions";
const MetaContext = React.createContext<MetaContextState>({
...getEmptyMetaState(),
isLoading: false,
// @ts-ignore
update: () => [AuctionData, BidderMetadata, BidderPot],
});
export function MetaProvider({ children = null as any }) {
@ -44,30 +47,41 @@ export function MetaProvider({ children = null as any }) {
[setState],
);
useEffect(() => {
(async () => {
if (!storeAddress) {
if (isReady) {
setIsLoading(false);
}
return;
} else if (!state.store) {
setIsLoading(true);
async function update(auctionAddress?: any, bidderAddress?: any) {
if (!storeAddress) {
if (isReady) {
setIsLoading(false);
}
return;
} else if (!state.store) {
setIsLoading(true);
}
console.log('-----> Query started');
console.log('-----> Query started');
const nextState = await loadAccounts(connection, all);
const nextState = await loadAccounts(connection, all);
console.log('loadAccounts', nextState);
console.log('------->Query finished');
console.log('------->Query finished');
setState(nextState);
setState(nextState);
setIsLoading(false);
console.log('------->set finished');
setIsLoading(false);
console.log('------->set finished');
await updateMints(nextState.metadataByMint);
updateMints(nextState.metadataByMint);
})();
if (auctionAddress && bidderAddress) {
const auctionBidderKey = auctionAddress + '-' + bidderAddress;
return [
nextState.auctions[auctionAddress],
nextState.bidderPotsByAuctionAndBidder[auctionBidderKey],
nextState.bidderMetadataByAuctionAndBidder[auctionBidderKey],
];
}
}
useEffect(() => {
update();
}, [connection, setState, updateMints, storeAddress, isReady]);
useEffect(() => {
@ -110,6 +124,8 @@ export function MetaProvider({ children = null as any }) {
<MetaContext.Provider
value={{
...state,
// @ts-ignore
update,
isLoading,
}}
>

View File

@ -259,7 +259,7 @@ export const AuctionCard = ({
(auctionView.isInstantSale &&
Number(auctionView.myBidderPot?.info.emptied) !== 0 &&
isAuctionManagerAuthorityNotWalletOwner &&
auctionView.auction.info.bidState.max.toNumber() === bids.length) ||
auctionView.auction.info.bidState.max.toNumber() === auctionView.auction.info.bidState.bids.length) ||
auctionView.vault.info.state === VaultState.Deactivated
) {
return <></>;

View File

@ -1,260 +0,0 @@
import {
useConnection,
useStore,
AUCTION_ID,
METAPLEX_ID,
VAULT_ID,
METADATA_PROGRAM_ID,
toPublicKey,
useQuerySearch,
AuctionData,
BidderPot,
BidderMetadata,
} from '@oyster/common';
import React, {
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { MetaState, MetaContextState, UpdateStateValueFunc } from './types';
import { queryExtendedMetadata } from './queryExtendedMetadata';
import { processAuctions } from './processAuctions';
import { processMetaplexAccounts } from './processMetaplexAccounts';
import { processMetaData } from './processMetaData';
import { processVaultData } from './processVaultData';
import {
loadAccounts,
makeSetter,
metadataByMintUpdater,
} from './loadAccounts';
import { onChangeAccount } from './onChangeAccount';
const MetaContext = React.createContext<MetaContextState>({
metadata: [],
metadataByMint: {},
masterEditions: {},
masterEditionsByPrintingMint: {},
masterEditionsByOneTimeAuthMint: {},
metadataByMasterEdition: {},
editions: {},
auctionManagersByAuction: {},
auctions: {},
auctionDataExtended: {},
vaults: {},
store: null,
isLoading: false,
bidderMetadataByAuctionAndBidder: {},
safetyDepositBoxesByVaultAndIndex: {},
safetyDepositConfigsByAuctionManagerAndIndex: {},
bidRedemptionV2sByAuctionManagerAndWinningIndex: {},
bidderPotsByAuctionAndBidder: {},
bidRedemptions: {},
whitelistedCreatorsByCreator: {},
payoutTickets: {},
prizeTrackingTickets: {},
stores: {},
// @ts-ignore
update: () => [AuctionData, BidderPot, BidderMetadata],
});
// eslint-disable-next-line react/prop-types
export function MetaProvider({ children = null as any }) {
const connection = useConnection();
const { isReady, storeAddress } = useStore();
const searchParams = useQuerySearch();
const all = searchParams.get('all') == 'true';
const [state, setState] = useState<MetaState>({
metadata: [],
metadataByMint: {},
masterEditions: {},
masterEditionsByPrintingMint: {},
masterEditionsByOneTimeAuthMint: {},
metadataByMasterEdition: {},
editions: {},
auctionManagersByAuction: {},
bidRedemptions: {},
auctions: {},
auctionDataExtended: {},
vaults: {},
payoutTickets: {},
store: null,
whitelistedCreatorsByCreator: {},
bidderMetadataByAuctionAndBidder: {},
bidderPotsByAuctionAndBidder: {},
safetyDepositBoxesByVaultAndIndex: {},
prizeTrackingTickets: {},
safetyDepositConfigsByAuctionManagerAndIndex: {},
bidRedemptionV2sByAuctionManagerAndWinningIndex: {},
stores: {},
});
const [isLoading, setIsLoading] = useState(true);
const updateMints = useCallback(
async metadataByMint => {
try {
if (!all) {
const { metadata, mintToMetadata } = await queryExtendedMetadata(
connection,
metadataByMint,
);
setState(current => ({
...current,
metadata,
metadataByMint: mintToMetadata,
}));
}
} catch (er) {
console.error(er);
}
},
[setState],
);
async function update(auctionAddress?, bidderAddress?) {
if (!storeAddress) {
if (isReady) {
setIsLoading(false);
}
return;
} else if (!state.store) {
setIsLoading(true);
}
console.log('-----> Query started');
const nextState = await loadAccounts(connection, all);
console.log('loadAccounts', nextState);
console.log('------->Query finished');
setState(nextState);
setIsLoading(false);
console.log('------->set finished');
await updateMints(nextState.metadataByMint);
if (auctionAddress && bidderAddress) {
const auctionBidderKey = auctionAddress + '-' + bidderAddress;
return [
nextState.auctions[auctionAddress],
nextState.bidderPotsByAuctionAndBidder[auctionBidderKey],
nextState.bidderMetadataByAuctionAndBidder[auctionBidderKey],
];
}
}
useEffect(() => {
update();
}, [connection, setState, updateMints, storeAddress, isReady]);
const updateStateValue = useMemo<UpdateStateValueFunc>(
() => (prop, key, value) => {
setState(current => makeSetter({ ...current })(prop, key, value));
},
[setState],
);
const store = state.store;
const whitelistedCreatorsByCreator = state.whitelistedCreatorsByCreator;
useEffect(() => {
if (isLoading) {
return;
}
const vaultSubId = connection.onProgramAccountChange(
toPublicKey(VAULT_ID),
onChangeAccount(processVaultData, updateStateValue, all),
);
const auctionSubId = connection.onProgramAccountChange(
toPublicKey(AUCTION_ID),
onChangeAccount(processAuctions, updateStateValue, all),
);
const metaplexSubId = connection.onProgramAccountChange(
toPublicKey(METAPLEX_ID),
onChangeAccount(processMetaplexAccounts, updateStateValue, all),
);
const metaSubId = connection.onProgramAccountChange(
toPublicKey(METADATA_PROGRAM_ID),
onChangeAccount(
processMetaData,
async (prop, key, value) => {
if (prop === 'metadataByMint') {
const nextState = await metadataByMintUpdater(value, state, all);
setState(nextState);
} else {
updateStateValue(prop, key, value);
}
},
all,
),
);
return () => {
connection.removeProgramAccountChangeListener(vaultSubId);
connection.removeProgramAccountChangeListener(metaplexSubId);
connection.removeProgramAccountChangeListener(metaSubId);
connection.removeProgramAccountChangeListener(auctionSubId);
};
}, [
connection,
updateStateValue,
setState,
store,
whitelistedCreatorsByCreator,
isLoading,
]);
// TODO: fetch names dynamically
// TODO: get names for creators
// useEffect(() => {
// (async () => {
// const twitterHandles = await connection.getProgramAccounts(NAME_PROGRAM_ID, {
// filters: [
// {
// dataSize: TWITTER_ACCOUNT_LENGTH,
// },
// {
// memcmp: {
// offset: VERIFICATION_AUTHORITY_OFFSET,
// bytes: TWITTER_VERIFICATION_AUTHORITY.toBase58()
// }
// }
// ]
// });
// const handles = twitterHandles.map(t => {
// const owner = new PublicKey(t.account.data.slice(32, 64));
// const name = t.account.data.slice(96, 114).toString();
// });
// console.log(handles);
// })();
// }, [whitelistedCreatorsByCreator]);
return (
<MetaContext.Provider
value={{
...state,
isLoading,
// @ts-ignore
update,
}}
>
{children}
</MetaContext.Provider>
);
}
export const useMeta = () => {
const context = useContext(MetaContext);
return context;
};