diff --git a/js/analysis.js b/js/analysis.js index 17a1f0f..fdef6f6 100644 --- a/js/analysis.js +++ b/js/analysis.js @@ -77,6 +77,20 @@ return `${min}:${sec}`; } + function normalizeFightName(name) { + return String(name ?? '').trim().toLowerCase(); + } + + function currentFightName() { + const fight = (window.App?.fights ?? []).find(f => f.id === window.App?.fightId); + return normalizeFightName(fight?.name); + } + + function isSameFightName(fight) { + const name = currentFightName(); + return name !== '' && normalizeFightName(fight?.name) === name; + } + let hiddenPlayers = new Set(); let hiddenPlayerNames = new Set(); let lastEvents = []; @@ -265,7 +279,7 @@ let allSameReportFights = []; function populateRefFightSelect() { - const visible = allSameReportFights.filter(f => f.id !== window.App.fightId); + const visible = allSameReportFights.filter(f => f.id !== window.App.fightId && isSameFightName(f)); refFightSelect.innerHTML = ''; visible.forEach(f => { const hp = f.kill ? 'Kill' : (f.fightPercentage != null ? f.fightPercentage.toFixed(2) + '%' : '?'); @@ -288,8 +302,22 @@ const refExtPanel = document.getElementById('ref-ext-panel'); const refReportInput = document.getElementById('ref-report-input'); const refReportLoad = document.getElementById('ref-report-load'); + const refFflogsLink = document.getElementById('ref-fflogs-report-link'); const refExtFightSelect = document.getElementById('ref-ext-fight-select'); + function updateRefFflogsLink(fightId = 0) { + if (!extReportCode) { + refFflogsLink.style.display = 'none'; + refFflogsLink.href = '#'; + return; + } + + refFflogsLink.href = window.App?.fflogsReportUrl + ? window.App.fflogsReportUrl(extReportCode, fightId) + : `https://www.fflogs.com/reports/${encodeURIComponent(extReportCode)}${fightId ? `#fight=${fightId}` : ''}`; + refFflogsLink.style.display = ''; + } + refReportInput.addEventListener('input', () => { const match = refReportInput.value.match(/fflogs\.com\/reports\/([A-Za-z0-9]+)/); if (match) refReportInput.value = match[1]; @@ -318,8 +346,9 @@ const fights = json?.data?.reportData?.report?.fights ?? []; extFights = fights; extReportCode = code; + updateRefFflogsLink(); - const visibleExt = fights; + const visibleExt = fights.filter(isSameFightName); refExtFightSelect.innerHTML = ''; visibleExt.forEach(f => { const hp = f.kill ? 'Kill' : (f.fightPercentage != null ? f.fightPercentage.toFixed(2) + '%' : '?'); @@ -330,8 +359,9 @@ }); refExtFightSelect.style.display = visibleExt.length ? '' : 'none'; refExtPanel.style.display = ''; - if (preferredFightId) { + if (preferredFightId && visibleExt.some(f => f.id === preferredFightId)) { refExtFightSelect.value = String(preferredFightId); + updateRefFflogsLink(preferredFightId); await loadExternalCompare(preferredFightId); } } catch { } @@ -392,7 +422,9 @@ } refExtFightSelect.addEventListener('change', async () => { - await loadExternalCompare(parseInt(refExtFightSelect.value, 10)); + const refId = parseInt(refExtFightSelect.value, 10) || 0; + updateRefFflogsLink(refId); + await loadExternalCompare(refId); }); // ── Timeline rendering ──────────────────────────────────────────────────── @@ -684,6 +716,8 @@ refFightSelect.style.display = 'none'; refExtFightSelect.value = ''; refExtFightSelect.style.display = 'none'; + refFflogsLink.style.display = 'none'; + refFflogsLink.href = '#'; refExtPanel.style.display = 'none'; }, }; diff --git a/js/app.js b/js/app.js index 3389b1a..701f0c5 100644 --- a/js/app.js +++ b/js/app.js @@ -7,6 +7,7 @@ document.addEventListener('DOMContentLoaded', () => { const initialHint = document.getElementById('initial-hint'); const fightSelectCard = document.getElementById('fight-select-card'); const fightSelect = document.getElementById('fight-select'); + const fflogsReportLink = document.getElementById('fflogs-report-link'); const languageSelect = document.getElementById('language-select'); const explorerCard = document.getElementById('event-explorer-card'); const exLoadBtn = document.getElementById('ex-load-btn'); @@ -59,6 +60,31 @@ document.addEventListener('DOMContentLoaded', () => { } window.App.setUrlState = setUrlState; + function fflogsReportUrl(reportCode, fightId = 0) { + const code = String(reportCode || '').trim(); + if (!code) return '#'; + + const host = { + de: 'de.fflogs.com', + fr: 'fr.fflogs.com', + jp: 'ja.fflogs.com', + }[window.App.language] ?? 'www.fflogs.com'; + const fight = parseInt(fightId, 10) || 0; + return `https://${host}/reports/${encodeURIComponent(code)}${fight ? `#fight=${fight}` : ''}`; + } + window.App.fflogsReportUrl = fflogsReportUrl; + + function updateFflogsReportLink() { + if (!window.App.reportCode) { + fflogsReportLink.style.display = 'none'; + fflogsReportLink.href = '#'; + return; + } + + fflogsReportLink.href = fflogsReportUrl(window.App.reportCode, window.App.fightId); + fflogsReportLink.style.display = ''; + } + const initialUrlState = getUrlState(); const storedLanguage = localStorage.getItem('ff14-mitigator-language'); const legacyTranslateLanguage = initialUrlState.translate === '1' ? 'de' : 'en'; @@ -114,6 +140,7 @@ document.addEventListener('DOMContentLoaded', () => { window.App.fightStart = fight.startTime; window.App.fightEnd = fight.endTime; window.App.phases = buildPhases(fight); + updateFflogsReportLink(); displayFight(fight); explorerCard.style.display = 'block'; @@ -224,6 +251,8 @@ document.addEventListener('DOMContentLoaded', () => { fightSelectCard.style.display = 'none'; explorerCard.style.display = 'none'; fightSelect.innerHTML = ''; + fflogsReportLink.style.display = 'none'; + fflogsReportLink.href = '#'; allFights = []; window.App.reportCode = reportCode; @@ -291,6 +320,7 @@ document.addEventListener('DOMContentLoaded', () => { window.App.fights = allFights; fightSelectCard.style.display = 'block'; + updateFflogsReportLink(); window.analysisTab?.onFightsLoaded?.(allFights); if (preferredFightId && selectFight(preferredFightId, true)) return; diff --git a/templates/fight-select.php b/templates/fight-select.php index da53a17..37db7ae 100644 --- a/templates/fight-select.php +++ b/templates/fight-select.php @@ -1,5 +1,8 @@