Merge pull request #85 from Moonlight-Panel/RemoveOldSupportSystem
Removed old support system
This commit is contained in:
commit
b790c31606
|
@ -30,8 +30,7 @@ public class DataContext : DbContext
|
|||
public DbSet<AuditLogEntry> AuditLog { get; set; }
|
||||
public DbSet<ErrorLogEntry> ErrorLog { get; set; }
|
||||
public DbSet<SecurityLogEntry> SecurityLog { get; set; }
|
||||
public DbSet<SupportMessage> SupportMessages { get; set; }
|
||||
|
||||
|
||||
public DbSet<SharedDomain> SharedDomains { get; set; }
|
||||
public DbSet<Domain> Domains { get; set; }
|
||||
public DbSet<Revoke> Revokes { get; set; }
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
using Moonlight.App.Models.Misc;
|
||||
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class SupportMessage
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Message { get; set; } = "";
|
||||
public User? Sender { get; set; } = null;
|
||||
public User? Recipient { get; set; } = null;
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public bool IsQuestion { get; set; } = false;
|
||||
public QuestionType Type { get; set; }
|
||||
public string Answer { get; set; } = "";
|
||||
public bool IsSystem { get; set; } = false;
|
||||
public bool IsSupport { get; set; } = false;
|
||||
}
|
1028
Moonlight/App/Database/Migrations/20230421143556_RemovedOldSupportChatModel.Designer.cs
generated
Normal file
1028
Moonlight/App/Database/Migrations/20230421143556_RemovedOldSupportChatModel.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.App.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class RemovedOldSupportChatModel : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "SupportMessages");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SupportMessages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
RecipientId = table.Column<int>(type: "int", nullable: true),
|
||||
SenderId = table.Column<int>(type: "int", nullable: true),
|
||||
Answer = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
IsQuestion = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
IsSupport = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
IsSystem = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Message = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Type = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SupportMessages", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SupportMessages_Users_RecipientId",
|
||||
column: x => x.RecipientId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_SupportMessages_Users_SenderId",
|
||||
column: x => x.SenderId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SupportMessages_RecipientId",
|
||||
table: "SupportMessages",
|
||||
column: "RecipientId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SupportMessages_SenderId",
|
||||
table: "SupportMessages",
|
||||
column: "SenderId");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -695,50 +695,6 @@ namespace Moonlight.App.Database.Migrations
|
|||
b.ToTable("SupportChatMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.SupportMessage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Answer")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("IsQuestion")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("IsSupport")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("IsSystem")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("RecipientId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("SenderId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RecipientId");
|
||||
|
||||
b.HasIndex("SenderId");
|
||||
|
||||
b.ToTable("SupportMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -1010,21 +966,6 @@ namespace Moonlight.App.Database.Migrations
|
|||
b.Navigation("Sender");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.SupportMessage", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.User", "Recipient")
|
||||
.WithMany()
|
||||
.HasForeignKey("RecipientId");
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.User", "Sender")
|
||||
.WithMany()
|
||||
.HasForeignKey("SenderId");
|
||||
|
||||
b.Navigation("Recipient");
|
||||
|
||||
b.Navigation("Sender");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Subscription", "CurrentSubscription")
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories;
|
||||
|
||||
public class SupportMessageRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public SupportMessageRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<SupportMessage> Get()
|
||||
{
|
||||
return DataContext.SupportMessages;
|
||||
}
|
||||
|
||||
public SupportMessage Add(SupportMessage message)
|
||||
{
|
||||
var x = DataContext.SupportMessages.Add(message);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(SupportMessage message)
|
||||
{
|
||||
DataContext.SupportMessages.Update(message);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(SupportMessage message)
|
||||
{
|
||||
DataContext.SupportMessages.Remove(message);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Services.Sessions;
|
||||
|
||||
namespace Moonlight.App.Services.Support;
|
||||
|
||||
public class SupportAdminService
|
||||
{
|
||||
private readonly SupportServerService SupportServerService;
|
||||
private readonly IdentityService IdentityService;
|
||||
private readonly MessageService MessageService;
|
||||
|
||||
public EventHandler<SupportMessage> OnNewMessage;
|
||||
|
||||
public EventHandler OnUpdateTyping;
|
||||
private List<string> TypingUsers = new();
|
||||
|
||||
private User Self;
|
||||
private User Recipient;
|
||||
|
||||
public SupportAdminService(
|
||||
SupportServerService supportServerService,
|
||||
IdentityService identityService,
|
||||
MessageService messageService)
|
||||
{
|
||||
SupportServerService = supportServerService;
|
||||
IdentityService = identityService;
|
||||
MessageService = messageService;
|
||||
}
|
||||
|
||||
public async Task Start(User user)
|
||||
{
|
||||
Self = (await IdentityService.Get())!;
|
||||
Recipient = user;
|
||||
|
||||
MessageService.Subscribe<SupportClientService, SupportMessage>(
|
||||
$"support.{Recipient.Id}.message",
|
||||
this,
|
||||
message =>
|
||||
{
|
||||
OnNewMessage?.Invoke(this, message);
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
MessageService.Subscribe<SupportClientService, User>(
|
||||
$"support.{Self.Id}.typing",
|
||||
this,
|
||||
user =>
|
||||
{
|
||||
HandleTyping(user);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
#region Typing
|
||||
|
||||
private void HandleTyping(User user)
|
||||
{
|
||||
var name = $"{user.FirstName} {user.LastName}";
|
||||
|
||||
lock (TypingUsers)
|
||||
{
|
||||
if (!TypingUsers.Contains(name))
|
||||
{
|
||||
TypingUsers.Add(name);
|
||||
OnUpdateTyping!.Invoke(this, null!);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
|
||||
if (TypingUsers.Contains(name))
|
||||
{
|
||||
TypingUsers.Remove(name);
|
||||
OnUpdateTyping!.Invoke(this, null!);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetTypingUsers()
|
||||
{
|
||||
lock (TypingUsers)
|
||||
{
|
||||
return TypingUsers.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public Task TriggerTyping()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await MessageService.Emit($"support.{Recipient.Id}.admintyping", Self);
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public async Task<SupportMessage[]> GetMessages()
|
||||
{
|
||||
return await SupportServerService.GetMessages(Recipient);
|
||||
}
|
||||
|
||||
public async Task SendMessage(string content)
|
||||
{
|
||||
var message = new SupportMessage()
|
||||
{
|
||||
Message = content
|
||||
};
|
||||
|
||||
await SupportServerService.SendMessage(
|
||||
Recipient,
|
||||
message,
|
||||
Self,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public async Task Close()
|
||||
{
|
||||
await SupportServerService.Close(Recipient);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
MessageService.Unsubscribe($"support.{Recipient.Id}.message", this);
|
||||
MessageService.Unsubscribe($"support.{Recipient.Id}.typing", this);
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Services.Sessions;
|
||||
|
||||
namespace Moonlight.App.Services.Support;
|
||||
|
||||
public class SupportClientService : IDisposable
|
||||
{
|
||||
private readonly SupportServerService SupportServerService;
|
||||
private readonly IdentityService IdentityService;
|
||||
private readonly MessageService MessageService;
|
||||
|
||||
public EventHandler<SupportMessage> OnNewMessage;
|
||||
|
||||
public EventHandler OnUpdateTyping;
|
||||
private List<string> TypingUsers = new();
|
||||
|
||||
private User Self;
|
||||
|
||||
public SupportClientService(
|
||||
SupportServerService supportServerService,
|
||||
IdentityService identityService,
|
||||
MessageService messageService)
|
||||
{
|
||||
SupportServerService = supportServerService;
|
||||
IdentityService = identityService;
|
||||
MessageService = messageService;
|
||||
}
|
||||
|
||||
public async Task Start()
|
||||
{
|
||||
Self = (await IdentityService.Get())!;
|
||||
|
||||
MessageService.Subscribe<SupportClientService, SupportMessage>(
|
||||
$"support.{Self.Id}.message",
|
||||
this,
|
||||
message =>
|
||||
{
|
||||
OnNewMessage?.Invoke(this, message);
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
MessageService.Subscribe<SupportClientService, User>(
|
||||
$"support.{Self.Id}.admintyping",
|
||||
this,
|
||||
user =>
|
||||
{
|
||||
HandleTyping(user);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
#region Typing
|
||||
|
||||
private void HandleTyping(User user)
|
||||
{
|
||||
var name = $"{user.FirstName} {user.LastName}";
|
||||
|
||||
lock (TypingUsers)
|
||||
{
|
||||
if (!TypingUsers.Contains(name))
|
||||
{
|
||||
TypingUsers.Add(name);
|
||||
OnUpdateTyping!.Invoke(this, null!);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
|
||||
if (TypingUsers.Contains(name))
|
||||
{
|
||||
TypingUsers.Remove(name);
|
||||
OnUpdateTyping!.Invoke(this, null!);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetTypingUsers()
|
||||
{
|
||||
lock (TypingUsers)
|
||||
{
|
||||
return TypingUsers.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public Task TriggerTyping()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await MessageService.Emit($"support.{Self.Id}.typing", Self);
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public async Task<SupportMessage[]> GetMessages()
|
||||
{
|
||||
return await SupportServerService.GetMessages(Self);
|
||||
}
|
||||
|
||||
public async Task SendMessage(string content)
|
||||
{
|
||||
var message = new SupportMessage()
|
||||
{
|
||||
Message = content
|
||||
};
|
||||
|
||||
await SupportServerService.SendMessage(
|
||||
Self,
|
||||
message,
|
||||
Self
|
||||
);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
MessageService.Unsubscribe($"support.{Self.Id}.message", this);
|
||||
MessageService.Unsubscribe($"support.{Self.Id}.admintyping", this);
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
using Logging.Net;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Repositories;
|
||||
|
||||
namespace Moonlight.App.Services.Support;
|
||||
|
||||
public class SupportServerService : IDisposable
|
||||
{
|
||||
private SupportMessageRepository SupportMessageRepository;
|
||||
private MessageService MessageService;
|
||||
private UserRepository UserRepository;
|
||||
private readonly IServiceScopeFactory ServiceScopeFactory;
|
||||
private IServiceScope ServiceScope;
|
||||
|
||||
public SupportServerService(IServiceScopeFactory serviceScopeFactory)
|
||||
{
|
||||
ServiceScopeFactory = serviceScopeFactory;
|
||||
|
||||
Task.Run(Run);
|
||||
}
|
||||
|
||||
public async Task SendMessage(User r, SupportMessage message, User s, bool isSupport = false)
|
||||
{
|
||||
var recipient = UserRepository.Get().First(x => x.Id == r.Id);
|
||||
var sender = UserRepository.Get().First(x => x.Id == s.Id);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
message.CreatedAt = DateTime.UtcNow;
|
||||
message.Sender = sender;
|
||||
message.Recipient = recipient;
|
||||
message.IsSupport = isSupport;
|
||||
|
||||
SupportMessageRepository.Add(message);
|
||||
|
||||
await MessageService.Emit($"support.{recipient.Id}.message", message);
|
||||
|
||||
if (!recipient.SupportPending)
|
||||
{
|
||||
recipient.SupportPending = true;
|
||||
UserRepository.Update(recipient);
|
||||
|
||||
if (!message.IsSupport)
|
||||
{
|
||||
var systemMessage = new SupportMessage()
|
||||
{
|
||||
Recipient = recipient,
|
||||
Sender = null,
|
||||
IsSystem = true,
|
||||
Message = "The support team has been notified. Please be patient"
|
||||
};
|
||||
|
||||
SupportMessageRepository.Add(systemMessage);
|
||||
|
||||
await MessageService.Emit($"support.{recipient.Id}.message", systemMessage);
|
||||
}
|
||||
|
||||
await MessageService.Emit($"support.new", recipient);
|
||||
|
||||
Logger.Info("Support ticket created: " + recipient.Id);
|
||||
//TODO: Ping or so
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("Error sending message");
|
||||
Logger.Error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Close(User user)
|
||||
{
|
||||
var recipient = UserRepository.Get().First(x => x.Id == user.Id);
|
||||
|
||||
recipient.SupportPending = false;
|
||||
UserRepository.Update(recipient);
|
||||
|
||||
var systemMessage = new SupportMessage()
|
||||
{
|
||||
Recipient = recipient,
|
||||
Sender = null,
|
||||
IsSystem = true,
|
||||
Message = "The ticket is now closed. Type a message to open it again"
|
||||
};
|
||||
|
||||
SupportMessageRepository.Add(systemMessage);
|
||||
|
||||
await MessageService.Emit($"support.{recipient.Id}.message", systemMessage);
|
||||
await MessageService.Emit($"support.close", recipient);
|
||||
}
|
||||
|
||||
public Task<SupportMessage[]> GetMessages(User r)
|
||||
{
|
||||
var recipient = UserRepository.Get().First(x => x.Id == r.Id);
|
||||
|
||||
var messages = SupportMessageRepository
|
||||
.Get()
|
||||
.Include(x => x.Recipient)
|
||||
.Include(x => x.Sender)
|
||||
.Where(x => x.Recipient.Id == recipient.Id)
|
||||
.AsEnumerable()
|
||||
.TakeLast(50)
|
||||
.OrderBy(x => x.Id)
|
||||
.ToArray();
|
||||
|
||||
return Task.FromResult(messages);
|
||||
}
|
||||
|
||||
private Task Run()
|
||||
{
|
||||
ServiceScope = ServiceScopeFactory.CreateScope();
|
||||
|
||||
SupportMessageRepository = ServiceScope
|
||||
.ServiceProvider
|
||||
.GetRequiredService<SupportMessageRepository>();
|
||||
|
||||
MessageService = ServiceScope
|
||||
.ServiceProvider
|
||||
.GetRequiredService<MessageService>();
|
||||
|
||||
UserRepository = ServiceScope
|
||||
.ServiceProvider
|
||||
.GetRequiredService<UserRepository>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SupportMessageRepository.Dispose();
|
||||
UserRepository.Dispose();
|
||||
ServiceScope.Dispose();
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ using Moonlight.App.Services.Notifications;
|
|||
using Moonlight.App.Services.OAuth2;
|
||||
using Moonlight.App.Services.Sessions;
|
||||
using Moonlight.App.Services.Statistics;
|
||||
using Moonlight.App.Services.Support;
|
||||
using Moonlight.App.Services.SupportChat;
|
||||
|
||||
namespace Moonlight
|
||||
|
@ -63,7 +62,6 @@ namespace Moonlight
|
|||
builder.Services.AddScoped<ServerRepository>();
|
||||
builder.Services.AddScoped<ServerBackupRepository>();
|
||||
builder.Services.AddScoped<ImageRepository>();
|
||||
builder.Services.AddScoped<SupportMessageRepository>();
|
||||
builder.Services.AddScoped<DomainRepository>();
|
||||
builder.Services.AddScoped<SharedDomainRepository>();
|
||||
builder.Services.AddScoped<RevokeRepository>();
|
||||
|
@ -125,11 +123,6 @@ namespace Moonlight
|
|||
builder.Services.AddScoped<MailService>();
|
||||
builder.Services.AddSingleton<TrashMailDetectorService>();
|
||||
|
||||
// Support TODO: Remove
|
||||
builder.Services.AddSingleton<SupportServerService>();
|
||||
builder.Services.AddScoped<SupportAdminService>();
|
||||
builder.Services.AddScoped<SupportClientService>();
|
||||
|
||||
// Support chat
|
||||
builder.Services.AddSingleton<SupportChatServerService>();
|
||||
builder.Services.AddScoped<SupportChatClientService>();
|
||||
|
@ -175,10 +168,7 @@ namespace Moonlight
|
|||
|
||||
app.MapBlazorHub();
|
||||
app.MapFallbackToPage("/_Host");
|
||||
|
||||
// Support service
|
||||
var supportServerService = app.Services.GetRequiredService<SupportServerService>();
|
||||
|
||||
|
||||
// AutoStart services
|
||||
_ = app.Services.GetRequiredService<CleanupService>();
|
||||
_ = app.Services.GetRequiredService<DiscordBotService>();
|
||||
|
|
|
@ -164,6 +164,7 @@
|
|||
|
||||
NavigationManager.LocationChanged += (sender, args) => { SessionService.Refresh(); };
|
||||
|
||||
/*
|
||||
MessageService.Subscribe<MainLayout, SupportMessage>(
|
||||
$"support.{User.Id}.message",
|
||||
this,
|
||||
|
@ -173,7 +174,7 @@
|
|||
{
|
||||
await ToastService.Info($"Support: {message.Message}");
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
RunDelayedMenu(0);
|
||||
RunDelayedMenu(1);
|
||||
|
|
Loading…
Reference in a new issue