11package net .javadiscord .javabot .systems .qotw .commands .view ;
22
3+ import java .sql .SQLException ;
34import java .util .Comparator ;
45import java .util .List ;
56
7+ import javax .annotation .Nonnull ;
8+
9+ import org .jetbrains .annotations .NotNull ;
10+
11+ import com .dynxsty .dih4jda .interactions .ComponentIdBuilder ;
612import com .dynxsty .dih4jda .interactions .commands .SlashCommand ;
13+ import com .dynxsty .dih4jda .interactions .components .ButtonHandler ;
714
815import net .dv8tion .jda .api .EmbedBuilder ;
916import net .dv8tion .jda .api .entities .MessageEmbed ;
1017import net .dv8tion .jda .api .events .interaction .command .SlashCommandInteractionEvent ;
18+ import net .dv8tion .jda .api .events .interaction .component .ButtonInteractionEvent ;
1119import net .dv8tion .jda .api .interactions .commands .OptionMapping ;
1220import net .dv8tion .jda .api .interactions .commands .OptionType ;
1321import net .dv8tion .jda .api .interactions .commands .build .SubcommandData ;
22+ import net .dv8tion .jda .api .interactions .components .ActionRow ;
23+ import net .dv8tion .jda .api .interactions .components .buttons .Button ;
1424import net .javadiscord .javabot .data .h2db .DbActions ;
25+ import net .javadiscord .javabot .data .h2db .DbHelper ;
1526import net .javadiscord .javabot .systems .qotw .dao .QuestionQueueRepository ;
1627import net .javadiscord .javabot .systems .qotw .model .QOTWQuestion ;
1728import net .javadiscord .javabot .util .Responses ;
1829
1930/**
2031 * Represents the `/qotw-view query` subcommand. It allows for listing filtering QOTWs.
2132 */
22- public class QOTWQuerySubcommand extends SlashCommand .Subcommand {
33+ public class QOTWQuerySubcommand extends SlashCommand .Subcommand implements ButtonHandler {
34+
35+ private static final int MAX_BUTTON_QUERY_LENGTH = 10 ;
36+ private static final int PAGE_LIMIT = 20 ;
37+
38+ /**
39+ * The constructor of this class, which sets the corresponding {@link SubcommandData}.
40+ */
2341 public QOTWQuerySubcommand () {
2442 setSubcommandData (new SubcommandData ("list-questions" , "Lists previous questions of the week" )
25- .addOption (OptionType .STRING , "query" , "Only queries questions that contain a specific query" , false ));
43+ .addOption (OptionType .STRING , "query" , "Only queries questions that contain a specific query" , false )
44+ .addOption (OptionType .INTEGER , "page" , "The page to show, starting with 1" ));
2645 }
2746
2847 @ Override
@@ -32,17 +51,72 @@ public void execute(SlashCommandInteractionEvent event) {
3251 return ;
3352 }
3453 String query = event .getOption ("query" , ()->"" , OptionMapping ::getAsString );
54+ int page = event .getOption ("page" ,() -> 1 , OptionMapping ::getAsInt )-1 ;
55+ if (page < 0 ) {
56+ Responses .error (event , "Invalid page - must be >= 1" ).queue ();
57+ return ;
58+ }
3559 event .deferReply (true ).queue ();
3660 DbActions .doAsyncDaoAction (QuestionQueueRepository ::new , repo ->{
37- List <QOTWQuestion > questions = repo .getUsedQuestionsWithQuery (event .getGuild ().getIdLong (), query , 0 , 20 );
38- EmbedBuilder eb = new EmbedBuilder ();
39- eb .setDescription ("Questions of the week" +(query .isEmpty ()?"" :" matching '" +query +"'" ));
40- questions
41- .stream ()
42- .sorted (Comparator .comparingInt (QOTWQuestion ::getQuestionNumber ))
43- .map (q -> new MessageEmbed .Field ("Question #" + q .getQuestionNumber (), q .getText (), true ))
44- .forEach (eb ::addField );
45- event .getHook ().sendMessageEmbeds (eb .build ()).queue ();
61+ MessageEmbed embed = buildListQuestionsEmbed (repo , event .getGuild ().getIdLong (), query , page );
62+ event .getHook ()
63+ .sendMessageEmbeds (embed )
64+ .addActionRows (buildPageControls (query , page , embed ))
65+ .queue ();
66+ });
67+ }
68+
69+ @ Override
70+ public void handleButton (@ Nonnull ButtonInteractionEvent event , @ Nonnull Button button ) {
71+ event .deferEdit ().queue ();
72+ String [] id = ComponentIdBuilder .split (event .getComponentId ());
73+ int page = Integer .parseInt (id [1 ]);
74+ String query = id .length == 2 ? "" : id [2 ];
75+ if (page < 0 ) {
76+ Responses .error (event .getHook (), "Invalid page - must be >= 1" ).queue ();
77+ return ;
78+ }
79+ DbHelper .doDaoAction (QuestionQueueRepository ::new , repo -> {
80+ MessageEmbed embed = buildListQuestionsEmbed (repo , event .getGuild ().getIdLong (), query , page );
81+ event .getHook ()
82+ .editOriginalEmbeds (embed )
83+ .setActionRows (buildPageControls (query , page , embed ))
84+ .queue ();
4685 });
4786 }
87+
88+ @ NotNull
89+ private ActionRow buildPageControls (String query , int page , MessageEmbed embed ) {
90+ if (query .length () > MAX_BUTTON_QUERY_LENGTH ) {
91+ query = query .substring (0 ,MAX_BUTTON_QUERY_LENGTH );
92+ }
93+ return ActionRow .of (
94+ Button .primary (ComponentIdBuilder .build ("qotw-list-questions" , page -1 +"" , query ), "Previous Page" )
95+ .withDisabled (page <= 0 ),
96+ Button .primary (ComponentIdBuilder .build ("qotw-list-questions" , page +1 +"" , query ), "Next Page" )
97+ .withDisabled (embed .getFields ().size () < PAGE_LIMIT )
98+ );
99+ }
100+
101+ private MessageEmbed buildListQuestionsEmbed (QuestionQueueRepository repo , long guildId , String query , int page ) throws SQLException {
102+ List <QOTWQuestion > questions = repo .getUsedQuestionsWithQuery (guildId , query , page *PAGE_LIMIT , PAGE_LIMIT );
103+ EmbedBuilder eb = new EmbedBuilder ();
104+ eb .setDescription ("**Questions of the week" +(query .isEmpty ()?"" :" matching '" +query +"'" )+"**" );
105+ questions
106+ .stream ()
107+ .sorted (Comparator .comparingInt (QOTWQuestion ::getQuestionNumber ))
108+ .map (q -> new MessageEmbed .Field ("Question #" + q .getQuestionNumber (), q .getText (), true ))
109+ .forEach (eb ::addField );
110+ if (eb .getFields ().isEmpty ()) {
111+ eb .appendDescription ("\n No questions found" );
112+ if (page != 0 ) {
113+ eb .appendDescription (" on this page" );
114+ }
115+ }
116+ eb .setFooter ("Page " +(page +1 ));
117+ eb .setColor (Responses .Type .DEFAULT .getColor ());
118+ return eb .build ();
119+ }
120+
121+
48122}
0 commit comments