+
+
diff --git a/src/core/features/course/components/unsupported-module/unsupported-module.ts b/src/core/features/course/components/unsupported-module/unsupported-module.ts
index 5df40ab8f..15c3e7902 100644
--- a/src/core/features/course/components/unsupported-module/unsupported-module.ts
+++ b/src/core/features/course/components/unsupported-module/unsupported-module.ts
@@ -14,7 +14,6 @@
import { Component, Input, OnInit } from '@angular/core';
-import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
@@ -27,12 +26,10 @@ import { CoreCourseModuleDelegate } from '@features/course/services/module-deleg
})
export class CoreCourseUnsupportedModuleComponent implements OnInit {
- @Input() courseId?: number; // The course to module belongs to.
+ @Input() courseId?: number; // The course to module belongs to (unused).
@Input() module?: CoreCourseModuleData; // The module to render.
- isDisabledInSite?: boolean;
- isSupportedByTheApp?: boolean;
- moduleName?: string;
+ isDisabledInSite = false; // It is implicit than if not disabled it will be unsupported.
/**
* Component being initialized.
@@ -43,8 +40,6 @@ export class CoreCourseUnsupportedModuleComponent implements OnInit {
}
this.isDisabledInSite = CoreCourseModuleDelegate.isModuleDisabledInSite(this.module.modname);
- this.isSupportedByTheApp = CoreCourseModuleDelegate.hasHandler(this.module.modname);
- this.moduleName = CoreCourse.translateModuleName(this.module.modname);
}
}
diff --git a/src/core/features/course/lang.json b/src/core/features/course/lang.json
index 36f792de9..554f22f43 100644
--- a/src/core/features/course/lang.json
+++ b/src/core/features/course/lang.json
@@ -1,10 +1,8 @@
{
"activitydisabled": "Your organisation has disabled this activity in the mobile app.",
"activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.",
- "activitynotyetviewablesiteupgradeneeded": "Your organisation's Moodle installation needs to be updated.",
"allsections": "All sections",
"aria:sectionprogress": "Section progress:",
- "askadmintosupport": "Contact the site administrator and tell them you want to use this activity with the Moodle Mobile app.",
"availablespace": " You currently have about {{available}} free space.",
"cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
"completion_automatic:done": "Done:",
diff --git a/src/core/features/course/pages/module-preview/module-preview.html b/src/core/features/course/pages/module-preview/module-preview.html
index eb42c4b54..010351d87 100644
--- a/src/core/features/course/pages/module-preview/module-preview.html
+++ b/src/core/features/course/pages/module-preview/module-preview.html
@@ -11,8 +11,8 @@
-
+
@@ -24,44 +24,24 @@
+ [componentId]="module.id" [expandDescription]="true" [showAvailabilityInfo]="true">
+
+
+ void; // Update the module after a certain time.
@@ -80,6 +81,8 @@ export class CoreCourseModulePreviewPage implements OnInit {
if (!this.unsupported) {
this.module.handlerData =
await CoreCourseModuleDelegate.getModuleDataFor(this.module.modname, this.module, this.courseId);
+ } else {
+ this.isDisabledInSite = CoreCourseModuleDelegate.isModuleDisabledInSite(this.module.modname);
}
this.title = this.module.name;
diff --git a/src/core/lang.json b/src/core/lang.json
index 5b58a7e07..2a72d84e7 100644
--- a/src/core/lang.json
+++ b/src/core/lang.json
@@ -342,7 +342,6 @@
"whatisyourage": "What is your age?",
"wheredoyoulive": "In which country do you live?",
"whoissiteadmin": "\"Site Administrators\" are the people who manage the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.",
- "whoops": "Oops!",
"whyisthishappening": "Why is this happening?",
"whyisthisrequired": "Why is this required?",
"wsfunctionnotavailable": "The web service function is not available.",
From b185c0fc4583f25d2615904677848142be1cba12 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Fri, 18 Feb 2022 15:49:07 +0100
Subject: [PATCH 3/7] MOBILE-3814 module: Add prefetch status on module
activity cards
---
.../components/module/core-course-module.html | 2 +
.../course/components/module/module.scss | 1 +
.../course/components/module/module.ts | 72 ++++++++++++++++++-
3 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/src/core/features/course/components/module/core-course-module.html b/src/core/features/course/components/module/core-course-module.html
index e1048efe5..579f101e5 100644
--- a/src/core/features/course/components/module/core-course-module.html
+++ b/src/core/features/course/components/module/core-course-module.html
@@ -17,6 +17,8 @@
+
diff --git a/src/core/features/course/components/module/module.scss b/src/core/features/course/components/module/module.scss
index da557da41..c4fd942bd 100644
--- a/src/core/features/course/components/module/module.scss
+++ b/src/core/features/course/components/module/module.scss
@@ -13,6 +13,7 @@
.core-module-title .item-heading ion-icon {
@include margin-horizontal(8px, null);
+ vertical-align: middle;
}
.core-module-buttons,
diff --git a/src/core/features/course/components/module/module.ts b/src/core/features/course/components/module/module.ts
index 0761f2ad6..478dc0b62 100644
--- a/src/core/features/course/components/module/module.ts
+++ b/src/core/features/course/components/module/module.ts
@@ -22,6 +22,12 @@ import {
} from '@features/course/services/course-helper';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleDelegate, CoreCourseModuleHandlerButton } from '@features/course/services/module-delegate';
+import {
+ CoreCourseModulePrefetchDelegate,
+ CoreCourseModulePrefetchHandler,
+} from '@features/course/services/module-prefetch-delegate';
+import { CoreConstants } from '@/core/constants';
+import { CoreEventObserver, CoreEvents } from '@singletons/events';
/**
* Component to display a module entry in a list of modules.
@@ -47,11 +53,16 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
hasInfo = false;
showLegacyCompletion = false; // Whether to show module completion in the old format.
showManualCompletion = false; // Whether to show manual completion when completion conditions are disabled.
+ prefetchStatusIcon = ''; // Module prefetch status icon.
+ prefetchStatusText = ''; // Module prefetch status text.
+ protected prefetchHandler?: CoreCourseModulePrefetchHandler;
+
+ protected moduleStatusObserver?: CoreEventObserver;
/**
- * Component being initialized.
+ * @inheritdoc
*/
- ngOnInit(): void {
+ async ngOnInit(): Promise {
this.modNameTranslated = CoreCourse.translateModuleName(this.module.modname) || '';
this.showLegacyCompletion = !CoreSites.getCurrentSite()?.isVersionGreaterEqualThan('3.11');
this.checkShowManualCompletion();
@@ -70,6 +81,60 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
(this.module.visible !== 0 && this.module.isStealth) ||
(this.module.availabilityinfo)
);
+
+ if (this.module.handlerData?.showDownloadButton) {
+ const status = await CoreCourseModulePrefetchDelegate.getModuleStatus(this.module, this.module.course);
+ this.updateModuleStatus(status);
+
+ // Listen for changes on this module status, even if download isn't enabled.
+ this.prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module.modname);
+ if (!this.prefetchHandler) {
+ return;
+ }
+
+ this.moduleStatusObserver = CoreEvents.on(CoreEvents.PACKAGE_STATUS_CHANGED, (data) => {
+ if (this.module.id != data.componentId || data.component != this.prefetchHandler?.component) {
+ return;
+ }
+
+ let status = data.status;
+ if (this.prefetchHandler.determineStatus) {
+ // Call determineStatus to get the right status to display.
+ status = this.prefetchHandler.determineStatus(this.module, status, true);
+ }
+
+ // Update the status.
+ this.updateModuleStatus(status);
+ }, CoreSites.getCurrentSiteId());
+ }
+ }
+
+ /**
+ * Show module status.
+ *
+ * @param prefetchstatus Module status.
+ */
+ protected updateModuleStatus(prefetchstatus: string): void {
+ if (!prefetchstatus) {
+ return;
+ }
+
+ switch (prefetchstatus) {
+ case CoreConstants.OUTDATED:
+ this.prefetchStatusIcon = CoreConstants.ICON_OUTDATED;
+ this.prefetchStatusText = 'core.outdated';
+ break;
+ case CoreConstants.DOWNLOADED:
+ this.prefetchStatusIcon = CoreConstants.ICON_DOWNLOADED;
+ this.prefetchStatusText = 'core.downloaded';
+ break;
+ default:
+ this.prefetchStatusIcon = '';
+ this.prefetchStatusText = '';
+ break;
+ }
+
+ this.module.handlerData?.updateStatus?.(prefetchstatus);
}
/**
@@ -109,10 +174,11 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
}
/**
- * Component destroyed.
+ * @inheritdoc
*/
ngOnDestroy(): void {
this.module.handlerData?.onDestroy?.();
+ this.moduleStatusObserver?.off();
}
}
From 8d5e906b1e802efdd950fefa5c8cb7da92c5d4cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Mon, 21 Feb 2022 11:31:00 +0100
Subject: [PATCH 4/7] MOBILE-3814 module: Change cloud icons to new fontawesome
custom icons
---
.../services/handlers/course-menu.ts | 2 +-
.../fonts/moodle/font-awesome/cloud-done.svg | 1 +
.../moodle/font-awesome/cloud-refresh.svg | 1 +
.../core-download-refresh.html | 8 ++--
src/core/constants.ts | 6 +--
src/core/directives/fa-icon.ts | 47 ++++++++++++-------
.../module-summary/module-summary.html | 4 +-
.../core-courses-course-list-item.html | 4 +-
.../core-courses-course-progress.html | 2 +-
9 files changed, 44 insertions(+), 31 deletions(-)
create mode 100644 src/assets/fonts/moodle/font-awesome/cloud-done.svg
create mode 100644 src/assets/fonts/moodle/font-awesome/cloud-refresh.svg
diff --git a/src/addons/storagemanager/services/handlers/course-menu.ts b/src/addons/storagemanager/services/handlers/course-menu.ts
index 7aa36c6de..74dc8f409 100644
--- a/src/addons/storagemanager/services/handlers/course-menu.ts
+++ b/src/addons/storagemanager/services/handlers/course-menu.ts
@@ -48,7 +48,7 @@ export class AddonStorageManagerCourseMenuHandlerService implements CoreCourseOp
course: CoreCourseAnyCourseDataWithOptions,
): CoreCourseOptionsMenuHandlerData {
return {
- icon: 'cloud-download',
+ icon: 'fas-cloud-download-alt',
title: 'addon.storagemanager.coursedownloads',
page: 'storage/' + course.id,
pageParams: {
diff --git a/src/assets/fonts/moodle/font-awesome/cloud-done.svg b/src/assets/fonts/moodle/font-awesome/cloud-done.svg
new file mode 100644
index 000000000..9f80a5392
--- /dev/null
+++ b/src/assets/fonts/moodle/font-awesome/cloud-done.svg
@@ -0,0 +1 @@
+
diff --git a/src/assets/fonts/moodle/font-awesome/cloud-refresh.svg b/src/assets/fonts/moodle/font-awesome/cloud-refresh.svg
new file mode 100644
index 000000000..2e336c793
--- /dev/null
+++ b/src/assets/fonts/moodle/font-awesome/cloud-refresh.svg
@@ -0,0 +1 @@
+
diff --git a/src/core/components/download-refresh/core-download-refresh.html b/src/core/components/download-refresh/core-download-refresh.html
index f9580727f..21d380920 100644
--- a/src/core/components/download-refresh/core-download-refresh.html
+++ b/src/core/components/download-refresh/core-download-refresh.html
@@ -2,19 +2,19 @@
-
+
-
+
+ name="fam-cloud-done" [attr.aria-label]="(statusTranslatable || 'core.downloaded') | translate" role="status">
diff --git a/src/core/constants.ts b/src/core/constants.ts
index 7113598cc..0fcd0ddd3 100644
--- a/src/core/constants.ts
+++ b/src/core/constants.ts
@@ -93,10 +93,10 @@ export class CoreConstants {
static readonly NOT_DOWNLOADABLE = 'notdownloadable';
// Download / prefetch status icon.
- static readonly ICON_DOWNLOADED = 'cloud-done';
+ static readonly ICON_DOWNLOADED = 'fam-cloud-done';
static readonly ICON_DOWNLOADING = 'spinner';
- static readonly ICON_NOT_DOWNLOADED = 'cloud-download';
- static readonly ICON_OUTDATED = 'fas-redo-alt';
+ static readonly ICON_NOT_DOWNLOADED = 'fas-cloud-download-alt';
+ static readonly ICON_OUTDATED = 'fam-cloud-refresh';
static readonly ICON_NOT_DOWNLOADABLE = '';
// General download and sync icons.
diff --git a/src/core/directives/fa-icon.ts b/src/core/directives/fa-icon.ts
index 8a262dd45..9de2de27a 100644
--- a/src/core/directives/fa-icon.ts
+++ b/src/core/directives/fa-icon.ts
@@ -45,47 +45,58 @@ export class CoreFaIconDirective implements AfterViewInit, OnChanges {
* Detect icon name and use svg.
*/
async setIcon(): Promise {
- let library = 'ionic';
+ let library = '';
let iconName = this.name;
+ let font = 'ionicons';
const parts = iconName.split('-', 2);
if (parts.length == 2) {
switch (parts[0]) {
case 'far':
library = 'regular';
- iconName = iconName.substring(4);
+ font = 'font-awesome';
break;
case 'fa':
case 'fas':
library = 'solid';
- iconName = iconName.substring(parts[0].length + 1);
+ font = 'font-awesome';
break;
case 'fab':
library = 'brands';
- iconName = iconName.substring(4);
+ font = 'font-awesome';
+ break;
+ case 'moodle':
+ library = 'moodle';
+ font = 'moodle';
+ break;
+ case 'fam':
+ library = 'font-awesome';
+ font = 'moodle';
break;
default:
break;
}
}
- if (library != 'ionic') {
- const src = `assets/fonts/font-awesome/${library}/${iconName}.svg`;
- this.element.setAttribute('src', src);
- this.element.classList.add('faicon');
-
- if (CoreConstants.BUILD.isDevelopment || CoreConstants.BUILD.isTesting) {
- try {
- await Http.get(src, { responseType: 'text' }).toPromise();
- } catch (error) {
- this.logger.error(`Icon ${this.name} not found`);
- }
- }
- } else {
+ if (font == 'ionicons') {
this.element.removeAttribute('src');
this.logger.warn(`Ionic icon ${this.name} detected`);
+
+ return;
}
- return;
+ iconName = iconName.substring(parts[0].length + 1);
+
+ const src = `assets/fonts/${font}/${library}/${iconName}.svg`;
+ this.element.setAttribute('src', src);
+ this.element.classList.add('faicon');
+
+ if (CoreConstants.BUILD.isDevelopment || CoreConstants.BUILD.isTesting) {
+ try {
+ await Http.get(src, { responseType: 'text' }).toPromise();
+ } catch (error) {
+ this.logger.error(`Icon ${this.name} not found`);
+ }
+ }
}
/**
diff --git a/src/core/features/course/components/module-summary/module-summary.html b/src/core/features/course/components/module-summary/module-summary.html
index 820e944ef..6c60ba185 100644
--- a/src/core/features/course/components/module-summary/module-summary.html
+++ b/src/core/features/course/components/module-summary/module-summary.html
@@ -58,7 +58,7 @@