MediaWiki:Common.js: Difference between revisions

From Tuyin Archives
No edit summary
No edit summary
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */
// Audio Player System
// Audio Player System
$(document).ready(function() {
// Audio Player System
     // Initialize all audio players on page load
/* Any JavaScript here will be loaded for all users on every page load. */
     $('.audioplayer').each(function() {
// Audio Player System
         var container = $(this);
// Mobile audio unlocker
         var filename = container.data('filename');
/* Any JavaScript here will be loaded for all users on every page load. */
         var caption = container.data('caption') || 'Audio File';
// Audio Player System
 
// Mobile audio unlocker (optional but harmless)
document.addEventListener('DOMContentLoaded', function () {
     var isMobile = /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent);
    if (isMobile) {
        var unlockAudio = document.createElement('audio');
        unlockAudio.src = "data:audio/ogg;base64,T2dnUwACAAAAAAAAAABVDxXAAAAAAACf5tYBHgF2b3JiaXMAAAAAAkSsAAAAAAD+/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
        unlockAudio.muted = true;
        unlockAudio.playsInline = true;
        unlockAudio.autoplay = true;
        unlockAudio.preload = "auto";
        document.body.appendChild(unlockAudio);
        unlockAudio.play().catch(() => {});
    }
});
 
mw.hook('wikipage.content').add(function($content) {
     $content.find('.audioplayer').each(function() {
         var $container = $(this);
         var filename = $container.attr('data-filename');
         var caption = $container.attr('data-caption') || 'Audio File';
          
          
         if (!filename) return;
         if (!filename) return;
       
        // Create unique ID for this player
        var playerId = 'player_' + Math.random().toString(36).substr(2, 9);
       
        // Build the player HTML
        var playerHTML =
            '<div style="display: inline-flex; align-items: center; gap: 12px;">' +
                '<div style="border: 1px solid #8B7355; padding: 8px; border-radius: 4px; background-color: #F5F0E8; width: 200px;">' +
                    '<button id="' + playerId + '_btn" onclick="window.toggleAudioPlayer(\'' + playerId + '\', \'' + filename + '\')" style="padding: 4px 8px; margin-right: 8px; font-size: 12px; border: 1px solid #8B7355; background: #D4C4A8; color: #5D4E37;">▶️</button>' +
                    '<div style="display: inline-block; width: 120px; height: 6px; background-color: #D4C4A8; border-radius: 3px; vertical-align: middle;">' +
                        '<div id="' + playerId + '_progress" style="height: 100%; background-color: #8B7355; border-radius: 3px; width: 0%; transition: width 0.1s;"></div>' +
                    '</div>' +
                '</div>' +
                '<span style="color: #8B7355; font-style: italic;">' + caption + '</span>' +
            '</div>';
       
        container.html(playerHTML);
    });
});


// Global function to handle audio playback
        var baseName = filename.replace(/\.\w+$/, ''); // remove extension if present
window.toggleAudioPlayer = function(playerId, filename) {
 
    var button = document.getElementById(playerId + '_btn');
        // Generate unique ID
    var progress = document.getElementById(playerId + '_progress');
        var playerId = 'audio_' + Math.random().toString(36).substr(2, 9);
   
 
    // Create or get existing audio element
        // Create player HTML
    if (!button.audioElement) {
        var $player = $('<div>').css({
        button.audioElement = new Audio('https://tuyin.online/images/' + filename);
            'display': 'inline-flex',
          
            'align-items': 'center',
         // Set up progress tracking
            'gap': '12px'
         button.audioElement.addEventListener('timeupdate', function() {
        });
             if (this.duration) {
 
                 var percentage = (this.currentTime / this.duration) * 100;
        var $playerBox = $('<div>').css({
                 progress.style.width = percentage + '%';
            'border': '1px solid #8B7355',
            'padding': '8px',
            'border-radius': '4px',
            'background-color': '#F5F0E8',
            'width': '200px'
        });
 
        var $button = $('<button>').attr('id', playerId + '_btn').text('▶️').css({
            'padding': '4px 8px',
            'margin-right': '8px',
            'font-size': '12px',
            'border': '1px solid #8B7355',
            'background': '#D4C4A8',
            'color': '#5D4E37'
        });
 
        var $progressContainer = $('<div>').css({
            'display': 'inline-block',
            'width': '120px',
            'height': '6px',
            'background-color': '#D4C4A8',
            'border-radius': '3px',
            'vertical-align': 'middle'
        });
 
        var $progress = $('<div>').attr('id', playerId + '_progress').css({
            'height': '100%',
            'background-color': '#8B7355',
            'border-radius': '3px',
            'width': '0%',
            'transition': 'width 0.1s'
        });
 
        var $caption = $('<span>').text(caption).css({
            'color': '#8B7355',
            'font-style': 'italic'
        });
 
        // Build structure
        $progressContainer.append($progress);
        $playerBox.append($button).append($progressContainer);
        $player.append($playerBox).append($caption);
 
        // Replace container content
        $container.empty().append($player);
 
        // Create real DOM <audio> element with both sources
        var $realAudio = $('<audio preload="metadata" playsinline style="display:none;">')
            .append($('<source>').attr('src', 'https://tuyin.online/images/' + baseName + '.ogg').attr('type', 'audio/ogg'))
            .append($('<source>').attr('src', 'https://tuyin.online/images/' + baseName + '.mp3').attr('type', 'audio/mpeg'));
        $container.append($realAudio);
 
         var audio = $realAudio[0];
         var isPlaying = false;
 
         $button.click(function() {
            if (isPlaying) {
                audio.pause();
                $button.text('▶️');
                isPlaying = false;
            } else {
                audio.play().then(function() {
                    $button.text('⏸️');
                    isPlaying = true;
                }).catch(function(error) {
                    alert('Could not play audio: ' + error.message);
                });
            }
        });
 
        audio.addEventListener('timeupdate', function() {
             if (audio.duration) {
                 var percentage = (audio.currentTime / audio.duration) * 100;
                 $progress.css('width', percentage + '%');
             }
             }
         });
         });
       
 
         // Handle when audio ends
         audio.addEventListener('ended', function() {
        button.audioElement.addEventListener('ended', function() {
             $button.text('▶️');
             button.innerHTML = '▶️';
             $progress.css('width', '0%');
             progress.style.width = '0%';
            isPlaying = false;
         });
         });
     }
     });
      
});
     var audio = button.audioElement;
 
      
