Merge pull request #8 from darkcodi/new-ui

Improve token model
This commit is contained in:
Darkcodi 2022-09-30 05:05:28 -05:00 committed by GitHub
commit 3d33df9234
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 160 additions and 61 deletions

View File

@ -6,8 +6,12 @@ public class TokenDto
public string Name { get; set; }
public string Description { get; set; }
public DateTime CreatedAt { get; set; }
public string ImageFileName { get; set; }
public string ImageFileType { get; set; }
public string ImageFileData { get; set; }
public long? ImageFileSize { get; set; }
public string MainFileName { get; set; }
public string MainFileType { get; set; }
public string MainFileData { get; set; }
public long? MainFileSize { get; set; }
public string CoverFileName { get; set; }
public string CoverFileType { get; set; }
public string CoverFileData { get; set; }
public long? CoverFileSize { get; set; }
}

View File

@ -4,7 +4,10 @@ public class NewFileModel
{
public string Name { get; set; }
public string Description { get; set; }
public string FileData { get; set; }
public string FileName { get; set; }
public long? FileSize { get; set; }
public string MainFileData { get; set; }
public string MainFileName { get; set; }
public long? MainFileSize { get; set; }
public string CoverFileData { get; set; }
public string CoverFileName { get; set; }
public long? CoverFileSize { get; set; }
}

View File

@ -13,6 +13,9 @@ public class TokenMetadata
[JsonProperty("image")]
public string Image { get; set; }
[JsonProperty("animation_url")]
public string AnimationUrl { get; set; }
[JsonProperty("external_url")]
public string ExternalUrl { get; set; }
}

View File

@ -18,7 +18,7 @@
<PackageReference Include="Nethereum.ABI" Version="4.8.0" />
<PackageReference Include="Nethereum.JsonRpc.Client" Version="4.8.0" />
<PackageReference Include="Nethereum.Web3" Version="4.8.0" />
<PackageReference Include="Radzen.Blazor" Version="3.20.4" />
<PackageReference Include="Radzen.Blazor" Version="4.1.5" />
<PackageReference Include="RestEase" Version="1.5.7" />
<PackageReference Include="Solana.Metaplex" Version="1.2.0" />
<PackageReference Include="TG.Blazor.IndexedDB" Version="1.5.0-preview" />

View File

@ -5,17 +5,29 @@
<form onsubmit="@OnSavePressed">
<div class="mb-4">
<h4>Image</h4>
<RadzenFileInput @bind-Value=@Model.FileData @bind-FileName=@Model.FileName @bind-FileSize=@Model.FileSize TValue="string" Class="w-100"/>
<RadzenText TextStyle="TextStyle.H6" Style="display: inline;">Main file</RadzenText><text style="color: red"> *</text>
<RadzenFileInput Error="@OnMainFileError" @bind-Value=@Model.MainFileData @bind-FileName=@Model.MainFileName @bind-FileSize=@Model.MainFileSize TValue="string" Class="w-100"/>
</div>
@if (!string.IsNullOrEmpty(Model.MainFileData) && !string.IsNullOrEmpty(Model.MainFileName) && Model.MainFileSize != null && Model.MainFileSize != 0)
{
var mainFileType = DetermineFileType(Model.MainFileName);
if (!mainFileType.StartsWith("image/") || mainFileType == "image/gif")
{
<div class="mb-4">
<RadzenText TextStyle="TextStyle.H6" Style="display: inline;">Cover file</RadzenText>
<RadzenFileInput Error="@OnCoverFileError" @bind-Value=@Model.CoverFileData @bind-FileName=@Model.CoverFileName @bind-FileSize=@Model.CoverFileSize TValue="string" Class="w-100"/>
</div>
}
}
<div class="mb-4">
<h4>Name</h4>
<RadzenText TextStyle="TextStyle.H6" Style="display: inline;">Name</RadzenText><text style="color: red"> *</text>
<RadzenTextBox Placeholder="YING #668" MaxLength="50" @bind-Value="@Model.Name" Class="w-100"/>
</div>
<div class="mb-4">
<h4>Description</h4>
<RadzenText TextStyle="TextStyle.H6" Style="display: inline;">Description</RadzenText><text style="color: red"> *</text>
<RadzenTextArea Placeholder="YING, ecotype enterprises IP of Inkeverse and the avatar spokesperson for Inkeverse." MaxLength="250" @bind-Value="@Model.Description" Class="w-100"/>
</div>

View File

@ -2,6 +2,7 @@ using MimeTypes;
using NftFaucet.Components;
using NftFaucet.Models;
using NftFaucet.Plugins;
using Radzen;
namespace NftFaucet.Pages;
@ -21,14 +22,28 @@ public partial class CreateTokenDialog : BasicComponent
Name = Model.Name,
Description = Model.Description,
CreatedAt = DateTime.Now,
Image = new TokenMedia
MainFile = new TokenMedia
{
FileName = Model.FileName,
FileType = DetermineFileType(Model.FileName),
FileData = Model.FileData,
FileSize = Model.FileSize!.Value,
FileName = Model.MainFileName,
FileType = DetermineFileType(Model.MainFileName),
FileData = Model.MainFileData,
FileSize = Model.MainFileSize!.Value,
},
};
if (!string.IsNullOrEmpty(Model.CoverFileData) &&
!string.IsNullOrEmpty(Model.CoverFileName) &&
Model.CoverFileSize != null)
{
token.CoverFile = new TokenMedia
{
FileName = Model.CoverFileName,
FileType = DetermineFileType(Model.CoverFileName),
FileData = Model.CoverFileData,
FileSize = Model.CoverFileSize!.Value,
};
}
DialogService.Close(token);
}
@ -51,15 +66,34 @@ public partial class CreateTokenDialog : BasicComponent
if (string.IsNullOrWhiteSpace(Model.Description))
return false;
if (string.IsNullOrEmpty(Model.FileData))
if (string.IsNullOrEmpty(Model.MainFileData))
return false;
if (string.IsNullOrEmpty(Model.FileName))
if (string.IsNullOrEmpty(Model.MainFileName))
return false;
if (Model.FileSize is null or 0)
if (Model.MainFileSize is null or 0)
return false;
return true;
}
private void OnMainFileError(UploadErrorEventArgs args)
{
NotificationService.Notify(NotificationSeverity.Error, "File selection error", args.Message);
Model.MainFileData = null;
Model.MainFileName = null;
Model.MainFileSize = null;
Model.CoverFileData = null;
Model.CoverFileName = null;
Model.CoverFileSize = null;
}
private void OnCoverFileError(UploadErrorEventArgs args)
{
NotificationService.Notify(NotificationSeverity.Error, "File selection error", args.Message);
Model.CoverFileData = null;
Model.CoverFileName = null;
Model.CoverFileSize = null;
}
}

View File

