# Progressive Web App (PWA) Guide (Română) 🌐 **Languages:** 🇺🇸 [English](../../../../guides/PWA_GUIDE.md) · 🇪🇹 [am](../../../am/docs/guides/PWA_GUIDE.md) · 🇸🇦 [ar](../../../ar/docs/guides/PWA_GUIDE.md) · 🇦🇿 [az](../../../az/docs/guides/PWA_GUIDE.md) · 🇧🇬 [bg](../../../bg/docs/guides/PWA_GUIDE.md) · 🇧🇩 [bn](../../../bn/docs/guides/PWA_GUIDE.md) · 🇧🇦 [bs](../../../bs/docs/guides/PWA_GUIDE.md) · 🇨🇿 [cs](../../../cs/docs/guides/PWA_GUIDE.md) · 🇩🇰 [da](../../../da/docs/guides/PWA_GUIDE.md) · 🇩🇪 [de](../../../de/docs/guides/PWA_GUIDE.md) · 🇬🇷 [el](../../../el/docs/guides/PWA_GUIDE.md) · 🇪🇸 [es](../../../es/docs/guides/PWA_GUIDE.md) · 🇪🇪 [et](../../../et/docs/guides/PWA_GUIDE.md) · 🇮🇷 [fa](../../../fa/docs/guides/PWA_GUIDE.md) · 🇫🇮 [fi](../../../fi/docs/guides/PWA_GUIDE.md) · 🇫🇷 [fr](../../../fr/docs/guides/PWA_GUIDE.md) · 🇮🇪 [ga](../../../ga/docs/guides/PWA_GUIDE.md) · 🇮🇳 [gu](../../../gu/docs/guides/PWA_GUIDE.md) · 🇳🇬 [ha](../../../ha/docs/guides/PWA_GUIDE.md) · 🇮🇱 [he](../../../he/docs/guides/PWA_GUIDE.md) · 🇮🇳 [hi](../../../hi/docs/guides/PWA_GUIDE.md) · 🇭🇷 [hr](../../../hr/docs/guides/PWA_GUIDE.md) · 🇭🇺 [hu](../../../hu/docs/guides/PWA_GUIDE.md) · 🇦🇲 [hy](../../../hy/docs/guides/PWA_GUIDE.md) · 🇮🇩 [id](../../../id/docs/guides/PWA_GUIDE.md) · 🇳🇬 [ig](../../../ig/docs/guides/PWA_GUIDE.md) · 🇮🇹 [it](../../../it/docs/guides/PWA_GUIDE.md) · 🇯🇵 [ja](../../../ja/docs/guides/PWA_GUIDE.md) · 🇬🇪 [ka](../../../ka/docs/guides/PWA_GUIDE.md) · 🇰🇭 [km](../../../km/docs/guides/PWA_GUIDE.md) · 🇮🇳 [kn](../../../kn/docs/guides/PWA_GUIDE.md) · 🇰🇷 [ko](../../../ko/docs/guides/PWA_GUIDE.md) · 🇱🇹 [lt](../../../lt/docs/guides/PWA_GUIDE.md) · 🇱🇻 [lv](../../../lv/docs/guides/PWA_GUIDE.md) · 🇮🇳 [ml](../../../ml/docs/guides/PWA_GUIDE.md) · 🇮🇳 [mr](../../../mr/docs/guides/PWA_GUIDE.md) · 🇲🇾 [ms](../../../ms/docs/guides/PWA_GUIDE.md) · 🇲🇹 [mt](../../../mt/docs/guides/PWA_GUIDE.md) · 🇲🇲 [my](../../../my/docs/guides/PWA_GUIDE.md) · 🇳🇵 [ne](../../../ne/docs/guides/PWA_GUIDE.md) · 🇳🇱 [nl](../../../nl/docs/guides/PWA_GUIDE.md) · 🇳🇴 [no](../../../no/docs/guides/PWA_GUIDE.md) · 🇮🇳 [or](../../../or/docs/guides/PWA_GUIDE.md) · 🇮🇳 [pa](../../../pa/docs/guides/PWA_GUIDE.md) · 🇵🇭 [phi](../../../phi/docs/guides/PWA_GUIDE.md) · 🇵🇱 [pl](../../../pl/docs/guides/PWA_GUIDE.md) · 🇵🇹 [pt](../../../pt/docs/guides/PWA_GUIDE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/guides/PWA_GUIDE.md) · 🇷🇺 [ru](../../../ru/docs/guides/PWA_GUIDE.md) · 🇱🇰 [si](../../../si/docs/guides/PWA_GUIDE.md) · 🇸🇰 [sk](../../../sk/docs/guides/PWA_GUIDE.md) · 🇸🇮 [sl](../../../sl/docs/guides/PWA_GUIDE.md) · 🇷🇸 [sr](../../../sr/docs/guides/PWA_GUIDE.md) · 🇸🇪 [sv](../../../sv/docs/guides/PWA_GUIDE.md) · 🇰🇪 [sw](../../../sw/docs/guides/PWA_GUIDE.md) · 🇮🇳 [ta](../../../ta/docs/guides/PWA_GUIDE.md) · 🇮🇳 [te](../../../te/docs/guides/PWA_GUIDE.md) · 🇹🇭 [th](../../../th/docs/guides/PWA_GUIDE.md) · 🇹🇷 [tr](../../../tr/docs/guides/PWA_GUIDE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/guides/PWA_GUIDE.md) · 🇵🇰 [ur](../../../ur/docs/guides/PWA_GUIDE.md) · 🇺🇿 [uz](../../../uz/docs/guides/PWA_GUIDE.md) · 🇻🇳 [vi](../../../vi/docs/guides/PWA_GUIDE.md) · 🇳🇬 [yo](../../../yo/docs/guides/PWA_GUIDE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/guides/PWA_GUIDE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/guides/PWA_GUIDE.md) --- OmniRoute este livrată ca o aplicație web progresivă complet instalabilă. Când accesați panoul de control din orice browser mobil — Android (Chrome) sau iOS (Safari) — puteți selecta „Adăugați pe ecranul principal” și beneficia de o experiență similară unei aplicații native, fără a fi necesar un magazin de aplicații. ## Ce este o PWA? O aplicație web progresivă transformă panoul de control web OmniRoute într-o aplicație care arată și se comportă ca o aplicație mobilă nativă. După instalare, aceasta: - Pornește de pe ecranul principal cu propria pictogramă - Se deschide pe tot ecranul — fără bara de adrese sau interfața cu file a browserului - Funcționează offline, cu o pagină dedicată pentru conectivitate - Stochează în cache resursele statice pentru o încărcare mai rapidă - Acceptă atât orientarea portret, cât și orientarea peisaj ## Instalare ### Android (Chrome) 1. Deschideți panoul de control OmniRoute în Chrome: `http://YOUR_IP:20128` 2. Chrome va afișa automat bannerul **„Adăugați OmniRoute pe ecranul principal”** sau: - Atingeți meniul **⋮** (trei puncte) → **„Adăugați pe ecranul principal”** sau **„Instalați aplicația”** 3. Confirmați solicitarea 4. OmniRoute apare pe ecranul principal ca aplicație autonomă ### iOS (Safari) 1. Deschideți panoul de control OmniRoute în Safari: `http://YOUR_IP:20128` 2. Atingeți butonul **Partajare** (caseta cu săgeată) 3. Derulați în jos și atingeți **„Adăugați pe ecranul principal”** 4. Alegeți un nume (implicit este „OmniRoute”) și atingeți **Adăugați** 5. OmniRoute apare pe ecranul principal cu pictograma aplicației ### Desktop (Chrome / Edge) 1. Deschideți panoul de control OmniRoute 2. Faceți clic pe **pictograma de instalare** din bara de adrese (sau ⋮ → „Instalați OmniRoute...”) 3. Confirmați solicitarea 4. OmniRoute se deschide într-o fereastră autonomă — fără file și fără bară de adrese ## Funcționalități ### Experiență pe tot ecranul Manifestul este configurat cu `display: "fullscreen"`, ceea ce înseamnă că aplicația instalată utilizează întregul ecran — fără interfața browserului și fără suprapunerea barei de stare. Astfel, panoul de control oferă o experiență cu adevărat nativă. ### Compatibilitate offline OmniRoute include un service worker (`sw.js`) care asigură stocarea inteligentă în cache: | Tip de resursă | Strategie | Comportament | | ---------------------------------------------------------------------- | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | **Structura aplicației** | Mai întâi cache-ul | `/`, `/offline`, manifestul și pictogramele sunt stocate în cache la instalare | | **Resurse statice** (CSS, JS, imagini, fonturi) | Mai întâi rețeaua, cu revenire la cache | Preia versiunea recentă din rețea; revine la cache dacă este offline | | **Pachete Next.js** (`/_next/`) | Mai întâi rețeaua, cu actualizarea cache-ului | Preia din rețea și actualizează cache-ul; furnizează versiunea din cache dacă este offline | | **Solicitări de navigare** | Ocolire (nu sunt interceptate niciodată) | Browserul gestionează revenirea de la HTTP/3 la HTTP/2; un socket QUIC nefuncțional nu trebuie să devină `Response.error()` | | **Rute API / ale panoului de control** (`/api/`, `/a2a`, `/dashboard`) | Ocolire (nu sunt stocate niciodată în cache) | Ajung întotdeauna direct la server — nu sunt interceptate niciodată de service worker | ### Pagina offline Când rețeaua nu este disponibilă și un utilizator navighează la o pagină nouă, service worker-ul furnizează o pagină `/offline` dedicată care: - Afișează un mesaj clar **„Problemă de conectivitate”** - Afișează un **indicator de stare online/offline** în timp real - Oferă un buton **„Reîncercați conexiunea”** pentru reîncărcare atunci când conexiunea revine - Include un link către **Pagina de stare** pentru diagnosticare ### Pictogramele aplicației OmniRoute oferă pictograme optimizate pentru fiecare platformă: | Fișier | Dimensiune | Utilizat de | | ---------------------- | -------------------- | ---------------------------------------------------- | | `icon-512.png` | 512×512 | Solicitarea de instalare Android, ecranul de pornire | | `apple-touch-icon.png` | 180×180 | Pictograma de pe ecranul principal iOS | | `icon-192.svg` | 192×192 (vectorială) | Pictograma adaptivă Android | | `apple-touch-icon.svg` | 180×180 (vectorială) | Alternativa pentru Apple | | `favicon.svg` | Vectorială | Filele browserului | | `favicon.ico` | Dimensiuni multiple | Browsere mai vechi | ### Înregistrare automată Service worker-ul este înregistrat automat prin intermediul componentei `` din aspectul rădăcină. Nu este necesară nicio acțiune din partea utilizatorului — aplicația devine instalabilă imediat ce browserul detectează manifestul valid și service worker-ul. ## Arhitectură tehnică ### Manifestul aplicației web (`manifest.webmanifest`) Generat de Next.js prin `src/app/manifest.ts`: ```json { "name": "OmniRoute", "short_name": "OmniRoute", "description": "OmniRoute is an AI gateway for multi-provider LLMs. One endpoint for all your AI providers.", "start_url": "/", "scope": "/", "display": "fullscreen", "orientation": "any", "background_color": "#0b0f1a", "theme_color": "#0b0f1a", "icons": [ { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }, { "src": "/apple-touch-icon.png", "sizes": "180x180", "type": "image/png" } ] } ``` ### Service Worker (`public/sw.js`) Un service worker standard (fără dependențe de framework), cu: - **Faza de instalare**: Pre-memorează în cache shell-ul aplicației (pagina rădăcină, pagina offline, manifestul și pictogramele) - **Faza de activare**: Elimină versiunile vechi din cache și preia controlul asupra tuturor clienților - **Faza de preluare**: Rutare inteligentă în funcție de tipul solicitării (navigare, resursă statică, API) - **Versionarea cache-ului**: `omniroute-pwa-v3` — incrementați această versiune pentru a forța recrearea cache-ului la actualizare ### Metadatele layoutului (`src/app/layout.tsx`) Layoutul rădăcină furnizează toate metaetichetele necesare pentru compatibilitatea PWA: - Linkul `manifest` către `/manifest.webmanifest` - `apple-web-app-capable: true` pentru modul autonom pe iOS - `apple-web-app-status-bar-style: black-translucent` - `mobile-web-app-capable: yes` pentru Chrome pe Android - `theme-color: #0b0f1a` - `viewport-fit: cover` pentru randarea de la o margine la alta ### Componenta: `PwaRegister` Aflată în `src/shared/components/PwaRegister.tsx`, această componentă client: 1. Rulează la montare (doar pe partea de client) 2. Verifică dacă browserul oferă suport pentru `serviceWorker` 3. Înregistrează `/sw.js` silențios (erorile sunt ignorate pentru a evita blocarea aplicației) 4. Nu randează nimic (`return null`) — este o componentă utilizată exclusiv pentru efecte secundare ## Utilizarea cu Termux (Android) Când OmniRoute rulează pe Android prin Termux, PWA-ul funcționează fără probleme: 1. Porniți OmniRoute în Termux: `npx omniroute` 2. Deschideți Chrome pe același telefon: `http://localhost:20128` 3. Instalați PWA-ul prin „Adăugați pe ecranul de pornire” 4. PWA-ul se conectează la serverul Termux local — totul rulează pe dispozitiv Această combinație înseamnă că telefonul Android este atât **serverul** (Termux), cât și **clientul** (PWA) — un gateway AI complet autonom. ## Utilizarea de pe alte dispozitive Instalați PWA-ul pe orice dispozitiv care are acces prin browser la serverul OmniRoute: - **Alt telefon/altă tabletă**: Accesați `http://PHONE_IP:20128` și instalați PWA-ul - **Laptop**: Deschideți Chrome/Edge și instalați-l ca PWA pentru desktop - **Smart TV cu browser**: Accesați panoul de control în modul ecran complet ## Personalizare ### Numele instanței Titlul PWA-ului respectă setarea **Numele instanței** din `Panou de control → Setări`. Dacă redenumiți instanța în „Gateway-ul meu AI”, PWA-ul instalat va afișa acest nume. ### Favicon personalizat Dacă încărcați un favicon personalizat prin `Panou de control → Setări`, pictograma PWA-ului de pe desktop va reflecta pictograma personalizată. Pictogramele de pe ecranul de pornire al dispozitivelor mobile utilizează fișierele predefinite `icon-512.png` și `apple-touch-icon.png`. ## Limitări - **Fără notificări push** — Service worker-ul nu implementează Push API. În schimb, notificările sunt gestionate de aplicația Electron. - **Fără sincronizare în fundal** — Acțiunile offline nu sunt puse în coadă pentru a fi reluate. PWA-ul este în principal un panou de monitorizare. - **Restricții iOS** — Safari pe iOS nu acceptă toate funcționalitățile PWA (de exemplu, solicitările de instalare sunt manuale, iar service worker-ele din fundal sunt limitate). - **Dimensiunea cache-ului** — Service worker-ul memorează în cache doar resursele statice. Volumele mari de date din răspunsurile rutelor `/api/` nu sunt memorate niciodată în cache. - **Pictograme personalizate pe dispozitive mobile** — Schimbarea faviconului în setări nu actualizează pictograma de pe ecranul principal al dispozitivului mobil (acest lucru necesită regenerarea pictogramelor PWA). ## Referință pentru fișiere | Fișier | Scop | | --------------------------------------- | ----------------------------------------------------------------- | | `src/app/manifest.ts` | Ruta de manifest Next.js (generează `manifest.webmanifest`) | | `public/sw.js` | Service worker cu logică de memorare în cache | | `src/shared/components/PwaRegister.tsx` | Componentă client care înregistrează service worker-ul | | `src/app/offline/page.tsx` | Pagină de rezervă offline cu indicator de stare în timp real | | `src/app/layout.tsx` | Layout rădăcină cu metadate PWA (apple-web-app, theme-color etc.) | | `public/icon-512.png` | Pictogramă PNG de 512×512 (Android, ecran de pornire) | | `public/apple-touch-icon.png` | Pictogramă PNG de 180×180 (ecranul principal iOS) | | `public/icon-192.svg` | Pictogramă SVG de 192×192 (pictogramă adaptivă Android) | | `public/apple-touch-icon.svg` | Pictogramă SVG de 180×180 (variantă de rezervă pentru Apple) |