Skip to content

Commit 93a9d19

Browse files
authored
Merge pull request #3838 from crazyserver/MOBILE-4362
Mobile 4362
2 parents 38f4dcd + 1497204 commit 93a9d19

File tree

24 files changed

+148
-110
lines changed

24 files changed

+148
-110
lines changed
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
:host {
2-
--mod-icon-filter: brightness(0);
3-
42
core-mod-icon {
53
background: transparent;
64
margin: 0;
7-
--filter: var(--mod-icon-filter);
5+
--filter: var(--module-icon-filter);
86
}
97
}
10-
11-
:host-context(html.dark) {
12-
--mod-icon-filter: brightness(0) invert(1);
13-
}

src/addons/messages/pages/discussion/discussion.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<ion-title>
77
<h1>
88
<img *ngIf="loaded && !otherMember && conversationImage" class="core-bar-button-image" [src]="conversationImage" alt=""
9-
onError="this.src='assets/img/group-avatar.svg'" core-external-content role="presentation" [siteId]="siteId || null">
9+
onError="this.src='assets/img/group-avatar.svg'" core-external-content role="presentation" [siteId]="siteId">
1010
<core-user-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" [user]="otherMember" [linkProfile]="false"
1111
[checkOnline]="otherMember.showonlinestatus">
1212
</core-user-avatar>

src/addons/messages/pages/discussion/discussion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
5858
@ViewChild(IonContent) content?: IonContent;
5959
@ViewChild(CoreInfiniteLoadingComponent) infinite?: CoreInfiniteLoadingComponent;
6060

61-
siteId: string;
6261
protected fetching = false;
6362
protected polling?: number;
6463
protected logger: CoreLogger;
@@ -79,6 +78,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
7978
conversation?: AddonMessagesConversationFormatted; // The conversation object (if it exists).
8079
userId?: number; // User ID you're talking to (only if group messaging not enabled or it's a new individual conversation).
8180
currentUserId: number;
81+
siteId: string;
8282
title?: string;
8383
showInfo = false;
8484
conversationImage?: string;

src/addons/mod/lti/services/handlers/module.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { AddonModLtiHelper } from '../lti-helper';
2222
import { AddonModLtiIndexComponent } from '../../components/index';
2323
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
2424
import { CoreCourse } from '@features/course/services/course';
25-
import { CoreSites } from '@services/sites';
2625

2726
/**
2827
* Handler to support LTI modules.
@@ -87,19 +86,6 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
8786
return module?.modicon ?? modicon ?? CoreCourse.getModuleIconSrc(this.modName);
8887
}
8988

90-
/**
91-
* @inheritdoc
92-
*/
93-
iconIsShape(module?: CoreCourseModuleData | undefined, modicon?: string | undefined): boolean | undefined {
94-
const iconUrl = module?.modicon ?? modicon;
95-
96-
if (!iconUrl) {
97-
return true;
98-
}
99-
100-
return iconUrl.startsWith(CoreSites.getRequiredCurrentSite().siteUrl);
101-
}
102-
10389
}
10490

10591
export const AddonModLtiModuleHandler = makeSingleton(AddonModLtiModuleHandlerService);

src/addons/mod/resource/services/handlers/module.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,5 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
170170
return AddonModResourceIndexComponent;
171171
}
172172

173-
/**
174-
* @inheritdoc
175-
*/
176-
iconIsShape(module?: CoreCourseModuleData | undefined, modicon?: string | undefined): boolean | undefined {
177-
const iconUrl = module?.modicon ?? modicon;
178-
179-
return !iconUrl?.startsWith('assets/img/files_legacy/') && !iconUrl?.endsWith('.png');
180-
}
181-
182173
}
183174
export const AddonModResourceModuleHandler = makeSingleton(AddonModResourceModuleHandlerService);

src/addons/mod/url/services/handlers/module.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,6 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
218218
return this.shouldOpenLink(module);
219219
}
220220

221-
/**
222-
* @inheritdoc
223-
*/
224-
iconIsShape(module?: CoreCourseModuleData | undefined, modicon?: string | undefined): boolean | undefined {
225-
const iconUrl = module?.modicon ?? modicon;
226-
227-
return !iconUrl?.startsWith('assets/img/files_legacy/') && !iconUrl?.endsWith('.png');
228-
}
229-
230221
/**
231222
* Log module viewed.
232223
*/

src/core/components/mod-icon/mod-icon.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
--icon-radius: var(--module-icon-radius, var(--radius-xs));
88
--margin-end: 0px;
99
--margin-vertical: 0px;
10-
--filter: brightness(0) invert(1);
1110

1211
margin-top: var(--margin-vertical);
1312
margin-bottom: var(--margin-vertical);
@@ -22,7 +21,7 @@
2221
&.#{$type} {
2322
background-color: var(--activity#{$type});
2423
img {
25-
filter: var(--filter);
24+
filter: var(--filter, brightness(0) invert(1));
2625
}
2726
}
2827
}

