diff --git a/src/NuSocial/Core/UsefulExtensions.cs b/src/NuSocial/Core/UsefulExtensions.cs index 17086c0..d0c1258 100644 --- a/src/NuSocial/Core/UsefulExtensions.cs +++ b/src/NuSocial/Core/UsefulExtensions.cs @@ -1,13 +1,25 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NuSocial.Core +namespace NuSocial.Core { - internal static class UsefulExtensions + public static class ObservableCollectionExtensions { + public static void RemoveLastN(this ObservableCollection collection, int n) + { + if (collection == null) + { + throw new ArgumentNullException(nameof(collection)); + } + + if (n < 0) + { + throw new ArgumentOutOfRangeException(nameof(n), "n must be non-negative"); + } + + int removeCount = Math.Min(n, collection.Count); + for (int i = 0; i < removeCount; i++) + { + collection.RemoveAt(collection.Count - 1); + } + } } } diff --git a/src/NuSocial/Localization/NuSocial/en.json b/src/NuSocial/Localization/NuSocial/en.json index cbfb773..07853fa 100644 --- a/src/NuSocial/Localization/NuSocial/en.json +++ b/src/NuSocial/Localization/NuSocial/en.json @@ -17,6 +17,7 @@ "AccountKeyPlaceholder": "nsec1...", "NuSocial": "NuSocial", "TapToRegenerate": "Tap to regenerate", - "WelcomeText": "#nostr NuSocial: Your Universe, Nu Connections" + "WelcomeText": "#nostr NuSocial: Your Universe, Nu Connections", + "NoRecentPosts": "No recent posts" } } diff --git a/src/NuSocial/Models/User.cs b/src/NuSocial/Models/User.cs index 0150fff..8eb77a3 100644 --- a/src/NuSocial/Models/User.cs +++ b/src/NuSocial/Models/User.cs @@ -32,7 +32,7 @@ public string PrivateKeyString public class Profile { - private string? _picture; + private string? _picture = "https://placehold.co/60x60"; public string Name { get; internal set; } = string.Empty; public string? DisplayName { get; internal set; } @@ -40,7 +40,7 @@ public string? Picture { get { - if (string.IsNullOrEmpty(_picture)) + if (string.IsNullOrEmpty(_picture) || (_picture.Equals("https://placehold.co/60x60", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(Name))) { _picture = $"https://placehold.co/60x60?text={Name}"; } @@ -70,11 +70,8 @@ public class UserConfiguration } /// -/// A simple model for a contact. +/// A contact on the #nostr network /// -/// Gets the name of the contact. -/// Gets the email of the contact. -/// Gets the picture of the contact. public sealed record Contact { [JsonPropertyName("name")] diff --git a/src/NuSocial/ViewModels/MainViewModel.cs b/src/NuSocial/ViewModels/MainViewModel.cs index 421a7c1..10a54cc 100644 --- a/src/NuSocial/ViewModels/MainViewModel.cs +++ b/src/NuSocial/ViewModels/MainViewModel.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.Messaging; using Nostr.Client.Messages; +using NuSocial.Core; using NuSocial.Core.ViewModel; using NuSocial.Messages; using System.Collections.Immutable; @@ -12,6 +13,7 @@ public partial class MainViewModel : BaseViewModel, ITransientDependency, IDispo { private readonly IAuthorService _authorService; private CancellationTokenSource? _cts = new(); + private const int _postThreshold = 100; [ObservableProperty] private ObservableCollection _posts = new(); @@ -143,8 +145,14 @@ private Task UpdatePostsAsync() return SetBusyAsync(() => { var posts = _postsWaiting.ToImmutableList(); + _postsWaiting.Clear(); OnPropertyChanged(nameof(UnreadLabel)); + + if (Posts.Count > _postThreshold) + { + Posts.RemoveLastN(posts.Count); + } foreach (var post in posts) { Posts.AddFirst(post); diff --git a/src/NuSocial/Views/LoginView.xaml b/src/NuSocial/Views/LoginView.xaml index b8fb578..15cdbbb 100644 --- a/src/NuSocial/Views/LoginView.xaml +++ b/src/NuSocial/Views/LoginView.xaml @@ -19,6 +19,7 @@