stable build just need it to fetch sources

This commit is contained in:
2026-10-04 21:11:07 -07:00
parent 72b55f473d
commit 3ee95c1bf5
15 changed files with 94 additions and 34 deletions

View File

@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.software.leanback" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.software.leanback" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<application
@@ -11,19 +13,21 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:banner="@drawable/tv_banner">
android:banner="@drawable/tv_banner"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch"
android:banner="@drawable/tv_banner"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 205 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>

View File

@@ -21,7 +21,19 @@ body {
font-family: "Inter", "SF Pro Display", "Segoe UI", Roboto, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
overflow: hidden;
cursor: default
cursor: default;
overscroll-behavior: none;
touch-action: pan-x pan-y;
}
.card,
.sc,
.pe,
.tr,
.ep {
transform: translateZ(0);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
::-webkit-scrollbar {

View File

@@ -65,6 +65,21 @@
filter: drop-shadow(0 4px 18px rgba(0, 0, 0, .6))
}
#dback {
position: fixed;
top: 3.5vh;
left: 3.5vw;
z-index: 12;
background: rgba(255, 255, 255, .12);
backdrop-filter: blur(12px);
}
#dback.on {
background: #fff;
color: #000;
transform: scale(1.08);
}
.dh h1 {
font-size: clamp(30px, 4.4vw, 76px);
font-weight: 700;

View File

@@ -24,7 +24,7 @@
height: 100%;
object-fit: contain;
background: #000;
z-index: 1;
z-index: 0;
}
#pl.cover #pv {
@@ -702,14 +702,4 @@ video::cue {
#pl.cover #pbg {
opacity: 0;
visibility: hidden;
}
#pv {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: contain;
background: transparent;
z-index: 1;
}

View File

