1
0
mirror of git://f0xx.org/ac/ac-be-hub synced 2026-07-29 03:38:44 +03:00
Files
ac-be-hub/assets/hub-downloads.js
Anton Afanasyeu db8832b417 feat(hub): shared nav shell, downloads UI, footer fix
Signed-off-by: Anton Afanasyeu <a.afanasieff@gmail.com>
2026-07-12 13:53:36 +02:00

121 lines
3.5 KiB
JavaScript

(function () {
'use strict';
/** Orchestration default channel; stable is fallback for promoted releases. */
var OTA_CHANNELS = ['staging', 'stable'];
function setStatus(msg) {
var el = document.getElementById('hub-download-apk-status');
if (el) {
el.textContent = msg;
}
}
function fetchJson(url) {
return fetch(url, { cache: 'no-store' }).then(function (r) {
if (!r.ok) {
throw new Error('HTTP ' + r.status + ' for ' + url);
}
return r.json();
});
}
function resolveApkFromChannel(channelName) {
return fetchJson('/v0/ota/channel/' + encodeURIComponent(channelName) + '.json')
.then(function (channel) {
var manifestUrl = channel && channel.manifestUrl;
if (!manifestUrl) {
throw new Error(channelName + ' missing manifestUrl');
}
return fetchJson(manifestUrl);
})
.then(function (manifest) {
var url =
(manifest && (manifest.browserApkUrl || manifest.apkUrl)) || '';
if (!url) {
throw new Error('manifest missing browserApkUrl/apkUrl');
}
if (!manifest.browserApkUrl && /\.otapkg(\?|$)/.test(url)) {
url = url.replace(/\.otapkg(\?|$)/, '.apk$1');
}
var nameMatch = url.match(/\/([^/?#]+\.apk)(?:\?|$)/i);
var filename = nameMatch ? nameMatch[1] : 'android_cast-latest.apk';
return { url: url, filename: filename, channel: channelName };
});
}
function resolveApkUrl() {
var chain = Promise.reject(new Error('no channel'));
OTA_CHANNELS.forEach(function (ch) {
chain = chain.catch(function () {
return resolveApkFromChannel(ch);
});
});
return chain;
}
function triggerDownload(url, filename) {
if (/\.apk(\?|$)/i.test(url)) {
var a = document.createElement('a');
a.href = url;
a.download = filename;
a.rel = 'noopener';
document.body.appendChild(a);
a.click();
a.remove();
return Promise.resolve();
}
return fetch(url, { cache: 'no-store' })
.then(function (r) {
if (!r.ok) {
throw new Error('download HTTP ' + r.status);
}
return r.blob();
})
.then(function (blob) {
var blobUrl = URL.createObjectURL(blob);
var link = document.createElement('a');
link.href = blobUrl;
link.download = filename;
link.rel = 'noopener';
document.body.appendChild(link);
link.click();
link.remove();
setTimeout(function () {
URL.revokeObjectURL(blobUrl);
}, 60000);
});
}
function wireApkButton() {
var btn = document.getElementById('hub-download-apk');
if (!btn) {
return;
}
btn.addEventListener('click', function () {
btn.disabled = true;
setStatus('Resolving OTA channel…');
resolveApkUrl()
.then(function (resolved) {
setStatus('Downloading ' + resolved.filename + ' (' + resolved.channel + ')…');
return triggerDownload(resolved.url, resolved.filename);
})
.catch(function (err) {
setStatus(
'APK unavailable — run builder with OTA publish (staging). ' +
(err.message || err)
);
})
.finally(function () {
btn.disabled = false;
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', wireApkButton);
} else {
wireApkButton();
}
})();