{"id":479,"date":"2023-02-10T12:39:43","date_gmt":"2023-02-10T12:39:43","guid":{"rendered":"http:\/\/www.gambetti.com\/marcello\/?page_id=479"},"modified":"2025-12-29T17:24:04","modified_gmt":"2025-12-29T17:24:04","slug":"repertorio","status":"publish","type":"page","link":"https:\/\/www.gambetti.com\/marcello\/repertorio\/","title":{"rendered":"Repertorio"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Ecco una lista aggiornata del mio repertorio di canto <br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.gambetti.com\/marcello\/wp-admin\/edit.php?post_type=page\"><\/a><\/p>\n\n\n\n<style>\n    \/* --- STILE GENERALE E CONTENITORE --- *\/\n    #contenitore-repertorio {\n        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n        color: #333;\n        margin-top: 20px;\n        font-size: 15px;\n        \/* Reset per evitare conflitti WP *\/\n        line-height: 1.6;\n        box-sizing: border-box;\n    }\n\n    \/* --- CAMPO DI RICERCA --- *\/\n    #input-ricerca {\n        width: 100%;\n        padding: 12px;\n        margin-bottom: 15px;\n        border: 1px solid #ccc;\n        border-radius: 4px;\n        font-size: 16px;\n        box-sizing: border-box; \/* Importante per non sbordare *\/\n    }\n\n    \/* --- TABELLA --- *\/\n    #tabella-repertorio {\n        width: 100%;\n        border-collapse: collapse;\n        border: none;\n        margin: 0;\n    }\n\n    \/* Intestazione *\/\n    #tabella-repertorio th {\n        background-color: #444;\n        color: #fff;\n        padding: 12px 15px;\n        text-align: left;\n        font-weight: 600;\n        text-transform: uppercase;\n        font-size: 13px;\n        letter-spacing: 1px;\n        border: none;\n    }\n\n    \/* Celle *\/\n    #tabella-repertorio td {\n        padding: 10px 15px;\n        border-bottom: 1px solid #eee; \/* Leggero divisore *\/\n        color: #444;\n        vertical-align: middle;\n    }\n\n    \/* Righe alterne *\/\n    #tabella-repertorio tr:nth-child(odd) { background-color: #ffffff; }\n    #tabella-repertorio tr:nth-child(even) { background-color: #f9f9f9; }\n\n    \/* Colonna Numero *\/\n    .col-numero {\n        color: #999 !important;\n        font-weight: bold;\n        text-align: center;\n        font-size: 13px;\n    }\n\n    \/* --- STILE PLAYER (Pulsanti) --- *\/\n    \/* Uso !important per sovrascrivere i temi aggressivi di WordPress *\/\n    .btn-play {\n        display: inline-flex !important;\n        align-items: center;\n        justify-content: center;\n        width: 36px !important;\n        height: 36px !important;\n        border-radius: 50% !important;\n        border: none !important;\n        transition: all 0.2s ease;\n        padding: 0 !important;\n        margin: 0 auto !important; \/* Centra il bottone *\/\n        line-height: 0 !important;\n        box-shadow: none !important;\n        text-decoration: none !important;\n        background: none; \/* Reset background *\/\n    }\n\n    \/* Stato ATTIVO (File presente) *\/\n    .btn-active {\n        background-color: #4CAF50 !important; \/* Verde *\/\n        cursor: pointer;\n        box-shadow: 0 2px 5px rgba(0,0,0,0.2) !important;\n    }\n    .btn-active:hover {\n        background-color: #3e8e41 !important;\n        transform: scale(1.1);\n    }\n    \n    \/* Stato PLAYING (Quando sta suonando) - Cambia colore *\/\n    .btn-playing {\n        background-color: #e74c3c !important; \/* Rosso per Stop *\/\n        animation: pulse 2s infinite;\n    }\n\n    \/* Icone SVG *\/\n    .btn-active svg {\n        fill: #ffffff !important;\n        width: 16px !important;\n        height: 16px !important;\n        display: block;\n    }\n    \n    \/* Stato DISABILITATO *\/\n    .btn-disabled {\n        background-color: #e0e0e0 !important;\n        cursor: default;\n        pointer-events: none;\n    }\n    .btn-disabled svg {\n        fill: #a0a0a0 !important;\n    }\n\n    \/* Animazione pulsante che suona *\/\n    @keyframes pulse {\n        0% { box-shadow: 0 0 0 0 rgba(231, 76, 60, 0.7); }\n        70% { box-shadow: 0 0 0 10px rgba(231, 76, 60, 0); }\n        100% { box-shadow: 0 0 0 0 rgba(231, 76, 60, 0); }\n    }\n\n    #messaggio-loading { padding: 20px; font-style: italic; color: #777; }\n    \n    \/* Nascondi righe filtrate *\/\n    .riga-nascosta { display: none !important; }\n<\/style>\n\n<div id=\"contenitore-repertorio\">\n    \n    <input type=\"text\" id=\"input-ricerca\" placeholder=\"Cerca nel repertorio...\" disabled>\n\n    <div id=\"messaggio-loading\">Caricamento tabella&#8230;<\/div>\n    \n    <audio id=\"player-audio-nascosto\" style=\"display:none;\"><\/audio>\n\n    <table id=\"tabella-repertorio\" style=\"display:none;\">\n        <thead>\n            <tr id=\"intestazione-tabella\">\n                <th style=\"width: 50px; text-align: center;\">#<\/th> \n                <\/tr>\n        <\/thead>\n        <tbody id=\"corpo-tabella\"><\/tbody>\n    <\/table>\n<\/div>\n\n<script>\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n\n    \/\/ --- CONFIGURAZIONE ---\n    const urlGoogleSheet = \"https:\/\/docs.google.com\/spreadsheets\/d\/e\/2PACX-1vSiF8HSExQKDpupGaGBZgeXSOgif0eRygpyq24smFV3HQICWXQdjHmV5VjVjIpvBKiANRESG4IYDFHA\/pub?gid=730397723&single=true&output=csv\";\n    const colonneDaMostrare = [0, 1, 2, 8]; \n    const indiceColonnaAudio = 8;\n    const cartellaMp3 = \"\/cb\/mp3\/repertorio\/\";\n    \n    \/\/ Icone SVG\n    const iconaPlay = '<svg viewBox=\"0 0 24 24\"><path d=\"M8 5v14l11-7z\"\/><\/svg>'; \/\/ Triangolo\n    const iconaStop = '<svg viewBox=\"0 0 24 24\"><path d=\"M6 6h12v12H6z\"\/><\/svg>'; \/\/ Quadrato\n\n    \/\/ Riferimenti DOM\n    const audioPlayer = document.getElementById('player-audio-nascosto');\n    const inputRicerca = document.getElementById('input-ricerca');\n    let bottoneCorrente = null; \/\/ Memorizza quale bottone sta suonando\n\n    fetch(urlGoogleSheet)\n    .then(response => {\n        if (!response.ok) throw new Error(\"Errore connessione\");\n        return response.text();\n    })\n    .then(csvText => {\n        const righe = csvText.split('\\n');\n        const tHeadRow = document.getElementById('intestazione-tabella');\n        const tBody = document.getElementById('corpo-tabella');\n        const tabella = document.getElementById('tabella-repertorio');\n        const loader = document.getElementById('messaggio-loading');\n\n        if (righe.length < 1) { loader.innerText = \"Nessun dato trovato.\"; return; }\n\n        let primaRiga = true;\n        let contatoreRighe = 1;\n\n        righe.forEach((riga, index) => {\n            if (!riga || riga.replace(\/,\/g, '').trim() === '') return;\n            const celle = riga.split(\/,(?=(?:(?:[^\"]*\"){2})*[^\"]*$)\/);\n\n            \/\/ --- INTESTAZIONE ---\n            if (primaRiga) {\n                colonneDaMostrare.forEach(idx => {\n                    const th = document.createElement('th');\n                    let testoHeader = celle[idx] ? celle[idx].replace(\/^\"|\"$\/g, '') : '';\n                    if(idx === indiceColonnaAudio) testoHeader = \"Ascolta\";\n                    th.textContent = testoHeader;\n                    tHeadRow.appendChild(th);\n                });\n                primaRiga = false;\n                return; \n            }\n\n            \/\/ --- RIGHE DATI ---\n            const tr = document.createElement('tr');\n\n            \/\/ Colonna Numero\n            const tdNum = document.createElement('td');\n            tdNum.className = 'col-numero';\n            tdNum.textContent = contatoreRighe++;\n            tr.appendChild(tdNum);\n\n            colonneDaMostrare.forEach(idx => {\n                const td = document.createElement('td');\n                let testoCella = celle[idx] ? celle[idx].replace(\/^\"|\"$\/g, '').trim() : '';\n\n                \/\/ LOGICA PLAYER\n                if (idx === indiceColonnaAudio) {\n                    td.style.textAlign = \"center\";\n                    \n                    if (testoCella !== \"\") {\n                        \/\/ Bottone Attivo\n                        const nomeFile = testoCella + \".mp3\";\n                        const percorso = cartellaMp3 + nomeFile;\n                        \n                        const btn = document.createElement('button');\n                        btn.className = 'btn-play btn-active';\n                        btn.innerHTML = iconaPlay; \n                        btn.title = \"Riproduci: \" + testoCella;\n                        \n                        \/\/ Gestore Click (Play\/Stop Logic)\n                        btn.onclick = function() {\n                            gestisciClickPlayer(btn, percorso);\n                        };\n                        \n                        td.appendChild(btn);\n                    } else {\n                        \/\/ Bottone Disabilitato\n                        const btnDisabled = document.createElement('span');\n                        btnDisabled.className = 'btn-play btn-disabled';\n                        btnDisabled.innerHTML = iconaPlay;\n                        td.appendChild(btnDisabled);\n                    }\n                } \n                \/\/ LOGICA TESTO\n                else {\n                    td.textContent = testoCella;\n                }\n                tr.appendChild(td);\n            });\n            tBody.appendChild(tr);\n        });\n\n        \/\/ Mostra tutto\n        loader.style.display = 'none';\n        tabella.style.display = 'table';\n        inputRicerca.disabled = false; \/\/ Attiva la ricerca\n    })\n    .catch(err => {\n        document.getElementById('messaggio-loading').innerHTML = \"Errore: \" + err.message;\n    });\n\n    \/\/ --- FUNZIONI LOGICA PLAYER ---\n    function gestisciClickPlayer(btnCliccato, percorsoFile) {\n        \/\/ Se stiamo cliccando sullo stesso bottone che sta gi\u00e0 suonando\n        if (bottoneCorrente === btnCliccato && !audioPlayer.paused) {\n            audioPlayer.pause();\n            audioPlayer.currentTime = 0; \/\/ Opzionale: riavvolge\n            resettaIcona(btnCliccato);\n            bottoneCorrente = null;\n            return;\n        }\n\n        \/\/ Se c'era un altro bottone che suonava, lo resettiamo\n        if (bottoneCorrente && bottoneCorrente !== btnCliccato) {\n            resettaIcona(bottoneCorrente);\n        }\n\n        \/\/ Avvia nuovo brano\n        audioPlayer.src = percorsoFile;\n        audioPlayer.play().then(() => {\n            \/\/ Cambio icona in STOP\n            btnCliccato.innerHTML = iconaStop;\n            btnCliccato.classList.add('btn-playing'); \/\/ Aggiunge stile rosso\/pulsante\n            bottoneCorrente = btnCliccato;\n        }).catch(e => {\n            alert(\"File non trovato o errore audio.\");\n            console.error(e);\n        });\n    }\n\n    function resettaIcona(btn) {\n        btn.innerHTML = iconaPlay;\n        btn.classList.remove('btn-playing');\n    }\n\n    \/\/ Reset automatico quando l'audio finisce\n    audioPlayer.addEventListener('ended', () => {\n        if(bottoneCorrente) {\n            resettaIcona(bottoneCorrente);\n            bottoneCorrente = null;\n        }\n    });\n\n    \/\/ --- LOGICA RICERCA ---\n    inputRicerca.addEventListener('keyup', function() {\n        const termine = this.value.toLowerCase();\n        const righe = document.querySelectorAll('#corpo-tabella tr');\n\n        righe.forEach(riga => {\n            \/\/ Uniamo tutto il testo della riga per cercare ovunque\n            const testoRiga = riga.textContent.toLowerCase();\n            if (testoRiga.includes(termine)) {\n                riga.classList.remove('riga-nascosta');\n            } else {\n                riga.classList.add('riga-nascosta');\n            }\n        });\n    });\n\n});\n<\/script>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ecco una lista aggiornata del mio repertorio di canto Caricamento tabella&#8230; #<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-479","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/pages\/479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/comments?post=479"}],"version-history":[{"count":18,"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/pages\/479\/revisions"}],"predecessor-version":[{"id":1018,"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/pages\/479\/revisions\/1018"}],"wp:attachment":[{"href":"https:\/\/www.gambetti.com\/marcello\/wp-json\/wp\/v2\/media?parent=479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}