Browse Source

Merge branch 'master' into viewer-fixes

master
Eduard Kuzmenko 3 years ago committed by GitHub
parent
commit
d10f355031
  1. 11
      src/components/buttonMenu.ts
  2. 4
      src/components/wrappers.ts
  3. 14
      src/layer.d.ts
  4. 1
      src/lib/appManagers/apiUpdatesManager.ts
  5. 2
      src/lib/appManagers/appDraftsManager.ts
  6. 21
      src/lib/appManagers/appMessagesManager.ts
  7. 1
      src/lib/appManagers/appStickersManager.ts
  8. 22
      src/lib/mediaPlayer.ts
  9. 54
      src/lib/mtproto/apiFileManager.ts
  10. 3
      src/lib/mtproto/mtproto.worker.ts
  11. 12
      src/scripts/in/schema_additional_params.json
  12. 12
      src/scss/partials/_ckin.scss

11
src/components/buttonMenu.ts

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

4
src/components/wrappers.ts

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

14
src/layer.d.ts vendored

@ -855,7 +855,8 @@ export namespace Message {
fromId?: number, fromId?: number,
random_id?: string, random_id?: string,
rReply?: string, rReply?: string,
viaBotId?: number viaBotId?: number,
clear_history?: boolean
}; };
export type messageService = { export type messageService = {
@ -1881,7 +1882,7 @@ export namespace MessagesFilter {
/** /**
* @link https://core.telegram.org/type/Update * @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 namespace Update {
export type updateNewMessage = { export type updateNewMessage = {
@ -2195,7 +2196,8 @@ export namespace Update {
_: 'updateDraftMessage', _: 'updateDraftMessage',
peer: Peer, peer: Peer,
draft: DraftMessage, draft: DraftMessage,
local?: boolean local?: boolean,
threadId?: number
}; };
export type updateReadFeaturedStickers = { export type updateReadFeaturedStickers = {
@ -2552,6 +2554,11 @@ export namespace Update {
messages?: number[], messages?: number[],
channel_id?: number channel_id?: number
}; };
export type updateChannelReload = {
_: 'updateChannelReload',
channel_id?: number
};
} }
/** /**
@ -9821,6 +9828,7 @@ export interface ConstructorDeclMap {
'messageActionChatReturnYou': MessageAction.messageActionChatReturnYou, 'messageActionChatReturnYou': MessageAction.messageActionChatReturnYou,
'updateNewDiscussionMessage': Update.updateNewDiscussionMessage, 'updateNewDiscussionMessage': Update.updateNewDiscussionMessage,
'updateDeleteDiscussionMessages': Update.updateDeleteDiscussionMessages, 'updateDeleteDiscussionMessages': Update.updateDeleteDiscussionMessages,
'updateChannelReload': Update.updateChannelReload,
} }
export type InvokeAfterMsg = { export type InvokeAfterMsg = {

1
src/lib/appManagers/apiUpdatesManager.ts

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

2
src/lib/appManagers/appDraftsManager.ts

@ -37,7 +37,7 @@ export class AppDraftsManager {
rootScope.addMultipleEventsListeners({ rootScope.addMultipleEventsListeners({
updateDraftMessage: (update) => { updateDraftMessage: (update) => {
const peerID = appPeersManager.getPeerId(update.peer); 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});
} }
}); });
} }

21
src/lib/appManagers/appMessagesManager.ts

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

1
src/lib/appManagers/appStickersManager.ts

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

22
src/lib/mediaPlayer.ts

@ -11,6 +11,8 @@ import RangeSelector from "../components/rangeSelector";
import { onVideoLoad } from "../helpers/files"; import { onVideoLoad } from "../helpers/files";
import { cancelEvent } from "../helpers/dom/cancelEvent"; import { cancelEvent } from "../helpers/dom/cancelEvent";
import ListenerSetter from "../helpers/listenerSetter"; import ListenerSetter from "../helpers/listenerSetter";
import ButtonMenu from "../components/buttonMenu";
import { ButtonMenuToggleHandler } from "../components/buttonMenuToggle";
export class MediaProgressLine extends RangeSelector { export class MediaProgressLine extends RangeSelector {
private filledLoad: HTMLDivElement; private filledLoad: HTMLDivElement;
@ -187,6 +189,7 @@ export default class VideoPlayer {
this.skin = video.dataset.ckin ?? 'default'; this.skin = video.dataset.ckin ?? 'default';
this.stylePlayer(duration); this.stylePlayer(duration);
this.setBtnMenuToggle();
if(this.skin === 'default') { if(this.skin === 'default') {
const controls = this.wrapper.querySelector('.default__controls.ckin__controls') as HTMLDivElement; 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="${skin}__controls ckin__controls">
<div class="bottom-controls"> <div class="bottom-controls">
<div class="left-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"> <div class="time">
<time id="time-elapsed">0:00</time> <time id="time-elapsed">0:00</time>
<span> / </span> <span> / </span>
@ -420,13 +423,28 @@ export default class VideoPlayer {
</div> </div>
</div> </div>
<div class="right-controls"> <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> </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 { public static isFullScreen(): boolean {
// @ts-ignore // @ts-ignore
return !!(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement); return !!(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement);

54
src/lib/mtproto/apiFileManager.ts

@ -27,6 +27,7 @@ import apiManager from "./apiManager";
import { isWebpSupported } from "./mtproto.worker"; import { isWebpSupported } from "./mtproto.worker";
import { bytesToHex } from "../../helpers/bytes"; import { bytesToHex } from "../../helpers/bytes";
import assumeType from "../../helpers/assumeType"; import assumeType from "../../helpers/assumeType";
import { ctx } from "../../helpers/userAgent";
type Delayed = { type Delayed = {
offset: number, offset: number,
@ -86,7 +87,12 @@ export class ApiFileManager {
private downloadActives: {[dcId: string]: number} = {}; private downloadActives: {[dcId: string]: number} = {};
public webpConvertPromises: {[fileName: string]: CancellablePromise<Uint8Array>} = {}; 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 log: ReturnType<typeof logger> = logger('AFM', LogTypes.Error | LogTypes.Log);
private tempId = 0; private tempId = 0;
@ -96,7 +102,7 @@ export class ApiFileManager {
constructor() { constructor() {
setInterval(() => { // clear old promises setInterval(() => { // clear old promises
for(const hex in this.refreshReferencePromises) { for(const hex in this.refreshReferencePromises) {
const deferred = this.refreshReferencePromises[hex]; const {deferred} = this.refreshReferencePromises[hex];
if(deferred.isFulfilled || deferred.isRejected) { if(deferred.isFulfilled || deferred.isRejected) {
delete this.refreshReferencePromises[hex]; 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) { 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(); checkCancel && checkCancel();
const invoke = (): Promise<MyUploadFile> => { const invoke = (): Promise<MyUploadFile> => {
checkCancel && checkCancel();
const promise = apiManager.invokeApi('upload.getFile', { const promise = apiManager.invokeApi('upload.getFile', {
location, location,
offset, offset,
@ -199,7 +207,7 @@ export class ApiFileManager {
return promise.catch((err) => { return promise.catch((err) => {
if(err.type === 'FILE_REFERENCE_EXPIRED') { if(err.type === 'FILE_REFERENCE_EXPIRED') {
return this.refreshReference(location).then(() => invoke()); return this.refreshReference(location).then(invoke);
} }
throw err; throw err;
@ -212,7 +220,7 @@ export class ApiFileManager {
location.checkedReference = true; location.checkedReference = true;
const hex = bytesToHex(reference); const hex = bytesToHex(reference);
if(this.refreshReferencePromises[hex]) { 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) { private refreshReference(inputFileLocation: InputFileLocation) {
const reference = (inputFileLocation as InputFileLocation.inputDocumentFileLocation).file_reference; const reference = (inputFileLocation as InputFileLocation.inputDocumentFileLocation).file_reference;
const hex = bytesToHex(reference); const hex = bytesToHex(reference);
let promise = this.refreshReferencePromises[hex];
const havePromise = !!promise;
if(!havePromise) { let r = this.refreshReferencePromises[hex];
promise = deferredPromise<ReferenceBytes>(); if(!r) {
this.refreshReferencePromises[hex] = promise; 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)) { if(hex === bytesToHex(reference)) {
throw 'REFERENCE_IS_NOT_REFRESHED'; 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> { public downloadFile(options: DownloadOptions): CancellablePromise<Blob> {

3
src/lib/mtproto/mtproto.worker.ts

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

12
src/scripts/in/schema_additional_params.json

@ -51,7 +51,8 @@
{"name": "unread", "type": "true"}, {"name": "unread", "type": "true"},
{"name": "is_outgoing", "type": "true"}, {"name": "is_outgoing", "type": "true"},
{"name": "rReply", "type": "string"}, {"name": "rReply", "type": "string"},
{"name": "viaBotId", "type": "number"} {"name": "viaBotId", "type": "number"},
{"name": "clear_history", "type": "boolean"}
] ]
}, { }, {
"predicate": "messageService", "predicate": "messageService",
@ -233,8 +234,15 @@
}, { }, {
"predicate": "updateDraftMessage", "predicate": "updateDraftMessage",
"params": [ "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", "predicate": "messages.stickerSet",
"params": [ "params": [

12
src/scss/partials/_ckin.scss

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

Loading…
Cancel
Save