From dec332cab56fa843dd4cef01e6fd2f4d7e7dc777 Mon Sep 17 00:00:00 2001 From: aNNiMON Date: Thu, 19 Oct 2023 20:19:57 +0300 Subject: [PATCH] Switch prev/next buttons with selectable parameters --- .../ffmpeg/CallbackQueryCommands.java | 4 +- .../ffmpeg/MediaProcessingBundle.java | 43 +++++--------- .../ffmpeg/MediaProcessingKeyboard.java | 58 ++++++++++++++++--- .../ffmpegbot/parameters/AudioBitrate.java | 6 +- .../ffmpegbot/parameters/AudioEffect.java | 6 +- .../parameters/AudioStreamByLanguage.java | 6 +- .../ffmpegbot/parameters/AudioVolume.java | 6 +- .../parameters/BooleanParameter.java | 11 +--- .../ffmpegbot/parameters/Parameter.java | 39 ++++++------- .../ffmpegbot/parameters/VideoBitrate.java | 6 +- .../ffmpegbot/parameters/VideoFrameRate.java | 6 +- .../ffmpegbot/parameters/VideoScale.java | 6 +- .../ffmpegbot/session/MediaSession.java | 12 ++++ 13 files changed, 119 insertions(+), 90 deletions(-) diff --git a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/CallbackQueryCommands.java b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/CallbackQueryCommands.java index a8ac5a1..2eb292b 100644 --- a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/CallbackQueryCommands.java +++ b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/CallbackQueryCommands.java @@ -1,9 +1,7 @@ package com.annimon.ffmpegbot.commands.ffmpeg; public final class CallbackQueryCommands { - public static final String PREV = "prev"; - public static final String NEXT = "next"; - public static final String DETAIL = "detail"; + public static final String PARAMETER = "p"; public static final String PROCESS = "process"; public static final String YTDLP_START = "ytdlp_start"; public static final String YTDLP_INFO = "ytdlp_info"; diff --git a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java index a39b81a..7528839 100644 --- a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java +++ b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.stream.Collectors; import static com.annimon.ffmpegbot.Permissions.ALLOWED_USERS; import static com.annimon.ffmpegbot.commands.ffmpeg.CallbackQueryCommands.*; @@ -43,9 +42,7 @@ public class MediaProcessingBundle implements CommandBundle { @Override public void register(@NotNull CommandRegistry commands) { - commands.register(new SimpleCallbackQueryCommand(PREV, ALLOWED_USERS, ctx -> toggleParameter(ctx, true))); - commands.register(new SimpleCallbackQueryCommand(NEXT, ALLOWED_USERS, ctx -> toggleParameter(ctx, false))); - commands.register(new SimpleCallbackQueryCommand(DETAIL, ALLOWED_USERS, sessionCommand(this::details))); + commands.register(new SimpleCallbackQueryCommand(PARAMETER, ALLOWED_USERS, sessionCommand(this::parameter))); commands.register(new SimpleCallbackQueryCommand(PROCESS, ALLOWED_USERS, sessionCommand(this::process))); } @@ -76,38 +73,26 @@ public class MediaProcessingBundle implements CommandBundle { .call(sender); } - private void toggleParameter(final CallbackQueryContext ctx, final boolean toLeft) { - final var msg = ctx.message(); - if (msg == null) return; + private void parameter(final CallbackQueryContext ctx, final MediaSession session) { + if (ctx.argumentsLength() == 0) { + session.setSelectedParam(null); + } else { + final String id = ctx.argument(0); + final var param = session.getParams().stream() + .filter(p -> p.getId().equals(id)) + .findFirst().orElse(null); - final var session = sessions.getMediaSession(msg.getChatId(), msg.getMessageId()); - if (session == null) return; + session.setSelectedParam(param); - final String id = ctx.argument(0); - final var parameters = session.getParams().stream() - .filter(p -> p.getId().equals(id)) - .collect(Collectors.toSet()); - if (parameters.isEmpty()) return; - - for (Parameter param : parameters) { - if (toLeft) { - param.toggleLeft(); - } else { - param.toggleRight(); + if (param != null && ctx.argumentsLength() == 2) { + final int index = Integer.parseInt(ctx.argument(1)); + param.select(index); + session.setSelectedParam(null); } } editMessage(ctx, session); } - private void details(final CallbackQueryContext ctx, final MediaSession session) { - final String id = ctx.argument(0); - session.getParams().stream() - .filter(p -> p.getId().equals(id)) - .findFirst() - .ifPresent(p -> - ctx.answerAsAlert(p.describe()).callAsync(ctx.sender)); - } - private void process(final CallbackQueryContext ctx, final MediaSession session) { if (!session.isDownloaded()) { sendAction(ctx, session); diff --git a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingKeyboard.java b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingKeyboard.java index cf95a78..250c8e2 100644 --- a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingKeyboard.java +++ b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingKeyboard.java @@ -7,25 +7,63 @@ import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMa import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import static com.annimon.ffmpegbot.commands.ffmpeg.CallbackQueryCommands.*; public class MediaProcessingKeyboard { + private static final int BUTTON_COLUMNS = 2; + public static InlineKeyboardMarkup createKeyboard(MediaSession session) { + final var selectedParam = session.getSelectedParam(); + if (selectedParam != null) { + return createParamKeyboard(selectedParam); + } else { + return createParamsListKeyboard(session.getParams()); + } + } + + private static InlineKeyboardMarkup createParamsListKeyboard(List> params) { final var keyboard = new ArrayList>(); - for (Parameter param : session.getParams()) { - final String paramId = param.getId(); - keyboard.add(List.of( - inlineKeyboardButton("<", callbackData(PREV, paramId)), - inlineKeyboardButton(param.describe(), callbackData(DETAIL, paramId)), - inlineKeyboardButton(">", callbackData(NEXT, paramId)) - )); + final var it = params.iterator(); + while (it.hasNext()) { + final var row = new ArrayList(); + for (int i = 0; i < BUTTON_COLUMNS; i++) { + if (it.hasNext()) { + final var param = it.next(); + final String paramId = param.getId(); + row.add(inlineKeyboardButton(param.describe(), callbackData(PARAMETER, paramId))); + } + } + keyboard.add(row); } keyboard.add(List.of(inlineKeyboardButton("Process", callbackData(PROCESS)))); return new InlineKeyboardMarkup(keyboard); } + private static InlineKeyboardMarkup createParamKeyboard(Parameter param) { + final var keyboard = new ArrayList>(); + final String paramId = param.getId(); + final int maxSize = param.getPossibleValuesSize(); + int index = 0; + while (index < maxSize) { + final var row = new ArrayList(); + for (int i = 0; i < BUTTON_COLUMNS; i++) { + if (index < maxSize) { + String value = param.describeValueByIndex(index); + row.add(inlineKeyboardButton(value, callbackData(PARAMETER, callbackParams(paramId, index)))); + index++; + } + } + keyboard.add(row); + } + keyboard.add(List.of(inlineKeyboardButton("Back", callbackData(PARAMETER)))); + return new InlineKeyboardMarkup(keyboard); + } + public static InlineKeyboardMarkup createKeyboard(YtDlpSession session) { final var keyboard = new ArrayList>(); if (!session.hasAdditionalInfo()) { @@ -42,12 +80,16 @@ public class MediaProcessingKeyboard { return button; } - @SuppressWarnings("SameParameterValue") private static String callbackData(String command) { return command; } + @SuppressWarnings("SameParameterValue") private static String callbackData(String command, String data) { return command + ":" + data; } + + private static String callbackParams(Object... params) { + return Arrays.stream(params).map(Objects::toString).collect(Collectors.joining(" ")); + } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/AudioBitrate.java b/src/main/java/com/annimon/ffmpegbot/parameters/AudioBitrate.java index c764fc0..d2003b2 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/AudioBitrate.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/AudioBitrate.java @@ -15,11 +15,11 @@ public class AudioBitrate extends StringParameter { } @Override - public String describe() { + public String describeValue(String value) { if (value.isEmpty()) { - return describeValue("AUTO"); + return "AUTO"; } else { - return super.describe(); + return super.describeValue(value); } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/AudioEffect.java b/src/main/java/com/annimon/ffmpegbot/parameters/AudioEffect.java index 338ba1a..819711f 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/AudioEffect.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/AudioEffect.java @@ -20,11 +20,11 @@ public class AudioEffect extends StringParameter { } @Override - public String describe() { + public String describeValue(String value) { if (value.isEmpty()) { - return describeValue("NONE"); + return "NONE"; } else { - return super.describe(); + return super.describeValue(value); } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/AudioStreamByLanguage.java b/src/main/java/com/annimon/ffmpegbot/parameters/AudioStreamByLanguage.java index 0cffccf..563c14e 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/AudioStreamByLanguage.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/AudioStreamByLanguage.java @@ -14,11 +14,11 @@ public class AudioStreamByLanguage extends StringParameter { } @Override - public String describe() { + public String describeValue(String value) { if (value.isEmpty()) { - return describeValue("AUTO"); + return "AUTO"; } else { - return super.describe(); + return super.describeValue(value); } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/AudioVolume.java b/src/main/java/com/annimon/ffmpegbot/parameters/AudioVolume.java index bf5b933..fc305e7 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/AudioVolume.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/AudioVolume.java @@ -14,11 +14,11 @@ public class AudioVolume extends StringParameter { } @Override - public String describe() { + public String describeValue(String value) { if (value.isEmpty()) { - return describeValue("ORIGINAL"); + return "ORIGINAL"; } else { - return super.describe(); + return super.describeValue(value); } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/BooleanParameter.java b/src/main/java/com/annimon/ffmpegbot/parameters/BooleanParameter.java index 5d3ccc9..fd960db 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/BooleanParameter.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/BooleanParameter.java @@ -8,16 +8,11 @@ public abstract class BooleanParameter extends Parameter { } @Override - public String describe() { + public String describeValue(Boolean value) { if (value) { - return describeValue("ON"); + return "ON"; } else { - return describeValue("OFF"); + return "OFF"; } } - - @Override - protected void toggle(int dir) { - value = !value; - } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/Parameter.java b/src/main/java/com/annimon/ffmpegbot/parameters/Parameter.java index 7f7519f..53ec19a 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/Parameter.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/Parameter.java @@ -30,41 +30,38 @@ public abstract class Parameter { return value; } - public List getPossibleValues() { - return possibleValues; + public int getPossibleValuesSize() { + return possibleValues.size(); } + public abstract void accept(Visitor visitor, I input); - public String describe() { - return describeValue(Objects.toString(value)); + public final String describe() { + return displayName + ": " + describeValue(value); } - protected final String describeValue(String customValue) { - return displayName + ": " + customValue; + public final String describeValueByIndex(int index) { + return describeValue(safeGet(index)); } - public void toggleLeft() { - toggle(-1); + protected String describeValue(T valueToDescribe) { + return Objects.toString(valueToDescribe); } - public void toggleRight() { - toggle(+1); - } - - protected void toggle(int dir) { - final int size = possibleValues.size(); - if (size == 1) return; - - int nextIndex = possibleValues.indexOf(value) + dir; - if (nextIndex >= size) nextIndex -= size; - else if (nextIndex < 0) nextIndex += size; - - value = possibleValues.get(nextIndex); + public void select(int index) { + value = safeGet(index); } @Override public String toString() { return "[" + id + "] " + displayName + ": " + value; } + + private T safeGet(int index) { + final int size = possibleValues.size(); + if (index >= size) index = size - 1; + else if (index < 0) index = 0; + return possibleValues.get(index); + } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/VideoBitrate.java b/src/main/java/com/annimon/ffmpegbot/parameters/VideoBitrate.java index 7abeb79..b2c1989 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/VideoBitrate.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/VideoBitrate.java @@ -15,11 +15,11 @@ public class VideoBitrate extends StringParameter { } @Override - public String describe() { + public String describeValue(String value) { if (value.isEmpty()) { - return describeValue("AUTO"); + return "AUTO"; } else { - return super.describe(); + return super.describeValue(value); } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/VideoFrameRate.java b/src/main/java/com/annimon/ffmpegbot/parameters/VideoFrameRate.java index bc2aeb9..6e7ce69 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/VideoFrameRate.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/VideoFrameRate.java @@ -14,11 +14,11 @@ public class VideoFrameRate extends StringParameter { } @Override - public String describe() { + public String describeValue(String value) { if (value.isEmpty()) { - return describeValue("ORIGINAL"); + return "ORIGINAL"; } else { - return super.describe(); + return super.describeValue(value); } } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/VideoScale.java b/src/main/java/com/annimon/ffmpegbot/parameters/VideoScale.java index 9c477ac..721671a 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/VideoScale.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/VideoScale.java @@ -14,11 +14,11 @@ public class VideoScale extends StringParameter { } @Override - public String describe() { + public String describeValue(String value) { if (value.isEmpty()) { - return describeValue("ORIGINAL"); + return "ORIGINAL"; } else { - return describeValue(value + "p"); + return value + "p"; } } diff --git a/src/main/java/com/annimon/ffmpegbot/session/MediaSession.java b/src/main/java/com/annimon/ffmpegbot/session/MediaSession.java index 90f288f..e8b9134 100644 --- a/src/main/java/com/annimon/ffmpegbot/session/MediaSession.java +++ b/src/main/java/com/annimon/ffmpegbot/session/MediaSession.java @@ -17,6 +17,7 @@ public final class MediaSession extends Session { private Integer duration; private String resolution; // Parameters + private Parameter selectedParam; private List> params; // Files private File inputFile; @@ -77,6 +78,14 @@ public final class MediaSession extends Session { this.params = params; } + public void setSelectedParam(Parameter selectedParam) { + this.selectedParam = selectedParam; + } + + public Parameter getSelectedParam() { + return selectedParam; + } + public boolean isDownloaded() { return (inputFile != null) && (inputFile.canRead()); } @@ -128,6 +137,9 @@ public final class MediaSession extends Session { if (status != null) { joiner.add("" + safeHtml(status) + ""); } + if (selectedParam != null) { + joiner.add(safeHtml(selectedParam.describe())); + } return joiner; }