Top bar menu:
Add contact Block/unblock Fix Firefox scrollbar Fix selecting text in country input
This commit is contained in:
parent
f48ae2d013
commit
306478b7d5
@ -35,13 +35,14 @@ import blurActiveElement from "../../helpers/dom/blurActiveElement";
|
||||
import { cancelEvent } from "../../helpers/dom/cancelEvent";
|
||||
import { attachClickEvent } from "../../helpers/dom/clickEvent";
|
||||
import findUpTag from "../../helpers/dom/findUpTag";
|
||||
import { toast } from "../toast";
|
||||
import { toast, toastNew } from "../toast";
|
||||
import replaceContent from "../../helpers/dom/replaceContent";
|
||||
import { ChatFull } from "../../layer";
|
||||
import PopupPickUser from "../popups/pickUser";
|
||||
import PopupPeer from "../popups/peer";
|
||||
import generateVerifiedIcon from "../generateVerifiedIcon";
|
||||
import { fastRaf } from "../../helpers/schedulers";
|
||||
import AppEditContactTab from "../sidebarRight/tabs/editContact";
|
||||
|
||||
export default class ChatTopbar {
|
||||
public container: HTMLDivElement;
|
||||
@ -273,6 +274,15 @@ export default class ChatTopbar {
|
||||
this.chat.selection.cancelSelection();
|
||||
},
|
||||
verify: () => this.chat.selection.isSelecting
|
||||
}, {
|
||||
icon: 'adduser',
|
||||
text: 'AddContact',
|
||||
onClick: () => {
|
||||
const tab = new AppEditContactTab(this.appSidebarRight);
|
||||
tab.peerId = this.peerId;
|
||||
tab.open();
|
||||
},
|
||||
verify: () => this.peerId > 0 && !this.appUsersManager.isContact(this.peerId)
|
||||
}, {
|
||||
icon: 'forward',
|
||||
text: 'ShareContact',
|
||||
@ -312,6 +322,46 @@ export default class ChatTopbar {
|
||||
});
|
||||
},
|
||||
verify: () => rootScope.myId !== this.peerId && this.peerId > 0 && this.appUsersManager.isContact(this.peerId)
|
||||
}, {
|
||||
icon: 'lock',
|
||||
text: 'BlockUser',
|
||||
onClick: () => {
|
||||
new PopupPeer('', {
|
||||
peerId: this.peerId,
|
||||
titleLangKey: 'BlockUser',
|
||||
descriptionLangKey: 'AreYouSureBlockContact2',
|
||||
descriptionLangArgs: [new PeerTitle({peerId: this.peerId}).element],
|
||||
buttons: [{
|
||||
langKey: 'BlockUser',
|
||||
isDanger: true,
|
||||
callback: () => {
|
||||
this.appUsersManager.toggleBlock(this.peerId, true).then(value => {
|
||||
if(value) {
|
||||
toastNew({langPackKey: 'UserBlocked'});
|
||||
}
|
||||
});
|
||||
}
|
||||
}]
|
||||
}).show();
|
||||
},
|
||||
verify: () => {
|
||||
const userFull = this.appProfileManager.usersFull[this.peerId];
|
||||
return this.peerId > 0 && userFull && !userFull.pFlags?.blocked;
|
||||
}
|
||||
}, {
|
||||
icon: 'lockoff',
|
||||
text: 'Unblock',
|
||||
onClick: () => {
|
||||
this.appUsersManager.toggleBlock(this.peerId, false).then(value => {
|
||||
if(value) {
|
||||
toastNew({langPackKey: 'UserUnblocked'});
|
||||
}
|
||||
});
|
||||
},
|
||||
verify: () => {
|
||||
const userFull = this.appProfileManager.usersFull[this.peerId];
|
||||
return this.peerId > 0 && !!userFull?.pFlags?.blocked;
|
||||
}
|
||||
}, {
|
||||
icon: 'delete danger',
|
||||
text: 'Delete',
|
||||
|
@ -8,6 +8,7 @@ import simulateEvent from "../helpers/dom/dispatchEvent";
|
||||
import findUpAttribute from "../helpers/dom/findUpAttribute";
|
||||
import getRichValue from "../helpers/dom/getRichValue";
|
||||
import isInputEmpty from "../helpers/dom/isInputEmpty";
|
||||
import selectElementContents from "../helpers/dom/selectElementContents";
|
||||
import { i18n, LangPackKey, _i18n } from "../lib/langPack";
|
||||
import RichTextProcessor from "../lib/richtextprocessor";
|
||||
|
||||
@ -215,8 +216,14 @@ class InputField {
|
||||
}
|
||||
|
||||
public select() {
|
||||
if((this.input as HTMLInputElement).value) { // * avoid selecting whole empty field on iOS devices
|
||||
if(!this.value) { // * avoid selecting whole empty field on iOS devices
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.options.plainText) {
|
||||
(this.input as HTMLInputElement).select(); // * select text
|
||||
} else {
|
||||
selectElementContents(this.input);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,9 +285,7 @@ class InputField {
|
||||
(!this.required || !isInputEmpty(this.input));
|
||||
}
|
||||
|
||||
public setOriginalValue(value: InputField['originalValue'] = '', silent = false) {
|
||||
this.originalValue = value;
|
||||
|
||||
public setDraftValue(value = '', silent = false) {
|
||||
if(!this.options.plainText) {
|
||||
value = RichTextProcessor.wrapDraftText(value);
|
||||
}
|
||||
@ -292,6 +297,11 @@ class InputField {
|
||||
}
|
||||
}
|
||||
|
||||
public setOriginalValue(value: InputField['originalValue'] = '', silent = false) {
|
||||
this.originalValue = value;
|
||||
this.setDraftValue(value, silent);
|
||||
}
|
||||
|
||||
public setState(state: InputState, label?: LangPackKey) {
|
||||
if(label) {
|
||||
this.label.textContent = '';
|
||||
|
@ -31,7 +31,8 @@ export default class AppEditContactTab extends SliderSuperTab {
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('edit-peer-container', 'edit-contact-container');
|
||||
this.setTitle(this.peerId ? 'Edit' : 'AddContactTitle');
|
||||
const isNew = !appUsersManager.isContact(this.peerId);
|
||||
this.setTitle(isNew ? 'AddContactTitle' : 'Edit');
|
||||
|
||||
{
|
||||
const section = new SettingSection({noDelimiter: true});
|
||||
@ -41,12 +42,13 @@ export default class AppEditContactTab extends SliderSuperTab {
|
||||
inputWrapper.classList.add('input-wrapper');
|
||||
|
||||
this.nameInputField = new InputField({
|
||||
label: 'EditProfile.FirstNameLabel',
|
||||
label: 'FirstName',
|
||||
name: 'contact-name',
|
||||
maxLength: 70
|
||||
maxLength: 70,
|
||||
required: true
|
||||
});
|
||||
this.lastNameInputField = new InputField({
|
||||
label: 'Login.Register.LastName.Placeholder',
|
||||
label: 'LastName',
|
||||
name: 'contact-lastname',
|
||||
maxLength: 70
|
||||
});
|
||||
@ -54,8 +56,13 @@ export default class AppEditContactTab extends SliderSuperTab {
|
||||
if(this.peerId) {
|
||||
const user = appUsersManager.getUser(this.peerId);
|
||||
|
||||
this.nameInputField.setOriginalValue(user.first_name);
|
||||
this.lastNameInputField.setOriginalValue(user.last_name);
|
||||
if(isNew) {
|
||||
this.nameInputField.setDraftValue(user.first_name);
|
||||
this.lastNameInputField.setDraftValue(user.last_name);
|
||||
} else {
|
||||
this.nameInputField.setOriginalValue(user.first_name);
|
||||
this.lastNameInputField.setOriginalValue(user.last_name);
|
||||
}
|
||||
}
|
||||
|
||||
inputWrapper.append(this.nameInputField.container, this.lastNameInputField.container);
|
||||
@ -97,13 +104,6 @@ export default class AppEditContactTab extends SliderSuperTab {
|
||||
}
|
||||
});
|
||||
|
||||
const notificationsRow = new Row({
|
||||
checkboxField: notificationsCheckboxField
|
||||
});
|
||||
|
||||
const enabled = !appNotificationsManager.isPeerLocalMuted(this.peerId, false);
|
||||
notificationsCheckboxField.checked = enabled;
|
||||
|
||||
const profileNameDiv = document.createElement('div');
|
||||
profileNameDiv.classList.add('profile-name');
|
||||
profileNameDiv.append(new PeerTitle({
|
||||
@ -115,7 +115,30 @@ export default class AppEditContactTab extends SliderSuperTab {
|
||||
profileSubtitleDiv.classList.add('profile-subtitle');
|
||||
profileSubtitleDiv.append(i18n('EditContact.OriginalName'));
|
||||
|
||||
section.content.append(div, profileNameDiv, profileSubtitleDiv, inputWrapper, notificationsRow.container);
|
||||
section.content.append(div, profileNameDiv, profileSubtitleDiv, inputWrapper);
|
||||
|
||||
if(!isNew) {
|
||||
const notificationsRow = new Row({
|
||||
checkboxField: notificationsCheckboxField
|
||||
});
|
||||
|
||||
const enabled = !appNotificationsManager.isPeerLocalMuted(this.peerId, false);
|
||||
notificationsCheckboxField.checked = enabled;
|
||||
|
||||
section.content.append(notificationsRow.container);
|
||||
} else {
|
||||
const user = appUsersManager.getUser(this.peerId);
|
||||
|
||||
const phoneRow = new Row({
|
||||
icon: 'phone',
|
||||
titleLangKey: user.phone ? undefined : 'MobileHidden',
|
||||
title: user.phone ? appUsersManager.formatUserPhone(user.phone) : undefined,
|
||||
subtitleLangKey: user.phone ? 'Phone' : 'MobileHiddenExceptionInfo',
|
||||
subtitleLangArgs: user.phone ? undefined : [new PeerTitle({peerId: this.peerId}).element]
|
||||
});
|
||||
|
||||
section.content.append(phoneRow.container);
|
||||
}
|
||||
} else {
|
||||
section.content.append(inputWrapper);
|
||||
}
|
||||
@ -133,7 +156,7 @@ export default class AppEditContactTab extends SliderSuperTab {
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
}
|
||||
|
||||
if(this.peerId) {
|
||||
if(!isNew) {
|
||||
const section = new SettingSection({
|
||||
|
||||
});
|
||||
|
8
src/helpers/dom/selectElementContents.ts
Normal file
8
src/helpers/dom/selectElementContents.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// https://stackoverflow.com/a/6150060
|
||||
export default function selectElementContents(el: HTMLElement) {
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(el);
|
||||
const sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
}
|
@ -575,6 +575,15 @@ const lang = {
|
||||
"DiscardVoiceMessageTitle": "Discard Voice Message",
|
||||
"DiscardVoiceMessageDescription": "Are you sure you want to stop recording and discard your voice message?",
|
||||
"DiscardVoiceMessageAction": "Discard",
|
||||
"AddContact": "Add to contacts",
|
||||
"BlockUser": "Block user",
|
||||
"MobileHidden": "Mobile hidden",
|
||||
"MobileHiddenExceptionInfo": "Phone number will be visible once %1$s adds you as a contact.",
|
||||
"FirstName": "First name (required)",
|
||||
"LastName": "Last name (optional)",
|
||||
"AreYouSureBlockContact2": "Are you sure you want to block **%1$s**?",
|
||||
"UserBlocked": "User blocked",
|
||||
"UserUnblocked": "User unblocked",
|
||||
|
||||
// * macos
|
||||
"AccountSettings.Filters": "Chat Folders",
|
||||
|
@ -37,13 +37,6 @@ const DialogColorsMap = [0, 7, 4, 1, 6, 3, 5];
|
||||
|
||||
export type PeerType = 'channel' | 'chat' | 'megagroup' | 'group' | 'saved';
|
||||
export class AppPeersManager {
|
||||
constructor() {
|
||||
rootScope.addMultipleEventsListeners({
|
||||
updatePeerBlocked: (update) => {
|
||||
rootScope.dispatchEvent('peer_block', {peerId: this.getPeerId(update.peer_id), blocked: update.blocked});
|
||||
}
|
||||
});
|
||||
}
|
||||
/* public savePeerInstance(peerId: number, instance: any) {
|
||||
if(peerId < 0) appChatsManager.saveApiChat(instance);
|
||||
else appUsersManager.saveApiUser(instance);
|
||||
|
@ -31,7 +31,7 @@ export type UserTyping = Partial<{userId: number, action: SendMessageAction, tim
|
||||
|
||||
export class AppProfileManager {
|
||||
//private botInfos: any = {};
|
||||
private usersFull: {[id: string]: UserFull.userFull} = {};
|
||||
public usersFull: {[id: string]: UserFull.userFull} = {};
|
||||
public chatsFull: {[id: string]: ChatFull} = {};
|
||||
private fullPromises: {[peerId: string]: Promise<ChatFull.chatFull | ChatFull.channelFull | UserFull>} = {};
|
||||
|
||||
@ -94,7 +94,9 @@ export class AppProfileManager {
|
||||
|
||||
updateUserTyping: this.onUpdateUserTyping,
|
||||
updateChatUserTyping: this.onUpdateUserTyping,
|
||||
updateChannelUserTyping: this.onUpdateUserTyping
|
||||
updateChannelUserTyping: this.onUpdateUserTyping,
|
||||
|
||||
updatePeerBlocked: this.onUpdatePeerBlocked
|
||||
});
|
||||
|
||||
rootScope.addEventListener('chat_update', (chatId) => {
|
||||
@ -639,6 +641,19 @@ export class AppProfileManager {
|
||||
}
|
||||
};
|
||||
|
||||
private onUpdatePeerBlocked = (update: Update.updatePeerBlocked) => {
|
||||
const peerId = appPeersManager.getPeerId(update.peer_id);
|
||||
if(peerId > 0) {
|
||||
const userFull = this.usersFull[peerId];
|
||||
if(userFull) {
|
||||
if(update.blocked) userFull.pFlags.blocked = true;
|
||||
else delete userFull.pFlags.blocked;
|
||||
}
|
||||
}
|
||||
|
||||
rootScope.dispatchEvent('peer_block', {peerId, blocked: update.blocked});
|
||||
};
|
||||
|
||||
public getPeerTypings(peerId: number) {
|
||||
return this.typingsInPeer[peerId];
|
||||
}
|
||||
|
@ -31,8 +31,6 @@ import appChatsManager from "./appChatsManager";
|
||||
import appPeersManager from "./appPeersManager";
|
||||
import appStateManager from "./appStateManager";
|
||||
|
||||
// TODO: updateUserBlocked
|
||||
|
||||
export type User = MTUser.user;
|
||||
export type TopPeerType = 'correspondents' | 'bots_inline';
|
||||
export type MyTopPeer = {id: number, rating: number};
|
||||
|
@ -80,14 +80,14 @@ html:not(.is-safari):not(.is-ios) {
|
||||
|
||||
&.scrollable-x {
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
scrollbar-width: thin; // Firefox only
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
&.scrollable-y {
|
||||
overflow-y: auto;
|
||||
overflow-y: overlay;
|
||||
scrollbar-width: none;
|
||||
scrollbar-width: thin; // Firefox only
|
||||
-ms-overflow-style: none;
|
||||
|
||||
/* html.is-safari & {
|
||||
|
Loading…
x
Reference in New Issue
Block a user