# Progressive Web App (PWA) Guide (Bahasa Melayu) 🌐 **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) · 🇲🇹 [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) --- OmniRoute diedarkan sebagai Progressive Web App yang boleh dipasang sepenuhnya. Apabila anda mengakses papan pemuka daripada mana-mana pelayar mudah alih — Android (Chrome) atau iOS (Safari) — anda boleh memilih "Tambah ke Skrin Utama" dan menikmati pengalaman seperti aplikasi natif tanpa memerlukan gedung aplikasi. ## Apakah Itu PWA? Progressive Web App mengubah papan pemuka web OmniRoute menjadi sesuatu yang kelihatan dan berfungsi seperti aplikasi mudah alih natif. Setelah dipasang, aplikasi ini: - Dilancarkan daripada skrin utama anda dengan ikonnya sendiri - Dibuka dalam skrin penuh — tanpa bar alamat pelayar atau UI tab - Berfungsi di luar talian dengan halaman kesambungan khusus - Menyimpan aset statik dalam cache untuk pemuatan yang lebih pantas - Menyokong orientasi potret dan landskap ## Pemasangan ### Android (Chrome) 1. Buka papan pemuka OmniRoute dalam Chrome: `http://YOUR_IP:20128` 2. Chrome akan memaparkan sepanduk **"Tambah OmniRoute ke Skrin utama"** secara automatik, atau: - Ketik menu **⋮** (tiga titik) → **"Tambah ke Skrin utama"** atau **"Pasang aplikasi"** 3. Sahkan gesaan tersebut 4. OmniRoute muncul pada skrin utama anda sebagai aplikasi kendiri ### iOS (Safari) 1. Buka papan pemuka OmniRoute dalam Safari: `http://YOUR_IP:20128` 2. Ketik butang **Kongsi** (kotak dengan anak panah) 3. Tatal ke bawah dan ketik **"Tambah ke Skrin Utama"** 4. Berikan nama (lalainya ialah "OmniRoute") dan ketik **Tambah** 5. OmniRoute muncul pada skrin utama anda dengan ikon aplikasi ### Desktop (Chrome / Edge) 1. Buka papan pemuka OmniRoute 2. Klik **ikon pemasangan** dalam bar alamat (atau ⋮ → "Pasang OmniRoute...") 3. Sahkan gesaan tersebut 4. OmniRoute dibuka sebagai tetingkap kendiri — tanpa tab, tanpa bar alamat ## Ciri-ciri ### Pengalaman Skrin Penuh Manifes dikonfigurasikan dengan `display: "fullscreen"`, yang bermaksud aplikasi yang dipasang menggunakan keseluruhan skrin — tanpa elemen pelayar, tanpa tindihan bar status. Ini menjadikan papan pemuka benar-benar terasa seperti aplikasi natif. ### Sokongan Luar Talian OmniRoute menyertakan service worker (`sw.js`) yang menyediakan pengurusan cache pintar: | Jenis Aset | Strategi | Tingkah Laku | | ------------------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | | **Cangkerang aplikasi** | Utamakan cache | `/`, `/offline`, manifes dan ikon dipracache semasa pemasangan | | **Aset statik** (CSS, JS, imej, fon) | Utamakan rangkaian dengan sandaran cache | Mengambil versi terkini daripada rangkaian; menggunakan cache jika di luar talian | | **Himpunan Next.js** (`/_next/`) | Utamakan rangkaian dengan kemas kini cache | Mengambil daripada rangkaian dan mengemas kini cache; menyediakan versi cache jika di luar talian | | **Permintaan navigasi** | Pintas (tidak pernah dipintas) | Pelayar mengendalikan penggunaan sandaran HTTP/3→HTTP/2; soket QUIC yang tidak aktif tidak boleh menjadi `Response.error()` | | **Laluan API / papan pemuka** (`/api/`, `/a2a`, `/dashboard`) | Pintas (tidak pernah dicache) | Sentiasa dihantar terus kepada pelayan — tidak pernah dipintas oleh service worker | ### Halaman Luar Talian Apabila rangkaian tidak tersedia dan pengguna menavigasi ke halaman baharu, service worker menyediakan halaman `/offline` khusus yang: - Memaparkan mesej **"Isu Kesambungan"** yang jelas - Menunjukkan **penunjuk status dalam talian/luar talian** secara langsung yang dikemas kini dalam masa nyata - Menyediakan butang **"Cuba Sambungan Semula"** untuk memuatkan semula apabila kesambungan pulih - Memaut ke **Halaman Status** untuk diagnostik ### Ikon Aplikasi OmniRoute menyediakan ikon yang dioptimumkan untuk setiap platform: | Fail | Saiz | Digunakan Oleh | | ---------------------- | ---------------- | ----------------------------------------- | | `icon-512.png` | 512×512 | Gesaan pemasangan Android, skrin percikan | | `apple-touch-icon.png` | 180×180 | Ikon skrin utama iOS | | `icon-192.svg` | 192×192 (vektor) | Ikon adaptif Android | | `apple-touch-icon.svg` | 180×180 (vektor) | Sandaran Apple | | `favicon.svg` | Vektor | Tab pelayar | | `favicon.ico` | Pelbagai saiz | Pelayar lama | ### Pendaftaran Automatik Service worker didaftarkan secara automatik melalui komponen `` dalam reka letak akar. Tiada tindakan pengguna diperlukan — aplikasi boleh dipasang sebaik sahaja pelayar mengesan manifes dan service worker yang sah. ## Seni Bina Teknikal ### Manifes Aplikasi Web (`manifest.webmanifest`) Dijana oleh Next.js melalui `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`) Service worker biasa (tanpa kebergantungan rangka kerja) dengan: - **Fasa pemasangan**: Melakukan pracache bagi kerangka aplikasi (akar, halaman luar talian, manifes, ikon) - **Fasa pengaktifan**: Membersihkan versi cache lama dan mengambil alih semua klien - **Fasa pengambilan**: Penghalaan pintar berdasarkan jenis permintaan (navigasi, aset statik, API) - **Pemversian cache**: `omniroute-pwa-v3` — tingkatkan versi ini untuk memaksa cache baharu semasa kemas kini ### Metadata Tataletak (`src/app/layout.tsx`) Tataletak akar menyediakan semua tag meta yang diperlukan untuk pematuhan PWA: - Pautan `manifest` ke `/manifest.webmanifest` - `apple-web-app-capable: true` untuk mod kendiri iOS - `apple-web-app-status-bar-style: black-translucent` - `mobile-web-app-capable: yes` untuk Chrome pada Android - `theme-color: #0b0f1a` - `viewport-fit: cover` untuk pemaparan dari tepi ke tepi ### Komponen: `PwaRegister` Terletak di `src/shared/components/PwaRegister.tsx`, komponen klien ini: 1. Dijalankan semasa pelekapan (sebelah klien sahaja) 2. Memeriksa sokongan `serviceWorker` dalam pelayar 3. Mendaftarkan `/sw.js` secara senyap (ralat diabaikan untuk mengelakkan aplikasi daripada disekat) 4. Tidak memaparkan apa-apa (`return null`) — komponen ini hanya menghasilkan kesan sampingan ## Penggunaan Dengan Termux (Android) Apabila menjalankan OmniRoute pada Android melalui Termux, PWA berfungsi dengan lancar: 1. Mulakan OmniRoute dalam Termux: `npx omniroute` 2. Buka Chrome pada telefon yang sama: `http://localhost:20128` 3. Pasang PWA melalui "Tambah pada Skrin Utama" 4. PWA bersambung ke pelayan Termux setempat — semuanya dijalankan pada peranti Gabungan ini bermakna telefon Android anda ialah **pelayan** (Termux) dan juga **klien** (PWA) — sebuah gerbang AI lengkap dan serba lengkap. ## Penggunaan Dari Peranti Lain Pasang PWA pada mana-mana peranti yang mempunyai akses pelayar ke pelayan OmniRoute anda: - **Telefon/tablet lain**: Navigasi ke `http://PHONE_IP:20128` dan pasang PWA - **Komputer riba**: Buka Chrome/Edge dan pasangkannya sebagai PWA desktop - **TV pintar dengan pelayar**: Akses papan pemuka dalam skrin penuh ## Penyesuaian ### Nama Instans Tajuk PWA mematuhi tetapan **Nama Instans** daripada `Papan Pemuka → Tetapan`. Jika anda menamakan semula instans anda kepada "Gerbang AI Saya", PWA yang dipasang akan memaparkan nama tersebut. ### Favicon Tersuai Jika anda memuat naik favicon tersuai melalui `Papan Pemuka → Tetapan`, ikon PWA pada desktop akan mencerminkan ikon tersuai tersebut. Ikon skrin utama mudah alih menggunakan fail `icon-512.png` dan `apple-touch-icon.png` yang telah dibina terlebih dahulu. ## Batasan - **Tiada pemberitahuan push** — Service worker tidak melaksanakan Push API. Sebaliknya, pemberitahuan dikendalikan oleh aplikasi Electron. - **Tiada penyegerakan latar belakang** — Tindakan luar talian tidak dibariskan untuk dimainkan semula. PWA ini terutamanya berfungsi sebagai pemapar papan pemuka. - **Sekatan iOS** — Safari pada iOS tidak menyokong semua ciri PWA (contohnya, gesaan pemasangan perlu dilakukan secara manual dan service worker latar belakang adalah terhad). - **Saiz cache** — Service worker hanya menyimpan aset statik dalam cache. Muatan respons yang besar daripada laluan `/api/` tidak pernah disimpan dalam cache. - **Ikon tersuai pada peranti mudah alih** — Menukar favicon dalam tetapan tidak mengemas kini ikon skrin utama pada peranti mudah alih (ini memerlukan ikon PWA dijana semula). ## Rujukan Fail | Fail | Tujuan | | --------------------------------------- | ---------------------------------------------------------------------- | | `src/app/manifest.ts` | Laluan manifes Next.js (menjana `manifest.webmanifest`) | | `public/sw.js` | Service worker dengan logik cache | | `src/shared/components/PwaRegister.tsx` | Komponen klien yang mendaftarkan service worker | | `src/app/offline/page.tsx` | Halaman sandaran luar talian dengan penunjuk status masa nyata | | `src/app/layout.tsx` | Susun atur akar dengan metadata PWA (apple-web-app, theme-color, dll.) | | `public/icon-512.png` | Ikon PNG 512×512 (Android, skrin percikan) | | `public/apple-touch-icon.png` | Ikon PNG 180×180 (skrin utama iOS) | | `public/icon-192.svg` | Ikon SVG 192×192 (adaptif Android) | | `public/apple-touch-icon.svg` | Ikon SVG 180×180 (sandaran Apple) |