@ -74,24 +74,38 @@ public partial class CreateUploadDialog : BasicComponent
IsUploading = true;
RefreshMediator.NotifyStateHasChangedSafe();
var imageLocationResult = await SelectedUploader.Upload(Token.Image.FileName, Token.Image.FileType, Base64DataToBytes(Token.Image.FileData));
if (imageLocationResult.IsFailure)
var mainFileLocationResult = await SelectedUploader.Upload(Token.MainFile.FileName, Token.MainFile.FileType, Base64DataToBytes(Token.MainFile.FileData));
if (mainFileLocationResult.IsFailure)
{
IsUploading = false;
RefreshMediator.NotifyStateHasChangedSafe();
NotificationService.Notify(NotificationSeverity.Error, "Uploading image failed", imageLocationResult.Error);
NotificationService.Notify(NotificationSeverity.Error, "Failed to upload main file", mainFileLocationResult.Error);
return;
}
var mainFileLocation = mainFileLocationResult.Value;
var imageLocation = imageLocationResult.Value;
var tokenMetadata = GenerateTokenMetadata(Token, imageLocation);
Uri coverFileLocation = null;
if (Token.CoverFile != null)
{
var coverFileLocationResult = await SelectedUploader.Upload(Token.CoverFile.FileName, Token.CoverFile.FileType, Base64DataToBytes(Token.CoverFile.FileData));
if (coverFileLocationResult.IsFailure)
{
IsUploading = false;
RefreshMediator.NotifyStateHasChangedSafe();
NotificationService.Notify(NotificationSeverity.Error, "Failed to upload cover file", coverFileLocationResult.Error);
return;
}
coverFileLocation = coverFileLocationResult.Value;
}
var tokenMetadata = GenerateTokenMetadata(Token, mainFileLocation, coverFileLocation);
var tokenMetadataBytes = Encoding.UTF8.GetBytes(tokenMetadata);
var tokenLocationResult = await SelectedUploader.Upload($"{Token.Id}.json", "application/json", tokenMetadataBytes);
if (tokenLocationResult.IsFailure)
{
IsUploading = false;
RefreshMediator.NotifyStateHasChangedSafe();
NotificationService.Notify(NotificationSeverity.Error, "Uploading metadata failed", tokenLocationResult.Error);
NotificationService.Notify(NotificationSeverity.Error, "Failed to upload metadata", tokenLocationResult.Error);
return;
}
@ -117,13 +131,14 @@ public partial class CreateUploadDialog : BasicComponent
return Convert.FromBase64String(encoded);
}
private static string GenerateTokenMetadata(IToken token, Uri imageLocation)
private static string GenerateTokenMetadata(IToken token, Uri mainFileLocation, Uri coverFileLocation)
{
var tokenMetadata = new TokenMetadata
{
Name = token.Name,
Description = token.Description,
Image = imageLocation.OriginalString,
Image = coverFileLocation != null ? coverFileLocation.OriginalString : mainFileLocation.OriginalString,
AnimationUrl = coverFileLocation != null ? mainFileLocation.OriginalString : null,
ExternalUrl = "https://darkcodi.github.io/nft-faucet/",
};
var metadataJson = JsonConvert.SerializeObject(tokenMetadata, Formatting.Indented);

View File

@ -21,25 +21,36 @@ public partial class TokensPage : BasicComponent
}
private CardListItem MapCardListItem(IToken token)
=> new CardListItem
{
var properties = new List<CardListItemProperty>
{
new CardListItemProperty
{
Name = "Description",
Value = token.Description,
},
};
properties.Add(new CardListItemProperty
{
Name = token.CoverFile == null ? "Size" : "MF Size",
Value = ByteSize.FromBytes(token.MainFile.FileSize).ToString(),
});
if (token.CoverFile != null)
{
properties.Add(new CardListItemProperty
{
Name = "CF Size",
Value = ByteSize.FromBytes(token.CoverFile.FileSize).ToString(),
});
}
return new CardListItem
{
Id = token.Id,
Header = token.Name,
ImageLocation = token.Image.FileData,
Properties = new[]
{
new CardListItemProperty
{
Name = "Description",
Value = token.Description,
},
new CardListItemProperty
{
Name = "Size",
Value = ByteSize.FromBytes(token.Image.FileSize).ToString(),
},
},
ImageLocation = token.CoverFile?.FileData ?? token.MainFile.FileData,
Properties = properties.ToArray(),
};
}
private async Task OpenCreateTokenDialog()
{

View File

@ -6,5 +6,6 @@ public interface IToken
public string Name { get; }
public string Description { get; }
public DateTime CreatedAt { get; }
public ITokenMedia Image { get; }
public ITokenMedia MainFile { get; }
public ITokenMedia CoverFile { get; }
}

View File

@ -6,5 +6,6 @@ public class Token : IToken
public string Name { get; set; }
public string Description { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
public ITokenMedia Image { get; set; }
public ITokenMedia MainFile { get; set; }
public ITokenMedia CoverFile { get; set; }
}

View File

