From 5981f9ff02dd07d94d73d91d398d094bb21e2de4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Feb 2026 06:59:49 +0000 Subject: [PATCH 1/4] Initial plan From 425b1da9572575c2c2e8aa4dcd293e298131a06a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Feb 2026 07:02:30 +0000 Subject: [PATCH 2/4] Add PWA functionality with manifest, service worker, and meta tags Co-authored-by: sriail <225764385+sriail@users.noreply.github.com> --- manifest.json | 35 ++++++++++ sw.js | 78 +++++++++++++++++++++ worker.js | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 manifest.json create mode 100644 sw.js diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..232f3f7 --- /dev/null +++ b/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "CloudMoon InPlay", + "short_name": "CloudMoon", + "description": "Play Roblox, Fortnite, Call of Duty Mobile, Delta Force, and more in your browser", + "start_url": "/", + "display": "standalone", + "background_color": "#0d1117", + "theme_color": "#2d2d2d", + "orientation": "any", + "scope": "/", + "icons": [ + { + "src": "data:image/svg+xml,", + "sizes": "512x512", + "type": "image/svg+xml", + "purpose": "any maskable" + } + ], + "categories": ["games", "entertainment"], + "screenshots": [], + "shortcuts": [ + { + "name": "Open CloudMoon", + "short_name": "Play", + "description": "Open CloudMoon gaming library", + "url": "/", + "icons": [ + { + "src": "data:image/svg+xml,", + "sizes": "96x96" + } + ] + } + ] +} diff --git a/sw.js b/sw.js new file mode 100644 index 0000000..037e146 --- /dev/null +++ b/sw.js @@ -0,0 +1,78 @@ +// CloudMoon InPlay Service Worker +const CACHE_NAME = 'cloudmoon-v1'; +const RUNTIME_CACHE = 'cloudmoon-runtime'; + +// Install event - cache essential resources +self.addEventListener('install', (event) => { + console.log('[ServiceWorker] Install'); + event.waitUntil( + caches.open(CACHE_NAME).then((cache) => { + console.log('[ServiceWorker] Caching app shell'); + return cache.addAll([ + '/', + ]); + }).then(() => { + return self.skipWaiting(); + }) + ); +}); + +// Activate event - clean up old caches +self.addEventListener('activate', (event) => { + console.log('[ServiceWorker] Activate'); + event.waitUntil( + caches.keys().then((cacheNames) => { + return Promise.all( + cacheNames.map((cacheName) => { + if (cacheName !== CACHE_NAME && cacheName !== RUNTIME_CACHE) { + console.log('[ServiceWorker] Removing old cache', cacheName); + return caches.delete(cacheName); + } + }) + ); + }).then(() => { + return self.clients.claim(); + }) + ); +}); + +// Fetch event - network first, fallback to cache +self.addEventListener('fetch', (event) => { + // Skip cross-origin requests + if (!event.request.url.startsWith(self.location.origin)) { + return; + } + + event.respondWith( + fetch(event.request) + .then((response) => { + // If response is valid, clone it and cache it + if (response && response.status === 200) { + const responseToCache = response.clone(); + caches.open(RUNTIME_CACHE).then((cache) => { + cache.put(event.request, responseToCache); + }); + } + return response; + }) + .catch(() => { + // If network fails, try to serve from cache + return caches.match(event.request).then((response) => { + if (response) { + return response; + } + // If not in cache, return a basic offline page + if (event.request.mode === 'navigate') { + return caches.match('/'); + } + }); + }) + ); +}); + +// Handle messages from clients +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting(); + } +}); diff --git a/worker.js b/worker.js index 3957167..c78746e 100644 --- a/worker.js +++ b/worker.js @@ -13,6 +13,23 @@ async function handleRequest(request) { }); } + // Serve manifest.json for PWA + if (url.pathname === '/manifest.json') { + return new Response(getManifest(), { + headers: { 'Content-Type': 'application/json' } + }); + } + + // Serve service worker for PWA + if (url.pathname === '/sw.js') { + return new Response(getServiceWorker(), { + headers: { + 'Content-Type': 'application/javascript', + 'Service-Worker-Allowed': '/' + } + }); + } + // Proxy everything else to CloudMoon return proxyCloudMoon(request); } @@ -177,6 +194,17 @@ function getMainHTML() {