diff --git a/blocks/timeline/templates/event-list-item.mustache b/blocks/timeline/templates/event-list-item.mustache index efd5d1ab45a..e8b71a7da64 100644 --- a/blocks/timeline/templates/event-list-item.mustache +++ b/blocks/timeline/templates/event-list-item.mustache @@ -54,7 +54,10 @@ {{#userdate}} {{timesort}}, {{#str}} strftimetime24, core_langconfig {{/str}} {{/userdate}} -
+
{{#icon}} {{#iconurl}} {{alttext}} diff --git a/calendar/classes/external/event_icon_exporter.php b/calendar/classes/external/event_icon_exporter.php index bdc8b6386d3..715b10a6ff5 100644 --- a/calendar/classes/external/event_icon_exporter.php +++ b/calendar/classes/external/event_icon_exporter.php @@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die(); use \core\external\exporter; use \core_calendar\local\event\entities\event_interface; +use core_course\output\activity_icon; /** * Class for displaying a calendar event's icon. @@ -63,19 +64,25 @@ class event_icon_exporter extends exporter { $isuserevent = ($user && !empty($userid)); $iconurl = ''; $iconclass = ''; + $purpose = ''; if ($isactivityevent) { $key = 'monologo'; $component = $coursemodule->get('modname'); - $iconurl = get_fast_modinfo($courseid)->get_cm($coursemodule->get('id'))->get_icon_url(); - $iconclass = $iconurl->get_param('filtericon') ? '' : 'nofilter'; - $iconurl = $iconurl->out(false); if (get_string_manager()->string_exists($event->get_type(), $component)) { $alttext = get_string($event->get_type(), $component); } else { $alttext = get_string('activityevent', 'calendar'); } + + $renderer = \core\di::get(\core\output\renderer_helper::class)->get_core_renderer(); + $activityicon = activity_icon::from_cm_info($coursemodule->get_proxied_instance()) + ->set_title($alttext); + + $iconurl = $activityicon->get_icon_url($renderer)->out(false); + $iconclass = $activityicon->get_icon_classes($renderer); + $purpose = $activityicon->get_purpose(); } else if ($event->get_component()) { // Guess the icon and the title for the component event. By default display calendar icon and the // plugin name as the alttext. @@ -125,6 +132,7 @@ class event_icon_exporter extends exporter { $data->alttext = $alttext; $data->iconurl = $iconurl; $data->iconclass = $iconclass; + $data->purpose = $purpose; parent::__construct($data, $related); } @@ -141,6 +149,7 @@ class event_icon_exporter extends exporter { 'alttext' => ['type' => PARAM_TEXT], 'iconurl' => ['type' => PARAM_TEXT], 'iconclass' => ['type' => PARAM_TEXT], + 'purpose' => ['type' => PARAM_TEXT], ]; } diff --git a/calendar/templates/upcoming_mini.mustache b/calendar/templates/upcoming_mini.mustache index caed6a09801..4405c34c295 100644 --- a/calendar/templates/upcoming_mini.mustache +++ b/calendar/templates/upcoming_mini.mustache @@ -44,7 +44,10 @@ }} data-eventtype-{{normalisedeventtype}}="1"{{! }} data-region="event-item"{{! }}> -
+
{{#icon}} {{#iconurl}} {{alttext}} diff --git a/course/classes/output/activity_icon.php b/course/classes/output/activity_icon.php index 6c0690b4de0..d495d7047b0 100644 --- a/course/classes/output/activity_icon.php +++ b/course/classes/output/activity_icon.php @@ -135,15 +135,9 @@ class activity_icon implements renderable, templatable { #[\Override] public function export_for_template(renderer_base $output): array { - if (!isset($this->iconurl)) { - $this->iconurl = $this->get_icon_url($output); - } - $needfiltering = $this->colourize && $this->iconurl->get_param('filtericon'); - $iconclass = $needfiltering ? '' : 'nofilter'; - $data = [ - 'icon' => $this->iconurl, - 'iconclass' => $iconclass, + 'icon' => $this->get_icon_url($output), + 'iconclass' => $this->get_icon_classes($output), 'modname' => $this->modname, 'pluginname' => get_string('pluginname', 'mod_' . $this->modname), 'purpose' => $this->purpose, @@ -165,6 +159,9 @@ class activity_icon implements renderable, templatable { * @return url */ public function get_icon_url(renderer_base $output): url { + if (isset($this->iconurl)) { + return $this->iconurl; + } $icon = $output->image_url('monologo', $this->modname); // Legacy activity modules may only have an `icon` icon instead of a `monologo` icon. $ismonologo = component::has_monologo_icon('mod', $this->modname); @@ -174,6 +171,7 @@ class activity_icon implements renderable, templatable { // The name of the param is not colorize to preserve backward compatibility. $icon->param('filtericon', 1); } + $this->iconurl = $icon; return $icon; } @@ -213,6 +211,20 @@ class activity_icon implements renderable, templatable { return $this->extraclasses; } + /** + * Get the icon classes. + * + * @param renderer_base $output + * @return string + */ + public function get_icon_classes(renderer_base $output): string { + $result = 'activityicon icon'; + $iconurl = $this->get_icon_url($output); + $needfiltering = $this->colourize && $iconurl->get_param('filtericon'); + $result .= ($needfiltering) ? '' : ' nofilter'; + return $result; + } + /** * Get the icon size. * diff --git a/course/templates/activity_icon.mustache b/course/templates/activity_icon.mustache index 5929a09de7a..382b84d8f3a 100644 --- a/course/templates/activity_icon.mustache +++ b/course/templates/activity_icon.mustache @@ -36,7 +36,7 @@ > {{#title}}{{#cleanstr}} activityicon, moodle, {{{pluginname}}} {{/cleanstr}}{{/title}}out(false), '', $iconattrs); $purposeclass = plugin_supports('mod', $this->page->activityname, FEATURE_MOD_PURPOSE); - $purposeclass .= ' activityiconcontainer icon-size-6'; + $purposeclass .= ' activityiconcontainer me-2'; $purposeclass .= ' modicon_' . $this->page->activityname; $isbranded = component_callback('mod_' . $this->page->activityname, 'is_branded', [], false); $imagedata = html_writer::tag('div', $imagedata, ['class' => $purposeclass . ($isbranded ? ' isbranded' : '')]); diff --git a/theme/boost/scss/moodle/icons.scss b/theme/boost/scss/moodle/icons.scss index 58215e7d223..dd767df90cb 100644 --- a/theme/boost/scss/moodle/icons.scss +++ b/theme/boost/scss/moodle/icons.scss @@ -192,55 +192,6 @@ img.icon { } } -// Revisit these styles when MDL-78284 lands with new icons. -// Icon container will be removed and icons will be used directly. -.activityiconcontainer { - display: inline-flex; - justify-content: center; - align-items: center; - border-radius: 4px; - .activityicon, - .icon { - margin: 0; - font-size: $icon-medium-height; - height: $icon-medium-height; - width: $icon-medium-width; - max-height: $icon-medium-height; - max-width: $icon-medium-width; - } - &.small { - width: $activity-iconcontainer-width - 10px; - height: $activity-iconcontainer-height - 10px; - max-width: $activity-iconcontainer-width - 10px; - max-height: $activity-iconcontainer-height - 10px; - } - &.smaller { - width: $activity-iconcontainer-width - 20px; - height: $activity-iconcontainer-height - 20px; - max-width: $activity-iconcontainer-width - 20px; - max-height: $activity-iconcontainer-height - 20px; - .activityicon { - width: $icon-medium-width; - height: $icon-medium-height; - max-width: $icon-medium-width; - max-height: $icon-medium-height; - } - } -} - -@each $type, $value in $activity-icon-colors { - .activityiconcontainer.#{$type} { - &:not(.isbranded) { - .activityicon, - .icon { - &:not(.nofilter) { - @include recolor-icon($value, 1); - } - } - } - } -} - .icon-box { width: $icon-box-width; height: $icon-box-height; @@ -280,6 +231,51 @@ img.icon { } } +/* + * Activity icons + */ + +.activityiconcontainer { + width: $activity-iconcontainer-width; + height: $activity-iconcontainer-height; + max-width: $activity-iconcontainer-width; + max-height: $activity-iconcontainer-height; + &.small { + width: $activity-iconcontainer-width - 10px; + height: $activity-iconcontainer-height - 10px; + max-width: $activity-iconcontainer-width - 10px; + max-height: $activity-iconcontainer-height - 10px; + } + &.smaller { + width: $activity-iconcontainer-width - 20px; + height: $activity-iconcontainer-height - 20px; + max-width: $activity-iconcontainer-width - 20px; + max-height: $activity-iconcontainer-height - 20px; + } + .activityicon, + .icon { + margin: 0; + font-size: inherit; + width: inherit; + height: inherit; + max-width: inherit; + max-height: inherit; + } +} + +@each $type, $value in $activity-icon-colors { + .activityiconcontainer.#{$type} { + &:not(.isbranded) { + .activityicon, + .icon { + &:not(.nofilter) { + @include recolor-icon($value, 1); + } + } + } + } +} + // Make activtity colours available for custom modules. :root { @each $type, $value in $activity-icon-colors { diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index a336abe275f..5dc4e057112 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -28834,70 +28834,6 @@ img.icon { align-items: center; } -.activityiconcontainer { - display: inline-flex; - justify-content: center; - align-items: center; - border-radius: 4px; -} -.activityiconcontainer .activityicon, -.activityiconcontainer .icon { - margin: 0; - font-size: 32px; - height: 32px; - width: 40px; - max-height: 32px; - max-width: 40px; -} -.activityiconcontainer.small { - width: 42px; - height: 42px; - max-width: 42px; - max-height: 42px; -} -.activityiconcontainer.smaller { - width: 32px; - height: 32px; - max-width: 32px; - max-height: 32px; -} -.activityiconcontainer.smaller .activityicon { - width: 40px; - height: 32px; - max-width: 40px; - max-height: 32px; -} - -.activityiconcontainer.administration:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.administration:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.assessment:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.assessment:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.collaboration:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.collaboration:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.communication:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.communication:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.content:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.content:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.interactivecontent:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.interactivecontent:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - .icon-box { width: 60px; height: 48px; @@ -28934,6 +28870,67 @@ img.icon { color: #fff; } +/* + * Activity icons + */ +.activityiconcontainer { + width: 52px; + height: 52px; + max-width: 52px; + max-height: 52px; +} +.activityiconcontainer.small { + width: 42px; + height: 42px; + max-width: 42px; + max-height: 42px; +} +.activityiconcontainer.smaller { + width: 32px; + height: 32px; + max-width: 32px; + max-height: 32px; +} +.activityiconcontainer .activityicon, +.activityiconcontainer .icon { + margin: 0; + font-size: inherit; + width: inherit; + height: inherit; + max-width: inherit; + max-height: inherit; +} + +.activityiconcontainer.administration:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.administration:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.assessment:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.assessment:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.collaboration:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.collaboration:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.communication:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.communication:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.content:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.content:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.interactivecontent:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.interactivecontent:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + :root { --activityadministration: #da58ef; --activityassessment: #f90086; diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css index 3852ca31282..0d5bc4a0feb 100644 --- a/theme/classic/style/moodle.css +++ b/theme/classic/style/moodle.css @@ -28834,70 +28834,6 @@ img.icon { align-items: center; } -.activityiconcontainer { - display: inline-flex; - justify-content: center; - align-items: center; - border-radius: 4px; -} -.activityiconcontainer .activityicon, -.activityiconcontainer .icon { - margin: 0; - font-size: 32px; - height: 32px; - width: 40px; - max-height: 32px; - max-width: 40px; -} -.activityiconcontainer.small { - width: 42px; - height: 42px; - max-width: 42px; - max-height: 42px; -} -.activityiconcontainer.smaller { - width: 32px; - height: 32px; - max-width: 32px; - max-height: 32px; -} -.activityiconcontainer.smaller .activityicon { - width: 40px; - height: 32px; - max-width: 40px; - max-height: 32px; -} - -.activityiconcontainer.administration:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.administration:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.assessment:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.assessment:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.collaboration:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.collaboration:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.communication:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.communication:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.content:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.content:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - -.activityiconcontainer.interactivecontent:not(.isbranded) .activityicon:not(.nofilter), -.activityiconcontainer.interactivecontent:not(.isbranded) .icon:not(.nofilter) { - filter: url('data:image/svg+xml;utf8,#recolor'); -} - .icon-box { width: 60px; height: 48px; @@ -28934,6 +28870,67 @@ img.icon { color: #fff; } +/* + * Activity icons + */ +.activityiconcontainer { + width: 52px; + height: 52px; + max-width: 52px; + max-height: 52px; +} +.activityiconcontainer.small { + width: 42px; + height: 42px; + max-width: 42px; + max-height: 42px; +} +.activityiconcontainer.smaller { + width: 32px; + height: 32px; + max-width: 32px; + max-height: 32px; +} +.activityiconcontainer .activityicon, +.activityiconcontainer .icon { + margin: 0; + font-size: inherit; + width: inherit; + height: inherit; + max-width: inherit; + max-height: inherit; +} + +.activityiconcontainer.administration:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.administration:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.assessment:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.assessment:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.collaboration:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.collaboration:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.communication:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.communication:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.content:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.content:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + +.activityiconcontainer.interactivecontent:not(.isbranded) .activityicon:not(.nofilter), +.activityiconcontainer.interactivecontent:not(.isbranded) .icon:not(.nofilter) { + filter: url('data:image/svg+xml;utf8,#recolor'); +} + :root { --activityadministration: #da58ef; --activityassessment: #f90086;