Drrrkari 翻訳ボット3(Enterキー対応、ドラッグ移動可能)

Google翻訳を利用してメッセージを翻訳し送信できる、Enterキー対応ボタン(位置変更可能、ON/OFF機能付き)

// ==UserScript==
// @name         Drrrkari 翻訳ボット3(Enterキー対応、ドラッグ移動可能)
// @namespace    http://tampermonkey.net/
// @version      1.3.0
// @description  Google翻訳を利用してメッセージを翻訳し送信できる、Enterキー対応ボタン(位置変更可能、ON/OFF機能付き)
// @author       AoiRabbit
// @match        *://drrrkari.com/room*
// @grant        none
// @require      https://unpkg.com/axios/dist/axios.min.js
// @icon         https://www.google.com/s2/favicons?domain=drrrkari.com
// ==/UserScript==

(function () {
    'use strict';

    // DOM 要素取得
    const input = document.querySelector("#message .inputarea textarea");
    const submit = document.querySelector("#message .submit input");

    // 翻訳ボタンの作成
    const translateButton = document.createElement("button");
    translateButton.innerText = "翻訳: OFF";
    translateButton.style.padding = "10px";
    translateButton.style.borderRadius = "5px";
    translateButton.style.backgroundColor = "#008000";
    translateButton.style.color = "white";
    translateButton.style.position = "fixed";
    translateButton.style.bottom = "20px";
    translateButton.style.right = "20px";
    translateButton.style.cursor = "grab";
    translateButton.style.zIndex = "1000"; // 最前面に表示

    // ドラッグ移動用変数
    let isDragging = false;
    let offsetX = 0;
    let offsetY = 0;

    // ボタンの状態管理用変数
    let isTranslationEnabled = false;

    // ボタンのドラッグイベントリスナー
    translateButton.addEventListener("mousedown", (e) => {
        isDragging = true;
        offsetX = e.clientX - translateButton.offsetLeft;
        offsetY = e.clientY - translateButton.offsetTop;
        translateButton.style.cursor = "grabbing";
    });

    document.addEventListener("mousemove", (e) => {
        if (isDragging) {
            translateButton.style.left = `${e.clientX - offsetX}px`;
            translateButton.style.top = `${e.clientY - offsetY}px`;
            translateButton.style.transform = ""; // 移動中は中央基準を無効化
        }
    });

    document.addEventListener("mouseup", () => {
        isDragging = false;
        translateButton.style.cursor = "grab";
    });

    // ボタンのクリックイベントでON/OFF切り替え
    translateButton.addEventListener("click", () => {
        isTranslationEnabled = !isTranslationEnabled;
        if (isTranslationEnabled) {
            translateButton.innerText = "翻訳: ON";
            translateButton.style.backgroundColor = "#007bff";
        } else {
            translateButton.innerText = "翻訳: OFF";
            translateButton.style.backgroundColor = "#008000";
        }
    });

    // 翻訳と送信を行う関数
    async function handleTranslationAndSend() {
        if (!isTranslationEnabled) {
            console.log("翻訳はOFF状態です");
            sendChatMessage(input.value);
            return;
        }
        const message = input.value;
        if (message) {
            const translatedMessage = await translateMessage(message);
            sendChatMessage(translatedMessage);
        }
    }

    // 翻訳ボタンの動作
    translateButton.onclick = handleTranslationAndSend;

    // ボタンをページに追加
    document.body.appendChild(translateButton);

    // Google翻訳APIを利用した翻訳関数
    async function translateMessage(text) {
        try {
            const response = await axios.get(`https://api.mymemory.translated.net/get`, {
                params: {
                    q: text,
                    langpair: "ja|en"
                }
            });
            const translatedText = response.data.responseData.translatedText;
            console.log(`Original: ${text}, Translated: ${translatedText}`);
            return translatedText;
        } catch (error) {
            console.error("翻訳エラー:", error);
            return "翻訳に失敗しました";
        }
    }

    // メッセージを送信する関数
    function sendChatMessage(text) {
        if (!text || !input || !submit) return;
        input.value = text;
        submit.click();
        console.log("Sent:", text);
    }

    // Enterキーを監視して翻訳して送信
    input.addEventListener("keydown", async (e) => {
        if (e.key === "Enter" && !e.shiftKey) {
            e.preventDefault(); // Enterキーによるデフォルト送信を防止
            await handleTranslationAndSend();
        }
    });
})();