Poste sur Onche.org a une heure precise
// ==UserScript==
// @name Horlonche
// @namespace http://tampermonkey.net/
// @version 9.0
// @description Poste sur Onche.org a une heure precise
// @author toi
// @match https://onche.org/topic/*
// @match https://onche.org/forum/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
var estForum = window.location.pathname.indexOf('/forum/') === 0;
var timer = null;
var modeChoisi = null;
// 'topic', 'citation', 'nouveau'
// =========================================================
// Panel
// =========================================================
var panel = document.createElement('div');
panel.style.cssText = 'position:fixed;bottom:20px;right:20px;background:#1e2a3a;border:1px solid #4a90d9;border-radius:8px;padding:14px;z-index:99999;width:270px;font-family:sans-serif;font-size:13px;color:#eee;box-shadow:0 4px 15px rgba(0,0,0,0.5)';
panel.innerHTML = ''
+ '<div style="font-weight:bold;margin-bottom:12px;font-size:14px;color:#4a90d9">Horlonche</div>'
// --- Etape 1 : choisir le mode ---
+ '<div id="os-etape1">'
+ '<div style="margin-bottom:8px;color:#aaa;font-size:12px">Que veux-tu faire ?</div>'
+ (estForum
? '<button class="os-mode-btn" data-mode="nouveau" style="width:100%;padding:7px;margin-bottom:6px;background:#2c3e50;color:#eee;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;text-align:left">📝 Créer un nouveau topic</button>'
: '<button class="os-mode-btn" data-mode="topic" style="width:100%;padding:7px;margin-bottom:6px;background:#2c3e50;color:#eee;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;text-align:left">💬 Répondre dans le topic</button>'
+ '<button class="os-mode-btn" data-mode="citation" style="width:100%;padding:7px;margin-bottom:6px;background:#2c3e50;color:#eee;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;text-align:left">↩ Citer / répondre à un message</button>'
)
+ '</div>'
// --- Etape 2 : formulaire ---
+ '<div id="os-etape2" style="display:none">'
+ '<div id="os-label-mode" style="margin-bottom:10px;padding:5px 8px;background:#0d1b2a;border-radius:4px;font-size:12px;color:#4a90d9"></div>'
+ '<div id="os-instruction-citation" style="display:none;margin-bottom:10px;padding:6px;background:#2c1a00;border:1px solid #f39c12;border-radius:4px;font-size:11px;color:#f39c12">'
+ '⚠ Clique sur la flèche du message AVANT de cliquer "Programmer"</div>'
+ '<div id="os-champ-titre" style="display:none">'
+ '<label style="display:block;margin-bottom:4px">Titre du topic</label>'
+ '<input id="os-titre" type="text" placeholder="Titre..." style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;margin-bottom:10px;box-sizing:border-box">'
+ '</div>'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">' + '<label>Heure (HH:MM:SS)</label>' + '<label style="font-size:11px;color:#aaa;cursor:pointer;display:flex;align-items:center;gap:4px">' + '<input id="os-chk-jour" type="checkbox" style="cursor:pointer"> Choisir un jour' + '</label>' + '</div>' + '<input id="os-heure" type="time" step="1" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;margin-bottom:6px;box-sizing:border-box">' + '<div id="os-champ-jour" style="display:none;margin-bottom:10px">' + '<input id="os-jour" type="date" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;box-sizing:border-box">' + '</div>'
+ '<label style="display:block;margin-bottom:4px">Message</label>'
+ '<textarea id="os-message" rows="3" style="width:100%;padding:5px;background:#0d1b2a;color:#eee;border:1px solid #4a90d9;border-radius:4px;margin-bottom:6px;box-sizing:border-box;resize:vertical"></textarea>'
+ '<button id="os-btn-preview" style="width:100%;padding:5px;background:#2c3e50;color:#aaa;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;font-size:12px;margin-bottom:10px">👁 Prévisualiser</button>'
+ '<button id="os-btn-start" style="width:100%;padding:7px;background:#4a90d9;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;margin-bottom:6px">Programmer</button>'
+ '<button id="os-btn-back" style="width:100%;padding:5px;background:#2c3e50;color:#aaa;border:1px solid #4a90d9;border-radius:4px;cursor:pointer;font-size:12px">← Retour</button>'
+ '</div>'
// --- Etape 3 : compte a rebours ---
+ '<div id="os-etape3" style="display:none">'
+ '<div id="os-label-attente" style="margin-bottom:10px;padding:5px 8px;background:#0d1b2a;border-radius:4px;font-size:12px;color:#4a90d9"></div>'
+ '<div id="os-status" style="font-size:22px;font-weight:bold;text-align:center;color:#4a90d9;margin:10px 0"></div>'
+ '<div id="os-status-sub" style="font-size:11px;text-align:center;color:#aaa;margin-bottom:10px"></div>'
+ '<button id="os-btn-stop" style="width:100%;padding:7px;background:#c0392b;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px">Annuler</button>'
+ '</div>';
document.body.appendChild(panel);
// =========================================================
// Navigation entre etapes
// =========================================================
// Etape 1 -> 2 : choix du mode
var modeBtns = panel.querySelectorAll('.os-mode-btn');
for (var i = 0; i < modeBtns.length; i++) {
modeBtns[i].addEventListener('click', function () {
modeChoisi = this.getAttribute('data-mode');
afficherEtape2(modeChoisi);
});
}
function afficherEtape2(mode) {
document.getElementById('os-etape1').style.display = 'none';
document.getElementById('os-etape2').style.display = 'block';
var labels = { 'topic': 'Répondre dans le topic', 'citation': 'Citer un message', 'nouveau': 'Nouveau topic' };
document.getElementById('os-label-mode').textContent = '→ ' + labels[mode];
document.getElementById('os-instruction-citation').style.display = (mode === 'citation') ? 'block' : 'none';
document.getElementById('os-champ-titre').style.display = (mode === 'nouveau') ? 'block' : 'none';
}
// Retour etape 2 -> 1
document.getElementById('os-btn-back').addEventListener('click', function () {
document.getElementById('os-etape2').style.display = 'none';
document.getElementById('os-etape1').style.display = 'block';
modeChoisi = null;
});
// Case a cocher jour
document.getElementById('os-chk-jour').addEventListener('change', function () {
var champJour = document.getElementById('os-champ-jour');
if (this.checked) {
champJour.style.display = 'block';
// Prefill avec aujourd'hui
var auj = new Date();
var yyyy = auj.getFullYear();
var mm = pad(auj.getMonth() + 1);
var dd = pad(auj.getDate());
document.getElementById('os-jour').value = yyyy + '-' + mm + '-' + dd;
} else {
champJour.style.display = 'none';
document.getElementById('os-jour').value = '';
}
});
// Etape 2 -> 3 : programmer
document.getElementById('os-btn-start').addEventListener('click', function () {
var heureVal = document.getElementById('os-heure').value;
var messageVal = document.getElementById('os-message').value.trim();
var titreEl = document.getElementById('os-titre');
var titreVal = titreEl ? titreEl.value.trim() : null;
if (!heureVal) { alert('Choisis une heure !'); return; }
if (!messageVal) { alert('Ecris un message !'); return; }
if (modeChoisi === 'nouveau' && !titreVal) { alert('Ecris un titre !'); return; }
var parts = heureVal.split(':');
var cible = new Date();
var jourVal = document.getElementById('os-jour').value;
if (jourVal) {
// Jour specifique choisi
var jourParts = jourVal.split('-');
cible.setFullYear(parseInt(jourParts[0]), parseInt(jourParts[1]) - 1, parseInt(jourParts[2]));
}
cible.setHours(parseInt(parts[0]), parseInt(parts[1]), parseInt(parts[2] || 0), 0);
if (!jourVal && cible.getTime() <= Date.now()) {
cible.setDate(cible.getDate() + 1);
}
document.getElementById('os-etape2').style.display = 'none';
document.getElementById('os-etape3').style.display = 'block';
var labels = { 'topic': 'Répondre dans le topic', 'citation': 'Citer un message', 'nouveau': 'Nouveau topic' };
var jourVal2 = document.getElementById('os-jour').value;
var labelJour = jourVal2 ? ' le ' + jourVal2.split('-').reverse().join('/') + ' à ' : ' à ';
document.getElementById('os-label-attente').textContent = labels[modeChoisi] + labelJour + heureVal;
lancerTimer(cible.getTime(), messageVal, titreVal, modeChoisi);
});
// Annuler
document.getElementById('os-btn-stop').addEventListener('click', function () {
if (timer) clearInterval(timer);
timer = null;
document.getElementById('os-etape3').style.display = 'none';
document.getElementById('os-etape1').style.display = 'block';
modeChoisi = null;
});
// =========================================================
// Timer
// =========================================================
function lancerTimer(tsEcheance, message, titre, mode) {
timer = setInterval(function () {
var resteMs = tsEcheance - Date.now();
if (resteMs <= 0) {
clearInterval(timer);
timer = null;
document.getElementById('os-status').textContent = 'Envoi...';
document.getElementById('os-status-sub').textContent = '';
if (mode === 'citation') {
posterCitation(message);
} else if (mode === 'nouveau') {
posterNouveauTopic(titre, message);
} else {
posterReponse(message);
}
return;
}
var resteS = Math.floor(resteMs / 1000);
var h = Math.floor(resteS / 3600);
var m = Math.floor((resteS % 3600) / 60);
var s = resteS % 60;
document.getElementById('os-status').textContent = pad(h) + ':' + pad(m) + ':' + pad(s);
}, 50);
}
// =========================================================
// Poster une reponse normale dans le topic
// =========================================================
function posterReponse(message) {
var textarea = document.querySelector("[placeholder*='Repondre au message']")
|| document.querySelector("[placeholder*='Parle de ce que']")
|| document.querySelector("textarea");
if (!textarea) { terminer('Zone de texte introuvable !', false); return; }
textarea.focus();
textarea.value = message;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.dispatchEvent(new Event('change', { bubbles: true }));
var bouton = trouverBoutonEnvoyer();
if (!bouton) { terminer('Bouton Envoyer introuvable !', false); return; }
bouton.click();
terminer('Poste !', true);
}
// =========================================================
// Poster dans la popup de citation (deja ouverte par l'user)
// =========================================================
function posterCitation(message) {
// La popup est deja ouverte, on cherche le textarea visible dedans
var textareas = document.querySelectorAll('textarea');
var textarea = null;
var principal = document.querySelector("[placeholder*='Repondre au message']")
|| document.querySelector("[placeholder*='Parle de ce que']");
for (var i = 0; i < textareas.length; i++) {
if (textareas[i] !== principal && textareas[i].offsetParent !== null) {
textarea = textareas[i];
break;
}
}
if (!textarea) {
// Fallback : la popup n'est peut-etre plus ouverte, on poste en reponse normale
posterReponse(message);
return;
}
textarea.focus();
textarea.value = message;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.dispatchEvent(new Event('change', { bubbles: true }));
// Cherche le bouton dans le meme formulaire
var form = textarea.closest('form');
var bouton = form ? form.querySelector("button[type='submit']") || form.querySelector('button') : null;
if (!bouton) bouton = trouverBoutonEnvoyer();
if (!bouton) { terminer('Bouton introuvable dans la popup !', false); return; }
bouton.click();
terminer('Citation postee !', true);
}
// =========================================================
// Creer un nouveau topic (page forum)
// =========================================================
function posterNouveauTopic(titre, message) {
var champTitre = document.querySelector("[placeholder*='envie de parler']")
|| document.querySelector("[placeholder*='titre' i]")
|| document.querySelector("[placeholder*='title' i]");
var champMessage = document.querySelector("[placeholder*='Parle de ce que']")
|| document.querySelector("textarea");
if (!champTitre || !champMessage) { terminer('Champs introuvables !', false); return; }
champTitre.focus();
champTitre.value = titre;
champTitre.dispatchEvent(new Event('input', { bubbles: true }));
champTitre.dispatchEvent(new Event('change', { bubbles: true }));
champMessage.focus();
champMessage.value = message;
champMessage.dispatchEvent(new Event('input', { bubbles: true }));
champMessage.dispatchEvent(new Event('change', { bubbles: true }));
var bouton = trouverBoutonEnvoyer();
if (!bouton) { terminer('Bouton Envoyer introuvable !', false); return; }
bouton.click();
terminer('Topic cree !', true);
}
// =========================================================
// Utilitaires
// =========================================================
function trouverBoutonEnvoyer() {
return document.querySelector("button[type='submit']")
|| trouverBoutonParTexte('Envoyer')
|| trouverBoutonParTexte('Poster')
|| trouverBoutonParTexte('Publier')
|| document.querySelector('form button');
}
function trouverBoutonParTexte(texte) {
var elements = document.querySelectorAll('button');
for (var i = 0; i < elements.length; i++) {
if (elements[i].textContent.trim().toLowerCase().indexOf(texte.toLowerCase()) !== -1) {
return elements[i];
}
}
return null;
}
function terminer(msg, succes) {
document.getElementById('os-status').textContent = msg;
document.getElementById('os-status').style.color = succes ? '#2ecc71' : '#e74c3c';
setTimeout(function () {
document.getElementById('os-etape3').style.display = 'none';
document.getElementById('os-etape1').style.display = 'block';
modeChoisi = null;
}, 3000);
}
function pad(n) { return n < 10 ? '0' + n : '' + n; }
// =========================================================
// Horloge dans le titre de l'onglet
// =========================================================
function mettreAJourTitre() {
var maintenant = new Date();
var h = pad(maintenant.getHours());
var m = pad(maintenant.getMinutes());
var s = pad(maintenant.getSeconds());
document.title = h + ':' + m + ':' + s + ' | Horlonche';
}
mettreAJourTitre();
setInterval(mettreAJourTitre, 1000);
// =========================================================
// Fenetre de preview
// =========================================================
var previewBox = document.createElement('div');
previewBox.style.cssText = 'display:none;position:fixed;bottom:20px;right:310px;background:#1e2a3a;border:1px solid #4a90d9;border-radius:8px;padding:14px;z-index:99998;width:340px;max-height:300px;font-family:sans-serif;font-size:14px;color:#eee;box-shadow:0 4px 15px rgba(0,0,0,0.5);overflow-y:auto;word-break:break-word;white-space:pre-wrap;line-height:1.6';
document.body.appendChild(previewBox);
var previewOuvert = false;
document.getElementById('os-btn-preview').addEventListener('click', function () {
var msg = document.getElementById('os-message').value;
if (!previewOuvert) {
previewBox.textContent = msg || '(message vide)';
previewBox.style.display = 'block';
this.textContent = '✕ Fermer la prévisualisation';
this.style.color = '#4a90d9';
previewOuvert = true;
// Mise a jour en temps reel quand on tape
document.getElementById('os-message').addEventListener('input', mettreAJourPreview);
} else {
previewBox.style.display = 'none';
this.textContent = '👁 Prévisualiser';
this.style.color = '#aaa';
previewOuvert = false;
document.getElementById('os-message').removeEventListener('input', mettreAJourPreview);
}
});
function mettreAJourPreview() {
var msg = document.getElementById('os-message').value;
previewBox.textContent = msg || '(message vide)';
}
})();