src/core/components/mod-icon/mod-icon.ts

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChange } from '@
1717
import { CoreCourse } from '@features/course/services/course';
1818
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
1919
import { CoreSites } from '@services/sites';
20+
import { CoreUrlUtils } from '@services/utils/url';
2021

2122
const assetsPath = 'assets/img/';
2223
const fallbackModName = 'external-tool';
@@ -54,12 +55,7 @@ export class CoreModIconComponent implements OnInit, OnChanges {
5455
async ngOnInit(): Promise<void> {
5556
if (!this.modname && this.modicon) {
5657
// Guess module from the icon url.
57-
const matches = this.modicon.match('/theme/image.php/[^/]+/([^/]+)/[-0-9]*/');
58-
this.modname = (matches && matches[1]) || '';
59-
60-
if (this.modname.startsWith('mod_')) {
61-
this.modname = this.modname.substring(4);
62-
}
58+
this.modname = this.getComponentNameFromIconUrl(this.modicon);
6359
}
6460

6561
this.modNameTranslated = CoreCourse.translateModuleName(this.modname, this.fallbackTranslation);
@@ -105,16 +101,15 @@ export class CoreModIconComponent implements OnInit, OnChanges {
105101
!!this.modname &&
106102
!!this.componentId &&
107103
!this.isLocalUrl &&
108-
!this.icon.match('/theme/image.php/[^/]+/' + this.modname + '/[-0-9]*/');
104+
this.getComponentNameFromIconUrl(this.icon) != this.modname;
109105

110-
const iconIsShape = await CoreCourseModuleDelegate.moduleIconIsShape(this.modname, this.icon);
111-
this.noFilter = iconIsShape === false;
106+
this.noFilter = await this.getIconNoFilter();
112107
}
113108

114109
/**
115110
* Icon to load on error.
116111
*/
117-
loadFallbackIcon(): void {
112+
async loadFallbackIcon(): Promise<void> {
118113
this.isLocalUrl = true;
119114
const moduleName = !this.modname || CoreCourse.CORE_MODULES.indexOf(this.modname) < 0
120115
? fallbackModName
@@ -127,7 +122,75 @@ export class CoreModIconComponent implements OnInit, OnChanges {
127122
}
128123

129124
this.icon = path + moduleName + '.svg';
130-
this.noFilter = false;
125+
this.noFilter = await this.getIconNoFilter();
126+
}
127+
128+
/**
129+
* Returns if the icon does not need to be filtered.
130+
*
131+
* @returns wether the icon does not need to be filtered.
132+
*/
133+
protected async getIconNoFilter(): Promise<boolean> {
134+
// Earlier 4.0, icons were never filtered.
135+
if (this.legacyIcon) {
136+
return true;
137+
}
138+
139+
// No icon or local icon (not legacy), filter it.
140+
if (!this.icon || this.isLocalUrl) {
141+
return false;
142+
}
143+
144+
// If it's an Moodle Theme icon, check if filtericon is set and use it.
145+
if (this.icon && CoreUrlUtils.isThemeImageUrl(this.icon)) {
146+
const iconParams = CoreUrlUtils.extractUrlParams(this.icon);
147+
if (iconParams['filtericon'] === '1') {
148+
return false;
149+
}
150+
151+
// filtericon was introduced in 4.2 and backported to 4.1.3 and 4.0.8.
152+
if (this.modname && !CoreSites.getCurrentSite()?.isVersionGreaterEqualThan(['4.0.8', '4.1.3', '4.2'])) {
153+
// If version is prior to that, check if the url is a module icon and filter it.
154+
if (this.getComponentNameFromIconUrl(this.icon) === this.modname) {
155+
return false;
156+
}
157+
}
158+
}
159+
160+
// External icons, or non monologo, do not filter.
161+
return true;
162+
}
163+
164+
/**
165+
* Guesses the mod name form the url.
166+
*
167+
* @param iconUrl Icon url.
168+
* @returns Guessed modname.
169+
*/
170+
protected getComponentNameFromIconUrl(iconUrl: string): string {
171+
if (!CoreUrlUtils.isThemeImageUrl(this.icon)) {
172+
// Cannot be guessed.
173+
return '';
174+
}
175+
176+
const iconParams = CoreUrlUtils.extractUrlParams(iconUrl);
177+
let component = iconParams['component'];
178+
179+
if (!component) {
180+
const matches = iconUrl.match('/theme/image.php/[^/]+/([^/]+)/[-0-9]*/');
181+
component = (matches && matches[1]) || '';
182+
}
183+
184+
// Some invalid components (others may be added later on).
185+
if (component === 'core' || component === 'theme') {
186+
return '';
187+
}
188+
189+
if (component.startsWith('mod_')) {
190+
component = component.substring(4);
191+
}
192+
193+
return component;
131194
}
132195

133196
}

src/core/components/user-avatar/core-user-avatar.html

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<ng-container *ngIf="avatarUrl">
2-
<img *ngIf="linkProfile" [src]="avatarUrl" [alt]="'core.pictureof' | translate:{$a: fullname}" core-external-content
2+
<img class="userpicture" *ngIf="linkProfile" [src]="avatarUrl" [alt]="'core.pictureof' | translate:{$a: fullname}" core-external-content
33
(error)="loadImageError()" (ariaButtonClick)="gotoProfile($event)" [siteId]="siteId">
44

5-
<img *ngIf="!linkProfile" [src]="avatarUrl" [alt]="'core.pictureof' | translate:{$a: fullname}" core-external-content
6-
(error)="loadImageError()" aria-hidden="true" [siteId]="siteId">
5+
<img class="userpicture" *ngIf="!linkProfile" [src]="avatarUrl" [alt]="'core.pictureof' | translate:{$a: fullname}"
6+
core-external-content (error)="loadImageError()" aria-hidden="true" [siteId]="siteId">
77
</ng-container>
88
<ng-container *ngIf="!avatarUrl && initials">
99
<div class="userinitials" *ngIf="linkProfile" [attr.aria-label]="'core.pictureof' | translate:{$a: fullname}"
@@ -16,10 +16,11 @@
1616
</div>
1717
</ng-container>
1818
<ng-container *ngIf="!avatarUrl && !initials">
19-
<img *ngIf="linkProfile" src="assets/img/user-avatar.png" [alt]="'core.pictureof' | translate:{$a: fullname}"
19+
<img class="userpicture" *ngIf="linkProfile" src="assets/img/user-avatar.png" [alt]="'core.pictureof' | translate:{$a: fullname}"
2020
(ariaButtonClick)="gotoProfile($event)">
2121

22-
<img *ngIf="!linkProfile" src="assets/img/user-avatar.png" [alt]="'core.pictureof' | translate:{$a: fullname}" aria-hidden="true">
22+
<img class="userpicture" *ngIf="!linkProfile" src="assets/img/user-avatar.png" [alt]="'core.pictureof' | translate:{$a: fullname}"
23+
aria-hidden="true">
2324
</ng-container>
2425

2526
<span *ngIf="checkOnline && isOnline()" class="contact-status online" role="status" [attr.aria-label]="'core.online' | translate">

src/core/components/user-avatar/user-avatar.scss

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,47 @@
44
position: relative;
55
width: var(--core-avatar-size);
66
height: var(--core-avatar-size);
7+
padding: 0px;
78
--contact-status-size: 14px;
89
--margin-end-on-item: 8px;
910
--margin-vertical-on-item: 8px;
11+
--userpicture-padding: 0px;
1012

11-
img {
13+
img.userpicture {
1214
border-radius: var(--core-avatar-radius);
1315
width: var(--core-avatar-size);
1416
height: var(--core-avatar-size);
1517
max-width: var(--core-avatar-size);
1618
max-height: var(--core-avatar-size);
17-
}
18-
img[alt] {
19-
text-indent: -999999px;
20-
white-space: nowrap;
21-
overflow: hidden;
22-
}
23-
img[core-external-content]:not([src]),
24-
img[core-external-content][src=""] {
25-
visibility: visible;
26-
display: inline-block;
27-
position: relative;
28-
&:after {
29-
border-radius: var(--core-avatar-radius);
30-
display: block;
31-
position: absolute;
32-
top: 0;
33-
left: 0;
34-
width: 100%;
35-
height: 100%;
36-
background: url('/assets/img/user-avatar.png');
37-
background-size: contain;
38-
content: "";
19+
padding: var(--userpicture-padding);
20+
&[alt] {
21+
text-indent: -999999px;
22+
white-space: nowrap;
23+
overflow: hidden;
24+
}
25+
&:not([src]),
26+
&[src=""] {
27+
visibility: visible;
28+
display: inline-block;
29+
position: relative;
30+
margin: var(--userpicture-padding);
31+
width: calc(var(--core-avatar-size) - var(--userpicture-padding) - var(--userpicture-padding));
32+
height: calc(var(--core-avatar-size) - var(--userpicture-padding) - var(--userpicture-padding));
33+
&:after {
34+
border-radius: var(--core-avatar-radius);
35+
display: block;
36+
position: absolute;
37+
top: 0;
38+
left: 0;
39+
right: 0;
40+
bottom: 0;
41+
background: url('/assets/img/user-avatar.png');
42+
background-size: contain;
43+
content: "";
44+
}
3945
}
4046
}
47+
4148
&.core-bar-button-image {
4249
padding: 0;
4350
width: var(--core-header-toolbar-button-image-size);
@@ -74,9 +81,10 @@
7481
border-radius: var(--core-avatar-radius);
7582
color: var(--gray-800);
7683
font-weight: normal;
77-
width: var(--core-avatar-size);
78-
height: var(--core-avatar-size);
84+
width: calc(var(--core-avatar-size) - var(--userpicture-padding) - var(--userpicture-padding));
85+
height: calc(var(--core-avatar-size) - var(--userpicture-padding) - var(--userpicture-padding));
7986
font-size: calc(var(--core-avatar-size)*0.3);
87+
margin: var(--userpicture-padding);
8088
}
8189

8290
&.large-avatar .userinitials {

0 commit comments

Comments
 (0)