MOBILE-2235 h5p: Display download button in H5P placeholder
parent
690544afbf
commit
9b637fc496
|
@ -1,4 +1,4 @@
|
||||||
<div [class.core-loading-container]="loading">
|
<div [class.core-loading-container]="loading" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}">
|
||||||
<iframe #iframe [hidden]="loading" class="core-iframe" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}" [src]="safeUrl"></iframe>
|
<iframe #iframe [hidden]="loading" class="core-iframe" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}" [src]="safeUrl"></iframe>
|
||||||
<span class="core-loading-spinner">
|
<span class="core-loading-spinner">
|
||||||
<ion-spinner *ngIf="loading"></ion-spinner>
|
<ion-spinner *ngIf="loading"></ion-spinner>
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
ion-app.app-root core-iframe {
|
ion-app.app-root core-iframe {
|
||||||
> div {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
iframe {
|
iframe {
|
||||||
border: 0;
|
border: 0;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import { CORE_COURSES_PROVIDERS } from '@core/courses/courses.module';
|
||||||
import { CORE_FILEUPLOADER_PROVIDERS } from '@core/fileuploader/fileuploader.module';
|
import { CORE_FILEUPLOADER_PROVIDERS } from '@core/fileuploader/fileuploader.module';
|
||||||
import { CORE_FILTER_PROVIDERS } from '@core/filter/filter.module';
|
import { CORE_FILTER_PROVIDERS } from '@core/filter/filter.module';
|
||||||
import { CORE_GRADES_PROVIDERS } from '@core/grades/grades.module';
|
import { CORE_GRADES_PROVIDERS } from '@core/grades/grades.module';
|
||||||
|
import { CORE_H5P_PROVIDERS } from '@core/h5p/h5p.module';
|
||||||
import { CORE_LOGIN_PROVIDERS } from '@core/login/login.module';
|
import { CORE_LOGIN_PROVIDERS } from '@core/login/login.module';
|
||||||
import { CORE_MAINMENU_PROVIDERS } from '@core/mainmenu/mainmenu.module';
|
import { CORE_MAINMENU_PROVIDERS } from '@core/mainmenu/mainmenu.module';
|
||||||
import { CORE_QUESTION_PROVIDERS } from '@core/question/question.module';
|
import { CORE_QUESTION_PROVIDERS } from '@core/question/question.module';
|
||||||
|
@ -236,7 +237,7 @@ export class CoreCompileProvider {
|
||||||
.concat(ADDON_MOD_SURVEY_PROVIDERS).concat(ADDON_MOD_URL_PROVIDERS).concat(ADDON_MOD_WIKI_PROVIDERS)
|
.concat(ADDON_MOD_SURVEY_PROVIDERS).concat(ADDON_MOD_URL_PROVIDERS).concat(ADDON_MOD_WIKI_PROVIDERS)
|
||||||
.concat(ADDON_MOD_WORKSHOP_PROVIDERS).concat(ADDON_NOTES_PROVIDERS).concat(ADDON_NOTIFICATIONS_PROVIDERS)
|
.concat(ADDON_MOD_WORKSHOP_PROVIDERS).concat(ADDON_NOTES_PROVIDERS).concat(ADDON_NOTIFICATIONS_PROVIDERS)
|
||||||
.concat(CORE_PUSHNOTIFICATIONS_PROVIDERS).concat(ADDON_REMOTETHEMES_PROVIDERS).concat(CORE_BLOCK_PROVIDERS)
|
.concat(CORE_PUSHNOTIFICATIONS_PROVIDERS).concat(ADDON_REMOTETHEMES_PROVIDERS).concat(CORE_BLOCK_PROVIDERS)
|
||||||
.concat(CORE_FILTER_PROVIDERS);
|
.concat(CORE_FILTER_PROVIDERS).concat(CORE_H5P_PROVIDERS);
|
||||||
|
|
||||||
// We cannot inject anything to this constructor. Use the Injector to inject all the providers into the instance.
|
// We cannot inject anything to this constructor. Use the Injector to inject all the providers into the instance.
|
||||||
for (const i in providers) {
|
for (const i in providers) {
|
||||||
|
|
|
@ -402,7 +402,7 @@ export type CoreFilterFilter = {
|
||||||
*/
|
*/
|
||||||
export type CoreFilterGetAvailableInContextResult = {
|
export type CoreFilterGetAvailableInContextResult = {
|
||||||
filters: CoreFilterFilter[]; // Available filters.
|
filters: CoreFilterFilter[]; // Available filters.
|
||||||
warning: CoreWSExternalWarning[]; // List of warnings.
|
warnings: CoreWSExternalWarning[]; // List of warnings.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
<div *ngIf="!showPackage" class="core-h5p-placeholder">
|
<div *ngIf="!showPackage" class="core-h5p-placeholder">
|
||||||
<button *ngIf="!loading" class="core-h5p-placeholder-play-button" ion-button icon-only clear color="dark" (click)="play($event)">
|
<button *ngIf="!loading && !errorMessage" class="core-h5p-placeholder-play-button" ion-button icon-only clear (click)="play($event)">
|
||||||
<core-icon name="fa-play-circle"></core-icon>
|
<core-icon name="fa-play-circle"></core-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ion-spinner *ngIf="loading" class="core-h5p-placeholder-spinner"></ion-spinner>
|
<ion-spinner *ngIf="loading && !errorMessage" class="core-h5p-placeholder-spinner"></ion-spinner>
|
||||||
|
|
||||||
|
<div *ngIf="errorMessage" class="core-h5p-placeholder-error">{{ errorMessage }}</div>
|
||||||
|
|
||||||
|
<div class="core-h5p-placeholder-download-container">
|
||||||
|
<core-download-refresh [status]="state" [enabled]="canDownload" [loading]="calculating" [canTrustDownload]="true" (action)="download()"></core-download-refresh>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<core-iframe *ngIf="showPackage" [src]="src"></core-iframe>
|
<core-iframe *ngIf="showPackage" [src]="playerSrc" iframeHeight="230px"></core-iframe>
|
||||||
|
|
|
@ -1,23 +1,56 @@
|
||||||
|
// H5P variables.
|
||||||
|
$core-h5p-placeholder-bg-color: $gray !default;
|
||||||
|
$core-h5p-placeholder-text-color: $text-color !default;
|
||||||
|
|
||||||
ion-app.app-root core-h5p-player {
|
ion-app.app-root core-h5p-player {
|
||||||
.core-h5p-placeholder {
|
.core-h5p-placeholder {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 230px;
|
height: 230px;
|
||||||
background: url('../assets/img/icons/h5p.svg') center top 25px / 100px auto no-repeat $core-h5p-placeholder-bg-color;
|
background: url('../assets/img/icons/h5p.svg') center top 25px / 100px auto no-repeat $core-h5p-placeholder-bg-color;
|
||||||
|
color: $core-h5p-placeholder-text-color;
|
||||||
|
|
||||||
.core-h5p-placeholder-play-button {
|
.icon {
|
||||||
|
color: $core-h5p-placeholder-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.core-h5p-placeholder-play-button, .core-h5p-placeholder-spinner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.core-h5p-placeholder-play-button {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
min-height: 50px;
|
min-height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-h5p-placeholder-download-container {
|
.core-h5p-placeholder-download-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 10px;
|
top: 0;
|
||||||
font-size: 1.8em;
|
right: 0;
|
||||||
|
|
||||||
|
ion-spinner {
|
||||||
|
margin-right: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
core-download-refresh > ion-icon {
|
||||||
|
margin: 0.4rem 0.2rem;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
line-height: .67;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.core-h5p-placeholder-error {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-spinner circle {
|
||||||
|
stroke: $core-h5p-placeholder-text-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,12 @@
|
||||||
// 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, ElementRef } from '@angular/core';
|
import { Component, Input, ElementRef, OnInit, SimpleChange } from '@angular/core';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
|
import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
||||||
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
|
import { CoreH5PProvider } from '@core/h5p/providers/h5p';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render an H5P package.
|
* Component to render an H5P package.
|
||||||
|
@ -22,17 +26,39 @@ import { CoreSitesProvider } from '@providers/sites';
|
||||||
selector: 'core-h5p-player',
|
selector: 'core-h5p-player',
|
||||||
templateUrl: 'core-h5p-player.html'
|
templateUrl: 'core-h5p-player.html'
|
||||||
})
|
})
|
||||||
export class CoreH5PPlayerComponent {
|
export class CoreH5PPlayerComponent implements OnInit {
|
||||||
@Input() src: string; // The URL of the player to display the H5P package.
|
@Input() src: string; // The URL of the player to display the H5P package.
|
||||||
|
|
||||||
|
playerSrc: string;
|
||||||
showPackage = false;
|
showPackage = false;
|
||||||
loading = false;
|
loading = false;
|
||||||
status: string;
|
status: string;
|
||||||
canDownload: boolean;
|
canDownload: boolean;
|
||||||
calculating = true;
|
calculating = true;
|
||||||
|
errorMessage: string;
|
||||||
|
|
||||||
constructor(public elementRef: ElementRef,
|
constructor(public elementRef: ElementRef,
|
||||||
protected sitesProvider: CoreSitesProvider) {
|
protected sitesProvider: CoreSitesProvider,
|
||||||
|
protected urlUtils: CoreUrlUtilsProvider,
|
||||||
|
protected utils: CoreUtilsProvider,
|
||||||
|
protected textUtils: CoreTextUtilsProvider,
|
||||||
|
protected h5pProvider: CoreH5PProvider) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being initialized.
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.checkCanDownload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect changes on input properties.
|
||||||
|
*/
|
||||||
|
ngOnChanges(changes: {[name: string]: SimpleChange}): void {
|
||||||
|
// If it's already playing and the src changes, don't change the player src, the user could lose data.
|
||||||
|
if (changes.src && !this.showPackage) {
|
||||||
|
this.checkCanDownload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,11 +72,57 @@ export class CoreH5PPlayerComponent {
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
|
// @TODO: Check if package is downloaded and use the local player if so.
|
||||||
|
|
||||||
// Get auto-login URL so the user is automatically authenticated.
|
// Get auto-login URL so the user is automatically authenticated.
|
||||||
this.sitesProvider.getCurrentSite().getAutoLoginUrl(this.src, false).then((url) => {
|
this.sitesProvider.getCurrentSite().getAutoLoginUrl(this.src, false).then((url) => {
|
||||||
this.src = url;
|
this.playerSrc = url;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.showPackage = true;
|
this.showPackage = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download the package.
|
||||||
|
*/
|
||||||
|
download(): void {
|
||||||
|
// @TODO: Implement package download.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the package can be downloaded.
|
||||||
|
*/
|
||||||
|
protected checkCanDownload(): void {
|
||||||
|
if (this.src && this.h5pProvider.canGetTrustedH5PFileInSite()) {
|
||||||
|
const params = this.urlUtils.extractUrlParams(this.src);
|
||||||
|
|
||||||
|
// @todo: Check if H5P offline is disabled in the site.
|
||||||
|
|
||||||
|
// Now check if the package can be played.
|
||||||
|
this.calculating = true;
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
frame: this.utils.isTrueOrOne(params.frame),
|
||||||
|
export: this.utils.isTrueOrOne(params.export),
|
||||||
|
embed: this.utils.isTrueOrOne(params.embed),
|
||||||
|
copyright: this.utils.isTrueOrOne(params.copyright),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.h5pProvider.getTrustedH5PFile(params.url, options).then((file) => {
|
||||||
|
this.canDownload = true;
|
||||||
|
this.errorMessage = undefined;
|
||||||
|
}).catch((error) => {
|
||||||
|
this.canDownload = false;
|
||||||
|
this.errorMessage = this.textUtils.getErrorMessageFromError(error);
|
||||||
|
}).finally(() => {
|
||||||
|
this.calculating = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.calculating = false;
|
||||||
|
this.canDownload = false;
|
||||||
|
this.errorMessage = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CoreH5PComponentsModule } from './components/components.module';
|
import { CoreH5PComponentsModule } from './components/components.module';
|
||||||
|
import { CoreH5PProvider } from './providers/h5p';
|
||||||
|
|
||||||
|
// List of providers (without handlers).
|
||||||
|
export const CORE_H5P_PROVIDERS: any[] = [
|
||||||
|
CoreH5PProvider
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [],
|
declarations: [],
|
||||||
|
@ -21,6 +27,7 @@ import { CoreH5PComponentsModule } from './components/components.module';
|
||||||
CoreH5PComponentsModule
|
CoreH5PComponentsModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
CoreH5PProvider
|
||||||
],
|
],
|
||||||
exports: []
|
exports: []
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// 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 { Injectable } from '@angular/core';
|
||||||
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
|
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
|
import { CoreWSExternalWarning, CoreWSExternalFile } from '@providers/ws';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service to provide H5P functionalities.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class CoreH5PProvider {
|
||||||
|
|
||||||
|
protected ROOT_CACHE_KEY = 'mmH5P:';
|
||||||
|
|
||||||
|
protected logger;
|
||||||
|
|
||||||
|
constructor(logger: CoreLoggerProvider,
|
||||||
|
private sitesProvider: CoreSitesProvider) {
|
||||||
|
|
||||||
|
this.logger = logger.getInstance('CoreFilterProvider');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not WS to get trusted H5P file is available.
|
||||||
|
*
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with true if ws is available, false otherwise.
|
||||||
|
* @since 3.8
|
||||||
|
*/
|
||||||
|
canGetTrustedH5PFile(siteId?: string): Promise<boolean> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
return this.canGetTrustedH5PFileInSite(site);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not WS to get trusted H5P file is available in a certain site.
|
||||||
|
*
|
||||||
|
* @param site Site. If not defined, current site.
|
||||||
|
* @return Promise resolved with true if ws is available, false otherwise.
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
canGetTrustedH5PFileInSite(site?: CoreSite): boolean {
|
||||||
|
site = site || this.sitesProvider.getCurrentSite();
|
||||||
|
|
||||||
|
return site.wsAvailable('core_h5p_get_trusted_h5p_file');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a trusted H5P file.
|
||||||
|
*
|
||||||
|
* @param url The file URL.
|
||||||
|
* @param options Options.
|
||||||
|
* @param ignoreCache Whether to ignore cache..
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with the file data.
|
||||||
|
*/
|
||||||
|
getTrustedH5PFile(url: string, options: CoreH5PGetTrustedFileOptions, ignoreCache?: boolean, siteId?: string)
|
||||||
|
: Promise<CoreWSExternalFile> {
|
||||||
|
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
url: url,
|
||||||
|
frame: options.frame ? 1 : 0,
|
||||||
|
export: options.export ? 1 : 0,
|
||||||
|
embed: options.embed ? 1 : 0,
|
||||||
|
copyright: options.copyright ? 1 : 0,
|
||||||
|
},
|
||||||
|
preSets: CoreSiteWSPreSets = {
|
||||||
|
cacheKey: this.getTrustedH5PFileCacheKey(url),
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_RARELY
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ignoreCache) {
|
||||||
|
preSets.getFromCache = false;
|
||||||
|
preSets.emergencyCache = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return site.read('core_h5p_get_trusted_h5p_file', data, preSets).then((result: CoreH5PGetTrustedH5PFileResult): any => {
|
||||||
|
if (result.warnings && result.warnings.length) {
|
||||||
|
return Promise.reject(result.warnings[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.files && result.files.length) {
|
||||||
|
return result.files[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for trusted H5P file WS calls.
|
||||||
|
*
|
||||||
|
* @param url The file URL.
|
||||||
|
* @return Cache key.
|
||||||
|
*/
|
||||||
|
protected getTrustedH5PFileCacheKey(url: string): string {
|
||||||
|
return this.getTrustedH5PFilePrefixCacheKey() + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get prefixed cache key for trusted H5P file WS calls.
|
||||||
|
*
|
||||||
|
* @return Cache key.
|
||||||
|
*/
|
||||||
|
protected getTrustedH5PFilePrefixCacheKey(): string {
|
||||||
|
return this.ROOT_CACHE_KEY + 'trustedH5PFile:';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates all trusted H5P file WS calls.
|
||||||
|
*
|
||||||
|
* @param siteId Site ID (empty for current site).
|
||||||
|
* @return Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
invalidateAllGetTrustedH5PFile(siteId?: string): Promise<any> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
return site.invalidateWsCacheForKeyStartingWith(this.getTrustedH5PFilePrefixCacheKey());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates get trusted H5P file WS call.
|
||||||
|
*
|
||||||
|
* @param url The URL of the file.
|
||||||
|
* @param siteId Site ID (empty for current site).
|
||||||
|
* @return Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
invalidateAvailableInContexts(url: string, siteId?: string): Promise<any> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
return site.invalidateWsCacheForKey(this.getTrustedH5PFileCacheKey(url));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for core_h5p_get_trusted_h5p_file.
|
||||||
|
*/
|
||||||
|
export type CoreH5PGetTrustedFileOptions = {
|
||||||
|
frame?: boolean; // Whether to show the bar options below the content.
|
||||||
|
export?: boolean; // Whether to allow to download the package.
|
||||||
|
embed?: boolean; // Whether to allow to copy the code to your site.
|
||||||
|
copyright?: boolean; // The copyright option.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of core_h5p_get_trusted_h5p_file.
|
||||||
|
*/
|
||||||
|
export type CoreH5PGetTrustedH5PFileResult = {
|
||||||
|
files: CoreWSExternalFile[]; // Files.
|
||||||
|
warnings: CoreWSExternalWarning[]; // List of warnings.
|
||||||
|
};
|
|
@ -369,9 +369,6 @@ $core-question-state-incorrect-color: $red-light !default;
|
||||||
$core-dd-question-selected-shadow: 2px 2px 4px $gray-dark !default;
|
$core-dd-question-selected-shadow: 2px 2px 4px $gray-dark !default;
|
||||||
$core-dd-question-colors: $white, $blue-light, #DCDCDC, #D8BFD8, #87CEFA, #DAA520, #FFD700, #F0E68C !default;
|
$core-dd-question-colors: $white, $blue-light, #DCDCDC, #D8BFD8, #87CEFA, #DAA520, #FFD700, #F0E68C !default;
|
||||||
|
|
||||||
// H5P variables.
|
|
||||||
$core-h5p-placeholder-bg-color: $gray-dark !default;
|
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
// -------------------------
|
// -------------------------
|
||||||
@mixin core-transition($where: all, $time: 500ms) {
|
@mixin core-transition($where: all, $time: 500ms) {
|
||||||
|
|
Loading…
Reference in New Issue