Browse Source

Multiselect: handle deleting messages

Select already selected messages while scrolling
master
Eduard Kuzmenko 4 years ago
parent
commit
872117fee8
  1. 25
      src/components/audio.ts
  2. 22
      src/components/chat/bubbles.ts
  3. 18
      src/components/chat/selection.ts
  4. 13
      src/components/poll.ts
  5. 2
      src/components/wrappers.ts
  6. 16
      src/lib/mtproto/apiFileManager.ts
  7. 2
      src/lib/mtproto/apiManager.ts

25
src/components/audio.ts

@ -328,10 +328,7 @@ export default class AudioElement extends HTMLElement { @@ -328,10 +328,7 @@ export default class AudioElement extends HTMLElement {
// элемент создан
}
connectedCallback() {
// браузер вызывает этот метод при добавлении элемента в документ
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
public render() {
this.classList.add('audio');
const doc = this.message.media.document || this.message.media.webpage.document;
@ -499,6 +496,11 @@ export default class AudioElement extends HTMLElement { @@ -499,6 +496,11 @@ export default class AudioElement extends HTMLElement {
}
}
/* connectedCallback() {
// браузер вызывает этот метод при добавлении элемента в документ
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
} */
public addAudioListener(name: string, callback: any) {
if(!this.attachedHandlers[name]) this.attachedHandlers[name] = [];
this.attachedHandlers[name].push(callback);
@ -523,21 +525,6 @@ export default class AudioElement extends HTMLElement { @@ -523,21 +525,6 @@ export default class AudioElement extends HTMLElement {
this.preloader = null;
}
static get observedAttributes(): string[] {
return [/* массив имён атрибутов для отслеживания их изменений */];
}
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
// вызывается при изменении одного из перечисленных выше атрибутов
}
adoptedCallback() {
// вызывается, когда элемент перемещается в новый документ
// (происходит в document.adoptNode, используется очень редко)
}
// у элемента могут быть ещё другие методы и свойства
}
customElements.define("audio-element", AudioElement);

22
src/components/chat/bubbles.ts

@ -359,7 +359,7 @@ export default class ChatBubbles { @@ -359,7 +359,7 @@ export default class ChatBubbles {
const mids = Object.keys(msgs).map(s => +s);
if(peerId == this.peerId) {
if(peerId === this.peerId) {
this.deleteMessagesByIds(mids);
}
});
@ -367,7 +367,7 @@ export default class ChatBubbles { @@ -367,7 +367,7 @@ export default class ChatBubbles {
this.listenerSetter.add(rootScope, 'dialog_unread', (e) => {
const info = e.detail;
if(info.peerId == this.peerId) {
if(info.peerId === this.peerId) {
this.chat.input.setUnreadCount();
this.updateUnreadByDialog();
}
@ -384,7 +384,7 @@ export default class ChatBubbles { @@ -384,7 +384,7 @@ export default class ChatBubbles {
this.listenerSetter.add(rootScope, 'dialog_notify_settings', (e) => {
const peerId = e.detail;
if(this.peerId == peerId) {
if(this.peerId === peerId) {
this.chat.input.setUnreadCount();
}
});
@ -899,7 +899,7 @@ export default class ChatBubbles { @@ -899,7 +899,7 @@ export default class ChatBubbles {
}
}
public deleteMessagesByIds(mids: number[]) {
public deleteMessagesByIds(mids: number[], permanent = true) {
mids.forEach(mid => {
if(!(mid in this.bubbles)) return;
@ -921,6 +921,10 @@ export default class ChatBubbles { @@ -921,6 +921,10 @@ export default class ChatBubbles {
bubble.remove();
//bubble.remove();
});
if(permanent && this.chat.selection.isSelecting) {
this.chat.selection.deleteSelectedMids(mids);
}
animationIntersector.checkAnimations(false, CHAT_ANIMATION_GROUP);
this.deleteEmptyDateGroups();
@ -1546,10 +1550,6 @@ export default class ChatBubbles { @@ -1546,10 +1550,6 @@ export default class ChatBubbles {
bubble.dataset.mid = message.mid;
bubble.dataset.timestamp = message.date;
if(this.chat.selection.isSelecting && message._ !== 'messageService') {
this.chat.selection.toggleBubbleCheckbox(bubble, true);
}
if(message._ === 'messageService') {
let action = message.action;
let _ = action._;
@ -2056,6 +2056,10 @@ export default class ChatBubbles { @@ -2056,6 +2056,10 @@ export default class ChatBubbles {
} */
}
if(this.chat.selection.isSelecting) {
this.chat.selection.toggleBubbleCheckbox(bubble, true);
}
let savedFrom = '';
const needName = (peerId < 0 && (peerId != message.fromId || our)) && message.fromId !== rootScope.myId;
@ -2557,7 +2561,7 @@ export default class ChatBubbles { @@ -2557,7 +2561,7 @@ export default class ChatBubbles {
this.log('getHistory: will slice ids:', ids, reverse);
this.deleteMessagesByIds(ids);
this.deleteMessagesByIds(ids, false);
}
this.setUnreadDelimiter(); // не нашёл места лучше

18
src/components/chat/selection.ts

@ -206,7 +206,7 @@ export default class ChatSelection { @@ -206,7 +206,7 @@ export default class ChatSelection {
bubble.firstElementChild.tagName == 'LABEL' && bubble.firstElementChild.firstElementChild as HTMLInputElement;
}
private updateForwardContainer(forceSelection = false) {
private updateContainer(forceSelection = false) {
if(!this.selectedMids.size && !forceSelection) return;
this.selectionCountEl.innerText = this.selectedMids.size + ' Message' + (this.selectedMids.size == 1 ? '' : 's');
@ -338,7 +338,7 @@ export default class ChatSelection { @@ -338,7 +338,7 @@ export default class ChatSelection {
}
if(forceSelection) {
this.updateForwardContainer(forceSelection);
this.updateContainer(forceSelection);
}
}
@ -371,7 +371,7 @@ export default class ChatSelection { @@ -371,7 +371,7 @@ export default class ChatSelection {
input.checked = isSelected;
this.toggleSelection();
this.updateForwardContainer();
this.updateContainer();
SetTransition(bubble, 'is-selected', isSelected, 200);
}
@ -443,6 +443,18 @@ export default class ChatSelection { @@ -443,6 +443,18 @@ export default class ChatSelection {
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) {
return !bubble.classList.contains('service') && !bubble.classList.contains('is-sending');
}

13
src/components/poll.ts

@ -179,7 +179,7 @@ export default class PollElement extends HTMLElement { @@ -179,7 +179,7 @@ export default class PollElement extends HTMLElement {
// элемент создан
}
connectedCallback() {
public render() {
// браузер вызывает этот метод при добавлении элемента в документ
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
@ -266,18 +266,18 @@ export default class PollElement extends HTMLElement { @@ -266,18 +266,18 @@ export default class PollElement extends HTMLElement {
svg.classList.add('poll-quiz-timer');
this.quizTimer = svg;
const strokeWidth = 2;
const radius = 7;
const circumference = 2 * Math.PI * radius;
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.classList.add('poll-quiz-timer-circle');
circle.setAttributeNS(null, 'cx', '16');
circle.setAttributeNS(null, 'cy', '16');
circle.setAttributeNS(null, 'r', '' + radius);
circle.setAttributeNS(null, 'stroke-width', '' + strokeWidth);
svg.append(circle);
this.descDiv.append(svg);
@ -381,9 +381,8 @@ export default class PollElement extends HTMLElement { @@ -381,9 +381,8 @@ export default class PollElement extends HTMLElement {
}
}
adoptedCallback() {
// вызывается, когда элемент перемещается в новый документ
// (происходит в document.adoptNode, используется очень редко)
connectedCallback() {
this.render();
}
initQuizHint(results: PollResults) {

2
src/components/wrappers.ts

@ -360,6 +360,7 @@ export function wrapDocument({message, withTime, fontWeight}: { @@ -360,6 +360,7 @@ export function wrapDocument({message, withTime, fontWeight}: {
audioElement.withTime = withTime;
audioElement.message = message;
audioElement.dataset.fontWeight = '' + fontWeight;
audioElement.render();
return audioElement;
}
@ -1053,5 +1054,6 @@ export function wrapPoll(message: any) { @@ -1053,5 +1054,6 @@ export function wrapPoll(message: any) {
elem.setAttribute('peer-id', '' + message.peerId);
elem.setAttribute('poll-id', message.media.poll.id);
elem.setAttribute('message-id', '' + message.mid);
//elem.render();
return elem;
}

16
src/lib/mtproto/apiFileManager.ts

@ -86,10 +86,7 @@ export class ApiFileManager { @@ -86,10 +86,7 @@ export class ApiFileManager {
public downloadCheck(dcId: string | number) {
const downloadPull = this.downloadPulls[dcId];
//const downloadLimit = dcId == 'upload' ? 11 : 5;
//const downloadLimit = 24;
//const downloadLimit = dcId == 'upload' ? 48 : 300;
const downloadLimit = dcId == 'upload' ? 48 : 100;
const downloadLimit = dcId == 'upload' ? 100 : 100;
//const downloadLimit = Infinity;
if(this.downloadActives[dcId] >= downloadLimit || !downloadPull || !downloadPull.length) {
@ -442,7 +439,10 @@ export class ApiFileManager { @@ -442,7 +439,10 @@ export class ApiFileManager {
}
let errorHandler = (error: any) => {
this.log.error('Up Error', error);
if(error?.type !== 'UPLOAD_CANCELED') {
this.log.error('Up Error', error);
}
deferred.reject(error);
canceled = true;
errorHandler = () => {};
@ -463,13 +463,13 @@ export class ApiFileManager { @@ -463,13 +463,13 @@ export class ApiFileManager {
reader.onloadend = (e) => {
if(canceled) {
uploadReject();
uploadReject({type: 'UPLOAD_CANCELED'});
return;
}
if(e.target.readyState != FileReader.DONE) {
self.log.error('wrong readyState!');
uploadReject();
uploadReject({type: 'WRONG_READY_STATE'});
return;
}
@ -513,8 +513,8 @@ export class ApiFileManager { @@ -513,8 +513,8 @@ export class ApiFileManager {
(r.value as Promise<void>).then(process);
};
//const maxRequests = Infinity;
const maxRequests = 10;
//const maxRequests = 10;
/* for(let i = 0; i < 10; ++i) {
process();
} */

2
src/lib/mtproto/apiManager.ts

@ -162,7 +162,7 @@ export class ApiManager { @@ -162,7 +162,7 @@ export class ApiManager {
/// #if MTPROTO_HTTP_UPLOAD
// @ts-ignore
const transportType: TransportType = connectionType == 'upload' && false ? 'https' : 'websocket';
const transportType: TransportType = connectionType == 'upload' ? 'https' : 'websocket';
//const transportType: TransportType = connectionType != 'client' ? 'https' : 'websocket';
/// #else
// @ts-ignore

Loading…
Cancel
Save