From d6ec1f93b86ba0d9198b96dd9a698d7083ecd771 Mon Sep 17 00:00:00 2001 From: alwaysmesmerizingyou Date: Wed, 7 Oct 2026 14:05:39 -0700 Subject: [PATCH] UI updated --- architecture/index.html.backup | 177 --------------------------------- assets/app.js | 16 ++- assets/base.css | 45 +++++++-- 3 files changed, 54 insertions(+), 184 deletions(-) delete mode 100644 architecture/index.html.backup diff --git a/architecture/index.html.backup b/architecture/index.html.backup deleted file mode 100644 index bfbcaca..0000000 --- a/architecture/index.html.backup +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - Our Architecture — Vyla - - - - - - - - - - - - - - - - - - - - - - - content="How Vyla Home, SDK, and Stream API relate, and where each responsibility belongs." /> - - - - - - - - - - - - -
- -
-
-

Our Architecture

-

How Vyla Home, SDK, and Stream API relate, and where each responsibility belongs. -

-

The Vyla stack

-

Vyla separates local application management, provider resolution, and client-facing delivery. That separation - lets each layer be used on its own while keeping the integration points clear.

-

Vyla Home

-

Home is responsible for a desktop session: local configuration, encrypted local credentials, update - coordination, managed processes, and the embedded interface. It is the right layer for launching and - supervising a local experience.

-

Vyla SDK

-

The SDK contains the provider-facing work: source configuration, stream resolution, subtitle retrieval, - download lookup, and health probes. It is the right layer when your Node.js application needs to decide how - requests are authorized, cached, selected, and returned.

-

Stream API

-

Stream API wraps the SDK in a self-hosted HTTP service. Its movie and TV endpoints use Server-Sent Events so - metadata can arrive first and usable sources can be delivered progressively. It also provides subtitle, - download, health, test, and optional debug routes.

-

Common deployment patterns

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PatternBest forKey decision
Home onlya managed local desktop experienceHome owns the lifecycle of bundled local services
App + SDKa Node.js backend with a custom product APIyour app owns authentication, policy, and response design
Player + Stream APIbrowser or mobile clients that need a stable HTTP contractdeploy Stream API and place it behind TLS when exposed remotely
Home + Stream APIa local player backed by a local servicekeep the service bound and access-controlled for the local environment
-

Data flow for playback

-
    -
  1. A client provides a TMDB media ID (plus season and episode for TV).
  2. -
  3. Stream API, or your own SDK-based backend, asks active providers for candidates.
  4. -
  5. Candidates are checked and successful sources are returned progressively.
  6. -
  7. The player begins with the first compatible candidate and keeps later candidates as fallbacks.
  8. -
  9. Subtitle and download lookups are separate operations; neither should block first playback.
  10. -
-

Provider availability varies by source and network environment. Build the player experience around fallbacks - and empty-result states, as described in Error handling.

-
- -
-
- - - - - \ No newline at end of file diff --git a/assets/app.js b/assets/app.js index ba33526..02af3db 100644 --- a/assets/app.js +++ b/assets/app.js @@ -81,7 +81,7 @@ function buildThemeControls() { seg.innerHTML = modes.map(function (m) { return '"; }).join(""); - links.appendChild(seg); + (document.querySelector("#sidebar .side-links") || links).appendChild(seg); [menu, seg].forEach(function (el) { el.addEventListener("click", function (e) { var b = e.target.closest("button"); @@ -185,7 +185,9 @@ function buildMobileBar() { var newSidebar = doc.querySelector("#sidebar"); if (newSidebar) { var groups = newSidebar.querySelectorAll(".group"); + var sideHead = sidebar.querySelector(".side-head"); sidebar.innerHTML = ""; + if (sideHead) sidebar.appendChild(sideHead); if (mobileTabs) sidebar.appendChild(mobileTabs); groups.forEach(function (group) { sidebar.appendChild(group.cloneNode(true)); @@ -202,6 +204,18 @@ function buildMobileBar() { }); }); } + var head = document.createElement("div"); + head.className = "side-head"; + var brand = document.querySelector("#navbar .brand"); + if (brand && sidebar) { + var b = brand.cloneNode(true); + b.querySelector("img").removeAttribute("id"); + var sideLinks = document.createElement("div"); + sideLinks.className = "side-links"; + head.appendChild(b); + head.appendChild(sideLinks); + sidebar.insertBefore(head, sidebar.firstChild); + } } function addEyebrow() { diff --git a/assets/base.css b/assets/base.css index c277b1b..1622437 100644 --- a/assets/base.css +++ b/assets/base.css @@ -1416,7 +1416,7 @@ html.dark .search-footer { .mobile-tabs { display: block; - margin-top: 50px; + margin-top: 8px; } body.nav-open #theme-seg { @@ -1445,16 +1445,16 @@ html.dark .search-footer { #sidebar { position: fixed; left: 0; - top: var(--sidebar-top, var(--header-height)); + top: 0; width: 80%; max-width: 340px; - height: calc(100vh - var(--sidebar-top, var(--header-height))); - height: calc(100dvh - var(--sidebar-top, var(--header-height))); - padding: 20px 16px; + height: 100vh; + height: 100dvh; + padding: 0 16px 20px; background: var(--bg-light); transform: translateX(-100%); transition: transform 0.2s ease; - z-index: 30; + z-index: 200; } html.dark #sidebar { @@ -1498,4 +1498,37 @@ main.prose p { main.prose p, main.prose li { line-height: 1.75; +} + +.side-head { + display: none; +} + +@media (max-width: 900px) { + .side-head { + display: flex; + align-items: center; + justify-content: space-between; + height: 60px; + margin: 0 -16px 12px; + padding: 0 20px; + } + + #sidebar .side-head .brand { + display: flex; + align-items: center; + } + + #sidebar .side-head .brand img { + height: 28px; + width: 28px; + border-radius: 50%; + display: block; + } + + #sidebar .side-links { + display: flex; + align-items: center; + gap: 10px; + } } \ No newline at end of file