Fix topic notifications

Fix add members layout
Support urlAuthRequest
This commit is contained in:
Eduard Kuzmenko 2023-01-08 18:07:01 +04:00
parent 2c96273e59
commit eb2b0aeb12
11 changed files with 180 additions and 19 deletions

View File

@ -29,7 +29,7 @@ import LazyLoadQueue from '../lazyLoadQueue';
import ListenerSetter from '../../helpers/listenerSetter'; import ListenerSetter from '../../helpers/listenerSetter';
import PollElement from '../poll'; import PollElement from '../poll';
import AudioElement from '../audio'; import AudioElement from '../audio';
import {Chat as MTChat, ChatInvite, Document, Message, MessageEntity, MessageMedia, MessageReplyHeader, Photo, PhotoSize, ReactionCount, ReplyMarkup, SponsoredMessage, Update, User, WebPage} from '../../layer'; import {Chat as MTChat, ChatInvite, Document, Message, MessageEntity, MessageMedia, MessageReplyHeader, Photo, PhotoSize, ReactionCount, ReplyMarkup, SponsoredMessage, Update, UrlAuthResult, User, WebPage} from '../../layer';
import {BOT_START_PARAM, NULL_PEER_ID, REPLIES_PEER_ID} from '../../lib/mtproto/mtproto_config'; import {BOT_START_PARAM, NULL_PEER_ID, REPLIES_PEER_ID} from '../../lib/mtproto/mtproto_config';
import {FocusDirection, ScrollStartCallbackDimensions} from '../../helpers/fastSmoothScroll'; import {FocusDirection, ScrollStartCallbackDimensions} from '../../helpers/fastSmoothScroll';
import useHeavyAnimationCheck, {getHeavyAnimationPromise, dispatchHeavyAnimationEvent, interruptHeavyAnimation} from '../../hooks/useHeavyAnimationCheck'; import useHeavyAnimationCheck, {getHeavyAnimationPromise, dispatchHeavyAnimationEvent, interruptHeavyAnimation} from '../../hooks/useHeavyAnimationCheck';
@ -128,6 +128,10 @@ import wrapUrl from '../../lib/richTextProcessor/wrapUrl';
import getMessageThreadId from '../../lib/appManagers/utils/messages/getMessageThreadId'; import getMessageThreadId from '../../lib/appManagers/utils/messages/getMessageThreadId';
import wrapTopicNameButton from '../wrappers/topicNameButton'; import wrapTopicNameButton from '../wrappers/topicNameButton';
import wrapMediaSpoiler from '../wrappers/mediaSpoiler'; import wrapMediaSpoiler from '../wrappers/mediaSpoiler';
import confirmationPopup from '../confirmationPopup';
import wrapPeerTitle from '../wrappers/peerTitle';
import {PopupPeerCheckboxOptions} from '../popups/peer';
import toggleDisability from '../../helpers/dom/toggleDisability';
export const USER_REACTIONS_INLINE = false; export const USER_REACTIONS_INLINE = false;
const USE_MEDIA_TAILS = false; const USE_MEDIA_TAILS = false;
@ -3970,6 +3974,105 @@ export default class ChatBubbles {
break; break;
} }
case 'keyboardButtonUrlAuth': {
buttonEl = document.createElement('button');
buttonEl.classList.add('is-url-auth');
const {peerId} = this;
const {mid} = message;
const {url, button_id} = button;
const openWindow = (url: string) => {
window.open(url, '_blank');
};
const onUrlAuthResultAccepted = (urlAuthResult: UrlAuthResult.urlAuthResultAccepted) => {
openWindow(urlAuthResult.url);
};
const onUrlAuthResult = async(urlAuthResult: UrlAuthResult): Promise<void> => {
if(urlAuthResult._ === 'urlAuthResultRequest') {
const b = document.createElement('b');
b.append(urlAuthResult.domain);
const peerTitle = await wrapPeerTitle({peerId: rootScope.myId});
const botPeerTitle = await wrapPeerTitle({peerId: urlAuthResult.bot.id.toPeerId()});
const logInCheckbox: PopupPeerCheckboxOptions = {
text: 'OpenUrlOption1',
textArgs: [b.cloneNode(true), peerTitle],
checked: true
};
const allowMessagesCheckbox: PopupPeerCheckboxOptions = urlAuthResult.pFlags.request_write_access ? {
text: 'OpenUrlOption2',
textArgs: [botPeerTitle],
checked: true
} : undefined;
const checkboxes: PopupPeerCheckboxOptions[] = [
logInCheckbox,
allowMessagesCheckbox
];
const confirmationPromise = confirmationPopup({
titleLangKey: 'OpenUrlTitle',
button: {
langKey: 'Open'
},
descriptionLangKey: 'OpenUrlAlert2',
descriptionLangArgs: [b],
checkboxes: checkboxes.filter(Boolean)
});
if(allowMessagesCheckbox) {
logInCheckbox.checkboxField.input.addEventListener('change', () => {
const disabled = !logInCheckbox.checkboxField.checked;
allowMessagesCheckbox.checkboxField.toggleDisability(disabled);
if(disabled) {
allowMessagesCheckbox.checkboxField.checked = false;
}
});
}
const [logInChecked, allowMessagesChecked] = await confirmationPromise;
if(!logInChecked) {
openWindow(url);
return;
}
const result = await this.managers.appMessagesManager.acceptUrlAuth(
peerId,
mid,
url,
button_id,
allowMessagesChecked
);
return onUrlAuthResult(result);
} else if(urlAuthResult._ === 'urlAuthResultAccepted') {
onUrlAuthResultAccepted(urlAuthResult);
} else {
openWindow(url);
}
};
attachClickEvent(buttonEl, () => {
const toggle = toggleDisability([buttonEl], true);
this.managers.appMessagesManager.requestUrlAuth(
peerId,
mid,
url,
button_id
).then((urlAuthResult) => {
toggle();
onUrlAuthResult(urlAuthResult);
});
});
break;
}
default: { default: {
buttonEl = document.createElement('button'); buttonEl = document.createElement('button');
break; break;
@ -4012,7 +4115,8 @@ export default class ChatBubbles {
!target || !target ||
target.classList.contains('is-link') || target.classList.contains('is-link') ||
target.classList.contains('is-switch-inline') || target.classList.contains('is-switch-inline') ||
target.classList.contains('is-buy') target.classList.contains('is-buy') ||
target.classList.contains('is-url-auth')
) return; ) return;
cancelEvent(e); cancelEvent(e);

View File

@ -5,7 +5,7 @@
*/ */
import {addCancelButton} from './popups'; import {addCancelButton} from './popups';
import PopupPeer, {PopupPeerOptions} from './popups/peer'; import PopupPeer, {PopupPeerCheckboxOptions, PopupPeerOptions} from './popups/peer';
// type PopupConfirmationOptions = Pick<PopupPeerOptions, 'titleLangKey'>; // type PopupConfirmationOptions = Pick<PopupPeerOptions, 'titleLangKey'>;
export type PopupConfirmationOptions = PopupPeerOptions & { export type PopupConfirmationOptions = PopupPeerOptions & {
@ -13,11 +13,17 @@ export type PopupConfirmationOptions = PopupPeerOptions & {
checkbox?: PopupPeerOptions['checkboxes'][0] checkbox?: PopupPeerOptions['checkboxes'][0]
}; };
export default function confirmationPopup(options: PopupConfirmationOptions) { export default function confirmationPopup<T extends PopupConfirmationOptions>(
return new Promise<boolean | void>((resolve, reject) => { options: T
): Promise<T['checkboxes'] extends PopupPeerCheckboxOptions[] ? Array<boolean> : (T['checkbox'] extends PopupPeerCheckboxOptions ? boolean : void)> {
return new Promise<any>((resolve, reject) => {
const {button, checkbox} = options; const {button, checkbox} = options;
button.callback = (set) => { button.callback = (set) => {
resolve(set ? !!set.size : undefined); if(checkbox || !set) {
resolve(set ? !!set.size : undefined);
} else {
resolve(options.checkboxes.map((checkbox) => set.has(checkbox.text)));
}
}; };
const buttons = addCancelButton(options.buttons || [button]); const buttons = addCancelButton(options.buttons || [button]);

View File

@ -21,7 +21,7 @@ const App = {
version: process.env.VERSION, version: process.env.VERSION,
versionFull: process.env.VERSION_FULL, versionFull: process.env.VERSION_FULL,
build: +process.env.BUILD, build: +process.env.BUILD,
langPackVersion: '0.7.3', langPackVersion: '0.7.5',
langPack: 'webk', langPack: 'webk',
langPackCode: 'en', langPackCode: 'en',
domains: MAIN_DOMAINS, domains: MAIN_DOMAINS,

View File

@ -853,6 +853,8 @@ const lang = {
'CreateGeneralTopicTitle': 'Choose topic name', 'CreateGeneralTopicTitle': 'Choose topic name',
'EditTopicHide': 'Show in Topics', 'EditTopicHide': 'Show in Topics',
'EditTopicHideInfo': 'If the \'General\' topic is hidden, group members can pull down in the topic list to view it.', 'EditTopicHideInfo': 'If the \'General\' topic is hidden, group members can pull down in the topic list to view it.',
'OpenUrlOption1': 'Log in to %1$s as **%2$s**',
'OpenUrlOption2': 'Allow **%1$s** to send me messages',
// * macos // * macos
'AccountSettings.Filters': 'Chat Folders', 'AccountSettings.Filters': 'Chat Folders',

View File

@ -1114,8 +1114,20 @@ class Some3 extends Some<ForumTopic> {
appDialogsManager.setUnreadMessagesN({dialog, dialogElement: this.getDialogElement(this.getDialogKey(dialog))}); appDialogsManager.setUnreadMessagesN({dialog, dialogElement: this.getDialogElement(this.getDialogKey(dialog))});
}); });
this.listenerSetter.add(rootScope)('dialog_notify_settings', (dialog) => { this.listenerSetter.add(rootScope)('dialog_notify_settings', async(dialog) => {
if(dialog._ !== 'forumTopic' || dialog.peerId !== this.peerId) { if(dialog.peerId !== this.peerId) {
return;
}
if(dialog._ === 'dialog') {
const all = this.sortedList.getAll();
const entries = [...all.entries()];
const promises = entries.map(([id]) => this.managers.dialogsStorage.getForumTopic(this.peerId, id));
const topics = await Promise.all(promises);
entries.forEach(([id, element], idx) => {
appDialogsManager.setUnreadMessagesN({dialog: topics[idx], dialogElement: element.dialogElement}); // возможно это не нужно, но нужно менять is-muted
});
return; return;
} }

View File

@ -13,7 +13,7 @@ import LazyLoadQueueBase from '../../components/lazyLoadQueueBase';
import deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise'; import deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise';
import tsNow from '../../helpers/tsNow'; import tsNow from '../../helpers/tsNow';
import {randomLong} from '../../helpers/random'; import {randomLong} from '../../helpers/random';
import {Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageMedia, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update, Photo, Updates, ReplyMarkup, InputPeer, InputPhoto, InputDocument, InputGeoPoint, WebPage, GeoPoint, ReportReason, MessagesGetDialogs, InputChannel, InputDialogPeer, ReactionCount, MessagePeerReaction, MessagesSearchCounter, Peer, MessageReactions, Document, InputFile, Reaction, ForumTopic as MTForumTopic, MessagesForumTopics, MessagesGetReplies, MessagesGetHistory, MessagesAffectedHistory} from '../../layer'; import {Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageMedia, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update, Photo, Updates, ReplyMarkup, InputPeer, InputPhoto, InputDocument, InputGeoPoint, WebPage, GeoPoint, ReportReason, MessagesGetDialogs, InputChannel, InputDialogPeer, ReactionCount, MessagePeerReaction, MessagesSearchCounter, Peer, MessageReactions, Document, InputFile, Reaction, ForumTopic as MTForumTopic, MessagesForumTopics, MessagesGetReplies, MessagesGetHistory, MessagesAffectedHistory, UrlAuthResult} from '../../layer';
import {ArgumentTypes, InvokeApiOptions} from '../../types'; import {ArgumentTypes, InvokeApiOptions} from '../../types';
import {logger, LogTypes} from '../logger'; import {logger, LogTypes} from '../logger';
import type {ApiFileManager} from '../mtproto/apiFileManager'; import type {ApiFileManager} from '../mtproto/apiFileManager';
@ -6399,4 +6399,31 @@ export class AppMessagesManager extends AppManager {
send_as: this.appPeersManager.getInputPeerById(sendAsPeerId) send_as: this.appPeersManager.getInputPeerById(sendAsPeerId)
}); });
} }
public requestUrlAuth(peerId: PeerId, mid: number, url: string, buttonId: number) {
return this.apiManager.invokeApi('messages.requestUrlAuth', {
button_id: buttonId,
msg_id: getServerMessageId(mid),
peer: this.appPeersManager.getInputPeerById(peerId),
url
}).then((urlAuthResult) => {
if(urlAuthResult._ === 'urlAuthResultRequest') {
this.appUsersManager.saveApiUser(urlAuthResult.bot);
}
return urlAuthResult;
});
}
public acceptUrlAuth(peerId: PeerId, mid: number, url: string, buttonId: number, writeAllowed?: boolean) {
return this.apiManager.invokeApi('messages.acceptUrlAuth', {
button_id: buttonId,
msg_id: getServerMessageId(mid),
peer: this.appPeersManager.getInputPeerById(peerId),
url,
write_allowed: writeAllowed
}).then((urlAuthResult) => {
return urlAuthResult as Exclude<UrlAuthResult, UrlAuthResult.urlAuthResultRequest>;
});
}
} }

View File

@ -300,10 +300,20 @@ export class AppNotificationsManager extends AppManager {
return options; return options;
} }
public isPeerLocalMuted(options: Parameters<AppNotificationsManager['getPeerLocalSettings']>[0]) { public isPeerLocalMuted(options: Parameters<AppNotificationsManager['getPeerLocalSettings']>[0]): boolean {
if(!(options = this.validatePeerSettings(options))) return false; if(!(options = this.validatePeerSettings(options))) return false;
if(options.threadId) {
const notifySettings = this.getPeerLocalSettings({...options, respectType: false});
if(notifySettings.silent !== undefined || notifySettings.mute_until !== undefined) {
return this.isMuted(notifySettings);
} else {
return this.isPeerLocalMuted({...options, threadId: undefined});
}
}
const notifySettings = this.getPeerLocalSettings(options); const notifySettings = this.getPeerLocalSettings(options);
return this.isMuted(notifySettings); const isMuted = this.isMuted(notifySettings);
return isMuted;
} }
} }

View File

@ -191,7 +191,11 @@ export class AppPeersManager extends AppManager {
peerId: PeerId, peerId: PeerId,
ignorePeerId?: boolean, ignorePeerId?: boolean,
threadId?: number threadId?: number
}>({peerId, ignorePeerId, threadId}: T): T['ignorePeerId'] extends true ? Exclude<InputNotifyPeer, InputNotifyPeer.inputNotifyPeer | InputNotifyPeer.inputNotifyForumTopic> : (T['threadId'] extends number ? InputNotifyPeer.inputNotifyForumTopic : InputNotifyPeer.inputNotifyPeer) { }>({
peerId,
ignorePeerId,
threadId
}: T): T['ignorePeerId'] extends true ? Exclude<InputNotifyPeer, InputNotifyPeer.inputNotifyPeer | InputNotifyPeer.inputNotifyForumTopic> : (T['threadId'] extends number ? InputNotifyPeer.inputNotifyForumTopic : InputNotifyPeer.inputNotifyPeer) {
if(ignorePeerId) { if(ignorePeerId) {
if(peerId.isUser()) { if(peerId.isUser()) {
return {_: 'inputNotifyUsers'} as any; return {_: 'inputNotifyUsers'} as any;

View File

@ -335,7 +335,7 @@ $btn-menu-z-index: 4;
font-size: .75rem; font-size: .75rem;
width: fit-content; width: fit-content;
min-width: calc(100% - .625rem); min-width: calc(100% - .625rem);
max-width: fit-content; max-width: 16.25rem;
.btn-menu-item-text { .btn-menu-item-text {
white-space: pre-wrap; white-space: pre-wrap;

View File

@ -255,10 +255,6 @@ ul.chatlist {
} }
} }
&.menu-open {
--background: var(--light-secondary-text-color);
}
@include respond-to(not-handhelds) { @include respond-to(not-handhelds) {
&.active { &.active {
--background: var(--primary-color) !important; --background: var(--primary-color) !important;

View File

@ -190,7 +190,7 @@
left: 1.25rem !important; left: 1.25rem !important;
} }
.chatlist-chat { .chatlist-chat.row-with-padding {
padding-left: #{4.5rem + $add} !important; // 4.5 + x padding-left: #{4.5rem + $add} !important; // 4.5 + x
} }