MOBILE-4193 grades: Avoid filtering rich images
parent
0c998b8f8b
commit
f82d3504f6
|
@ -22,6 +22,7 @@ import { AddonModLtiHelper } from '../lti-helper';
|
|||
import { AddonModLtiIndexComponent } from '../../components/index';
|
||||
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||
import { CoreCourse } from '@features/course/services/course';
|
||||
import { CoreSites } from '@services/sites';
|
||||
|
||||
/**
|
||||
* Handler to support LTI modules.
|
||||
|
@ -86,6 +87,19 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
|
|||
return module?.modicon ?? modicon ?? CoreCourse.getModuleIconSrc(this.modName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
iconIsShape(module?: CoreCourseModuleData | undefined, modicon?: string | undefined): boolean | undefined {
|
||||
const iconUrl = module?.modicon ?? modicon;
|
||||
|
||||
if (!iconUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return iconUrl.startsWith(CoreSites.getRequiredCurrentSite().siteUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const AddonModLtiModuleHandler = makeSingleton(AddonModLtiModuleHandlerService);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<img *ngIf="!isLocalUrl" [src]="icon" [alt]="showAlt ? modNameTranslated : ''" [attr.role]="!showAlt ? 'presentation' : null"
|
||||
class="core-module-icon" core-external-content [component]="linkIconWithComponent ? modname : null"
|
||||
class="core-module-icon" [class.no-filter]="noFilter" 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" (error)="loadFallbackIcon()">
|
||||
class="core-module-icon" [class.no-filter]="noFilter" (error)="loadFallbackIcon()">
|
||||
|
|
|
@ -42,6 +42,11 @@ 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, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChange } from '@angular/core';
|
||||
import { CoreCourse } from '@features/course/services/course';
|
||||
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||
import { CoreSites } from '@services/sites';
|
||||
|
@ -34,9 +34,12 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
@Input() modname?: string; // The module name. Used also as component if set.
|
||||
@Input() componentId?: number; // Component Id for external icons.
|
||||
@Input() modicon?: string; // Module icon url or local url.
|
||||
@Input() noFilter?: boolean; // Whether to disable filters.
|
||||
@Input() showAlt = true; // Show alt otherwise it's only presentation icon.
|
||||
@Input() purpose: ModPurpose = ModPurpose.MOD_PURPOSE_OTHER; // Purpose of the module.
|
||||
|
||||
@Output() failedLoading = new EventEmitter<void>();
|
||||
|
||||
icon = '';
|
||||
modNameTranslated = '';
|
||||
isLocalUrl = true;
|
||||
|
@ -122,6 +125,8 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
}
|
||||
|
||||
this.icon = path + moduleName + '.svg';
|
||||
|
||||
this.failedLoading.emit();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -87,6 +87,15 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
|
|||
*/
|
||||
getIconSrc?(module?: CoreCourseModuleData, modicon?: string): Promise<string | undefined> | string | undefined;
|
||||
|
||||
/**
|
||||
* Check whether the icon should be treated as a shape or a rich image.
|
||||
*
|
||||
* @param module Module to get the icon from.
|
||||
* @param modicon The mod icon string.
|
||||
* @returns Whether the icon should be treated as a shape.
|
||||
*/
|
||||
iconIsShape?(module?: CoreCourseModuleData, modicon?: string): Promise<boolean | undefined> | boolean | undefined;
|
||||
|
||||
/**
|
||||
* Check if this type of module supports a certain feature.
|
||||
* If this function is implemented, the supportedFeatures object will be ignored.
|
||||
|
@ -396,6 +405,18 @@ export class CoreCourseModuleDelegateService extends CoreDelegate<CoreCourseModu
|
|||
return icon ?? CoreCourse.getModuleIconSrc(modname, modicon) ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the icon for the given module should be treated as a shape or a rich image.
|
||||
*
|
||||
* @param modname The name of the module type.
|
||||
* @param modicon The mod icon string.
|
||||
* @param module The module to use.
|
||||
* @returns Whether the icon should be treated as a shape.
|
||||
*/
|
||||
async moduleIconIsShape(modname: string, modicon?: string, module?: CoreCourseModuleData): Promise<boolean | undefined> {
|
||||
return await this.executeFunctionOnEnabled<Promise<boolean>>(modname, 'iconIsShape', [module, modicon]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a certain type of module supports a certain feature.
|
||||
*
|
||||
|
|
|
@ -48,7 +48,8 @@
|
|||
<img *ngIf="row.image && !row.itemmodule" [src]="row.image" slot="start" class="core-module-icon"
|
||||
[alt]="row.iconAlt" />
|
||||
<core-mod-icon *ngIf="row.image && row.itemmodule" [modicon]="row.image" slot="start"
|
||||
[modname]="row.itemmodule">
|
||||
[modname]="row.itemmodule" [noFilter]="row.imageIsShape === false"
|
||||
(failedLoading)="failedLoadingRowImage(row)">
|
||||
</core-mod-icon>
|
||||
<span [innerHTML]="row.gradeitem"></span>
|
||||
</th>
|
||||
|
|
|
@ -239,4 +239,13 @@ export class CoreGradesCoursePage implements AfterViewInit, OnDestroy {
|
|||
infiniteComplete && infiniteComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle row image failed loading.
|
||||
*
|
||||
* @param row Row data.
|
||||
*/
|
||||
failedLoadingRowImage(row: CoreGradesFormattedTableRow): void {
|
||||
delete row.imageIsShape;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -684,14 +684,16 @@ export class CoreGradesHelperProvider {
|
|||
row.iconAlt = Translate.instant('core.grades.calculatedgrade');
|
||||
} else if (text.indexOf('/mod/') > -1) {
|
||||
const module = text.match(/mod\/([^/]*)\//);
|
||||
if (module?.[1] !== undefined) {
|
||||
const modname = module?.[1];
|
||||
|
||||
if (modname !== undefined) {
|
||||
const modicon = CoreDomUtils.convertToElement(text).querySelector('img')?.getAttribute('src') ?? undefined;
|
||||
|
||||
row.itemtype = 'mod';
|
||||
row.itemmodule = module[1];
|
||||
row.itemmodule = modname;
|
||||
row.iconAlt = CoreCourse.translateModuleName(row.itemmodule) || '';
|
||||
row.image = await CoreCourseModuleDelegate.getModuleIconSrc(
|
||||
module[1],
|
||||
CoreDomUtils.convertToElement(text).querySelector('img')?.getAttribute('src') ?? undefined,
|
||||
);
|
||||
row.image = await CoreCourseModuleDelegate.getModuleIconSrc(modname, modicon);
|
||||
row.imageIsShape = await CoreCourseModuleDelegate.moduleIconIsShape(modname, modicon);
|
||||
}
|
||||
} else {
|
||||
if (row.rowspan && row.rowspan > 1) {
|
||||
|
@ -804,6 +806,7 @@ export type CoreGradesFormattedRowCommonData = {
|
|||
rowclass?: string;
|
||||
itemtype?: string;
|
||||
image?: string;
|
||||
imageIsShape?: boolean;
|
||||
itemmodule?: string;
|
||||
iconAlt?: string;
|
||||
rowspan?: number;
|
||||
|
|
Loading…
Reference in New Issue