Merge branch 'master' into viewer-fixes

This commit is contained in:
Eduard Kuzmenko 2021-07-19 23:00:39 +03:00 committed by GitHub
commit 4fa28662f2
35 changed files with 130 additions and 85 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,8 +13,9 @@ import { closeBtnMenu } from "./misc";
import { ripple } from "./ripple";
export type ButtonMenuItemOptions = {
icon: string,
text: LangPackKey,
icon?: string,
text?: LangPackKey,
regularText?: string,
onClick: (e: MouseEvent | TouchEvent) => void,
element?: HTMLElement,
options?: AttachClickOptions,
@ -28,9 +29,11 @@ const ButtonMenuItem = (options: ButtonMenuItemOptions) => {
const {icon, text, onClick} = options;
const el = document.createElement('div');
el.className = 'btn-menu-item tgico-' + icon;
el.className = 'btn-menu-item' + (icon ? ' tgico-' + icon : '');
ripple(el);
const t = i18n(text);
const t = text ? i18n(text) : document.createElement('span');
if(options.regularText) t.innerHTML = options.regularText;
t.classList.add('btn-menu-item-text');
el.append(t);

View File

@ -331,7 +331,9 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
video.addEventListener('error', (e) => {
console.error("Error " + video.error.code + "; details: " + video.error.message);
preloader.detach();
if(preloader) {
preloader.detach();
}
}, {once: true});
if(!noAutoDownload && f) {

14
src/layer.d.ts vendored
View File

@ -855,7 +855,8 @@ export namespace Message {
fromId?: number,
random_id?: string,
rReply?: string,
viaBotId?: number
viaBotId?: number,
clear_history?: boolean
};
export type messageService = {
@ -1881,7 +1882,7 @@ export namespace MessagesFilter {
/**
* @link https://core.telegram.org/type/Update
*/
export type Update = Update.updateNewMessage | Update.updateMessageID | Update.updateDeleteMessages | Update.updateUserTyping | Update.updateChatUserTyping | Update.updateChatParticipants | Update.updateUserStatus | Update.updateUserName | Update.updateUserPhoto | Update.updateNewEncryptedMessage | Update.updateEncryptedChatTyping | Update.updateEncryption | Update.updateEncryptedMessagesRead | Update.updateChatParticipantAdd | Update.updateChatParticipantDelete | Update.updateDcOptions | Update.updateNotifySettings | Update.updateServiceNotification | Update.updatePrivacy | Update.updateUserPhone | Update.updateReadHistoryInbox | Update.updateReadHistoryOutbox | Update.updateWebPage | Update.updateReadMessagesContents | Update.updateChannelTooLong | Update.updateChannel | Update.updateNewChannelMessage | Update.updateReadChannelInbox | Update.updateDeleteChannelMessages | Update.updateChannelMessageViews | Update.updateChatParticipantAdmin | Update.updateNewStickerSet | Update.updateStickerSetsOrder | Update.updateStickerSets | Update.updateSavedGifs | Update.updateBotInlineQuery | Update.updateBotInlineSend | Update.updateEditChannelMessage | Update.updateBotCallbackQuery | Update.updateEditMessage | Update.updateInlineBotCallbackQuery | Update.updateReadChannelOutbox | Update.updateDraftMessage | Update.updateReadFeaturedStickers | Update.updateRecentStickers | Update.updateConfig | Update.updatePtsChanged | Update.updateChannelWebPage | Update.updateDialogPinned | Update.updatePinnedDialogs | Update.updateBotWebhookJSON | Update.updateBotWebhookJSONQuery | Update.updateBotShippingQuery | Update.updateBotPrecheckoutQuery | Update.updatePhoneCall | Update.updateLangPackTooLong | Update.updateLangPack | Update.updateFavedStickers | Update.updateChannelReadMessagesContents | Update.updateContactsReset | Update.updateChannelAvailableMessages | Update.updateDialogUnreadMark | Update.updateMessagePoll | Update.updateChatDefaultBannedRights | Update.updateFolderPeers | Update.updatePeerSettings | Update.updatePeerLocated | Update.updateNewScheduledMessage | Update.updateDeleteScheduledMessages | Update.updateTheme | Update.updateGeoLiveViewed | Update.updateLoginToken | Update.updateMessagePollVote | Update.updateDialogFilter | Update.updateDialogFilterOrder | Update.updateDialogFilters | Update.updatePhoneCallSignalingData | Update.updateChannelMessageForwards | Update.updateReadChannelDiscussionInbox | Update.updateReadChannelDiscussionOutbox | Update.updatePeerBlocked | Update.updateChannelUserTyping | Update.updatePinnedMessages | Update.updatePinnedChannelMessages | Update.updateChat | Update.updateGroupCallParticipants | Update.updateGroupCall | Update.updatePeerHistoryTTL | Update.updateChatParticipant | Update.updateChannelParticipant | Update.updateBotStopped | Update.updateGroupCallConnection | Update.updateBotCommands | Update.updateNewDiscussionMessage | Update.updateDeleteDiscussionMessages;
export type Update = Update.updateNewMessage | Update.updateMessageID | Update.updateDeleteMessages | Update.updateUserTyping | Update.updateChatUserTyping | Update.updateChatParticipants | Update.updateUserStatus | Update.updateUserName | Update.updateUserPhoto | Update.updateNewEncryptedMessage | Update.updateEncryptedChatTyping | Update.updateEncryption | Update.updateEncryptedMessagesRead | Update.updateChatParticipantAdd | Update.updateChatParticipantDelete | Update.updateDcOptions | Update.updateNotifySettings | Update.updateServiceNotification | Update.updatePrivacy | Update.updateUserPhone | Update.updateReadHistoryInbox | Update.updateReadHistoryOutbox | Update.updateWebPage | Update.updateReadMessagesContents | Update.updateChannelTooLong | Update.updateChannel | Update.updateNewChannelMessage | Update.updateReadChannelInbox | Update.updateDeleteChannelMessages | Update.updateChannelMessageViews | Update.updateChatParticipantAdmin | Update.updateNewStickerSet | Update.updateStickerSetsOrder | Update.updateStickerSets | Update.updateSavedGifs | Update.updateBotInlineQuery | Update.updateBotInlineSend | Update.updateEditChannelMessage | Update.updateBotCallbackQuery | Update.updateEditMessage | Update.updateInlineBotCallbackQuery | Update.updateReadChannelOutbox | Update.updateDraftMessage | Update.updateReadFeaturedStickers | Update.updateRecentStickers | Update.updateConfig | Update.updatePtsChanged | Update.updateChannelWebPage | Update.updateDialogPinned | Update.updatePinnedDialogs | Update.updateBotWebhookJSON | Update.updateBotWebhookJSONQuery | Update.updateBotShippingQuery | Update.updateBotPrecheckoutQuery | Update.updatePhoneCall | Update.updateLangPackTooLong | Update.updateLangPack | Update.updateFavedStickers | Update.updateChannelReadMessagesContents | Update.updateContactsReset | Update.updateChannelAvailableMessages | Update.updateDialogUnreadMark | Update.updateMessagePoll | Update.updateChatDefaultBannedRights | Update.updateFolderPeers | Update.updatePeerSettings | Update.updatePeerLocated | Update.updateNewScheduledMessage | Update.updateDeleteScheduledMessages | Update.updateTheme | Update.updateGeoLiveViewed | Update.updateLoginToken | Update.updateMessagePollVote | Update.updateDialogFilter | Update.updateDialogFilterOrder | Update.updateDialogFilters | Update.updatePhoneCallSignalingData | Update.updateChannelMessageForwards | Update.updateReadChannelDiscussionInbox | Update.updateReadChannelDiscussionOutbox | Update.updatePeerBlocked | Update.updateChannelUserTyping | Update.updatePinnedMessages | Update.updatePinnedChannelMessages | Update.updateChat | Update.updateGroupCallParticipants | Update.updateGroupCall | Update.updatePeerHistoryTTL | Update.updateChatParticipant | Update.updateChannelParticipant | Update.updateBotStopped | Update.updateGroupCallConnection | Update.updateBotCommands | Update.updateNewDiscussionMessage | Update.updateDeleteDiscussionMessages | Update.updateChannelReload;
export namespace Update {
export type updateNewMessage = {
@ -2195,7 +2196,8 @@ export namespace Update {
_: 'updateDraftMessage',
peer: Peer,
draft: DraftMessage,
local?: boolean
local?: boolean,
threadId?: number
};
export type updateReadFeaturedStickers = {
@ -2552,6 +2554,11 @@ export namespace Update {
messages?: number[],
channel_id?: number
};
export type updateChannelReload = {
_: 'updateChannelReload',
channel_id?: number
};
}
/**
@ -9821,6 +9828,7 @@ export interface ConstructorDeclMap {
'messageActionChatReturnYou': MessageAction.messageActionChatReturnYou,
'updateNewDiscussionMessage': Update.updateNewDiscussionMessage,
'updateDeleteDiscussionMessages': Update.updateDeleteDiscussionMessages,
'updateChannelReload': Update.updateChannelReload,
}
export type InvokeAfterMsg = {

View File

@ -366,7 +366,6 @@ export class ApiUpdatesManager {
this.debug && this.log.debug('channel diff too long', differenceResult);
delete this.channelStates[channelId];
// @ts-ignore
this.saveUpdate({_: 'updateChannelReload', channel_id: channelId});
return;
}

View File

@ -37,7 +37,7 @@ export class AppDraftsManager {
rootScope.addMultipleEventsListeners({
updateDraftMessage: (update) => {
const peerID = appPeersManager.getPeerId(update.peer);
this.saveDraft(peerID, (update as any).threadId, update.draft, {notify: true});
this.saveDraft(peerID, update.threadId, update.draft, {notify: true});
}
});
}

View File

@ -238,7 +238,6 @@ export class AppMessagesManager {
updateChannel: this.onUpdateChannel,
// @ts-ignore
updateChannelReload: this.onUpdateChannelReload,
updateChannelMessageViews: this.onUpdateChannelMessageViews,
@ -4017,8 +4016,7 @@ export class AppMessagesManager {
const dialog = this.getDialogOnly(peerId);
const isTopMessage = dialog && dialog.top_message === mid;
// @ts-ignore
if(message.clear_history) { // that's will never happen
if((message as Message.message).clear_history) {
if(isTopMessage) {
rootScope.dispatchEvent('dialog_flush', {peerId});
}
@ -4263,9 +4261,8 @@ export class AppMessagesManager {
}
};
private onUpdateChannelReload = (update: any) => {
// @ts-ignore
const channelId: number = update.channel_id;
private onUpdateChannelReload = (update: Update.updateChannelReload) => {
const channelId = update.channel_id;
const peerId = -channelId;
this.dialogsStorage.dropDialog(peerId);
@ -5104,20 +5101,18 @@ export class AppMessagesManager {
});
}
private handleReleasingMessage(message: any) {
if((message as Message.message).media) {
private handleReleasingMessage(message: MyMessage) {
if('media' in message) {
// @ts-ignore
const c = message.media.webpage || message.media;
const smth = c.photo || c.document;
const smth: Photo.photo | MyDocument = c.photo || c.document;
if(smth?.file_reference) {
referenceDatabase.deleteContext(smth.file_reference, {type: 'message', peerId: message.peerId, messageId: message.mid});
}
// @ts-ignore
if(message.media.webpage) {
// @ts-ignore
appWebPagesManager.deleteWebPageFromPending(message.media.webpage, mid);
if('webpage' in message.media) {
appWebPagesManager.deleteWebPageFromPending(message.media.webpage, message.mid);
}
}
}

View File

@ -55,6 +55,7 @@ export class AppStickersManager {
if(!this.getGreetingStickersPromise) {
this.getGreetingStickersPromise = this.getStickersByEmoticon('👋⭐️', false).then(docs => {
if(!docs.length) throw 'NO_STICKERS';
this.greetingStickers = docs.slice() as Document.document[];
this.greetingStickers.sort((a, b) => Math.random() - Math.random());
});

View File

@ -11,6 +11,8 @@ import RangeSelector from "../components/rangeSelector";
import { onVideoLoad } from "../helpers/files";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import ListenerSetter from "../helpers/listenerSetter";
import ButtonMenu from "../components/buttonMenu";
import { ButtonMenuToggleHandler } from "../components/buttonMenuToggle";
export class MediaProgressLine extends RangeSelector {
private filledLoad: HTMLDivElement;
@ -187,6 +189,7 @@ export default class VideoPlayer {
this.skin = video.dataset.ckin ?? 'default';
this.stylePlayer(duration);
this.setBtnMenuToggle();
if(this.skin === 'default') {
const controls = this.wrapper.querySelector('.default__controls.ckin__controls') as HTMLDivElement;
@ -412,7 +415,7 @@ export default class VideoPlayer {
<div class="${skin}__controls ckin__controls">
<div class="bottom-controls">
<div class="left-controls">
<button class="${skin}__button toggle tgico" title="Toggle Video"></button>
<button class="btn-icon ${skin}__button toggle tgico" title="Toggle Video"></button>
<div class="time">
<time id="time-elapsed">0:00</time>
<span> / </span>
@ -420,13 +423,28 @@ export default class VideoPlayer {
</div>
</div>
<div class="right-controls">
<button class="${skin}__button fullscreen tgico-fullscreen" title="Full Screen"></button>
<button class="btn-icon ${skin}__button btn-menu-toggle settings tgico-settings" title="Playback Rate"></button>
<button class="btn-icon ${skin}__button fullscreen tgico-fullscreen" title="Full Screen"></button>
</div>
</div>
</div>`;
}
}
protected setBtnMenuToggle() {
const buttons: Parameters<typeof ButtonMenu>[0] = [0.25, 0.5, 1, 1.25, 1.5, 2].map((rate) => {
return {
regularText: rate === 1 ? 'Normal' : '' + rate,
onClick: () => this.video.playbackRate = rate
};
});
const btnMenu = ButtonMenu(buttons);
const settingsButton = this.wrapper.querySelector('.settings') as HTMLElement;
btnMenu.classList.add('top-left');
ButtonMenuToggleHandler(settingsButton);
settingsButton.append(btnMenu);
}
public static isFullScreen(): boolean {
// @ts-ignore
return !!(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement);

View File

@ -27,6 +27,7 @@ import apiManager from "./apiManager";
import { isWebpSupported } from "./mtproto.worker";
import { bytesToHex } from "../../helpers/bytes";
import assumeType from "../../helpers/assumeType";
import { ctx } from "../../helpers/userAgent";
type Delayed = {
offset: number,
@ -86,7 +87,12 @@ export class ApiFileManager {
private downloadActives: {[dcId: string]: number} = {};
public webpConvertPromises: {[fileName: string]: CancellablePromise<Uint8Array>} = {};
public refreshReferencePromises: {[referenceHex: string]: CancellablePromise<ReferenceBytes>} = {};
public refreshReferencePromises: {
[referenceHex: string]: {
deferred: CancellablePromise<ReferenceBytes>,
timeout: number
}
} = {};
private log: ReturnType<typeof logger> = logger('AFM', LogTypes.Error | LogTypes.Log);
private tempId = 0;
@ -96,7 +102,7 @@ export class ApiFileManager {
constructor() {
setInterval(() => { // clear old promises
for(const hex in this.refreshReferencePromises) {
const deferred = this.refreshReferencePromises[hex];
const {deferred} = this.refreshReferencePromises[hex];
if(deferred.isFulfilled || deferred.isRejected) {
delete this.refreshReferencePromises[hex];
}
@ -184,10 +190,12 @@ export class ApiFileManager {
}
public requestFilePart(dcId: DcId, location: InputFileLocation, offset: number, limit: number, id = 0, queueId = 0, checkCancel?: () => void) {
return this.downloadRequest(dcId, id, async() => {
return this.downloadRequest(dcId, id, () => {
checkCancel && checkCancel();
const invoke = (): Promise<MyUploadFile> => {
checkCancel && checkCancel();
const promise = apiManager.invokeApi('upload.getFile', {
location,
offset,
@ -199,7 +207,7 @@ export class ApiFileManager {
return promise.catch((err) => {
if(err.type === 'FILE_REFERENCE_EXPIRED') {
return this.refreshReference(location).then(() => invoke());
return this.refreshReference(location).then(invoke);
}
throw err;
@ -212,7 +220,7 @@ export class ApiFileManager {
location.checkedReference = true;
const hex = bytesToHex(reference);
if(this.refreshReferencePromises[hex]) {
return this.refreshReference(location).then(() => invoke());
return this.refreshReference(location).then(invoke);
}
}
@ -256,29 +264,35 @@ export class ApiFileManager {
private refreshReference(inputFileLocation: InputFileLocation) {
const reference = (inputFileLocation as InputFileLocation.inputDocumentFileLocation).file_reference;
const hex = bytesToHex(reference);
let promise = this.refreshReferencePromises[hex];
const havePromise = !!promise;
if(!havePromise) {
promise = deferredPromise<ReferenceBytes>();
this.refreshReferencePromises[hex] = promise;
let r = this.refreshReferencePromises[hex];
if(!r) {
const deferred = deferredPromise<ReferenceBytes>();
r = this.refreshReferencePromises[hex] = {
deferred,
timeout: ctx.setTimeout(() => {
this.log.error('Didn\'t refresh the reference:', inputFileLocation);
deferred.reject('REFERENCE_IS_NOT_REFRESHED');
}, 60000)
};
deferred.finally(() => {
clearTimeout(r.timeout);
});
const task = {type: 'refreshReference', payload: reference};
notifySomeone(task);
}
promise = promise.then(reference => {
// have to replace file_reference in any way, because location can be different everytime if it's stream
return r.deferred.then(reference => {
if(hex === bytesToHex(reference)) {
throw 'REFERENCE_IS_NOT_REFRESHED';
}
return (inputFileLocation as InputFileLocation.inputDocumentFileLocation).file_reference = reference;
(inputFileLocation as InputFileLocation.inputDocumentFileLocation).file_reference = reference;
});
if(havePromise) {
return promise;
}
const task = {type: 'refreshReference', payload: reference};
notifySomeone(task);
return this.refreshReferencePromises[hex] = promise;
}
public downloadFile(options: DownloadOptions): CancellablePromise<Blob> {

View File

@ -88,7 +88,8 @@ const taskListeners = {
refreshReference: (task: RefreshReferenceTaskResponse) => {
const hex = bytesToHex(task.originalPayload);
const deferred = apiFileManager.refreshReferencePromises[hex];
const r = apiFileManager.refreshReferencePromises[hex];
const deferred = r?.deferred;
if(deferred) {
if(task.error) {
deferred.reject(task.error);

View File

@ -51,7 +51,8 @@
{"name": "unread", "type": "true"},
{"name": "is_outgoing", "type": "true"},
{"name": "rReply", "type": "string"},
{"name": "viaBotId", "type": "number"}
{"name": "viaBotId", "type": "number"},
{"name": "clear_history", "type": "boolean"}
]
}, {
"predicate": "messageService",
@ -233,8 +234,15 @@
}, {
"predicate": "updateDraftMessage",
"params": [
{"name": "local", "type": "boolean"}
{"name": "local", "type": "boolean"},
{"name": "threadId", "type": "number"}
]
}, {
"predicate": "updateChannelReload",
"params": [
{"name": "channel_id", "type": "number"}
],
"type": "Update"
}, {
"predicate": "messages.stickerSet",
"params": [

View File

@ -94,16 +94,10 @@
}
&__button {
background: none;
border: 0;
width: 2rem;
height: 2rem;
color: #fff;
outline: 0;
padding: 0 .625rem;
cursor: pointer;
font-size: 1.5rem;
line-height: 1;
display: flex;
align-items: center;
@include respond-to(handhelds) {
font-size: 1.375rem;
@ -428,6 +422,8 @@ input[type=range] {
}
.right-controls {
display: flex;
align-items: center;
float: right;
}