//Translator Tool
     if (audio.paused) {
mw.hook('wikipage.content').add(function ($content) {
         audio.play().then(function() {
     if (mw.config.get('wgPageName') !== 'Translator') return;
            button.innerHTML = '⏸️';
 
         }).catch(function(error) {
     const languages = ['dwarven', 'orcian', 'ratik', 'elvic', 'snekian', 'trogian'];
            alert('Could not play audio: ' + error.message);
    const dictionaries = {};
    let loaded = 0;
 
    // UI setup
    const container = $('<div>').css({
        padding: '1em',
        background: '#f5f0e8',
        border: '1px solid #ccc'
    });
 
     const dropdown = $('<select>').css({
        marginBottom: '1em',
        padding: '0.4em',
        display: 'block'
     });
 
    dropdown.append($('<option>').val('').text('Select a language'));
 
    languages.forEach(lang => {
         dropdown.append($('<option>').val(lang).text(lang.charAt(0).toUpperCase() + lang.slice(1)));
    });
 
    const input = $('<textarea>')
        .attr('placeholder', 'Enter English text...')
        .css({ width: '100%', height: '80px', marginBottom: '1em' });
 
    const output = $('<div>').attr('id', 'translator-output');
 
    container.append(dropdown).append(input).append(output);
    $content.prepend(container);
 
    // Load dictionaries
    languages.forEach(lang => {
         $.get(`/wiki/index.php?title=${lang.charAt(0).toUpperCase() + lang.slice(1)}&action=render`, html => {
            const dict = {};
            $(html).find('table.wikitable tr').each(function () {
                const cells = $(this).find('td');
                if (cells.length >= 2) {
                    const english = $(cells[0]).text().trim().toLowerCase();
                    const translated = $(cells[1]).text().trim();
                    if (english && translated) {
                        dict[english] = translated;
                    }
                }
            });
            dictionaries[lang] = dict;
            loaded++;
         });
         });
     } else {
     });
         audio.pause();
 
         button.innerHTML = '▶️';
    function updateOutput() {
         const lang = dropdown.val();
        const text = input.val().trim().toLowerCase();
 
         if (!lang || !text || !dictionaries[lang]) {
            output.empty();
            return;
        }
 
        const dict = dictionaries[lang];
        const words = text.split(/\s+/);
        const normal = words.map(w => dict[w] || w).join(' ');
        const script = words.map(w => (dict[w] || w).toUpperCase()).join(' ');
 
        const block = $('<div>').css({ marginTop: '1em' });
        block.append(
            $('<div>').css({ fontWeight: 'bold', marginBottom: '0.3em' })
                .text(lang.charAt(0).toUpperCase() + lang.slice(1) + ':')
        );
        block.append($('<div>').text(normal));
        block.append(
            $('<div>').addClass(lang).css({
                fontSize: '160%',
                marginTop: '0.5em'
            }).text(script)
        );
 
        output.html(block);
     }
     }
};
 
    input.on('input', updateOutput);
    dropdown.on('change', updateOutput);
});

