Browse Source

Fix gifs blinking

Fix SW registration path
Some prealoders
Fix forwarded by channel to channel
master
morethanwords 4 years ago
parent
commit
0102df4247
  1. 4
      .gitignore
  2. 13
      server.js
  3. 27
      src/components/emoticonsDropdown.ts
  4. 4
      src/components/poll.ts
  5. 8
      src/components/preloader.ts
  6. 109
      src/components/wrappers.ts
  7. 35
      src/lib/appManagers/appDocsManager.ts
  8. 2
      src/lib/appManagers/appDownloadManager.ts
  9. 12
      src/lib/appManagers/appImManager.ts
  10. 4
      src/lib/appManagers/appMediaViewer.ts
  11. 2
      src/lib/appManagers/appMessagesManager.ts
  12. 37
      src/lib/appManagers/appPhotosManager.ts
  13. 5
      src/lib/mtproto/mtprotoworker.ts
  14. 2
      src/lib/richtextprocessor.js
  15. 3
      src/scss/partials/_emojiDropdown.scss
  16. 1
      tsconfig.json

4
.gitignore vendored

@ -5,4 +5,6 @@ dist
.DS_Store .DS_Store
stats.json stats.json
certs certs
src/rlottie.github.io src/rlottie.github.io
public2
public3

13
server.js

@ -5,16 +5,21 @@ const fs = require('fs');
const app = express(); const app = express();
const thirdTour = process.argv[2] == 3;
const publicFolderName = thirdTour ? 'public3' : 'public';
const port = thirdTour ? 8443 : 443;
app.use(compression()); app.use(compression());
app.use(express.static('public')); app.use(express.static(publicFolderName));
app.get('/', (req, res) => { app.get('/', (req, res) => {
res.sendFile(__dirname + '/public3/index.html'); res.sendFile(__dirname + `/${publicFolderName}/index.html`);
}); });
https.createServer({ https.createServer({
key: fs.readFileSync(__dirname + '/certs/server-key.pem'), key: fs.readFileSync(__dirname + '/certs/server-key.pem'),
cert: fs.readFileSync(__dirname + '/certs/server-cert.pem') cert: fs.readFileSync(__dirname + '/certs/server-cert.pem')
}, app).listen(443/* 9001 */, () => { }, app).listen(port, () => {
console.log('Listening...'); console.log('Listening port:', port, 'folder:', publicFolderName);
}); });

27
src/components/emoticonsDropdown.ts

@ -625,13 +625,15 @@ class GifsTab implements EmoticonsTab {
}); });
const video = div.querySelector('video'); const video = div.querySelector('video');
video.addEventListener('loadeddata', () => { video.addEventListener('canplay', () => {
div.style.opacity = ''; div.style.opacity = '';
if(!mouseOut) { if(!mouseOut) {
img && img.remove(); img && img.classList.add('hide');
} else { } else {
div.innerHTML = ''; img && img.classList.remove('hide');
div.append(img); if(div.lastElementChild != img) {
div.lastElementChild.remove();
}
} }
}, {once: true}); }, {once: true});
}; };
@ -654,9 +656,20 @@ class GifsTab implements EmoticonsTab {
mouseOut = true; mouseOut = true;
div.innerHTML = ''; const cb = () => {
div.append(img); if(div.lastElementChild != img) {
div.addEventListener('mouseover', onMouseOver, {once: true}); div.lastElementChild.remove();
}
div.addEventListener('mouseover', onMouseOver, {once: true});
};
img && img.classList.remove('hide');
/* window.requestAnimationFrame(() => {
window.requestAnimationFrame();
}); */
if(img) window.requestAnimationFrame(() => window.requestAnimationFrame(cb));
else cb();
}); });
}; };

4
src/components/poll.ts

