// ==UserScript==
// @name Drawaria Copy Room Friend List
// @namespace http://tampermonkey.net/
// @version 1.3
// @description Add an option to copy the public room link to the context menu of the friends list in Drawaria.online.
// @author YouTubeDrawaria
// @match https://drawaria.online/*
// @grant none
// @license MIT
// @icon https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// ==/UserScript==
(function() {
'use strict';
if (typeof jQuery === 'undefined') {
console.error("jQuery no está disponible. El script no se ejecutará.");
return;
}
// Función para manejar la copia del enlace de la sala
async function copyRoomLink(playerUid, $button) {
// Guarda el contenido original del botón/enlace para restaurarlo después
const originalContent = $button.html();
// Muestra un indicador de carga/trabajo y deshabilita el botón temporalmente
$button.html('<i class="fas fa-spinner fa-spin"></i>').addClass('disabled');
try {
// Replicar la llamada a la API que friends.js hace para obtener la sala
const response = await new Promise((resolve, reject) => {
jQuery.post("/friendsapi/getfriendroom", { uid: playerUid }, function(data) {
if (data && !data.error) {
resolve(data.res); // Si es pública, devuelve el ID de la sala
} else {
// Si hay un error, rechaza con el mensaje de error o un error genérico
reject(data ? data.error : "Unknown error");
}
}, "json").fail(function(jqXHR, textStatus, errorThrown) {
// Manejo de errores de red o del servidor
reject(textStatus || errorThrown);
});
});
// Si la respuesta es un ID de sala válido (no '1', que indica sala privada)
if (response && response !== 1) { // '1' es el código para "habitación privada" según friends.js
const roomLink = `https://drawaria.online/room/${response}`;
await navigator.clipboard.writeText(roomLink);
// Feedback visual de éxito
$button.html('<i class="fas fa-check"></i>').removeClass('disabled');
console.log(`Enlace de sala copiado: ${roomLink}`);
} else if (response === 1) {
// Caso específico para sala privada
$button.html('<i class="fas fa-times"></i>').removeClass('disabled'); // Icono de error
console.log("Este jugador está en una sala privada. No se puede copiar el enlace.");
} else {
// Otros casos de error (jugador no encontrado, etc.)
$button.html('<i class="fas fa-times"></i>').removeClass('disabled'); // Icono de error
console.log("No se pudo obtener el enlace de la sala. El jugador podría estar desconectado o en un estado no unible.");
}
} catch (error) {
console.error("Error al copiar el enlace de la sala:", error);
$button.html('<i class="fas fa-times"></i>').removeClass('disabled'); // Icono de error
} finally {
// Restaura el contenido original del botón después de un breve retraso
setTimeout(() => {
$button.html(originalContent).removeClass('disabled');
}, 2000);
}
}
// Cuando el DOM esté completamente cargado
jQuery(function() {
const $friendMenu = jQuery("#tabfriendlist-rowmenu");
if ($friendMenu.length) {
// Crea el nuevo elemento del menú para "Copiar Enlace de Sala"
const $copyRoomItem = jQuery(
`<a class="dropdown-item" href="#" id="tabfriendlist-rowmenu-copyroom">Copiar Enlace de Sala <i class="fas fa-copy" style="margin-left: 5px;"></i></a>`
);
// Inserta el nuevo elemento justo después de "Join room" y añade un nuevo divisor
$friendMenu.find("#tabfriendlist-rowmenu-joinroom").after(
$copyRoomItem,
`<div class="dropdown-divider" id="divider-copyroom-link"></div>` // Nuevo divisor
);
// Adjunta el event listener al nuevo elemento del menú
$copyRoomItem.on("click", function(event) {
event.preventDefault(); // Previene el comportamiento predeterminado del enlace
event.stopPropagation(); // Detiene la propagación para evitar que el menú se cierre inmediatamente
const $targetRow = $friendMenu.data("target"); // Este es el elemento .tabrow del amigo
if ($targetRow && !$copyRoomItem.hasClass('disabled')) { // Solo procede si el botón no está deshabilitado
const playerUid = $targetRow.data("playeruid");
copyRoomLink(playerUid, $copyRoomItem);
}
});
// Escucha cuándo se muestra el menú desplegable para habilitar/deshabilitar la opción
$friendMenu.on("show.bs.dropdown", function() {
const $joinRoomItem = $friendMenu.find("#tabfriendlist-rowmenu-joinroom");
const $targetRow = $friendMenu.data("target"); // El elemento .tabrow del amigo
if ($targetRow && $targetRow.hasClass('inroom')) {
// Si el amigo está en una sala, verifica si la opción "Join room" está activa (no disabled)
if (!$joinRoomItem.hasClass('disabled')) { // Si "Join room" NO está deshabilitado, es una sala pública
$copyRoomItem.removeClass("disabled").css("cursor", "pointer");
$copyRoomItem.show(); // Asegura que el botón sea visible
$friendMenu.find("#divider-copyroom-link").show();
} else { // Está en sala, pero "Join room" está deshabilitado, lo que implica sala privada
$copyRoomItem.addClass("disabled").css("cursor", "not-allowed");
$copyRoomItem.show(); // Mostrarlo pero deshabilitado
$friendMenu.find("#divider-copyroom-link").show();
}
} else {
// Si el amigo no está en una sala, deshabilita y oculta la opción
$copyRoomItem.addClass("disabled").css("cursor", "not-allowed");
$copyRoomItem.hide(); // Oculta el botón si no está en una sala
$friendMenu.find("#divider-copyroom-link").hide();
}
});
// Restablece el estado del botón cuando el menú se oculta
$friendMenu.on('hidden.bs.dropdown', function () {
$copyRoomItem.html('Copy Room Link <i class="fas fa-copy" style="margin-left: 5px;"></i>');
$copyRoomItem.removeClass('disabled');
});
} else {
console.warn("No se encontró el elemento #tabfriendlist-rowmenu. El script no funcionará como se espera.");
}
});
// --- Esperar a que jQuery esté disponible ---
function waitForjQuery(callback) {
if (typeof window.jQuery !== 'undefined') {
callback(window.jQuery);
} else {
setTimeout(() => waitForjQuery(callback), 50);
}
}
waitForjQuery(function($) { // jQuery ($) está garantizado aquí.
// Función para obtener el UID de la URL de la página de perfil actual
function getProfileUidFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get('uid');
}
// Función para manejar la copia del enlace de la sala
async function copyRoomLink(playerUid, $button) {
if (!playerUid) {
console.error("No se proporcionó el UID del jugador para copiar el enlace de la sala.");
return;
}
// Guarda el contenido original del botón para restaurarlo después
const originalContent = $button.html();
// Muestra un indicador de carga/trabajo y deshabilita el botón temporalmente
$button.html('<i class="fas fa-spinner fa-spin"></i>').prop('disabled', true); // .prop('disabled', true) para botones HTML
try {
const response = await new Promise((resolve, reject) => {
$.post("/friendsapi/getfriendroom", { uid: playerUid }, function(data) {
if (data && !data.error) {
resolve(data.res);
} else {
reject(data ? data.error : "Unknown error");
}
}, "json").fail(function(jqXHR, textStatus, errorThrown) {
reject(textStatus || errorThrown);
});
});
if (response && response !== 1) { // '1' es el código para "habitación privada"
const roomLink = `https://drawaria.online/room/${response}`;
await navigator.clipboard.writeText(roomLink);
$button.html('<i class="fas fa-check"></i>'); // Icono de éxito
console.log(`Enlace de sala copiado: ${roomLink}`);
} else if (response === 1) {
$button.html('<i class="fas fa-times"></i>'); // Icono de error
console.log("Este jugador está en una sala privada. No se puede copiar el enlace.");
} else {
$button.html('<i class="fas fa-times"></i>'); // Icono de error
console.log("No se pudo obtener el enlace de la sala. El jugador podría estar desconectado o en un estado no unible.");
}
} catch (error) {
console.error("Error al copiar el enlace de la sala:", error);
$button.html('<i class="fas fa-times"></i>'); // Icono de error
} finally {
// Restaura el contenido original del botón y habilita después de un breve retraso
setTimeout(() => {
$button.html(originalContent).prop('disabled', false);
}, 2000);
}
}
// Función para inicializar el botón flotante en páginas de perfil
function initFloatingCopyButton() {
// Solo agregar el botón si estamos en una URL de perfil
if (!window.location.pathname.startsWith('/profile/')) {
return;
}
const profileUid = getProfileUidFromUrl();
if (!profileUid) {
console.warn("No se pudo obtener el UID del perfil de la URL. El botón flotante no se agregará.");
return;
}
// Evitar duplicados si el script se recarga por alguna razón
if ($("#floating-copy-room-button").length > 0) {
return;
}
const $floatingButton = $(`
<button id="floating-copy-room-button" style="
position: fixed;
bottom: 20px;
right: 20px;
background-color: #007bff; /* Color azul de Bootstrap primary */
color: white;
border: none;
border-radius: 50%;
width: 50px;
height: 50px;
font-size: 24px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
z-index: 1000;
opacity: 0.9;
transition: opacity 0.3s ease;
" title="Copiar Enlace de Sala del Perfil">
<i class="fas fa-copy"></i>
</button>
`);
$('body').append($floatingButton);
$floatingButton.on('click', function() {
copyRoomLink(profileUid, $floatingButton);
});
// Pequeño efecto hover
$floatingButton.hover(
function() { $(this).css('opacity', '1'); },
function() { $(this).css('opacity', '0.9'); }
);
}
// Cuando el DOM esté completamente cargado
$(function() {
// Llamamos a esta función sin importar la URL, ella misma se encargará de la comprobación
initFloatingCopyButton();
});
});
})();