MediaWiki:Common.js: Unterschied zwischen den Versionen

Keine Bearbeitungszusammenfassung
Markierung: Manuelle Zurücksetzung
Keine Bearbeitungszusammenfassung
Zeile 220: Zeile 220:




/* Whisky-Ratings – eigenes Frontend für RatePage (Variante B) */
/* Whisky-Ratings – eigenes Frontend für RatePage (Variante B, robust + Stats) */
mw.loader.using(['mediawiki.api', 'mediawiki.user']).then(function () {
mw.loader.using(['mediawiki.api', 'mediawiki.user']).then(function () {


Zeile 228: Zeile 228:


   function setupWidget(box) {
   function setupWidget(box) {
     const pageTitle = box.dataset.ratepageTitle;
     const pageId  = mw.config.get('wgArticleId');                       // stabiler als Titel
     const contest   = box.dataset.ratepageContest || undefined;
     const contest = box.dataset.ratepageContest || undefined;           // "NASE" | "GESCHMACK" | "ABGANG"
     const scale     = parseInt(box.dataset.ratepageScale || '10', 10);
     const scale   = parseInt(box.dataset.ratepageScale || '10', 10);


     const widget = box.querySelector('.whisky-rating__widget');
     const widget = box.querySelector('.whisky-rating__widget');
     const meta   = box.querySelector('.whisky-rating__meta');
     const meta   = box.querySelector('.whisky-rating__meta');


     const isAnon = mw.user.isAnon();
     const isAnon = mw.user.isAnon();
     if (isAnon) {
     if (isAnon) {
       box.classList.add('whisky-rating--disabled');
       box.classList.add('whisky-rating--disabled');
Zeile 241: Zeile 241:
     }
     }


     // Buttons bauen
     // --- Buttons bauen ---
     const buttons = [];
     const buttons = [];
     for (let i = 1; i <= scale; i++) {
     for (let i = 1; i <= scale; i++) {
Zeile 279: Zeile 279:
     }
     }


    // --- Stats laden (Ø & Stimmen, eigene Stimme, canVote/see) ---
    function updateStats() {
      const api = new mw.Api();
      api.get({
        action: 'query',
        prop: 'pagerating',
        pageids: pageId,
        prcontest: contest || undefined,
        format: 'json'
      }).done(function (data) {
        try {
          const page = data.query.pages[pageId];
          const pr = page && page.pagerating;
          if (!pr) { meta.textContent = ''; return; }
          // Ergebnisse sichtbar?
          if (typeof pr.canSee !== 'undefined' && pr.canSee === 0) {
            meta.textContent = 'Bewertungen sind verborgen.';
          } else {
            const hist = pr.pageRating || {};
            let total = 0, sum = 0;
            Object.keys(hist).forEach(k => {
              const s = parseInt(k, 10), c = parseInt(hist[k], 10);
              if (!isNaN(s) && !isNaN(c)) { total += c; sum += s * c; }
            });
            meta.textContent = total ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)') : 'Noch keine Bewertungen';
          }
          // eigene Stimme hervorheben
          if (pr.userVote) {
            current = pr.userVote;
            highlight(current);
          }
          // Voting erlaubnis anzeigen + ggf. deaktivieren
          if (typeof pr.canVote !== 'undefined' && pr.canVote === 0) {
            box.classList.add('whisky-rating--disabled');
            widget.querySelectorAll('.whisky-glass').forEach(b => b.disabled = true);
            meta.textContent += (meta.textContent ? ' • ' : '') + 'Du darfst hier nicht abstimmen.';
          }
        } catch (e) {
          console.error(e);
        }
      }).fail(function (xhr) {
        console.error('Pagerating-Load-Error', xhr);
      });
    }
    // --- Vote senden (per pageid) ---
     function vote(value) {
     function vote(value) {
       const api = new mw.Api();
       const api = new mw.Api();
       meta.textContent = 'Wird gespeichert …';
       meta.textContent = 'Wird gespeichert …';


       api.postWithToken('csrf', {
       api.postWithToken('csrf', {
         action: 'ratepage',
         action: 'ratepage',
         pagetitle: pageTitle, // Seitentitel, z. B. "Lagavulin 16"
         pageid: pageId,                 // ROBUST
         answer: value,       // 1..10
         answer: value,                 // 1..10
         contest: contest,     // "NASE" | "GESCHMACK" | "ABGANG"
         contest: contest || undefined, // Kategorie
         format: 'json'
         format: 'json'
       }).done(function (data) {
       }).done(function () {
         current = value;
         current = value;
         highlight(current);
         highlight(current);
         meta.textContent = 'Danke! Deine Bewertung: ' + value + ' / ' + scale;
         updateStats();                  // frische Ø/Count laden
        // Tipp: Wenn du später Durchschnitt/Anzahl anzeigen willst,
      }).fail(function (xhr) {
        // kannst du hier einen zusätzlichen API-Call einbauen,
        let msg = 'Unbekannter Fehler';
         // sofern du die Stats von RatePage abrufen möchtest.
        try {
      }).fail(function (err) {
          const j = xhr && xhr.responseJSON ? xhr.responseJSON : xhr;
         console.error(err);
          if (j && j.error) {
         meta.textContent = 'Speichern fehlgeschlagen. Bitte später erneut versuchen.';
            msg = (j.error.code ? j.error.code + ': ' : '') + (j.error.info || '');
          }
         } catch(e){}
         console.error('RatePage-API-Fehler:', xhr);
         meta.textContent = 'Speichern fehlgeschlagen: ' + msg;
       });
       });
     }
     }
    // Initial laden
    updateStats();
   }
   }


   // Warten bis der DOM da ist (auch bei VisualEditor-Nachladungen)
   // Init
   if (document.readyState === 'loading') {
   if (document.readyState === 'loading') {
     document.addEventListener('DOMContentLoaded', init);
     document.addEventListener('DOMContentLoaded', init);