Latest revision as of 13:20, 7 August 2025

/* Any JavaScript here will be loaded for all users on every page load. */
// Audio Player System
// Audio Player System
/* Any JavaScript here will be loaded for all users on every page load. */
// Audio Player System
// Mobile audio unlocker
/* Any JavaScript here will be loaded for all users on every page load. */
// Audio Player System

// Mobile audio unlocker (optional but harmless)
document.addEventListener('DOMContentLoaded', function () {
    var isMobile = /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent);
    if (isMobile) {
        var unlockAudio = document.createElement('audio');
        unlockAudio.src = "data:audio/ogg;base64,T2dnUwACAAAAAAAAAABVDxXAAAAAAACf5tYBHgF2b3JiaXMAAAAAAkSsAAAAAAD+/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
        unlockAudio.muted = true;
        unlockAudio.playsInline = true;
        unlockAudio.autoplay = true;
        unlockAudio.preload = "auto";
        document.body.appendChild(unlockAudio);
        unlockAudio.play().catch(() => {});
    }
});

mw.hook('wikipage.content').add(function($content) {
    $content.find('.audioplayer').each(function() {
        var $container = $(this);
        var filename = $container.attr('data-filename');
        var caption = $container.attr('data-caption') || 'Audio File';
        
        if (!filename) return;

        var baseName = filename.replace(/\.\w+$/, ''); // remove extension if present

        // Generate unique ID
        var playerId = 'audio_' + Math.random().toString(36).substr(2, 9);

        // Create player HTML
        var $player = $('<div>').css({
            'display': 'inline-flex',
            'align-items': 'center',
            'gap': '12px'
        });

        var $playerBox = $('<div>').css({
            'border': '1px solid #8B7355',
            'padding': '8px',
            'border-radius': '4px',
            'background-color': '#F5F0E8',
            'width': '200px'
        });

        var $button = $('<button>').attr('id', playerId + '_btn').text('▶️').css({
            'padding': '4px 8px',
            'margin-right': '8px',
            'font-size': '12px',
            'border': '1px solid #8B7355',
            'background': '#D4C4A8',
            'color': '#5D4E37'
        });

        var $progressContainer = $('<div>').css({
            'display': 'inline-block',
            'width': '120px',
            'height': '6px',
            'background-color': '#D4C4A8',
            'border-radius': '3px',
            'vertical-align': 'middle'
        });

        var $progress = $('<div>').attr('id', playerId + '_progress').css({
            'height': '100%',
            'background-color': '#8B7355',
            'border-radius': '3px',
            'width': '0%',
            'transition': 'width 0.1s'
        });

        var $caption = $('<span>').text(caption).css({
            'color': '#8B7355',
            'font-style': 'italic'
        });

        // Build structure
        $progressContainer.append($progress);
        $playerBox.append($button).append($progressContainer);
        $player.append($playerBox).append($caption);

        // Replace container content
        $container.empty().append($player);

        // Create real DOM <audio> element with both sources
        var $realAudio = $('<audio preload="metadata" playsinline style="display:none;">')
            .append($('<source>').attr('src', 'https://tuyin.online/images/' + baseName + '.ogg').attr('type', 'audio/ogg'))
            .append($('<source>').attr('src', 'https://tuyin.online/images/' + baseName + '.mp3').attr('type', 'audio/mpeg'));
        $container.append($realAudio);

        var audio = $realAudio[0];
        var isPlaying = false;

        $button.click(function() {
            if (isPlaying) {
                audio.pause();
                $button.text('▶️');
                isPlaying = false;
            } else {
                audio.play().then(function() {
                    $button.text('⏸️');
                    isPlaying = true;
                }).catch(function(error) {
                    alert('Could not play audio: ' + error.message);
                });
            }
        });

        audio.addEventListener('timeupdate', function() {
            if (audio.duration) {
                var percentage = (audio.currentTime / audio.duration) * 100;
                $progress.css('width', percentage + '%');
            }
        });

        audio.addEventListener('ended', function() {
            $button.text('▶️');
            $progress.css('width', '0%');
            isPlaying = false;
        });
    });
});

