Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
408c9cb09b |
15 changed files with 2718 additions and 2 deletions
|
|
@ -36,6 +36,8 @@ namespace LANCommander.Data
|
|||
builder.ConfigureBaseRelationships<ServerConsole>();
|
||||
builder.ConfigureBaseRelationships<ServerHttpPath>();
|
||||
builder.ConfigureBaseRelationships<Tag>();
|
||||
builder.ConfigureBaseRelationships<Message>();
|
||||
builder.ConfigureBaseRelationships<Channel>();
|
||||
|
||||
builder.Entity<Genre>()
|
||||
.HasMany(g => g.Games)
|
||||
|
|
@ -229,6 +231,23 @@ namespace LANCommander.Data
|
|||
rc => rc.HasOne<Role>().WithMany().HasForeignKey("RoleId")
|
||||
);
|
||||
#endregion
|
||||
|
||||
#region Chat Relationships
|
||||
builder.Entity<Channel>()
|
||||
.HasMany(c => c.Messages)
|
||||
.WithOne(m => m.Channel)
|
||||
.IsRequired(true)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Entity<Channel>()
|
||||
.HasMany(c => c.Users)
|
||||
.WithMany(u => u.Channels)
|
||||
.UsingEntity<Dictionary<string, object>>(
|
||||
"ChannelUsers",
|
||||
cu => cu.HasOne<User>().WithMany().HasForeignKey("UserId"),
|
||||
cu => cu.HasOne<Channel>().WithMany().HasForeignKey("ChannelId")
|
||||
);
|
||||
#endregion
|
||||
}
|
||||
|
||||
public DbSet<Game>? Games { get; set; }
|
||||
|
|
@ -254,5 +273,8 @@ namespace LANCommander.Data
|
|||
public DbSet<Redistributable>? Redistributables { get; set; }
|
||||
|
||||
public DbSet<Media>? Media { get; set; }
|
||||
|
||||
public DbSet<Message>? Messages { get; set; }
|
||||
public DbSet<Channel>? Channels { get; set; }
|
||||
}
|
||||
}
|
||||
9
LANCommander/Data/Enums/ChannelType.cs
Normal file
9
LANCommander/Data/Enums/ChannelType.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace LANCommander.Data.Enums
|
||||
{
|
||||
public enum ChannelType
|
||||
{
|
||||
Standard,
|
||||
DirectMessage,
|
||||
Game,
|
||||
}
|
||||
}
|
||||
18
LANCommander/Data/Models/Channel.cs
Normal file
18
LANCommander/Data/Models/Channel.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using LANCommander.Data.Enums;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace LANCommander.Data.Models
|
||||
{
|
||||
[Table("Channels")]
|
||||
public class Channel : BaseModel
|
||||
{
|
||||
[MaxLength(128)]
|
||||
public string Name { get; set; }
|
||||
|
||||
public ChannelType Type { get; set; } = ChannelType.Standard;
|
||||
|
||||
public virtual ICollection<Message>? Messages { get; set; }
|
||||
public virtual ICollection<User>? Users { get; set; }
|
||||
}
|
||||
}
|
||||
18
LANCommander/Data/Models/Message.cs
Normal file
18
LANCommander/Data/Models/Message.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace LANCommander.Data.Models
|
||||
{
|
||||
[Table("Messages")]
|
||||
public class Message : BaseModel
|
||||
{
|
||||
[Key]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[MaxLength(1024)]
|
||||
public string Contents { get; set; }
|
||||
|
||||
public virtual User? Sender { get; set; }
|
||||
public virtual Channel? Channel { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -51,6 +51,10 @@ namespace LANCommander.Data.Models
|
|||
|
||||
[JsonIgnore]
|
||||
public virtual ICollection<Media>? Media { get; set; }
|
||||
[JsonIgnore]
|
||||
public virtual ICollection<Message>? Messages { get; set; }
|
||||
[JsonIgnore]
|
||||
public virtual ICollection<Channel>? Channels { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool Approved { get; set; }
|
||||
|
|
|
|||
50
LANCommander/Hubs/ChatHub.cs
Normal file
50
LANCommander/Hubs/ChatHub.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
using LANCommander.Data.Models;
|
||||
using LANCommander.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace LANCommander.Hubs
|
||||
{
|
||||
[Authorize]
|
||||
public class ChatHub : Hub
|
||||
{
|
||||
public static ChatService ChatService;
|
||||
|
||||
public ChatHub(ChatService chatService)
|
||||
{
|
||||
ChatService = chatService;
|
||||
}
|
||||
|
||||
public async Task Connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
await ChatService.Connect(Context.ConnectionId, Context.User.Identity.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendMessage(Guid recipient, string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await ChatService.SendMessageToUserAsync(ChatService.GetUser(Context.ConnectionId).Id, recipient, message);
|
||||
|
||||
await Clients.Users(recipient.ToString()).SendAsync("ReceiveMessage", result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Message>> GetMessages(Guid channelId, int skip = 0, int take = 25)
|
||||
{
|
||||
return await ChatService.GetMessages(channelId, skip, take);
|
||||
}
|
||||
}
|
||||
}
|
||||
2148
LANCommander/Migrations/20240208020739_AddChat.Designer.cs
generated
Normal file
2148
LANCommander/Migrations/20240208020739_AddChat.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
157
LANCommander/Migrations/20240208020739_AddChat.cs
Normal file
157
LANCommander/Migrations/20240208020739_AddChat.cs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace LANCommander.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddChat : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Channels",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", maxLength: 128, nullable: false),
|
||||
Type = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
CreatedById = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
UpdatedOn = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
UpdatedById = table.Column<Guid>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Channels", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Channels_AspNetUsers_CreatedById",
|
||||
column: x => x.CreatedById,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_Channels_AspNetUsers_UpdatedById",
|
||||
column: x => x.UpdatedById,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelUsers",
|
||||
columns: table => new
|
||||
{
|
||||
ChannelId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelUsers", x => new { x.ChannelId, x.UserId });
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelUsers_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ChannelUsers_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Messages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Contents = table.Column<string>(type: "TEXT", maxLength: 1024, nullable: false),
|
||||
SenderId = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
ChannelId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
CreatedById = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
UpdatedOn = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
UpdatedById = table.Column<Guid>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Messages", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Messages_AspNetUsers_CreatedById",
|
||||
column: x => x.CreatedById,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_Messages_AspNetUsers_SenderId",
|
||||
column: x => x.SenderId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_Messages_AspNetUsers_UpdatedById",
|
||||
column: x => x.UpdatedById,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_Messages_Channels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "Channels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Channels_CreatedById",
|
||||
table: "Channels",
|
||||
column: "CreatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Channels_UpdatedById",
|
||||
table: "Channels",
|
||||
column: "UpdatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelUsers_UserId",
|
||||
table: "ChannelUsers",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_ChannelId",
|
||||
table: "Messages",
|
||||
column: "ChannelId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_CreatedById",
|
||||
table: "Messages",
|
||||
column: "CreatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_SenderId",
|
||||
table: "Messages",
|
||||
column: "SenderId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Messages_UpdatedById",
|
||||
table: "Messages",
|
||||
column: "UpdatedById");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ChannelUsers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Messages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Channels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ namespace LANCommander.Migrations
|
|||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.0")
|
||||
.HasAnnotation("ProductVersion", "8.0.1")
|
||||
.HasAnnotation("Proxies:ChangeTracking", false)
|
||||
.HasAnnotation("Proxies:CheckEquality", false)
|
||||
.HasAnnotation("Proxies:LazyLoading", true);
|
||||
|
|
@ -36,6 +36,21 @@ namespace LANCommander.Migrations
|
|||
b.ToTable("CategoryGame");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ChannelUsers", b =>
|
||||
{
|
||||
b.Property<Guid>("ChannelId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("ChannelId", "UserId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ChannelUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("CollectionGame", b =>
|
||||
{
|
||||
b.Property<Guid>("CollectionId")
|
||||
|
|
@ -277,6 +292,41 @@ namespace LANCommander.Migrations
|
|||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Channel", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("CreatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("UpdatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("UpdatedById");
|
||||
|
||||
b.ToTable("Channels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Collection", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
|
|
@ -583,6 +633,48 @@ namespace LANCommander.Migrations
|
|||
b.ToTable("Media");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Message", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ChannelId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Contents")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1024)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("CreatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("SenderId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("UpdatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("SenderId");
|
||||
|
||||
b.HasIndex("UpdatedById");
|
||||
|
||||
b.ToTable("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.MultiplayerMode", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
|
|
@ -1270,6 +1362,21 @@ namespace LANCommander.Migrations
|
|||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ChannelUsers", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.Channel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ChannelId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("CollectionGame", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.Collection", null)
|
||||
|
|
@ -1451,6 +1558,23 @@ namespace LANCommander.Migrations
|
|||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Channel", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "UpdatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedById")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Collection", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
|
|
@ -1620,6 +1744,37 @@ namespace LANCommander.Migrations
|
|||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Message", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.Channel", "Channel")
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("ChannelId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "Sender")
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("SenderId");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "UpdatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedById")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.Navigation("Channel");
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("Sender");
|
||||
|
||||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.MultiplayerMode", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
|
|
@ -1926,6 +2081,11 @@ namespace LANCommander.Migrations
|
|||
b.Navigation("Children");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Channel", b =>
|
||||
{
|
||||
b.Navigation("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Game", b =>
|
||||
{
|
||||
b.Navigation("Actions");
|
||||
|
|
@ -1975,6 +2135,8 @@ namespace LANCommander.Migrations
|
|||
|
||||
b.Navigation("Media");
|
||||
|
||||
b.Navigation("Messages");
|
||||
|
||||
b.Navigation("PlaySessions");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
|
|
|
|||
|
|
@ -183,6 +183,10 @@ namespace LANCommander
|
|||
builder.Services.AddScoped<IMediaGrabberService, SteamGridDBMediaGrabber>();
|
||||
builder.Services.AddScoped<WikiService>();
|
||||
builder.Services.AddScoped<UpdateService>();
|
||||
builder.Services.AddScoped<MessageService>();
|
||||
builder.Services.AddScoped<ChannelService>();
|
||||
|
||||
builder.Services.AddSingleton<ChatService>();
|
||||
|
||||
builder.Services.AddSingleton<ServerProcessService>();
|
||||
builder.Services.AddSingleton<IPXRelayService>();
|
||||
|
|
@ -241,6 +245,7 @@ namespace LANCommander
|
|||
|
||||
app.MapHub<LoggingHub>("/hubs/logging");
|
||||
app.MapHub<GameServerHub>("/hubs/gameserver");
|
||||
app.MapHub<ChatHub>("/hubs/chat");
|
||||
|
||||
Logger.Debug("Registering Endpoints");
|
||||
app.UseEndpoints(endpoints =>
|
||||
|
|
|
|||
12
LANCommander/Services/ChannelService.cs
Normal file
12
LANCommander/Services/ChannelService.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using LANCommander.Data;
|
||||
using LANCommander.Data.Models;
|
||||
|
||||
namespace LANCommander.Services
|
||||
{
|
||||
public class ChannelService : BaseDatabaseService<Channel>
|
||||
{
|
||||
public ChannelService(DatabaseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
91
LANCommander/Services/ChatService.cs
Normal file
91
LANCommander/Services/ChatService.cs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
using LANCommander.Data;
|
||||
using LANCommander.Data.Models;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LANCommander.Services
|
||||
{
|
||||
public class ChatService
|
||||
{
|
||||
private readonly IServiceScopeFactory ScopeFactory;
|
||||
private Dictionary<string, User> Connections { get; set; }
|
||||
|
||||
public ChatService(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
ScopeFactory = scopeFactory;
|
||||
Connections = new Dictionary<string, User>();
|
||||
}
|
||||
|
||||
public async Task Connect(string connectionId, string username)
|
||||
{
|
||||
using (var scope = ScopeFactory.CreateScope())
|
||||
{
|
||||
var context = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
|
||||
|
||||
var user = await context.Users.FirstOrDefaultAsync(u => u.UserName == username);
|
||||
|
||||
if (user == null)
|
||||
throw new UnauthorizedAccessException();
|
||||
|
||||
Connections[connectionId] = user;
|
||||
}
|
||||
}
|
||||
|
||||
public User GetUser(string connectionId)
|
||||
{
|
||||
return Connections[connectionId];
|
||||
}
|
||||
|
||||
public async Task<Message> SendMessageToUserAsync(Guid senderId, Guid recipientId, string contents)
|
||||
{
|
||||
using (var scope = ScopeFactory.CreateScope())
|
||||
{
|
||||
var context = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
|
||||
|
||||
var sender = await context.Users.FirstOrDefaultAsync(u => u.Id == senderId);
|
||||
var recipient = await context.Users.FirstOrDefaultAsync(u => u.Id == recipientId);
|
||||
|
||||
var channel = sender.Channels.FirstOrDefault(c => c.Users.Count() == 2 && c.Users.Any(u => u.Id == recipientId));
|
||||
|
||||
// Create DM channel if it doesn't already exist
|
||||
if (channel == null)
|
||||
{
|
||||
channel = new Channel
|
||||
{
|
||||
Type = Data.Enums.ChannelType.DirectMessage,
|
||||
CreatedBy = sender,
|
||||
Users = new List<User> { sender, recipient },
|
||||
Name = "Direct Message",
|
||||
CreatedOn = DateTime.Now
|
||||
};
|
||||
|
||||
await context.AddAsync(channel);
|
||||
}
|
||||
|
||||
var message = new Message
|
||||
{
|
||||
Channel = channel,
|
||||
Contents = contents,
|
||||
CreatedBy = sender,
|
||||
Sender = sender,
|
||||
CreatedOn = DateTime.Now
|
||||
};
|
||||
|
||||
await context.AddAsync(message);
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Message>> GetMessages(Guid channelId, int skip = 0, int take = 25)
|
||||
{
|
||||
using (var scope = ScopeFactory.CreateScope())
|
||||
{
|
||||
var context = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
|
||||
|
||||
return await context.Messages.Where(m => m.Channel.Id == channelId).OrderByDescending(m => m.CreatedOn).Skip(skip).Take(take).ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
LANCommander/Services/MessageService.cs
Normal file
12
LANCommander/Services/MessageService.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using LANCommander.Data;
|
||||
using LANCommander.Data.Models;
|
||||
|
||||
namespace LANCommander.Services
|
||||
{
|
||||
public class MessageService : BaseDatabaseService<Message>
|
||||
{
|
||||
public MessageService(DatabaseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,6 @@
|
|||
}
|
||||
|
||||
<link href="_content/XtermBlazor/XtermBlazor.css" rel="stylesheet" />
|
||||
|
||||
<link href="~/css/site.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body data-theme="@SettingService.GetSettings().Theme">
|
||||
|
|
@ -37,6 +36,7 @@
|
|||
<script src="~/_content/AntDesign/js/ant-design-blazor.js"></script>
|
||||
<script src="~/_content/AntDesign.Charts/ant-design-charts-blazor.js"></script>
|
||||
<script src="~/_framework/blazor.server.js"></script>
|
||||
<script src="~/lib/signalr/dist/browser/signalr.min.js"></script>
|
||||
|
||||
<script src="~/_content/XtermBlazor/XtermBlazor.min.js"></script>
|
||||
<script src="~/lib/xterm-addon-fit/lib/xterm-addon-fit.min.js"></script>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,14 @@
|
|||
"files": [
|
||||
"axios.min.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"provider": "unpkg",
|
||||
"library": "@microsoft/signalr@latest",
|
||||
"destination": "wwwroot/lib/signalr/",
|
||||
"files": [
|
||||
"dist/browser/signalr.min.js"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue