test
This commit is contained in:
parent
89f1b3406c
commit
143102d7ef
@ -1,4 +1,6 @@
|
||||
const { EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder } = require('discord.js');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const PINBOARD_SELECT_CUSTOM_ID = 'pinboard-image-select';
|
||||
const selectedImageIndexByMessage = new Map();
|
||||
@ -18,12 +20,72 @@ const toCacheBustedUrl = (url) => {
|
||||
return `${url}${separator}cb=${getCacheBustValue()}`;
|
||||
};
|
||||
|
||||
const parsePinboardImageUrls = () => {
|
||||
const raw = process.env.PINBOARD_IMAGE_URLS || '';
|
||||
return raw
|
||||
const readPinboardRawFromEnvFile = () => {
|
||||
try {
|
||||
const envPath = path.join(process.cwd(), '.env');
|
||||
if (!fs.existsSync(envPath)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(envPath, 'utf8');
|
||||
const marker = 'PINBOARD_IMAGE_URLS=';
|
||||
const start = content.indexOf(marker);
|
||||
|
||||
if (start === -1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const afterMarkerIndex = start + marker.length;
|
||||
const rest = content.slice(afterMarkerIndex);
|
||||
const nextVarMatch = rest.match(/\n[A-Z0-9_]+=/);
|
||||
const end = nextVarMatch ? afterMarkerIndex + nextVarMatch.index : content.length;
|
||||
return content.slice(afterMarkerIndex, end).trim();
|
||||
} catch (error) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const parsePinboardImageItems = () => {
|
||||
let raw = process.env.PINBOARD_IMAGE_URLS || '';
|
||||
|
||||
// Support multiline object-like config when dotenv only captures the first line.
|
||||
if (!raw || raw.trim() === '{') {
|
||||
raw = readPinboardRawFromEnvFile();
|
||||
}
|
||||
|
||||
if (!raw) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const items = [];
|
||||
const pairRegex = /name\s*:\s*([^,\n]+?)\s*,\s*url\s*:\s*(https?:\/\/[^\s,}\]]+)/gim;
|
||||
|
||||
let match = pairRegex.exec(raw);
|
||||
while (match) {
|
||||
const name = match[1].trim().replace(/^['"]|['"]$/g, '');
|
||||
const url = match[2].trim().replace(/^['"]|['"]$/g, '');
|
||||
|
||||
if (name && /^https?:\/\//i.test(url)) {
|
||||
items.push({ name, url });
|
||||
}
|
||||
|
||||
match = pairRegex.exec(raw);
|
||||
}
|
||||
|
||||
if (items.length > 0) {
|
||||
return items;
|
||||
}
|
||||
|
||||
// Fallback legacy: comma-separated URLs only
|
||||
const urls = raw
|
||||
.split(',')
|
||||
.map(url => url.trim())
|
||||
.filter(url => /^https?:\/\//i.test(url));
|
||||
|
||||
return urls.map((url, index) => ({
|
||||
name: `Image ${index + 1}`,
|
||||
url
|
||||
}));
|
||||
};
|
||||
|
||||
const clampIndex = (index, length) => {
|
||||
@ -33,18 +95,19 @@ const clampIndex = (index, length) => {
|
||||
return index;
|
||||
};
|
||||
|
||||
const buildSelectedImageEmbed = (url, index, total) => (
|
||||
const buildSelectedImageEmbed = (item, index, total) => (
|
||||
new EmbedBuilder()
|
||||
.setColor('#f59e0b')
|
||||
.setTitle(`Image selectionnee (${index + 1}/${total})`)
|
||||
.setImage(toCacheBustedUrl(url))
|
||||
.setTitle(item.name)
|
||||
.setDescription(`Image ${index + 1}/${total}`)
|
||||
.setImage(toCacheBustedUrl(item.url))
|
||||
);
|
||||
|
||||
const buildImageSelectorRow = (urls, selectedIndex) => {
|
||||
const options = urls.slice(0, 25).map((url, index) => ({
|
||||
label: `Image ${index + 1}`,
|
||||
const buildImageSelectorRow = (items, selectedIndex) => {
|
||||
const options = items.slice(0, 25).map((item, index) => ({
|
||||
label: item.name.length > 100 ? `${item.name.slice(0, 97)}...` : item.name,
|
||||
value: String(index),
|
||||
description: url.length > 95 ? `${url.slice(0, 92)}...` : url,
|
||||
description: item.url.length > 95 ? `${item.url.slice(0, 92)}...` : item.url,
|
||||
default: index === selectedIndex
|
||||
}));
|
||||
|
||||
@ -100,17 +163,17 @@ const buildPanelEmbed = (status) => {
|
||||
|
||||
const buildPanelPayload = (status, messageId) => {
|
||||
const panelEmbed = buildPanelEmbed(status);
|
||||
const pinboardUrls = parsePinboardImageUrls();
|
||||
const pinboardItems = parsePinboardImageItems().slice(0, 25);
|
||||
|
||||
if (pinboardUrls.length === 0) {
|
||||
if (pinboardItems.length === 0) {
|
||||
return { content: '', embeds: [panelEmbed], components: [] };
|
||||
}
|
||||
|
||||
const currentIndex = clampIndex(selectedImageIndexByMessage.get(messageId) ?? 0, pinboardUrls.length);
|
||||
const currentIndex = clampIndex(selectedImageIndexByMessage.get(messageId) ?? 0, pinboardItems.length);
|
||||
selectedImageIndexByMessage.set(messageId, currentIndex);
|
||||
|
||||
const selectedImageEmbed = buildSelectedImageEmbed(pinboardUrls[currentIndex], currentIndex, pinboardUrls.length);
|
||||
const selectorRow = buildImageSelectorRow(pinboardUrls, currentIndex);
|
||||
const selectedImageEmbed = buildSelectedImageEmbed(pinboardItems[currentIndex], currentIndex, pinboardItems.length);
|
||||
const selectorRow = buildImageSelectorRow(pinboardItems, currentIndex);
|
||||
|
||||
return {
|
||||
content: '',
|
||||
@ -173,15 +236,15 @@ const handlePinboardSelection = async (interaction) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const pinboardUrls = parsePinboardImageUrls();
|
||||
const pinboardItems = parsePinboardImageItems().slice(0, 25);
|
||||
|
||||
if (pinboardUrls.length === 0) {
|
||||
if (pinboardItems.length === 0) {
|
||||
await interaction.reply({ content: 'Aucune image configuree dans PINBOARD_IMAGE_URLS.', ephemeral: true });
|
||||
return true;
|
||||
}
|
||||
|
||||
const selectedRaw = Number.parseInt(interaction.values?.[0] || '0', 10);
|
||||
const selectedIndex = clampIndex(selectedRaw, pinboardUrls.length);
|
||||
const selectedIndex = clampIndex(selectedRaw, pinboardItems.length);
|
||||
selectedImageIndexByMessage.set(interaction.message.id, selectedIndex);
|
||||
|
||||
const status = await getMinecraftStatus();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user