feat: handle video URLs in e621 embeds (webm/mp4 shown as clickable links)

This commit is contained in:
loki5512344 2026-07-13 00:13:56 +02:00
parent ac46327380
commit bdaba4825c
Signed by: boba
GPG key ID: 253067914055423B

View file

@ -7,10 +7,13 @@ import net.dv8tion.jda.api.components.buttons.Button;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public final class ImageEmbedHelper {
private static final String NAV_PREFIX = "img_nav:";
private static final Set<String> IMAGE_EXTS = Set.of("jpg", "jpeg", "png", "gif", "webp", "bmp");
private static final Set<String> VIDEO_EXTS = Set.of("webm", "mp4");
private ImageEmbedHelper() {}
@ -23,11 +26,25 @@ public final class ImageEmbedHelper {
for (String url : pageUrls) {
var builder = EmbedFactory.create()
.withTitle("🔞 " + session.site())
.withImage(url)
.withColor(session.color());
if (!descUsed && !tagsStr.isBlank()) {
builder.withDescription(tagsStr);
descUsed = true;
String ext = extension(url);
boolean isVideo = isVideoExt(ext);
if (!isVideo) {
builder.withImage(url);
}
if (!descUsed) {
String desc = "";
if (!tagsStr.isBlank()) desc = tagsStr;
if (isVideo) {
if (!desc.isEmpty()) desc += "\n";
desc += "🎬 [" + ext.toUpperCase() + "](" + url + ")";
}
if (!desc.isEmpty()) {
builder.withDescription(desc);
descUsed = true;
}
} else if (isVideo) {
builder.withDescription("🎬 [" + ext.toUpperCase() + "](" + url + ")");
}
embeds.add(builder.build());
}
@ -37,16 +54,28 @@ public final class ImageEmbedHelper {
if (!session.tags().isBlank()) {
footer += " · " + session.tags();
}
// Последний эмбед получает футер
int last = embeds.size() - 1;
var lastUrl = pageUrls.get(last);
var lastExt = extension(lastUrl);
var lastBuilder = EmbedFactory.create()
.withTitle("🔞 " + session.site())
.withImage(pageUrls.get(last))
.withColor(session.color())
.withFooter(footer);
// Если description ещё не был поставлен (1 эмбед на странице)
if (!descUsed && !tagsStr.isBlank()) {
lastBuilder.withDescription(tagsStr);
if (!isVideoExt(lastExt)) {
lastBuilder.withImage(lastUrl);
}
if (!descUsed) {
String desc = "";
if (!tagsStr.isBlank()) desc = tagsStr;
if (isVideoExt(lastExt)) {
if (!desc.isEmpty()) desc += "\n";
desc += "🎬 [" + lastExt.toUpperCase() + "](" + lastUrl + ")";
}
if (!desc.isEmpty()) {
lastBuilder.withDescription(desc);
}
} else if (isVideoExt(lastExt)) {
lastBuilder.withDescription("🎬 [" + lastExt.toUpperCase() + "](" + lastUrl + ")");
}
embeds.set(last, lastBuilder.build());
}
@ -54,13 +83,6 @@ public final class ImageEmbedHelper {
return embeds.toArray(new MessageEmbed[0]);
}
/**
* Кнопка «Вперёд» отключается только если:
* - нет следующей страницы В сессии и уже последняя API-страница (isEmpty флаг).
* Поскольку мы не знаем заранее, есть ли ещё страницы на сервере,
* кнопка остаётся активной пока не придёт пустой ответ от API.
* Флаг session.exhausted() сигнализирует об этом.
*/
public static ActionRow buildActionRow(ImageSession session) {
boolean noPrev = !session.hasPrev();
boolean noNext = !session.hasNext() && session.exhausted();
@ -88,4 +110,16 @@ public final class ImageEmbedHelper {
public static String tagsDesc(String tags) {
return (tags == null || tags.isBlank()) ? "" : " `" + tags + "`";
}
private static String extension(String url) {
int dot = url.lastIndexOf('.');
if (dot < 0 || dot >= url.length() - 1) return "";
int end = url.indexOf('?', dot);
if (end < 0) end = url.length();
return url.substring(dot + 1, end).toLowerCase();
}
private static boolean isVideoExt(String ext) {
return VIDEO_EXTS.contains(ext);
}
}