@bosonprotocol/react-kit 0.30.0-alpha.3 → 0.30.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/dist/cjs/components/modal/components/Commit/OfferVariantView.d.ts.map +1 -1
  2. package/dist/cjs/components/modal/components/Commit/OfferVariantView.js +3 -0
  3. package/dist/cjs/components/modal/components/Commit/OfferVariantView.js.map +1 -1
  4. package/dist/cjs/components/modal/components/common/OfferFullDescription/DigitalProductData.d.ts.map +1 -1
  5. package/dist/cjs/components/modal/components/common/OfferFullDescription/DigitalProductData.js +33 -12
  6. package/dist/cjs/components/modal/components/common/OfferFullDescription/DigitalProductData.js.map +1 -1
  7. package/dist/cjs/components/modal/components/common/detail/PhygitalProduct.d.ts.map +1 -1
  8. package/dist/cjs/components/modal/components/common/detail/PhygitalProduct.js +9 -23
  9. package/dist/cjs/components/modal/components/common/detail/PhygitalProduct.js.map +1 -1
  10. package/dist/cjs/components/modal/components/common/detail/TokenGatedItem.d.ts.map +1 -1
  11. package/dist/cjs/components/modal/components/common/detail/TokenGatedItem.js +28 -16
  12. package/dist/cjs/components/modal/components/common/detail/TokenGatedItem.js.map +1 -1
  13. package/dist/cjs/components/productCard/ProductCard.d.ts.map +1 -1
  14. package/dist/cjs/components/productCard/ProductCard.js +1 -1
  15. package/dist/cjs/components/productCard/ProductCard.js.map +1 -1
  16. package/dist/cjs/components/productCard/ProductCard.styles.d.ts +1 -0
  17. package/dist/cjs/components/productCard/ProductCard.styles.d.ts.map +1 -1
  18. package/dist/cjs/components/productCard/ProductCard.styles.js +43 -3
  19. package/dist/cjs/components/productCard/ProductCard.styles.js.map +1 -1
  20. package/dist/cjs/components/ui/IpfsImage.d.ts +3 -0
  21. package/dist/cjs/components/ui/IpfsImage.d.ts.map +1 -1
  22. package/dist/cjs/components/ui/IpfsImage.js +12 -2
  23. package/dist/cjs/components/ui/IpfsImage.js.map +1 -1
  24. package/dist/cjs/hooks/bundles/useBundleItemsImages.d.ts +10 -0
  25. package/dist/cjs/hooks/bundles/useBundleItemsImages.d.ts.map +1 -0
  26. package/dist/cjs/hooks/bundles/useBundleItemsImages.js +56 -0
  27. package/dist/cjs/hooks/bundles/useBundleItemsImages.js.map +1 -0
  28. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uris.d.ts +11 -0
  29. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uris.d.ts.map +1 -0
  30. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uris.js +37 -0
  31. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uris.js.map +1 -0
  32. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUris.d.ts +11 -0
  33. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUris.d.ts.map +1 -0
  34. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUris.js +37 -0
  35. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUris.js.map +1 -0
  36. package/dist/cjs/hooks/contracts/useGetTokenUriImages.d.ts +10 -0
  37. package/dist/cjs/hooks/contracts/useGetTokenUriImages.d.ts.map +1 -0
  38. package/dist/cjs/hooks/contracts/useGetTokenUriImages.js +103 -0
  39. package/dist/cjs/hooks/contracts/useGetTokenUriImages.js.map +1 -0
  40. package/dist/cjs/hooks/index.d.ts +3 -3
  41. package/dist/cjs/hooks/index.d.ts.map +1 -1
  42. package/dist/cjs/hooks/index.js +3 -3
  43. package/dist/cjs/hooks/index.js.map +1 -1
  44. package/dist/cjs/lib/ipfs/ipfs.d.ts.map +1 -1
  45. package/dist/cjs/lib/ipfs/ipfs.js +9 -4
  46. package/dist/cjs/lib/ipfs/ipfs.js.map +1 -1
  47. package/dist/cjs/lib/offer/getOfferDetails.js.map +1 -1
  48. package/dist/esm/components/modal/components/Commit/OfferVariantView.d.ts.map +1 -1
  49. package/dist/esm/components/modal/components/Commit/OfferVariantView.js +3 -0
  50. package/dist/esm/components/modal/components/Commit/OfferVariantView.js.map +1 -1
  51. package/dist/esm/components/modal/components/common/OfferFullDescription/DigitalProductData.d.ts.map +1 -1
  52. package/dist/esm/components/modal/components/common/OfferFullDescription/DigitalProductData.js +34 -8
  53. package/dist/esm/components/modal/components/common/OfferFullDescription/DigitalProductData.js.map +1 -1
  54. package/dist/esm/components/modal/components/common/detail/PhygitalProduct.d.ts.map +1 -1
  55. package/dist/esm/components/modal/components/common/detail/PhygitalProduct.js +9 -24
  56. package/dist/esm/components/modal/components/common/detail/PhygitalProduct.js.map +1 -1
  57. package/dist/esm/components/modal/components/common/detail/TokenGatedItem.d.ts.map +1 -1
  58. package/dist/esm/components/modal/components/common/detail/TokenGatedItem.js +28 -16
  59. package/dist/esm/components/modal/components/common/detail/TokenGatedItem.js.map +1 -1
  60. package/dist/esm/components/productCard/ProductCard.d.ts.map +1 -1
  61. package/dist/esm/components/productCard/ProductCard.js +2 -2
  62. package/dist/esm/components/productCard/ProductCard.js.map +1 -1
  63. package/dist/esm/components/productCard/ProductCard.styles.d.ts +1 -0
  64. package/dist/esm/components/productCard/ProductCard.styles.d.ts.map +1 -1
  65. package/dist/esm/components/productCard/ProductCard.styles.js +42 -2
  66. package/dist/esm/components/productCard/ProductCard.styles.js.map +1 -1
  67. package/dist/esm/components/ui/IpfsImage.d.ts +3 -0
  68. package/dist/esm/components/ui/IpfsImage.d.ts.map +1 -1
  69. package/dist/esm/components/ui/IpfsImage.js +13 -3
  70. package/dist/esm/components/ui/IpfsImage.js.map +1 -1
  71. package/dist/esm/hooks/bundles/useBundleItemsImages.d.ts +10 -0
  72. package/dist/esm/hooks/bundles/useBundleItemsImages.d.ts.map +1 -0
  73. package/dist/esm/hooks/bundles/useBundleItemsImages.js +48 -0
  74. package/dist/esm/hooks/bundles/useBundleItemsImages.js.map +1 -0
  75. package/dist/esm/hooks/contracts/erc1155/useErc1155Uris.d.ts +11 -0
  76. package/dist/esm/hooks/contracts/erc1155/useErc1155Uris.d.ts.map +1 -0
  77. package/dist/esm/hooks/contracts/erc1155/useErc1155Uris.js +22 -0
  78. package/dist/esm/hooks/contracts/erc1155/useErc1155Uris.js.map +1 -0
  79. package/dist/esm/hooks/contracts/erc721/useErc721TokenUris.d.ts +11 -0
  80. package/dist/esm/hooks/contracts/erc721/useErc721TokenUris.d.ts.map +1 -0
  81. package/dist/esm/hooks/contracts/erc721/useErc721TokenUris.js +22 -0
  82. package/dist/esm/hooks/contracts/erc721/useErc721TokenUris.js.map +1 -0
  83. package/dist/esm/hooks/contracts/useGetTokenUriImages.d.ts +10 -0
  84. package/dist/esm/hooks/contracts/useGetTokenUriImages.d.ts.map +1 -0
  85. package/dist/esm/hooks/contracts/useGetTokenUriImages.js +90 -0
  86. package/dist/esm/hooks/contracts/useGetTokenUriImages.js.map +1 -0
  87. package/dist/esm/hooks/index.d.ts +3 -3
  88. package/dist/esm/hooks/index.d.ts.map +1 -1
  89. package/dist/esm/hooks/index.js +3 -3
  90. package/dist/esm/hooks/index.js.map +1 -1
  91. package/dist/esm/lib/ipfs/ipfs.d.ts.map +1 -1
  92. package/dist/esm/lib/ipfs/ipfs.js +9 -4
  93. package/dist/esm/lib/ipfs/ipfs.js.map +1 -1
  94. package/dist/esm/lib/offer/getOfferDetails.js.map +1 -1
  95. package/package.json +4 -4
  96. package/src/components/modal/components/Commit/OfferVariantView.tsx +3 -0
  97. package/src/components/modal/components/common/OfferFullDescription/DigitalProductData.tsx +157 -113
  98. package/src/components/modal/components/common/detail/PhygitalProduct.tsx +13 -30
  99. package/src/components/modal/components/common/detail/TokenGatedItem.tsx +27 -15
  100. package/src/components/productCard/ProductCard.styles.ts +43 -2
  101. package/src/components/productCard/ProductCard.tsx +2 -1
  102. package/src/components/ui/IpfsImage.tsx +18 -3
  103. package/src/components/widgets/commit/CommitWidget.tsx +1 -1
  104. package/src/hooks/bundles/useBundleItemsImages.ts +71 -0
  105. package/src/hooks/contracts/erc1155/useErc1155Uris.ts +52 -0
  106. package/src/hooks/contracts/erc721/useErc721TokenUris.ts +52 -0
  107. package/src/hooks/contracts/useGetTokenUriImages.ts +126 -0
  108. package/src/hooks/index.ts +3 -3
  109. package/src/lib/ipfs/ipfs.ts +15 -5
  110. package/src/lib/offer/getOfferDetails.ts +4 -4
  111. package/src/stories/widgets/Commit.stories.tsx +3 -3
  112. package/dist/cjs/components/nftItem/NftItemIcon.d.ts +0 -8
  113. package/dist/cjs/components/nftItem/NftItemIcon.d.ts.map +0 -1
  114. package/dist/cjs/components/nftItem/NftItemIcon.js +0 -14
  115. package/dist/cjs/components/nftItem/NftItemIcon.js.map +0 -1
  116. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uri.d.ts +0 -9
  117. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uri.d.ts.map +0 -1
  118. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uri.js +0 -29
  119. package/dist/cjs/hooks/contracts/erc1155/useErc1155Uri.js.map +0 -1
  120. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUri.d.ts +0 -9
  121. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUri.d.ts.map +0 -1
  122. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUri.js +0 -29
  123. package/dist/cjs/hooks/contracts/erc721/useErc721TokenUri.js.map +0 -1
  124. package/dist/cjs/hooks/contracts/useGetTokenUriImage.d.ts +0 -8
  125. package/dist/cjs/hooks/contracts/useGetTokenUriImage.d.ts.map +0 -1
  126. package/dist/cjs/hooks/contracts/useGetTokenUriImage.js +0 -93
  127. package/dist/cjs/hooks/contracts/useGetTokenUriImage.js.map +0 -1
  128. package/dist/esm/components/nftItem/NftItemIcon.d.ts +0 -8
  129. package/dist/esm/components/nftItem/NftItemIcon.d.ts.map +0 -1
  130. package/dist/esm/components/nftItem/NftItemIcon.js +0 -7
  131. package/dist/esm/components/nftItem/NftItemIcon.js.map +0 -1
  132. package/dist/esm/hooks/contracts/erc1155/useErc1155Uri.d.ts +0 -9
  133. package/dist/esm/hooks/contracts/erc1155/useErc1155Uri.d.ts.map +0 -1
  134. package/dist/esm/hooks/contracts/erc1155/useErc1155Uri.js +0 -16
  135. package/dist/esm/hooks/contracts/erc1155/useErc1155Uri.js.map +0 -1
  136. package/dist/esm/hooks/contracts/erc721/useErc721TokenUri.d.ts +0 -9
  137. package/dist/esm/hooks/contracts/erc721/useErc721TokenUri.d.ts.map +0 -1
  138. package/dist/esm/hooks/contracts/erc721/useErc721TokenUri.js +0 -16
  139. package/dist/esm/hooks/contracts/erc721/useErc721TokenUri.js.map +0 -1
  140. package/dist/esm/hooks/contracts/useGetTokenUriImage.d.ts +0 -8
  141. package/dist/esm/hooks/contracts/useGetTokenUriImage.d.ts.map +0 -1
  142. package/dist/esm/hooks/contracts/useGetTokenUriImage.js +0 -80
  143. package/dist/esm/hooks/contracts/useGetTokenUriImage.js.map +0 -1
  144. package/src/components/nftItem/NftItemIcon.tsx +0 -16
  145. package/src/hooks/contracts/erc1155/useErc1155Uri.ts +0 -31
  146. package/src/hooks/contracts/erc721/useErc721TokenUri.ts +0 -31
  147. package/src/hooks/contracts/useGetTokenUriImage.ts +0 -102
