Skip to content

Commit 5d2456c

Browse files
Enhance Nfts loading (#117)
* ✨ Improve Nfts loading and add option to only load metadata * 🐛 Fix Web3Auth intercept * ✨ Load texture when not cached
1 parent c9fd3de commit 5d2456c

File tree

3 files changed

+71
-39
lines changed

3 files changed

+71
-39
lines changed

Runtime/Plugins/Web3AuthSDK/Web3Auth.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,8 @@ private void request(string path, LoginParams loginParams = null, Dictionary<st
267267

268268
public void setResultUrl(Uri uri)
269269
{
270-
string hash = uri.Fragment;
271-
#if !UNITY_EDITOR && UNITY_WEBGL
272-
if (hash == null || hash.Length == 0)
273-
return;
274-
#else
275-
if (hash == null)
276-
throw new UserCancelledException();
277-
#endif
270+
string hash = uri?.Fragment;
271+
if (string.IsNullOrEmpty(hash)) return;
278272
hash = hash.Remove(0, 1);
279273

280274
Dictionary<string, string> queryParameters = Utils.ParseQuery(uri.Query);

Runtime/codebase/Web3.cs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public static event BalanceChange OnBalanceChange
9898
}
9999

100100
private static List<Nft.Nft> _nfts = new();
101+
private static bool _isLoadingNfts;
102+
101103
public delegate void NFTsUpdate(List<Nft.Nft> nfts, int total);
102104
private static event NFTsUpdate OnNFTsUpdateInternal;
103105
public static event NFTsUpdate OnNFTsUpdate
@@ -292,19 +294,37 @@ public static async UniTask UpdateBalance(Commitment commitment = Commitment.Con
292294
_solAmount = balance;
293295
OnBalanceChangeInternal?.Invoke(balance);
294296
}
295-
297+
296298
/// <summary>
297299
/// Update the list of NFTs owned by the current wallet
298300
/// Notify all registered listeners
299301
/// </summary>
300302
/// <param name="commitment"></param>
301303
public static async UniTask UpdateNFTs(Commitment commitment = Commitment.Confirmed)
302304
{
303-
if(Wallet == null) return;
305+
if(_isLoadingNfts) return;
306+
_isLoadingNfts = true;
307+
await LoadNFTs(notifyRegisteredListeners: true, commitment: commitment);
308+
_isLoadingNfts = false;
309+
}
310+
311+
/// <summary>
312+
/// Update the list of NFTs owned by the current wallet
313+
/// Notify all registered listeners
314+
/// </summary>
315+
/// <param name="loadTexture"></param>
316+
/// <param name="notifyRegisteredListeners">If true, notify the register listeners</param>
317+
/// <param name="commitment"></param>
318+
public static async UniTask<List<Nft.Nft>> LoadNFTs(
319+
bool loadTexture = true,
320+
bool notifyRegisteredListeners = false,
321+
Commitment commitment = Commitment.Confirmed)
322+
{
323+
if(Wallet == null) return null;
304324
var tokens = (await Wallet.GetTokenAccounts(commitment))?
305325
.ToList()
306326
.FindAll(m => m.Account.Data.Parsed.Info.TokenAmount.AmountUlong == 1);
307-
if(tokens == null) return;
327+
if(tokens == null) return null;
308328

309329
// Remove tokens not owned anymore
310330
var tkToRemove = new List<Nft.Nft>();
@@ -327,23 +347,30 @@ public static async UniTask UpdateNFTs(Commitment commitment = Commitment.Confir
327347
.FindAll(x => x.metaplexData.data.offchainData != null);
328348

329349
// Fetch nfts
350+
List<UniTask> loadingTasks = new List<UniTask>();
351+
List<Nft.Nft> nfts = new List<Nft.Nft>(_nfts);
330352
if (tokens is {Count: > 0})
331353
{
332354
var toFetch = tokens
333355
.Where(item => item.Account.Data.Parsed.Info.TokenAmount.AmountUlong == 1)
334-
.Where(item => _nfts
335-
.All(t => t.metaplexData.data.mint!= item.Account.Data.Parsed.Info.Mint));
356+
.Where(item => nfts
357+
.All(t => t.metaplexData.data.mint!= item.Account.Data.Parsed.Info.Mint)).ToArray();
336358
foreach (var item in toFetch)
337359
{
338-
Nft.Nft.TryGetNftData(item.Account.Data.Parsed.Info.Mint, Rpc).AsUniTask()
339-
.ContinueWith(nft =>
360+
var tNft = Nft.Nft.TryGetNftData(item.Account.Data.Parsed.Info.Mint, Rpc, loadTexture: loadTexture).AsUniTask();
361+
loadingTasks.Add(tNft);
362+
tNft.ContinueWith(nft =>
340363
{
341364
if(nft == null) return;
342-
_nfts.Add(nft);
343-
OnNFTsUpdateInternal?.Invoke(_nfts, _nfts.Count + toFetch.Count());
365+
nfts.Add(nft);
366+
if(notifyRegisteredListeners)
367+
OnNFTsUpdateInternal?.Invoke(nfts, nfts.Count + toFetch.Length);
344368
}).Forget();
345369
}
346370
}
371+
await UniTask.WhenAll(loadingTasks);
372+
_nfts = nfts;
373+
return nfts;
347374
}
348375

349376
private static async UniTask SubscribeToWalletEvents(Commitment commitment = Commitment.Confirmed)
@@ -357,7 +384,7 @@ await WsRpc.SubscribeAccountInfoAsync(
357384
Debug.Log("Account changed!, updated lamport: " + accountInfo.Value.Lamports);
358385
_solAmount = accountInfo.Value.Lamports / 1000000000d;
359386
OnBalanceChangeInternal?.Invoke(_solAmount);
360-
UpdateNFTs(commitment).Forget();
387+
UpdateNFTs(commitment: commitment).Forget();
361388
},
362389
commitment
363390
);

Runtime/codebase/nft/Nft.cs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ public class NftImage : iNftFile<Texture2D>
1919
public string extension { get; set; }
2020
public string externalUrl { get; set; }
2121
public Texture2D file { get; set; }
22-
23-
public int heightAndWidth = 75;
2422
}
2523

2624
[Serializable]
@@ -40,43 +38,35 @@ public Nft(Metaplex metaplexData)
4038
/// </summary>
4139
/// <param name="mint"></param>
4240
/// <param name="connection">Rpc client</param>
41+
/// /// <param name="loadTexture"></param>
42+
43+
/// <param name="imageHeightAndWidth"></param>
4344
/// <param name="tryUseLocalContent">If use local content for image</param>
4445
/// <param name="commitment"></param>
4546
/// <returns></returns>
4647
public static async Task<Nft> TryGetNftData(
4748
string mint,
4849
IRpcClient connection,
50+
bool loadTexture = true,
51+
int imageHeightAndWidth = 256,
4952
bool tryUseLocalContent = true,
5053
Commitment commitment = Commitment.Confirmed)
5154
{
5255
if (tryUseLocalContent)
5356
{
5457
var nft = TryLoadNftFromLocal(mint);
55-
if (nft != null)
56-
{
57-
return nft;
58-
}
58+
if(nft != null && loadTexture) await nft.LoadTexture();
59+
if (nft != null) return nft;
5960
}
6061
var newData = await MetadataAccount.GetAccount( connection, new PublicKey(mint), commitment);
6162

6263
if (newData?.metadata == null || newData?.offchainData == null) return null;
63-
var met = new Metaplex(newData);
6464

65-
var nftImage = new NftImage();
66-
if (newData.offchainData != null)
67-
{
68-
var texture = await FileLoader.LoadFile<Texture2D>(newData.offchainData.default_image);
69-
var compressedTexture = FileLoader.Resize(texture, 256, 256);
70-
FileLoader.SaveToPersistentDataPath(Path.Combine(Application.persistentDataPath, $"{mint}.png"), compressedTexture);
71-
if (compressedTexture)
72-
{
73-
nftImage.externalUrl = newData.offchainData.default_image;
74-
//nftImage.file = Resize(texture, nftImage.heightAndWidth, nftImage.heightAndWidth);
75-
nftImage.file = compressedTexture;
76-
met.nftImage = nftImage;
77-
}
78-
}
65+
var met = new Metaplex(newData);
7966
var newNft = new Nft(met);
67+
68+
if (loadTexture) await newNft.LoadTexture(imageHeightAndWidth);
69+
8070
FileLoader.SaveToPersistentDataPath(Path.Combine(Application.persistentDataPath, $"{mint}.json"), newNft.metaplexData.data);
8171
return newNft;
8272
}
@@ -106,5 +96,26 @@ public static Nft TryLoadNftFromLocal(string mint)
10696

10797
return local;
10898
}
99+
100+
/// <summary>
101+
/// Load the texture of the NFT
102+
/// </summary>
103+
/// <param name="nft"></param>
104+
/// <param name="imageHeightAndWidth"></param>
105+
public async Task LoadTexture(int imageHeightAndWidth = 256)
106+
{
107+
if (metaplexData.data.offchainData == null) return;
108+
if (metaplexData.nftImage != null) return;
109+
var nftImage = new NftImage();
110+
var texture = await FileLoader.LoadFile<Texture2D>(metaplexData.data.offchainData.default_image);
111+
var compressedTexture = FileLoader.Resize(texture, imageHeightAndWidth, imageHeightAndWidth);
112+
if (compressedTexture)
113+
{
114+
nftImage.externalUrl = metaplexData.data.offchainData.default_image;
115+
nftImage.file = compressedTexture;
116+
metaplexData.nftImage = nftImage;
117+
}
118+
FileLoader.SaveToPersistentDataPath(Path.Combine(Application.persistentDataPath, $"{metaplexData.data.mint}.png"), compressedTexture);
119+
}
109120
}
110121
}

0 commit comments

Comments
 (0)