MOBILE-4456 course: Adapt purpose of the icons to new version
parent
b69341ecb2
commit
c3c414a1da
|
@ -45,7 +45,7 @@ export class AddonModBBBModuleHandlerService extends CoreModuleHandlerBase imple
|
|||
[CoreConstants.FEATURE_GRADE_OUTCOMES]: true,
|
||||
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_OTHER,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_COMMUNICATION,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,7 +42,7 @@ export class AddonModH5PActivityModuleHandlerService extends CoreModuleHandlerBa
|
|||
[CoreConstants.FEATURE_GRADE_HAS_GRADE]: true,
|
||||
[CoreConstants.FEATURE_GRADE_OUTCOMES]: true,
|
||||
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_CONTENT,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_INTERACTIVECONTENT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,7 +42,7 @@ export class AddonModImscpModuleHandlerService extends CoreModuleHandlerBase imp
|
|||
[CoreConstants.FEATURE_GRADE_OUTCOMES]: false,
|
||||
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_CONTENT,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_INTERACTIVECONTENT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,7 +42,7 @@ export class AddonModLessonModuleHandlerService extends CoreModuleHandlerBase im
|
|||
[CoreConstants.FEATURE_GRADE_OUTCOMES]: true,
|
||||
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_CONTENT,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_INTERACTIVECONTENT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,7 +44,7 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
|
|||
[CoreConstants.FEATURE_GRADE_OUTCOMES]: true,
|
||||
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_CONTENT,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_OTHER,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,7 +41,7 @@ export class AddonModScormModuleHandlerService extends CoreModuleHandlerBase imp
|
|||
[CoreConstants.FEATURE_GRADE_OUTCOMES]: true,
|
||||
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_CONTENT,
|
||||
[CoreConstants.FEATURE_MOD_PURPOSE]: ModPurpose.MOD_PURPOSE_INTERACTIVECONTENT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1431,7 +1431,7 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (typeof versions == 'string') {
|
||||
} else if (typeof versions === 'string') {
|
||||
// Compare with this version.
|
||||
return siteVersion >= this.getVersionNumber(versions);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<img *ngIf="!isLocalUrl" [src]="icon" [alt]="showAlt ? modNameTranslated : ''" [attr.role]="!showAlt ? 'presentation' : null"
|
||||
class="core-module-icon" [class.no-filter]="noFilter" core-external-content [component]="linkIconWithComponent ? modname : null"
|
||||
<img *ngIf="!isLocalUrl && !iconSVG" [src]="icon" [alt]="showAlt ? modNameTranslated : ''" [attr.role]="!showAlt ? 'presentation' : null"
|
||||
class="core-module-icon" core-external-content [component]="linkIconWithComponent ? modname : null"
|
||||
[componentId]="linkIconWithComponent ? componentId : null" (error)="loadFallbackIcon()">
|
||||
<img *ngIf="isLocalUrl" [src]="icon" [alt]="showAlt ? modNameTranslated : ''" [attr.role]="!showAlt ? 'presentation' : null"
|
||||
class="core-module-icon" [class.no-filter]="noFilter" (error)="loadFallbackIcon()">
|
||||
<img *ngIf="isLocalUrl && !iconSVG" [src]="icon" [alt]="showAlt ? modNameTranslated : ''" [attr.role]="!showAlt ? 'presentation' : null"
|
||||
class="core-module-icon" (error)="loadFallbackIcon()">
|
||||
<div *ngIf="iconSVG" class="core-module-icon" [innerHTML]="iconSVG" [attr.aria-label]="showAlt ? modNameTranslated : ''"
|
||||
[attr.role]="!showAlt ? 'presentation' : null"></div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
:host {
|
||||
display: inline-block;
|
||||
--size: var(--module-icon-size, 24px);
|
||||
--size: var(--module-icon-size, 32px);
|
||||
--padding: var(--module-icon-padding, 8px);
|
||||
--icon-radius: var(--module-icon-radius, var(--radius-xs));
|
||||
--margin-end: 0px;
|
||||
|
@ -14,16 +14,43 @@
|
|||
|
||||
border-radius: var(--icon-radius);
|
||||
padding: var(--padding);
|
||||
background-color: $gray-100;
|
||||
background-color: transparent;
|
||||
line-height: var(--size);
|
||||
|
||||
@each $type, $value in $activity-icon-colors {
|
||||
&.#{$type} {
|
||||
background-color: var(--activity#{$type});
|
||||
img {
|
||||
filter: var(--filter, brightness(0) invert(1));
|
||||
&.version_current {
|
||||
@each $type, $value in $activity-icon-color-filters {
|
||||
&.#{$type} {
|
||||
--filter: var(--activity#{$type});
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
filter: var(--filter, brightness(0) invert(1));
|
||||
}
|
||||
}
|
||||
|
||||
&.version_40 {
|
||||
--size: var(--module-icon-size, 24px);
|
||||
background-color: $gray-100;
|
||||
|
||||
@each $type, $value in $activity-icon-background-colors {
|
||||
&.#{$type} {
|
||||
background-color: var(--activity-40-#{$type});
|
||||
img {
|
||||
filter: var(--filter, brightness(0) invert(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.version_legacy {
|
||||
--size: var(--module-icon-size, 24px);
|
||||
--filter: none;
|
||||
background-color: $gray-100;
|
||||
}
|
||||
|
||||
&.no-filter {
|
||||
--filter: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,11 +68,6 @@ img {
|
|||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&.no-filter {
|
||||
--filter: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
:host-context(ion-item) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { CoreConstants, ModPurpose } from '@/core/constants';
|
||||
import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChange } from '@angular/core';
|
||||
import { Component, ElementRef, HostBinding, Input, OnChanges, OnInit, SimpleChange } from '@angular/core';
|
||||
import { CoreCourse } from '@features/course/services/course';
|
||||
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||
import { CoreSites } from '@services/sites';
|
||||
|
@ -23,6 +23,12 @@ import { CoreUrlUtils } from '@services/utils/url';
|
|||
const assetsPath = 'assets/img/';
|
||||
const fallbackModName = 'external-tool';
|
||||
|
||||
const enum IconVersion {
|
||||
LEGACY_VERSION = 'version_legacy',
|
||||
VERSION_4_0 = 'version_40',
|
||||
CURRENT_VERSION = 'version_current',
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to handle a module icon.
|
||||
*/
|
||||
|
@ -33,6 +39,8 @@ const fallbackModName = 'external-tool';
|
|||
})
|
||||
export class CoreModIconComponent implements OnInit, OnChanges {
|
||||
|
||||
@HostBinding('class.no-filter') noFilter = false;
|
||||
|
||||
@Input() modname = ''; // The module name. Used also as component if set.
|
||||
@Input() fallbackTranslation = ''; // Fallback translation string if cannot auto translate.
|
||||
@Input() componentId?: number; // Component Id for external icons.
|
||||
|
@ -41,12 +49,12 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
@Input() purpose: ModPurpose = ModPurpose.MOD_PURPOSE_OTHER; // Purpose of the module.
|
||||
|
||||
icon = '';
|
||||
noFilter = false;
|
||||
|
||||
modNameTranslated = '';
|
||||
isLocalUrl = true;
|
||||
linkIconWithComponent = false;
|
||||
|
||||
protected legacyIcon = true; // @deprecatedonmoodle since 3.11.
|
||||
@HostBinding('class') iconVersion = 'legacy';
|
||||
|
||||
constructor(protected el: ElementRef) { }
|
||||
|
||||
|
@ -54,22 +62,35 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
* @inheritdoc
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.iconVersion = this.getIconVersion();
|
||||
|
||||
if (!this.modname && this.modicon) {
|
||||
// Guess module from the icon url.
|
||||
this.modname = this.getComponentNameFromIconUrl(this.modicon);
|
||||
}
|
||||
|
||||
this.modNameTranslated = CoreCourse.translateModuleName(this.modname, this.fallbackTranslation);
|
||||
if (CoreSites.getCurrentSite()?.isVersionGreaterEqualThan('4.0')) {
|
||||
this.legacyIcon = false;
|
||||
if (this.iconVersion !== IconVersion.LEGACY_VERSION) {
|
||||
|
||||
const purposeClass =
|
||||
let purposeClass =
|
||||
CoreCourseModuleDelegate.supportsFeature<ModPurpose>(
|
||||
this.modname || '',
|
||||
CoreConstants.FEATURE_MOD_PURPOSE,
|
||||
this.purpose,
|
||||
);
|
||||
|
||||
if (this.iconVersion === IconVersion.VERSION_4_0) {
|
||||
if (purposeClass === ModPurpose.MOD_PURPOSE_INTERACTIVECONTENT) {
|
||||
// Interactive content was introduced on 4.4, on previous versions CONTENT is used instead.
|
||||
purposeClass = ModPurpose.MOD_PURPOSE_CONTENT;
|
||||
}
|
||||
|
||||
if (this.modname === 'lti') {
|
||||
// LTI had content purpose with 4.0 icons.
|
||||
purposeClass = ModPurpose.MOD_PURPOSE_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (purposeClass) {
|
||||
const element: HTMLElement = this.el.nativeElement;
|
||||
element.classList.add(purposeClass);
|
||||
|
@ -129,13 +150,13 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
*/
|
||||
protected async getIconNoFilter(): Promise<boolean> {
|
||||
// Earlier 4.0, icons were never filtered.
|
||||
if (this.legacyIcon) {
|
||||
if (this.iconVersion === IconVersion.LEGACY_VERSION) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// No icon or local icon (not legacy), filter it.
|
||||
if (!this.icon || this.isLocalUrl) {
|
||||
return false;
|
||||
return await CoreCourseModuleDelegate.moduleIconIsBranded(this.modname);
|
||||
}
|
||||
|
||||
this.icon = CoreTextUtils.decodeHTMLEntities(this.icon);
|
||||
|
@ -192,4 +213,23 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the icon version depending on site version.
|
||||
*
|
||||
* @returns Icon version.
|
||||
*/
|
||||
protected getIconVersion(): IconVersion {
|
||||
if (!CoreSites.getCurrentSite()?.isVersionGreaterEqualThan('4.0')) {
|
||||
// @deprecatedonmoodle since 3.11.
|
||||
return IconVersion.LEGACY_VERSION;
|
||||
}
|
||||
|
||||
if (!CoreSites.getCurrentSite()?.isVersionGreaterEqualThan('4.4')) {
|
||||
// @deprecatedonmoodle since 4.3.
|
||||
return IconVersion.VERSION_4_0;
|
||||
}
|
||||
|
||||
return IconVersion.CURRENT_VERSION;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ export const enum ModPurpose {
|
|||
MOD_PURPOSE_COLLABORATION = 'collaboration',
|
||||
MOD_PURPOSE_CONTENT = 'content',
|
||||
MOD_PURPOSE_ADMINISTRATION = 'administration',
|
||||
MOD_PURPOSE_INTERFACE = 'interface',
|
||||
MOD_PURPOSE_INTERFACE = 'interface', // @deprecatedonmoodle since 4.4.
|
||||
MOD_PURPOSE_INTERACTIVECONTENT = 'interactivecontent',
|
||||
MOD_PURPOSE_OTHER = 'other',
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<ion-item class="ion-text-wrap" collapsible>
|
||||
<core-mod-icon slot="start" [modicon]="modicon" [modname]="module.modname" [componentId]="module.instance" />
|
||||
<core-mod-icon slot="start" [modicon]="modicon" [modname]="module.modname" [componentId]="module.instance" [purpose]="module.purpose" />
|
||||
<ion-label>
|
||||
<h1>
|
||||
<core-format-text [text]="module.name" contextLevel="module" [component]="component" [componentId]="componentId"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<ion-label>
|
||||
<p *ngIf="moduleNameTranslated" class="core-modulename">
|
||||
<core-mod-icon slot="start" [modicon]="modicon" [modname]="module.modname" [componentId]="module.instance"
|
||||
[fallbackTranslation]="module.modplural" />
|
||||
[fallbackTranslation]="module.modplural" [purpose]="module.purpose" />
|
||||
{{moduleNameTranslated}}
|
||||
</p>
|
||||
<h1>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<ion-label>
|
||||
<div class="activity-main">
|
||||
<core-mod-icon *ngIf="module.handlerData.icon" [modicon]="module.handlerData.icon" [modname]="module.modname"
|
||||
[componentId]="module.instance" [fallbackTranslation]="module.modplural" />
|
||||
[componentId]="module.instance" [fallbackTranslation]="module.modplural" [purpose]="module.purpose" />
|
||||
<div class="activity-title">
|
||||
<p class="item-heading">
|
||||
<core-format-text [text]="module.handlerData.title" contextLevel="module" [contextInstanceId]="module.id"
|
||||
|
|
|
@ -1750,6 +1750,7 @@ export type CoreCourseGetContentsWSModule = {
|
|||
visibleoncoursepage: number; // Is the module visible on course page. Cannot be undefined.
|
||||
modicon: string; // Activity icon url.
|
||||
modname: string; // Activity module type.
|
||||
purpose?: string; // @since 4.4 The module purpose.
|
||||
modplural: string; // Activity module plural name.
|
||||
availability?: string; // Module availability settings.
|
||||
indent: number; // Number of identation in the site.
|
||||
|
|
|
@ -123,6 +123,14 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
|
|||
* @returns Promise resolved when done.
|
||||
*/
|
||||
openActivityPage(module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Whether the activity is branded.
|
||||
* This information is used, for instance, to decide if a filter should be applied to the icon or not.
|
||||
*
|
||||
* @returns bool True if the activity is branded, false otherwise.
|
||||
*/
|
||||
isBranded?(): Promise<boolean>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -115,8 +115,8 @@ $core-user-hide-siteinfo: $core-more-hide-siteinfo !default;
|
|||
$core-user-hide-sitename: $core-more-hide-sitename !default;
|
||||
$core-user-hide-siteurl: $core-more-hide-siteurl !default;
|
||||
|
||||
// Activity icon background colors.
|
||||
$activity-icon-colors: (
|
||||
// Activity icon background colors. Only used on 4.0-4.3. @deprecatedonmoodle since 4.4.
|
||||
$activity-icon-background-colors: (
|
||||
administration: #5d63f6,
|
||||
assessment: #eb66a2,
|
||||
collaboration: #f7634d,
|
||||
|
@ -125,6 +125,25 @@ $activity-icon-colors: (
|
|||
interface: #a378ff
|
||||
) !default;
|
||||
|
||||
// Moodle 4.4 onwards.
|
||||
$activity-icon-colors: (
|
||||
administration: #da58ef,
|
||||
assessment: #f90086,
|
||||
collaboration: #5b40ff,
|
||||
communication: #eb6200,
|
||||
content: #0099ad,
|
||||
interactivecontent: #8d3d1b
|
||||
) !default;
|
||||
|
||||
$activity-icon-color-filters: (
|
||||
administration: invert(45%) sepia(46%) saturate(3819%) hue-rotate(260deg) brightness(101%) contrast(87%),
|
||||
assessment: invert(36%) sepia(98%) saturate(6969%) hue-rotate(315deg) brightness(90%) contrast(119%),
|
||||
collaboration: invert(25%) sepia(54%) saturate(6226%) hue-rotate(245deg) brightness(100%) contrast(102%),
|
||||
communication: invert(48%) sepia(74%) saturate(4887%) hue-rotate(11deg) brightness(102%) contrast(101%),
|
||||
content: invert(49%) sepia(52%) saturate(4675%) hue-rotate(156deg) brightness(89%) contrast(102%),
|
||||
interactivecontent: invert(25%) sepia(63%) saturate(1152%) hue-rotate(344deg) brightness(94%) contrast(91%)
|
||||
) !default;
|
||||
|
||||
$calendar-event-category-category: #8e24aa !default;
|
||||
$calendar-event-category-course: $red !default;
|
||||
$calendar-event-category-group: $yellow !default;
|
||||
|
|
|
@ -404,10 +404,15 @@ html {
|
|||
}
|
||||
|
||||
// Make activtity colours available for custom modules.
|
||||
@each $type, $value in $activity-icon-colors {
|
||||
@each $type, $value in $activity-icon-color-filters {
|
||||
--activity#{$type}: #{$value};
|
||||
}
|
||||
|
||||
// Make activtity colours available for custom modules.
|
||||
@each $type, $value in $activity-icon-background-colors {
|
||||
--activity-40-#{$type}: #{$value};
|
||||
}
|
||||
|
||||
--core-mainpage-sitename-display: none;
|
||||
--core-mainpage-headerlogo-display: none;
|
||||
--core-mainpage-headerlogo-maxheight: calc(var(--core-header-toolbar-height) - 16px);
|
||||
|
|
Loading…
Reference in New Issue