Skip to content

Commit

Permalink
Merge pull request #289 from Itheum/stg
Browse files Browse the repository at this point in the history
1.11.0 STG -> MAIN
  • Loading branch information
damienen authored Feb 14, 2024
2 parents a2c6295 + c36fa3d commit b5be5b4
Show file tree
Hide file tree
Showing 45 changed files with 1,188 additions and 422 deletions.
440 changes: 250 additions & 190 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "explorer-dapp",
"description": "Itheum Explorer is a DApp for the public to explore and visualize data within the Itheum protocol",
"version": "1.10.5",
"version": "1.11.0",
"author": "Itheum",
"license": "GPL-3.0-or-later",
"dependencies": {
Expand All @@ -22,6 +22,7 @@
"clsx": "2.1.0",
"d3": "7.8.5",
"dompurify": "3.0.8",
"framer-motion": "11.0.3",
"lucide-react": "0.309.0",
"moment": "2.30.1",
"moment-timezone": "0.5.44",
Expand Down
3 changes: 2 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { TransactionsToastList, NotificationModal, SignTransactionsModals } from
import { apiTimeout, walletConnectV2ProjectId, sampleAuthenticatedDomains, ELROND_NETWORK } from "config";
import { MultiversxBubbles, MultiversxInfographics, MyWallet, PageNotFound, Unlock } from "pages";
import { ItheumTrailblazer } from "pages/AppMarketplace/ItheumTrailblazer/ItheumTrailblazer";
import { TimeCapsule } from "pages/AppMarketplace/TimeCapsule/TimeCapsule";
import { NFTunes } from "pages/AppMarketplace/NFTunes";
import { routes, routeNames } from "routes";
import { ThemeProvider } from "./libComponents/ThemeProvider";
Expand Down Expand Up @@ -44,7 +45,7 @@ export const App = () => {
<Route path={`${routeNames.multiversxbubbles}/:targetNonce/:targetMessageToBeSigned`} element={<MultiversxBubbles />} />
<Route path={`${routeNames.multiversxinfographics}/:targetNonce/:targetMessageToBeSigned`} element={<MultiversxInfographics />} />
<Route path={`${routeNames.nftunes}/:targetNonce/:targetMessageToBeSigned`} element={<NFTunes />} />

<Route path={`${routeNames.timecapsule}/:targetNonce/:targetMessageToBeSigned`} element={<TimeCapsule />} />
<Route path={`${routeNames.mywallet}/:targetNonce/:targetMessageToBeSigned`} element={<MyWallet />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
Expand Down
11 changes: 9 additions & 2 deletions src/appsConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ export const MULTIVERSX_INFOGRAPHICS_TOKENS: app_token[] = IS_DEVNET
// { tokenIdentifier: "DATANFTFT-e0b917", nonce: 490 },
]
: [{ tokenIdentifier: "DATANFTFT-e936d4", nonce: 3 }];
export const FEATURED_NF_TUNES_TOKEN: app_token = IS_DEVNET
? { tokenIdentifier: "DATANFTFT-e0b917", nonce: 15 }
: { tokenIdentifier: "DATANFTFT-e936d4", nonce: 4 };
export const NF_TUNES_TOKENS: app_token[] = IS_DEVNET
? [
{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 15 },
{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 2 },
{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 10 },
{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 15 },
{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 34 },
{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 42 },
{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 56 },
// { tokenIdentifier: "DATANFTFT-e0b917", nonce: 529 },
]
: [{ tokenIdentifier: "DATANFTFT-e936d4", nonce: 4 }];
Expand All @@ -46,7 +50,10 @@ export const PLAYSTATION_GAMER_PASSPORT_TOKENS: app_token[] = [
export const ESDT_BUBBLE_TOKENS: app_token[] = [
// { tokenIdentifier: "DATANFTFT-e0b917", nonce: 417 }
];
export const TIMECAPSULE_TOKENS: app_token[] = IS_DEVNET
? [{ tokenIdentifier: "DATANFTFT-e0b917", nonce: 57 }]
: [{ tokenIdentifier: "DATANFTFT-e936d4", nonce: 5 }];

export const SUPPORTED_APPS = IS_DEVNET
? ["itheumtrailblazer", "multiversxbubbles", "esdtBubble", "playstationgamerpassport", "multiversxinfographics", "nftunes"]
? ["itheumtrailblazer", "multiversxbubbles", "esdtBubble", "playstationgamerpassport", "multiversxinfographics", "nftunes", "timecapsule"]
: ["itheumtrailblazer", "multiversxbubbles", "multiversxinfographics", "nftunes"];
Binary file added src/assets/img/nf-tunes/benefits-logo1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/benefits-logo2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/benefits-logo3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/bg-manu.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/manu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/megaphone-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/megaphone.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/music-note-black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/music-note-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/nf-tunes/platforms-logo/xoxno.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/zstorage/back.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/zstorage/cubes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/zstorage/data-lines.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/zstorage/front.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/zstorage/vault-dots.png
Binary file added src/assets/img/zstorage/zstorage-data-vault.png
202 changes: 123 additions & 79 deletions src/components/AudioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { useEffect, useState } from "react";
import { DataNft, ViewDataReturnType } from "@itheum/sdk-mx-data-nft/out";
import { ArrowBigLeft, Library, Loader2, Pause, Play, RefreshCcwDot, SkipBack, SkipForward, Volume1, Volume2, VolumeX } from "lucide-react";
import { ArrowBigLeft, Library, Loader2, Pause, Play, RefreshCcwDot, SkipBack, SkipForward, Volume1, Volume2, VolumeX, XCircle } from "lucide-react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

import DEFAULT_SONG_IMAGE from "assets/img/audio-player-image.png";
import DEFAULT_SONG_LIGHT_IMAGE from "assets/img/audio-player-light-image.png";
import { decodeNativeAuthToken, toastError } from "libs/utils";
import toast from "react-hot-toast";

type AudioPlayerProps = {
dataNftToOpen: DataNft;
songs: any;
tokenLogin: any;
dataNftToOpen?: DataNft;
songs?: any;
tokenLogin?: any;
previewUrl?: string;
};

export const AudioPlayer = (props: AudioPlayerProps) => {
useEffect(() => {
audio.addEventListener("ended", function () {
Expand All @@ -27,12 +30,13 @@ export const AudioPlayer = (props: AudioPlayerProps) => {
// play the song
if (audio.currentTime == 0) togglePlay();
});
props.songs?.forEach((song: any) => {
///TODO if there are more than 10 songs, analyze this
fetchMarshalForSong(song.idx);
});
updateProgress();

if (props.songs) {
props.songs?.forEach((song: any) => {
///TODO if there are more than 10 songs, analyze this
fetchMarshalForSong(song.idx);
});
updateProgress();
}
return () => {
audio.pause();
audio.removeEventListener("timeupdate", updateProgress);
Expand Down Expand Up @@ -119,30 +123,32 @@ export const AudioPlayer = (props: AudioPlayerProps) => {
[index]: "Fetching", // update the value of specific key
}));
/// if not previously fetched, fetch now and save the url of the blob
const res: ViewDataReturnType = await props.dataNftToOpen.viewDataViaMVXNativeAuth({
mvxNativeAuthOrigins: [decodeNativeAuthToken(props.tokenLogin.nativeAuthToken).origin],
mvxNativeAuthMaxExpirySeconds: 3600,

fwdHeaderMapLookup: {
"authorization": `Bearer ${props.tokenLogin?.nativeAuthToken}`,
},

stream: true,
nestedIdxToStream: index, /// get the song for the current index
});

if (!res.error) {
const blobUrl = URL.createObjectURL(res.data);

setSongSource((prevState) => ({
...prevState, // keep all other key-value pairs
[index]: blobUrl, // update the value of specific key
}));
} else {
setSongSource((prevState) => ({
...prevState,
[index]: "Error: " + res.error,
}));
if (props.dataNftToOpen) {
const res: ViewDataReturnType = await props.dataNftToOpen.viewDataViaMVXNativeAuth({
mvxNativeAuthOrigins: [decodeNativeAuthToken(props.tokenLogin.nativeAuthToken).origin],
mvxNativeAuthMaxExpirySeconds: 3600,

fwdHeaderMapLookup: {
"authorization": `Bearer ${props.tokenLogin?.nativeAuthToken}`,
},

stream: true,
nestedIdxToStream: index, /// get the song for the current index
});

if (!res.error) {
const blobUrl = URL.createObjectURL(res.data);

setSongSource((prevState) => ({
...prevState, // keep all other key-value pairs
[index]: blobUrl, // update the value of specific key
}));
} else {
setSongSource((prevState) => ({
...prevState,
[index]: "Error: " + res.error,
}));
}
}
} catch (err) {
setSongSource((prevState) => ({
Expand Down Expand Up @@ -218,7 +224,15 @@ export const AudioPlayer = (props: AudioPlayerProps) => {
};

const handleChangeSong = () => {
if (props.previewUrl) {
audio.src = props.previewUrl;
audio.load();
updateProgress();
audio.currentTime = 0;
return true;
}
const index = props.songs[currentTrackIndex]?.idx;

if (songSource[index]) {
// if we previously fetched the song and it was an error, show again the exact error.
if (songSource[index].includes("Error:")) {
Expand All @@ -245,10 +259,29 @@ export const AudioPlayer = (props: AudioPlayerProps) => {
handleChangeSong();
}, [currentTrackIndex, songSource[props.songs[currentTrackIndex]?.idx]]);

useEffect(() => {
if (props.previewUrl) {
audio.pause();
audio.src = props.previewUrl;
setIsPlaying(false);
setIsLoaded(false);
handleChangeSong();
}
}, [props.previewUrl]);

const showPlaylist = () => {
setDisplayPlaylist(true);
if (props.previewUrl) {
toast.error("This is just a preview. You have to buy the Music Data Nft to see all the songs.", {
icon: (
<button onClick={() => toast.dismiss()}>
<XCircle color="red" />
</button>
),
});
} else {
setDisplayPlaylist(true);
}
};

return (
<div className="bg-gradient-to-br from-[#00C79740] to-[#3D00EA20] bg-blend-multiply">
<div className="bg-[#1b1b1b10] backdrop-contrast-[1.10]">
Expand Down Expand Up @@ -295,26 +328,35 @@ export const AudioPlayer = (props: AudioPlayerProps) => {
) : (
<div className="overflow-hidden w-full flex flex-col bg-bgWhite dark:bg-bgDark items-center justify-center">
<div className=" select-none h-[30%] bg-[#FaFaFa]/25 dark:bg-[#0F0F0F]/25 border-[1px] border-foreground/40 relative md:w-[60%] flex flex-col rounded-xl">
<div className="px-10 pt-10 pb-4 flex items-center">
<div className="px-10 pt-10 pb-4 flex flex-col md:flex-row items-center">
<img
src={props.songs[currentTrackIndex]?.cover_art_url}
src={props.songs ? props.songs[currentTrackIndex]?.cover_art_url : ""}
alt="Album Cover"
className=" select-none w-24 h-24 rounded-md mr-6 border border-grey-900"
className=" select-none w-24 h-24 rounded-md md:mr-6 border border-grey-900"
onError={({ currentTarget }) => {
currentTarget.src = theme === "light" ? DEFAULT_SONG_LIGHT_IMAGE : DEFAULT_SONG_IMAGE;
}}
/>

<div className="flex flex-col select-text">
<div>
{props.previewUrl ? (
<div className="flex flex-col select-text justify-center ">
<span className="font-sans text-lg font-medium leading-7 text-foreground">{props.songs[currentTrackIndex]?.title}</span>{" "}
<span className="ml-2 font-sans text-base font-medium text-muted-foreground">{props.songs[currentTrackIndex]?.date.split("T")[0]}</span>
<span className="font-sans text-base font-medium text-foreground/60">Preview</span>
<span className="font-sans text-base font-medium leading-6 text-muted-foreground overflow-ellipsis overflow-y-auto max-w-[90%] max-h-32 ">
{props.songs[currentTrackIndex]?.description}
</span>
</div>
) : (
<div className="flex flex-col select-text">
<div>
<span className="font-sans text-lg font-medium leading-7 text-foreground">{props.songs[currentTrackIndex]?.title}</span>{" "}
<span className="ml-2 font-sans text-base font-medium text-muted-foreground">{props.songs[currentTrackIndex]?.date.split("T")[0]}</span>
</div>

<span className="font-sans text-base font-medium text-foreground/60">{props.songs[currentTrackIndex]?.category}</span>
<span className="font-sans text-lg font-medium leading-6 text-foreground">{props.songs[currentTrackIndex]?.artist}</span>
<span className="font-sans text-base font-medium leading-6 text-muted-foreground">{props.songs[currentTrackIndex]?.album}</span>
</div>
<span className="font-sans text-base font-medium text-foreground/60">{props.songs[currentTrackIndex]?.category}</span>
<span className="font-sans text-lg font-medium leading-6 text-foreground">{props.songs[currentTrackIndex]?.artist}</span>
<span className="font-sans text-base font-medium leading-6 text-muted-foreground">{props.songs[currentTrackIndex]?.album}</span>
</div>
)}
</div>

<div className="gap-2 text-foreground select-none w-full flex flex-row justify-center items-center px-10 pb-6">
Expand Down Expand Up @@ -368,45 +410,47 @@ export const AudioPlayer = (props: AudioPlayerProps) => {
</button>
</div>
</div>
<div className="w-[80%] 2xl:w-[70%] mt-8 mx-auto">
<h4 className="select-none flex justify-start font-semibold text-foreground mt-4 mb-2">{`Tracklist ${props.songs.length} songs`} </h4>
<Slider {...settings}>
{props.songs.map((song: any, index: number) => {
return (
<div key={index} className=" w-32 xl:w-64 shadow-none flex items-center justify-center">
<div
onClick={() => {
setCurrentTrackIndex(index);
}}
className="mx-auto w-32 xl:w-64 select-none flex flex-col xl:flex-row items-center justify-center bg-[#fafafa]/25 dark:bg-[#0f0f0f]/25 cursor-pointer transition-shadow duration-300 shadow-xl hover:shadow-inner hover:shadow-teal-200 rounded-2xl text-foreground border-[1px] border-foreground/40">
<div className="w-[80%] xl:w-[40%] justify-center">
<img
src={song.cover_art_url}
alt="Album Cover"
className="h-24 p-2 rounded-md"
onError={({ currentTarget }) => {
currentTarget.src = theme === "light" ? DEFAULT_SONG_LIGHT_IMAGE : DEFAULT_SONG_IMAGE;
}}
/>
</div>
<div className=" xl:w-[60%] flex flex-col justify-center text-center ">
<h6 className=" text-base text-foreground truncate ">{song.title}</h6>
<p className="font-sans text-base font-medium leading-6 text-muted-foreground truncate">{song.artist}</p>
{!props.previewUrl && (
<div className="w-[80%] 2xl:w-[70%] mt-8 mx-auto">
<h4 className="select-none flex justify-start font-semibold text-foreground mt-4 mb-2">{`Tracklist ${props.songs.length} songs`} </h4>
<Slider {...settings}>
{props.songs.map((song: any, index: number) => {
return (
<div key={index} className=" w-32 xl:w-64 shadow-none flex items-center justify-center">
<div
onClick={() => {
setCurrentTrackIndex(index);
}}
className="mx-auto w-32 xl:w-64 select-none flex flex-col xl:flex-row items-center justify-center bg-[#fafafa]/25 dark:bg-[#0f0f0f]/25 cursor-pointer transition-shadow duration-300 shadow-xl hover:shadow-inner hover:shadow-teal-200 rounded-2xl text-foreground border-[1px] border-foreground/40">
<div className="w-[80%] xl:w-[40%] justify-center">
<img
src={song.cover_art_url}
alt="Album Cover"
className="h-24 p-2 rounded-md"
onError={({ currentTarget }) => {
currentTarget.src = theme === "light" ? DEFAULT_SONG_LIGHT_IMAGE : DEFAULT_SONG_IMAGE;
}}
/>
</div>
<div className=" xl:w-[60%] flex flex-col justify-center text-center ">
<h6 className=" text-base text-foreground truncate ">{song.title}</h6>
<p className="font-sans text-base font-medium leading-6 text-muted-foreground truncate">{song.artist}</p>
</div>
</div>
</div>
</div>
);
})}
</Slider>
<style>
{`
);
})}
</Slider>
<style>
{`
/* CSS styles for Swiper navigation arrows */
.slick-prev:before,
.slick-next:before {
color: ${theme === "light" ? "black;" : "white;"},
}`}
</style>
</div>
</style>
</div>
)}
</div>
)}
</div>
Expand Down
14 changes: 10 additions & 4 deletions src/components/DataNftCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { DataNft } from "@itheum/sdk-mx-data-nft/out";
import { useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks/useGetNetworkConfig";
import { MARKETPLACE_DETAILS_PAGE } from "config";
import { convertToLocalString } from "libs/utils";
import { cn, convertToLocalString } from "libs/utils";
import { Modal } from "./Modal/Modal";
import { MXAddressLink } from "./MXAddressLink";
import { Button } from "../libComponents/Button";
Expand All @@ -22,6 +22,7 @@ export function DataNftCard({
modalTitleStyle,
hasFilter,
filterData,
cardStyles,
}: {
index: number;
dataNft: DataNft;
Expand All @@ -35,6 +36,7 @@ export function DataNftCard({
modalTitleStyle?: string;
hasFilter?: boolean;
filterData?: Array<IFilterData>;
cardStyles?: string;
}) {
const {
network: { explorerAddress },
Expand All @@ -45,7 +47,11 @@ export function DataNftCard({

return (
<div className="mb-3">
<Card className="border-[0.5px] dark:border-slate-100/30 border-slate-300 bg-transparent rounded-[2.37rem] base:w-[18.5rem] md:w-[20.6rem]">
<Card
className={cn(
cardStyles,
"border-[0.5px] dark:border-slate-100/30 border-slate-300 bg-transparent rounded-[2.37rem] base:w-[18.5rem] md:w-[20.6rem]"
)}>
<CardContent className="flex flex-col p-3">
<div className="mb-4 flex justify-center">
<img className="md:w-auto base:w-[15rem]" src={!isLoading ? dataNft.nftImgUrl : "https://media.elrond.com/nfts/thumbnail/default.png"} />
Expand Down Expand Up @@ -97,7 +103,7 @@ export function DataNftCard({
<div className="grid grid-cols-12 mb-1">
<span className="col-span-4 opacity-6 base:text-sm md:text-base">Royalties:</span>
<span className="col-span-8 text-left base:text-sm md:text-base">
{isNaN(dataNft.royalties) ? "0%" : convertToLocalString(dataNft.royalties * 100, 2) + "%"}
{isNaN(dataNft.royalties) ? "0%" : (dataNft.royalties * 100).toFixed(2) + "%"}
</span>
</div>
</div>
Expand Down Expand Up @@ -132,7 +138,7 @@ export function DataNftCard({
{modalContent}
</Modal>
) : (
<div className="bg-gradient-to-r from-yellow-300 to-orange-500 p-[1px] rounded-md ">
<div className="text-foreground bg-gradient-to-r from-yellow-300 to-orange-500 p-[1px] rounded-md ">
<Button
className="dark:bg-[#0f0f0f] border-0 rounded-md font-medium tracking-tight !text-sm hover:opacity-90"
variant="outline"
Expand Down
Loading

0 comments on commit b5be5b4

Please sign in to comment.