MDL-82385 subsection: Support subsection in app 4.4 and older

This commit is contained in:
Dani Palou
2024-08-14 11:42:01 +02:00
parent 2b2dcab6a5
commit 4f2f985902
4 changed files with 233 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Mobile output class for subsection.
*
* @package mod_subsection
* @copyright 2024 Dani Palou <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_subsection\output;
/**
* Mobile output class for subsection.
*
* @copyright 2024 Dani Palou <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mobile {
/**
* Returns the JS code to support mod_subsection in versions of the app previous to 4.5.
*
* @param array $args Arguments from tool_mobile_get_content WS
* @return array HTML, javascript and otherdata
*/
public static function mobile_init($args) {
global $CFG;
return [
'templates' => [],
'javascript' => file_get_contents($CFG->dirroot . '/mod/subsection/mobileapp/init.js'),
];
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
// This file is part of the Choice group module for Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Structure to support subsection in versions of the app previous to 4.5.
*
* @package mod_subsection
* @copyright 2024 Dani Palou <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$addons = [
'mod_subsection' => [
'handlers' => [
'subsection' => [
'delegate' => '', // Don't use a delegate, the JS code will register the handler.
'init' => 'mobile_init',
'styles' => [
'url' => $CFG->wwwroot . '/mod/subsection/mobileapp/styles.css',
'version' => '1',
],
],
],
],
];
+110
View File
@@ -0,0 +1,110 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the JS code to support mod_subsection in versions of the app previous to 4.5.
*
* @copyright 2024 Dani Palou <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
const context = this;
/**
* Open a subsection.
*/
const openSubsection = async(module, courseId, siteId) => {
const customData = context.CoreTextUtilsProvider.parseJSON(module.customdata);
const pageParams = {
sectionId: customData.sectionid,
};
if (
(!siteId || siteId === context.CoreSitesProvider.getCurrentSiteId()) &&
context.CoreCourseProvider.currentViewIsCourse(courseId)
) {
context.CoreCourseProvider.selectCourseTab('', pageParams);
} else {
await context.CoreCourseHelperProvider.getAndOpenCourse(courseId, pageParams, siteId);
}
};
/**
* Handler to support mod_subsection in a course.
*/
class SubsectionModuleHandler {
constructor() {
this.name = 'PluginModSubsection';
this.modName = 'subsection';
}
isEnabled() {
return true;
}
getData(module) {
return {
icon: context.CoreCourseProvider.getModuleIconSrc(module.modname, module.modicon),
title: module.name,
action: async(event, module, courseId) => {
try {
await openSubsection(module, courseId);
} catch (error) {
context.CoreDomUtilsProvider.showErrorModalDefault(error, 'Error opening subsection.');
}
},
};
}
}
/**
* Handler to support links to mod_subsection.
*/
class SubsectionLinkHandler extends this.CoreContentLinksHandlerBase {
constructor() {
super();
this.name = 'PluginModSubsection';
this.priority = 0;
this.featureName = 'CoreCourseModuleDelegate_AddonModSubsection';
this.pattern = new RegExp('/mod/subsection/view.php.*([&?]id=\\d+)');
}
getActions(siteIds, url, params, courseId) {
return [{
action: async(siteId) => {
const modal = await context.CoreDomUtilsProvider.showModalLoading();
const moduleId = Number(params.id);
try {
// Get the module.
const module = await context.CoreCourseProvider.getModule(moduleId, courseId, undefined, true, false, siteId);
await openSubsection(module, module.course, siteId);
} catch (error) {
context.CoreDomUtilsProvider.showErrorModalDefault(error, 'Error opening link.');
} finally {
modal.dismiss();
}
},
}];
}
}
this.CoreCourseModuleDelegate.registerHandler(new SubsectionModuleHandler());
this.CoreContentLinksDelegate.registerHandler(new SubsectionLinkHandler());
+34
View File
@@ -0,0 +1,34 @@
/* Hide subsections in course index, 'All sections' and the buttons for next/previous section */
.ionic5 core-course-format section:has(.course-mod_subsection):not(:only-of-type),
.ionic7 core-course-format section:has(.course-mod_subsection):not(:only-of-type) {
display: none;
}
.ionic5 core-course-course-index .section:has(.course-mod_subsection),
.ionic5 core-course-course-index .section:has(.course-mod_subsection) + div[id^="core-course-index-section"],
.ionic7 core-course-course-index .section:has(.course-mod_subsection),
.ionic7 core-course-course-index .section:has(.course-mod_subsection) + div[id^="core-course-index-section"] {
display: none;
}
.ionic5 .core-course-section-nav-buttons ion-button:has(.course-mod_subsection),
.ionic7 .core-course-section-nav-buttons ion-button:has(.course-mod_subsection) {
display: none;
}
/* Styles for devices not supporting :has() */
.ionic5 .core-course-section-nav-buttons .course-mod_subsection,
.ionic7 .core-course-section-nav-buttons .course-mod_subsection {
font-style: italic;
font-weight: normal;
}
.ionic5 core-course-course-index .course-mod_subsection,
.ionic7 core-course-course-index .course-mod_subsection {
font-style: italic;
font-weight: normal;
padding-inline-start: 16px;
}