diff --git a/src/Angor/Client/Pages/Browse.razor b/src/Angor/Client/Pages/Browse.razor index e89e7275..db20785d 100644 --- a/src/Angor/Client/Pages/Browse.razor +++ b/src/Angor/Client/Pages/Browse.razor @@ -3,6 +3,9 @@ @using Angor.Shared.Models @using Angor.Shared.Services @using Nostr.Client.Keys +@using Nostr.Client.Messages +@using System.Text.Json +@using Angor.Client.Models @inject ICacheStorage SessionStorage; @inject NavigationManager NavigationManager @inject IRelayService _RelayService @@ -15,42 +18,105 @@
+ + +
+ + +
+ + @if (findInProgress) + { +
+
+
+ } + + + @if (findProject != null) + { +
+
+
@findProject.ProjectIdentifier
+

Nostr ID: @(NostrPublicKey.FromHex(findProject.NostrPubKey).Bech32)

- -
-
- - + @if (SessionStorage.IsProjectInStorageById(findProject.ProjectIdentifier)) + { + @if (SessionStorage.IsProjectMetadataStorageByPubkey(findProject.NostrPubKey)) + { + var metadata = SessionStorage.GetProjectMetadataByPubkey(findProject.NostrPubKey); +
+

@metadata?.Name

+

@metadata?.About

+
+ } + + //var info = SessionStorage.GetProjectById(findProject.ProjectIdentifier); + + + } + else + { +

Project not found in any relay!

+ } +
- -

- + } + +
+ +
@if (searchInProgress) { -
+
+
+
} else { @if (projects.Count == 0) { -

No projects found.

+
+

No projects found.

+
} else { - foreach (var project in projects.OrderByDescending(project => project.CreatedOnBlock)) + foreach (var project in projects.OrderBy(project => project.CreatedOnBlock)) {
@project.ProjectIdentifier
-

Nostr ID: @(NostrPublicKey.FromHex(project.NostrPubKey).Bech32)

- +

Nostr ID: @(NostrPublicKey.FromHex(project.NostrPubKey).Bech32)

+ + @if (SessionStorage.IsProjectInStorageById(project.ProjectIdentifier)) + { + @if (SessionStorage.IsProjectMetadataStorageByPubkey(project.NostrPubKey)) + { + var metadata = SessionStorage.GetProjectMetadataByPubkey(project.NostrPubKey); +
+

@metadata?.Name

+

@metadata?.About

+
+ } + + //var info = SessionStorage.GetProjectById(project.ProjectIdentifier); + + + } + else + { +

Project not found in any relay!

+ }
} } } + +
@@ -59,6 +125,9 @@ NotificationComponent notificationComponent; private string searchQuery; bool searchInProgress = false; + bool findInProgress = false; + + ProjectIndexerData? findProject = null; private List projects = new(); @@ -67,11 +136,60 @@ projects = SessionStorage.GetProjectIndexerData() ?? new(); } + private async Task FindProject() + { + findProject = projects.FirstOrDefault(_ => _.ProjectIdentifier == searchQuery); + + if (findProject != null) + { + return; + } + + findInProgress = true; + + findProject = await _IndexerService.GetProjectByIdAsync(searchQuery); + + if (findProject != null) + { + _RelayService.RequestProjectCreateEventsByPubKey(e => + { + switch (e) + { + case { Kind: NostrKind.Metadata }: + var nostrMetadata = JsonSerializer.Deserialize(e.Content, Angor.Shared.Services.RelayService.settings); + if (!SessionStorage.IsProjectMetadataStorageByPubkey(e.Pubkey)) + SessionStorage.StoreProjectMetadata(e.Pubkey, nostrMetadata); + break; + case { Kind: NostrKind.ApplicationSpecificData }: + var projectInfo = JsonSerializer.Deserialize(e.Content, Angor.Shared.Services.RelayService.settings); + if (!SessionStorage.IsProjectInStorageById(projectInfo.ProjectIdentifier)) + SessionStorage.StoreProjectInfo(projectInfo); + break; + } + }, () => + { + StateHasChanged(); + }, + new[] { findProject.NostrPubKey }); + + //_RelayService.LookupProjectsInfoByPubKeys(_ => + //{ + // if (!SessionStorage.IsProjectInStorageById(_.ProjectIdentifier)) + // SessionStorage.StoreProjectInfo(_); + //}, + //OnEndOfStreamAction: () => + //{ + //}, + //nostrPubKey: new[] { findProject.NostrPubKey }); + } + + findInProgress = false; + } private async Task SearchProjects() { searchInProgress = true; - var blockchainProjects = await _IndexerService.GetProjectsAsync(); + var blockchainProjects = await _IndexerService.GetProjectsAsync(null, 20); var projectsNotInList = blockchainProjects .Where(blockchainProject => projects.All(_ => _.ProjectIdentifier != blockchainProject.ProjectIdentifier)) @@ -88,22 +206,44 @@ .ToArray(); if (projectsForLookup.Any()) - _RelayService.LookupProjectsInfoByPubKeys(_ => + _RelayService.RequestProjectCreateEventsByPubKey(e => { - if (!SessionStorage.IsProjectInStorageById(_.ProjectIdentifier)) - SessionStorage.StoreProjectInfo(_); - }, - OnEndOfStreamAction: () => + switch (e) { - projects = projects //Remove projects that were not found on the relays - .Where(_ => SessionStorage.IsProjectInStorageById(_.ProjectIdentifier)) - .ToList(); + case { Kind: NostrKind.Metadata }: + var nostrMetadata = JsonSerializer.Deserialize(e.Content, Angor.Shared.Services.RelayService.settings); + SessionStorage.StoreProjectMetadata(e.Pubkey, nostrMetadata); + break; + case { Kind: NostrKind.ApplicationSpecificData }: + var projectInfo = JsonSerializer.Deserialize(e.Content, Angor.Shared.Services.RelayService.settings); + if (!SessionStorage.IsProjectInStorageById(projectInfo.ProjectIdentifier)) + SessionStorage.StoreProjectInfo(projectInfo); + break; + } + }, () => + { + searchInProgress = false; + StateHasChanged(); + }, + projectsForLookup); + + //if (projectsForLookup.Any()) + // _RelayService.LookupProjectsInfoByPubKeys(_ => + // { + // if (!SessionStorage.IsProjectInStorageById(_.ProjectIdentifier)) + // SessionStorage.StoreProjectInfo(_); + // }, + // OnEndOfStreamAction: () => + // { + // projects = projects //Remove projects that were not found on the relays + // .Where(_ => SessionStorage.IsProjectInStorageById(_.ProjectIdentifier)) + // .ToList(); - SessionStorage.SetProjectIndexerData(projects); + // SessionStorage.SetProjectIndexerData(projects); - StateHasChanged(); - }, - nostrPubKey: projectsForLookup); + // StateHasChanged(); + // }, + // nostrPubKey: projectsForLookup); StateHasChanged(); } diff --git a/src/Angor/Client/Pages/Create.razor b/src/Angor/Client/Pages/Create.razor index 283eee4b..179c0255 100644 --- a/src/Angor/Client/Pages/Create.razor +++ b/src/Angor/Client/Pages/Create.razor @@ -348,7 +348,12 @@ foreach (var stage in project.Stages) { if ((stage.ReleaseDate - prev).Days < 0) + { notificationComponent.ShowErrorMessage("Stages must be chronological"); + return; + } + + prev = stage.ReleaseDate; } var operationResult = await notificationComponent.LongOperation(async () => diff --git a/src/Angor/Client/Pages/View.razor b/src/Angor/Client/Pages/View.razor index 77560a6b..6b9fd3ad 100644 --- a/src/Angor/Client/Pages/View.razor +++ b/src/Angor/Client/Pages/View.razor @@ -35,6 +35,17 @@
Project Identifier: @project.ProjectIdentifier
+ + @if (SessionStorage.IsProjectMetadataStorageByPubkey(project.NostrPubKey)) + { + var metadata = SessionStorage.GetProjectMetadataByPubkey(project.NostrPubKey); + +
+

@metadata?.Name

+

@metadata?.About

+
+ } + View the transaction on the explorer.

Founder Key: @project.FounderKey

Start Date: @project.StartDate.ToString("dd/MM/yyyy")

diff --git a/src/Angor/Client/Storage/LocalSessionStorage.cs b/src/Angor/Client/Storage/LocalSessionStorage.cs index eb8136ec..d98a038c 100644 --- a/src/Angor/Client/Storage/LocalSessionStorage.cs +++ b/src/Angor/Client/Storage/LocalSessionStorage.cs @@ -1,3 +1,4 @@ +using Angor.Client.Models; using Angor.Client.Services; using Angor.Shared.Models; using Angor.Shared.Services; @@ -21,10 +22,26 @@ public void StoreProjectInfo(ProjectInfo project) _sessionStorageService.SetItem(project.ProjectIdentifier,project); } + public ProjectMetadata? GetProjectMetadataByPubkey(string pubkey) + { + return _sessionStorageService.GetItem(pubkey); + } + + public void StoreProjectMetadata(string pubkey, ProjectMetadata projectMetadata) + { + _sessionStorageService.SetItem(pubkey, projectMetadata); + } + + public bool IsProjectMetadataStorageByPubkey(string pubkey) + { + return _sessionStorageService.ContainKey(pubkey); + } + public ProjectInfo? GetProjectById(string projectId) { return _sessionStorageService.GetItem(projectId); } + public bool IsProjectInStorageById(string projectId) { return _sessionStorageService.ContainKey(projectId); diff --git a/src/Angor/Client/Models/ProjectMetadata.cs b/src/Angor/Shared/Models/ProjectMetadata.cs similarity index 98% rename from src/Angor/Client/Models/ProjectMetadata.cs rename to src/Angor/Shared/Models/ProjectMetadata.cs index cc6e02b1..06c64a7f 100644 --- a/src/Angor/Client/Models/ProjectMetadata.cs +++ b/src/Angor/Shared/Models/ProjectMetadata.cs @@ -1,6 +1,6 @@ using Nostr.Client.Messages.Metadata; -namespace Angor.Client.Models; +namespace Angor.Shared.Models; public class ProjectMetadata { diff --git a/src/Angor/Shared/Services/ICacheStorage.cs b/src/Angor/Shared/Services/ICacheStorage.cs index 079e0a6d..3cd57606 100644 --- a/src/Angor/Shared/Services/ICacheStorage.cs +++ b/src/Angor/Shared/Services/ICacheStorage.cs @@ -8,6 +8,9 @@ public interface ICacheStorage void StoreProjectInfo(ProjectInfo project); ProjectInfo? GetProjectById(string projectId); bool IsProjectInStorageById(string projectId); + ProjectMetadata? GetProjectMetadataByPubkey(string pubkey); + void StoreProjectMetadata(string pubkey, ProjectMetadata projectMetadata); + bool IsProjectMetadataStorageByPubkey(string pubkey); List? GetProjectIndexerData(); void SetProjectIndexerData(List list); List GetUnconfirmedInboundFunds(); diff --git a/src/Angor/Shared/Services/IndexerService.cs b/src/Angor/Shared/Services/IndexerService.cs index f5327531..72e2a67a 100644 --- a/src/Angor/Shared/Services/IndexerService.cs +++ b/src/Angor/Shared/Services/IndexerService.cs @@ -9,7 +9,7 @@ namespace Angor.Client.Services { public interface IIndexerService { - Task> GetProjectsAsync(); + Task> GetProjectsAsync(int? offset, int limit); Task GetProjectByIdAsync(string projectId); Task> GetInvestmentsAsync(string projectId); Task PublishTransactionAsync(string trxHex); @@ -58,11 +58,10 @@ public IndexerService(INetworkConfiguration networkConfiguration, HttpClient htt _networkService = networkService; } - public async Task> GetProjectsAsync() + public async Task> GetProjectsAsync(int? offset, int limit) { var indexer = _networkService.GetPrimaryIndexer(); - // todo: dan - make this proper paging - var response = await _httpClient.GetAsync($"{indexer.Url}/api/query/Angor/projects?offset=0&limit=50"); + var response = await _httpClient.GetAsync($"{indexer.Url}/api/query/Angor/projects?offset={offset}&limit={limit}"); _networkService.CheckAndHandleError(response); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync>(); @@ -70,6 +69,11 @@ public async Task> GetProjectsAsync() public async Task GetProjectByIdAsync(string projectId) { + if (string.IsNullOrEmpty(projectId)) + { + return null; + } + var indexer = _networkService.GetPrimaryIndexer(); var response = await _httpClient.GetAsync($"{indexer.Url}/api/query/Angor/projects/{projectId}"); _networkService.CheckAndHandleError(response);