@@ -717,6 +717,9 @@ await thread.ModifyAsync(t =>
717717 protected override Task ExecuteAsync ( CancellationToken stoppingToken )
718718 {
719719 _discordClient . GuildAvailable += OnGuildAvailable ;
720+ _discordClient . MessageReactionAdded += OnMessageReactionAdded ;
721+ _discordClient . MessageReactionRemoved += OnMessageReactionRemoved ;
722+
720723 Load ( ) ;
721724 return Task . CompletedTask ;
722725 }
@@ -763,6 +766,66 @@ private DiscordEmbedBuilder CreateDefaultEmbed(Suggestion suggestion, DiscordGui
763766 return embed ;
764767 }
765768
769+ private Task OnMessageReactionRemoved ( DiscordClient sender , MessageReactionRemoveEventArgs args )
770+ {
771+ string emoji = args . Emoji . Name ;
772+
773+ if ( ! ValidateReaction ( args . User as DiscordMember , args . Message , emoji , out Suggestion ? suggestion ) )
774+ {
775+ return Task . CompletedTask ;
776+ }
777+
778+ switch ( emoji )
779+ {
780+ case "👍" :
781+ suggestion . UpVotes -- ;
782+ break ;
783+
784+ case "👎" :
785+ suggestion . DownVotes -- ;
786+ break ;
787+
788+ default :
789+ return Task . CompletedTask ;
790+ }
791+
792+ using SuggestionContext context = _contextFactory . CreateDbContext ( ) ;
793+ context . Suggestions . Update ( suggestion ) ;
794+ context . SaveChanges ( ) ;
795+
796+ return Task . CompletedTask ;
797+ }
798+
799+ private Task OnMessageReactionAdded ( DiscordClient sender , MessageReactionAddEventArgs args )
800+ {
801+ string emoji = args . Emoji . Name ;
802+
803+ if ( ! ValidateReaction ( args . User as DiscordMember , args . Message , emoji , out Suggestion ? suggestion ) )
804+ {
805+ return Task . CompletedTask ;
806+ }
807+
808+ switch ( emoji )
809+ {
810+ case "👍" :
811+ suggestion . UpVotes ++ ;
812+ break ;
813+
814+ case "👎" :
815+ suggestion . DownVotes ++ ;
816+ break ;
817+
818+ default :
819+ return Task . CompletedTask ;
820+ }
821+
822+ using SuggestionContext context = _contextFactory . CreateDbContext ( ) ;
823+ context . Suggestions . Update ( suggestion ) ;
824+ context . SaveChanges ( ) ;
825+
826+ return Task . CompletedTask ;
827+ }
828+
766829 private Task OnGuildAvailable ( DiscordClient sender , GuildCreateEventArgs args )
767830 {
768831 DiscordGuild guild = args . Guild ;
@@ -785,9 +848,88 @@ private Task OnGuildAvailable(DiscordClient sender, GuildCreateEventArgs args)
785848 _logger . LogWarning ( "{Guild} is not configured!" , guild ) ;
786849 }
787850
851+ RefreshSuggestionScores ( args . Guild ) ;
788852 return Task . CompletedTask ;
789853 }
790854
855+ private bool ValidateReaction ( DiscordMember ? member ,
856+ DiscordMessage message ,
857+ string emoji ,
858+ [ NotNullWhen ( true ) ] out Suggestion ? suggestion )
859+ {
860+ suggestion = null ;
861+
862+ if ( member is null || member . IsBot )
863+ {
864+ return false ;
865+ }
866+
867+ DiscordGuild guild = member . Guild ;
868+ if ( message . Channel . Id != _configurationService . GetGuildConfiguration ( guild ) ? . SuggestionChannel )
869+ {
870+ return false ;
871+ }
872+
873+ if ( ! _suggestions . TryGetValue ( guild . Id , out List < Suggestion > ? suggestions ) )
874+ {
875+ return false ;
876+ }
877+
878+ if ( emoji != "👍" && emoji != "👎" )
879+ {
880+ return false ;
881+ }
882+
883+ suggestion = suggestions . FirstOrDefault ( s => s . MessageId == message . Id ) ;
884+ if ( suggestion is null )
885+ {
886+ return false ;
887+ }
888+
889+ return suggestion . Status != SuggestionStatus . Suggested ;
890+ }
891+
892+ private void RefreshSuggestionScores ( DiscordGuild guild )
893+ {
894+ IEnumerable < Suggestion > suggestions = GetSuggestions ( guild ) . Where ( s => s is
895+ {
896+ Status : SuggestionStatus . Suggested ,
897+ UpVotes : 0 ,
898+ DownVotes : 0
899+ } ) ;
900+
901+ var updatedSuggestions = new List < Suggestion > ( ) ;
902+
903+ foreach ( Suggestion suggestion in suggestions )
904+ {
905+ DiscordMessage ? message = GetSuggestionMessage ( suggestion ) ;
906+ if ( message is null )
907+ {
908+ continue ;
909+ }
910+
911+ int upVotes = message . Reactions . Count ( r => r . Emoji . Name == "👍" ) ;
912+ int downVotes = message . Reactions . Count ( r => r . Emoji . Name == "👎" ) ;
913+ if ( upVotes == suggestion . UpVotes && downVotes == suggestion . DownVotes )
914+ {
915+ continue ;
916+ }
917+
918+ suggestion . UpVotes = upVotes ;
919+ suggestion . DownVotes = downVotes ;
920+ updatedSuggestions . Add ( suggestion ) ;
921+ }
922+
923+ if ( updatedSuggestions . Count == 0 )
924+ {
925+ return ;
926+ }
927+
928+ using SuggestionContext context = _contextFactory . CreateDbContext ( ) ;
929+ context . Suggestions . UpdateRange ( updatedSuggestions ) ;
930+ context . SaveChanges ( ) ;
931+ }
932+
791933 private void Load ( )
792934 {
793935 using SuggestionContext context = _contextFactory . CreateDbContext ( ) ;
0 commit comments