stremio/apps/tizen-tv/www/js/focus.js
Jos Vooges | STH a0311c031e Add Samsung Tizen TV web client.
Focus-friendly VMC shell for Tizen with live TV and playback against the master API.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 19:16:30 +02:00

100 lines
2.8 KiB
JavaScript

(function (global) {
var keys = {
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
ENTER: 13,
BACK: 10009,
ESC: 27,
PLAY: 415,
PAUSE: 19,
PLAYPAUSE: 10252,
FF: 417,
REW: 412,
STOP: 413,
};
function visibleFocusables(root) {
root = root || document;
var nodes = root.querySelectorAll(".focusable, .tile, .profile-tile, .ep, .num-key, .btn");
var out = [];
for (var i = 0; i < nodes.length; i++) {
var el = nodes[i];
if (el.disabled) continue;
if (el.classList.contains("hidden")) continue;
if (el.closest && el.closest(".hidden")) continue;
var r = el.getBoundingClientRect();
if (r.width < 2 || r.height < 2) continue;
out.push(el);
}
return out;
}
function center(el) {
var r = el.getBoundingClientRect();
return { x: r.left + r.width / 2, y: r.top + r.height / 2, r: r };
}
function move(direction) {
var active = document.activeElement;
var list = visibleFocusables();
if (!list.length) return;
if (!active || list.indexOf(active) < 0) {
list[0].focus();
return;
}
var a = center(active);
var best = null;
var bestScore = Infinity;
for (var i = 0; i < list.length; i++) {
var el = list[i];
if (el === active) continue;
var b = center(el);
var dx = b.x - a.x;
var dy = b.y - a.y;
var ok = false;
if (direction === "left") ok = dx < -10 && Math.abs(dy) < Math.abs(dx) * 1.6;
if (direction === "right") ok = dx > 10 && Math.abs(dy) < Math.abs(dx) * 1.6;
if (direction === "up") ok = dy < -10 && Math.abs(dx) < Math.abs(dy) * 1.8;
if (direction === "down") ok = dy > 10 && Math.abs(dx) < Math.abs(dy) * 1.8;
if (!ok) continue;
var score = Math.abs(dx) + Math.abs(dy) * 1.2;
if (score < bestScore) {
bestScore = score;
best = el;
}
}
if (best) {
best.focus();
if (best.scrollIntoView) best.scrollIntoView({ block: "nearest", inline: "nearest" });
}
}
function registerKeys() {
try {
if (global.tizen && tizen.tvinputdevice) {
var supported = tizen.tvinputdevice.getSupportedKeys() || [];
var names = ["MediaPlay", "MediaPause", "MediaPlayPause", "MediaFastForward", "MediaRewind", "MediaStop"];
for (var i = 0; i < supported.length; i++) {
if (names.indexOf(supported[i].name) >= 0) {
try {
tizen.tvinputdevice.registerKey(supported[i].name);
} catch (e) {}
}
}
}
} catch (e) {}
}
global.McFocus = {
keys: keys,
move: move,
focusFirst: function (root) {
var list = visibleFocusables(root);
if (list[0]) list[0].focus();
},
registerKeys: registerKeys,
};
})(window);