@@ -1,21 +1,21 @@
1
1
  import { ArrowSquareUpRight } from "phosphor-react";
2
2
  import React, { ReactNode } from "react";
3
3
  import styled from "styled-components";
4
- import { useGetTokenUriImage } from "../../../../../hooks";
4
+ import { useBundleItemsImages } from "../../../../../hooks/bundles/useBundleItemsImages";
5
5
  import { useErc1155Name } from "../../../../../hooks/contracts/erc1155/useErc1155Name";
6
6
  import { useErc721Name } from "../../../../../hooks/contracts/erc721/useErc721Name";
7
7
  import { useCoreSDKWithContext } from "../../../../../hooks/core-sdk/useCoreSdkWithContext";
8
+ import { formatAddress } from "../../../../../lib/address/address";
8
9
  import { isNftItem, isProductV1Item } from "../../../../../lib/bundle/filter";
9
10
  import { getOfferDetails } from "../../../../../lib/offer/getOfferDetails";
11
+ import { theme } from "../../../../../theme";
10
12
  import { Offer } from "../../../../../types/offer";
13
+ import { Tooltip } from "../../../../tooltip/Tooltip";
11
14
  import { Grid } from "../../../../ui/Grid";
12
15
  import IpfsImage from "../../../../ui/IpfsImage";
