# Progressive Web App (PWA) Guide (Bosanski) 🌐 **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) · 🇨🇿 [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) · 🇷🇴 [ro](../../../ro/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) --- # Vodič za Progressive Web App (PWA) OmniRoute dolazi kao potpuno instalabilna Progressive Web aplikacija. Kada pristupite kontrolnoj tabli iz bilo kojeg mobilnog pretraživača — Android (Chrome) ili iOS (Safari) — možete odabrati "Dodaj na početni ekran" (Add to Home Screen) i dobiti iskustvo slično izvornoj (native) aplikaciji bez potrebe za prodavnicom aplikacija. ## Šta je PWA? Progressive Web aplikacija pretvara OmniRoute web kontrolnu tablu u nešto što izgleda i djeluje kao izvorna mobilna aplikacija. Jednom instalirana, ona: - Pokreće se sa vašeg početnog ekrana sa svojom ikonicom - Otvara se preko cijelog ekrana — bez adresne trake pretraživača ili korisničkog interfejsa sa karticama - Radi van mreže (offline) sa namjenskom stranicom za povezivanje - Kešira statičke resurse za brže učitavanje - Podržava i portretnu i pejzažnu orijentaciju ## Instalacija ### Android (Chrome) 1. Otvorite OmniRoute kontrolnu tablu u Chrome-u: `http://YOUR_IP:20128` 2. Chrome će automatski prikazati baner **"Dodaj OmniRoute na početni ekran"**, ili: - Dodirnite meni **⋮** (tri tačke) → **"Dodaj na početni ekran"** ili **"Instaliraj aplikaciju"** 3. Potvrdite upit 4. OmniRoute se pojavljuje na vašem početnom ekranu kao samostalna aplikacija ### iOS (Safari) 1. Otvorite OmniRoute kontrolnu tablu u Safari-ju: `http://YOUR_IP:20128` 2. Dodirnite dugme **Dijeli** (kvadrat sa strelicom) 3. Skrolujte dole i dodirnite **"Dodaj na početni ekran"** 4. Imenujte je (podrazumijevano je "OmniRoute") i dodirnite **Dodaj** 5. OmniRoute se pojavljuje na vašem početnom ekranu sa ikonicom aplikacije ### Desktop (Chrome / Edge) 1. Otvorite OmniRoute kontrolnu tablu 2. Kliknite na **ikonu za instalaciju** u adresnoj traci (ili ⋮ → "Instaliraj OmniRoute...") 3. Potvrdite upit 4. OmniRoute se otvara kao samostalan prozor — bez kartica, bez adresne trake ## Funkcionalnosti ### Iskustvo preko cijelog ekrana Manifest je konfigurisan sa `display: "fullscreen"`, što znači da instalirana aplikacija koristi cijeli ekran — bez hroma pretraživača, bez preklapanja statusne trake. Zbog toga kontrolna tabla djeluje zaista izvorno (native). ### Offline podrška OmniRoute uključuje service worker (`sw.js`) koji omogućava inteligentno keširanje: | Tip resursa | Strategija | Ponašanje | | -------------------------------------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | | **App Shell** | Prvo keš (Cache-first) | `/`, `/offline`, manifest i ikonice se unaprijed keširaju pri instalaciji | | **Statički resursi** (CSS, JS, slike, fontovi) | Prvo mreža sa rezervom u kešu (Network-first with cache fallback) | Dohvata svježe podatke sa mreže; vraća se na keš ako je offline | | **Next.js paketi** (`/_next/`) | Prvo mreža sa ažuriranjem keša (Network-first with cache update) | Dohvata sa mreže i ažurira keš; servira keširanu verziju ako je offline | | **Navigacioni zahtjevi** | Zaobilaženje (nikada se ne presreću) | Pretraživač upravlja HTTP/3→HTTP/2 rezervom; mrtav QUIC socket ne smije postati `Response.error()` | | **API / rute kontrolne table** (`/api/`, `/a2a`, `/dashboard`) | Zaobilaženje (nikada se ne kešira) | Uvijek ide direktno na server — nikada se ne presreće od strane service workera | ### Offline stranica Kada mreža nije dostupna i korisnik pređe na novu stranicu, service worker servira namjensku `/offline` stranicu koja: - Prikazuje jasnu poruku **"Problem sa povezivanjem"** - Prikazuje indikator statusa **online/offline** uživo koji se ažurira u realnom vremenu - Pruža dugme **"Pokušaj ponovo"** za ponovno učitavanje kada se veza uspostavi - Linkuje ka **Stranici statusa** za dijagnostiku ### Ikonice aplikacije OmniRoute pruža ikonice optimizovane za svaku platformu: | Datoteka | Veličina | Koristi se za | | ---------------------- | ---------------- | ----------------------------------------- | | `icon-512.png` | 512×512 | Android upit za instalaciju, splash ekran | | `apple-touch-icon.png` | 180×180 | iOS ikonica početnog ekrana | | `icon-192.svg` | 192×192 (vektor) | Android adaptivna ikonica | | `apple-touch-icon.svg` | 180×180 (vektor) | Apple rezerva | | `favicon.svg` | Vektor | Kartice pretraživača | | `favicon.ico` | Više veličina | Stariji pretraživači | ### Automatska registracija Service worker se automatski registruje putem `` komponente u root layout-u. Nije potrebna nikakva akcija korisnika — aplikacija postaje instalabilna čim pretraživač detektuje validan manifest i service worker. ## Tehnička arhitektura ### Web App Manifest (`manifest.webmanifest`) Generisano od strane Next.js putem `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`) Vanilla service worker (bez zavisnosti o frameworku) sa: - **Faza instalacije**: Pre-kešira app shell (root, offline stranicu, manifest, ikonice) - **Faza aktivacije**: Čisti stare verzije keša i preuzima kontrolu nad svim klijentima - **Faza preuzimanja (Fetch)**: Inteligentno rutiranje na osnovu tipa zahtjeva (navigacija, statički resurs, API) - **Verzionisanje keša**: `omniroute-pwa-v3` — povećajte ovo da biste forsirali svjež keš prilikom ažuriranja ### Metapodaci layouta (`src/app/layout.tsx`) Root layout pruža sve meta tagove potrebne za usklađenost sa PWA standardima: - `manifest` link ka `/manifest.webmanifest` - `apple-web-app-capable: true` za iOS samostalni (standalone) režim - `apple-web-app-status-bar-style: black-translucent` - `mobile-web-app-capable: yes` za Android Chrome - `theme-color: #0b0f1a` - `viewport-fit: cover` za prikaz od ivice do ivice (edge-to-edge) ### Komponenta: `PwaRegister` Nalazi se na `src/shared/components/PwaRegister.tsx`, ova klijentska komponenta: 1. Pokreće se prilikom montiranja (samo na strani klijenta) 2. Provjerava podršku za `serviceWorker` u pregledniku 3. Tiho registruje `/sw.js` (greške se zanemaruju kako bi se izbjeglo blokiranje aplikacije) 4. Ne renderuje ništa (`return null`) — to je komponenta isključivo za sporedne efekte (side-effects) ## Korištenje sa Termux-om (Android) Kada pokrećete OmniRoute na Androidu putem Termux-a, PWA radi besprijekorno: 1. Pokrenite OmniRoute u Termux-u: `npx omniroute` 2. Otvorite Chrome na istom telefonu: `http://localhost:20128` 3. Instalirajte PWA putem "Add to Home Screen" 4. PWA se povezuje sa lokalnim Termux serverom — sve se pokreće na samom uređaju Ova kombinacija znači da je vaš Android telefon istovremeno i server (Termux) i klijent (PWA) — kompletan samostalan AI gateway. ## Korištenje sa drugih uređaja Instalirajte PWA na bilo koji uređaj koji ima pristup vašem OmniRoute serveru putem preglednika: - **Drugi telefon/tablet**: Idite na `http://PHONE_IP:20128` i instalirajte PWA - **Laptop**: Otvorite Chrome/Edge i instalirajte ga kao desktop PWA - **Smart TV sa preglednikom**: Pristupite kontrolnoj tabli preko cijelog ekrana ## Prilagođavanje ### Ime instance Naslov PWA aplikacije poštuje postavku **Instance Name** iz `Dashboard → Settings`. Ako preimenujete svoju instancu u "My AI Gateway", instalirani PWA će prikazivati to ime. ### Prilagođeni Favicon Ako otpremite prilagođeni favicon putem `Dashboard → Settings`, PWA ikonica na desktopu će odražavati tu prilagođenu ikonicu. Ikonice na početnom ekranu mobilnih uređaja koriste unaprijed pripremljene `icon-512.png` i `apple-touch-icon.png` datoteke. ## Ograničenja - **Nema push obavijesti** — Service worker ne implementira Push API. Obavijesti umjesto toga obrađuje Electron aplikacija. - **Nema pozadinske sinhronizacije** — Radnje van mreže (offline) se ne stavljaju u red za ponovno izvršavanje. PWA je prvenstveno preglednik kontrolne ploče. - **iOS ograničenja** — Safari na iOS-u ne podržava sve PWA funkcije (npr. upiti za instalaciju su ručni, a pozadinski service worker-i su ograničeni). - **Veličina predmemorije** — Service worker predmemorira samo statičke resurse. Veliki payload-i odgovora sa `/api/` ruta se nikada ne predmemoriraju. - **Prilagođene ikone na mobilnim uređajima** — Promjena favicon-a u postavkama ne ažurira ikonu na početnom ekranu na mobilnom uređaju (ovo zahtijeva ponovno generiranje PWA ikona). ## Pregled datoteka | Datoteka | Namjena | | --------------------------------------- | ------------------------------------------------------------------------ | | `src/app/manifest.ts` | Next.js manifest ruta (generiše `manifest.webmanifest`) | | `public/sw.js` | Service worker sa logikom predmemoriranja | | `src/shared/components/PwaRegister.tsx` | Klijentska komponenta koja registruje service worker | | `src/app/offline/page.tsx` | Offline rezervna stranica sa indikatorom statusa uživo | | `src/app/layout.tsx` | Korijenski layout sa PWA metapodacima (apple-web-app, theme-color, itd.) | | `public/icon-512.png` | 512×512 PNG ikona (Android, splash ekran) | | `public/apple-touch-icon.png` | 180×180 PNG ikona (iOS početni ekran) | | `public/icon-192.svg` | 192×192 SVG ikona (Android adaptivna) | | `public/apple-touch-icon.svg` | 180×180 SVG ikona (Apple rezervna) |