@ -173,7 +173,7 @@ export default class PollElement extends HTMLElement {
if(!lineTotalLength) { if(!lineTotalLength) {
lineTotalLength = (document.getElementById('poll-line') as any as SVGPathElement).getTotalLength(); lineTotalLength = (document.getElementById('poll-line') as any as SVGPathElement).getTotalLength();
console.log('line total length:', lineTotalLength); //console.log('line total length:', lineTotalLength);
} }
this.pollID = this.getAttribute('poll-id'); this.pollID = this.getAttribute('poll-id');
@ -182,7 +182,7 @@ export default class PollElement extends HTMLElement {
connectedPolls.push({id: this.pollID, element: this}); connectedPolls.push({id: this.pollID, element: this});
console.log('pollElement poll:', poll, results); //console.log('pollElement poll:', poll, results);
let desc = ''; let desc = '';
if(poll.pFlags) { if(poll.pFlags) {

8
src/components/preloader.ts

@ -50,7 +50,7 @@ export default class ProgressivePreloader {
} }
public attach(elem: Element, reset = true, promise?: CancellablePromise<any>, append = true) { public attach(elem: Element, reset = true, promise?: CancellablePromise<any>, append = true) {
if(promise) { if(promise/* && false */) {
this.promise = promise; this.promise = promise;
const tempID = --this.tempID; const tempID = --this.tempID;
@ -99,14 +99,14 @@ export default class ProgressivePreloader {
this.detached = true; this.detached = true;
if(this.preloader.parentElement) { if(this.preloader.parentElement) {
window.requestAnimationFrame(() => { /* setTimeout(() => */window.requestAnimationFrame(() => {
if(!this.detached) return; if(!this.detached) return;
this.detached = true; this.detached = true;
if(this.preloader.parentElement) { if(this.preloader.parentElement) {
this.preloader.parentElement.removeChild(this.preloader); this.preloader.remove();
} }
}); })/* , 5e3) */;
} }
} }

109
src/components/wrappers.ts

@ -1,4 +1,4 @@
import appPhotosManager from '../lib/appManagers/appPhotosManager'; import appPhotosManager, { MTPhoto } from '../lib/appManagers/appPhotosManager';
import LottieLoader from '../lib/lottieLoader'; import LottieLoader from '../lib/lottieLoader';
import appDocsManager from "../lib/appManagers/appDocsManager"; import appDocsManager from "../lib/appManagers/appDocsManager";
import { formatBytes, getEmojiToneIndex } from "../lib/utils"; import { formatBytes, getEmojiToneIndex } from "../lib/utils";
@ -14,7 +14,7 @@ import { mediaSizes, isSafari } from '../lib/config';
import { MTDocument, MTPhotoSize } from '../types'; import { MTDocument, MTPhotoSize } from '../types';
import animationIntersector from './animationIntersector'; import animationIntersector from './animationIntersector';
import AudioElement from './audio'; import AudioElement from './audio';
import appDownloadManager, { Download } from '../lib/appManagers/appDownloadManager'; import appDownloadManager, { Download, Progress, DownloadBlob } from '../lib/appManagers/appDownloadManager';
import { webpWorkerController } from '../lib/webp/webpWorkerController'; import { webpWorkerController } from '../lib/webp/webpWorkerController';
export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group}: { export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group}: {
@ -50,6 +50,10 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
} }
} }
if(doc.mime_type == 'image/gif') {
return wrapPhoto(doc, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware);
}
const video = document.createElement('video'); const video = document.createElement('video');
let img: HTMLImageElement; let img: HTMLImageElement;
@ -61,19 +65,16 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
if(withTail) { if(withTail) {
img = wrapMediaWithTail(doc, message, container, boxWidth, boxHeight, isOut); img = wrapMediaWithTail(doc, message, container, boxWidth, boxHeight, isOut);
} else { } else {
if(!boxWidth && !boxHeight) { // album if(boxWidth && boxHeight) { // !album
let sizes = doc.thumbs; appPhotosManager.setAttachmentSize(doc, container, boxWidth, boxHeight, false, true);
if(!doc.downloaded && sizes && sizes[0].bytes) { }
appPhotosManager.setAttachmentPreview(sizes[0].bytes, container, false);
} if(doc.thumbs && doc.thumbs[0]?.bytes) {
} else { appPhotosManager.setAttachmentPreview(doc.thumbs[0].bytes, container, false);
if(!container.firstElementChild || (container.firstElementChild.tagName != 'IMG' && container.firstElementChild.tagName != 'VIDEO')) {
appPhotosManager.setAttachmentSize(doc, container, boxWidth, boxHeight);
}
} }
img = container.lastElementChild as HTMLImageElement; img = container.lastElementChild as HTMLImageElement;
if(!img || img.tagName != 'IMG') { if(img?.tagName != 'IMG') {
container.append(img = new Image()); container.append(img = new Image());
} }
} }
@ -102,17 +103,26 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
} }
const loadVideo = async() => { const loadVideo = async() => {
if(middleware && !middleware()) {
return;
}
let preloader: ProgressivePreloader;
if(message?.media?.preloader) { // means upload if(message?.media?.preloader) { // means upload
(message.media.preloader as ProgressivePreloader).attach(container, undefined, undefined, false); preloader = message.media.preloader as ProgressivePreloader;
} else if(!doc.downloaded) { preloader.attach(container, undefined, undefined, true);
/* const promise = appDocsManager.downloadDoc(doc.id); } else if(!doc.downloaded && !doc.supportsStreaming) {
const promise = appDocsManager.downloadDocNew(doc);
//if(!doc.supportsStreaming) { preloader = new ProgressivePreloader(container, true);
const preloader = new ProgressivePreloader(container, true); preloader.attach(container, true, promise, true);
preloader.attach(container, true, promise, false);
//} /* video.addEventListener('canplay', () => {
if(preloader) {
preloader.detach();
}
}, {once: true}); */
await promise; */ await promise;
} }
if(middleware && !middleware()) { if(middleware && !middleware()) {
@ -121,21 +131,21 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
//console.log('loaded doc:', doc, doc.url, container); //console.log('loaded doc:', doc, doc.url, container);
if(doc.type == 'gif'/* || true */) { //if(doc.type == 'gif'/* || true */) {
video.addEventListener('canplay', () => { video.addEventListener('canplay', () => {
if(img && img.parentElement) { if(img?.parentElement) {
img.remove(); img.remove();
} }
/* if(!video.paused) { /* if(!video.paused) {
video.pause(); video.pause();
} */ } */
if(group) { if(doc.type == 'gif' && group) {
animationIntersector.addAnimation(video, group); animationIntersector.addAnimation(video, group);
} }
}, {once: true}); }, {once: true});
} //}
renderImageFromUrl(video, doc.url); renderImageFromUrl(video, doc.url);
video.setAttribute('playsinline', ''); video.setAttribute('playsinline', '');
@ -149,10 +159,9 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
//video.play(); //video.play();
video.autoplay = true; video.autoplay = true;
} else if(doc.type == 'round') { } else if(doc.type == 'round') {
//video.dataset.ckin = doc.type == 'round' ? 'circle' : 'default';
video.dataset.ckin = 'circle'; video.dataset.ckin = 'circle';
video.dataset.overlay = '1'; video.dataset.overlay = '1';
let player = new VideoPlayer(video/* , doc.type != 'round' */); new VideoPlayer(video);
} }
}; };
@ -174,7 +183,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
return; return;
} */ } */
doc.downloaded || !lazyLoadQueue/* && false */ ? loadVideo() : lazyLoadQueue.push({div: container, load: loadVideo/* , wasSeen: true */}); /* doc.downloaded || */!lazyLoadQueue/* && false */ ? loadVideo() : lazyLoadQueue.push({div: container, load: loadVideo/* , wasSeen: true */});
return video; return video;
} }
@ -228,7 +237,7 @@ export function wrapDocument(doc: MTDocument, withTime = false, uploading = fals
if(!uploading) { if(!uploading) {
let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement; let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement;
let preloader: ProgressivePreloader; let preloader: ProgressivePreloader;
let download: Download; let download: DownloadBlob;
docDiv.addEventListener('click', () => { docDiv.addEventListener('click', () => {
if(!download) { if(!download) {
@ -271,16 +280,16 @@ export function wrapAudio(doc: MTDocument, withTime = false, mid?: number): HTML
return elem; return elem;
} }
function wrapMediaWithTail(photo: any, message: {mid: number, message: string}, container: HTMLDivElement, boxWidth: number, boxHeight: number, isOut: boolean) { function wrapMediaWithTail(photo: MTPhoto | MTDocument, message: {mid: number, message: string}, container: HTMLDivElement, boxWidth: number, boxHeight: number, isOut: boolean) {
let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.classList.add('bubble__media-container', isOut ? 'is-out' : 'is-in'); svg.classList.add('bubble__media-container', isOut ? 'is-out' : 'is-in');
let foreignObject = document.createElementNS("http://www.w3.org/2000/svg", 'foreignObject'); const foreignObject = document.createElementNS("http://www.w3.org/2000/svg", 'foreignObject');
appPhotosManager.setAttachmentSize(photo._ == 'document' ? photo : photo.id, foreignObject, boxWidth, boxHeight); appPhotosManager.setAttachmentSize(photo, foreignObject, boxWidth, boxHeight/* , false, true */);
let width = +foreignObject.getAttributeNS(null, 'width'); const width = +foreignObject.getAttributeNS(null, 'width');
let height = +foreignObject.getAttributeNS(null, 'height'); const height = +foreignObject.getAttributeNS(null, 'height');
svg.setAttributeNS(null, 'width', '' + width); svg.setAttributeNS(null, 'width', '' + width);
svg.setAttributeNS(null, 'height', '' + height); svg.setAttributeNS(null, 'height', '' + height);
@ -288,10 +297,10 @@ function wrapMediaWithTail(photo: any, message: {mid: number, message: string},
svg.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height); svg.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height);
svg.setAttributeNS(null, 'preserveAspectRatio', 'none'); svg.setAttributeNS(null, 'preserveAspectRatio', 'none');
let clipID = 'clip' + message.mid; const clipID = 'clip' + message.mid;
svg.dataset.clipID = clipID; svg.dataset.clipID = clipID;
let defs = document.createElementNS("http://www.w3.org/2000/svg", 'defs'); const defs = document.createElementNS("http://www.w3.org/2000/svg", 'defs');
let clipPathHTML: string = ''; let clipPathHTML: string = '';
if(message.message) { if(message.message) {
@ -326,20 +335,20 @@ function wrapMediaWithTail(photo: any, message: {mid: number, message: string},
return img; return img;
} }
export function wrapPhoto(photoID: any, message: any, container: HTMLDivElement, boxWidth = mediaSizes.active.regular.width, boxHeight = mediaSizes.active.regular.height, withTail = true, isOut = false, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean, size: MTPhotoSize = null) { export function wrapPhoto(photo: MTPhoto | MTDocument, message: any, container: HTMLDivElement, boxWidth = mediaSizes.active.regular.width, boxHeight = mediaSizes.active.regular.height, withTail = true, isOut = false, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean, size: MTPhotoSize = null) {
const photo = appPhotosManager.getPhoto(photoID);
let image: HTMLImageElement; let image: HTMLImageElement;
if(withTail) { if(withTail) {
image = wrapMediaWithTail(photo, message, container, boxWidth, boxHeight, isOut); image = wrapMediaWithTail(photo, message, container, boxWidth, boxHeight, isOut);
} else { } else {
if(size) { // album if(boxWidth && boxHeight) { // !album
let sizes = photo.sizes; size = appPhotosManager.setAttachmentSize(photo, container, boxWidth, boxHeight, false, true);
if(!photo.downloaded && sizes && sizes[0].bytes) { }
appPhotosManager.setAttachmentPreview(sizes[0].bytes, container, false);
if(photo._ == 'document' || !photo.downloaded) {
const thumbs = (photo as MTPhoto).sizes || (photo as MTDocument).thumbs;
if(thumbs && thumbs[0]?.bytes) {
appPhotosManager.setAttachmentPreview(thumbs[0].bytes, container, false);
} }
} else if(boxWidth && boxHeight) { // means webpage's preview
size = appPhotosManager.setAttachmentSize(photo, container, boxWidth, boxHeight, false);
} }
image = container.lastElementChild as HTMLImageElement; image = container.lastElementChild as HTMLImageElement;
@ -360,7 +369,7 @@ export function wrapPhoto(photoID: any, message: any, container: HTMLDivElement,
} }
const load = () => { const load = () => {
const promise = appPhotosManager.preloadPhoto(photoID, size); const promise = photo._ == 'document' && photo.animated ? appDocsManager.downloadDocNew(photo) : appPhotosManager.preloadPhoto(photo, size);
if(preloader) { if(preloader) {
preloader.attach(container, true, promise); preloader.attach(container, true, promise);
@ -378,7 +387,7 @@ export function wrapPhoto(photoID: any, message: any, container: HTMLDivElement,
return promise.then(() => { return promise.then(() => {
if(middleware && !middleware()) return; if(middleware && !middleware()) return;
renderImageFromUrl(image || container, cacheContext.url); renderImageFromUrl(image || container, cacheContext.url || photo.url);
}); });
}; };
@ -697,7 +706,7 @@ export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLo
if(media._ == 'photo') { if(media._ == 'photo') {
wrapPhoto( wrapPhoto(
media.id, media,
message, message,
div, div,
0, 0,

35
src/lib/appManagers/appDocsManager.ts

@ -4,7 +4,7 @@ import { isObject, getFileURL, FileURLType } from '../utils';
import opusDecodeController from '../opusDecodeController'; import opusDecodeController from '../opusDecodeController';
import { MTDocument, inputDocumentFileLocation, MTPhotoSize } from '../../types'; import { MTDocument, inputDocumentFileLocation, MTPhotoSize } from '../../types';
import { getFileNameByLocation } from '../bin_utils'; import { getFileNameByLocation } from '../bin_utils';
import appDownloadManager, { Download, ResponseMethod } from './appDownloadManager'; import appDownloadManager, { Download, ResponseMethod, DownloadBlob } from './appDownloadManager';
import appPhotosManager from './appPhotosManager'; import appPhotosManager from './appPhotosManager';
class AppDocsManager { class AppDocsManager {
@ -60,7 +60,7 @@ class AppDocsManager {
apiDoc.w = attribute.w; apiDoc.w = attribute.w;
apiDoc.h = attribute.h; apiDoc.h = attribute.h;
//apiDoc.supportsStreaming = attribute.pFlags?.supports_streaming/* && apiDoc.size > 524288 */; //apiDoc.supportsStreaming = attribute.pFlags?.supports_streaming/* && apiDoc.size > 524288 */;
if(apiDoc.thumbs && attribute.pFlags.round_message) { if(/* apiDoc.thumbs && */attribute.pFlags.round_message) {
apiDoc.type = 'round'; apiDoc.type = 'round';
} else /* if(apiDoc.thumbs) */ { } else /* if(apiDoc.thumbs) */ {
apiDoc.type = 'video'; apiDoc.type = 'video';
@ -93,7 +93,7 @@ class AppDocsManager {
break; break;
case 'documentAttributeAnimated': case 'documentAttributeAnimated':
if((apiDoc.mime_type == 'image/gif' || apiDoc.mime_type == 'video/mp4') && apiDoc.thumbs) { if((apiDoc.mime_type == 'image/gif' || apiDoc.mime_type == 'video/mp4')/* && apiDoc.thumbs */) {
apiDoc.type = 'gif'; apiDoc.type = 'gif';
} }
@ -211,14 +211,19 @@ class AppDocsManager {
public getThumbURL(doc: MTDocument, useBytes = true) { public getThumbURL(doc: MTDocument, useBytes = true) {
if(doc.thumbs?.length) { if(doc.thumbs?.length) {
if(doc.thumbs[0].bytes && useBytes) { let thumb: MTPhotoSize;
return appPhotosManager.getPreviewURLFromBytes(doc.thumbs[0].bytes, !!doc.sticker); if(!useBytes) {
thumb = doc.thumbs.find(t => !t.bytes);
}
if(!thumb) {
thumb = doc.thumbs[0];
} }
const thumb = doc.thumbs.find(t => !t.bytes); if(thumb.bytes) {
if(thumb) { return appPhotosManager.getPreviewURLFromBytes(doc.thumbs[0].bytes, !!doc.sticker);
const url = this.getFileURL(doc, false, thumb); } else {
return url; return this.getFileURL(doc, false, thumb);
} }
} }
@ -291,7 +296,7 @@ class AppDocsManager {
return this.downloadPromises[doc.id] = deferred; return this.downloadPromises[doc.id] = deferred;
} }
public downloadDocNew(docID: string | MTDocument/* , method: ResponseMethod = 'blob' */): Download { public downloadDocNew(docID: string | MTDocument/* , method: ResponseMethod = 'blob' */): DownloadBlob {
const doc = this.getDoc(docID); const doc = this.getDoc(docID);
if(doc._ == 'documentEmpty') { if(doc._ == 'documentEmpty') {
@ -300,16 +305,20 @@ class AppDocsManager {
const fileName = this.getInputFileName(doc); const fileName = this.getInputFileName(doc);
let download = appDownloadManager.getDownload(fileName); let download: DownloadBlob = appDownloadManager.getDownload(fileName);
if(download) { if(download) {
return download; return download;
} }
download = appDownloadManager.download(doc.url, fileName, /*method*/); download = appDownloadManager.download(doc.url, fileName/* , method */);
const originalPromise = download; const originalPromise = download;
originalPromise.then(() => { originalPromise.then((blob) => {
doc.downloaded = true; doc.downloaded = true;
if(!doc.supportsStreaming) {
doc.url = URL.createObjectURL(blob);
}
}); });
if(doc.type == 'voice' && !opusDecodeController.isPlaySupported()) { if(doc.type == 'voice' && !opusDecodeController.isPlaySupported()) {

2
src/lib/appManagers/appDownloadManager.ts

@ -40,7 +40,7 @@ export class AppDownloadManager {
public download(url: string, fileName: string, responseMethod?: ResponseMethodBlob): DownloadBlob; public download(url: string, fileName: string, responseMethod?: ResponseMethodBlob): DownloadBlob;
public download(url: string, fileName: string, responseMethod?: ResponseMethodJson): DownloadJson; public download(url: string, fileName: string, responseMethod?: ResponseMethodJson): DownloadJson;
public download(url: string, fileName: string, responseMethod: ResponseMethod = 'blob'): Download { public download(url: string, fileName: string, responseMethod: ResponseMethod = 'blob'): DownloadBlob {
if(this.downloads.hasOwnProperty(fileName)) return this.downloads[fileName]; if(this.downloads.hasOwnProperty(fileName)) return this.downloads[fileName];
const deferred = deferredPromise<Blob>(); const deferred = deferredPromise<Blob>();

12
src/lib/appManagers/appImManager.ts

@ -2215,7 +2215,7 @@ export class AppImManager {
this.log('will wrap pending photo:', pending, message, appPhotosManager.getPhoto(message.id)); this.log('will wrap pending photo:', pending, message, appPhotosManager.getPhoto(message.id));
const tailSupported = !isAndroid; const tailSupported = !isAndroid;
if(tailSupported) bubble.classList.add('with-media-tail'); if(tailSupported) bubble.classList.add('with-media-tail');
wrapPhoto(message.id, message, attachmentDiv, undefined, undefined, tailSupported, true, this.lazyLoadQueue, null); wrapPhoto(appPhotosManager.getPhoto(message.id), message, attachmentDiv, undefined, undefined, tailSupported, true, this.lazyLoadQueue, null);
bubble.classList.add('hide-name', 'photo'); bubble.classList.add('hide-name', 'photo');
//} //}
@ -2304,7 +2304,7 @@ export class AppImManager {
} }
} }
wrapPhoto(photo.id, message, attachmentDiv, undefined, undefined, tailSupported, isOut, this.lazyLoadQueue, this.getMiddleware()); wrapPhoto(photo, message, attachmentDiv, undefined, undefined, tailSupported, isOut, this.lazyLoadQueue, this.getMiddleware());
break; break;
} }
@ -2401,7 +2401,7 @@ export class AppImManager {
bubble.classList.add('is-vertical-photo'); bubble.classList.add('is-vertical-photo');
} }
wrapPhoto(webpage.photo.id, message, preview, mediaSizes.active.webpage.width, mediaSizes.active.webpage.height, false, null, this.lazyLoadQueue, this.getMiddleware()); wrapPhoto(webpage.photo, message, preview, mediaSizes.active.webpage.width, mediaSizes.active.webpage.height, false, null, this.lazyLoadQueue, this.getMiddleware());
} }
box.append(quote); box.append(quote);
@ -2566,6 +2566,8 @@ export class AppImManager {
if((this.peerID < 0 && !our) || message.fwd_from || message.reply_to_mid) { // chat if((this.peerID < 0 && !our) || message.fwd_from || message.reply_to_mid) { // chat
let title = appPeersManager.getPeerTitle(message.fwdFromID || message.fromID); let title = appPeersManager.getPeerTitle(message.fwdFromID || message.fromID);
const isForwardFromChannel = !message.fromID && message.fwd_from;
let isHidden = message.fwd_from && !message.fwd_from.from_id && !message.fwd_from.channel_id; let isHidden = message.fwd_from && !message.fwd_from.from_id && !message.fwd_from.channel_id;
if(isHidden) { if(isHidden) {
@ -2594,7 +2596,7 @@ export class AppImManager {
nameDiv.classList.add('name'); nameDiv.classList.add('name');
nameDiv.dataset.peerID = message.fwdFromID; nameDiv.dataset.peerID = message.fwdFromID;
if(this.peerID == this.myID) { if(this.peerID == this.myID || isForwardFromChannel) {
nameDiv.style.color = appPeersManager.getPeerColorByID(message.fwdFromID, false); nameDiv.style.color = appPeersManager.getPeerColorByID(message.fwdFromID, false);
nameDiv.innerHTML = title; nameDiv.innerHTML = title;
} else { } else {
@ -2650,7 +2652,7 @@ export class AppImManager {
avatarElem.setAttribute('peer-title', message.fwd_from.from_name); avatarElem.setAttribute('peer-title', message.fwd_from.from_name);
} }
avatarElem.setAttribute('peer', '' + ((message.fwd_from && this.peerID == this.myID ? message.fwdFromID : message.fromID) || 0)); avatarElem.setAttribute('peer', '' + (((message.fwd_from && this.peerID == this.myID) || isForwardFromChannel ? message.fwdFromID : message.fromID) || 0));
avatarElem.update(); avatarElem.update();
//this.log('exec loadDialogPhoto', message); //this.log('exec loadDialogPhoto', message);

4
src/lib/appManagers/appMediaViewer.ts

@ -132,7 +132,7 @@ export class AppMediaViewer {
const download = (e: MouseEvent) => { const download = (e: MouseEvent) => {
let message = appMessagesManager.getMessage(this.currentMessageID); let message = appMessagesManager.getMessage(this.currentMessageID);
if(message.media.photo) { if(message.media.photo) {
appPhotosManager.savePhotoFile(message.media.photo.id); appPhotosManager.savePhotoFile(message.media.photo);
} else { } else {
let document: any = null; let document: any = null;
@ -759,7 +759,7 @@ export class AppMediaViewer {
//const maxWidth = appPhotosManager.windowW - 16; //const maxWidth = appPhotosManager.windowW - 16;
const maxWidth = mediaSizes.isMobile ? this.pageEl.scrollWidth : this.pageEl.scrollWidth - 16; const maxWidth = mediaSizes.isMobile ? this.pageEl.scrollWidth : this.pageEl.scrollWidth - 16;
const maxHeight = appPhotosManager.windowH - 100; const maxHeight = appPhotosManager.windowH - 100;
const size = appPhotosManager.setAttachmentSize(isVideo ? media : media.id, container, maxWidth, maxHeight); const size = appPhotosManager.setAttachmentSize(media, container, maxWidth, maxHeight);
// need after setAttachmentSize // need after setAttachmentSize
/* if(useContainerAsTarget) { /* if(useContainerAsTarget) {

2
src/lib/appManagers/appMessagesManager.ts

@ -1572,7 +1572,7 @@ export class AppMessagesManager {
if(messageMedia.photo) { if(messageMedia.photo) {
let photo = messageMedia.photo; let photo = messageMedia.photo;
appPhotosManager.savePhoto(photo); appPhotosManager.savePhoto(photo);
inputMedia = appPhotosManager.getInputByID(photo.id); inputMedia = appPhotosManager.getInput(photo);
} else { } else {
let doc = messageMedia.document; let doc = messageMedia.document;
appDocsManager.saveDoc(doc); appDocsManager.saveDoc(doc);

37
src/lib/appManagers/appPhotosManager.ts

@ -1,12 +1,12 @@
import { calcImageInBox, isObject, getFileURL } from "../utils"; import { calcImageInBox, isObject, getFileURL } from "../utils";
import { bytesFromHex, getFileNameByLocation } from "../bin_utils"; import { bytesFromHex, getFileNameByLocation } from "../bin_utils";
import { MTPhotoSize, inputPhotoFileLocation, inputDocumentFileLocation, FileLocation } from "../../types"; import { MTPhotoSize, inputPhotoFileLocation, inputDocumentFileLocation, FileLocation, MTDocument } from "../../types";
import appDownloadManager, { Download } from "./appDownloadManager"; import appDownloadManager, { Download } from "./appDownloadManager";
import { deferredPromise, CancellablePromise } from "../polyfill"; import { deferredPromise, CancellablePromise } from "../polyfill";
import { isSafari } from "../../helpers/userAgent"; import { isSafari } from "../../helpers/userAgent";
export type MTPhoto = { export type MTPhoto = {
_: 'photo' | 'photoEmpty' | string, _: 'photo' | 'photoEmpty',
pFlags: any, pFlags: any,
flags: number, flags: number,
id: string, id: string,
@ -61,7 +61,7 @@ export class AppPhotosManager {
return photo; return photo;
} }
public choosePhotoSize(photo: any, width = 0, height = 0) { public choosePhotoSize(photo: MTPhoto | MTDocument, width = 0, height = 0) {
//if(Config.Navigator.retina) { //if(Config.Navigator.retina) {
if(window.devicePixelRatio > 1) { if(window.devicePixelRatio > 1) {
width *= 2; width *= 2;
@ -80,14 +80,14 @@ export class AppPhotosManager {
d crop 1280x1280 */ d crop 1280x1280 */
let bestPhotoSize: MTPhotoSize = {_: 'photoSizeEmpty'}; let bestPhotoSize: MTPhotoSize = {_: 'photoSizeEmpty'};
let sizes = (photo.sizes || photo.thumbs) as typeof bestPhotoSize[]; const sizes = ((photo as MTPhoto).sizes || (photo as MTDocument).thumbs) as typeof bestPhotoSize[];
if(sizes) { if(sizes) {
for(let photoSize of sizes) { for(const photoSize of sizes) {
if(!photoSize.w || !photoSize.h) continue; if(!photoSize.w || !photoSize.h) continue;
bestPhotoSize = photoSize; bestPhotoSize = photoSize;
let {w, h} = calcImageInBox(photoSize.w, photoSize.h, width, height); const {w, h} = calcImageInBox(photoSize.w, photoSize.h, width, height);
if(w == width || h == height) { if(w == width || h == height) {
break; break;
} }
@ -142,7 +142,7 @@ export class AppPhotosManager {
return URL.createObjectURL(blob); return URL.createObjectURL(blob);
} }
public getPreviewURLFromThumb(thumb: any, isSticker = false) { public getPreviewURLFromThumb(thumb: MTPhotoSize, isSticker = false) {
return thumb.url ?? (thumb.url = this.getPreviewURLFromBytes(thumb.bytes, isSticker)); return thumb.url ?? (thumb.url = this.getPreviewURLFromBytes(thumb.bytes, isSticker));
} }
@ -171,21 +171,12 @@ export class AppPhotosManager {
} }
} }
public setAttachmentSize(photoID: any, element: HTMLElement | SVGForeignObjectElement, boxWidth: number, boxHeight: number, isSticker = false) { public setAttachmentSize(photo: MTPhoto | MTDocument, element: HTMLElement | SVGForeignObjectElement, boxWidth: number, boxHeight: number, isSticker = false, dontRenderPreview = false) {
let photo: /* MTDocument | MTPhoto */any = null;
if(typeof(photoID) === 'string') {
photo = this.photos[photoID];
if(!photo) return {_: 'photoEmpty'};
} else {
photo = photoID;
}
let photoSize = this.choosePhotoSize(photo, boxWidth, boxHeight); let photoSize = this.choosePhotoSize(photo, boxWidth, boxHeight);
//console.log('setAttachmentSize', photo, photo.sizes[0].bytes, div); //console.log('setAttachmentSize', photo, photo.sizes[0].bytes, div);
let sizes = photo.sizes || photo.thumbs; let sizes = (photo as MTPhoto).sizes || (photo as MTDocument).thumbs;
if(!photo.downloaded && !isSticker && sizes && sizes[0].bytes) { if((!photo.downloaded || (photo as MTDocument).type == 'video' || (photo as MTDocument).type == 'gif') && !isSticker && sizes && sizes[0].bytes && !dontRenderPreview) {
this.setAttachmentPreview(sizes[0].bytes, element, isSticker); this.setAttachmentPreview(sizes[0].bytes, element, isSticker);
} }
@ -213,7 +204,7 @@ export class AppPhotosManager {
return photoSize; return photoSize;
} }
public getPhotoURL(photo: MTPhoto, photoSize: MTPhotoSize) { public getPhotoURL(photo: MTPhoto | MTDocument, photoSize: MTPhotoSize) {
const isDocument = photo._ == 'document'; const isDocument = photo._ == 'document';
if(!photoSize || photoSize._ == 'photoSizeEmpty') { if(!photoSize || photoSize._ == 'photoSizeEmpty') {
@ -285,8 +276,7 @@ export class AppPhotosManager {
return isObject(photoID) ? photoID : this.photos[photoID]; return isObject(photoID) ? photoID : this.photos[photoID];
} }
public getInputByID(photoID: any) { public getInput(photo: MTPhoto) {
let photo = this.getPhoto(photoID);
return { return {
_: 'inputMediaPhoto', _: 'inputMediaPhoto',
flags: 0, flags: 0,
@ -300,8 +290,7 @@ export class AppPhotosManager {
}; };
} }
public savePhotoFile(photoID: string) { public savePhotoFile(photo: MTPhoto | MTDocument) {
const photo = this.photos[photoID];
const fullWidth = this.windowW; const fullWidth = this.windowW;
const fullHeight = this.windowH; const fullHeight = this.windowH;
const fullPhotoSize = this.choosePhotoSize(photo, fullWidth, fullHeight); const fullPhotoSize = this.choosePhotoSize(photo, fullWidth, fullHeight);

5
src/lib/mtproto/mtprotoworker.ts

@ -1,7 +1,7 @@
import {isObject, $rootScope} from '../utils'; import {isObject, $rootScope} from '../utils';
import AppStorage from '../storage'; import AppStorage from '../storage';
import CryptoWorkerMethods from '../crypto/crypto_methods'; import CryptoWorkerMethods from '../crypto/crypto_methods';
import runtime from 'serviceworker-webpack-plugin/lib/runtime'; //import runtime from 'serviceworker-webpack-plugin/lib/runtime';
import { logger } from '../logger'; import { logger } from '../logger';
import { webpWorkerController } from '../webp/webpWorkerController'; import { webpWorkerController } from '../webp/webpWorkerController';
@ -33,7 +33,8 @@ class ApiManagerProxy extends CryptoWorkerMethods {
/** /**
* Service worker * Service worker
*/ */
(runtime.register({ scope: '/' }) as Promise<ServiceWorkerRegistration>).then(registration => { //(runtime.register({ scope: './' }) as Promise<ServiceWorkerRegistration>).then(registration => {
navigator.serviceWorker.register('./sw.js', {scope: './'}).then(registration => {
}, (err) => { }, (err) => {
this.log.error('SW registration failed!', err); this.log.error('SW registration failed!', err);

2
src/lib/richtextprocessor.js

@ -8,7 +8,7 @@ var EmojiHelper = {
}; };
var emojiData = Config.Emoji; var emojiData = Config.Emoji;
var emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS/i) != -1/* && false */, var emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS/i) != -1/* && false *//* || true */,
emojiCode; emojiCode;
// added * to (?:[©®\\u2122\\u265f]\\ufe0f) and removed \\ufe0f from end // added * to (?:[©®\\u2122\\u265f]\\ufe0f) and removed \\ufe0f from end

3
src/scss/partials/_emojiDropdown.scss

@ -341,6 +341,9 @@
object-fit: cover; object-fit: cover;
width: 100%; width: 100%;
height: 100%; height: 100%;
}
img {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;

1
tsconfig.json

@ -71,5 +71,6 @@
"./src/lib/*.js", "./src/lib/*.js",
"./src/*.js", "./src/*.js",
"*.js", "*.js",
"public3"
] ]
} }

Loading…
Cancel
Save