//Translator Tool
mw.hook('wikipage.content').add(function ($content) {
    if (mw.config.get('wgPageName') !== 'Translator') return;

    const languages = ['dwarven', 'orcian', 'ratik', 'elvic', 'snekian', 'trogian'];
    const dictionaries = {};
    let loaded = 0;

    // UI setup
    const container = $('<div>').css({
        padding: '1em',
        background: '#f5f0e8',
        border: '1px solid #ccc'
    });

    const dropdown = $('<select>').css({
        marginBottom: '1em',
        padding: '0.4em',
        display: 'block'
    });

    dropdown.append($('<option>').val('').text('Select a language'));

    languages.forEach(lang => {
        dropdown.append($('<option>').val(lang).text(lang.charAt(0).toUpperCase() + lang.slice(1)));
    });

    const input = $('<textarea>')
        .attr('placeholder', 'Enter English text...')
        .css({ width: '100%', height: '80px', marginBottom: '1em' });

    const output = $('<div>').attr('id', 'translator-output');

    container.append(dropdown).append(input).append(output);
    $content.prepend(container);

    // Load dictionaries
    languages.forEach(lang => {
        $.get(`/wiki/index.php?title=${lang.charAt(0).toUpperCase() + lang.slice(1)}&action=render`, html => {
            const dict = {};
            $(html).find('table.wikitable tr').each(function () {
                const cells = $(this).find('td');
                if (cells.length >= 2) {
                    const english = $(cells[0]).text().trim().toLowerCase();
                    const translated = $(cells[1]).text().trim();
                    if (english && translated) {
                        dict[english] = translated;
                    }
                }
            });
            dictionaries[lang] = dict;
            loaded++;
        });
    });

    function updateOutput() {
        const lang = dropdown.val();
        const text = input.val().trim().toLowerCase();

        if (!lang || !text || !dictionaries[lang]) {
            output.empty();
            return;
        }

        const dict = dictionaries[lang];
        const words = text.split(/\s+/);
        const normal = words.map(w => dict[w] || w).join(' ');
        const script = words.map(w => (dict[w] || w).toUpperCase()).join(' ');

        const block = $('<div>').css({ marginTop: '1em' });
        block.append(
            $('<div>').css({ fontWeight: 'bold', marginBottom: '0.3em' })
                .text(lang.charAt(0).toUpperCase() + lang.slice(1) + ':')
        );
        block.append($('<div>').text(normal));
        block.append(
            $('<div>').addClass(lang).css({
                fontSize: '160%',
                marginTop: '0.5em'
            }).text(script)
        );

        output.html(block);
    }

    input.on('input', updateOutput);
    dropdown.on('change', updateOutput);
});