commit
85fd170f99
|
@ -5,9 +5,6 @@
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<h1>{{ 'addon.messages.contacts' | translate }}</h1>
|
<h1>{{ 'addon.messages.contacts' | translate }}</h1>
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<!-- Add an empty context menu so discussion page can add items in split view,
|
|
||||||
otherwise the menu disappears in some cases. -->
|
|
||||||
<core-context-menu></core-context-menu>
|
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
|
@ -8,9 +8,6 @@
|
||||||
<ion-button fill="clear" (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate">
|
<ion-button fill="clear" (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate">
|
||||||
<ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<!-- Add an empty context menu so discussion page can add items in split view, otherwise the menu
|
|
||||||
disappears in some cases. -->
|
|
||||||
<core-context-menu></core-context-menu>
|
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<h1>{{ 'addon.messages.messages' | translate }}</h1>
|
<h1>{{ 'addon.messages.messages' | translate }}</h1>
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<!-- Add an empty context menu so discussion page can add items in split view,
|
|
||||||
otherwise the menu disappears in some cases. -->
|
|
||||||
<core-context-menu></core-context-menu>
|
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
|
@ -11,9 +11,6 @@
|
||||||
<ion-button (click)="gotoSettings()" [attr.aria-label]="'addon.messages.messagepreferences' | translate">
|
<ion-button (click)="gotoSettings()" [attr.aria-label]="'addon.messages.messagepreferences' | translate">
|
||||||
<ion-icon name="fas-cog" slot="icon-only" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-cog" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<!-- Add an empty context menu so discussion page can add items in split view,
|
|
||||||
otherwise the menu disappears in some cases. -->
|
|
||||||
<core-context-menu></core-context-menu>
|
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<h1>{{ 'addon.messages.searchcombined' | translate }}</h1>
|
<h1>{{ 'addon.messages.searchcombined' | translate }}</h1>
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<!-- Add an empty context menu so discussion page can add items in split view,
|
|
||||||
otherwise the menu disappears in some cases. -->
|
|
||||||
<core-context-menu></core-context-menu>
|
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
|
@ -12,7 +12,16 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, OnInit, OnDestroy, ElementRef } from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
Input,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
ElementRef,
|
||||||
|
ViewContainerRef,
|
||||||
|
ViewChild,
|
||||||
|
ComponentFactoryResolver,
|
||||||
|
} from '@angular/core';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreContextMenuComponent } from '../context-menu/context-menu';
|
import { CoreContextMenuComponent } from '../context-menu/context-menu';
|
||||||
|
@ -42,11 +51,13 @@ const BUTTON_HIDDEN_CLASS = 'core-navbar-button-hidden';
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'core-navbar-buttons',
|
selector: 'core-navbar-buttons',
|
||||||
template: '<ng-content></ng-content>',
|
template: '<ng-content></ng-content><template #contextMenuContainer></template>',
|
||||||
styleUrls: ['navbar-buttons.scss'],
|
styleUrls: ['navbar-buttons.scss'],
|
||||||
})
|
})
|
||||||
export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
@ViewChild('contextMenuContainer', { read: ViewContainerRef }) container?: ViewContainerRef;
|
||||||
|
|
||||||
// If the hidden input is true, hide all buttons.
|
// If the hidden input is true, hide all buttons.
|
||||||
// eslint-disable-next-line @angular-eslint/no-input-rename
|
// eslint-disable-next-line @angular-eslint/no-input-rename
|
||||||
@Input('hidden') set hidden(value: boolean) {
|
@Input('hidden') set hidden(value: boolean) {
|
||||||
|
@ -63,8 +74,9 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
protected logger: CoreLogger;
|
protected logger: CoreLogger;
|
||||||
protected movedChildren?: Node[];
|
protected movedChildren?: Node[];
|
||||||
protected mergedContextMenu?: CoreContextMenuComponent;
|
protected mergedContextMenu?: CoreContextMenuComponent;
|
||||||
|
protected createdMainContextMenuElement?: HTMLElement;
|
||||||
|
|
||||||
constructor(element: ElementRef) {
|
constructor(element: ElementRef, protected factoryResolver: ComponentFactoryResolver) {
|
||||||
this.element = element.nativeElement;
|
this.element = element.nativeElement;
|
||||||
this.logger = CoreLogger.getInstance('CoreNavBarButtonsComponent');
|
this.logger = CoreLogger.getInstance('CoreNavBarButtonsComponent');
|
||||||
|
|
||||||
|
@ -99,6 +111,9 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
this.movedChildren = CoreDomUtils.moveChildren(this.element, buttonsContainer, prepend);
|
this.movedChildren = CoreDomUtils.moveChildren(this.element, buttonsContainer, prepend);
|
||||||
this.showHideAllElements();
|
this.showHideAllElements();
|
||||||
|
|
||||||
|
// Make sure that context-menu is always at the end of buttons if any.
|
||||||
|
const contextMenu = buttonsContainer.querySelector('core-context-menu');
|
||||||
|
contextMenu?.parentElement?.appendChild(contextMenu);
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn('The header was found, but it didn\'t have the right ion-buttons.', selector);
|
this.logger.warn('The header was found, but it didn\'t have the right ion-buttons.', selector);
|
||||||
}
|
}
|
||||||
|
@ -127,19 +142,22 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
*/
|
*/
|
||||||
protected mergeContextMenus(buttonsContainer: HTMLElement): void {
|
protected mergeContextMenus(buttonsContainer: HTMLElement): void {
|
||||||
// Check if both button containers have a context menu.
|
// Check if both button containers have a context menu.
|
||||||
const mainContextMenu = buttonsContainer.querySelector('core-context-menu');
|
|
||||||
if (!mainContextMenu) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const secondaryContextMenu = this.element.querySelector('core-context-menu');
|
const secondaryContextMenu = this.element.querySelector('core-context-menu');
|
||||||
if (!secondaryContextMenu) {
|
if (!secondaryContextMenu) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Both containers have a context menu. Merge them to prevent having 2 menus at the same time.
|
const mainContextMenu = buttonsContainer.querySelector('core-context-menu');
|
||||||
const mainContextMenuInstance = CoreDomUtils.getInstanceByElement<CoreContextMenuComponent>(mainContextMenu);
|
|
||||||
const secondaryContextMenuInstance = CoreDomUtils.getInstanceByElement<CoreContextMenuComponent>(secondaryContextMenu);
|
const secondaryContextMenuInstance = CoreDomUtils.getInstanceByElement<CoreContextMenuComponent>(secondaryContextMenu);
|
||||||
|
let mainContextMenuInstance: CoreContextMenuComponent | undefined;
|
||||||
|
if (mainContextMenu) {
|
||||||
|
// Both containers have a context menu. Merge them to prevent having 2 menus at the same time.
|
||||||
|
mainContextMenuInstance = CoreDomUtils.getInstanceByElement<CoreContextMenuComponent>(mainContextMenu);
|
||||||
|
} else {
|
||||||
|
// There is a context-menu in these buttons, but there is no main context menu in the header.
|
||||||
|
// Create one main context menu dynamically.
|
||||||
|
mainContextMenuInstance = this.createMainContextMenu();
|
||||||
|
}
|
||||||
|
|
||||||
// Check that both context menus belong to the same core-tab. We shouldn't merge menus from different tabs.
|
// Check that both context menus belong to the same core-tab. We shouldn't merge menus from different tabs.
|
||||||
if (mainContextMenuInstance && secondaryContextMenuInstance) {
|
if (mainContextMenuInstance && secondaryContextMenuInstance) {
|
||||||
|
@ -152,6 +170,20 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new and empty context menu to be used as a "parent".
|
||||||
|
*
|
||||||
|
* @return Created component.
|
||||||
|
*/
|
||||||
|
protected createMainContextMenu(): CoreContextMenuComponent {
|
||||||
|
const factory = this.factoryResolver.resolveComponentFactory(CoreContextMenuComponent);
|
||||||
|
const componentRef = this.container!.createComponent<CoreContextMenuComponent>(factory);
|
||||||
|
|
||||||
|
this.createdMainContextMenuElement = componentRef.location.nativeElement;
|
||||||
|
|
||||||
|
return componentRef.instance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search the ion-header where the buttons should be added.
|
* Search the ion-header where the buttons should be added.
|
||||||
*
|
*
|
||||||
|
@ -214,11 +246,9 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
*/
|
*/
|
||||||
protected showHideAllElements(): void {
|
protected showHideAllElements(): void {
|
||||||
// Show or hide all moved children.
|
// Show or hide all moved children.
|
||||||
if (this.movedChildren) {
|
this.movedChildren?.forEach((child: Node) => {
|
||||||
this.movedChildren.forEach((child: Node) => {
|
this.showHideElement(child);
|
||||||
this.showHideElement(child);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show or hide all the context menu items that were merged to another context menu.
|
// Show or hide all the context menu items that were merged to another context menu.
|
||||||
if (this.mergedContextMenu) {
|
if (this.mergedContextMenu) {
|
||||||
|
@ -236,8 +266,8 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
* @param element Element to show or hide.
|
* @param element Element to show or hide.
|
||||||
*/
|
*/
|
||||||
protected showHideElement(element: Node): void {
|
protected showHideElement(element: Node): void {
|
||||||
// Check if it's an HTML Element
|
// Check if it's an HTML Element and it's not a created context menu. Never hide created context menus.
|
||||||
if (element instanceof Element) {
|
if (element instanceof Element && element !== this.createdMainContextMenuElement) {
|
||||||
element.classList.toggle(BUTTON_HIDDEN_CLASS, !!this.forceHidden || !!this.allButtonsHidden);
|
element.classList.toggle(BUTTON_HIDDEN_CLASS, !!this.forceHidden || !!this.allButtonsHidden);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,17 +279,13 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy {
|
||||||
// This component was destroyed, remove all the buttons that were moved.
|
// This component was destroyed, remove all the buttons that were moved.
|
||||||
// The buttons can be moved outside of the current page, that's why we need to manually destroy them.
|
// The buttons can be moved outside of the current page, that's why we need to manually destroy them.
|
||||||
// There's no need to destroy context menu items that were merged because they weren't moved from their DOM position.
|
// There's no need to destroy context menu items that were merged because they weren't moved from their DOM position.
|
||||||
if (this.movedChildren) {
|
this.movedChildren?.forEach((child) => {
|
||||||
this.movedChildren.forEach((child) => {
|
if (child.parentElement && child !== this.createdMainContextMenuElement) {
|
||||||
if (child.parentElement) {
|
child.parentElement.removeChild(child);
|
||||||
child.parentElement.removeChild(child);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.mergedContextMenu) {
|
this.mergedContextMenu?.removeMergedItems();
|
||||||
this.mergedContextMenu.removeMergedItems();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,8 @@
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template #news>
|
<ng-template #news>
|
||||||
<core-course-module class="core-sitehome-news" *ngIf="newsForumModule" [module]="newsForumModule" [courseId]="siteHomeId">
|
<core-course-module class="core-sitehome-news" *ngIf="newsForumModule" [module]="newsForumModule" [courseId]="siteHomeId"
|
||||||
|
[downloadEnabled]="downloadEnabled">
|
||||||
</core-course-module>
|
</core-course-module>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue