152 lines
5.2 KiB
JavaScript
152 lines
5.2 KiB
JavaScript
/* The OC Guy — page behaviour.
|
|
Everything degrades: without JS the page is a plain, readable
|
|
document with working links and a mail form. */
|
|
(function () {
|
|
'use strict';
|
|
|
|
var doc = document.documentElement;
|
|
doc.classList.add('js');
|
|
|
|
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
|
|
/* ---------- entrance for the blocks of each section ---------- */
|
|
var targets = document.querySelectorAll(
|
|
'.lead-caption, .box, .side-list, .section-head, .card, .feature, .news li, .ask-inner'
|
|
);
|
|
|
|
if (!reduce && 'IntersectionObserver' in window) {
|
|
var io = new IntersectionObserver(function (entries) {
|
|
entries.forEach(function (entry) {
|
|
if (!entry.isIntersecting) return;
|
|
entry.target.classList.add('rv-in');
|
|
io.unobserve(entry.target);
|
|
});
|
|
}, { rootMargin: '0px 0px -8% 0px', threshold: 0.08 });
|
|
|
|
Array.prototype.forEach.call(targets, function (el) {
|
|
el.setAttribute('data-rv', '1');
|
|
io.observe(el);
|
|
});
|
|
} else {
|
|
Array.prototype.forEach.call(targets, function (el) { el.classList.add('rv-in'); });
|
|
}
|
|
|
|
/* ---------- the ask form: one question, by mail ---------- */
|
|
var form = document.querySelector('.ask-form');
|
|
var mail = document.getElementById('ask-mail');
|
|
|
|
if (form && mail) {
|
|
form.addEventListener('submit', function (event) {
|
|
event.preventDefault();
|
|
var addr = (mail.value || '').trim();
|
|
if (!addr || addr.indexOf('@') === -1) {
|
|
mail.setAttribute('aria-invalid', 'true');
|
|
mail.focus();
|
|
return;
|
|
}
|
|
mail.removeAttribute('aria-invalid');
|
|
var body = 'My question about Odoo Community:\n\n\n— reply to: ' + addr + '\n';
|
|
window.location.href = 'mailto:oliver@oc-guy.com'
|
|
+ '?subject=' + encodeURIComponent('Odoo Community question')
|
|
+ '&body=' + encodeURIComponent(body);
|
|
});
|
|
}
|
|
|
|
/* ---------- OCA module status, live from the n8n feed ---------- */
|
|
var ocaBody = document.getElementById('oca-rows');
|
|
|
|
function statusCell(ok, version) {
|
|
var td = document.createElement('td');
|
|
td.className = 'oca-status';
|
|
var mark = document.createElement('span');
|
|
mark.className = ok ? 'mark is-on' : 'mark';
|
|
mark.setAttribute('aria-hidden', 'true');
|
|
mark.textContent = ok ? '\u2713' : '\u2014';
|
|
var sr = document.createElement('span');
|
|
sr.className = 'sr-only';
|
|
sr.textContent = ok ? ' has a ' + version + ' branch' : ' no ' + version + ' branch yet';
|
|
td.appendChild(mark);
|
|
td.appendChild(sr);
|
|
return td;
|
|
}
|
|
|
|
function renderOca(rows) {
|
|
ocaBody.textContent = '';
|
|
rows.forEach(function (m) {
|
|
var tr = document.createElement('tr');
|
|
|
|
var name = document.createElement('td');
|
|
name.className = 'oca-name';
|
|
var a = document.createElement('a');
|
|
a.href = m.URL || '#';
|
|
a.target = '_blank';
|
|
a.rel = 'noopener';
|
|
a.textContent = m.name || 'Module';
|
|
name.appendChild(a);
|
|
|
|
var area = document.createElement('td');
|
|
area.className = 'oca-area';
|
|
area.textContent = m.area || '';
|
|
|
|
tr.appendChild(name);
|
|
tr.appendChild(area);
|
|
tr.appendChild(statusCell(!!m.v19, '19.0'));
|
|
tr.appendChild(statusCell(!!m.v20, '20.0'));
|
|
ocaBody.appendChild(tr);
|
|
});
|
|
}
|
|
|
|
/* ---------- featured module: one editorial pick, status live from the feed ---------- */
|
|
var FEATURED = 'mail tracker';
|
|
|
|
function updateFeatured(rows) {
|
|
var link = document.getElementById('featured-link');
|
|
if (!link) return;
|
|
var hit = rows.filter(function (m) {
|
|
return String(m.name || '').toLowerCase().trim() === FEATURED;
|
|
})[0];
|
|
if (!hit) return;
|
|
if (hit.URL) link.href = hit.URL;
|
|
var branches = document.querySelectorAll('#featured-branches .branch');
|
|
if (branches[0]) branches[0].classList.toggle('is-on', !!hit.v19);
|
|
if (branches[1]) branches[1].classList.toggle('is-on', !!hit.v20);
|
|
}
|
|
|
|
if (ocaBody) {
|
|
fetch('https://n8n.odoo4projects.com/webhook/oc-guy/modules')
|
|
.then(function (r) { if (!r.ok) throw new Error('http ' + r.status); return r.json(); })
|
|
.then(function (payload) {
|
|
var rows = payload && Array.isArray(payload.data) ? payload.data
|
|
: (Array.isArray(payload) ? payload : null);
|
|
if (!rows || !rows.length) throw new Error('empty');
|
|
renderOca(rows);
|
|
updateFeatured(rows);
|
|
})
|
|
.catch(function () {
|
|
/* keep the snapshot already in the markup */
|
|
});
|
|
}
|
|
|
|
/* ---------- which section the reader is in ---------- */
|
|
var links = Array.prototype.slice.call(document.querySelectorAll('.nav a[href^="#"]'));
|
|
var sections = links
|
|
.map(function (a) { return document.querySelector(a.getAttribute('href')); })
|
|
.filter(Boolean);
|
|
|
|
if (sections.length && 'IntersectionObserver' in window) {
|
|
var seen = new IntersectionObserver(function (entries) {
|
|
entries.forEach(function (entry) {
|
|
if (!entry.isIntersecting) return;
|
|
links.forEach(function (a) {
|
|
if (a.getAttribute('href') === '#' + entry.target.id) {
|
|
a.setAttribute('aria-current', 'true');
|
|
} else {
|
|
a.removeAttribute('aria-current');
|
|
}
|
|
});
|
|
});
|
|
}, { rootMargin: '-45% 0px -50% 0px' });
|
|
sections.forEach(function (s) { seen.observe(s); });
|
|
}
|
|
})();
|