From dca99732221b2565362c1d552b2ba7d0ec2f117c Mon Sep 17 00:00:00 2001 From: roiLeo Date: Wed, 23 Oct 2024 12:01:49 +0200 Subject: [PATCH 01/87] =?UTF-8?q?=E2=9C=A8=20swap=20page=20landing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/svg/arrows.svg | 19 ++++++++++ components/swap/landing.vue | 68 +++++++++++++++++++++++++++++++++++ locales/en.json | 8 +++++ pages/[prefix]/swap/index.vue | 18 ++++++++++ 4 files changed, 113 insertions(+) create mode 100644 assets/svg/arrows.svg create mode 100644 components/swap/landing.vue create mode 100644 pages/[prefix]/swap/index.vue diff --git a/assets/svg/arrows.svg b/assets/svg/arrows.svg new file mode 100644 index 0000000000..10a3492e44 --- /dev/null +++ b/assets/svg/arrows.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/components/swap/landing.vue b/components/swap/landing.vue new file mode 100644 index 0000000000..4b5802cbe5 --- /dev/null +++ b/components/swap/landing.vue @@ -0,0 +1,68 @@ + + + diff --git a/locales/en.json b/locales/en.json index 61277caac1..a6e83b2fd8 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1787,6 +1787,14 @@ "support": { "tooltip": "Cover costs mean that users help to support initial costs for Koda which stores your JPEG on your behalf." }, + "swap": { + "beginSwap": "Begin Swap offer", + "connectTrader": "Connect with a trader", + "connectTraderInfo": "Enter the wallet address of the trader you want to engage with, and we’ll guide you through the secure process of making a swap offer.", + "landingSubtitle": "Koda Swap facilitates secure and straightforward exchanges of digital assets. Connect directly with traders and confidently navigate your NFT transactions with our reliable platform.", + "landingTitle": "Koda Swap", + "learnMoreAboutSwaps": "Learn more about swaps" + }, "tabs": { "activity": "Activity", "chart": "Chart", diff --git a/pages/[prefix]/swap/index.vue b/pages/[prefix]/swap/index.vue new file mode 100644 index 0000000000..ef7a323847 --- /dev/null +++ b/pages/[prefix]/swap/index.vue @@ -0,0 +1,18 @@ + + + From 2d4c882bfb2dd0ba1ef187abb40c4fd71f8f731e Mon Sep 17 00:00:00 2001 From: roiLeo Date: Wed, 23 Oct 2024 14:24:33 +0200 Subject: [PATCH 02/87] =?UTF-8?q?=E2=9C=A8=20wip:=20swap=20page=20Step=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/swap/DestinationProfile.vue | 45 ++++++++++++++++++++++++++ components/swap/landing.vue | 11 ++++--- pages/[prefix]/swap/[id].vue | 9 ++++++ 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 components/swap/DestinationProfile.vue create mode 100644 pages/[prefix]/swap/[id].vue diff --git a/components/swap/DestinationProfile.vue b/components/swap/DestinationProfile.vue new file mode 100644 index 0000000000..d7e3dee3e2 --- /dev/null +++ b/components/swap/DestinationProfile.vue @@ -0,0 +1,45 @@ + + + diff --git a/components/swap/landing.vue b/components/swap/landing.vue index 4b5802cbe5..1648eaafeb 100644 --- a/components/swap/landing.vue +++ b/components/swap/landing.vue @@ -34,7 +34,7 @@

-
+ @@ -60,9 +60,12 @@ diff --git a/pages/[prefix]/swap/[id].vue b/pages/[prefix]/swap/[id].vue new file mode 100644 index 0000000000..5cfb562e5c --- /dev/null +++ b/pages/[prefix]/swap/[id].vue @@ -0,0 +1,9 @@ + + + From ca6665512f52e0be3ec54365dcc52f963416c596 Mon Sep 17 00:00:00 2001 From: roiLeo Date: Thu, 24 Oct 2024 10:57:59 +0200 Subject: [PATCH 03/87] =?UTF-8?q?=E2=9C=A8=20wip:=20swap=20page=20Step=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/swap/DestinationProfile.vue | 23 ++++++++++++++++++----- components/swap/landing.vue | 1 + locales/en.json | 6 +++++- middleware/redirects.global.ts | 3 ++- utils/config/permission.config.ts | 4 ++++ 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/components/swap/DestinationProfile.vue b/components/swap/DestinationProfile.vue index d7e3dee3e2..3d8b60cd44 100644 --- a/components/swap/DestinationProfile.vue +++ b/components/swap/DestinationProfile.vue @@ -3,17 +3,17 @@

- Select their NFTs for the Swap + {{ $t('swap.selectNft') }}

- Click on any NFT to add it to your swap list. + {{ $t('swap.clickOnNft') }}

- Your Address + {{ $t('swap.yourAddress') }}
@@ -26,14 +26,27 @@
- Counterparty + {{ $t('swap.counterparty') }}
-
+
+
+
+
+
+
+
+
+ Your Swap List +
+
+
+
+
diff --git a/components/swap/landing.vue b/components/swap/landing.vue index 1648eaafeb..23bef6e2cd 100644 --- a/components/swap/landing.vue +++ b/components/swap/landing.vue @@ -40,6 +40,7 @@ placeholder="Enter wallet address" :strict="false" empty-on-error + with-address-check /> { const { urlPrefix } = usePrefix() @@ -51,6 +51,7 @@ export default defineNuxtRouteMiddleware((route) => { }, getPermissionRouteCondition((val: string) => val === `/${urlPrefix.value}/teleport`, teleportVisible), getPermissionRouteCondition((val: string) => val === `/${urlPrefix.value}/transfer`, transferVisible), + getPermissionRouteCondition((val: string) => val === `/${urlPrefix.value}/swap`, swapVisible), getPermissionRouteCondition((val: string) => val === '/migrate', migrateVisible), { cond: (val: string) => val.startsWith('/transfer'), diff --git a/utils/config/permission.config.ts b/utils/config/permission.config.ts index fd048f4660..9be6ce7548 100644 --- a/utils/config/permission.config.ts +++ b/utils/config/permission.config.ts @@ -71,3 +71,7 @@ export const dropsVisible = (prefix: Prefix | string) => { export const explorerVisible = (prefix: Prefix | string): boolean => { return hasExplorer[prefix] ?? true } + +export const swapVisible = (prefix: Prefix | string): boolean => { + return ['ahp', 'ahk'].includes(prefix) +} From 0fe2f3d7516ed5e0b3664abed39a46fb5ad5ddc3 Mon Sep 17 00:00:00 2001 From: roiLeo Date: Thu, 24 Oct 2024 11:22:18 +0200 Subject: [PATCH 04/87] =?UTF-8?q?=E2=9C=A8=20wip:=20swap=20page=20Step=202?= =?UTF-8?q?=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/swap/DestinationProfile.vue | 29 +++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/components/swap/DestinationProfile.vue b/components/swap/DestinationProfile.vue index 3d8b60cd44..1dd5dac2b6 100644 --- a/components/swap/DestinationProfile.vue +++ b/components/swap/DestinationProfile.vue @@ -1,7 +1,7 @@ diff --git a/components/swap/Preview.vue b/components/swap/Preview.vue index 13f888dd76..0e4dafb586 100644 --- a/components/swap/Preview.vue +++ b/components/swap/Preview.vue @@ -64,6 +64,7 @@ size="large" label="Next" variant="primary" + :disabled no-shadow expanded @click="emit('next')" @@ -80,6 +81,7 @@ import { sanitizeIpfsUrl } from '@/utils/ipfs' const emit = defineEmits(['next', 'clear']) const props = defineProps<{ title: string + disabled?: boolean items: any[] }>() diff --git a/components/swap/YourProfile.vue b/components/swap/YourProfile.vue index dd53f07f5e..08991292f4 100644 --- a/components/swap/YourProfile.vue +++ b/components/swap/YourProfile.vue @@ -12,20 +12,30 @@ diff --git a/stores/atomicSwaps.ts b/stores/atomicSwaps.ts index 7a49c6a540..0f82fc5c25 100644 --- a/stores/atomicSwaps.ts +++ b/stores/atomicSwaps.ts @@ -1,26 +1,80 @@ import { defineStore } from 'pinia' +import { computed } from 'vue' + +export type AtomicSwap = { + counterparty: string + offerer: string + offered: SwapItem[] + desired: SwapItem[] + createdAt: number +} & CartItem type SwapItem = { id: string } -type State = { - counterparty?: string - offered: SwapItem[] - desired: SwapItem[] -} +export const useAtomicSwapsStore = defineStore('atomicSwaps', () => { + const { + items, + chain, + count, + itemsInChain, + getItem, + setItem, + removeItem, + clear, + updateItem, + } = useCart() + + const { accountId } = useAuth() + const { urlPrefix } = usePrefix() + const getItems = computed(() => items.value) + const route = useRoute() + + // make a ref + const counterparty = computed(() => route.params.id.toString() as string) + + const lastSwap = computed(() => { + const atomicSwaps = items.value + .filter(item => + item.counterparty === counterparty.value + && item.urlPrefix === urlPrefix.value + && item.offerer === accountId.value, + ).sort((a, b) => b.createdAt - a.createdAt) + return atomicSwaps[0] + }) + + const createSwap = () => { + const newAtomicSwap: AtomicSwap = { + id: window.crypto.randomUUID(), + counterparty: counterparty.value, + offerer: accountId.value, + offered: [], + desired: [], + createdAt: Date.now(), + urlPrefix: urlPrefix.value, + } + + setItem(newAtomicSwap) + + return newAtomicSwap + } -export const useAtomicSwapsStore = defineStore('atomicSwaps', { - state: (): State => ({ - counterparty: undefined, - offered: [], - desired: [], - }), - actions: { - reset() { - this.counterparty = undefined - this.offered = [] - this.desired = [] - }, - }, + return { + // state + items, + // getters + chain, + count, + itemsInChain, + getItems, + // actions + getItem, + lastSwap, + setItem, + updateItem, + removeItem, + clear, + createSwap, + } }) From bc35ebdddd319e60073bff219c9a73e67416d327 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:52:51 +0500 Subject: [PATCH 09/87] ref(useAtomicSwapAction.ts): cleaner and null check --- components/items/ItemsGrid/useAtomicSwapAction.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/components/items/ItemsGrid/useAtomicSwapAction.ts b/components/items/ItemsGrid/useAtomicSwapAction.ts index 4f98e4c6a3..964c779c97 100644 --- a/components/items/ItemsGrid/useAtomicSwapAction.ts +++ b/components/items/ItemsGrid/useAtomicSwapAction.ts @@ -35,17 +35,15 @@ export default (nft: NFTWithMetadata) => { const isItemSelected = computed(() => items.value?.some(item => item.id === nft.id)) const onAtomicSwapSelect = () => { - if (!itemsKey.value) { + if (!itemsKey.value || !lastSwap.value) { return } - const updatedSwap = lastSwap.value - if (isItemSelected.value) { - updatedSwap[itemsKey.value] = items.value.filter(item => item.id !== nft.id) + lastSwap.value[itemsKey.value] = items.value.filter(item => item.id !== nft.id) } else { - updatedSwap[itemsKey.value].push(nft) + lastSwap.value[itemsKey.value].push(nft) } } From 75041cdd51f6e18856d50745874c3953e812ce2a Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:45:13 +0500 Subject: [PATCH 10/87] add(swaps): add connect wallet button if wallet is not disconnected --- components/swap/banner/accounts.vue | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/components/swap/banner/accounts.vue b/components/swap/banner/accounts.vue index 2203ffdff7..6f13fe7b6c 100644 --- a/components/swap/banner/accounts.vue +++ b/components/swap/banner/accounts.vue @@ -1,10 +1,14 @@ - + @@ -13,5 +14,6 @@ const gridSection = GridSection.PROFILE_GALLERY defineProps<{ query: Record + selectable?: boolean }>() diff --git a/components/swap/YourProfile.vue b/components/swap/YourProfile.vue index 08991292f4..7302e146e4 100644 --- a/components/swap/YourProfile.vue +++ b/components/swap/YourProfile.vue @@ -8,7 +8,10 @@ /> - + @@ -23,7 +27,6 @@ diff --git a/components/swap/review.vue b/components/swap/review.vue index e5bf81fca3..0346b2f5cc 100644 --- a/components/swap/review.vue +++ b/components/swap/review.vue @@ -26,8 +26,13 @@

{{ $t('swap.reviewSelected') }}

+ + -
+
{{ $t('swap.reviewCounterpartyAccept') }}

+ +
@@ -55,5 +65,10 @@ diff --git a/middleware/swap.ts b/middleware/swap.ts new file mode 100644 index 0000000000..fbfc77db0d --- /dev/null +++ b/middleware/swap.ts @@ -0,0 +1,23 @@ +export default defineNuxtRouteMiddleware((to) => { + const { toast } = useToast() + const atomicSwapsStore = useAtomicSwapsStore() + const { lastSwap, counterparty } = storeToRefs(atomicSwapsStore) + + const id = to.params.id?.toString() + + if (!id) { + return navigateTo({ name: 'prefix-swap' }) + } + + counterparty.value = id + + if (to.name === 'prefix-swap-id' && !lastSwap.value) { + atomicSwapsStore.createSwap() + return + } + + if (!lastSwap.value) { + toast('First select the NFTs you want to offer') + return navigateTo({ name: 'prefix-swap-id', params: { id } }) + } +}) diff --git a/pages/[prefix]/swap/[id]/index.vue b/pages/[prefix]/swap/[id]/index.vue index 5cfb562e5c..36e190dc1e 100644 --- a/pages/[prefix]/swap/[id]/index.vue +++ b/pages/[prefix]/swap/[id]/index.vue @@ -5,5 +5,6 @@ diff --git a/pages/[prefix]/swap/[id]/offer.vue b/pages/[prefix]/swap/[id]/offer.vue index 423b8a153d..fec12ce6a8 100644 --- a/pages/[prefix]/swap/[id]/offer.vue +++ b/pages/[prefix]/swap/[id]/offer.vue @@ -5,5 +5,6 @@ diff --git a/pages/[prefix]/swap/[id]/review.vue b/pages/[prefix]/swap/[id]/review.vue index 4c2a4be72a..2802fd2a61 100644 --- a/pages/[prefix]/swap/[id]/review.vue +++ b/pages/[prefix]/swap/[id]/review.vue @@ -5,5 +5,6 @@ diff --git a/stores/atomicSwaps.ts b/stores/atomicSwaps.ts index 0f82fc5c25..63ffa2bbf6 100644 --- a/stores/atomicSwaps.ts +++ b/stores/atomicSwaps.ts @@ -29,10 +29,8 @@ export const useAtomicSwapsStore = defineStore('atomicSwaps', () => { const { accountId } = useAuth() const { urlPrefix } = usePrefix() const getItems = computed(() => items.value) - const route = useRoute() - // make a ref - const counterparty = computed(() => route.params.id.toString() as string) + const counterparty = ref() const lastSwap = computed(() => { const atomicSwaps = items.value @@ -63,6 +61,7 @@ export const useAtomicSwapsStore = defineStore('atomicSwaps', () => { return { // state items, + counterparty, // getters chain, count, From 6e0c279b33830439fe644ea8137d6126260ddb99 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:28:34 +0500 Subject: [PATCH 12/87] add(swaps): pesist store and step --- .../items/ItemsGrid/useAtomicSwapAction.ts | 21 +++++----- components/swap/DestinationProfile.vue | 13 ++++--- components/swap/YourProfile.vue | 9 +++-- components/swap/review.vue | 6 +-- middleware/swap.ts | 18 +++++++-- stores/atomicSwaps.ts | 39 ++++++++++++++----- 6 files changed, 70 insertions(+), 36 deletions(-) diff --git a/components/items/ItemsGrid/useAtomicSwapAction.ts b/components/items/ItemsGrid/useAtomicSwapAction.ts index 964c779c97..57ef86d707 100644 --- a/components/items/ItemsGrid/useAtomicSwapAction.ts +++ b/components/items/ItemsGrid/useAtomicSwapAction.ts @@ -8,42 +8,41 @@ export const ATOMIC_SWAP_PAGES = [ export default (nft: NFTWithMetadata) => { const route = useRoute() - const { lastSwap } = storeToRefs(useAtomicSwapsStore()) + const { swap, step } = storeToRefs(useAtomicSwapsStore()) const routeName = computed(() => route.name?.toString() as string) const showAtomicSwapAction = computed(() => ATOMIC_SWAP_PAGES.includes(routeName.value)) - const isDesiredSelection = computed(() => routeName.value === 'prefix-swap-id') - const isOfferedSelection = computed(() => routeName.value === 'prefix-swap-id-offer') - const itemsKey = computed(() => { - if (isDesiredSelection.value) { + if (step.value === SwapStep.DESIRED) { return 'desired' } - if (isOfferedSelection.value) { + if (step.value === SwapStep.OFFERED) { return 'offered' } }) const items = computed(() => { - const items = lastSwap.value?.[itemsKey.value || ''] + const items = swap.value?.[itemsKey.value || ''] return items }) - const isItemSelected = computed(() => items.value?.some(item => item.id === nft.id)) + const isItemSelected = computed(() => { + return step.value === SwapStep.REVIEW ? false : items.value?.some(item => item.id === nft.id) + }) const onAtomicSwapSelect = () => { - if (!itemsKey.value || !lastSwap.value) { + if (!itemsKey.value || !swap.value) { return } if (isItemSelected.value) { - lastSwap.value[itemsKey.value] = items.value.filter(item => item.id !== nft.id) + swap.value[itemsKey.value] = items.value.filter(item => item.id !== nft.id) } else { - lastSwap.value[itemsKey.value].push(nft) + swap.value[itemsKey.value].push(nft) } } diff --git a/components/swap/DestinationProfile.vue b/components/swap/DestinationProfile.vue index 6101034598..dbca3c8faf 100644 --- a/components/swap/DestinationProfile.vue +++ b/components/swap/DestinationProfile.vue @@ -15,12 +15,15 @@ @@ -31,7 +34,7 @@ const { accountId } = useAuth() const route = useRoute() const atomicSwapsStore = useAtomicSwapsStore() -const { lastSwap } = storeToRefs(atomicSwapsStore) +const { swap } = storeToRefs(atomicSwapsStore) const query = reactive({ currentOwner_eq: route.params.id, diff --git a/components/swap/YourProfile.vue b/components/swap/YourProfile.vue index 7302e146e4..39d04f4ec2 100644 --- a/components/swap/YourProfile.vue +++ b/components/swap/YourProfile.vue @@ -15,10 +15,11 @@ @@ -27,7 +28,7 @@ diff --git a/middleware/swap.ts b/middleware/swap.ts index fbfc77db0d..64c856a4e9 100644 --- a/middleware/swap.ts +++ b/middleware/swap.ts @@ -1,7 +1,8 @@ export default defineNuxtRouteMiddleware((to) => { const { toast } = useToast() + const { accountId } = useAuth() const atomicSwapsStore = useAtomicSwapsStore() - const { lastSwap, counterparty } = storeToRefs(atomicSwapsStore) + const { swap, counterparty } = storeToRefs(atomicSwapsStore) const id = to.params.id?.toString() @@ -11,12 +12,21 @@ export default defineNuxtRouteMiddleware((to) => { counterparty.value = id - if (to.name === 'prefix-swap-id' && !lastSwap.value) { - atomicSwapsStore.createSwap() + watchEffect(() => { + if (swap.value) { + atomicSwapsStore.updateItem({ + ...swap.value, + creator: accountId.value ? accountId.value : undefined, + }) + } + }) + + if (to.name === 'prefix-swap-id' && !swap.value) { + atomicSwapsStore.createSwap(id) return } - if (!lastSwap.value) { + if (!swap.value) { toast('First select the NFTs you want to offer') return navigateTo({ name: 'prefix-swap-id', params: { id } }) } diff --git a/stores/atomicSwaps.ts b/stores/atomicSwaps.ts index 63ffa2bbf6..c494ecea87 100644 --- a/stores/atomicSwaps.ts +++ b/stores/atomicSwaps.ts @@ -3,16 +3,23 @@ import { computed } from 'vue' export type AtomicSwap = { counterparty: string - offerer: string + creator?: string offered: SwapItem[] desired: SwapItem[] createdAt: number + surcharge: { receive?: string, send?: string } } & CartItem type SwapItem = { id: string } +export enum SwapStep { + DESIRED = 'desired', + OFFERED = 'offered', + REVIEW = 'review', +} + export const useAtomicSwapsStore = defineStore('atomicSwaps', () => { const { items, @@ -30,27 +37,40 @@ export const useAtomicSwapsStore = defineStore('atomicSwaps', () => { const { urlPrefix } = usePrefix() const getItems = computed(() => items.value) + const route = useRoute() + const routeName = computed(() => route.name?.toString()) + + const step = computed(() => { + return routeName.value + ? { + 'prefix-swap-id': SwapStep.DESIRED, + 'prefix-swap-id-offer': SwapStep.OFFERED, + 'prefix-swap-id-review': SwapStep.REVIEW, + }[routeName.value] + : undefined + }) + const counterparty = ref() - const lastSwap = computed(() => { + const swap = computed(() => { const atomicSwaps = items.value .filter(item => item.counterparty === counterparty.value - && item.urlPrefix === urlPrefix.value - && item.offerer === accountId.value, + && item.urlPrefix === urlPrefix.value, ).sort((a, b) => b.createdAt - a.createdAt) return atomicSwaps[0] }) - const createSwap = () => { + const createSwap = (counterparty: string) => { const newAtomicSwap: AtomicSwap = { id: window.crypto.randomUUID(), - counterparty: counterparty.value, - offerer: accountId.value, + counterparty, offered: [], desired: [], createdAt: Date.now(), urlPrefix: urlPrefix.value, + surcharge: {}, + creator: accountId.value ? accountId.value : undefined, } setItem(newAtomicSwap) @@ -67,13 +87,14 @@ export const useAtomicSwapsStore = defineStore('atomicSwaps', () => { count, itemsInChain, getItems, + step, // actions getItem, - lastSwap, + swap, setItem, updateItem, removeItem, clear, createSwap, } -}) +}, { persist: true }) From d0d6ad3493fd8a5b307499df95362a3b50b142e2 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Sat, 9 Nov 2024 16:21:18 +0500 Subject: [PATCH 13/87] add(swaps): init `createSwap` transaction --- components/items/ItemsGrid/ItemsGridImage.vue | 2 +- .../items/ItemsGrid/useAtomicSwapAction.ts | 8 +- components/offer/OfferExpirationSelector.vue | 13 ++- components/swap/DestinationProfile.vue | 11 ++- components/swap/Preview.vue | 18 +++++ components/swap/YourProfile.vue | 11 ++- components/swap/review.vue | 74 ++++++++++++++++- .../transaction/transactionCreateSwap.ts | 80 +++++++++++++++++++ composables/transaction/transactionOffer.ts | 2 +- composables/transaction/types.ts | 24 ++++++ composables/transaction/utils.ts | 3 + composables/useTransaction.ts | 10 +++ locales/en.json | 4 + stores/atomicSwaps.ts | 12 ++- utils/shoppingActions.ts | 1 + 15 files changed, 257 insertions(+), 16 deletions(-) create mode 100644 composables/transaction/transactionCreateSwap.ts diff --git a/components/items/ItemsGrid/ItemsGridImage.vue b/components/items/ItemsGrid/ItemsGridImage.vue index 070c419f1a..eabddf547d 100644 --- a/components/items/ItemsGrid/ItemsGridImage.vue +++ b/components/items/ItemsGrid/ItemsGridImage.vue @@ -28,7 +28,7 @@ #action >
{ swap.value[itemsKey.value] = items.value.filter(item => item.id !== nft.id) } else { - swap.value[itemsKey.value].push(nft) + swap.value[itemsKey.value].push({ + id: nft.id, + collectionId: nft.collection.id, + sn: nft.sn, + name: nft.name, + meta: nft.meta, + }) } } diff --git a/components/offer/OfferExpirationSelector.vue b/components/offer/OfferExpirationSelector.vue index b644913bd8..0904d3b89f 100644 --- a/components/offer/OfferExpirationSelector.vue +++ b/components/offer/OfferExpirationSelector.vue @@ -3,7 +3,7 @@ v-model="selected" aria-role="list" :triggers="['click']" - position="bottom-left" + :position="position" append-to-body close-menu-on-move class="w-full" @@ -54,9 +54,14 @@ const options = EXPIRATION_DAYS_LIST.map(value => ({ const selectedItem = computed(() => options.find(option => option.value === selected.value)) -const props = defineProps<{ - modelValue?: number -}>() +const props = withDefaults( + defineProps<{ + modelValue?: number + position?: string + }>(), { + position: 'bottom-left', + }, +) const emit = defineEmits(['update:modelValue']) diff --git a/components/swap/DestinationProfile.vue b/components/swap/DestinationProfile.vue index dbca3c8faf..a0af27587a 100644 --- a/components/swap/DestinationProfile.vue +++ b/components/swap/DestinationProfile.vue @@ -1,5 +1,5 @@ - + Report @@ -94,6 +97,7 @@ const props = defineProps<{ const action = ref('') const isOwner = computed(() => accountId.value === props.nft?.currentOwner) +const isCollectionIssuer = computed(() => accountId.value === props.nft?.collection?.issuer) const nftId = computed(() => props.nft?.id || '') const { data } = useQuery({ diff --git a/queries/subsquid/ahk/nftById.graphql b/queries/subsquid/ahk/nftById.graphql index eac7db68b0..ca1912ae0d 100644 --- a/queries/subsquid/ahk/nftById.graphql +++ b/queries/subsquid/ahk/nftById.graphql @@ -9,6 +9,7 @@ query nftById($id: String!) { collection { id name + issuer } attributes { key: trait diff --git a/queries/subsquid/general/nftById.graphql b/queries/subsquid/general/nftById.graphql index 22e4e90e55..aff35f6cbd 100644 --- a/queries/subsquid/general/nftById.graphql +++ b/queries/subsquid/general/nftById.graphql @@ -8,6 +8,7 @@ query nftById($id: String!) { collection { id name + issuer floorPrice: nfts( where: { burned_eq: false, price_not_eq: "0" } orderBy: price_ASC diff --git a/queries/subsquid/ksm/nftById.graphql b/queries/subsquid/ksm/nftById.graphql index 9cd904eaa6..49db389018 100644 --- a/queries/subsquid/ksm/nftById.graphql +++ b/queries/subsquid/ksm/nftById.graphql @@ -20,6 +20,7 @@ query nftById($id: String!) { collection { id name + issuer } emotes { caller diff --git a/queries/subsquid/rmrk/nftById.graphql b/queries/subsquid/rmrk/nftById.graphql index 870cc69d17..cddee2c03d 100644 --- a/queries/subsquid/rmrk/nftById.graphql +++ b/queries/subsquid/rmrk/nftById.graphql @@ -8,6 +8,7 @@ query nftById($id: String!) { collection { id name + issuer } emotes { caller diff --git a/types/index.ts b/types/index.ts index a20328adbb..8c49f0d4fd 100644 --- a/types/index.ts +++ b/types/index.ts @@ -110,6 +110,7 @@ export interface TokenId { export type EntityWithId = { id: string name: string + issuer: string floor: string } From 44e74a2f3cdda40417d7e06978e5139173250d3d Mon Sep 17 00:00:00 2001 From: Jarsen <31397967+Jarsen136@users.noreply.github.com> Date: Thu, 28 Nov 2024 22:45:22 +0100 Subject: [PATCH 45/87] fix: collection current owner --- .../gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue | 4 ++-- queries/subsquid/ahk/nftById.graphql | 2 +- queries/subsquid/general/nftById.graphql | 2 +- queries/subsquid/ksm/nftById.graphql | 2 +- queries/subsquid/rmrk/nftById.graphql | 2 +- types/index.ts | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue b/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue index a9adaa8855..99f39ddb53 100644 --- a/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue +++ b/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue @@ -49,7 +49,7 @@ @@ -97,7 +97,7 @@ const props = defineProps<{ const action = ref('') const isOwner = computed(() => accountId.value === props.nft?.currentOwner) -const isCollectionIssuer = computed(() => accountId.value === props.nft?.collection?.issuer) +const isCollectionOwner = computed(() => accountId.value === props.nft?.collection?.currentOwner) const nftId = computed(() => props.nft?.id || '') const { data } = useQuery({ diff --git a/queries/subsquid/ahk/nftById.graphql b/queries/subsquid/ahk/nftById.graphql index ca1912ae0d..09057edc03 100644 --- a/queries/subsquid/ahk/nftById.graphql +++ b/queries/subsquid/ahk/nftById.graphql @@ -9,7 +9,7 @@ query nftById($id: String!) { collection { id name - issuer + currentOwner } attributes { key: trait diff --git a/queries/subsquid/general/nftById.graphql b/queries/subsquid/general/nftById.graphql index aff35f6cbd..54f9d3b2ef 100644 --- a/queries/subsquid/general/nftById.graphql +++ b/queries/subsquid/general/nftById.graphql @@ -8,7 +8,7 @@ query nftById($id: String!) { collection { id name - issuer + currentOwner floorPrice: nfts( where: { burned_eq: false, price_not_eq: "0" } orderBy: price_ASC diff --git a/queries/subsquid/ksm/nftById.graphql b/queries/subsquid/ksm/nftById.graphql index 49db389018..75435b9c57 100644 --- a/queries/subsquid/ksm/nftById.graphql +++ b/queries/subsquid/ksm/nftById.graphql @@ -20,7 +20,7 @@ query nftById($id: String!) { collection { id name - issuer + currentOwner } emotes { caller diff --git a/queries/subsquid/rmrk/nftById.graphql b/queries/subsquid/rmrk/nftById.graphql index cddee2c03d..a7c34d9631 100644 --- a/queries/subsquid/rmrk/nftById.graphql +++ b/queries/subsquid/rmrk/nftById.graphql @@ -8,7 +8,7 @@ query nftById($id: String!) { collection { id name - issuer + currentOwner } emotes { caller diff --git a/types/index.ts b/types/index.ts index 8c49f0d4fd..81f1b02db8 100644 --- a/types/index.ts +++ b/types/index.ts @@ -110,7 +110,7 @@ export interface TokenId { export type EntityWithId = { id: string name: string - issuer: string + currentOwner: string floor: string } From 2d63c95636ef44ced075a071c2c74bfb5dd84527 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:45:26 +0500 Subject: [PATCH 46/87] fix(swaps): `surcharge` not being saved --- components/swap/Preview.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/swap/Preview.vue b/components/swap/Preview.vue index 673b8e36cc..487218c5d1 100644 --- a/components/swap/Preview.vue +++ b/components/swap/Preview.vue @@ -198,11 +198,11 @@ const onBack = async () => { const clearAll = () => { swapStore.updateStepItems([]) - swap.value.surcharge = undefined + swapStore.updateSwap({ surcharge: undefined }) } const addSurcharge = () => { - swap.value.surcharge = { amount: String(Number(amount.value) * Math.pow(10, decimals.value)), direction: stepDetails.value.surchargeDirection } + swapStore.updateSwap({ surcharge: { amount: String(Number(amount.value) * Math.pow(10, decimals.value)), direction: stepDetails.value.surchargeDirection } }) amount.value = '' } From d1b1204bec0d2febda231425db240c0a5c494ede Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:47:08 +0500 Subject: [PATCH 47/87] ref: removed comments --- components/items/ItemsGrid/ItemsGridImage.vue | 2 -- components/swap/landing.vue | 1 - 2 files changed, 3 deletions(-) diff --git a/components/items/ItemsGrid/ItemsGridImage.vue b/components/items/ItemsGrid/ItemsGridImage.vue index eabddf547d..9a3a40202b 100644 --- a/components/items/ItemsGrid/ItemsGridImage.vue +++ b/components/items/ItemsGrid/ItemsGridImage.vue @@ -165,8 +165,6 @@ const onClickShoppingCart = () => { const onClickListingCart = () => listNftByNftWithMetadata(props.nft, { toggle: true }) -// select - const selectLabel = computed(() => { const selected = showAtomicSwapAction.value ? isAtomicSwapItemSelected.value : listingCartStore.isItemInCart(props.nft.id) return selected ? $i18n.t('remove') : $i18n.t('select') diff --git a/components/swap/landing.vue b/components/swap/landing.vue index 22c7920719..fea924305e 100644 --- a/components/swap/landing.vue +++ b/components/swap/landing.vue @@ -66,7 +66,6 @@ const { accountId } = useAuth() const traderAddress = ref('') const handleSubmit = async () => { - // check valid address await navigateTo({ name: 'prefix-swap-id', params: { id: traderAddress.value } }) } From 10c040871320bf04afb03f79ad35030e937c8de0 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:27:46 +0500 Subject: [PATCH 48/87] fix: profile interactions test --- components/profile/ProfileDetail.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/profile/ProfileDetail.vue b/components/profile/ProfileDetail.vue index 74a7f33458..e71059b6e6 100644 --- a/components/profile/ProfileDetail.vue +++ b/components/profile/ProfileDetail.vue @@ -619,7 +619,9 @@ const buttonConfig = computed(() => ) const switchToTab = (tab: ProfileTab) => { - activeTab.value = tab + if (activeTab.value !== tab) { + activeTab.value = tab + } } const onFollowersClick = () => { From d741f2d538f78855fdac673ba4ac44ac5379a964 Mon Sep 17 00:00:00 2001 From: Jarsen <31397967+Jarsen136@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:52:40 +0100 Subject: [PATCH 49/87] feat: Collection Edit: Support Name Update and Description Update --- components/collection/EditModal.vue | 38 +++++++++++++++++-- .../collection/HeroButtonEditCollection.vue | 12 +++--- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/components/collection/EditModal.vue b/components/collection/EditModal.vue index cf5bfb0679..3dba158c89 100644 --- a/components/collection/EditModal.vue +++ b/components/collection/EditModal.vue @@ -12,6 +12,29 @@ class="flex flex-col gap-6" @submit.prevent > + + + + + + + + () +const description = ref() const image = ref() const banner = ref() const imageUrl = ref() @@ -142,18 +167,21 @@ const max = ref(null) const disabled = computed(() => { const hasImage = imageUrl.value + const isNameFilled = Boolean(name.value) - const hasImagechanged = (!imageUrl.value && Boolean(props.collection?.image)) || Boolean(image.value) + const nameChanged = props.collection.name !== name.value + const descriptionChanged = props.collection.description !== description.value + const hasImageChanged = (!imageUrl.value && Boolean(props.collection?.image)) || Boolean(image.value) const hasBannerChanged = (!bannerUrl.value && Boolean(props.collection?.banner)) || Boolean(banner.value) const hasMaxChanged = max.value !== props.collection?.max - return !hasImage || (!hasImagechanged && !hasBannerChanged && !hasMaxChanged) + return !hasImage || !isNameFilled || (!nameChanged && !descriptionChanged && !hasImageChanged && !hasBannerChanged && !hasMaxChanged) }) const editCollection = async () => { emit('submit', { - name: props.collection.name, - description: props.collection.description, + name: name.value, + description: description.value, image: image.value || props.collection.image, imageType: props.collection.imageType, banner: bannerUrl.value ? banner.value || props.collection.banner : undefined, @@ -163,6 +191,8 @@ const editCollection = async () => { watch(isModalActive, (value) => { if (value && props.collection) { + name.value = props.collection.name + description.value = props.collection.description imageUrl.value = sanitizeIpfsUrl(props.collection.image) bannerUrl.value = props.collection.banner && sanitizeIpfsUrl(props.collection.banner) image.value = undefined diff --git a/components/collection/HeroButtonEditCollection.vue b/components/collection/HeroButtonEditCollection.vue index 9abd1fafe6..a0e30fd549 100644 --- a/components/collection/HeroButtonEditCollection.vue +++ b/components/collection/HeroButtonEditCollection.vue @@ -13,9 +13,9 @@ /> @@ -37,7 +37,7 @@ const route = useRoute() const isModalActive = ref(false) -const collectinoMetadata = computed(() => +const collectionMetadata = computed(() => props.collection ? { name: props.collection.meta.name, @@ -61,7 +61,7 @@ const updateMetadata = (a: UpdateCollection, b: UpdateCollection) => { const editCollection = async (collection: UpdateCollection) => { isModalActive.value = false - if (!collectinoMetadata.value) { + if (!collectionMetadata.value) { return } @@ -70,8 +70,8 @@ const editCollection = async (collection: UpdateCollection) => { collectionId: route.params.id.toString(), collection, update: { - metadata: updateMetadata(collection, collectinoMetadata.value), - max: collection.max !== collectinoMetadata.value.max, + metadata: updateMetadata(collection, collectionMetadata.value), + max: collection.max !== collectionMetadata.value.max, }, urlPrefix: urlPrefix.value, successMessage: $i18n.t('edit.collection.success'), From 45a20416583972b73a8d1e1c0b9aeb79a00ded2d Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Sat, 30 Nov 2024 07:57:02 +0500 Subject: [PATCH 50/87] fix(swaps): trade modal successful transaction transalation details --- .../overviewModal/TradeOverviewModal.vue | 34 +++++++++++++++---- locales/en.json | 1 + 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/components/trade/overviewModal/TradeOverviewModal.vue b/components/trade/overviewModal/TradeOverviewModal.vue index 5433251699..51cf6dc32b 100644 --- a/components/trade/overviewModal/TradeOverviewModal.vue +++ b/components/trade/overviewModal/TradeOverviewModal.vue @@ -61,12 +61,17 @@ import nftById from '@/queries/subsquid/general/nftById.graphql' import { TradeType } from '@/composables/useTrades' import type { NFT } from '@/types' -type Details = { +type OverviewModeDetails = { title: string signingTitle: string notificationTitle: string } +type Details = { + transactionSuccessTitle: string + transactionSuccessTab: string +} + type TradeNFTs = { desired: NFT, offered: NFT } type ExecTxParams = { @@ -88,10 +93,9 @@ const { urlPrefix, client } = usePrefix() const { transaction, status, isError, isLoading } = useTransaction({ disableSuccessNotification: true }) const { $i18n } = useNuxtApp() const { notification, lastSessionId, updateSession } = useLoadingNotfication() -const { $i18n: { t } } = useNuxtApp() const { mode } = useIsTradeOverview(computed(() => props.trade)) -const TradeTypeDetails: Record> = { +const TradeTypeOverviewModeDetails: Record> = { [TradeType.SWAP]: { incoming: { title: $i18n.t('swap.incomingSwap'), @@ -118,6 +122,17 @@ const TradeTypeDetails: Record> = { }, } +const TradeTypeDetails: Record = { + [TradeType.SWAP]: { + transactionSuccessTitle: $i18n.t('swap.manageSwaps'), + transactionSuccessTab: 'swaps', + }, + [TradeType.OFFER]: { + transactionSuccessTitle: $i18n.t('offer.manageOffers'), + transactionSuccessTab: 'offers', + }, +} + const TradeTypeTx: Record void>> = { [TradeType.SWAP]: { owner: ({ offered }) => { @@ -166,13 +181,18 @@ const nftId = computed(() => props.trade?.desired.id) const offeredItemId = computed(() => props.trade?.offered.id) const offeredItemSn = computed(() => props.trade?.offered.sn) -const details = computed
(() => +const details = computed
(() => props.trade - ? TradeTypeDetails[props.trade.type][mode.value] + ? { + ...TradeTypeDetails[props.trade.type], + ...TradeTypeOverviewModeDetails[props.trade.type][mode.value], + } : { title: '', signingTitle: '', notificationTitle: '', + transactionSuccessTitle: '', + transactionSuccessTab: '', }) const { data: nft, pending: nftLoading } = await useAsyncData(`tarde-nft-id-${nftId.value}`, async () => { @@ -238,9 +258,9 @@ useTransactionNotification({ action: computed(() => { if (isSessionState('succeeded')) { return { - label: t('offer.manageOffers'), + label: details.value.transactionSuccessTitle, icon: 'arrow-up-right', - url: `/${urlPrefix.value}/u/${accountId.value}?tab=offers&filter=outgoing`, + url: `/${urlPrefix.value}/u/${accountId.value}?tab=${details.value.transactionSuccessTab}&filter=outgoing`, } } return undefined diff --git a/locales/en.json b/locales/en.json index 0911467b73..c298b56790 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1826,6 +1826,7 @@ "landingSubtitle": "Koda Swap facilitates secure and straightforward exchanges of digital assets. Connect directly with traders and confidently navigate your NFT transactions with our reliable platform.", "landingTitle": "Koda Swap", "learnMoreAboutSwaps": "Learn more about swaps", + "manageSwaps": "Manage Swaps", "modifyOffer": "Modify Offer", "requestToken": "Request Token", "reviewCheckAssets": "Check the assets on both sides of the swap", From fc1155e5d4d259b95230e1b4d913ae55c3e65fb1 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Sat, 30 Nov 2024 07:58:13 +0500 Subject: [PATCH 51/87] fix(transactions): `ActionAcceptOffer` type --- composables/transaction/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composables/transaction/types.ts b/composables/transaction/types.ts index fb940a8667..714bdf342a 100644 --- a/composables/transaction/types.ts +++ b/composables/transaction/types.ts @@ -229,7 +229,7 @@ export type ActionAcceptOffer = { urlPrefix: Prefix nftId: string collectionId: string - offeredId: number + offeredId: string price: string successMessage?: string errorMessage?: string From 032aaf342d6458d4a6c9a48843616789e0144332 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Sat, 30 Nov 2024 10:08:16 +0500 Subject: [PATCH 52/87] fix(swaps): transaction translations --- components/trade/TradeOwnerButton.vue | 8 ++++---- .../trade/overviewModal/TradeOverviewModal.vue | 12 ++++++------ locales/en.json | 11 ++++++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/components/trade/TradeOwnerButton.vue b/components/trade/TradeOwnerButton.vue index ab118bee91..c059caa5f9 100644 --- a/components/trade/TradeOwnerButton.vue +++ b/components/trade/TradeOwnerButton.vue @@ -21,12 +21,12 @@ const onClick = () => emit('click', props.trade) const details = { [TradeType.SWAP]: { - cancel: 'swap.cancelSwap', - accept: 'swap.acceptSwap', + cancel: 'transaction.withdrawSwap', + accept: 'transaction.acceptSwap', }, [TradeType.OFFER]: { - cancel: 'transaction.offerWithdraw', - accept: 'transaction.offerAccept', + cancel: 'transaction.withdrawOffer', + accept: 'transaction.acceptOffer', }, } diff --git a/components/trade/overviewModal/TradeOverviewModal.vue b/components/trade/overviewModal/TradeOverviewModal.vue index 51cf6dc32b..abb6871406 100644 --- a/components/trade/overviewModal/TradeOverviewModal.vue +++ b/components/trade/overviewModal/TradeOverviewModal.vue @@ -99,24 +99,24 @@ const TradeTypeOverviewModeDetails: Record Date: Sun, 1 Dec 2024 14:58:48 +0100 Subject: [PATCH 53/87] feat: Item Edit: Limit Name and Image Update --- components/common/EditNftModal.vue | 30 +++++++++++-------- .../common/NonRecommendFieldNotification.vue | 26 ++++++++++++++++ locales/en.json | 1 + 3 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 components/common/NonRecommendFieldNotification.vue diff --git a/components/common/EditNftModal.vue b/components/common/EditNftModal.vue index 7bd0d1a324..a052b0218b 100644 --- a/components/common/EditNftModal.vue +++ b/components/common/EditNftModal.vue @@ -16,10 +16,12 @@ :label="$t('mint.nft.art.label')" required > - + + + @@ -28,11 +30,13 @@ required :error="!name" > - + + + @@ -91,17 +95,17 @@ const image = ref() const imageUrl = ref() const attributes = ref([]) +const nameChanged = computed(() => props.metadata?.name !== name.value) +const imageChanged = computed(() => Boolean(image.value)) + const disabled = computed(() => { const hasImage = Boolean(imageUrl.value) const isNameFilled = Boolean(name.value) - - const nameChanged = props.metadata?.name !== name.value const descriptionChanged = props.metadata?.description !== description.value - const imageChanged = Boolean(image.value) const attributesChanged = JSON.stringify(attributes.value) !== JSON.stringify(props.metadata?.attributes || []) return !hasImage || !isNameFilled - || (!nameChanged && !descriptionChanged && !imageChanged && !attributesChanged) + || (!nameChanged.value && !descriptionChanged && !imageChanged.value && !attributesChanged) }) const editCollection = async () => { diff --git a/components/common/NonRecommendFieldNotification.vue b/components/common/NonRecommendFieldNotification.vue new file mode 100644 index 0000000000..206307ac4b --- /dev/null +++ b/components/common/NonRecommendFieldNotification.vue @@ -0,0 +1,26 @@ + + + diff --git a/locales/en.json b/locales/en.json index e0df34b649..3af8e8f3dc 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1358,6 +1358,7 @@ "message": "People will be able to buy your NFT." } }, + "notRecommendedModify": "Please note that this value is not recommended to be modified as it may lead to misuse and confusion", "progress": "In Progress", "requiredDeposit": "A deposit of {0} is required to create a {1}. Please note, this initial deposit is refundable.", "royalty": { From 874e602a6dbb63066378e38fda4e80fdfa731600 Mon Sep 17 00:00:00 2001 From: Jarsen <31397967+Jarsen136@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:51:04 +0100 Subject: [PATCH 54/87] feat: undo edit nft --- components/common/EditNftModal.vue | 22 ++++++++++--- .../common/NonRecommendFieldNotification.vue | 31 ++++++++++++++++--- locales/en.json | 2 +- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/components/common/EditNftModal.vue b/components/common/EditNftModal.vue index a052b0218b..470521dfa7 100644 --- a/components/common/EditNftModal.vue +++ b/components/common/EditNftModal.vue @@ -16,7 +16,10 @@ :label="$t('mint.nft.art.label')" required > - + - + () const imageUrl = ref() const attributes = ref([]) +const originalImageUrl = computed(() => sanitizeIpfsUrl(props.metadata?.image)) + const nameChanged = computed(() => props.metadata?.name !== name.value) -const imageChanged = computed(() => Boolean(image.value)) +const imageChanged = computed(() => originalImageUrl.value !== imageUrl.value) + +const initImage = () => { + imageUrl.value = originalImageUrl.value + image.value = undefined +} const disabled = computed(() => { const hasImage = Boolean(imageUrl.value) @@ -122,8 +135,7 @@ const editCollection = async () => { watch(isModalActive, (value) => { if (value) { - imageUrl.value = sanitizeIpfsUrl(props.metadata?.image) - image.value = undefined + initImage() name.value = props.metadata?.name description.value = props.metadata?.description attributes.value = structuredClone(toRaw(props.metadata?.attributes || [])) diff --git a/components/common/NonRecommendFieldNotification.vue b/components/common/NonRecommendFieldNotification.vue index 206307ac4b..2490f88b90 100644 --- a/components/common/NonRecommendFieldNotification.vue +++ b/components/common/NonRecommendFieldNotification.vue @@ -10,17 +10,40 @@ class="text-yellow-500 flex-shrink-0" size="small" /> -

- {{ $t('mint.notRecommendedModify') }} -

+ +
+

+ {{ $t('mint.notRecommendedModify') }} +

+
+ + + {{ $t('undo') }} + +
+
diff --git a/locales/en.json b/locales/en.json index 3af8e8f3dc..40de2ad3ef 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1358,7 +1358,7 @@ "message": "People will be able to buy your NFT." } }, - "notRecommendedModify": "Please note that this value is not recommended to be modified as it may lead to misuse and confusion", + "notRecommendedModify": "Please note that this field is not recommended to be modified as it may lead to misuse and confusion", "progress": "In Progress", "requiredDeposit": "A deposit of {0} is required to create a {1}. Please note, this initial deposit is refundable.", "royalty": { From 70ae8a6c9d5d6b77cb168eb96c61c4744a2e55f8 Mon Sep 17 00:00:00 2001 From: Jarsen <31397967+Jarsen136@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:58:06 +0100 Subject: [PATCH 55/87] chore: remove class --- components/common/NonRecommendFieldNotification.vue | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/common/NonRecommendFieldNotification.vue b/components/common/NonRecommendFieldNotification.vue index 2490f88b90..043a1710e8 100644 --- a/components/common/NonRecommendFieldNotification.vue +++ b/components/common/NonRecommendFieldNotification.vue @@ -7,11 +7,11 @@ > -
+

{{ $t('mint.notRecommendedModify') }}

@@ -26,7 +26,6 @@ > {{ $t('undo') }} From e1c2281a3d1d7ecb8622e3bd3c3eced8854ae8a6 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 3 Dec 2024 07:06:46 +0500 Subject: [PATCH 56/87] ref: init `UserCartModal` component --- components/common/ItemTransferModal.vue | 121 +++++++++++++++ .../UserCartModal.vue} | 146 ++++-------------- .../UserCartMultipleItems.vue} | 0 .../UserCartSingleItem.vue} | 0 .../GalleryItemMoreActionBtn.vue | 1 - 5 files changed, 149 insertions(+), 119 deletions(-) create mode 100644 components/common/ItemTransferModal.vue rename components/common/{itemTransfer/ItemTransferModal.vue => userCart/UserCartModal.vue} (60%) rename components/common/{itemTransfer/ItemTransferMultipleItems.vue => userCart/UserCartMultipleItems.vue} (100%) rename components/common/{itemTransfer/ItemTransferSingleItem.vue => userCart/UserCartSingleItem.vue} (100%) diff --git a/components/common/ItemTransferModal.vue b/components/common/ItemTransferModal.vue new file mode 100644 index 0000000000..58e80d34ff --- /dev/null +++ b/components/common/ItemTransferModal.vue @@ -0,0 +1,121 @@ + + + diff --git a/components/common/itemTransfer/ItemTransferModal.vue b/components/common/userCart/UserCartModal.vue similarity index 60% rename from components/common/itemTransfer/ItemTransferModal.vue rename to components/common/userCart/UserCartModal.vue index ff3fdbad16..2617d0e047 100644 --- a/components/common/itemTransfer/ItemTransferModal.vue +++ b/components/common/userCart/UserCartModal.vue @@ -6,7 +6,7 @@ :is-loading="isLoading" :status="status" close-at-signed - @try-again="itemTransfer" + @try-again="exectTransaction" />
- -
-
- -

- {{ $t('transaction.transferTo') }} -

- - +
@@ -68,7 +54,7 @@ :fees="{ forceActionAutoFees: true }" :actions="actions" :disabled="isDisabled" - :label="transferItemLabel" + :label="label" variant="primary" no-shadow with-shortcut @@ -78,17 +64,7 @@ @confirm="handleTransfer" /> -
- - -

- {{ $t('transaction.wrongAddressCannotRecoveredWarning') }} -

-
+
@@ -96,53 +72,41 @@ diff --git a/components/common/itemTransfer/ItemTransferMultipleItems.vue b/components/common/userCart/UserCartMultipleItems.vue similarity index 100% rename from components/common/itemTransfer/ItemTransferMultipleItems.vue rename to components/common/userCart/UserCartMultipleItems.vue diff --git a/components/common/itemTransfer/ItemTransferSingleItem.vue b/components/common/userCart/UserCartSingleItem.vue similarity index 100% rename from components/common/itemTransfer/ItemTransferSingleItem.vue rename to components/common/userCart/UserCartSingleItem.vue diff --git a/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue b/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue index 99f39ddb53..e4ef4dc958 100644 --- a/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue +++ b/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue @@ -73,7 +73,6 @@ import { sanitizeIpfsUrl, toOriginalContentUrl } from '@/utils/ipfs' import { isMobileDevice } from '@/utils/extension' import { hasOperationsDisabled } from '@/utils/prefix' import { refreshOdaTokenMetadata } from '@/services/oda' -import ItemTransferModal from '@/components/common/itemTransfer/ItemTransferModal.vue' import type { NFT } from '@/types' import type { Abi } from '@/composables/transaction/types' From 51b748408de9161dd592d5aaa10146326dd64462 Mon Sep 17 00:00:00 2001 From: Jarsen <31397967+Jarsen136@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:51:57 +0100 Subject: [PATCH 57/87] chore: update translation --- components/common/NonRecommendFieldNotification.vue | 2 +- locales/en.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/common/NonRecommendFieldNotification.vue b/components/common/NonRecommendFieldNotification.vue index 043a1710e8..27de4d33e2 100644 --- a/components/common/NonRecommendFieldNotification.vue +++ b/components/common/NonRecommendFieldNotification.vue @@ -28,7 +28,7 @@ icon="undo" size="small" /> - {{ $t('undo') }} + {{ $t('general.undo') }}
diff --git a/locales/en.json b/locales/en.json index 40de2ad3ef..ae894a5be4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -941,6 +941,7 @@ "cancelled": "Transaction was cancelled", "feesPaidIn": "You are paying fees in {0}" }, + "undo": "Undo", "updateOnWebsiteSoon": "Update on website visible soon", "usd": "USD", "using": "using" From 6d8dd9f500dc87bb2050273cdea521cabec663fc Mon Sep 17 00:00:00 2001 From: Hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:56:43 +0500 Subject: [PATCH 58/87] Update composables/transaction/transactionCreateSwap.ts Co-authored-by: Preschian Febryantara --- composables/transaction/transactionCreateSwap.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composables/transaction/transactionCreateSwap.ts b/composables/transaction/transactionCreateSwap.ts index b1ff448276..db0e08ea13 100644 --- a/composables/transaction/transactionCreateSwap.ts +++ b/composables/transaction/transactionCreateSwap.ts @@ -26,7 +26,7 @@ async function execCreateSwapStatmine({ item, api, executeTransaction, isLoading amount, direction: item.surcharge.direction, } - : undefined, + : null, BLOCKS_PER_DAY * item.duration, ) From 2004e2a814f25320b62f68fb8abe05cd466d868f Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:41:40 +0500 Subject: [PATCH 59/87] fix(UserCartModal.vue): missing `exectTransaction` function --- components/common/userCart/UserCartModal.vue | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/components/common/userCart/UserCartModal.vue b/components/common/userCart/UserCartModal.vue index 2617d0e047..8cf029e42c 100644 --- a/components/common/userCart/UserCartModal.vue +++ b/components/common/userCart/UserCartModal.vue @@ -6,7 +6,7 @@ :is-loading="isLoading" :status="status" close-at-signed - @try-again="exectTransaction" + @try-again="execTransaction" /> { closeModal() } +const execTransaction = async () => { + try { + await transaction(action.value) + } + catch (error) { + warningMessage(error) + } +} + const handleTransfer = async ({ autoteleport }: AutoTeleportActionButtonConfirmEvent) => { try { clearTransaction() @@ -144,7 +153,7 @@ const handleTransfer = async ({ autoteleport }: AutoTeleportActionButtonConfirmE autoTeleport.value = autoteleport if (!autoteleport) { - await transaction(action.value) + await execTransaction() } closeModal() From 894f666b9e8fc458443d3e0fbaa5f1127956ba58 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:42:20 +0500 Subject: [PATCH 60/87] fix(ItemTransferModal.vue): `isYourAddress` invalid not working --- components/common/ItemTransferModal.vue | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/components/common/ItemTransferModal.vue b/components/common/ItemTransferModal.vue index 58e80d34ff..57d779e279 100644 --- a/components/common/ItemTransferModal.vue +++ b/components/common/ItemTransferModal.vue @@ -22,7 +22,7 @@ class="flex-1" placeholder="Enter wallet address" with-address-check - @check="handleAddressCheck" + @check="isValid => isAddressValid = isValid" /> @@ -77,7 +77,7 @@ const transferItemLabel = computed(() => { return $i18n.t('transaction.transferNft') }) -const isYourAddress = computed(() => accountId.value === getChainAddress(address.value)) +const isYourAddress = computed(() => getChainAddress(accountId.value) === getChainAddress(address.value)) const loading = computed(() => (isEvm(urlPrefix.value) ? !abi.value : false)) const disabled = computed( @@ -106,10 +106,6 @@ const reset = () => { isAddressValid.value = false } -const handleAddressCheck = (isValid: boolean) => { - isAddressValid.value = isValid -} - const getChainAddress = (value: string) => { try { return toSubstrateAddress(value) From d902547d58b4c19f45a4a7aabcd838f5fa2bc4fd Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:53:18 +0500 Subject: [PATCH 61/87] ref(UserCartModal.vue): `submit` function --- components/common/userCart/UserCartModal.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/common/userCart/UserCartModal.vue b/components/common/userCart/UserCartModal.vue index 8cf029e42c..ba46a0b30d 100644 --- a/components/common/userCart/UserCartModal.vue +++ b/components/common/userCart/UserCartModal.vue @@ -61,7 +61,7 @@ early-success auto-close-modal :auto-close-modal-delay-modal="0" - @confirm="handleTransfer" + @confirm="submit" /> @@ -146,7 +146,7 @@ const execTransaction = async () => { } } -const handleTransfer = async ({ autoteleport }: AutoTeleportActionButtonConfirmEvent) => { +const submit = async ({ autoteleport }: AutoTeleportActionButtonConfirmEvent) => { try { clearTransaction() From f8790a46ba7c23f52bb5b786c1d9fed7eed4f630 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 3 Dec 2024 20:02:16 +0500 Subject: [PATCH 62/87] ref(UserCartModal.vue): add `title` and `signingTitle` props --- components/common/ItemTransferModal.vue | 6 ++++-- components/common/userCart/UserCartModal.vue | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/components/common/ItemTransferModal.vue b/components/common/ItemTransferModal.vue index 57d779e279..062145a404 100644 --- a/components/common/ItemTransferModal.vue +++ b/components/common/ItemTransferModal.vue @@ -2,8 +2,10 @@ userCartModal.value?.items || [] as ListCartItem[]) const nft = computed(() => items.value[0]) const abi = useCollectionAbi(computed(() => nft.value?.collection.id)) -const transferItemLabel = computed(() => { +const label = computed(() => { if (!address.value) { return $i18n.t('transaction.inputAddressFirst') } diff --git a/components/common/userCart/UserCartModal.vue b/components/common/userCart/UserCartModal.vue index ba46a0b30d..164ab99c31 100644 --- a/components/common/userCart/UserCartModal.vue +++ b/components/common/userCart/UserCartModal.vue @@ -2,7 +2,7 @@
() const isModalActive = defineModel({ type: Boolean, required: true }) @@ -172,7 +174,7 @@ useTransactionNotification({ init: () => { return notification(({ isSessionState, notify, session }) => { return notify({ - title: ref($i18n.t('transaction.transferingNft', items.value.length)), + title: ref(props.signingTitle), state: computed(() => session?.value.state as LoadingNotificationState), action: computed(() => { return isSessionState('succeeded') From c5d5839e5812f88f3a7e0d2a0fe9c008a9c8abe8 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 3 Dec 2024 20:19:19 +0500 Subject: [PATCH 63/87] ref(UserCartModal.vue): add `mode` prop` --- components/common/ItemTransferModal.vue | 5 +---- .../common/listingCart/ListingCartMini.vue | 18 +++++++++++++++++- components/common/userCart/UserCartModal.vue | 6 +++--- stores/preferences.ts | 6 ++++-- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/components/common/ItemTransferModal.vue b/components/common/ItemTransferModal.vue index 062145a404..0e03e5c4f1 100644 --- a/components/common/ItemTransferModal.vue +++ b/components/common/ItemTransferModal.vue @@ -1,7 +1,7 @@ diff --git a/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue b/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue index e4ef4dc958..6273b793df 100644 --- a/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue +++ b/components/gallery/GalleryItemButton/GalleryItemMoreActionBtn.vue @@ -4,10 +4,10 @@ :title="signingModalTitle" :is-loading="isLoading" :status="status" - @try-again="burn" + @try-again="tryAgain" /> - + Transfer NFT @@ -93,8 +93,9 @@ const props = defineProps<{ abi?: Abi | null }>() -const action = ref('') +const action = ref<'unlist' | ''>('') +const id = computed(() => route.params.id.toString()) const isOwner = computed(() => accountId.value === props.nft?.currentOwner) const isCollectionOwner = computed(() => accountId.value === props.nft?.collection?.currentOwner) const nftId = computed(() => props.nft?.id || '') @@ -102,7 +103,7 @@ const nftId = computed(() => props.nft?.id || '') const { data } = useQuery({ queryKey: ['nft-with-metadata', nftId], queryFn: async () => - nftId.value && canTransfer.value + nftId.value && canDoActions.value ? (await useAsyncGraphql({ query: 'nftEntitiesByIDs', variables: { ids: [nftId.value] }, @@ -111,12 +112,11 @@ const { data } = useQuery({ }) const nftWithMetadata = computed(() => data.value?.nftEntities?.[0]) -const canTransfer = computed(() => props.nft && isOwner.value) +const canDoActions = computed(() => props.nft && isOwner.value) const signingModalTitle = computed(() => { return ( { - burn: $i18n.t('mint.nft.burning'), unlist: $i18n.t('mint.nft.delisting'), }[action.value] || '' ) @@ -164,17 +164,12 @@ const downloadMedia = async () => { } const burn = () => { - action.value = 'burn' - transaction({ - interaction: Interaction.CONSUME, - urlPrefix: urlPrefix.value, - nftId: route.params.id as string, - nftSn: props.nft?.sn as string, - collectionId: props.nft?.collection?.id as string, - abi: props.abi, - successMessage: $i18n.t('transaction.consume.success') as string, - errorMessage: $i18n.t('transaction.consume.error') as string, - }) + openUserCartModal('burn') +} + +const tryAgain = () => { + const map = { unlist } + map[action.value]?.() } const unlist = () => { @@ -183,7 +178,7 @@ const unlist = () => { interaction: Interaction.LIST, urlPrefix: urlPrefix.value, token: { - nftId: route.params.id as string, + nftId: id.value, price: '0', }, successMessage: $i18n.t('transaction.unlist.success') as string, @@ -198,10 +193,12 @@ const refreshMetadata = async () => { } } -const transfer = () => { +const openUserCartModal = (mode: UserCartMode) => { if (nftWithMetadata.value) { listNftByNftWithMetadata(nftWithMetadata.value) - preferencesStore.itemTransferCartModalOpen = true + preferencesStore.setOpenedUserCartModal(mode) } } + +const transfer = () => openUserCartModal('transfer') diff --git a/components/migrate/steps/SignLoader3.vue b/components/migrate/steps/SignLoader3.vue index e704859fee..ddc182f8eb 100644 --- a/components/migrate/steps/SignLoader3.vue +++ b/components/migrate/steps/SignLoader3.vue @@ -82,8 +82,10 @@ diff --git a/composables/useCollectionAbi.ts b/composables/useCollectionAbi.ts index 8142da1b62..1932adad54 100644 --- a/composables/useCollectionAbi.ts +++ b/composables/useCollectionAbi.ts @@ -1,12 +1,16 @@ import { useQuery } from '@tanstack/vue-query' import type { Prefix } from '@kodadot1/static' +import type { MaybeComputedRef } from '@vueuse/core' import { fetchOdaCollectionAbi } from '@/services/oda' -export default (collectionId: Ref, prefix: Ref = usePrefix().urlPrefix) => { +export default (collectionId: Ref, { + prefix = usePrefix().urlPrefix, + disabled = false, +}: { prefix?: Ref, disabled?: MaybeComputedRef } = {}) => { const { data: abi } = useQuery({ queryKey: ['collection-abi', collectionId], queryFn: () => isEvm(prefix.value) ? fetchOdaCollectionAbi(prefix.value, collectionId.value as string) : Promise.resolve(null), - enabled: computed(() => Boolean(collectionId.value)), + enabled: computed(() => Boolean(collectionId.value) && !unref(disabled)), }) return abi From 63f898e225d45ec3e9dd8b05a383d21fc23c5870 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Fri, 6 Dec 2024 06:49:40 +0500 Subject: [PATCH 73/87] fix: deepscan local variable not used. --- components/common/ItemTransferModal.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/common/ItemTransferModal.vue b/components/common/ItemTransferModal.vue index c818c8aca3..d6821220c0 100644 --- a/components/common/ItemTransferModal.vue +++ b/components/common/ItemTransferModal.vue @@ -6,8 +6,8 @@ :signing-title="$t('transaction.transferingNft', items.length)" :get-action="getAction" :label="label" - :disabled - :loading + :disabled="disabled" + :loading="loading" @reset="reset" > From 6842ba7e7aa7759dfd63a0376e662ae3d3152d60 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:13:47 +0500 Subject: [PATCH 77/87] remove: watch `getPrefixByAddress` --- components/profile/ProfileDetail.vue | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/components/profile/ProfileDetail.vue b/components/profile/ProfileDetail.vue index e71059b6e6..1e11a35df1 100644 --- a/components/profile/ProfileDetail.vue +++ b/components/profile/ProfileDetail.vue @@ -504,16 +504,14 @@ const { $i18n } = useNuxtApp() const { toast } = useToast() const { replaceUrl } = useReplaceUrl() const { accountId, isCurrentOwner } = useAuth() -const { urlPrefix, client, setUrlPrefix } = usePrefix() +const { urlPrefix, client } = usePrefix() const { shareOnX, shareOnFarcaster } = useSocialShare() -const { redirectAfterChainChange } = useChainRedirect() const profileOnboardingStore = useProfileOnboardingStore() const { getIsOnboardingShown } = storeToRefs(profileOnboardingStore) const { isSub } = useIsChain(urlPrefix) const listingCartStore = useListingCartStore() const { vm } = useChain() -const { getPrefixByAddress } = useAddress() const { params } = useRoute() const { hasProfile, userProfile, isFetchingProfile } = useProfile(computed(() => params?.id as string)) @@ -826,15 +824,6 @@ watch(collections, (value) => { }) }) -watch(() => getPrefixByAddress(route.params.id.toString()), (prefix) => { - if (prefix !== urlPrefix.value) { - setUrlPrefix(prefix) - redirectAfterChainChange(prefix) - } -}, { - immediate: true, -}) - watchEffect(() => { if (!hasProfile.value && !isFetchingProfile.value && isOwner.value && !getIsOnboardingShown.value) { profileOnboardingStore.setOnboardingShown() From 574e4ee676da2c24143b013e62bae79abaf0b00f Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:29:45 +0500 Subject: [PATCH 78/87] fix(profile): route redirect on wallet connect --- .../common/ConnectWallet/ConnectWalletModal.vue | 8 ++++++-- composables/useAddress.ts | 4 ++-- composables/useChainRedirect.ts | 14 ++++++-------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/components/common/ConnectWallet/ConnectWalletModal.vue b/components/common/ConnectWallet/ConnectWalletModal.vue index bb9cd9665f..0abd36c1af 100644 --- a/components/common/ConnectWallet/ConnectWalletModal.vue +++ b/components/common/ConnectWallet/ConnectWalletModal.vue @@ -56,10 +56,14 @@ import WalletAsset from '@/components/common/ConnectWallet/WalletAsset.vue' import { ModalCloseType } from '@/components/navbar/types' import { arePrefixesOfSameVm } from '@/utils/config/chain.config' +const NO_PREFIX_CHNAGE_ROUTES_NAMES = [ + 'prefix-u-id', +] + const emit = defineEmits(['close', 'connect']) const props = defineProps<{ preselected?: ChainVM }>() const { isWalletModalOpen } = useWallet() - +const route = useRoute() const { urlPrefix, setUrlPrefix } = usePrefix() const { redirectAfterChainChange } = useChainRedirect() const walletStore = useWalletStore() @@ -76,7 +80,7 @@ const setAccount = ({ account, prefix }: { account: WalletAccount, prefix?: Pref walletStore.setWallet(account) identityStore.setAuth({ address: account.address }) - if (!arePrefixesOfSameVm(prefix, urlPrefix.value)) { + if (!arePrefixesOfSameVm(prefix, urlPrefix.value) && !NO_PREFIX_CHNAGE_ROUTES_NAMES.includes(route.name?.toString() || '')) { setUrlPrefix(prefix) redirectAfterChainChange(urlPrefix.value) } diff --git a/composables/useAddress.ts b/composables/useAddress.ts index 1103046ceb..44040cb73f 100644 --- a/composables/useAddress.ts +++ b/composables/useAddress.ts @@ -1,7 +1,7 @@ import { isEthereumAddress } from '@polkadot/util-crypto' +import { type Prefix } from '@kodadot1/static' -export default function () { - const { urlPrefix } = usePrefix() +export default function (urlPrefix: ComputedRef = usePrefix().urlPrefix) { const { isEvm, isSub } = useIsChain(urlPrefix) const getPrefixByAddress = (address: string) => { diff --git a/composables/useChainRedirect.ts b/composables/useChainRedirect.ts index 95940981b7..e4a694fd73 100644 --- a/composables/useChainRedirect.ts +++ b/composables/useChainRedirect.ts @@ -15,10 +15,6 @@ const NO_REDIRECT_ROUTE_NAMES = [ 'create-collection', ] -const REDIRECT_HOME_ON_VM_CHANGE_ROUTE_NAMES = [ - 'prefix-u-id', -] - function isNoRedirect(routeName: string): boolean { return NO_REDIRECT_ROUTE_NAMES.includes(routeName) } @@ -46,11 +42,13 @@ function getRedirectPathForPrefix({ chain: Prefix route: RouteLocationNormalizedLoadedGeneric }): RouteLocationRaw { - if (!arePrefixesOfSameVm(route.params.prefix.toString() as Prefix, chain) && REDIRECT_HOME_ON_VM_CHANGE_ROUTE_NAMES.includes(routeName)) { - return { path: `/${chain}` } - } + const vmChanged = !arePrefixesOfSameVm(route.params.prefix.toString() as Prefix, chain) if (routeName === 'prefix-u-id') { + if (vmChanged) { + return { path: `/${chain}` } + } + const accountId = getss58AddressByPrefix(route.params.id.toString(), chain) delete route.query.collections @@ -106,7 +104,7 @@ export default function () { const router = useRouter() const redirectAfterChainChange = (newChain: Prefix): void => { - const routeName = route.name as string + const routeName = route.name?.toString() || '' if (isNoRedirect(routeName)) { return From f30179d6a46163c8160a640d2eb786b799c53971 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Sat, 7 Dec 2024 07:31:24 +0500 Subject: [PATCH 79/87] fix(AddressInput.vue): `strict` prop as `optional` --- components/shared/AddressInput.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/shared/AddressInput.vue b/components/shared/AddressInput.vue index 0a5a0122fa..0b2d17f682 100644 --- a/components/shared/AddressInput.vue +++ b/components/shared/AddressInput.vue @@ -37,7 +37,7 @@ const props = withDefaults( modelValue: string label?: string emptyOnError?: boolean - strict: boolean + strict?: boolean icon?: string placeholder?: string disableError?: boolean From e1cfc1243951ea29effe8e677e8826ba25fe9285 Mon Sep 17 00:00:00 2001 From: roiLeo Date: Mon, 9 Dec 2024 14:42:42 +0100 Subject: [PATCH 80/87] =?UTF-8?q?=E2=9C=A8=20profile=20Swaps=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/profile/ProfileDetail.vue | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/profile/ProfileDetail.vue b/components/profile/ProfileDetail.vue index e71059b6e6..998b1890bb 100644 --- a/components/profile/ProfileDetail.vue +++ b/components/profile/ProfileDetail.vue @@ -92,6 +92,14 @@ @follow:fail="openProfileCreateModal" @unfollow:success="handleFollowRefresh" /> + + {{ $t('swaps') }} + From 462d25f0a548e3508b8796ba79971a58c1396e55 Mon Sep 17 00:00:00 2001 From: roiLeo Date: Mon, 9 Dec 2024 14:47:52 +0100 Subject: [PATCH 81/87] =?UTF-8?q?=E2=9C=A8=20Profile=20swap=20btn=20visibl?= =?UTF-8?q?e=20only=20on=20authorized=20prefix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/profile/ProfileDetail.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/profile/ProfileDetail.vue b/components/profile/ProfileDetail.vue index 998b1890bb..42d6bb6fd3 100644 --- a/components/profile/ProfileDetail.vue +++ b/components/profile/ProfileDetail.vue @@ -93,6 +93,7 @@ @unfollow:success="handleFollowRefresh" /> Date: Tue, 10 Dec 2024 06:57:05 +0500 Subject: [PATCH 82/87] fix(create/nft): minting error --- composables/massmint/useMassMint.ts | 4 ++-- composables/transaction/mintToken/utils.ts | 3 +-- composables/transaction/types.ts | 9 ++------- queries/subsquid/general/collectionForMint.graphql | 2 +- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/composables/massmint/useMassMint.ts b/composables/massmint/useMassMint.ts index 4e8cf84fec..3645d0fb0a 100644 --- a/composables/massmint/useMassMint.ts +++ b/composables/massmint/useMassMint.ts @@ -47,7 +47,7 @@ export const useCollectionForMint = () => { collections.value = [] - return (await useAsyncGraphql({ + return (await useAsyncGraphql<{ collectionEntities: any[] }>({ query: 'collectionForMint', variables: { account: accountId.value, @@ -62,7 +62,7 @@ export const useCollectionForMint = () => { if (collectionEntities?.length) { const newCollections = collectionEntities .map(collection => ({ ...collection, lastIndexUsed: Number(collection.lastNft[0]?.sn || 0) })) - .filter(collection => (collection.max || Infinity) - collection.minted > 0) + .filter((collection: MintedCollection) => (collection.max || Infinity) - collection.alreadyMinted > 0) collections.value = unwrapSafe(newCollections) } diff --git a/composables/transaction/mintToken/utils.ts b/composables/transaction/mintToken/utils.ts index 1ce5be1c66..e28c35fca6 100644 --- a/composables/transaction/mintToken/utils.ts +++ b/composables/transaction/mintToken/utils.ts @@ -1,6 +1,5 @@ import type { ActionMintToken, - Max, MintedCollection, SubstrateMintTokenParams, TokenToMint, @@ -11,7 +10,7 @@ import type { SupportTokens } from '@/utils/support' export const copiesToMint = (token: T): number => { const { copies, selectedCollection } = token - const { alreadyMinted, max } = selectedCollection as MintedCollection & Max + const { alreadyMinted, max } = selectedCollection as MintedCollection const maxAllowedNftsInCollection = (max || 0) === 0 ? Infinity : max const remaining = maxAllowedNftsInCollection - alreadyMinted diff --git a/composables/transaction/types.ts b/composables/transaction/types.ts index d6d4dc5aa6..8b2a7b042f 100644 --- a/composables/transaction/types.ts +++ b/composables/transaction/types.ts @@ -77,8 +77,6 @@ export type NftCountType = { nftCount: number } -export type Max = { max: number } - export type SymbolType = { symbol: string } @@ -108,13 +106,10 @@ export type MintedCollection = { name?: string lastIndexUsed: number totalCount: number + max: number } -export type MintedCollectionKusama = MintedCollection & Max & SymbolType - -export type TokenToMint = BaseTokenType< - MintedCollection | MintedCollectionKusama -> & { +export type TokenToMint = BaseTokenType & { tags: Attribute[] nsfw: boolean postfix: boolean diff --git a/queries/subsquid/general/collectionForMint.graphql b/queries/subsquid/general/collectionForMint.graphql index 95e49f913e..67f4cdf039 100644 --- a/queries/subsquid/general/collectionForMint.graphql +++ b/queries/subsquid/general/collectionForMint.graphql @@ -7,7 +7,7 @@ query collectionForMint($account: String!) { name metadata max - minted: nftCount + alreadyMinted: nftCount totalCount: supply lastNft: nfts(orderBy: sn_DESC, limit: 1) { sn From f3e9b9cc71029df1a64751fe9482dce483e7f672 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 10 Dec 2024 08:15:35 +0500 Subject: [PATCH 83/87] fix(CreateNft.vue): mint action types --- components/create/CreateNft.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/create/CreateNft.vue b/components/create/CreateNft.vue index af31ca4a84..c829c7653e 100644 --- a/components/create/CreateNft.vue +++ b/components/create/CreateNft.vue @@ -302,7 +302,7 @@ import { toNFTId } from '@kodadot1/minimark/v2' import type { CreatedNFT } from '@kodadot1/minimark/v1' import { Interaction } from '@kodadot1/minimark/v1' import CreateNftPreview from './CreateNftPreview.vue' -import type { Actions, TokenToList } from '@/composables/transaction/types' +import type { ActionMintToken, ActionList, TokenToList } from '@/composables/transaction/types' import ChooseCollectionDropdown from '@/components/common/ChooseCollectionDropdown.vue' import BasicSwitch from '@/components/shared/form/BasicSwitch.vue' import CustomAttributeInput from '@/components/rmrk/Create/CustomAttributeInput.vue' @@ -429,14 +429,14 @@ const transactionStatus = ref< const createdItems = ref() const mintedBlockNumber = ref() -const mintAction = computed(() => ({ +const mintAction = computed(() => ({ interaction: Interaction.MINTNFT, urlPrefix: currentChain.value, token: { file: form.file, name: form.name, description: form.description, - selectedCollection: selectedCollection.value, + selectedCollection: selectedCollection.value || null, copies: form.copies, nsfw: form.nsfw, postfix: form.postfix, @@ -448,7 +448,7 @@ const mintAction = computed(() => ({ }, })) -const listAction = computed(() => { +const listAction = computed(() => { const list: TokenToList[] = createdItems.value?.map(nft => ({ price: balanceFrom(form.salePrice, decimals.value), nftId: toNFTId(nft, String(blockNumber.value)), From 47f1d34d66fff7ec813e5fc3a05c77fb13ae62bf Mon Sep 17 00:00:00 2001 From: roiLeo Date: Tue, 10 Dec 2024 08:44:22 +0100 Subject: [PATCH 84/87] =?UTF-8?q?=F0=9F=94=A7=20handleSwapPageRedirect=20o?= =?UTF-8?q?n=20profile=20details?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/profile/ProfileDetail.vue | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/components/profile/ProfileDetail.vue b/components/profile/ProfileDetail.vue index 42d6bb6fd3..5ac4d14d6c 100644 --- a/components/profile/ProfileDetail.vue +++ b/components/profile/ProfileDetail.vue @@ -94,10 +94,9 @@ /> {{ $t('swaps') }} @@ -482,6 +481,7 @@ import { openProfileCreateModal } from '@/components/profile/create/openProfileM import { getHigherResolutionCloudflareImage } from '@/utils/ipfs' import { offerVisible, swapVisible } from '@/utils/config/permission.config' import { TradeType } from '@/composables/useTrades' +import { doAfterCheckCurrentChainVM } from '@/components/common/ConnectWallet/openReconnectWalletModal' const NuxtImg = resolveComponent('NuxtImg') const NuxtLink = resolveComponent('NuxtLink') @@ -643,6 +643,12 @@ const onFollowingClick = () => { isFollowModalActive.value = true } +const handleSwapPageRedirect = () => { + doAfterCheckCurrentChainVM(() => { + return navigateTo(`/${urlPrefix}/swap/${isOwner.value ? '' : id}`) + }) +} + const tabKey = computed(() => activeTab.value === ProfileTab.OWNED ? 'currentOwner_eq' : 'issuer_eq', ) From 6e3b3fd2f1eda0843e4235e95be1922b99bca398 Mon Sep 17 00:00:00 2001 From: roiLeo Date: Tue, 10 Dec 2024 08:49:26 +0100 Subject: [PATCH 85/87] =?UTF-8?q?=F0=9F=94=A7=20handleSwapPageRedirect=20.?= =?UTF-8?q?=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/profile/ProfileDetail.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/profile/ProfileDetail.vue b/components/profile/ProfileDetail.vue index 5ac4d14d6c..7455377810 100644 --- a/components/profile/ProfileDetail.vue +++ b/components/profile/ProfileDetail.vue @@ -645,7 +645,7 @@ const onFollowingClick = () => { const handleSwapPageRedirect = () => { doAfterCheckCurrentChainVM(() => { - return navigateTo(`/${urlPrefix}/swap/${isOwner.value ? '' : id}`) + return navigateTo(`/${urlPrefix.value}/swap/${isOwner.value ? '' : id.value}`) }) } From 1e0cf84a09b58a4696dd5d24b7e91c6b770922c4 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 10 Dec 2024 13:52:03 +0500 Subject: [PATCH 86/87] add(WalletAssetMenu.vue): `Swap` button --- .../common/ConnectWallet/WalletAssetMenu.vue | 24 ++++++------------- locales/en.json | 1 + 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/components/common/ConnectWallet/WalletAssetMenu.vue b/components/common/ConnectWallet/WalletAssetMenu.vue index f8546e5157..64b0f03aea 100644 --- a/components/common/ConnectWallet/WalletAssetMenu.vue +++ b/components/common/ConnectWallet/WalletAssetMenu.vue @@ -82,11 +82,11 @@ import { NeoDropdown, NeoDropdownItem, NeoIcon } from '@kodadot1/brick' import type { Prefix } from '@kodadot1/static' import { langsFlags, setUserLocale } from '@/utils/config/i18n' -import { transferVisible, teleportVisible } from '@/utils/config/permission.config' +import { transferVisible, teleportVisible, swapVisible } from '@/utils/config/permission.config' const { urlPrefix } = usePrefix() -// const { isAssetHub } = useIsChain(urlPrefix) const { neoModal } = useProgrammatic() +const { $i18n } = useNuxtApp() const menus = ref<{ label: string, to: string, check: (v: Prefix) => boolean }[]>([ { @@ -99,23 +99,13 @@ const menus = ref<{ label: string, to: string, check: (v: Prefix) => boolean }[] to: `/${urlPrefix.value}/teleport`, check: teleportVisible, }, + { + label: $i18n.t('swap.swap'), + to: `/${urlPrefix.value}/swap`, + check: swapVisible, + }, ]) -// TODO: enable when asset hub offers are ready -// watchEffect(() => { -// if (isAssetHub.value) { -// menus.value.push({ -// label: 'Incoming Offers', -// to: `/${urlPrefix.value}/incomingoffers`, -// }) - -// menus.value.push({ -// label: 'Assets', -// to: `/${urlPrefix.value}/assets`, -// }) -// } -// }) - const filteredMenus = computed(() => menus.value.filter(menu => menu.check(urlPrefix.value)), ) diff --git a/locales/en.json b/locales/en.json index d33f293e5b..f873c9430c 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1840,6 +1840,7 @@ "selectOffer": "Select your offer", "selectOfferSubtitle": "Select your NFTs you want to offer in this swap.", "submit": "Submit Swap Offer", + "swap": "Swap", "swapWithdrawl": "Swap Cancelation", "youOffer": "You offer", "youWillReceive": "You will receive", From ce7217124b982494aae452a68318777c2061f0f0 Mon Sep 17 00:00:00 2001 From: hassnian <44554284+hassnian@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:14:33 +0500 Subject: [PATCH 87/87] fix(ConnectWalletModal.vue): constant typo --- components/common/ConnectWallet/ConnectWalletModal.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/common/ConnectWallet/ConnectWalletModal.vue b/components/common/ConnectWallet/ConnectWalletModal.vue index 0abd36c1af..09bb3907d0 100644 --- a/components/common/ConnectWallet/ConnectWalletModal.vue +++ b/components/common/ConnectWallet/ConnectWalletModal.vue @@ -56,7 +56,7 @@ import WalletAsset from '@/components/common/ConnectWallet/WalletAsset.vue' import { ModalCloseType } from '@/components/navbar/types' import { arePrefixesOfSameVm } from '@/utils/config/chain.config' -const NO_PREFIX_CHNAGE_ROUTES_NAMES = [ +const NO_PREFIX_CHANGE_ROUTES_NAMES = [ 'prefix-u-id', ] @@ -80,7 +80,7 @@ const setAccount = ({ account, prefix }: { account: WalletAccount, prefix?: Pref walletStore.setWallet(account) identityStore.setAuth({ address: account.address }) - if (!arePrefixesOfSameVm(prefix, urlPrefix.value) && !NO_PREFIX_CHNAGE_ROUTES_NAMES.includes(route.name?.toString() || '')) { + if (!arePrefixesOfSameVm(prefix, urlPrefix.value) && !NO_PREFIX_CHANGE_ROUTES_NAMES.includes(route.name?.toString() || '')) { setUrlPrefix(prefix) redirectAfterChainChange(urlPrefix.value) }