function createReviewController({ fetchJson }) { function endpoint(item) { const [owner, repo] = String(item.repository || '').split('/'); if (!owner || !repo || !Number.isInteger(Number(item.number))) { throw new Error('This review link is invalid.'); } return 'api/v1/repos/' + encodeURIComponent(owner) + '/' + encodeURIComponent(repo) + '/pulls/' + Number(item.number) + '/review'; } async function load(item) { return fetchJson(endpoint(item), { headers: { Accept: 'application/json' } }); } return { load }; } function diffLineClass(line) { if (line.startsWith('@@')) return 'hunk'; if (line.startsWith('+')) return 'added'; if (line.startsWith('-')) return 'removed'; return 'context'; } function renderDiffFile(file, index, escapeHtml) { const panelId = 'review-diff-' + index; let preview; if (file.diff_available) { const lines = (file.diff_lines || []).map(line => '' + escapeHtml(String(line)) + '' ).join(''); preview = '
' + lines +
(file.diff_truncated ? 'Preview truncated · open in Gitea for the full diff.' : '') +
'';
} else {
const message = file.diff_binary ? 'Binary file · preview unavailable.' : 'Diff preview unavailable.';
preview = '