@ -33,7 +33,7 @@ builder.Services.AddMetaMaskBlazor();
builder.Services.AddIndexedDB(dbStore =>
{
dbStore.DbName = "NftFaucet";
dbStore.Version = 1;
dbStore.Version = 2;
dbStore.Stores.Add(new StoreSchema
{
@ -60,10 +60,14 @@ builder.Services.AddIndexedDB(dbStore =>
new IndexSpec {Name = "name", KeyPath = "name", Auto = false},
new IndexSpec {Name = "description", KeyPath = "description", Auto = false},
new IndexSpec {Name = "createdAt", KeyPath = "createdAt", Auto = false},
new IndexSpec {Name = "imageFileName", KeyPath = "imageFileName", Auto = false},
new IndexSpec {Name = "imageFileType", KeyPath = "imageFileType", Auto = false},
new IndexSpec {Name = "imageFileData", KeyPath = "imageFileData", Auto = false},
new IndexSpec {Name = "imageFileSize", KeyPath = "imageFileSize", Auto = false},
new IndexSpec {Name = "mainFileName", KeyPath = "mainFileName", Auto = false},
new IndexSpec {Name = "mainFileType", KeyPath = "mainFileType", Auto = false},
new IndexSpec {Name = "mainFileData", KeyPath = "mainFileData", Auto = false},
new IndexSpec {Name = "mainFileSize", KeyPath = "mainFileSize", Auto = false},
new IndexSpec {Name = "coverFileName", KeyPath = "coverFileName", Auto = false},
new IndexSpec {Name = "coverFileType", KeyPath = "coverFileType", Auto = false},
new IndexSpec {Name = "coverFileData", KeyPath = "coverFileData", Auto = false},
new IndexSpec {Name = "coverFileSize", KeyPath = "coverFileSize", Auto = false},
}
});

View File

@ -25,10 +25,14 @@ public class Mapper
Name = token.Name,
Description = token.Description,
CreatedAt = token.CreatedAt,
ImageFileName = token.Image?.FileName,
ImageFileType = token.Image?.FileType,
ImageFileData = token.Image?.FileData,
ImageFileSize = token.Image?.FileSize,
MainFileName = token.MainFile?.FileName,
MainFileType = token.MainFile?.FileType,
MainFileData = token.MainFile?.FileData,
MainFileSize = token.MainFile?.FileSize,
CoverFileName = token.CoverFile?.FileName,
CoverFileType = token.CoverFile?.FileType,
CoverFileData = token.CoverFile?.FileData,
CoverFileSize = token.CoverFile?.FileSize,
};
public UploadLocationDto ToDto(ITokenUploadLocation uploadLocation)
@ -58,18 +62,25 @@ public class Mapper
};
public IToken ToDomain(TokenDto tokenDto)
=> tokenDto == null ? null : new Token
=> tokenDto == null || string.IsNullOrEmpty(tokenDto.MainFileData) ? null : new Token
{
Id = tokenDto.Id,
Name = tokenDto.Name,
Description = tokenDto.Description,
CreatedAt = tokenDto.CreatedAt,
Image = new TokenMedia
MainFile = new TokenMedia
{
FileName = tokenDto.ImageFileName,
FileType = tokenDto.ImageFileType,
FileData = tokenDto.ImageFileData,
FileSize = tokenDto.ImageFileSize ?? 0,
FileName = tokenDto.MainFileName,
FileType = tokenDto.MainFileType,
FileData = tokenDto.MainFileData,
FileSize = tokenDto.MainFileSize ?? 0,
},
CoverFile = string.IsNullOrEmpty(tokenDto.CoverFileData) ? null : new TokenMedia
{
FileName = tokenDto.CoverFileName,
FileType = tokenDto.CoverFileType,
FileData = tokenDto.CoverFileData,
FileSize = tokenDto.CoverFileSize ?? 0,
},
};

View File

@ -76,7 +76,7 @@ public class StateRepository
if (existingTokens == null || existingTokens.Count == 0)
return Array.Empty<IToken>();
return existingTokens.Select(_mapper.ToDomain).ToArray();
return existingTokens.Select(_mapper.ToDomain).Where(x => x != null).ToArray();
}
public async Task SaveUploadLocation(ITokenUploadLocation uploadLocation)