test
This commit is contained in:
parent
89f1b3406c
commit
143102d7ef
@ -1,4 +1,6 @@
|
|||||||
const { EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder } = require('discord.js');
|
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 PINBOARD_SELECT_CUSTOM_ID = 'pinboard-image-select';
|
||||||
const selectedImageIndexByMessage = new Map();
|
const selectedImageIndexByMessage = new Map();
|
||||||
@ -18,12 +20,72 @@ const toCacheBustedUrl = (url) => {
|
|||||||
return `${url}${separator}cb=${getCacheBustValue()}`;
|
return `${url}${separator}cb=${getCacheBustValue()}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parsePinboardImageUrls = () => {
|
const readPinboardRawFromEnvFile = () => {
|
||||||
const raw = process.env.PINBOARD_IMAGE_URLS || '';
|
try {
|
||||||
return raw
|
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(',')
|
.split(',')
|
||||||
.map(url => url.trim())
|
.map(url => url.trim())
|
||||||
.filter(url => /^https?:\/\//i.test(url));
|
.filter(url => /^https?:\/\//i.test(url));
|
||||||
|
|
||||||
|
return urls.map((url, index) => ({
|
||||||
|
name: `Image ${index + 1}`,
|
||||||
|
url
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const clampIndex = (index, length) => {
|
const clampIndex = (index, length) => {
|
||||||
@ -33,18 +95,19 @@ const clampIndex = (index, length) => {
|
|||||||
return index;
|
return index;
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildSelectedImageEmbed = (url, index, total) => (
|
const buildSelectedImageEmbed = (item, index, total) => (
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.setColor('#f59e0b')
|
.setColor('#f59e0b')
|
||||||
.setTitle(`Image selectionnee (${index + 1}/${total})`)
|
.setTitle(item.name)
|
||||||
.setImage(toCacheBustedUrl(url))
|
.setDescription(`Image ${index + 1}/${total}`)
|
||||||
|
.setImage(toCacheBustedUrl(item.url))
|
||||||
);
|
);
|
||||||
|
|
||||||
const buildImageSelectorRow = (urls, selectedIndex) => {
|
const buildImageSelectorRow = (items, selectedIndex) => {
|
||||||
const options = urls.slice(0, 25).map((url, index) => ({
|
const options = items.slice(0, 25).map((item, index) => ({
|
||||||
label: `Image ${index + 1}`,
|
label: item.name.length > 100 ? `${item.name.slice(0, 97)}...` : item.name,
|
||||||
value: String(index),
|
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
|
default: index === selectedIndex
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -100,17 +163,17 @@ const buildPanelEmbed = (status) => {
|
|||||||
|
|
||||||
const buildPanelPayload = (status, messageId) => {
|
const buildPanelPayload = (status, messageId) => {
|
||||||
const panelEmbed = buildPanelEmbed(status);
|
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: [] };
|
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);
|
selectedImageIndexByMessage.set(messageId, currentIndex);
|
||||||
|
|
||||||
const selectedImageEmbed = buildSelectedImageEmbed(pinboardUrls[currentIndex], currentIndex, pinboardUrls.length);
|
const selectedImageEmbed = buildSelectedImageEmbed(pinboardItems[currentIndex], currentIndex, pinboardItems.length);
|
||||||
const selectorRow = buildImageSelectorRow(pinboardUrls, currentIndex);
|
const selectorRow = buildImageSelectorRow(pinboardItems, currentIndex);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: '',
|
content: '',
|
||||||
@ -173,15 +236,15 @@ const handlePinboardSelection = async (interaction) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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 });
|
await interaction.reply({ content: 'Aucune image configuree dans PINBOARD_IMAGE_URLS.', ephemeral: true });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedRaw = Number.parseInt(interaction.values?.[0] || '0', 10);
|
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);
|
selectedImageIndexByMessage.set(interaction.message.id, selectedIndex);
|
||||||
|
|
||||||
const status = await getMinecraftStatus();
|
const status = await getMinecraftStatus();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user