mirror of
https://github.com/danog/telegram-tt.git
synced 2024-12-11 08:39:59 +01:00
1 line
23 KiB
Plaintext
1 line
23 KiB
Plaintext
{"version":3,"sources":["webpack:///./src/util/cycleRestrict.ts","webpack:///./src/util/WorkerConnector.ts","webpack:///./src/lib/rlottie/RLottie.ts","webpack:///./src/lib/rlottie/rlottie.worker.ts"],"names":["cycleRestrict","length","index","Math","floor","WorkerConnector","constructor","worker","Map","this","subscribe","request","messageData","requestStates","requestStatesByCallback","messageId","generateIdFor","payload","type","requestState","promise","Promise","resolve","reject","Object","assign","args","callback","pop","set","catch","finally","delete","postMessage","cancelCallback","progressCallback","isCanceled","get","addEventListener","data","error","response","callbackArgs","HIGH_PRIORITY_QUALITY","IS_MOBILE_SCREEN","LOW_PRIORITY_QUALITY","HIGH_PRIORITY_CACHE_MODULO","IS_SAFARI","workers","Array","fill","undefined","map","Worker","lastWorkerIndex","RLottie","id","container","animationData","params","onLoad","document","createElement","canvas","getContext","initContainer","initConfig","initRenderer","isPlaying","isAnimating","isWaiting","play","stopFrameIndex","direction","doPlay","pause","approxFrameIndex","currentChunkIndex","getChunkIndex","chunks","chunk","i","goToAndPlay","frameIndex","reduceFactor","goToAndStop","playSegment","startFrameIndex","setSpeed","speed","destroy","isDestroyed","destroyRenderer","destroyContainer","parentNode","HTMLElement","Error","size","offsetWidth","parseInt","style","width","height","isLowPriority","quality","imgSize","round","max","DPR","appendChild","key","maxFps","sourceFps","fr","msPerFrame","cacheModulo","chunkSize","remove","workerIndex","name","onRendererInit","bind","framesCount","chunksCount","ceil","lastRenderAt","animate","isOnLoadFired","chunkIndex","requestChunk","cleanupPrevChunk","requestNextChunk","prevFrameIndex","frame","getFrame","imageData","ImageData","Uint8ClampedArray","ctx","putImageData","now","Date","currentSpeed","delta","min","expectedNextFrameIndex","noLoop","nextFrameIndex","indexInChunk","getFrameIndexInChunk","fromIndex","toIndex","onFrameLoad","prevChunkIndex","nextChunkIndex","arrayBuffer","module","exports"],"mappings":"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","file":"7.de73a1e71b416d7dd3a2.js","sourcesContent":["export default function cycleRestrict(length: number, index: number) {\n return index - Math.floor(index / length) * length;\n}\n","import generateIdFor from './generateIdFor';\n\nexport interface CancellableCallback {\n (\n ...args: any[]\n ): void;\n\n isCanceled?: boolean;\n acceptsBuffer?: boolean;\n}\n\ntype CallMethodData = {\n type: 'callMethod';\n messageId?: string;\n name: string;\n args: any;\n};\n\ntype OriginMessageData = CallMethodData | {\n type: 'cancelProgress';\n messageId: string;\n};\n\nexport interface OriginMessageEvent {\n data: OriginMessageData;\n}\n\nexport type WorkerMessageData = {\n type: 'methodResponse';\n messageId: string;\n response?: any;\n error?: { message: string };\n} | {\n type: 'methodCallback';\n messageId: string;\n callbackArgs: any[];\n} | {\n type: 'unhandledError';\n error?: { message: string };\n};\n\nexport interface WorkerMessageEvent {\n data: WorkerMessageData;\n}\n\ninterface RequestStates {\n messageId: string;\n resolve: Function;\n reject: Function;\n callback: AnyToVoidFunction;\n}\n\n// TODO Replace `any` with proper generics\nexport default class WorkerConnector {\n private requestStates = new Map<string, RequestStates>();\n\n private requestStatesByCallback = new Map<AnyToVoidFunction, RequestStates>();\n\n constructor(private worker: Worker) {\n this.subscribe();\n }\n\n request(messageData: { name: string; args: any }) {\n const { worker, requestStates, requestStatesByCallback } = this;\n\n const messageId = generateIdFor(requestStates);\n const payload: CallMethodData = {\n type: 'callMethod',\n messageId,\n ...messageData,\n };\n\n const requestState = { messageId } as RequestStates;\n\n // Re-wrap type because of `postMessage`\n const promise: Promise<any> = new Promise((resolve, reject) => {\n Object.assign(requestState, { resolve, reject });\n });\n\n if (typeof payload.args[payload.args.length - 1] === 'function') {\n const callback = payload.args.pop() as AnyToVoidFunction;\n requestState.callback = callback;\n requestStatesByCallback.set(callback, requestState);\n }\n\n requestStates.set(messageId, requestState);\n promise\n .catch(() => undefined)\n .finally(() => {\n requestStates.delete(messageId);\n\n if (requestState.callback) {\n requestStatesByCallback.delete(requestState.callback);\n }\n });\n\n worker.postMessage(payload);\n\n return promise;\n }\n\n cancelCallback(progressCallback: CancellableCallback) {\n progressCallback.isCanceled = true;\n\n const { messageId } = this.requestStatesByCallback.get(progressCallback) || {};\n if (!messageId) {\n return;\n }\n\n this.worker.postMessage({\n type: 'cancelProgress',\n messageId,\n });\n }\n\n private subscribe() {\n const { worker, requestStates } = this;\n\n worker.addEventListener('message', ({ data }: WorkerMessageEvent) => {\n if (data.type === 'methodResponse') {\n const requestState = requestStates.get(data.messageId);\n if (requestState) {\n if (data.error) {\n requestState.reject(data.error);\n } else {\n requestState.resolve(data.response);\n }\n }\n } else if (data.type === 'methodCallback') {\n const requestState = requestStates.get(data.messageId);\n if (requestState && requestState.callback) {\n requestState.callback(...data.callbackArgs);\n }\n } else if (data.type === 'unhandledError') {\n throw data.error;\n }\n });\n }\n}\n","import Worker from 'worker-loader!./rlottie.worker';\n\nimport {\n DPR,\n IS_MOBILE_SCREEN,\n IS_SAFARI,\n} from '../../util/environment';\nimport WorkerConnector from '../../util/WorkerConnector';\nimport { animate } from '../../util/animation';\nimport cycleRestrict from '../../util/cycleRestrict';\n\ninterface Params {\n noLoop?: boolean;\n size?: number;\n quality?: number;\n isLowPriority?: boolean;\n}\n\ntype Frames = ArrayBuffer[];\ntype Chunks = (Frames | undefined)[];\n\n// TODO Consider removing chunks\nconst CHUNK_SIZE = 1;\nconst MAX_WORKERS = 4;\nconst HIGH_PRIORITY_QUALITY = IS_MOBILE_SCREEN ? 0.75 : 1;\nconst LOW_PRIORITY_QUALITY = 0.75;\nconst HIGH_PRIORITY_MAX_FPS = 60;\nconst LOW_PRIORITY_MAX_FPS = 30;\nconst HIGH_PRIORITY_CACHE_MODULO = IS_SAFARI ? 2 : 4;\nconst LOW_PRIORITY_CACHE_MODULO = 0;\n\nconst workers = new Array(MAX_WORKERS).fill(undefined).map(() => new WorkerConnector(new Worker()));\nlet lastWorkerIndex = -1;\n\nclass RLottie {\n // Config\n\n private imgSize!: number;\n\n private key!: string;\n\n private msPerFrame!: number;\n\n private reduceFactor!: number;\n\n private cacheModulo!: number;\n\n private chunkSize!: number;\n\n private workerIndex!: number;\n\n private chunks: Chunks = [];\n\n private framesCount?: number;\n\n private chunksCount?: number;\n\n // Container\n\n private canvas = document.createElement('canvas');\n\n private ctx = this.canvas.getContext('2d')!;\n\n // State\n\n private isAnimating = false;\n\n private isWaiting = true;\n\n private isOnLoadFired = false;\n\n private isDestroyed = false;\n\n private approxFrameIndex = 0;\n\n private prevFrameIndex = -1;\n\n private stopFrameIndex? = 0;\n\n private speed = 1;\n\n private direction: 1 | -1 = 1;\n\n private lastRenderAt?: number;\n\n constructor(\n private id: string,\n private container: HTMLDivElement,\n private animationData: AnyLiteral,\n private params: Params = {},\n private onLoad?: () => void,\n ) {\n this.initContainer();\n this.initConfig();\n this.initRenderer();\n }\n\n isPlaying() {\n return this.isAnimating || this.isWaiting;\n }\n\n play() {\n this.stopFrameIndex = undefined;\n this.direction = 1;\n this.doPlay();\n }\n\n pause() {\n if (this.isWaiting) {\n this.stopFrameIndex = this.approxFrameIndex;\n } else {\n this.isAnimating = false;\n }\n\n const currentChunkIndex = this.getChunkIndex(this.approxFrameIndex);\n this.chunks = this.chunks.map((chunk, i) => (i === currentChunkIndex ? chunk : undefined));\n }\n\n goToAndPlay(frameIndex: number) {\n this.approxFrameIndex = Math.floor(frameIndex / this.reduceFactor);\n this.stopFrameIndex = undefined;\n this.direction = 1;\n this.doPlay();\n }\n\n goToAndStop(frameIndex: number) {\n this.approxFrameIndex = Math.floor(frameIndex / this.reduceFactor);\n this.stopFrameIndex = Math.floor(frameIndex / this.reduceFactor);\n this.direction = 1;\n this.doPlay();\n }\n\n playSegment([startFrameIndex, stopFrameIndex]: [number, number]) {\n this.approxFrameIndex = Math.floor(startFrameIndex / this.reduceFactor);\n this.stopFrameIndex = Math.floor(stopFrameIndex / this.reduceFactor);\n this.direction = startFrameIndex < stopFrameIndex ? 1 : -1;\n this.doPlay();\n }\n\n setSpeed(speed: number) {\n this.speed = speed;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.pause();\n this.destroyRenderer();\n this.destroyContainer();\n }\n\n private initContainer() {\n if (!(this.container.parentNode instanceof HTMLElement)) {\n throw new Error('[RLottie] Container is not mounted');\n }\n\n let { size } = this.params;\n\n if (!size) {\n size = (\n this.container.offsetWidth\n || parseInt(this.container.style.width, 10)\n || this.container.parentNode.offsetWidth\n );\n\n if (!size) {\n throw new Error('[RLottie] Failed to detect width from container');\n }\n }\n\n this.canvas.style.width = `${size}px`;\n this.canvas.style.height = `${size}px`;\n\n const { isLowPriority, quality = isLowPriority ? LOW_PRIORITY_QUALITY : HIGH_PRIORITY_QUALITY } = this.params;\n // Reduced quality only looks acceptable on high DPR screens\n const imgSize = Math.round(size * Math.max(DPR * quality, 1));\n\n this.canvas.width = imgSize;\n this.canvas.height = imgSize;\n\n this.container.appendChild(this.canvas);\n\n this.imgSize = imgSize;\n }\n\n private initConfig() {\n this.key = `${this.id}_${this.imgSize}`;\n\n const { isLowPriority } = this.params;\n\n const maxFps = isLowPriority ? LOW_PRIORITY_MAX_FPS : HIGH_PRIORITY_MAX_FPS;\n const sourceFps = this.animationData.fr || maxFps;\n this.reduceFactor = sourceFps % maxFps === 0 ? sourceFps / maxFps : 1;\n this.msPerFrame = 1000 / (sourceFps / this.reduceFactor);\n this.cacheModulo = isLowPriority ? LOW_PRIORITY_CACHE_MODULO : HIGH_PRIORITY_CACHE_MODULO;\n this.chunkSize = CHUNK_SIZE;\n }\n\n private destroyContainer() {\n this.canvas.remove();\n }\n\n private initRenderer() {\n this.workerIndex = cycleRestrict(MAX_WORKERS, ++lastWorkerIndex);\n\n workers[this.workerIndex].request({\n name: 'init',\n args: [\n this.key,\n this.animationData,\n this.imgSize,\n this.params.isLowPriority,\n this.reduceFactor,\n this.onRendererInit.bind(this),\n ],\n });\n }\n\n private destroyRenderer() {\n workers[this.workerIndex].request({\n name: 'destroy',\n args: [this.key],\n });\n }\n\n private onRendererInit(framesCount: number) {\n this.framesCount = framesCount;\n this.chunksCount = Math.ceil(framesCount / this.chunkSize);\n\n if (this.isWaiting) {\n this.doPlay();\n }\n }\n\n private doPlay() {\n if (!this.framesCount) {\n return;\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (this.isAnimating) {\n return;\n }\n\n if (!this.isWaiting) {\n this.lastRenderAt = undefined;\n }\n\n this.isAnimating = true;\n this.isWaiting = false;\n\n animate(() => {\n if (this.isDestroyed) {\n return false;\n }\n\n // Paused from outside\n if (!this.isAnimating && this.isOnLoadFired) {\n return false;\n }\n\n const frameIndex = Math.round(this.approxFrameIndex);\n const chunkIndex = this.getChunkIndex(frameIndex);\n const chunk = this.chunks[chunkIndex];\n if (!chunk) {\n this.requestChunk(chunkIndex);\n this.isAnimating = false;\n this.isWaiting = true;\n return false;\n }\n\n if (this.cacheModulo && chunkIndex % this.cacheModulo === 0) {\n this.cleanupPrevChunk(chunkIndex);\n }\n\n this.requestNextChunk(chunkIndex);\n\n if (frameIndex !== this.prevFrameIndex) {\n const frame = this.getFrame(frameIndex);\n if (!frame) {\n this.isAnimating = false;\n this.isWaiting = true;\n return false;\n }\n\n const imageData = new ImageData(new Uint8ClampedArray(frame), this.imgSize, this.imgSize);\n this.ctx.putImageData(imageData, 0, 0);\n\n if (this.onLoad && !this.isOnLoadFired) {\n this.isOnLoadFired = true;\n this.onLoad();\n }\n\n this.prevFrameIndex = frameIndex;\n }\n\n const now = Date.now();\n const currentSpeed = this.lastRenderAt ? this.msPerFrame / (now - this.lastRenderAt) : 1;\n const delta = Math.min(1, (this.direction * this.speed) / currentSpeed);\n const expectedNextFrameIndex = Math.round(this.approxFrameIndex + delta);\n\n this.lastRenderAt = now;\n\n // Forward animation finished\n if (delta > 0 && (frameIndex === this.framesCount! - 1 || expectedNextFrameIndex > this.framesCount! - 1)) {\n if (this.params.noLoop) {\n this.isAnimating = false;\n return false;\n }\n\n this.approxFrameIndex = 0;\n\n // Backward animation finished\n } else if (delta < 0 && (frameIndex === 0 || expectedNextFrameIndex < 0)) {\n if (this.params.noLoop) {\n this.isAnimating = false;\n return false;\n }\n\n this.approxFrameIndex = this.framesCount! - 1;\n\n // Stop frame reached\n } else if (\n this.stopFrameIndex !== undefined\n && (frameIndex === this.stopFrameIndex\n || (\n (delta > 0 && expectedNextFrameIndex > this.stopFrameIndex)\n || (delta < 0 && expectedNextFrameIndex < this.stopFrameIndex)\n ))\n ) {\n this.stopFrameIndex = undefined;\n this.isAnimating = false;\n return false;\n\n // Preparing next frame\n } else {\n this.approxFrameIndex += delta;\n }\n\n const nextFrameIndex = Math.round(this.approxFrameIndex);\n\n if (!this.getFrame(nextFrameIndex)) {\n this.requestChunk(this.getChunkIndex(nextFrameIndex));\n this.isWaiting = true;\n this.isAnimating = false;\n return false;\n }\n\n return true;\n });\n }\n\n private getFrame(frameIndex: number) {\n const chunkIndex = this.getChunkIndex(frameIndex);\n const indexInChunk = this.getFrameIndexInChunk(frameIndex);\n const chunk = this.chunks[chunkIndex];\n if (!chunk) {\n return undefined;\n }\n\n return chunk[indexInChunk];\n }\n\n private getFrameIndexInChunk(frameIndex: number) {\n const chunkIndex = this.getChunkIndex(frameIndex);\n return frameIndex - chunkIndex * this.chunkSize;\n }\n\n private getChunkIndex(frameIndex: number) {\n return Math.floor(frameIndex / this.chunkSize);\n }\n\n private requestChunk(chunkIndex: number) {\n if (this.chunks[chunkIndex]) {\n return;\n }\n\n this.chunks[chunkIndex] = [];\n\n const fromIndex = chunkIndex * this.chunkSize;\n const toIndex = Math.min(fromIndex + this.chunkSize - 1, this.framesCount! - 1);\n\n workers[this.workerIndex].request({\n name: 'renderFrames',\n args: [this.key, fromIndex, toIndex, this.onFrameLoad.bind(this)],\n });\n }\n\n private cleanupPrevChunk(chunkIndex: number) {\n if (this.chunksCount! < 3) {\n return;\n }\n\n const prevChunkIndex = cycleRestrict(this.chunksCount!, chunkIndex - 1);\n this.chunks[prevChunkIndex] = undefined;\n }\n\n private requestNextChunk(chunkIndex: number) {\n if (this.chunksCount === 1) {\n return;\n }\n\n const nextChunkIndex = cycleRestrict(this.chunksCount!, chunkIndex + 1);\n\n if (!this.chunks[nextChunkIndex]) {\n this.requestChunk(nextChunkIndex);\n }\n }\n\n private onFrameLoad(frameIndex: number, arrayBuffer: ArrayBuffer) {\n const chunkIndex = this.getChunkIndex(frameIndex);\n const chunk = this.chunks[chunkIndex];\n // Frame can be skipped and chunk can be already cleaned up\n if (!chunk) {\n return;\n }\n\n chunk[this.getFrameIndexInChunk(frameIndex)] = arrayBuffer;\n\n if (this.isWaiting) {\n this.doPlay();\n }\n }\n}\n\nexport default RLottie;\n","module.exports = function() {\n return new Worker(__webpack_public_path__ + \"3fcca40d11f516ceb903.worker.js\");\n};"],"sourceRoot":""} |