13
16
  import ThemedButton from "../../../../ui/ThemedButton";
14
17
  import { Typography } from "../../../../ui/Typography";
15
18
  import Video from "../../../../ui/Video";
16
- import { theme } from "../../../../../theme";
17
- import { Tooltip } from "../../../../tooltip/Tooltip";
18
- import { formatAddress } from "../../../../../lib/address/address";
19
19
  const colors = theme.colors.light;
20
20
  const imageSize = "2.5rem";
21
21
 
@@ -52,27 +52,7 @@ export const PhygitalProduct: React.FC<PhygitalProductProps> = ({ offer }) => {
52
52
  },
53
53
  { enabled: !!contracts?.length, coreSDK }
54
54
  );
55
- const { data: ercImages } = useGetTokenUriImage(
56
- {
57
- tokenIds: bundleItems?.map((bundleItem) => {
58
- if (isNftItem(bundleItem)) {
59
- return (
60
- bundleItem.tokenIdRange?.min ??
61
- bundleItem.tokenIdRange?.max ??
62
- bundleItem.tokenId
63
- );
64
- }
65
- return null;
66
- }),
67
- tokenUris: bundleItems?.map((bundleItem) => {
68
- if (isNftItem(bundleItem)) {
69
- return bundleItem.metadataUri;
70
- }
71
- return null;
72
- })
73
- },
74
- { enabled: !!bundleItems?.length }
75
- );
55
+ const { images } = useBundleItemsImages({ bundleItems, coreSDK });
76
56
  return (
77
57
  <Grid flexDirection="column" alignItems="flex-start" gap="1rem">
78
58
  <Typography>
@@ -118,7 +98,7 @@ export const PhygitalProduct: React.FC<PhygitalProductProps> = ({ offer }) => {
118
98
  </Tooltip>
119
99
  );
120
100
  }
