mirror of
https://github.com/danog/telegram-tt.git
synced 2024-12-02 17:48:34 +01:00
1 line
27 KiB
Plaintext
1 line
27 KiB
Plaintext
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/config.ts","webpack:///./src/serviceWorker/progressive.ts","webpack:///./src/util/generateIdFor.ts","webpack:///./src/util/schedulers.ts","webpack:///./src/serviceWorker.ts","webpack:///./src/serviceWorker/assetCache.ts"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","Set","window","innerHeight","requestStates","Map","async","respondForProgressive","e","url","request","range","headers","bytes","exec","start","Number","originalEnd","end","match","fileSize","mimeType","Response","Uint8Array","buffer","status","statusText","cacheKey","cachedArrayBuffer","cachedHeaders","cache","self","caches","open","Promise","all","then","arrayBuffer","undefined","json","fetchFromCache","partInfo","params","clientId","client","clients","messageId","store","id","String","Math","random","replace","generateIdFor","requestState","promise","race","ms","resolve","setTimeout","reject","Error","assign","set","catch","finally","delete","postMessage","type","requestPart","err","process","fullSize","partSize","min","byteLength","arrayBufferPart","slice","put","Request","JSON","stringify","saveToCache","addEventListener","result","data","ASSET_CACHE_PATTERN","waitUntil","skipWaiting","claim","respondWith","includes","startsWith","cached","remote","fetch","clone","respondWithCache","obj","error","text","title","options","body","description","icon","registration","showNotification","event","notification","close","matchAll","windowClients","length","focus","openWindow"],"mappings":"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","file":"serviceWorker.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","export const APP_INFO = process.env.APP_INFO || 'Telegram T';\n\nexport const DEBUG = (\n process.env.APP_ENV !== 'production' && process.env.APP_ENV !== 'perf' && process.env.APP_ENV !== 'test'\n);\nexport const DEBUG_MORE = false;\n\nexport const IS_TEST = process.env.APP_ENV === 'test';\nexport const IS_PERF = process.env.APP_ENV === 'perf';\n\nexport const DEBUG_ALERT_MSG = 'Shoot!\\nSomething went wrong, please see the error details in Dev Tools Console.';\nexport const DEBUG_GRAMJS = false;\n\nexport const GRAMJS_SESSION_ID_KEY = 'GramJs:sessionId';\n\nexport const GLOBAL_STATE_CACHE_DISABLED = false;\nexport const GLOBAL_STATE_CACHE_KEY = 'tt-global-state';\nexport const GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT = 30;\nexport const GLOBAL_STATE_CACHE_USER_LIST_LIMIT = 5000;\n\nexport const MEDIA_CACHE_DISABLED = false;\nexport const MEDIA_CACHE_NAME = 'tt-media';\nexport const MEDIA_CACHE_NAME_AVATARS = 'tt-media-avatars';\nexport const MEDIA_PROGRESSIVE_CACHE_DISABLED = false;\nexport const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive';\nexport const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB\nexport const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';\nexport const LANG_CACHE_NAME = 'tt-lang-packs';\nexport const ASSET_CACHE_NAME = 'tt-assets';\n\nexport const API_UPDATE_THROTTLE = 300;\nexport const API_THROTTLE_RESET_UPDATES = new Set([\n 'newMessage', 'newScheduledMessage', 'deleteMessages', 'deleteScheduledMessages', 'deleteHistory',\n]);\n\nexport const DOWNLOAD_WORKERS = 16;\nexport const UPLOAD_WORKERS = 16;\n\nconst isBigScreen = typeof window !== 'undefined' && window.innerHeight >= 900;\n\nexport const MIN_PASSWORD_LENGTH = 1;\n\nexport const MESSAGE_LIST_SENSITIVE_AREA = 750;\nexport const MESSAGE_LIST_SLICE = isBigScreen ? 60 : 40;\nexport const MESSAGE_LIST_VIEWPORT_LIMIT = MESSAGE_LIST_SLICE * 2;\n\nexport const CHAT_HEIGHT_PX = 72;\nexport const CHAT_LIST_SLICE = isBigScreen ? 30 : 25;\nexport const CHAT_LIST_LOAD_SLICE = 100;\nexport const SHARED_MEDIA_SLICE = 42;\nexport const MESSAGE_SEARCH_SLICE = 42;\nexport const GLOBAL_SEARCH_SLICE = 20;\nexport const CHANNEL_MEMBERS_LIMIT = 30;\nexport const PINNED_MESSAGES_LIMIT = 50;\nexport const BLOCKED_LIST_LIMIT = 100;\n\nexport const TOP_CHAT_MESSAGES_PRELOAD_LIMIT = 25;\nexport const ALL_CHATS_PRELOAD_DISABLED = false;\n\nexport const ANIMATION_LEVEL_MIN = 0;\nexport const ANIMATION_LEVEL_MED = 1;\nexport const ANIMATION_LEVEL_MAX = 2;\nexport const ANIMATION_LEVEL_DEFAULT = ANIMATION_LEVEL_MAX;\n\nexport const DEFAULT_MESSAGE_TEXT_SIZE_PX = 16;\n\nexport const DRAFT_DEBOUNCE = 10000; // 10s\n\nexport const EDITABLE_INPUT_ID = 'editable-message-text';\nexport const EDITABLE_INPUT_MODAL_ID = 'editable-message-text-modal';\n\n// Screen width where Pinned Message / Audio Player in the Middle Header can be safely displayed\nexport const SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN = 1440; // px\n// Screen width where Pinned Message / Audio Player in the Middle Header shouldn't collapse with ChatInfo\nexport const SAFE_SCREEN_WIDTH_FOR_CHAT_INFO = 1150; // px\n\nexport const MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN = 1275; // px\nexport const MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN = 925; // px\nexport const MOBILE_SCREEN_MAX_WIDTH = 600; // px\nexport const MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH = 950; // px\nexport const MOBILE_SCREEN_LANDSCAPE_MAX_HEIGHT = 450; // px\n\nexport const LOCAL_MESSAGE_ID_BASE = 1e9;\n\nexport const ANIMATION_END_DELAY = 100;\n\nexport const STICKER_SIZE_INLINE_DESKTOP_FACTOR = 13;\nexport const STICKER_SIZE_INLINE_MOBILE_FACTOR = 11;\nexport const STICKER_SIZE_AUTH = 160;\nexport const STICKER_SIZE_AUTH_MOBILE = 120;\nexport const STICKER_SIZE_PICKER = 64;\nexport const STICKER_SIZE_GENERAL_SETTINGS = 48;\nexport const STICKER_SIZE_PICKER_HEADER = 32;\nexport const STICKER_SIZE_SEARCH = 64;\nexport const STICKER_SIZE_MODAL = 64;\nexport const STICKER_SIZE_TWO_FA = 160;\nexport const STICKER_SIZE_DISCUSSION_GROUPS = 140;\nexport const STICKER_SIZE_FOLDER_SETTINGS = 80;\nexport const MEMOJI_STICKER_ID = 'MEMOJI_STICKER';\n\nexport const MENU_TRANSITION_DURATION = 200;\nexport const SLIDE_TRANSITION_DURATION = 450;\nexport const LAYERS_TRANSITION_DURATION = 450;\n\nexport const CONTENT_TYPES_FOR_QUICK_UPLOAD = 'image/png,image/gif,image/jpeg,video/mp4,video/avi,video/quicktime';\n\n// eslint-disable-next-line max-len\nexport const RE_LINK_TEMPLATE = '((ftp|https?):\\\\/\\\\/)?((www\\\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\\\.[a-zA-Z0-9()]{1,6})\\\\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)';\nexport const RE_TME_LINK = /^(?:https?:\\/\\/)?(?:t\\.me\\/)([\\d\\w_]+)(?:\\/([\\d]+))?$/gm;\nexport const RE_TME_INVITE_LINK = /^(?:https?:\\/\\/)?(?:t\\.me\\/joinchat\\/)([\\d\\w_]+)?$/gm;\n\n// MTProto constants\nexport const SERVICE_NOTIFICATIONS_USER_ID = 777000;\nexport const ALL_FOLDER_ID = 0;\nexport const ARCHIVED_FOLDER_ID = 1;\nexport const DELETED_COMMENTS_CHANNEL_ID = 777;\nexport const MAX_MEDIA_FILES_FOR_ALBUM = 10;\nexport const MAX_ACTIVE_PINNED_CHATS = 5;\nexport const SCHEDULED_WHEN_ONLINE = 0x7FFFFFFE;\nexport const DEFAULT_LANG_PACK = 'android';\nexport const LANG_PACKS = ['android', 'ios'];\nexport const TIPS_USERNAME = 'TelegramTips';\nexport const FEEDBACK_URL = 'https://bugs.telegram.org/?tag_ids=41&sort=time';\nexport const DARK_THEME_BG_COLOR = '#0F0F0F';\nexport const DARK_THEME_PATTERN_COLOR = '#0a0a0a8c';\nexport const DEFAULT_PATTERN_COLOR = 'rgba(90, 110, 70, 0.6)';\n","import { pause } from '../util/schedulers';\nimport generateIdFor from '../util/generateIdFor';\nimport {\n DEBUG,\n MEDIA_CACHE_MAX_BYTES,\n MEDIA_PROGRESSIVE_CACHE_DISABLED,\n MEDIA_PROGRESSIVE_CACHE_NAME,\n} from '../config';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\ntype PartInfo = {\n type: 'PartInfo';\n arrayBuffer: ArrayBuffer;\n mimeType: 'string';\n fullSize: number;\n};\n\ntype RequestStates = {\n resolve: (response: PartInfo) => void;\n reject: () => void;\n};\n\nconst MB = 1024 * 1024;\nconst DEFAULT_PART_SIZE = 0.5 * MB;\nconst MAX_END_TO_CACHE = 2 * MB - 1; // We only cache the first 2 MB of each file\nconst PART_TIMEOUT = 30000;\n\nconst requestStates = new Map<string, RequestStates>();\n\nexport async function respondForProgressive(e: FetchEvent) {\n const { url } = e.request;\n const range = e.request.headers.get('range');\n const bytes = /^bytes=(\\d+)-(\\d+)?$/g.exec(range || '')!;\n const start = Number(bytes[1]);\n const originalEnd = Number(bytes[2]);\n\n let end = originalEnd;\n if (!end || (end - start + 1) > DEFAULT_PART_SIZE) {\n end = start + DEFAULT_PART_SIZE - 1;\n }\n\n // Optimization for Safari\n if (start === 0 && end === 1) {\n const match = e.request.url.match(/fileSize=(\\d+)&mimeType=([\\w/]+)/);\n const fileSize = match && Number(match[1]);\n const mimeType = match && match[2];\n\n if (fileSize && mimeType) {\n return new Response(new Uint8Array(2).buffer, {\n status: 206,\n statusText: 'Partial Content',\n headers: [\n ['Content-Range', `bytes 0-1/${fileSize}`],\n ['Accept-Ranges', 'bytes'],\n ['Content-Length', '2'],\n ['Content-Type', mimeType],\n ],\n });\n }\n }\n\n const cacheKey = `${url}?start=${start}&end=${end}`;\n const [cachedArrayBuffer, cachedHeaders] = !MEDIA_PROGRESSIVE_CACHE_DISABLED ? await fetchFromCache(cacheKey) : [];\n\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.log(\n `FETCH PROGRESSIVE ${cacheKey} (request: ${start}-${originalEnd}) CACHED: ${Boolean(cachedArrayBuffer)}`,\n );\n }\n\n if (cachedArrayBuffer) {\n return new Response(cachedArrayBuffer, {\n status: 206,\n statusText: 'Partial Content',\n headers: cachedHeaders,\n });\n }\n\n let partInfo;\n try {\n partInfo = await requestPart(e, { url, start, end });\n } catch (err) {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.error('FETCH PROGRESSIVE', err);\n }\n }\n\n if (!partInfo) {\n return new Response('', {\n status: 500,\n statusText: 'Failed to fetch progressive part',\n });\n }\n\n const { arrayBuffer, fullSize, mimeType } = partInfo;\n\n const partSize = Math.min(end - start + 1, arrayBuffer.byteLength);\n end = start + partSize - 1;\n const arrayBufferPart = arrayBuffer.slice(0, partSize);\n const headers = [\n ['Content-Range', `bytes ${start}-${end}/${fullSize}`],\n ['Accept-Ranges', 'bytes'],\n ['Content-Length', String(partSize)],\n ['Content-Type', mimeType],\n ];\n\n if (!MEDIA_PROGRESSIVE_CACHE_DISABLED && partSize <= MEDIA_CACHE_MAX_BYTES && end < MAX_END_TO_CACHE) {\n saveToCache(cacheKey, arrayBufferPart, headers);\n }\n\n return new Response(arrayBufferPart, {\n status: 206,\n statusText: 'Partial Content',\n headers,\n });\n}\n\n// We can not cache 206 responses: https://github.com/GoogleChrome/workbox/issues/1644#issuecomment-638741359\nasync function fetchFromCache(cacheKey: string) {\n const cache = await self.caches.open(MEDIA_PROGRESSIVE_CACHE_NAME);\n\n return Promise.all([\n cache.match(`${cacheKey}&type=arrayBuffer`).then((r) => (r ? r.arrayBuffer() : undefined)),\n cache.match(`${cacheKey}&type=headers`).then((r) => (r ? r.json() : undefined)),\n ]);\n}\n\nasync function saveToCache(cacheKey: string, arrayBuffer: ArrayBuffer, headers: HeadersInit) {\n const cache = await self.caches.open(MEDIA_PROGRESSIVE_CACHE_NAME);\n\n return Promise.all([\n cache.put(new Request(`${cacheKey}&type=arrayBuffer`), new Response(arrayBuffer)),\n cache.put(new Request(`${cacheKey}&type=headers`), new Response(JSON.stringify(headers))),\n ]);\n}\n\nasync function requestPart(\n e: FetchEvent,\n params: { url: string; start: number; end: number },\n): Promise<PartInfo | undefined> {\n if (!e.clientId) {\n return undefined;\n }\n\n // eslint-disable-next-line no-restricted-globals\n const client = await self.clients.get(e.clientId);\n if (!client) {\n return undefined;\n }\n\n const messageId = generateIdFor(requestStates);\n const requestState = {} as RequestStates;\n\n const promise = Promise.race([\n pause(PART_TIMEOUT).then(() => Promise.reject(new Error('ERROR_PART_TIMEOUT'))),\n new Promise<PartInfo>((resolve, reject) => {\n Object.assign(requestState, { resolve, reject });\n }),\n ]);\n\n requestStates.set(messageId, requestState);\n promise\n .catch(() => undefined)\n .finally(() => {\n requestStates.delete(messageId);\n });\n\n client.postMessage({\n type: 'requestPart',\n messageId,\n params,\n });\n\n return promise;\n}\n\nself.addEventListener('message', (e) => {\n const { type, messageId, result } = e.data as {\n type: string;\n messageId: string;\n result: PartInfo;\n };\n\n if (type === 'partResponse') {\n const requestState = requestStates.get(messageId);\n if (requestState) {\n requestState.resolve(result);\n }\n }\n});\n","export default (store: AnyLiteral) => {\n let id;\n\n do {\n id = String(Math.random()).replace('0.', 'id');\n } while (store.hasOwnProperty(id));\n\n return id;\n};\n","type Scheduler = typeof requestAnimationFrame | typeof onTickEnd | typeof runNow;\n\nexport function debounce<F extends AnyToVoidFunction>(\n fn: F,\n ms: number,\n shouldRunFirst = true,\n shouldRunLast = true,\n) {\n let waitingTimeout: number | undefined;\n\n return (...args: Parameters<F>) => {\n if (waitingTimeout) {\n clearTimeout(waitingTimeout);\n waitingTimeout = undefined;\n } else if (shouldRunFirst) {\n // @ts-ignore\n fn(...args);\n }\n\n // eslint-disable-next-line no-restricted-globals\n waitingTimeout = self.setTimeout(() => {\n if (shouldRunLast) {\n // @ts-ignore\n fn(...args);\n }\n\n waitingTimeout = undefined;\n }, ms);\n };\n}\n\nexport function throttle<F extends AnyToVoidFunction>(\n fn: F,\n ms: number,\n shouldRunFirst = true,\n) {\n let interval: number | undefined;\n let isPending: boolean;\n let args: Parameters<F>;\n\n return (..._args: Parameters<F>) => {\n isPending = true;\n args = _args;\n\n if (!interval) {\n if (shouldRunFirst) {\n isPending = false;\n // @ts-ignore\n fn(...args);\n }\n\n // eslint-disable-next-line no-restricted-globals\n interval = self.setInterval(() => {\n if (!isPending) {\n // eslint-disable-next-line no-restricted-globals\n self.clearInterval(interval!);\n interval = undefined;\n return;\n }\n\n isPending = false;\n // @ts-ignore\n fn(...args);\n }, ms);\n }\n };\n}\n\nexport function throttleWithRaf<F extends AnyToVoidFunction>(fn: F) {\n return throttleWith(fastRaf, fn);\n}\n\nexport function throttleWithPrimaryRaf<F extends AnyToVoidFunction>(fn: F) {\n return throttleWith(fastPrimaryRaf, fn);\n}\n\nexport function throttleWithTickEnd<F extends AnyToVoidFunction>(fn: F) {\n return throttleWith(onTickEnd, fn);\n}\n\nexport function throttleWithNow<F extends AnyToVoidFunction>(fn: F) {\n return throttleWith(runNow, fn);\n}\n\nexport function throttleWith<F extends AnyToVoidFunction>(schedulerFn: Scheduler, fn: F) {\n let waiting = false;\n let args: Parameters<F>;\n\n return (..._args: Parameters<F>) => {\n args = _args;\n\n if (!waiting) {\n waiting = true;\n\n schedulerFn(() => {\n waiting = false;\n // @ts-ignore\n fn(...args);\n });\n }\n };\n}\n\nexport function onTickEnd(cb: NoneToVoidFunction) {\n Promise.resolve().then(cb);\n}\n\nexport function onIdle(cb: NoneToVoidFunction) {\n // eslint-disable-next-line no-restricted-globals\n if (self.requestIdleCallback) {\n // eslint-disable-next-line no-restricted-globals\n self.requestIdleCallback(cb);\n } else {\n onTickEnd(cb);\n }\n}\n\nfunction runNow(fn: NoneToVoidFunction) {\n fn();\n}\n\nexport const pause = (ms: number) => new Promise((resolve) => {\n setTimeout(() => resolve(), ms);\n});\n\nexport function rafPromise() {\n return new Promise((resolve) => {\n requestAnimationFrame(resolve);\n });\n}\n\nlet fastRafCallbacks: NoneToVoidFunction[] | undefined;\n\nexport function fastRaf(callback: NoneToVoidFunction, isPrimary = false) {\n if (!fastRafCallbacks) {\n fastRafCallbacks = [callback];\n\n requestAnimationFrame(() => {\n const currentCallbacks = fastRafCallbacks!;\n fastRafCallbacks = undefined;\n currentCallbacks.forEach((cb) => cb());\n });\n } else if (isPrimary) {\n fastRafCallbacks.unshift(callback);\n } else {\n fastRafCallbacks.push(callback);\n }\n}\n\nexport function fastPrimaryRaf(callback: NoneToVoidFunction) {\n return fastRaf(callback, true);\n}\n","import { DEBUG } from './config';\nimport { respondForProgressive } from './serviceWorker/progressive';\nimport { respondWithCache, clearAssetCache } from './serviceWorker/assetCache';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\nconst ASSET_CACHE_PATTERN = /[0-9a-f]{20}.*\\.(js|css|woff2?|svg|png|jpg|json|wasm)$/;\n\nself.addEventListener('install', (e) => {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.log('ServiceWorker installed');\n }\n\n // Activate worker immediately\n e.waitUntil(self.skipWaiting());\n});\n\nself.addEventListener('activate', (e) => {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.log('ServiceWorker activated');\n }\n\n // Become available to all pages\n e.waitUntil(clearAssetCache());\n e.waitUntil(self.clients.claim());\n});\n\n// eslint-disable-next-line no-restricted-globals\nself.addEventListener('fetch', (e: FetchEvent) => {\n e.respondWith((() => {\n const { url } = e.request;\n\n if (url.includes('/progressive/')) {\n return respondForProgressive(e);\n }\n\n if (url.startsWith('http') && url.match(ASSET_CACHE_PATTERN)) {\n return respondWithCache(e);\n }\n\n return fetch(e.request);\n })());\n});\n\n\nself.addEventListener('push', (e: PushEvent) => {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.log('[SW] Push received event', e);\n if (e.data) {\n // eslint-disable-next-line no-console\n console.log(`[SW] Push received with data \"${e.data.text()}\"`);\n }\n }\n if (!e.data) return;\n let obj;\n try {\n obj = e.data.json();\n } catch (error) {\n obj = e.data.text();\n }\n\n const title = obj.title || 'Telegram';\n const body = obj.description || obj;\n const options = {\n body,\n icon: 'android-chrome-192x192.png',\n };\n\n e.waitUntil(\n self.registration.showNotification(title, options),\n );\n});\n\nself.addEventListener('notificationclick', (event) => {\n const url = '/';\n event.notification.close(); // Android needs explicit close.\n event.waitUntil(\n self.clients.matchAll({ type: 'window' })\n .then((windowClients) => {\n // Check if there is already a window/tab open with the target URL\n for (let i = 0; i < windowClients.length; i++) {\n const client = windowClients[i] as WindowClient;\n // If so, just focus it.\n if (client.url === url && client.focus) {\n client.focus();\n return;\n }\n }\n // If not, then open the target URL in a new window/tab.\n if (self.clients.openWindow) {\n self.clients.openWindow(url);\n }\n }),\n );\n});\n","import { ASSET_CACHE_NAME } from '../config';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport async function respondWithCache(e: FetchEvent) {\n const cache = await self.caches.open(ASSET_CACHE_NAME);\n const cached = await cache.match(e.request);\n\n if (cached) {\n return cached;\n }\n\n const remote = await fetch(e.request);\n cache.put(e.request, remote.clone());\n\n return remote;\n}\n\nexport function clearAssetCache() {\n return self.caches.delete(ASSET_CACHE_NAME);\n}\n"],"sourceRoot":""} |