Implement infinite loading with chat thread

- Chat messages are now loaded based on scroll position
- Read status is now updated and set by last message read
- Reworked script importing by using ScriptProvider
This commit is contained in:
Pat Hartl 2026-01-11 14:38:24 -06:00
parent a0c7bf63f0
commit 66abc6e59e
40 changed files with 3723 additions and 117 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,67 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LANCommander.Migrations
{
/// <inheritdoc />
public partial class ChatReadStatusMessageId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_ChatThreadReadStatuses_ThreadId",
table: "ChatThreadReadStatuses");
migrationBuilder.RenameColumn(
name: "LastReadOn",
table: "ChatThreadReadStatuses",
newName: "LastReadMessageId");
migrationBuilder.AddPrimaryKey(
name: "PK_ChatThreadReadStatuses",
table: "ChatThreadReadStatuses",
columns: new[] { "ThreadId", "UserId" });
migrationBuilder.CreateIndex(
name: "IX_ChatThreadReadStatuses_LastReadMessageId",
table: "ChatThreadReadStatuses",
column: "LastReadMessageId");
migrationBuilder.AddForeignKey(
name: "FK_ChatThreadReadStatuses_ChatMessages_LastReadMessageId",
table: "ChatThreadReadStatuses",
column: "LastReadMessageId",
principalTable: "ChatMessages",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_ChatThreadReadStatuses_ChatMessages_LastReadMessageId",
table: "ChatThreadReadStatuses");
migrationBuilder.DropPrimaryKey(
name: "PK_ChatThreadReadStatuses",
table: "ChatThreadReadStatuses");
migrationBuilder.DropIndex(
name: "IX_ChatThreadReadStatuses_LastReadMessageId",
table: "ChatThreadReadStatuses");
migrationBuilder.RenameColumn(
name: "LastReadMessageId",
table: "ChatThreadReadStatuses",
newName: "LastReadOn");
migrationBuilder.CreateIndex(
name: "IX_ChatThreadReadStatuses_ThreadId",
table: "ChatThreadReadStatuses",
column: "ThreadId");
}
}
}

View file

@ -378,16 +378,18 @@ namespace LANCommander.Migrations
modelBuilder.Entity("LANCommander.Server.Data.Models.ChatThreadReadStatus", b =>
{
b.Property<DateTime?>("LastReadOn")
.HasColumnType("TEXT");
b.Property<Guid>("ThreadId")
.HasColumnType("TEXT");
b.Property<Guid>("UserId")
.HasColumnType("TEXT");
b.HasIndex("ThreadId");
b.Property<Guid?>("LastReadMessageId")
.HasColumnType("TEXT");
b.HasKey("ThreadId", "UserId");
b.HasIndex("LastReadMessageId");
b.HasIndex("UserId");
@ -2093,6 +2095,11 @@ namespace LANCommander.Migrations
modelBuilder.Entity("LANCommander.Server.Data.Models.ChatThreadReadStatus", b =>
{
b.HasOne("LANCommander.Server.Data.Models.ChatMessage", "LastReadMessage")
.WithMany()
.HasForeignKey("LastReadMessageId")
.OnDelete(DeleteBehavior.SetNull);
b.HasOne("LANCommander.Server.Data.Models.ChatThread", "Thread")
.WithMany()
.HasForeignKey("ThreadId")
@ -2105,6 +2112,8 @@ namespace LANCommander.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LastReadMessage");
b.Navigation("Thread");
b.Navigation("User");