Commit b6f67b1a authored by Robert Rudman's avatar Robert Rudman

Implements #32 - Unpin messages we've pinned before pinning a new one

parent d8935b52
Pipeline #59346162 passed with stages
in 5 minutes and 46 seconds
......@@ -29,6 +29,7 @@ namespace Rodgort.Data
public DbSet<DbRole> Roles { get; set; }
public DbSet<DbUnknownDeletion> UnknownDeletions { get; set; }
public DbSet<DbSeenQuestion> SeenQuestions { get; set; }
public DbSet<DbPinnedMessages> PinnedMessages { get; set; }
public DbSet<DbMetaQuestionTagTrackingStatusAudit> MetaQuestionTagTrackingStatusAudits { get; set; }
public DbQuery<DbZombieTagsView> ZombieTagsView { get; set; }
......@@ -140,6 +141,9 @@ namespace Rodgort.Data
modelBuilder.Entity<DbSeenQuestion>().HasKey(sq => new { sq.Id, sq.Tag });
modelBuilder.Entity<DbSeenQuestion>().HasIndex(sq => sq.Tag);
modelBuilder.Entity<DbPinnedMessages>().ToTable("pinned_messages");
modelBuilder.Entity<DbPinnedMessages>().HasKey(pm => pm.Id);
modelBuilder.Query<DbZombieTagsView>().ToView("zombie_tags");
modelBuilder.Query<DbZombieTagsView>().HasOne(z => z.Tag).WithMany().HasForeignKey(z => z.TagName);
modelBuilder.Query<DbZombieTagsView>().Property(z => z.TagName).HasColumnName("tag_name");
......
namespace Rodgort.Data.Tables
{
public class DbPinnedMessages
{
public int Id { get; set; }
public string ChatDomain { get; set; }
public int MessageId { get; set; }
public int RoomId { get; set; }
}
}
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Rodgort.Migrations
{
public partial class TrackPinnedMessages : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "pinned_messages",
columns: table => new
{
id = table.Column<int>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
chat_domain = table.Column<string>(nullable: true),
message_id = table.Column<int>(nullable: false),
room_id = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_pinned_messages", x => x.id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "pinned_messages");
}
}
}
......@@ -322,6 +322,27 @@ namespace Rodgort.Migrations
);
});
modelBuilder.Entity("Rodgort.Data.Tables.DbPinnedMessages", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnName("id");
b.Property<string>("ChatDomain")
.HasColumnName("chat_domain");
b.Property<int>("MessageId")
.HasColumnName("message_id");
b.Property<int>("RoomId")
.HasColumnName("room_id");
b.HasKey("Id")
.HasName("pk_pinned_messages");
b.ToTable("pinned_messages");
});
modelBuilder.Entity("Rodgort.Data.Tables.DbRole", b =>
{
b.Property<int>("Id")
......
......@@ -138,7 +138,9 @@ namespace Rodgort.Services
var openQuestionsLink = QueryHelpers.AddQueryString("https://stackoverflow.com/search", new Dictionary<string, string> { { "q", $"[{tag}] is:q closed:no" } });
var burninationMessage = $"The burnination of [tag:{tag}] has STARTED! [Close Queue]({closeQueueLink}) - [Open questions]({openQuestionsLink}) - [Meta post]({metaPostUrl}) - [Burn room](https://chat.stackoverflow.com/rooms/{roomId}).";
await _chatClient.SendMessageAndPin(ChatSite.StackOverflow, ChatRooms.TROGDOR, burninationMessage);
var messageId = await _chatClient.SendMessageAndPin(ChatSite.StackOverflow, ChatRooms.TROGDOR, burninationMessage);
await UnpinMine(ChatSite.StackOverflow, ChatRooms.TROGDOR);
SavePinned(ChatSite.StackOverflow, ChatRooms.TROGDOR, messageId);
}
private async Task RenameObservationRoom(int roomId, string metaPostUrl, string tag)
......@@ -208,8 +210,10 @@ namespace Rodgort.Services
var burninationMessage = $"The burnination of [tag:{tag}] is now being discussed. [Meta post]({metaPostUrl}). [Observation room](https://chat.stackoverflow.com/rooms/{roomId}).";
await _chatClient.SendMessageAndPin(ChatSite.StackOverflow, ChatRooms.TROGDOR, burninationMessage);
var messageId = await _chatClient.SendMessageAndPin(ChatSite.StackOverflow, ChatRooms.TROGDOR, burninationMessage);
await UnpinMine(ChatSite.StackOverflow, ChatRooms.TROGDOR);
SavePinned(ChatSite.StackOverflow, ChatRooms.TROGDOR, messageId);
var burnakiFollow = new DbBurnakiFollow
{
BurnakiId = ChatUserIds.GEMMY,
......@@ -230,5 +234,21 @@ namespace Rodgort.Services
CancellationToken.None
);
}
private void SavePinned(ChatSite chatSite, int roomId, int messageId)
{
_rodgortContext.PinnedMessages.Add(new DbPinnedMessages { MessageId = messageId, ChatDomain = chatSite.ChatDomain, RoomId = roomId });
_rodgortContext.SaveChanges();
}
private async Task UnpinMine(ChatSite chatSite, int roomId)
{
var pinnedMessages = _rodgortContext.PinnedMessages.Where(pm => pm.ChatDomain == chatSite.ChatDomain && pm.RoomId == roomId).ToList();
await _chatClient.UnpinMessages(chatSite, roomId, pinnedMessages.Select(pm => pm.MessageId).ToArray());
foreach (var pinnedMessage in pinnedMessages)
_rodgortContext.PinnedMessages.Remove(pinnedMessage);
_rodgortContext.SaveChanges();
}
}
}
......@@ -43,7 +43,7 @@ namespace StackExchangeChat
public async Task<int> SendMessageAndPin(ChatSite chatSite, int roomId, string message)
{
var messageId = await SendMessage(chatSite, roomId, message);
await PinMessage(chatSite, roomId, messageId);
await PinMessages(chatSite, roomId, messageId);
return messageId;
}
......@@ -136,19 +136,23 @@ namespace StackExchangeChat
});
}
public async Task PinMessage(ChatSite chatSite, int currentRoomId, int messageId)
public async Task PinMessages(ChatSite chatSite, int currentRoomId, params int[] messageIds)
{
if (!await IsPinned(chatSite, currentRoomId, messageId))
await TogglePin(chatSite, currentRoomId, messageId);
var pinnedMessages = await PinnedMessages(chatSite, currentRoomId);
var messagesToPin = messageIds.Except(pinnedMessages);
foreach(var messageToPin in messagesToPin)
await TogglePin(chatSite, currentRoomId, messageToPin);
}
public async Task UnpinMessage(ChatSite chatSite, int currentRoomId, int messageId)
public async Task UnpinMessages(ChatSite chatSite, int currentRoomId, params int[] messageIds)
{
if (await IsPinned(chatSite, currentRoomId, messageId))
await TogglePin(chatSite, currentRoomId, messageId);
var pinnedMessages = await PinnedMessages(chatSite, currentRoomId);
var messagesToUnpin = messageIds.Intersect(pinnedMessages);
foreach (var messageToUnpin in messagesToUnpin)
await TogglePin(chatSite, currentRoomId, messageToUnpin);
}
public async Task<bool> IsPinned(ChatSite chatSite, int currentRoomId, int messageId)
public async Task<List<int>> PinnedMessages(ChatSite chatSite, int currentRoomId)
{
using (var httpClient = _serviceProvider.GetService<HttpClientWithHandler>())
{
......@@ -180,10 +184,15 @@ namespace StackExchangeChat
.Select(n => n.Value)
.ToList();
return pinnedMessageIds.Contains(messageId);
return pinnedMessageIds;
}
}
public async Task<bool> IsPinned(ChatSite chatSite, int currentRoomId, int messageId)
{
return (await PinnedMessages(chatSite, currentRoomId)).Contains(messageId);
}
public async Task TogglePin(ChatSite chatSite, int currentRoomId, int messageId)
{
await ThrottlingUtils.Throttle(ChatThrottleGroups.WebRequestThrottle, async () =>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment