Multiselect: handle deleting messages
Select already selected messages while scrolling
This commit is contained in:
parent
ded66cf09b
commit
872117fee8
@ -328,10 +328,7 @@ export default class AudioElement extends HTMLElement {
|
|||||||
// элемент создан
|
// элемент создан
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
public render() {
|
||||||
// браузер вызывает этот метод при добавлении элемента в документ
|
|
||||||
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
|
|
||||||
|
|
||||||
this.classList.add('audio');
|
this.classList.add('audio');
|
||||||
|
|
||||||
const doc = this.message.media.document || this.message.media.webpage.document;
|
const doc = this.message.media.document || this.message.media.webpage.document;
|
||||||
@ -499,6 +496,11 @@ export default class AudioElement extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* connectedCallback() {
|
||||||
|
// браузер вызывает этот метод при добавлении элемента в документ
|
||||||
|
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
|
||||||
|
} */
|
||||||
|
|
||||||
public addAudioListener(name: string, callback: any) {
|
public addAudioListener(name: string, callback: any) {
|
||||||
if(!this.attachedHandlers[name]) this.attachedHandlers[name] = [];
|
if(!this.attachedHandlers[name]) this.attachedHandlers[name] = [];
|
||||||
this.attachedHandlers[name].push(callback);
|
this.attachedHandlers[name].push(callback);
|
||||||
@ -523,21 +525,6 @@ export default class AudioElement extends HTMLElement {
|
|||||||
|
|
||||||
this.preloader = null;
|
this.preloader = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get observedAttributes(): string[] {
|
|
||||||
return [/* массив имён атрибутов для отслеживания их изменений */];
|
|
||||||
}
|
|
||||||
|
|
||||||
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
|
|
||||||
// вызывается при изменении одного из перечисленных выше атрибутов
|
|
||||||
}
|
|
||||||
|
|
||||||
adoptedCallback() {
|
|
||||||
// вызывается, когда элемент перемещается в новый документ
|
|
||||||
// (происходит в document.adoptNode, используется очень редко)
|
|
||||||
}
|
|
||||||
|
|
||||||
// у элемента могут быть ещё другие методы и свойства
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("audio-element", AudioElement);
|
customElements.define("audio-element", AudioElement);
|
@ -359,7 +359,7 @@ export default class ChatBubbles {
|
|||||||
|
|
||||||
const mids = Object.keys(msgs).map(s => +s);
|
const mids = Object.keys(msgs).map(s => +s);
|
||||||
|
|
||||||
if(peerId == this.peerId) {
|
if(peerId === this.peerId) {
|
||||||
this.deleteMessagesByIds(mids);
|
this.deleteMessagesByIds(mids);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -367,7 +367,7 @@ export default class ChatBubbles {
|
|||||||
this.listenerSetter.add(rootScope, 'dialog_unread', (e) => {
|
this.listenerSetter.add(rootScope, 'dialog_unread', (e) => {
|
||||||
const info = e.detail;
|
const info = e.detail;
|
||||||
|
|
||||||
if(info.peerId == this.peerId) {
|
if(info.peerId === this.peerId) {
|
||||||
this.chat.input.setUnreadCount();
|
this.chat.input.setUnreadCount();
|
||||||
this.updateUnreadByDialog();
|
this.updateUnreadByDialog();
|
||||||
}
|
}
|
||||||
@ -384,7 +384,7 @@ export default class ChatBubbles {
|
|||||||
this.listenerSetter.add(rootScope, 'dialog_notify_settings', (e) => {
|
this.listenerSetter.add(rootScope, 'dialog_notify_settings', (e) => {
|
||||||
const peerId = e.detail;
|
const peerId = e.detail;
|
||||||
|
|
||||||
if(this.peerId == peerId) {
|
if(this.peerId === peerId) {
|
||||||
this.chat.input.setUnreadCount();
|
this.chat.input.setUnreadCount();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -899,7 +899,7 @@ export default class ChatBubbles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteMessagesByIds(mids: number[]) {
|
public deleteMessagesByIds(mids: number[], permanent = true) {
|
||||||
mids.forEach(mid => {
|
mids.forEach(mid => {
|
||||||
if(!(mid in this.bubbles)) return;
|
if(!(mid in this.bubbles)) return;
|
||||||
|
|
||||||
@ -921,6 +921,10 @@ export default class ChatBubbles {
|
|||||||
bubble.remove();
|
bubble.remove();
|
||||||
//bubble.remove();
|
//bubble.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(permanent && this.chat.selection.isSelecting) {
|
||||||
|
this.chat.selection.deleteSelectedMids(mids);
|
||||||
|
}
|
||||||
|
|
||||||
animationIntersector.checkAnimations(false, CHAT_ANIMATION_GROUP);
|
animationIntersector.checkAnimations(false, CHAT_ANIMATION_GROUP);
|
||||||
this.deleteEmptyDateGroups();
|
this.deleteEmptyDateGroups();
|
||||||
@ -1546,10 +1550,6 @@ export default class ChatBubbles {
|
|||||||
bubble.dataset.mid = message.mid;
|
bubble.dataset.mid = message.mid;
|
||||||
bubble.dataset.timestamp = message.date;
|
bubble.dataset.timestamp = message.date;
|
||||||
|
|
||||||
if(this.chat.selection.isSelecting && message._ !== 'messageService') {
|
|
||||||
this.chat.selection.toggleBubbleCheckbox(bubble, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message._ === 'messageService') {
|
if(message._ === 'messageService') {
|
||||||
let action = message.action;
|
let action = message.action;
|
||||||
let _ = action._;
|
let _ = action._;
|
||||||
@ -2056,6 +2056,10 @@ export default class ChatBubbles {
|
|||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.chat.selection.isSelecting) {
|
||||||
|
this.chat.selection.toggleBubbleCheckbox(bubble, true);
|
||||||
|
}
|
||||||
|
|
||||||
let savedFrom = '';
|
let savedFrom = '';
|
||||||
|
|
||||||
const needName = (peerId < 0 && (peerId != message.fromId || our)) && message.fromId !== rootScope.myId;
|
const needName = (peerId < 0 && (peerId != message.fromId || our)) && message.fromId !== rootScope.myId;
|
||||||
@ -2557,7 +2561,7 @@ export default class ChatBubbles {
|
|||||||
|
|
||||||
this.log('getHistory: will slice ids:', ids, reverse);
|
this.log('getHistory: will slice ids:', ids, reverse);
|
||||||
|
|
||||||
this.deleteMessagesByIds(ids);
|
this.deleteMessagesByIds(ids, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setUnreadDelimiter(); // не нашёл места лучше
|
this.setUnreadDelimiter(); // не нашёл места лучше
|
||||||
|
@ -206,7 +206,7 @@ export default class ChatSelection {
|
|||||||
bubble.firstElementChild.tagName == 'LABEL' && bubble.firstElementChild.firstElementChild as HTMLInputElement;
|
bubble.firstElementChild.tagName == 'LABEL' && bubble.firstElementChild.firstElementChild as HTMLInputElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateForwardContainer(forceSelection = false) {
|
private updateContainer(forceSelection = false) {
|
||||||
if(!this.selectedMids.size && !forceSelection) return;
|
if(!this.selectedMids.size && !forceSelection) return;
|
||||||
this.selectionCountEl.innerText = this.selectedMids.size + ' Message' + (this.selectedMids.size == 1 ? '' : 's');
|
this.selectionCountEl.innerText = this.selectedMids.size + ' Message' + (this.selectedMids.size == 1 ? '' : 's');
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ export default class ChatSelection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(forceSelection) {
|
if(forceSelection) {
|
||||||
this.updateForwardContainer(forceSelection);
|
this.updateContainer(forceSelection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +371,7 @@ export default class ChatSelection {
|
|||||||
input.checked = isSelected;
|
input.checked = isSelected;
|
||||||
|
|
||||||
this.toggleSelection();
|
this.toggleSelection();
|
||||||
this.updateForwardContainer();
|
this.updateContainer();
|
||||||
SetTransition(bubble, 'is-selected', isSelected, 200);
|
SetTransition(bubble, 'is-selected', isSelected, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,6 +443,18 @@ export default class ChatSelection {
|
|||||||
this.updateBubbleSelection(bubble, !found);
|
this.updateBubbleSelection(bubble, !found);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ! Call this method only to handle deleted messages
|
||||||
|
*/
|
||||||
|
public deleteSelectedMids(mids: number[]) {
|
||||||
|
mids.forEach(mid => {
|
||||||
|
this.selectedMids.delete(mid);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateContainer();
|
||||||
|
this.toggleSelection();
|
||||||
|
}
|
||||||
|
|
||||||
public canSelectBubble(bubble: HTMLElement) {
|
public canSelectBubble(bubble: HTMLElement) {
|
||||||
return !bubble.classList.contains('service') && !bubble.classList.contains('is-sending');
|
return !bubble.classList.contains('service') && !bubble.classList.contains('is-sending');
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ export default class PollElement extends HTMLElement {
|
|||||||
// элемент создан
|
// элемент создан
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
public render() {
|
||||||
// браузер вызывает этот метод при добавлении элемента в документ
|
// браузер вызывает этот метод при добавлении элемента в документ
|
||||||
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
|
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
|
||||||
|
|
||||||
@ -266,18 +266,18 @@ export default class PollElement extends HTMLElement {
|
|||||||
svg.classList.add('poll-quiz-timer');
|
svg.classList.add('poll-quiz-timer');
|
||||||
|
|
||||||
this.quizTimer = svg;
|
this.quizTimer = svg;
|
||||||
|
|
||||||
const strokeWidth = 2;
|
const strokeWidth = 2;
|
||||||
const radius = 7;
|
const radius = 7;
|
||||||
const circumference = 2 * Math.PI * radius;
|
const circumference = 2 * Math.PI * radius;
|
||||||
|
|
||||||
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
||||||
circle.classList.add('poll-quiz-timer-circle');
|
circle.classList.add('poll-quiz-timer-circle');
|
||||||
circle.setAttributeNS(null, 'cx', '16');
|
circle.setAttributeNS(null, 'cx', '16');
|
||||||
circle.setAttributeNS(null, 'cy', '16');
|
circle.setAttributeNS(null, 'cy', '16');
|
||||||
circle.setAttributeNS(null, 'r', '' + radius);
|
circle.setAttributeNS(null, 'r', '' + radius);
|
||||||
circle.setAttributeNS(null, 'stroke-width', '' + strokeWidth);
|
circle.setAttributeNS(null, 'stroke-width', '' + strokeWidth);
|
||||||
|
|
||||||
svg.append(circle);
|
svg.append(circle);
|
||||||
this.descDiv.append(svg);
|
this.descDiv.append(svg);
|
||||||
|
|
||||||
@ -381,9 +381,8 @@ export default class PollElement extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
adoptedCallback() {
|
connectedCallback() {
|
||||||
// вызывается, когда элемент перемещается в новый документ
|
this.render();
|
||||||
// (происходит в document.adoptNode, используется очень редко)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initQuizHint(results: PollResults) {
|
initQuizHint(results: PollResults) {
|
||||||
|
@ -360,6 +360,7 @@ export function wrapDocument({message, withTime, fontWeight}: {
|
|||||||
audioElement.withTime = withTime;
|
audioElement.withTime = withTime;
|
||||||
audioElement.message = message;
|
audioElement.message = message;
|
||||||
audioElement.dataset.fontWeight = '' + fontWeight;
|
audioElement.dataset.fontWeight = '' + fontWeight;
|
||||||
|
audioElement.render();
|
||||||
return audioElement;
|
return audioElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1053,5 +1054,6 @@ export function wrapPoll(message: any) {
|
|||||||
elem.setAttribute('peer-id', '' + message.peerId);
|
elem.setAttribute('peer-id', '' + message.peerId);
|
||||||
elem.setAttribute('poll-id', message.media.poll.id);
|
elem.setAttribute('poll-id', message.media.poll.id);
|
||||||
elem.setAttribute('message-id', '' + message.mid);
|
elem.setAttribute('message-id', '' + message.mid);
|
||||||
|
//elem.render();
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
@ -86,10 +86,7 @@ export class ApiFileManager {
|
|||||||
|
|
||||||
public downloadCheck(dcId: string | number) {
|
public downloadCheck(dcId: string | number) {
|
||||||
const downloadPull = this.downloadPulls[dcId];
|
const downloadPull = this.downloadPulls[dcId];
|
||||||
//const downloadLimit = dcId == 'upload' ? 11 : 5;
|
const downloadLimit = dcId == 'upload' ? 100 : 100;
|
||||||
//const downloadLimit = 24;
|
|
||||||
//const downloadLimit = dcId == 'upload' ? 48 : 300;
|
|
||||||
const downloadLimit = dcId == 'upload' ? 48 : 100;
|
|
||||||
//const downloadLimit = Infinity;
|
//const downloadLimit = Infinity;
|
||||||
|
|
||||||
if(this.downloadActives[dcId] >= downloadLimit || !downloadPull || !downloadPull.length) {
|
if(this.downloadActives[dcId] >= downloadLimit || !downloadPull || !downloadPull.length) {
|
||||||
@ -442,7 +439,10 @@ export class ApiFileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let errorHandler = (error: any) => {
|
let errorHandler = (error: any) => {
|
||||||
this.log.error('Up Error', error);
|
if(error?.type !== 'UPLOAD_CANCELED') {
|
||||||
|
this.log.error('Up Error', error);
|
||||||
|
}
|
||||||
|
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
canceled = true;
|
canceled = true;
|
||||||
errorHandler = () => {};
|
errorHandler = () => {};
|
||||||
@ -463,13 +463,13 @@ export class ApiFileManager {
|
|||||||
|
|
||||||
reader.onloadend = (e) => {
|
reader.onloadend = (e) => {
|
||||||
if(canceled) {
|
if(canceled) {
|
||||||
uploadReject();
|
uploadReject({type: 'UPLOAD_CANCELED'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e.target.readyState != FileReader.DONE) {
|
if(e.target.readyState != FileReader.DONE) {
|
||||||
self.log.error('wrong readyState!');
|
self.log.error('wrong readyState!');
|
||||||
uploadReject();
|
uploadReject({type: 'WRONG_READY_STATE'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,8 +513,8 @@ export class ApiFileManager {
|
|||||||
(r.value as Promise<void>).then(process);
|
(r.value as Promise<void>).then(process);
|
||||||
};
|
};
|
||||||
|
|
||||||
//const maxRequests = Infinity;
|
|
||||||
const maxRequests = 10;
|
const maxRequests = 10;
|
||||||
|
//const maxRequests = 10;
|
||||||
/* for(let i = 0; i < 10; ++i) {
|
/* for(let i = 0; i < 10; ++i) {
|
||||||
process();
|
process();
|
||||||
} */
|
} */
|
||||||
|
@ -162,7 +162,7 @@ export class ApiManager {
|
|||||||
|
|
||||||
/// #if MTPROTO_HTTP_UPLOAD
|
/// #if MTPROTO_HTTP_UPLOAD
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const transportType: TransportType = connectionType == 'upload' && false ? 'https' : 'websocket';
|
const transportType: TransportType = connectionType == 'upload' ? 'https' : 'websocket';
|
||||||
//const transportType: TransportType = connectionType != 'client' ? 'https' : 'websocket';
|
//const transportType: TransportType = connectionType != 'client' ? 'https' : 'websocket';
|
||||||
/// #else
|
/// #else
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
Loading…
x
Reference in New Issue
Block a user