Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: nftunes radio loads 1st song via cache for fast playback and other ux and perf fixes #512

Merged
merged 1 commit into from
Sep 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 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.21.0",
"version": "1.21.1",
"author": "Itheum",
"license": "GPL-3.0-or-later",
"dependencies": {
Binary file removed src/assets/img/nf-tunes/platforms-logo/drip.png
Binary file not shown.
Binary file not shown.
Binary file removed src/assets/img/nf-tunes/platforms-logo/itheum.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed src/assets/img/nf-tunes/platforms-logo/tensor.png
Binary file not shown.
Binary file not shown.
Binary file removed src/assets/img/nf-tunes/platforms-logo/xoxno.png
Binary file not shown.
Binary file removed src/assets/img/spreadsheet-nfts/banner.jpg
Binary file not shown.
Binary file added src/assets/img/spreadsheet-nfts/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 35 additions & 6 deletions src/components/AudioPlayer/RadioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import "./AudioPlayer.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 { toastError } from "libs/utils";
import { useAppsStore } from "store/apps";
import { Button } from "../../libComponents/Button";

type RadioPlayerProps = {
@@ -27,6 +28,7 @@ export const RadioPlayer = (props: RadioPlayerProps) => {
const [duration, setDuration] = useState("00:00");
const [isLoaded, setIsLoaded] = useState(false);
const [songSource, setSongSource] = useState<{ [key: number]: string }>({}); // map to keep the already fetched songs
const appsStore = useAppsStore();

useEffect(() => {
audio.addEventListener("ended", function () {
@@ -106,13 +108,40 @@ export const RadioPlayer = (props: RadioPlayerProps) => {
[index]: "Fetching", // update the value of specific key
}));

const blob = await fetch(songs[index - 1].stream).then((r) => r.blob());
const blobUrl = URL.createObjectURL(blob);
let errMsg = null;
let blobUrl = "";

try {
const trackIndex = index - 1;
const nfTunesRadioFirstTrackCachedBlob = appsStore.nfTunesRadioFirstTrackCachedBlob;

// if we have cached the first song blob when Explorer loaded, then just load that from the cache direct to start the playback fast
if (trackIndex === 0 && nfTunesRadioFirstTrackCachedBlob && nfTunesRadioFirstTrackCachedBlob.trim() !== "") {
blobUrl = nfTunesRadioFirstTrackCachedBlob;
console.log(`Track ${trackIndex} Loaded from cache`);
console.log("nfTunesRadioFirstTrackCachedBlob ", nfTunesRadioFirstTrackCachedBlob);
} else {
console.log(`Track ${trackIndex} Loading on-Demand`);
const blob = await fetch(songs[trackIndex].stream).then((r) => r.blob());
blobUrl = URL.createObjectURL(blob);
}

console.log("blobUrl ", blobUrl);
} catch (error: any) {
errMsg = error.toString();
}

setSongSource((prevState) => ({
...prevState, // keep all other key-value pairs
[index]: blobUrl, // update the value of specific key
}));
if (!errMsg) {
setSongSource((prevState) => ({
...prevState, // keep all other key-value pairs
[index]: blobUrl, // update the value of specific key
}));
} else {
setSongSource((prevState) => ({
...prevState,
[index]: "Error: " + errMsg,
}));
}
} catch (err) {
setSongSource((prevState) => ({
...prevState,
47 changes: 35 additions & 12 deletions src/components/Layout/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import { useWallet } from "@solana/wallet-adapter-react";
import { Home, Menu, Store, Wallet, Gamepad2, AreaChart } from "lucide-react";
import { Link } from "react-router-dom";
@@ -7,13 +7,7 @@ import logo192 from "assets/img/logo192.png";
import { SolBitzDropdown } from "components/BitzDropdown/SolBitzDropdown";
import { CopyAddress } from "components/CopyAddress";
import { useGetAccount, useGetIsLoggedIn } from "hooks";
import { cn, sleep } from "libs/utils";
import { APP_MAPPINGS } from "libs/utils/constant";
import { returnRoute } from "pages/Home";
import { routeNames } from "routes";
import { useLocalStorageStore } from "store/LocalStorageStore.ts";
import { SwitchButton } from "./SwitchButton";
import { Button } from "../../libComponents/Button";
import { Button } from "libComponents/Button";
import {
DropdownMenu,
DropdownMenuContent,
@@ -22,16 +16,24 @@ import {
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "../../libComponents/DropdownMenu";
} from "libComponents/DropdownMenu";
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "../../libComponents/NavigationMenu";
import { useAccountStore } from "../../store/account";
} from "libComponents/NavigationMenu";
import { cn, sleep } from "libs/utils";
import { APP_MAPPINGS } from "libs/utils/constant";
import { returnRoute } from "pages/Home";
import { routeNames } from "routes";
import { useAccountStore } from "store/account";
import { useAppsStore } from "store/apps";
import { useLocalStorageStore } from "store/LocalStorageStore.ts";
import { SwitchButton } from "./SwitchButton";
import { getNFTuneFirstTrackBlobData } from "../../pages/AppMarketplace/NFTunes";
import { MvxBitzDropdown } from "../BitzDropdown/MvxBitzDropdown";
import { PlayBitzModal } from "../PlayBitzModal/PlayBitzModal";

@@ -43,8 +45,29 @@ export const Navbar = () => {
const { address: addressMvx } = useGetAccount();
const bitzBalance = useAccountStore((state: any) => state.bitzBalance);
const setDefaultChain = useLocalStorageStore((state) => state.setDefaultChain);

const [showPlayBitzModal, setShowPlayBitzModal] = useState<boolean>(false);
const appsStore = useAppsStore();
const updateNfTunesRadioFirstTrackCachedBlob = appsStore.updateNfTunesRadioFirstTrackCachedBlob;

useEffect(() => {
// lets get the 1st song blob for NFTunes Radio, so we can store in the "browser" cache for fast playback
// ... we do it here as the NavBar loads first always
async function cacheFirstNFTuneRadioTrack() {
const nfTunesRadioFirstTrackCachedBlob = appsStore.nfTunesRadioFirstTrackCachedBlob;

if (nfTunesRadioFirstTrackCachedBlob === "") {
const trackBlobUrl = await getNFTuneFirstTrackBlobData();

if (trackBlobUrl !== "") {
console.log("NFTune Radio 1st Song Data Cached...");
}

updateNfTunesRadioFirstTrackCachedBlob(trackBlobUrl || "");
}
}

cacheFirstNFTuneRadioTrack();
}, []);

return (
<div className="flex flex-row justify-between items-center xl:mx-[7.5rem] md:mx-[4rem] h-20">
32 changes: 12 additions & 20 deletions src/pages/AppMarketplace/NFPodcast/index.tsx
Original file line number Diff line number Diff line change
@@ -5,7 +5,15 @@ import { motion } from "framer-motion";
import { Music, Music2 } from "lucide-react";
import { Link } from "react-router-dom";
import { NF_PODCAST_TOKENS } from "appsConfig";
import musicNoteBlack from "assets/img/nf-tunes/music-note-black.png";
import musicNote from "assets/img/nf-tunes/music-note-white.png";
import disk from "assets/img/nf-tunes-logo-disk.png";
import stick from "assets/img/nf-tunes-logo-stick.png";
import backCube from "assets/img/zstorage/back.png";
import cubes from "assets/img/zstorage/cubes.png";
import dataLines from "assets/img/zstorage/data-lines.png";
import frontCube from "assets/img/zstorage/front.png";
import vault from "assets/img/zstorage/vault-dots.png";
import { MvxDataNftCard, Loader } from "components";
import { AudioPlayer } from "components/AudioPlayer/AudioPlayer";
import { HeaderComponent } from "components/Layout/HeaderComponent";
@@ -15,16 +23,7 @@ import { useGetPendingTransactions } from "hooks";
import { Button } from "libComponents/Button";
import { BlobDataType, ExtendedViewDataReturnType } from "libs/types";
import { decodeNativeAuthToken, getApiDataMarshal, toastError } from "libs/utils";
import { scrollToSection } from "libs/utils";
import { useNftsStore } from "store/nfts";
import musicNoteBlack from "../../../assets/img/nf-tunes/music-note-black.png";
import musicNote from "../../../assets/img/nf-tunes/music-note-white.png";
import stick from "../../../assets/img/nf-tunes-logo-stick.png";
import backCube from "../../../assets/img/zstorage/back.png";
import cubes from "../../../assets/img/zstorage/cubes.png";
import dataLines from "../../../assets/img/zstorage/data-lines.png";
import frontCube from "../../../assets/img/zstorage/front.png";
import vault from "../../../assets/img/zstorage/vault-dots.png";

export const NFPodcast = () => {
const { theme } = useTheme();
@@ -153,30 +152,23 @@ export const NFPodcast = () => {
<div className="flex flex-col justify-center items-center xl:items-start h-[100vsh] w-[100%] pt-8 xl:pt-16 mb-16 xl:mb-32 pl-4 ">
<div className="flex flex-col w-full xl:w-[60%] gap-6">
<div className="flex-row flex items-center">
<span className="text-5xl xl:text-[8rem] text-primary">NF-Podcast</span>
<span className="text-4xl xl:text-[6rem] text-primary">NF-Podcast</span>
<img className="max-h-[30%] mb-6" src={currentTheme === "dark" ? musicNote : musicNoteBlack} />
</div>
<div className="flex flex-row justify-between">
<span className="text-base md:text-2xl text-primary text-light w-[70%]">
<span className="text-base md:text-xl text-primary text-light w-[70%]">
Empowering content creators to engage with their communities and discover alternative avenues for content distribution
</span>
</div>

<button
onClick={() => scrollToSection("data-nfts")}
className="hover:scale-110 transition duration-700 text-sm md:text-xl p-2 md:p-4 rounded-lg max-w-[50%] xl:max-w-[35%] text-white
bg-gradient-to-br from-[#737373] from-5% via-[#A76262] via-40% to-[#5D3899] to-100%">
Visualize NF-Podcasts
</button>
</div>

<div className="flex flex-col xl:flex-row w-full justify-between items-center h-full">
<div className="p-6 pl-32">
<Music className="md:scale-[2] mb-8 ml-[14%] text-primary" />
</div>

<div className="relative min-h-[10rem] h-full w-full xl:-mt-[15%] -z-10">
<div className="absolute w-[60%] max-w-[500px] -mt-[10%] left-[20%] xl:left-[35%] h-[300px] xl:h-[500px] bg-gradient-to-br from-[#737373] from-20% via-[#A76262] via-40% to-[#5D3899] to-80% rounded-full filter blur-2xl opacity-25 "></div>
<div className="relative min-h-[10rem] h-full w-full xl:-mt-[5%] -z-10">
<div className="absolute w-[60%] max-w-[500px] -mt-[10%] left-[20%] xl:left-[35%] h-[300px] xl:h-[500px] bg-gradient-to-br from-[#737373] from-20% via-[#A76262] via-40% to-[#5D3899] to-80% rounded-full filter blur-2xl opacity-25 "></div>
<img className="animate-spin-slow w-[60%] left-[20%] xl:left-[40%] max-w-[350px] absolute" src={disk} alt="disk" />
<img className="absolute left-[60%] lg:left-[50%] xl:left-[70%] top-[-30px] xl:top-[-50px] w-[30%] max-w-[200px]" src={stick} alt="stick" />
</div>
171 changes: 81 additions & 90 deletions src/pages/AppMarketplace/NFTunes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,46 @@
import React, { useEffect, useState } from "react";
import { DataNft, ViewDataReturnType } from "@itheum/sdk-mx-data-nft";
import { DasApiAsset } from "@metaplex-foundation/digital-asset-standard-api";
import { useGetLoginInfo, useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks";
import { useWallet } from "@solana/wallet-adapter-react";
import axios from "axios";
import bs58 from "bs58";
import { motion } from "framer-motion";
import { Music, Music2 } from "lucide-react";
import { Link, useSearchParams } from "react-router-dom";
import { NF_TUNES_TOKENS } from "appsConfig";
import benefitsLogo1 from "assets/img/nf-tunes/benefits-logo1.png";
import benefitsLogo2 from "assets/img/nf-tunes/benefits-logo2.png";
import benefitsLogo3 from "assets/img/nf-tunes/benefits-logo3.png";
import disk from "assets/img/nf-tunes-logo-disk.png";
import { MvxDataNftCard, Loader } from "components";
import { AudioPlayer } from "components/AudioPlayer/AudioPlayer";
import { RadioPlayer } from "components/AudioPlayer/RadioPlayer";
import { HeaderComponent } from "components/Layout/HeaderComponent";
import YouTubeEmbed from "components/YouTubeEmbed";
import { SHOW_NFTS_STEP } from "config";
import { useTheme } from "contexts/ThemeProvider";
import { useGetPendingTransactions } from "hooks";
import { Button } from "libComponents/Button";
import { BlobDataType, ExtendedViewDataReturnType } from "libs/types";
import { decodeNativeAuthToken, getApiDataMarshal, toastError } from "libs/utils";
import { useNftsStore } from "store/nfts";
import megaphoneLight from "assets/img/nf-tunes/megaphone-light.png";
import megaphone from "assets/img/nf-tunes/megaphone.png";
import musicNoteBlack from "assets/img/nf-tunes/music-note-black.png";
import musicNote from "assets/img/nf-tunes/music-note-white.png";
import itheumLogoLight from "assets/img/nf-tunes/platforms-logo/itheum-light.png";
import itheumLogo from "assets/img/nf-tunes/platforms-logo/itheum.png";
import multiversxLogoLight from "assets/img/nf-tunes/platforms-logo/multiversx-light.png";
import multiversxLogo from "assets/img/nf-tunes/platforms-logo/multiversx.png";
import dripLogo from "assets/img/nf-tunes/platforms-logo/drip.png";
import tensorLogo from "assets/img/nf-tunes/platforms-logo/tensor.png";
import xoxnoLogoLight from "assets/img/nf-tunes/platforms-logo/xoxno-light.png";
import xoxnoLogo from "assets/img/nf-tunes/platforms-logo/xoxno.png";
import disk from "assets/img/nf-tunes-logo-disk.png";
import stick from "assets/img/nf-tunes-logo-stick.png";
import backCube from "assets/img/zstorage/back.png";
import cubes from "assets/img/zstorage/cubes.png";
import dataLines from "assets/img/zstorage/data-lines.png";
import frontCube from "assets/img/zstorage/front.png";
import vault from "assets/img/zstorage/vault-dots.png";
import { useWallet } from "@solana/wallet-adapter-react";
import { DasApiAsset } from "@metaplex-foundation/digital-asset-standard-api";
import { useAccountStore } from "store/account";
import { MvxDataNftCard, Loader } from "components";
import { AudioPlayer } from "components/AudioPlayer/AudioPlayer";
import { RadioPlayer } from "components/AudioPlayer/RadioPlayer";
import { SolAudioPlayer } from "components/AudioPlayer/SolAudioPlayer";
import { HeaderComponent } from "components/Layout/HeaderComponent";
import { MvxSolSwitch } from "components/MvxSolSwitch";
import { SolDataNftCard } from "components/SolDataNftCard";
import { SolAudioPlayer } from "components/AudioPlayer/SolAudioPlayer";
import YouTubeEmbed from "components/YouTubeEmbed";
import { SHOW_NFTS_STEP } from "config";
import { useTheme } from "contexts/ThemeProvider";
import { useGetPendingTransactions } from "hooks";
import { Button } from "libComponents/Button";
import { itheumSolPreaccess, itheumSolViewData } from "libs/sol/SolViewData";
import bs58 from "bs58";
import { BlobDataType, ExtendedViewDataReturnType } from "libs/types";
import { decodeNativeAuthToken, getApiDataMarshal, toastError, getApiWeb2Apps } from "libs/utils";
import { useAccountStore } from "store/account";
import { useLocalStorageStore } from "store/LocalStorageStore.ts";
import { useNftsStore } from "store/nfts";

export const NFTunes = () => {
const { theme } = useTheme();
@@ -64,6 +57,8 @@ export const NFTunes = () => {
const { mvxNfts, isLoadingMvx, solNfts, isLoadingSol, updateIsLoadingMvx } = useNftsStore();
const nfTunesTokens = [...NF_TUNES_TOKENS].filter((v) => mvxNfts.find((nft) => nft.collection === v.tokenIdentifier && nft.nonce === v.nonce));
const [stopRadio, setStopRadio] = useState<boolean>(false);
const [radioTracksLoading, setRadioTracksLoading] = useState<boolean>(false);
const [radioTracks, setRadioTracks] = useState<any[]>([]);

// get query param called chain
const [searchParams, setSearchParams] = useSearchParams();
@@ -83,6 +78,17 @@ export const NFTunes = () => {
top: 0,
behavior: "smooth",
});

async function getRadioTracksData() {
setRadioTracksLoading(true);

const allRadioTracks = await getRadioStreamsData();

setRadioTracks(allRadioTracks);
setRadioTracksLoading(false);
}

getRadioTracksData();
}, []);

useEffect(() => {
@@ -290,70 +296,21 @@ export const NFTunes = () => {
<div className="flex flex-col w-full xl:w-[100%] mt-3 mb-[80px]">
<div>
<div className="px-2">NF-Tunes Radio</div>
<RadioPlayer
stopRadioNow={stopRadio}
onPlayHappened={(isPlaying: boolean) => {
if (isPlaying) {
setStopRadio(false);
}
}}
songs={[
{
"idx": 1,
"artist": "Hachi Mugen",
"category": "Lofi Hip Hop",
"album": "Digital EP",
"cover_art_url":
"https://gateway.lighthouse.storage/ipfs/bafybeibyaadr632jyehayikqvkjivaedtg6rvo3hxvdn4oh5hlryen2s6i/94451.image_SipofNostalgia.jpg",
"title": "Sip of Nostalgia",
"stream":
"https://gateway.lighthouse.storage/ipfs/bafybeibyaadr632jyehayikqvkjivaedtg6rvo3hxvdn4oh5hlryen2s6i/94991.audio_SipofNostalgia.mp3",
"airdrop": "https://x.com/itheum/status/1829117957198196930",
},
{
"idx": 2,
"artist": "7g0Strike",
"category": "DnB",
"album": "Love in Disasters",
"cover_art_url": "https://gateway.lighthouse.storage/ipfs/QmQa8nPFvD6KaPCRgNn6umcSDVpG3W4sVGYKko5s7g9J6E/92171.image_SeismicPulse.jpg",
"title": "Seismic Pulse",
"stream": "https://gateway.lighthouse.storage/ipfs/QmQa8nPFvD6KaPCRgNn6umcSDVpG3W4sVGYKko5s7g9J6E/9241.audio_SeismicPulse.mp3",
"buy": "https://drip.haus/itheum/set/5baed2d8-9f49-41bc-af9e-a2364f79c32a",
},
{
"idx": 3,
"artist": "Hachi Mugen",
"category": "Lofi Hip Hop",
"album": "Digital EP",
"cover_art_url":
"https://gateway.lighthouse.storage/ipfs/bafybeibyaadr632jyehayikqvkjivaedtg6rvo3hxvdn4oh5hlryen2s6i/9473.image_MugenCafe.jpg",
"title": "Mugen Cafe",
"stream": "https://gateway.lighthouse.storage/ipfs/bafybeibyaadr632jyehayikqvkjivaedtg6rvo3hxvdn4oh5hlryen2s6i/94303.audio_MugenCafe.mp3",
"airdrop": "https://x.com/itheum/status/1829117957198196930",
},
{
"idx": 4,
"artist": "Hachi Mugen",
"category": "Lofi Hip Hop",
"album": "Digital EP",
"cover_art_url":
"https://gateway.lighthouse.storage/ipfs/bafybeibyaadr632jyehayikqvkjivaedtg6rvo3hxvdn4oh5hlryen2s6i/94952.image_DarkRoast.jpg",
"title": "Dark Roast",
"stream": "https://gateway.lighthouse.storage/ipfs/bafybeibyaadr632jyehayikqvkjivaedtg6rvo3hxvdn4oh5hlryen2s6i/94602.audio_DarkRoast.mp3",
"airdrop": "https://x.com/itheum/status/1829117957198196930",
},
{
"idx": 5,
"category": "MIX",
"artist": "YFGP",
"album": "Mixes",
"title": "DustyMix",
"stream": "https://dataassetsm.yfgpmusic.com/file_storagem/1_hour_boom_bap_mix101.mp3",
"cover_art_url": "https://dataassetsm.yfgpmusic.com/file_storagem/1_hour_boom_bap_mix101cover_art.webp",
"buy": "https://drip.haus/itheum/set/325fab5f-83ad-4fdb-9a89-aba05452f54b",
},
]}
/>
{radioTracksLoading || radioTracks.length === 0 ? (
<div className="select-none h-[30%] bg-[#FaFaFa]/25 dark:bg-[#0F0F0F]/25 border-[1px] border-foreground/40 relative md:w-[100%] flex flex-col rounded-xl mt-2 p-3">
{radioTracksLoading ? "Radio service powering up..." : "Radio service unavailable."}
</div>
) : (
<RadioPlayer
stopRadioNow={stopRadio}
onPlayHappened={(isPlaying: boolean) => {
if (isPlaying) {
setStopRadio(false);
}
}}
songs={radioTracks}
/>
)}
</div>
</div>

@@ -720,3 +677,37 @@ export const NFTunes = () => {
</div>
);
};

export async function getRadioStreamsData(firstNTracks?: number) {
try {
let getRadioStreamAPI = `${getApiWeb2Apps()}/datadexapi/bespoke/nfTunes/getRadioStreams`;

if (firstNTracks) {
getRadioStreamAPI += `?firstNTracks=${firstNTracks}`;
}

const tracksRes = await axios.get(getRadioStreamAPI);
const tracksData = tracksRes.data;

return tracksData;
} catch (e) {
console.error(e);
return [];
}
}

export async function getNFTuneFirstTrackBlobData() {
try {
const firstNFTuneRadioTrackData = await getRadioStreamsData(1);

if (firstNFTuneRadioTrackData && firstNFTuneRadioTrackData.length > 0) {
const blob = await fetch(firstNFTuneRadioTrackData[0].stream).then((r) => r.blob());
const blobUrl = URL.createObjectURL(blob);

return blobUrl;
}
} catch (e) {
console.error(e);
return "";
}
}
56 changes: 28 additions & 28 deletions src/pages/AppMarketplace/SpreadsheetNfts/SpreadsheetNfts.css
Original file line number Diff line number Diff line change
@@ -3,40 +3,40 @@
min-height: 900px;
}

.react-pdf__Document {
display: flex;
flex-direction: column;
align-items: center;
}
.react-pdf__Document {
display: flex;
flex-direction: column;
align-items: center;
}

.react-pdf__Page {
max-width: calc(100% - 2em);
box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
margin: 1em;
min-height: 300px;
}
.react-pdf__Page {
max-width: calc(100% - 2em);
box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
margin: 1em;
min-height: 300px;
}

.react-pdf__Page canvas {
max-width: 100%;
height: auto !important;
}
.react-pdf__Page canvas {
max-width: 100%;
height: auto !important;
}

.react-pdf__message {
padding: 20px;
color: white;
}
.react-pdf__message {
padding: 20px;
color: white;
}

.c-container-paging {
text-align: center;
}

.btn-outline-primary:hover:disabled {
color: grey;
cursor: initial;
}
.btn-outline-primary:hover:disabled {
color: grey;
cursor: initial;
}

.c-pagecount {
margin: 0;
display: flex;
align-items: center;
}
.c-pagecount {
margin: 0;
display: flex;
align-items: center;
}
4 changes: 2 additions & 2 deletions src/pages/AppMarketplace/SpreadsheetNfts/index.tsx
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import { DataNft, ViewDataReturnType } from "@itheum/sdk-mx-data-nft";
import { useGetLoginInfo, useGetNetworkConfig } from "@multiversx/sdk-dapp/hooks";
import { SPREADSHEET_NFTS_TOKENS } from "appsConfig";
import headerHero from "assets/img/spreadsheet-nfts/banner.jpg";
import headerHero from "assets/img/spreadsheet-nfts/banner.png";
import { MvxDataNftCard, Loader } from "components";
import { SHOW_NFTS_STEP } from "config";
import { useGetPendingTransactions } from "hooks";
@@ -156,7 +156,7 @@ export const SpreadsheetNfts = () => {
/>
))
) : (
<h3 className="text-center text-white">No DataNFT</h3>
<h3 className="text-center text-white m-auto mt-2">No Data NFTs found that can unlock this app</h3>
)}
</HeaderComponent>
<div className="m-auto mb-5">
8 changes: 6 additions & 2 deletions src/store/StoreProvider.tsx
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import { useGetAccount } from "hooks";
import { decodeNativeAuthToken, getApiSolNft, getApiWeb2Apps } from "libs/utils";
import { computeRemainingCooldown } from "libs/utils/functions";
import { useAccountStore } from "./account";
import { useAppsStore } from "./apps";
import { useNftsStore } from "./nfts";
import { viewDataJSONCore } from "../pages/AppMarketplace/GetBitz/GetBitzMvx";

@@ -21,15 +22,18 @@ export const StoreProvider = ({ children }: PropsWithChildren) => {
// flag to check locally if we got the MVX NFTs
const [mvxNFTsFetched, setMvxNFTsFetched] = useState<boolean>(false);

// ACCOUNT STORE
// ACCOUNT Store
const updateBitzBalance = useAccountStore((state) => state.updateBitzBalance);
const updateCooldown = useAccountStore((state) => state.updateCooldown);
const updateGivenBitzSum = useAccountStore((state) => state.updateGivenBitzSum);
const updateCollectedBitzSum = useAccountStore((state) => state.updateCollectedBitzSum);
const updateBonusBitzSum = useAccountStore((state) => state.updateBonusBitzSum);
const updateBonusTries = useAccountStore((state) => state.updateBonusTries);

// NFT STORE
// APPs Store
const updateNfTunesRadioFirstTrackCachedBlob = useAppsStore((state) => state.updateNfTunesRadioFirstTrackCachedBlob);

// NFT Store
const { mvxNfts, updateMvxNfts, updateIsLoadingMvx, solNfts, updateSolNfts, updateIsLoadingSol } = useNftsStore();

useEffect(() => {
14 changes: 14 additions & 0 deletions src/store/apps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { create } from "zustand";

type State = {
nfTunesRadioFirstTrackCachedBlob: string;
};

type Action = {
updateNfTunesRadioFirstTrackCachedBlob: (nfTunesRadioFirstTrackCachedBlob: State["nfTunesRadioFirstTrackCachedBlob"]) => void;
};

export const useAppsStore = create<State & Action>((set) => ({
nfTunesRadioFirstTrackCachedBlob: "",
updateNfTunesRadioFirstTrackCachedBlob: (value: string) => set(() => ({ nfTunesRadioFirstTrackCachedBlob: value })),
}));