@@ -215,10 +215,15 @@
.sc {
flex: 0 0 var(--cw);
transition: transform .32s cubic-bezier(.22, .9, .3, 1)
width: var(--cw);
max-width: var(--cw);
min-width: 0;
transition: transform .32s cubic-bezier(.22, .9, .3, 1);
}
.sc .po {
width: 100%;
height: calc(var(--cw) * 1.5);
aspect-ratio: 2/3;
border-radius: 14px;
overflow: hidden;

View File

@@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>Vyla</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">

View File

@@ -2,7 +2,7 @@ let dgen = 0;
async function openDetail(it) {
const t = it._t;
if (!ov.classList.contains('show')) ov._prev = cur;
ov.classList.add('show'); side.classList.remove('open'); const my = ++dgen; ov.innerHTML = SK.detail(it); ov.scrollTop = 0;
ov.classList.add('show'); side.classList.remove('open'); const my = ++dgen; ov.innerHTML = `<div class="pic f" id="dback">${ic('<path d="M19 12H5M12 19l-7-7 7-7"/>')}</div>` + SK.detail(it); $('#dback')._a = closeDetail; ov.scrollTop = 0;
const d = await api(`/${t}/${it.id}`, `&append_to_response=videos,credits,recommendations,images,${t === 'movie' ? 'release_dates' : 'content_ratings'}&include_image_language=en,null`);
if (my !== dgen || !ov.classList.contains('show')) return;
if (!d.id) { closeDetail(); return }
@@ -11,8 +11,8 @@ async function openDetail(it) {
const rt = t === 'movie' ? (d.runtime ? `${Math.floor(d.runtime / 60)}h ${d.runtime % 60}m` : '') : (d.number_of_seasons ? `${d.number_of_seasons} Season${d.number_of_seasons > 1 ? 's' : ''}` : '');
const lg = ((d.images || {}).logos || []).find(x => x.iso_639_1 === 'en') || ((d.images || {}).logos || [])[0];
const bp = d.backdrop_path || d.poster_path;
ov.innerHTML = `<div class="dbl" style="background-image:url(${I}w780${bp})"></div><div class="dw"><div class="dimg" style="background-image:url(${I}w1280${bp})"></div><div class="dc"><div class="dh"><div id="dlogo">${lg ? `<img src="${I}w500${lg.file_path}" alt="">` : `<h1>${title}</h1>`}</div><div class="meta"><span>${(d.vote_average || 0).toFixed(1)}</span><span>${year}</span>${cert ? `<span class="b">${cert}</span>` : ''}<span>${rt}</span><span>${(d.genres || []).slice(0, 3).map(g => g.name).join(', ')}</span></div><div class="hb"><button class="pb f" id="dplay">Play</button><div class="circ f" id="dmenu">&#8942;</div><div class="mx" id="dmx"><div class="circ f" id="dwl"></div><div class="circ f" id="dfv"></div></div></div><p class="otx" id="otx">${d.overview || ''}</p><span class="more f" id="dmore">MORE</span></div><div id="dsecs"></div></div></div>`;
const secs = $('#dsecs');
ov.innerHTML = `<div class="pic f" id="dback">${ic('<path d="M19 12H5M12 19l-7-7 7-7"/>')}</div><div class="dbl" style="background-image:url(${I}w780${bp})"></div><div class="dw"><div class="dimg" style="background-image:url(${I}w1280${bp})"></div><div class="dc"><div class="dh"><div id="dlogo">${lg ? `<img src="${I}w500${lg.file_path}" alt="">` : `<h1>${title}</h1>`}</div><div class="meta"><span>${(d.vote_average || 0).toFixed(1)}</span><span>${year}</span>${cert ? `<span class="b">${cert}</span>` : ''}<span>${rt}</span><span>${(d.genres || []).slice(0, 3).map(g => g.name).join(', ')}</span></div><div class="hb"><button class="pb f" id="dplay">Play</button><div class="circ f" id="dmenu">&#8942;</div><div class="mx" id="dmx"><div class="circ f" id="dwl"></div><div class="circ f" id="dfv"></div></div></div><p class="otx" id="otx">${d.overview || ''}</p><span class="more f" id="dmore">MORE</span></div><div id="dsecs"></div></div></div>`;
$('#dback')._a = closeDetail; const secs = $('#dsecs');
const rowOf = (name, kids) => { if (!kids.length) return; const s = document.createElement('section'); s.className = 'ds'; s.innerHTML = `<h3>${name}</h3><div class="row"></div>`; s.lastChild.append(...kids); secs.appendChild(s) };
const el = (c, h) => { const e = document.createElement('div'); e.className = c + ' f'; e.tabIndex = -1; e.innerHTML = h; e._a = () => { }; return e };
if (t === 'tv') {

View File

@@ -1,3 +1,10 @@
if (window.tizen && window.tizen.tvinputdevice) {
try {
['MediaPlay', 'MediaPause', 'MediaPlayPause', 'MediaStop', 'MediaFastForward', 'MediaRewind', '10009']
.forEach(k => tizen.tvinputdevice.registerKey(k));
} catch (_) { }
}
const KM = {
37: 'l', 21: 'l',
38: 'u', 19: 'u',
@@ -11,7 +18,7 @@ document.addEventListener('keydown', e => {
fast = e.repeat;
document.body.classList.add('kbm');
if (e.keyCode === 85 || e.keyCode === 179) {
if (e.keyCode === 85 || e.keyCode === 179 || e.keyCode === 10252 || e.keyCode === 415) {
e.preventDefault();
tgl();
return;
@@ -21,17 +28,17 @@ document.addEventListener('keydown', e => {
vd.play();
return;
}
if (e.keyCode === 127) {
if (e.keyCode === 127 || e.keyCode === 413) {
e.preventDefault();
vd.pause();
return;
}
if (e.keyCode === 89 || e.keyCode === 227) {
if (e.keyCode === 89 || e.keyCode === 227 || e.keyCode === 412) {
e.preventDefault();
vd.currentTime = Math.max(0, vd.currentTime - 10);
return;
}
if (e.keyCode === 90 || e.keyCode === 228) {
if (e.keyCode === 90 || e.keyCode === 228 || e.keyCode === 417) {
e.preventDefault();
vd.currentTime = Math.min(vd.duration || Infinity, vd.currentTime + 10);
return;

View File

@@ -21,7 +21,19 @@ body {
font-family: "Inter", "SF Pro Display", "Segoe UI", Roboto, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
overflow: hidden;
cursor: default
cursor: default;
overscroll-behavior: none;
touch-action: pan-x pan-y;
}
.card,
.sc,
.pe,
.tr,
.ep {
transform: translateZ(0);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
::-webkit-scrollbar {

View File

@@ -24,7 +24,7 @@
height: 100%;
object-fit: contain;
background: #000;
z-index: 1;
z-index: 0;
}
#pl.cover #pv {
@@ -710,6 +710,6 @@ video::cue {
width: 100%;
height: 100%;
object-fit: contain;
background: transparent;
z-index: 1;
background: #000;
z-index: 0;
}

View File

@@ -215,10 +215,15 @@
.sc {
flex: 0 0 var(--cw);
transition: transform .32s cubic-bezier(.22, .9, .3, 1)
width: var(--cw);
max-width: var(--cw);
min-width: 0;
transition: transform .32s cubic-bezier(.22, .9, .3, 1);
}
.sc .po {
width: 100%;
height: calc(var(--cw) * 1.5);
aspect-ratio: 2/3;
border-radius: 14px;
overflow: hidden;

View File

@@ -11,7 +11,7 @@ document.addEventListener('keydown', e => {
fast = e.repeat;
document.body.classList.add('kbm');
if (e.keyCode === 85 || e.keyCode === 179) {
if (e.keyCode === 85 || e.keyCode === 179 || e.keyCode === 10252 || e.keyCode === 415) {
e.preventDefault();
tgl();
return;
@@ -21,17 +21,17 @@ document.addEventListener('keydown', e => {
vd.play();
return;
}
if (e.keyCode === 127) {
if (e.keyCode === 127 || e.keyCode === 413) {
e.preventDefault();
vd.pause();
return;
}
if (e.keyCode === 89 || e.keyCode === 227) {
if (e.keyCode === 89 || e.keyCode === 227 || e.keyCode === 412) {
e.preventDefault();
vd.currentTime = Math.max(0, vd.currentTime - 10);
return;
}
if (e.keyCode === 90 || e.keyCode === 228) {
if (e.keyCode === 90 || e.keyCode === 228 || e.keyCode === 417) {
e.preventDefault();
vd.currentTime = Math.min(vd.duration || Infinity, vd.currentTime + 10);
return;