Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.8 KiB
122 lines
3.8 KiB
3 years ago
|
/*
|
||
|
* https://github.com/morethanwords/tweb
|
||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||
|
*/
|
||
|
|
||
|
import { IS_SAFARI } from "../../environment/userAgent";
|
||
|
import { indexOfAndSplice } from "../../helpers/array";
|
||
|
import { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl";
|
||
|
import { deepEqual } from "../../helpers/object";
|
||
|
|
||
|
type ChatBackgroundPatternRendererInitOptions = {
|
||
|
url: string,
|
||
|
width: number,
|
||
|
height: number
|
||
|
};
|
||
|
|
||
|
export default class ChatBackgroundPatternRenderer {
|
||
|
private static INSTANCES: ChatBackgroundPatternRenderer[] = [];
|
||
|
|
||
|
private pattern: CanvasPattern;
|
||
|
private objectUrl: string;
|
||
|
private options: ChatBackgroundPatternRendererInitOptions;
|
||
|
private canvases: Set<HTMLCanvasElement>;
|
||
|
private createCanvasPatternPromise: Promise<void>;
|
||
|
private exportCanvasPatternToImagePromise: Promise<string>;
|
||
|
// private img: HTMLImageElement;
|
||
|
|
||
|
constructor() {
|
||
|
this.canvases = new Set();
|
||
|
}
|
||
|
|
||
|
public static getInstance(options: ChatBackgroundPatternRendererInitOptions) {
|
||
|
let instance = this.INSTANCES.find((instance) => {
|
||
|
return deepEqual(instance.options, options);
|
||
|
});
|
||
|
|
||
|
if(!instance) {
|
||
|
instance = new ChatBackgroundPatternRenderer();
|
||
|
instance.init(options);
|
||
|
this.INSTANCES.push(instance);
|
||
|
}
|
||
|
|
||
|
return instance;
|
||
|
}
|
||
|
|
||
|
public init(options: ChatBackgroundPatternRendererInitOptions) {
|
||
|
this.options = options;
|
||
|
}
|
||
|
|
||
|
public renderToCanvas(canvas: HTMLCanvasElement) {
|
||
|
return this.createCanvasPattern(canvas).then(() => {
|
||
|
return this.fillCanvas(canvas);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
private createCanvasPattern(canvas: HTMLCanvasElement) {
|
||
|
if(this.createCanvasPatternPromise) return this.createCanvasPatternPromise;
|
||
|
return this.createCanvasPatternPromise = new Promise((resolve) => {
|
||
|
const img = document.createElement('img');
|
||
|
img.crossOrigin = 'anonymous';
|
||
|
renderImageFromUrlPromise(img, this.options.url, false).then(() => {
|
||
|
let createPatternFrom: HTMLImageElement | HTMLCanvasElement;
|
||
|
if(IS_SAFARI) {
|
||
|
const canvas = createPatternFrom = document.createElement('canvas');
|
||
|
canvas.width = img.naturalWidth;
|
||
|
canvas.height = img.naturalHeight;
|
||
|
const ctx = canvas.getContext('2d');
|
||
|
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
||
|
} else {
|
||
|
createPatternFrom = img;
|
||
|
}
|
||
|
|
||
|
// this.img = img;
|
||
|
this.pattern = canvas.getContext('2d').createPattern(createPatternFrom, 'repeat-x');
|
||
|
resolve();
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public exportCanvasPatternToImage(canvas: HTMLCanvasElement) {
|
||
|
if(this.exportCanvasPatternToImagePromise) return this.exportCanvasPatternToImagePromise;
|
||
|
return this.exportCanvasPatternToImagePromise = new Promise<string>((resolve) => {
|
||
|
canvas.toBlob((blob) => {
|
||
|
const newUrl = this.objectUrl = URL.createObjectURL(blob);
|
||
|
resolve(newUrl);
|
||
|
}, 'image/png');
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public cleanup(canvas: HTMLCanvasElement) {
|
||
|
this.canvases.delete(canvas);
|
||
|
|
||
|
if(!this.canvases.size) {
|
||
|
indexOfAndSplice(ChatBackgroundPatternRenderer.INSTANCES, this);
|
||
|
|
||
|
if(this.objectUrl) {
|
||
|
URL.revokeObjectURL(this.objectUrl);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public fillCanvas(canvas: HTMLCanvasElement) {
|
||
|
const context = canvas.getContext('2d');
|
||
|
context.fillStyle = this.pattern;
|
||
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
||
|
// context.drawImage(this.img, 0, 0, canvas.width, canvas.height);
|
||
|
}
|
||
|
|
||
|
public setCanvasDimensions(canvas: HTMLCanvasElement) {
|
||
|
canvas.width = this.options.width * window.devicePixelRatio;
|
||
|
canvas.height = this.options.height * window.devicePixelRatio * 1.5;
|
||
|
}
|
||
|
|
||
|
public createCanvas() {
|
||
|
const canvas = document.createElement('canvas');
|
||
|
this.canvases.add(canvas);
|
||
|
this.setCanvasDimensions(canvas);
|
||
|
return canvas;
|
||
|
}
|
||
|
}
|