MOBILE-3931 performance: Fix memory leak on context menu

main
Pau Ferrer Ocaña 2022-02-17 09:02:54 +01:00
parent 6a862730e2
commit 9bab09dace
3 changed files with 17 additions and 7 deletions

View File

@ -13,6 +13,7 @@
// limitations under the License.
import { Component, Input, Output, OnInit, OnDestroy, EventEmitter, OnChanges, SimpleChange } from '@angular/core';
import { CoreLogger } from '@singletons/logger';
import { CoreContextMenuComponent } from '../context-menu/context-menu';
/**
@ -35,7 +36,6 @@ import { CoreContextMenuComponent } from '../context-menu/context-menu';
export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChanges {
@Input() content?: string; // Content of the item.
@Input() iconDescription?: string; // Name of the icon to be shown on the left side of the item.
@Input() iconAction?: string; // Name of the icon to show on the right side of the item. Represents the action to do on click.
// If is "spinner" an spinner will be shown.
// If is "toggle" a toggle switch will be shown.
@ -58,6 +58,11 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange
@Output() onClosed?: EventEmitter<() => void>; // Will emit an event when the popover is closed because the item was clicked.
@Output() toggleChange = new EventEmitter<boolean>();// Will emit an event when toggle changes to enable 2-way data binding.
/**
* @deprecated since 4.0.
*/
@Input() iconDescription?: string; // Name of the icon to be shown on the left side of the item. Not used anymore.
protected hasAction = false;
protected destroyed = false;
@ -88,6 +93,11 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange
if (!this.destroyed) {
this.ctxtMenu.addItem(this);
}
if (this.iconDescription !== undefined) {
CoreLogger.getInstance('CoreContextMenuItemComponent')
.warn('iconDescription Input is deprecated and should not be used');
}
}
/**

View File

@ -13,7 +13,7 @@
// limitations under the License.
import { Component, Input, OnInit, OnDestroy, ElementRef, ChangeDetectorRef } from '@angular/core';
import { Subject } from 'rxjs';
import { Subject, Subscription } from 'rxjs';
import { auditTime } from 'rxjs/operators';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
@ -42,11 +42,12 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
protected itemsChangedStream: Subject<void>; // Stream to update the hideMenu boolean when items change.
protected parentContextMenu?: CoreContextMenuComponent;
protected expanded = false;
protected itemsSubscription: Subscription;
constructor(elementRef: ElementRef, changeDetector: ChangeDetectorRef) {
// Create the stream and subscribe to it. We ignore successive changes during 250ms.
this.itemsChangedStream = new Subject<void>();
this.itemsChangedStream.pipe(auditTime(250)).subscribe(() => {
this.itemsSubscription = this.itemsChangedStream.pipe(auditTime(250)).subscribe(() => {
// Hide the menu if all items are hidden.
this.hideMenu = !this.items.some((item) => !item.hidden);
@ -63,7 +64,7 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
}
/**
* Component being initialized.
* @inheritdoc
*/
ngOnInit(): void {
this.icon = this.icon || 'ellipsis-vertical';
@ -197,10 +198,11 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
}
/**
* Component destroyed.
* @inheritdoc
*/
ngOnDestroy(): void {
this.removeMergedItems();
this.itemsSubscription.unsubscribe();
}
}

View File

@ -6,8 +6,6 @@
[href]="item.href" (click)="itemClicked($event, item)" [attr.aria-label]="item.ariaAction" [hidden]="item.hidden"
[detail]="(item.href && !item.iconAction) || null" role="menuitem" [button]="(item.href && !item.iconAction)"
[showBrowserWarning]="item.showBrowserWarning">
<ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" aria-hidden="true" slot="start">
</ion-icon>
<ion-label>
<p class="item-heading">
<core-format-text [clean]="true" [text]="item.content" [filter]="false"></core-format-text>