MOBILE-2310 core: Implement image viewer
parent
cbc9bc715c
commit
764309edd7
|
@ -17,6 +17,7 @@ import { CoreSitesProvider } from '../../../../providers/sites';
|
|||
import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '../../../../providers/utils/text';
|
||||
import { CoreUtilsProvider } from '../../../../providers/utils/utils';
|
||||
import { CoreCourseProvider } from '../../../course/providers/course';
|
||||
import * as moment from 'moment';
|
||||
|
||||
/**
|
||||
|
@ -41,7 +42,8 @@ export class CoreCoursesOverviewEventsComponent implements OnChanges {
|
|||
future: any[] = [];
|
||||
|
||||
constructor(private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private sitesProvider: CoreSitesProvider) {
|
||||
private domUtils: CoreDomUtilsProvider, private sitesProvider: CoreSitesProvider,
|
||||
private courseProvider: CoreCourseProvider) {
|
||||
this.loadMore = new EventEmitter();
|
||||
}
|
||||
|
||||
|
@ -73,7 +75,7 @@ export class CoreCoursesOverviewEventsComponent implements OnChanges {
|
|||
|
||||
return start <= event.timesort;
|
||||
}).map((event) => {
|
||||
// @todo: event.iconUrl = this.courseProvider.getModuleIconSrc(event.icon.component);
|
||||
event.iconUrl = this.courseProvider.getModuleIconSrc(event.icon.component);
|
||||
return event;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
|
||||
<ion-buttons end *ngIf="isModal">
|
||||
<button ion-button icon-only (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
|
||||
<ion-icon name="close"></ion-icon>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<img [src]="image" alt="{{ title }}" core-external-content [component]="component" [componentId]="componentId">
|
||||
</ion-content>
|
|
@ -0,0 +1,31 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CoreViewerImagePage } from './image';
|
||||
import { CoreDirectivesModule } from '../../../../directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
CoreViewerImagePage
|
||||
],
|
||||
imports: [
|
||||
CoreDirectivesModule,
|
||||
IonicPageModule.forChild(CoreViewerImagePage),
|
||||
TranslateModule.forChild()
|
||||
]
|
||||
})
|
||||
export class CoreViewerImagePageModule {}
|
|
@ -0,0 +1,48 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { IonicPage, ViewController, NavParams } from 'ionic-angular';
|
||||
|
||||
/**
|
||||
* Page to view an image. If opened as a modal, it will have a button to close the modal.
|
||||
*/
|
||||
@IonicPage({segment: 'core-viewer-image'})
|
||||
@Component({
|
||||
selector: 'page-core-viewer-image',
|
||||
templateUrl: 'image.html',
|
||||
})
|
||||
export class CoreViewerImagePage {
|
||||
title: string; // Page title.
|
||||
image: string; // Image URL.
|
||||
isModal: boolean; // Whether it should be opened in a modal or in a page.
|
||||
component: string; // Component to use in external-content.
|
||||
componentId: string|number; // Component ID to use in external-content.
|
||||
|
||||
constructor(private viewCtrl: ViewController, params: NavParams, translate: TranslateService) {
|
||||
this.title = params.get('title') || translate.instant('core.imageviewer');
|
||||
this.image = params.get('image');
|
||||
this.isModal = params.get('isModal');
|
||||
this.component = params.get('component');
|
||||
this.componentId = params.get('componentId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Close modal.
|
||||
*/
|
||||
closeModal() : void {
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
}
|
|
@ -125,15 +125,35 @@ export class CoreFormatTextDirective implements OnChanges {
|
|||
|
||||
if (imgWidth > elWidth) {
|
||||
// The image has been adapted, add an anchor to view it in full size.
|
||||
let imgSrc = this.textUtils.escapeHTML(img.getAttribute('src')),
|
||||
label = this.textUtils.escapeHTML(this.translate.instant('core.openfullimage'));
|
||||
|
||||
// @todo: Implement image viewer. Maybe we can add the listener here directly?
|
||||
container.innerHTML += '<a href="#" class="core-image-viewer-icon" core-image-viewer img="' + imgSrc +
|
||||
'" aria-label="' + label + '"><ion-icon name="search"></ion-icon></a>';
|
||||
this.addMagnifyingGlass(container, img);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a magnifying glass icon to view an image at full size.
|
||||
*
|
||||
* @param {HTMLElement} container The container of the image.
|
||||
* @param {HTMLElement} img The image.
|
||||
*/
|
||||
addMagnifyingGlass(container: HTMLElement, img: HTMLElement) : void {
|
||||
let imgSrc = this.textUtils.escapeHTML(img.getAttribute('src')),
|
||||
label = this.textUtils.escapeHTML(this.translate.instant('core.openfullimage')),
|
||||
anchor = document.createElement('a');
|
||||
|
||||
anchor.classList.add('core-image-viewer-icon');
|
||||
anchor.setAttribute('aria-label', label);
|
||||
// Add an ion-icon item to apply the right styles, but the ion-icon component won't be executed.
|
||||
anchor.innerHTML = '<ion-icon name="search" class="icon icon-md ion-md-search"></ion-icon>';
|
||||
|
||||
anchor.addEventListener('click', (e: Event) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.domUtils.viewImage(imgSrc, img.getAttribute('alt'), true, this.component, this.componentId);
|
||||
});
|
||||
|
||||
container.appendChild(anchor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the rendering, displaying the element again and calling afterRender.
|
||||
*/
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { LoadingController, Loading, ToastController, Toast, AlertController, Alert, Platform, Content } from 'ionic-angular';
|
||||
import { LoadingController, Loading, ToastController, Toast, AlertController, Alert, Platform, Content,
|
||||
NavController, ModalController } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreTextUtilsProvider } from './text';
|
||||
import { CoreAppProvider } from '../app';
|
||||
|
@ -33,7 +34,8 @@ export class CoreDomUtilsProvider {
|
|||
|
||||
constructor(private translate: TranslateService, private loadingCtrl: LoadingController, private toastCtrl: ToastController,
|
||||
private alertCtrl: AlertController, private textUtils: CoreTextUtilsProvider, private appProvider: CoreAppProvider,
|
||||
private platform: Platform, private configProvider: CoreConfigProvider, private urlUtils: CoreUrlUtilsProvider) {}
|
||||
private platform: Platform, private configProvider: CoreConfigProvider, private urlUtils: CoreUrlUtilsProvider,
|
||||
private modalCtrl: ModalController) {}
|
||||
|
||||
/**
|
||||
* Wraps a message with core-format-text if the message contains HTML tags.
|
||||
|
@ -840,6 +842,40 @@ export class CoreDomUtilsProvider {
|
|||
(el.tagName.toLowerCase() == 'input' && this.inputSupportKeyboard.indexOf(el.type) != -1));
|
||||
}
|
||||
|
||||
/**
|
||||
* View an image in a new page or modal.
|
||||
*
|
||||
* @param {string} image URL of the image.
|
||||
* @param {string} title Title of the page or modal.
|
||||
* @param {boolean} [isModal] Whether it should be opened in a modal (true) or in a new page (false).
|
||||
* @param {string} [component] Component to link the image to if needed.
|
||||
* @param {string|number} [componentId] An ID to use in conjunction with the component.
|
||||
* @param {NavController} [navCtrl] The NavController instance to use.
|
||||
*/
|
||||
viewImage(image: string, title?: string, isModal?: boolean, component?: string, componentId?: string|number,
|
||||
navCtrl?: NavController) : void {
|
||||
if (image) {
|
||||
let params: any = {
|
||||
title: title,
|
||||
image: image,
|
||||
component: component,
|
||||
componentId: componentId
|
||||
};
|
||||
|
||||
if (isModal) {
|
||||
// Open a modal with the contents.
|
||||
params.isModal = true;
|
||||
|
||||
let modal = this.modalCtrl.create('CoreViewerImagePage', params);
|
||||
modal.present();
|
||||
} else if (navCtrl) {
|
||||
// Open a new page with the contents.
|
||||
navCtrl.push('CoreViewerImagePage', params);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an HTMLElement with another element.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue