Skip to content

Commit

Permalink
more progress on messages and (single) message/thread views
Browse files Browse the repository at this point in the history
  • Loading branch information
kfrancis committed May 27, 2023
1 parent ee061ba commit 357c2d7
Show file tree
Hide file tree
Showing 10 changed files with 469 additions and 177 deletions.
7 changes: 6 additions & 1 deletion src/NuSocial.Core/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,12 @@ public class Message
public Contact? From { get; set; }

[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<MessageData> Messages { get; set; } = new();
public List<MessageData> Messages { get; set; } = new();

public bool ContainsText(string filter)
{
return Messages.Any(x => x.Text.Contains(filter, StringComparison.OrdinalIgnoreCase));
}

public DateTime LatestMessageDate
{
Expand Down
2 changes: 1 addition & 1 deletion src/NuSocial.Core/Services/NavigationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public async Task NavigateTo(string key, object parameter)

var parameters = new Dictionary<string, object>
{
{ "cabParameter", parameter }
{ "nsParameter", parameter }
};

await Shell.Current.GoToAsync(key, parameters);
Expand Down
79 changes: 79 additions & 0 deletions src/NuSocial.Core/ViewModels/MessageViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using CommunityToolkit.Maui.Core.Extensions;
using Microsoft.Maui.Graphics;
using NuSocial.Core.ViewModel;
using Volo.Abp.DependencyInjection;

namespace NuSocial.ViewModels;

public partial class MessageViewModel : BaseViewModel, ITransientDependency
{
[ObservableProperty]
private ObservableCollection<MessageData> _messages = new ObservableCollection<MessageData>();

[ObservableProperty]
private Message? _parentMessage;

public MessageViewModel(IDialogService dialogService, INavigationService navigationService) : base(dialogService, navigationService)
{
}

[ObservableProperty]
private string? _searchText;

[RelayCommand(CanExecute = nameof(IsNotBusy))]
private Task Search()
{
return SetBusyAsync(() =>
{
if (Messages != null && !string.IsNullOrEmpty(SearchText))
{
Messages = Messages.Where(x => x.Text.Contains(SearchText, StringComparison.OrdinalIgnoreCase)).ToObservableCollection();
}
return Task.CompletedTask;
});
}

[RelayCommand(CanExecute = nameof(IsNotBusy))]
private Task SearchTextChanged()
{
return SetBusyAsync(() =>
{
if (string.IsNullOrEmpty(SearchText) && ParentMessage != null)
{
if (ParentMessage.From != null)
{
Title = ParentMessage.From.Name.ToString();
}
if (ParentMessage.Messages.Count > 0)
{
Messages.AddIfNotContains(ParentMessage.Messages.OrderBy(x => x.When));
}
}
return Task.CompletedTask;
});
}

public override Task OnParameterSet()
{
return SetBusyAsync(() =>
{
if (NavigationParameter is Message parentMessage)
{
ParentMessage = parentMessage;
if (parentMessage.From != null)
{
Title = parentMessage.From.Name.ToString();
}
if (parentMessage.Messages.Count > 0)
{
Messages.AddIfNotContains(parentMessage.Messages.OrderBy(x => x.When));
}
}
return Task.CompletedTask;
});
}
}
256 changes: 175 additions & 81 deletions src/NuSocial.Core/ViewModels/MessagesViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,82 +1,176 @@
using Bogus;
using CommunityToolkit.Maui.Core.Extensions;
using Volo.Abp.DependencyInjection;
using Contact = NuSocial.Models.Contact;

namespace NuSocial.ViewModels;

public partial class MessagesViewModel : BaseViewModel, ITransientDependency
{

[ObservableProperty]
private ObservableCollection<Message> _messages = new ObservableCollection<Message>();

private readonly IDatabase _db;

public MessagesViewModel(IDialogService dialogService,
INavigationService navigationService,
IDatabase db)
: base(dialogService, navigationService)
{
_db = db;
}

public override async Task OnAppearing()
{
// Load data
var messages = await _db.GetMessagesAsync();
Messages.AddIfNotContains(messages);
}

public override async Task InitializeAsync()
{
Title = L["Messages"];

// Load data
var messages = await _db.GetMessagesAsync();

if (messages == null || !messages.Any())
{
var faker = new Faker();

var nameFaker = new Faker<Name>()
.RuleFor(n => n.First, f => f.Person.FirstName)
.RuleFor(n => n.Last, f => f.Person.LastName);

var pictureFaker = new Faker<Picture>()
.RuleFor(p => p.Url, f => new(f.Internet.Avatar()));

var contactFaker = new Faker<Contact>()
.RuleFor(c => c.Name, f => nameFaker.Generate())
.RuleFor(c => c.PetName, f => f.Internet.UserName())
.RuleFor(c => c.Email, f => f.Internet.Email())
.RuleFor(c => c.PublicKey, f => f.Lorem.Word())
.RuleFor(c => c.Picture, f => pictureFaker.Generate());

var messageDataFaker = new Faker<MessageData>()
.RuleFor(m => m.Id, f => f.Random.Int())
.RuleFor(m => m.When, f => f.Date.Past())
.RuleFor(m => m.Text, f => f.Lorem.Word())
.RuleFor(m => m.IsRead, f => f.Random.Bool())
.RuleFor(m => m.IsIncoming, f => f.Random.Bool())
.RuleFor(m => m.MessageId, f => f.Random.Int());

var messageFaker = new Faker<Message>()
.RuleFor(m => m.From, f => contactFaker.Generate())
.RuleFor(m => m.Id, f => f.Random.Int())
.RuleFor(m => m.ContactId, f => f.Random.Int())
.RuleFor(m => m.Messages, f => messageDataFaker.GenerateBetween(1, f.Random.Int(3,5)))
.FinishWith((f, m) => {
m.ContactId = m.From?.Id ?? 0;
foreach (var item in m.Messages)
{
item.MessageId = m.Id;
}
});

var newMessages = messageFaker.GenerateBetween(1, faker.Random.Int(2,4));

await _db.UpdateMessagesAsync(newMessages.ToObservableCollection());
}
}
using Bogus;
using CommunityToolkit.Maui.Core.Extensions;
using Volo.Abp.DependencyInjection;
using Contact = NuSocial.Models.Contact;

namespace NuSocial.ViewModels;

public partial class MessagesViewModel : BaseViewModel, ITransientDependency
{
private readonly IDatabase _db;

[ObservableProperty]
private ObservableCollection<Message>? _messages = new ObservableCollection<Message>();

public MessagesViewModel(IDialogService dialogService,
INavigationService navigationService,
IDatabase db)
: base(dialogService, navigationService)
{
_db = db;
}

[ObservableProperty]
private string _searchText = string.Empty;

[RelayCommand(CanExecute = nameof(IsNotBusy))]
private Task Search()
{
return SetBusyAsync(() =>
{
if (Messages != null && !string.IsNullOrEmpty(SearchText))
{
Messages = Messages.Where(x => x.ContainsText(SearchText) == true).ToObservableCollection();
}
return Task.CompletedTask;
});
}
[RelayCommand(CanExecute = nameof(IsNotBusy))]
private Task Refresh()
{
return SetBusyAsync(() =>
{
LoadData();
return Task.CompletedTask;
});
}

[RelayCommand(CanExecute = nameof(IsNotBusy))]
private Task SearchTextChanged()
{
if (string.IsNullOrEmpty(SearchText))
{
LoadData();
}
return Task.CompletedTask;
}

[RelayCommand(CanExecute = nameof(IsNotBusy))]
private Task ViewMessage(Message message)
{
return SetBusyAsync(() =>
{
return Navigation.NavigateTo(nameof(MessageViewModel), message);
});
}

public override async Task InitializeAsync()
{
Title = L["Messages"];

// Load data
var messages = await _db.GetMessagesAsync();

if (messages == null || !messages.Any())
{
var faker = new Faker();

var nameFaker = new Faker<Name>()
.RuleFor(n => n.First, f => f.Person.FirstName)
.RuleFor(n => n.Last, f => f.Person.LastName);

var pictureFaker = new Faker<Picture>()
.RuleFor(p => p.Url, f => new(f.Internet.Avatar()));

var contactFaker = new Faker<Contact>()
.RuleFor(c => c.Name, f => nameFaker.Generate())
.RuleFor(c => c.PetName, f => f.Internet.UserName())
.RuleFor(c => c.Email, f => f.Internet.Email())
.RuleFor(c => c.PublicKey, f => f.Lorem.Word())
.RuleFor(c => c.Picture, f => pictureFaker.Generate());

var messageDataFaker = new Faker<MessageData>()
.RuleFor(m => m.Id, f => f.Random.Int())
.RuleFor(m => m.When, f => f.Date.Past())
.RuleFor(m => m.Text, f => f.Lorem.Word())
.RuleFor(m => m.IsRead, f => f.Random.Bool())
.RuleFor(m => m.IsIncoming, f => f.Random.Bool())
.RuleFor(m => m.MessageId, f => f.Random.Int());

var messageFaker = new Faker<Message>()
.RuleFor(m => m.From, f => contactFaker.Generate())
.RuleFor(m => m.Id, f => f.Random.Int())
.RuleFor(m => m.ContactId, f => f.Random.Int())
.RuleFor(m => m.Messages, f => messageDataFaker.GenerateBetween(1, f.Random.Int(3, 5)))
.FinishWith((f, m) =>
{
m.ContactId = m.From?.Id ?? 0;
foreach (var item in m.Messages)
{
item.MessageId = m.Id;
}
});

var newMessages = messageFaker.GenerateBetween(1, faker.Random.Int(2, 4));

await _db.UpdateMessagesAsync(newMessages.ToObservableCollection());
}
}

public override Task OnAppearing()
{
// Load data
LoadData();
return Task.CompletedTask;
}

private void LoadData()
{
//var messages = await _db.GetMessagesAsync();
var faker = new Faker();
var nameFaker = new Faker<Name>()
.RuleFor(n => n.First, f => f.Person.FirstName)
.RuleFor(n => n.Last, f => f.Person.LastName);

var pictureFaker = new Faker<Picture>()
.RuleFor(p => p.Url, f => new(f.Internet.Avatar()));

var contactFaker = new Faker<Contact>()
.RuleFor(c => c.Id, f => f.UniqueIndex)
.RuleFor(c => c.Name, f => nameFaker.Generate())
.RuleFor(c => c.PetName, f => f.Internet.UserName())
.RuleFor(c => c.Email, f => f.Internet.Email())
.RuleFor(c => c.PublicKey, f => f.Lorem.Word())
.RuleFor(c => c.Picture, f => pictureFaker.Generate());

var contacts = contactFaker.GenerateBetween(1, faker.Random.Int(2, 5));

var messages = new List<Message>();
for (int i = 0; i < faker.Random.Int(2, 20); i++)
{
var messageContact = contacts[faker.Random.Int(0, contacts.Count - 1) % contacts.Count];
var messageId = i;
messages.Add(new Message()
{
ContactId = messageContact.Id,
Id = messageId,
From = messageContact,
Messages = new()
{
new MessageData(){
MessageId = messageId,
Id = i,
IsIncoming = faker.Random.Bool(),
IsRead = faker.Random.Bool(),
Text = faker.Lorem.Text(),
When = faker.Date.Recent()
}
}
});
}

Messages.AddIfNotContains(messages);
}
}
3 changes: 2 additions & 1 deletion src/NuSocial/AppShell.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ private void RegisterRoutes()
Routing.RegisterRoute(nameof(ProfileViewModel), typeof(ProfileView));
Routing.RegisterRoute(nameof(RelaysViewModel), typeof(RelaysView));
Routing.RegisterRoute(nameof(SettingsViewModel), typeof(SettingsView));
Routing.RegisterRoute(nameof(WalletViewModel), typeof(WalletView));
Routing.RegisterRoute(nameof(WalletViewModel), typeof(WalletView));
Routing.RegisterRoute(nameof(MessageViewModel), typeof(MessageView));
}
}
Loading

0 comments on commit 357c2d7

Please sign in to comment.