121
- imageSrc = ercImages?.[index] || bundleItem.image;
101
+ imageSrc = images?.[index];
122
102
  videoSrc = bundleItem.animationUrl;
123
103
  rangeText =
124
104
  bundleItem.tokenIdRange?.min ||
@@ -158,13 +138,16 @@ export const PhygitalProduct: React.FC<PhygitalProductProps> = ({ offer }) => {
158
138
  color: colors.darkGrey
159
139
  }}
160
140
  >
161
- {imageSrc ? (
141
+ {videoSrc ? (
162
142
  <MediaWrapper>
163
- <IpfsImage src={imageSrc} />
143
+ <Video src={videoSrc} />
164
144
  </MediaWrapper>
165
- ) : videoSrc ? (
145
+ ) : imageSrc ? (
166
146
  <MediaWrapper>
167
- <Video src={videoSrc} />
147
+ <IpfsImage
148
+ src={imageSrc}
149
+ overrides={{ ipfsGateway: "https://ipfs.io/ipfs" }}
150
+ />
168
151
  </MediaWrapper>
169
152
  ) : null}
170
153
  <div>{quantity}x</div>
@@ -10,12 +10,12 @@ import React, {
10
10
  useState
11
11
  } from "react";
12
12
  import styled from "styled-components";
13
- import { useErc1155Uri } from "../../../../../hooks/contracts/erc1155/useErc1155Uri";
13
+ import { useErc1155Uris } from "../../../../../hooks/contracts/erc1155/useErc1155Uris";
14
14
  import { useErc20ExchangeTokenInfo } from "../../../../../hooks/contracts/erc20/useErc20ExchangeTokenInfo";
15
- import { useErc721TokenUri } from "../../../../../hooks/contracts/erc721/useErc721TokenUri";
15
+ import { useErc721TokenUris } from "../../../../../hooks/contracts/erc721/useErc721TokenUris";
16
16
  import { useCoreSDKWithContext } from "../../../../../hooks/core-sdk/useCoreSdkWithContext";
17
17
  import { nativeOnChain } from "../../../../../lib/const/tokens";
18
- import { useGetTokenUriImage } from "../../../../../hooks/contracts/useGetTokenUriImage";
18
+ import { useGetTokenUriImages } from "../../../../../hooks/contracts/useGetTokenUriImages";
19
19
  import { theme } from "../../../../../theme";
20
20
  import { Offer } from "../../../../../types/offer";
21
21
  import { useConfigContext } from "../../../../config/ConfigContext";
@@ -185,10 +185,15 @@ export const TokenGatedItem = ({
185
185
  coreSDK
186
186
  }
187
187
  );
188
- const { data: erc721TokenUri } = useErc721TokenUri(
188
+ const pairsContractTokens = [
189
189
  {
190
190
  contractAddress: condition?.tokenAddress,
191
191
  tokenIds: [condition?.minTokenId]
192
+ }
193
+ ];
194
+ const { data: erc721TokenUri } = useErc721TokenUris(
195
+ {
196
+ pairsContractTokens
192
197
  },
193
198
  {
194
199
  enabled:
@@ -198,10 +203,9 @@ export const TokenGatedItem = ({
198
203
  coreSDK
199
204
  }
200
205
  );
201
- const { data: erc1155Uri } = useErc1155Uri(
206
+ const { data: erc1155Uri } = useErc1155Uris(
202
207
  {
203
- contractAddress: condition?.tokenAddress,
204
- tokenIds: [condition?.minTokenId]
208
+ pairsContractTokens
205
209
  },
206
210
  {
207
211
  enabled:
@@ -230,17 +234,25 @@ export const TokenGatedItem = ({
230
234
  );
231
235
 
232
236
  const tokenIdForImage = condition?.minTokenId;
233
- const { data: erc721Image } = useGetTokenUriImage(
237
+ const { data: erc721Image } = useGetTokenUriImages(
234
238
  {
235
- tokenUris: erc721TokenUri,
236
- tokenIds: [tokenIdForImage]
239
+ pairsTokenUrisIds: [
240
+ {
241
+ tokenUris: erc721TokenUri?.[0],
242
+ tokenIds: [tokenIdForImage]
243
+ }
244
+ ]
237
245
  },
238
246
  { enabled: !!(erc721TokenUri && erc721TokenUri[0] && tokenIdForImage) }
239
247
  );
240
- const { data: erc1155Image } = useGetTokenUriImage(
248
+ const { data: erc1155Image } = useGetTokenUriImages(
241
249
  {
242
- tokenUris: erc1155Uri,
243
- tokenIds: [tokenIdForImage]
250
+ pairsTokenUrisIds: [
251
+ {
252
+ tokenUris: erc1155Uri?.[0],
253
+ tokenIds: [tokenIdForImage]
254
+ }
255
+ ]
244
256
  },
245
257
  { enabled: !!(erc1155Uri && erc1155Uri[0] && tokenIdForImage) }
246
258
  );
@@ -255,9 +267,9 @@ export const TokenGatedItem = ({
255
267
  currencies={[currency]}
256
268
  />
257
269
  ) : erc721Image ? (
258
- <ErcImage src={erc721Image[0]} alt="erc721" />
270
+ <ErcImage src={erc721Image[0][0]} alt="erc721" />
259
271
  ) : erc1155Image ? (
260
- <ErcImage src={erc1155Image[0]} alt="erc1155" />
272
+ <ErcImage src={erc1155Image[0][0]} alt="erc1155" />
261
273
  ) : null}
262
274
  </>
263
275
  );
@@ -13,6 +13,45 @@ export const ProductCardLabelWrapper = styled.div`
13
13
  z-index: 1;
14
14
  `;
15
15
 
16
+ export const TopLeftRibbon = styled.div`
17
+ --d: 6px; /* folded part */
18
+ position: relative;
19
+ z-index: 1;
20
+ &:before {
21
+ content: attr(data-text);
22
+ font-size: var(--f);
23
+ font-weight: 600;
24
+ /* I : position & coloration */
25
+ position: absolute;
26
+ top: 0;
27
+ left: 0;
28
+ transform: translate(0%, 125%) rotate(-45deg);
29
+ transform-origin: bottom left;
30
+ padding: 5px 35px calc(var(--d) + 5px);
31
+ color: ${({ theme }) => theme?.colors?.light.white};
32
+ background: linear-gradient(rgba(0, 0, 0, 0.5) 0 0) bottom/100% var(--d)
33
+ no-repeat ${({ theme }) => theme?.colors?.light.secondary};
34
+ /* II : clipping */
35
+ clip-path: polygon(
36
+ 0 0,
37
+ 100% 0,
38
+ 100% 100%,
39
+ calc(100% - var(--d)) calc(100% - var(--d)),
40
+ var(--d) calc(100% - var(--d)),
41
+ 0 100%
42
+ );
43
+ /* III : masking */
44
+ -webkit-mask:
45
+ linear-gradient(135deg, transparent calc(50% - var(--d) * 0.707), #fff 0)
46
+ bottom left,
47
+ linear-gradient(-135deg, transparent calc(50% - var(--d) * 0.707), #fff 0)
48
+ bottom right;
49
+ -webkit-mask-size: 300vmax 300vmax;
50
+ -webkit-mask-composite: destination-in;
51
+ mask-composite: intersect;
52
+ }
53
+ `;
54
+
16
55
  export const ProductCardCreator = styled.div`
17
56
  display: flex;
18
57
  flex-direction: column;
@@ -130,8 +169,10 @@ export const ProductCardWrapper = styled.div<{ $isHoverDisabled: boolean }>`
130
169
  ? css`
131
170
  transition: all 300ms ease-in-out;
132
171
  &:hover {
133
- box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.05),
134
- 4px 4px 4px rgba(0, 0, 0, 0.05), 8px 8px 8px rgba(0, 0, 0, 0.05),
172
+ box-shadow:
173
+ 0px 0px 0px rgba(0, 0, 0, 0.05),
174
+ 4px 4px 4px rgba(0, 0, 0, 0.05),
175
+ 8px 8px 8px rgba(0, 0, 0, 0.05),
135
176
  16px 16px 16px rgba(0, 0, 0, 0.05);
136
177
 
137
178
  [data-image-wrapper] {
@@ -11,6 +11,7 @@ import {
11
11
  ProductCardBottomContent,
12
12
  ProductCardCreator,
13
13
  ProductCardCreatorAvatar,
14
+ TopLeftRibbon,
14
15
  ProductCardCreatorName,
15
16
  ProductCardData,
16
17
  ProductCardImageWrapper,
@@ -63,7 +64,7 @@ const Wrapper = ({
63
64
  return <>{children}</>;
64
65
  };
65
66
  export const PhygitalLabel = () => {
66
- return <ProductCardLabelWrapper>Phygital</ProductCardLabelWrapper>;
67
+ return <TopLeftRibbon data-text="Phygital" />;
67
68
  };
68
69
  export const ProductCard = (props: IProductCard) => {
69
70
  const {
@@ -1,5 +1,5 @@
1
1
  import { CameraSlash, Image as ImageIcon } from "phosphor-react";
2
- import React, { useState } from "react";
2
+ import React, { useEffect, useState } from "react";
3
3
  import styled from "styled-components";
4
4
 
5
5
  import { buttonText } from "./styles";
@@ -82,6 +82,9 @@ interface IImage {
82
82
  withLoading?: boolean;
83
83
  optimizationOpts?: Partial<ImageOptimizationOpts>;
84
84
  onSetStatus?: (status: LoadingStatus) => void;
85
+ overrides?: {
86
+ ipfsGateway?: string;
87
+ };
85
88
  }
86
89
  const IpfsImage: React.FC<IImage & React.HTMLAttributes<HTMLDivElement>> = ({
87
90
  src,
@@ -92,6 +95,7 @@ const IpfsImage: React.FC<IImage & React.HTMLAttributes<HTMLDivElement>> = ({
92
95
  withLoading = true,
93
96
  optimizationOpts,
94
97
  onSetStatus,
98
+ overrides,
95
99
  ...rest
96
100
  }) => {
97
101
  const { ipfsGateway } = useIpfsContext();
@@ -103,10 +107,21 @@ const IpfsImage: React.FC<IImage & React.HTMLAttributes<HTMLDivElement>> = ({
103
107
  onSetStatus?.(innerStatus);
104
108
  };
105
109
  const [currentSrc, setCurrentSrc] = useState<string>(
106
- getImageUrl(src, ipfsGateway, optimizationOpts)
110
+ getImageUrl(src, overrides?.ipfsGateway || ipfsGateway, optimizationOpts)
107
111
  );
108
112
  const [didOriginalSrcFail, setDidOriginalSrcFail] = useState<boolean>(false);
109
-
113
+ useEffect(() => {
114
+ if (src === currentSrc) {
115
+ return;
116
+ }
117
+ // reset all if src changes
118
+ setStatus(withLoading ? "loading" : "success");
119
+ setCurrentSrc(
120
+ getImageUrl(src, overrides?.ipfsGateway || ipfsGateway, optimizationOpts)
121
+ );
122
+ setDidOriginalSrcFail(false);
123
+ // eslint-disable-next-line react-hooks/exhaustive-deps
124
+ }, [src]);
110
125
  const isError = status === "error";
111
126
  const isLoading = status === "loading";
112
127
  const isSuccess = status === "success";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./CommitWidgetProviders";
9
9
  import GlobalStyle from "../../styles/GlobalStyle";
10
10
  import { CSSProperties } from "styled-components";
11
- import { useProvider } from "../../../hooks/connection/connection";
11
+
12
12
  type CommitProps = {
13
13
  buttonProps?: Omit<ButtonProps, "onClick">;
14
14
  trigger?: ComponentType<{ onClick: () => unknown }> | undefined;
@@ -0,0 +1,71 @@
1
+ import { CoreSDK, subgraph } from "@bosonprotocol/core-sdk";
2
+ import { isNftItem } from "../../lib/bundle/filter";
3
+ import { useErc721TokenUris } from "../contracts/erc721/useErc721TokenUris";
4
+ import { useErc1155Uris } from "../contracts/erc1155/useErc1155Uris";
5
+ import { useGetTokenUriImages } from "../contracts/useGetTokenUriImages";
6
+ import { isTruthy } from "../../types/helpers";
7
+
8
+ export const useBundleItemsImages = ({
9
+ bundleItems,
10
+ coreSDK
11
+ }: {
12
+ bundleItems:
13
+ | Extract<
14
+ subgraph.OfferFieldsFragment["metadata"],
15
+ { __typename: "BundleMetadataEntity" }
16
+ >["items"]
17
+ | undefined;
18
+ coreSDK: CoreSDK;
19
+ }) => {
20
+ const pairsContractTokens = bundleItems?.map((bundleItem) =>
21
+ isNftItem(bundleItem)
22
+ ? {
23
+ contractAddress: bundleItem.contract,
24
+ tokenIds: [
25
+ bundleItem.tokenId ||
26
+ bundleItem.tokenIdRange?.min ||
27
+ bundleItem.tokenIdRange?.max
28
+ ]
29
+ }
30
+ : null
31
+ );
32
+ const { data: erc721TokenUris } = useErc721TokenUris(
33
+ {
34
+ pairsContractTokens
35
+ },
36
+ {
37
+ enabled: !!pairsContractTokens?.length,
38
+ coreSDK
39
+ }
40
+ );
41
+ const { data: erc1155Uris } = useErc1155Uris(
42
+ {
43
+ pairsContractTokens
44
+ },
45
+ {
46
+ enabled: !!pairsContractTokens?.length,
47
+ coreSDK
48
+ }
49
+ );
50
+ const { data: ercImages } = useGetTokenUriImages(
51
+ {
52
+ pairsTokenUrisIds: pairsContractTokens?.map((pair, index) => {
53
+ return {
54
+ tokenIds: pair?.tokenIds,
55
+ tokenUris: erc721TokenUris?.[index]?.filter(isTruthy).length
56
+ ? erc721TokenUris?.[index]
57
+ : erc1155Uris?.[index]
58
+ };
59
+ })
60
+ },
61
+ { enabled: !!pairsContractTokens?.length }
62
+ );
63
+ const images = bundleItems?.map((bundleItem, index) => {
64
+ const img = ercImages?.[index][0] || ""; // image of first tokenId
65
+ if (isNftItem(bundleItem)) {
66
+ return img || bundleItem.image;
67
+ }
68
+ return img;
69
+ });
70
+ return { images };
71
+ };
@@ -0,0 +1,52 @@
1
+ import { CoreSDK } from "@bosonprotocol/core-sdk";
2
+ import { useQuery } from "react-query";
3
+
4
+ export const useErc1155Uris = (
5
+ props: {
6
+ pairsContractTokens:
7
+ | ({
8
+ contractAddress: string | undefined | null;
9
+ tokenIds: (string | null | undefined)[] | undefined;
10
+ } | null)[]
11
+ | undefined;
12
+ },
13
+ { enabled, coreSDK }: { enabled: boolean | undefined; coreSDK: CoreSDK }
14
+ ) => {
15
+ return useQuery(
16
+ ["useErc1155Uris", coreSDK.uuid, props],
17
+ async () => {
18
+ const { pairsContractTokens } = props;
19
+ if (!pairsContractTokens) {
20
+ return;
21
+ }
22
+
23
+ return (
24
+ await Promise.all(
25
+ pairsContractTokens.map(async (pair) =>
26
+ pair && pair.contractAddress && pair.tokenIds
27
+ ? await Promise.allSettled(
28
+ pair.tokenIds.map((tokenId) =>
29
+ tokenId && pair.contractAddress
30
+ ? coreSDK.erc1155Uri({
31
+ contractAddress: pair.contractAddress,
32
+ tokenId
33
+ })
34
+ : null
35
+ )
36
+ )
37
+ : null
38
+ )
39
+ )
40
+ ).map((promiseSettled) =>
41
+ promiseSettled
42
+ ? promiseSettled.map((promiseSettled) =>
43
+ promiseSettled.status === "fulfilled"
44
+ ? promiseSettled.value
45
+ : null
46
+ )
47
+ : null
48
+ );
49
+ },
50
+ { enabled }
51
+ );
52
+ };
@@ -0,0 +1,52 @@
1
+ import { CoreSDK } from "@bosonprotocol/core-sdk";
2
+ import { useQuery } from "react-query";
3
+
4
+ export const useErc721TokenUris = (
5
+ props: {
6
+ pairsContractTokens:
7
+ | ({
8
+ contractAddress: string | undefined | null;
9
+ tokenIds: (string | null | undefined)[] | undefined;
10
+ } | null)[]
11
+ | undefined;
12
+ },
13
+ { enabled, coreSDK }: { enabled: boolean | undefined; coreSDK: CoreSDK }
14
+ ) => {
15
+ return useQuery(
16
+ ["useErc721TokenUris", coreSDK.uuid, props],
17
+ async () => {
18
+ const { pairsContractTokens } = props;
19
+ if (!pairsContractTokens) {
20
+ return;
21
+ }
22
+
23
+ return (
24
+ await Promise.all(
25
+ pairsContractTokens.map(async (pair) =>
26
+ pair && pair.contractAddress && pair.tokenIds
27
+ ? await Promise.allSettled(
28
+ pair.tokenIds.map((tokenId) =>
29
+ tokenId && pair.contractAddress
30
+ ? coreSDK.erc721TokenUri({
31
+ contractAddress: pair.contractAddress,
32
+ tokenId
33
+ })
34
+ : null
35
+ )
36
+ )
37
+ : null
38
+ )
39
+ )
40
+ ).map((promiseSettled) =>
41
+ promiseSettled
42
+ ? promiseSettled.map((promiseSettled) =>
43
+ promiseSettled.status === "fulfilled"
44
+ ? promiseSettled.value
45
+ : null
46
+ )
47
+ : null
48
+ );
49
+ },
50
+ { enabled }
51
+ );
52
+ };
@@ -0,0 +1,126 @@
1
+ import { getImageUrl } from "../../lib/images/images";
2
+ import { useQuery } from "react-query";
3
+
4
+ const replaceUrlWithId = ({
5
+ tokenId,
6
+ url
7
+ }: {
8
+ url: string;
9
+ tokenId: string;
10
+ }) => {
11
+ const urlWithIdReplaced = url.replace("{id}", tokenId);
12
+ return urlWithIdReplaced;
13
+ };
14
+
15
+ export const useGetTokenUriImages = (
16
+ props: {
17
+ pairsTokenUrisIds:
18
+ | ({
19
+ tokenUris: (string | null | undefined)[] | undefined | null;
20
+ tokenIds: (string | null | undefined)[] | undefined | null;
21
+ } | null)[]
22
+ | undefined;
23
+
24
+ ipfsGateway?: string;
25
+ },
26
+ { enabled }: { enabled: boolean }
27
+ ) => {
28
+ const { pairsTokenUrisIds, ipfsGateway = "https://ipfs.io/ipfs" } = props;
29
+ return useQuery(
30
+ ["useGetTokenUriImages", props],
31
+ async () => {
32
+ if (!pairsTokenUrisIds) {
33
+ return [];
34
+ }
35
+ try {
36
+ return await Promise.all(
37
+ pairsTokenUrisIds.map(async (pair): Promise<string[]> => {
38
+ if (!pair) {
39
+ return Promise.resolve([]);
40
+ }
41
+ const { tokenIds, tokenUris } = pair;
42
+ if (
43
+ !tokenIds ||
44
+ !tokenUris ||
45
+ tokenUris.length !== tokenIds.length
46
+ ) {
47
+ return Promise.resolve([]);
48
+ }
49
+ return await Promise.all(
50
+ tokenUris.map(async (tokenUri, index): Promise<string> => {
51
+ const tokenId = tokenIds[index];
52
+ if (!tokenUri || !tokenId) {
53
+ return "";
54
+ }
55
+ if (tokenUri.startsWith("data:application/json")) {
56
+ const base64Data = tokenUri.substring(
57
+ tokenUri.indexOf(",") + 1
58
+ );
59
+ const jsonValue = window.atob(base64Data);
60
+ const parsedJson = JSON.parse(jsonValue);
61
+ const image = parsedJson.image;
62
+ const imageUrl = getImageUrl(image, ipfsGateway);
63
+ const urlWithIdReplaced = replaceUrlWithId({
64
+ url: imageUrl,
65
+ tokenId
66
+ });
67
+ return urlWithIdReplaced;
68
+ }
69
+ if (tokenUri.startsWith("ipfs")) {
70
+ const imageUrl = getImageUrl(tokenUri, ipfsGateway);
71
+ const urlWithIdReplaced = replaceUrlWithId({
72
+ url: imageUrl,
73
+ tokenId
74
+ });
75
+
76
+ const fetchedMetadata = await fetch(urlWithIdReplaced);
77
+ try {
78
+ const jsonMetadata = await fetchedMetadata.json();
79
+ const imageUrl = getImageUrl(
80
+ jsonMetadata.image,
81
+ ipfsGateway
82
+ );
83
+ return imageUrl;
84
+ } catch (error) {
85
+ console.debug(error);
86
+ }
87
+
88
+ return urlWithIdReplaced;
89
+ }
90
+ if (tokenUri.startsWith("http")) {
91
+ const urlWithIdReplaced = replaceUrlWithId({
92
+ url: tokenUri,
93
+ tokenId
94
+ });
95
+ const fetchedMetadata = await fetch(urlWithIdReplaced);
96
+ try {
97
+ const jsonMetadata = await fetchedMetadata.json();
98
+ const image = jsonMetadata.image;
99
+ const imageUrl = getImageUrl(image, ipfsGateway);
100
+ return imageUrl;
101
+ } catch (error) {
102
+ console.debug(error);
103
+ }
104
+
105
+ return urlWithIdReplaced;
106
+ }
107
+
108
+ if (tokenUri.startsWith("data:image")) {
109
+ return tokenUri;
110
+ }
111
+
112
+ return "";
113
+ })
114
+ );
115
+ })
116
+ );
117
+ } catch (err) {
118
+ console.error(err);
119
+ throw err;
120
+ }
121
+ },
122
+ {
123
+ enabled
124
+ }
125
+ );
126
+ };
@@ -8,12 +8,12 @@ export * from "./useHandleText";
8
8
  export * from "./useExchanges";
9
9
  export * from "./useMetaTx";
10
10
  export * from "../components/widgets/finance/useOffersBacked";
11
- export * from "./contracts/useGetTokenUriImage";
11
+ export * from "./contracts/useGetTokenUriImages";
12
12
  export * from "./products/useProductByUuid";
13
13
  export * from "./bundles/useBundleByUuid";
14
- export * from "./contracts/erc721/useErc721TokenUri";
14
+ export * from "./contracts/erc721/useErc721TokenUris";
15
15
  export * from "./contracts/erc721/useErc721Name";
16
16
  export * from "./contracts/erc721/useErc721OwnerOf";
17
17
  export * from "./contracts/erc1155/useErc1155Name";
18
- export * from "./contracts/erc1155/useErc1155Uri";
18
+ export * from "./contracts/erc1155/useErc1155Uris";
19
19
  export * from "./uniswap/useIsWindowVisible";
@@ -1,6 +1,8 @@
1
1
  import { CID } from "multiformats/cid";
2
2
  import { sanitizeUrl } from "../url/url";
3
3
 
4
+ const lensIpfs = "https://lens.infura-ipfs.io/ipfs/";
5
+
4
6
  export function getIpfsGatewayUrl(
5
7
  uri: string,
6
8
  opts: {
@@ -10,18 +12,26 @@ export function getIpfsGatewayUrl(
10
12
  if (!uri) {
11
13
  return uri;
12
14
  }
15
+ if (uri.startsWith(lensIpfs)) {
16
+ return uri;
17
+ }
13
18
  const { gateway } = opts;
14
- const cidAndRest = uri.replaceAll("ipfs://", ""); // it may be ipfs://CID/123
15
-
16
19
  try {
17
- const [cid] = cidAndRest.split("/", 1); // it may be CID/123
20
+ const url = new URL(
21
+ uri.startsWith("ipfs://") ? uri.replace("ipfs://", "https://") : uri
22
+ );
23
+ const hostIndex = uri.toLowerCase().indexOf(url.host.toLowerCase());
24
+ const cid = uri.substring(hostIndex, hostIndex + url.host.length); // we cannot use url.host because the browser changes it to lowercase so a lowercased CID would not be valid
18
25
  CID.parse(cid);
19
- return `${gateway}/${cidAndRest}`.replace(/([^:]\/)\/+/g, "$1"); // remove double slash
26
+ return `${gateway}/${cid}${url.pathname === "/" ? "" : url.pathname}${url.search}`.replace(
27
+ /([^:]\/)\/+/g,
28
+ "$1"
29
+ ); // remove double slash
20
30
  } catch (error) {
21
31
  // If CID.parse throws, then it is either not a valid CID or just an URL
22
32
  const cidFromUrl = uri.split("/ipfs/")[1];
23
33
  if (cidFromUrl) {
24
- return getIpfsGatewayUrl(cidFromUrl.split("?")[0], opts);
34
+ return getIpfsGatewayUrl(`ipfs://${cidFromUrl}`, opts);
25
35
  }
26
36
 
27
37
  return sanitizeUrl(uri);