From 9360a03f9459644e9de832af878cec9f66ff6bc4 Mon Sep 17 00:00:00 2001 From: Milad Raeisi <6504337+miladsoft@users.noreply.github.com> Date: Wed, 3 Apr 2024 22:51:46 +0400 Subject: [PATCH] Fixed wallet UI (#63) * Remove extra js codes * Fix wallet UI except modals * Fixed create and recover modal UI * Fixed wallet words modad UI * Fixed tables UI * Fixed checkbox UI --- src/Angor/Client/Pages/Founder.razor | 20 +- src/Angor/Client/Pages/Investor.razor | 137 +-- src/Angor/Client/Pages/Penalties.razor | 99 ++- src/Angor/Client/Pages/Settings.razor | 192 ++-- src/Angor/Client/Pages/Signatures.razor | 103 ++- src/Angor/Client/Pages/View.razor | 123 +-- src/Angor/Client/Pages/Wallet.razor | 595 ++++++++----- src/Angor/Client/Shared/MainLayout.razor | 2 +- src/Angor/Client/wwwroot/assets/css/app.css | 26 +- .../Client/wwwroot/assets/css/dashboard.css | 128 +-- src/Angor/Client/wwwroot/assets/js/app.js | 62 +- .../Client/wwwroot/assets/js/dashboard.js | 830 ------------------ src/Angor/Client/wwwroot/index.html | 3 +- 13 files changed, 913 insertions(+), 1407 deletions(-) delete mode 100644 src/Angor/Client/wwwroot/assets/js/dashboard.js diff --git a/src/Angor/Client/Pages/Founder.razor b/src/Angor/Client/Pages/Founder.razor index cc72edb0..da4986f7 100644 --- a/src/Angor/Client/Pages/Founder.razor +++ b/src/Angor/Client/Pages/Founder.razor @@ -11,7 +11,7 @@ @inject NavigationManager NavigationManager @inject IWalletStorage _walletStorage; @inject IClientStorage storage; -@inject IRelayService RelayService; +@inject IRelayService RelayService; @inject IIndexerService _IndexerService @if (!hasWallet) @@ -22,8 +22,8 @@

Founder Page

- - + +
@@ -48,7 +48,7 @@ else { -
+
}
@@ -74,7 +74,7 @@
- @code { +@code { private string founderKey; private string projectId; private List founderProjects = new(); @@ -84,7 +84,7 @@ private NotificationComponent notificationComponent; - + protected override async Task OnInitializedAsync() { @@ -99,7 +99,7 @@ private async Task LookupProjectKeysOnIndexerAsync() { scanningForProjects = true; - + var keys = _walletStorage.GetFounderKeys(); var founderProjectsToLookup = new List(); @@ -128,11 +128,11 @@ if (founderProject != null && founderProject.Metadata is null) founderProject.Metadata = nostrMetadata; // else - // notificationComponent.ShowNotificationMessage($"Couldn't find the project details for the project {nostrMetadata.Name} try adding the missing relay."); //TODO + // notificationComponent.ShowNotificationMessage($"Couldn't find the project details for the project {nostrMetadata.Name} try adding the missing relay."); //TODO break; case { Kind: NostrKind.ApplicationSpecificData }: var projectInfo = JsonSerializer.Deserialize(e.Content, Angor.Shared.Services.RelayService.settings); - if(founderProjects.All(_ => _.ProjectInfo.NostrPubKey != e.Pubkey)) //Getting events from multiple relays + if (founderProjects.All(_ => _.ProjectInfo.NostrPubKey != e.Pubkey)) //Getting events from multiple relays founderProjects.Add(new FounderProject { ProjectInfo = projectInfo }); break; } @@ -147,7 +147,7 @@ else scanningForProjects = false; } - + private void NavigateToCreateProject() { NavigationManager.NavigateTo("/create"); diff --git a/src/Angor/Client/Pages/Investor.razor b/src/Angor/Client/Pages/Investor.razor index 5fc8b3a9..9ae2ed2a 100644 --- a/src/Angor/Client/Pages/Investor.razor +++ b/src/Angor/Client/Pages/Investor.razor @@ -23,9 +23,9 @@

Invested Portfolio

-
- - + + +
@@ -63,65 +63,78 @@
-

Your Projects

-
- - - - - - - - - - - - - - - - - @foreach(var project in projects) - { - Stats.TryGetValue(project.ProjectInfo.ProjectIdentifier, out var stats); - - - - - - - - - - - - - - } - -
Funding Target (@network.CoinTicker)Raised (@network.CoinTicker)Raised (% Target)Project StatusMy Investment (@network.CoinTicker)Spent by FounderAvailable to FounderIn Recovery
- @TrimString(@project.ProjectInfo.ProjectIdentifier) - @project.Metadata?.Name@project.ProjectInfo.TargetAmount @network.CoinTicker@Money.Satoshis(stats?.AmountInvested ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker @((stats?.AmountInvested ?? 0) * 100 / Money.Coins(project.ProjectInfo.TargetAmount).Satoshi) % - @if (project.ProjectInfo.StartDate < DateTime.UtcNow) - { -

Funding

- } - else - { -

Live

- } -
@Money.Satoshis(project.AmountInvested ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker - @if (!project.SignaturesInfo?.Signatures.Any() ?? false) - { - - } - --@Money.Satoshis(project.AmountInRecovery ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker
+
+
+
+
+
+
Your Projects
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + @foreach (var project in projects) + { + Stats.TryGetValue(project.ProjectInfo.ProjectIdentifier, out var stats); + + + + + + + + + + + + + } + +
NameFunding Target (@network.CoinTicker)Raised (@network.CoinTicker)Raised (% Target)Project StatusMy Investment (@network.CoinTicker)Spent by FounderAvailable to FounderIn Recovery
+ @project.Metadata?.Name + @project.ProjectInfo.TargetAmount @network.CoinTicker@Money.Satoshis(stats?.AmountInvested ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker @((stats?.AmountInvested ?? 0) * 100 / Money.Coins(project.ProjectInfo.TargetAmount).Satoshi) % + @if (project.ProjectInfo.StartDate < DateTime.UtcNow) + { +

Funding

+ } + else + { +

Live

+ } +
+ @Money.Satoshis(project.AmountInvested ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker + @if (!project.SignaturesInfo?.Signatures.Any() ?? false) + { + + } + --@Money.Satoshis(project.AmountInRecovery ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker
+
+
+
+
- @code { private List projects = new(); @@ -131,8 +144,8 @@ int TotalFundedProjects = 0; long TotalInRecovery = 0; - public Dictionary Stats = new(); - + public Dictionary Stats = new(); + protected override async Task OnInitializedAsync() { hasWallet = _walletStorage.HasWallet(); @@ -148,7 +161,7 @@ abi.UpdateAccountBalanceInfo(accountInfo, unconfirmedInfo); TotalFundedProjects = projects.Count; - TotalInvested = projects.Sum(s => s.AmountInvested ?? 0); + TotalInvested = projects.Sum(s => s.AmountInvested ?? 0); TotalWallet = abi.TotalBalance; TotalInRecovery = projects.Sum(s => s.AmountInRecovery ?? 0); @@ -161,7 +174,7 @@ try { Stats.Clear(); - + foreach (var project in projects) { var projectStats = await _IndexerService.GetProjectStatsAsync(project.ProjectInfo.ProjectIdentifier); @@ -188,4 +201,4 @@ { NavigationManager.NavigateTo("/penalties"); } -} \ No newline at end of file +} diff --git a/src/Angor/Client/Pages/Penalties.razor b/src/Angor/Client/Pages/Penalties.razor index 96dd572e..eef3e928 100644 --- a/src/Angor/Client/Pages/Penalties.razor +++ b/src/Angor/Client/Pages/Penalties.razor @@ -30,44 +30,59 @@ {
-
-

Penalties Details

- - - - - - - - - - @foreach (var penalty in penaltyProjects) - { - - - - +
Project IDAmount in PenaltyDays Left
@penalty.ProjectIdentifier@penalty.Amount @network.CoinTicker - @if (penalty.IsExpired) - { - if (penalty.IsReleased) - { - - } - else - { - - } - } - else + +
+
+
+
+
+
Penalties Details
+
+
+
+
+
+ + + + + + + + + + @foreach (var penalty in penaltyProjects) { - + + + + + } - - - } - -
Project IDAmount in PenaltyDays Left
@penalty.ProjectIdentifier@penalty.Amount @network.CoinTicker + @if (penalty.IsExpired) + { + if (penalty.IsReleased) + { + + } + else + { + + } + } + else + { + + } +
+
+
+
+
+ + } @@ -86,7 +101,7 @@ public int DaysLeftForPenalty; } - + protected override async Task OnInitializedAsync() { if (hasWallet) @@ -98,11 +113,11 @@ if (!string.IsNullOrEmpty(project.RecoveryTransactionId)) { penaltyProjects.Add(new PenaltiesData - { - ProjectIdentifier = project.ProjectInfo.ProjectIdentifier, - RecoveryTransactionId = project.RecoveryTransactionId, - IsReleased = !string.IsNullOrEmpty(project.RecoveryReleaseTransactionId), - }); + { + ProjectIdentifier = project.ProjectInfo.ProjectIdentifier, + RecoveryTransactionId = project.RecoveryTransactionId, + IsReleased = !string.IsNullOrEmpty(project.RecoveryReleaseTransactionId), + }); } } } @@ -121,7 +136,7 @@ foreach (var penaltyProject in penaltyProjects) { var recoveryTansaction = await _IndexerService.GetTransactionInfoByIdAsync(penaltyProject.RecoveryTransactionId); - + var totalsats = recoveryTansaction.Outputs.Where(s => Script.FromHex(s.ScriptPubKey).IsScriptType(ScriptType.P2WSH)).Sum(s => s.Balance); penaltyProject.Amount = Money.Satoshis(totalsats).ToUnit(MoneyUnit.BTC); diff --git a/src/Angor/Client/Pages/Settings.razor b/src/Angor/Client/Pages/Settings.razor index 58b705de..769fcd65 100644 --- a/src/Angor/Client/Pages/Settings.razor +++ b/src/Angor/Client/Pages/Settings.razor @@ -17,7 +17,7 @@ @inherits BaseComponent
-

Settings


+

Settings


@@ -26,7 +26,7 @@

Network Type: @networkType

Explorer url: @_networkConfiguration.GetDefaultExplorerUrl().First().Url

- +
@@ -43,8 +43,8 @@ +

This will wipe your wallet as well!

@@ -54,12 +54,12 @@ I confirm I have a backup of my wallet words, yes wipe all data from this device.
-
+
@if (showConfirmWipeMessage) {

Please tick the box to wipe all storage!

} - +
@@ -82,9 +82,9 @@ } -
-
- +
+
+
-
+

Indexers

@@ -108,40 +108,54 @@ - - - - - - - - - - - @foreach (var indexer in settingsInfo.Indexers) - { - - - - - - - } - -
LinkStatusDefault
@indexer.Url@indexer.Status.ToString() - @if (indexer.IsPrimary) - { - - } - else - { - - } - - -
- -
+
+
+
+
+
+
Indexers
+
+
+
+
+
+ + + + + + + + + + + @foreach (var indexer in settingsInfo.Indexers) + { + + + + + + + } + +
LinkStatusDefault
@indexer.Url@indexer.Status.ToString() + @if (indexer.IsPrimary) + { + + } + else + { + + } + + +
+
+
+
+
+
@*
*@ @@ -153,41 +167,55 @@ - - - - - - - - - - - - @foreach (var relay in settingsInfo.Relays) - { - - - - - - - - } - -
LinkNameStatusDefault
@relay.Url@relay.Name@relay.Status.ToString() - @if (relay.IsPrimary) - { - - } - else - { - - } - - -
- +
+
+
+
+
+
Nostr Relays
+
+
+
+
+
+ + + + + + + + + + + + @foreach (var relay in settingsInfo.Relays) + { + + + + + + + + } + +
LinkNameStatusDefault
@relay.Url@relay.Name@relay.Status.ToString() + @if (relay.IsPrimary) + { + + } + else + { + + } + + +
+
+
+
+
@@ -298,13 +326,13 @@ if (res != null) { settingsInfo.Indexers.Remove(res); - + if (res.IsPrimary && settingsInfo.Indexers.Any()) { var next = settingsInfo.Indexers.OrderBy(a => a.Status).First(); next.IsPrimary = true; } - + _clientStorage.SetSettingsInfo(settingsInfo); } @@ -316,7 +344,7 @@ if (res != null) { settingsInfo.Relays.Remove(res); - + if (res.IsPrimary && settingsInfo.Relays.Any()) { var next = settingsInfo.Relays.OrderBy(a => a.Status).First(); diff --git a/src/Angor/Client/Pages/Signatures.razor b/src/Angor/Client/Pages/Signatures.razor index d786b6f8..fd407c77 100644 --- a/src/Angor/Client/Pages/Signatures.razor +++ b/src/Angor/Client/Pages/Signatures.razor @@ -49,35 +49,52 @@ } else { - - - - - - - - - - @foreach (var signature in signaturesRequests.Where(_ => _ is { TransactionHex: not null, AmountToInvest: not null })) - { - - - - @if (signature.TimeApproved is null) - { - - } - else - { - - } - - } - -
Investment amountReceived atStatus
@Money.Coins(signature.AmountToInvest ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker@signature.TimeArrived.ToString("g")Approved on - @signature.TimeApproved.ToString()
+
+
+
+
+
+
Signatures
+
+
+
+
+
+ + + + + + + + + + @foreach (var signature in signaturesRequests.Where(_ => _ is { TransactionHex: not null, AmountToInvest: not null })) + { + + + + @if (signature.TimeApproved is null) + { + + } + else + { + + } + + } + +
Investment amountReceived atStatus
@Money.Coins(signature.AmountToInvest ?? 0).ToUnit(MoneyUnit.BTC) @network.CoinTicker@signature.TimeArrived.ToString("g")Approved on - @signature.TimeApproved.ToString()
+
+
+
+
+ } + } @@ -199,7 +216,7 @@ private async Task FetchPendingSignatures(FounderProject project) { - await SignService.LookupInvestmentRequestsAsync(project.ProjectInfo.NostrPubKey, null,// project.LastRequestForSignaturesTime , async + await SignService.LookupInvestmentRequestsAsync(project.ProjectInfo.NostrPubKey, null,// project.LastRequestForSignaturesTime , async (eventId, investorPubKey, encryptedMessage, timeArrived) => { Logger.LogDebug($"Sig request event received investorPubKey: {investorPubKey} - timeArrived: {timeArrived}"); @@ -226,21 +243,21 @@ messagesReceived = true; var signatureRequest = new SignatureRequest - { - investorPubKey = investorPubKey, - TimeArrived = timeArrived, - TransactionHex = encryptedMessage, //To be encrypted after js interop is loaded - EventId = eventId - }; + { + investorPubKey = investorPubKey, + TimeArrived = timeArrived, + TransactionHex = encryptedMessage, //To be encrypted after js interop is loaded + EventId = eventId + }; signaturesRequests.Add(signatureRequest); Logger.LogDebug($"Added to pendingSignatures"); - }, + }, () => { Logger.LogDebug($"End of messages"); - if (!messagesReceived) + if (!messagesReceived) return; Logger.LogDebug($"Calling StateHasChanged in EOSE"); @@ -250,7 +267,7 @@ private void FetchFounderApprovalsSignatures(FounderProject project) { - SignService.LookupInvestmentRequestApprovals(project.ProjectInfo.NostrPubKey, + SignService.LookupInvestmentRequestApprovals(project.ProjectInfo.NostrPubKey, (investorPubKey, timeApproved, reqEventId) => { Logger.LogDebug($"Sig response event received investorPubKey: {investorPubKey} - timeApproved: {timeApproved} - reqEventId: {reqEventId}"); @@ -259,11 +276,11 @@ if (signatureRequest is null || signatureRequest.TimeApproved != null) return; //multiple relays could mean the same massage multiple times - + if (signatureRequest.TimeArrived > timeApproved) { Logger.LogDebug($"The event received is replaced by time"); - return; // sig of an old request + return; // sig of an old request } if (reqEventId != null && signatureRequest.EventId != reqEventId) @@ -277,7 +294,7 @@ signatureRequest.TimeApproved = timeApproved; Logger.LogDebug($"Added to pendingSignatures"); - }, + }, () => { scanedForApprovals = true; @@ -291,7 +308,7 @@ if (FounderProject.LastRequestForSignaturesTime is null || FounderProject.LastRequestForSignaturesTime < latestApprovedTime) { FounderProject.LastRequestForSignaturesTime = latestApprovedTime; - Storage.UpdateFounderProject(FounderProject); + Storage.UpdateFounderProject(FounderProject); } } @@ -309,7 +326,7 @@ } else { - passwordComponent.ShowPassword( async () => + passwordComponent.ShowPassword(async () => { await ApproveSignature(signature); ; }); @@ -358,8 +375,8 @@ notificationComponent.ShowErrorMessage(operationResult.Message); } } - - private SignatureInfo signProject(string transactionHex,ProjectInfo info, string founderSigningPrivateKey) + + private SignatureInfo signProject(string transactionHex, ProjectInfo info, string founderSigningPrivateKey) { var investorTrx = _networkConfiguration.GetNetwork().CreateTransaction(transactionHex); diff --git a/src/Angor/Client/Pages/View.razor b/src/Angor/Client/Pages/View.razor index be4f61f8..a66b6a6c 100644 --- a/src/Angor/Client/Pages/View.razor +++ b/src/Angor/Client/Pages/View.razor @@ -36,7 +36,7 @@ } else { -

project not found...

+

project not found...

} } else @@ -55,11 +55,11 @@ if (metadata?.Banner != null) {
- +
} -
+

@metadata?.Name

@metadata?.About


@@ -99,7 +99,7 @@ } - } + } @@ -117,7 +117,7 @@
- + @if (projectStats.Loading) {
@@ -126,10 +126,10 @@ {

Total Raised: @Money.Satoshis(projectStats.TotalRaised).ToUnit(MoneyUnit.BTC) @network.CoinTicker

Total Investors: @projectStats.TotalInvestors

- @*

Total Seeders: @projectStats.TotalSeeders

*@ -

Time Left for Investing: @projectStats.TimeLeft days

+ @*

Total Seeders: @projectStats.TotalSeeders

*@ +

Time Left for Investing: @projectStats.TimeLeft days

} - +
@@ -141,46 +141,48 @@

Stages

- - - - - - - - - - - @for (int index = 0; index < project.ProjectInfo.Stages.Count; index++) - { +
+
Stage Stage %Release Date
+ - - - - + + + + - } - -
@(index + 1)@project.ProjectInfo.Stages[index].AmountToRelease %@project.ProjectInfo.Stages[index].ReleaseDate.ToString("dd/MM/yyyy")Stage Stage %Release Date
+ + + @for (int index = 0; index < project.ProjectInfo.Stages.Count; index++) + { + + @(index + 1) + @project.ProjectInfo.Stages[index].AmountToRelease % + @project.ProjectInfo.Stages[index].ReleaseDate.ToString("dd/MM/yyyy") + + + } + + +
-@*
-
-

Selected Seeders

-
-
- @if (SelectedSeeders.Any()) - { - - } - else - { -

No seeders yet.

- } -
-
*@ + @*
+
+

Selected Seeders

+
+
+ @if (SelectedSeeders.Any()) + { + + } + else + { +

No seeders yet.

+ } +
+
*@
@@ -203,7 +205,7 @@
- +
@@ -212,7 +214,8 @@ } else if (invested) { -

You have already invested in this project. +

+ You have already invested in this project. View the transaction on the explorer.

@@ -225,7 +228,7 @@ }
- +
@@ -273,25 +276,25 @@ }; ProjectStats projectStats = new ProjectStats - { - Loading = true, - TimeLeft = 0, - TotalInvestors = 0, - TotalRaised = 0, - TotalSeeders = 0, - FundingProgressPercent = 0, - }; + { + Loading = true, + TimeLeft = 0, + TotalInvestors = 0, + TotalRaised = 0, + TotalSeeders = 0, + FundingProgressPercent = 0, + }; bool founder = false; bool invested = false; bool findInProgress = false; - private List NostrClients = new (); + private List NostrClients = new(); protected override async Task OnInitializedAsync() { NostrClients = _NetworkConfiguration.GetDefaultRelayUrls().Select(_ => _.Url.ToString()).ToList(); - + project = storage.GetInvestmentProjects().FirstOrDefault(p => p.ProjectInfo.ProjectIdentifier == ProjectId); if (project is InvestorProject findProject) @@ -352,7 +355,7 @@ if (project?.CreationTransactionId != null) { projectExplorerLink = _NetworkConfiguration.GetExplorerUrl().Url + $"/transaction/{project.CreationTransactionId}"; - + await RefreshBalance(); } } @@ -373,7 +376,7 @@ projectStats.TotalRaised = data.AmountInvested; projectStats.TimeLeft = (project.ProjectInfo.StartDate - DateTime.UtcNow).Days; - if (projectStats.TimeLeft < 0) + if (projectStats.TimeLeft < 0) projectStats.TimeLeft = 0; var targetSat = Money.Coins(project.ProjectInfo.TargetAmount).Satoshi; @@ -389,7 +392,7 @@ { projectStats.Loading = false; } - + } private async Task RecoverFunds() @@ -404,7 +407,7 @@ else notificationComponent.ShowNotificationMessage("You must create a wallet if you want to invest"); } - + private async Task CopyNsecToClipboardAsyncCheckPassword() { if (!passwordComponent.HasPassword()) @@ -425,7 +428,7 @@ var nostrKey = _derivationOperations.DeriveProjectNostrPrivateKey(words, founderProject.ProjectIndex); var nsec = NBitcoin.DataEncoders.Encoders.Hex.EncodeData(nostrKey.ToBytes()); await _clipboardService.WriteTextAsync(nsec); - StateHasChanged(); + StateHasChanged(); } } } \ No newline at end of file diff --git a/src/Angor/Client/Pages/Wallet.razor b/src/Angor/Client/Pages/Wallet.razor index 0f0d487c..3ed1f395 100644 --- a/src/Angor/Client/Pages/Wallet.razor +++ b/src/Angor/Client/Pages/Wallet.razor @@ -24,167 +24,268 @@ Wallet and balances -
-

Wallet and balances

- +
+
+
+
+
+ wallet +
+
+ Wallet +
+

+ Wallet and balances +

+
+
+ @if (hasWallet) + { +
+ +
+ } + +
+
+
@if (!hasWallet) { - +
- +
+
+ + info + + No Wallet Found +
+
-
- -
+
+
-
+
-
-@*
+
-
- -
Recover Wallet
-
+
+ +
Recover Wallet
+
-
*@ +
+
+ @if (walletWordsCreateModal) + { + +