mirror of
https://github.com/moodle/moodle.git
synced 2025-07-16 20:06:30 +02:00
MDL-61657 block_myoverview: implement course images for the myoverview block
This commit is contained in:
committed by
Eloy Lafuente (stronk7)
parent
4450d19ae1
commit
c8cc25caba
@@ -60,6 +60,7 @@ lib/fonts/
|
||||
lib/amd/src/adapter.js
|
||||
lib/validateurlsyntax.php
|
||||
lib/amd/src/popper.js
|
||||
lib/geopattern-php/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
|
@@ -61,6 +61,7 @@ lib/fonts/
|
||||
lib/amd/src/adapter.js
|
||||
lib/validateurlsyntax.php
|
||||
lib/amd/src/popper.js
|
||||
lib/geopattern-php/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
|
@@ -65,6 +65,7 @@ class courses_view implements renderable, templatable {
|
||||
public function export_for_template(renderer_base $output) {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
require_once($CFG->dirroot.'/lib/coursecatlib.php');
|
||||
|
||||
// Build courses view data structure.
|
||||
$coursesview = [
|
||||
@@ -83,6 +84,29 @@ class courses_view implements renderable, templatable {
|
||||
// Convert summary to plain text.
|
||||
$exportedcourse->summary = content_to_text($exportedcourse->summary, $exportedcourse->summaryformat);
|
||||
|
||||
$course = new \course_in_list($course);
|
||||
foreach ($course->get_course_overviewfiles() as $file) {
|
||||
$isimage = $file->is_valid_image();
|
||||
if ($isimage) {
|
||||
$url = file_encode_url("$CFG->wwwroot/pluginfile.php",
|
||||
'/'. $file->get_contextid(). '/'. $file->get_component(). '/'.
|
||||
$file->get_filearea(). $file->get_filepath(). $file->get_filename(), !$isimage);
|
||||
$exportedcourse->courseimage = $url;
|
||||
$exportedcourse->classes = 'courseimage';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$exportedcourse->color = $this->coursecolor($course->id);
|
||||
|
||||
if (!isset($exportedcourse->courseimage)) {
|
||||
$pattern = new \core_geopattern();
|
||||
$pattern->setColor($exportedcourse->color);
|
||||
$pattern->patternbyid($courseid);
|
||||
$exportedcourse->classes = 'coursepattern';
|
||||
$exportedcourse->courseimage = $pattern->datauri();
|
||||
}
|
||||
|
||||
// Include course visibility.
|
||||
$exportedcourse->visible = (bool)$course->visible;
|
||||
|
||||
@@ -148,4 +172,19 @@ class courses_view implements renderable, templatable {
|
||||
|
||||
return $coursesview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a semi-random color based on the courseid number (so it will always return
|
||||
* the same color for a course)
|
||||
*
|
||||
* @param int $courseid
|
||||
* @return string $color, hexvalue color code.
|
||||
*/
|
||||
protected function coursecolor($courseid) {
|
||||
// The colour palette is hardcoded for now. It would make sense to combine it with theme settings.
|
||||
$basecolors = ['#81ecec', '#74b9ff', '#a29bfe', '#dfe6e9', '#00b894', '#0984e3', '#b2bec3', '#fdcb6e', '#fd79a8', '#6c5ce7'];
|
||||
|
||||
$color = $basecolors[$courseid % 10];
|
||||
return $color;
|
||||
}
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@
|
||||
}
|
||||
}}
|
||||
{{< block_myoverview/paging-content-item }}
|
||||
{{$classes}}row{{/classes}}
|
||||
{{$classes}}row card-deck{{/classes}}
|
||||
{{$content}}
|
||||
{{#courses}}
|
||||
{{> block_myoverview/courses-view-course-item }}
|
||||
|
@@ -26,8 +26,11 @@
|
||||
"summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
|
||||
}
|
||||
}}
|
||||
<div class="col-lg-6">
|
||||
<div class="card mb-3 courses-view-course-item">
|
||||
<a href="{{viewurl}}">
|
||||
<div class="card-img-top myoverviewimg {{classes}}" style='background-image: url("{{{courseimage}}}");'>
|
||||
</div>
|
||||
</a>
|
||||
<div class="card-body course-info-container" id="course-info-container-{{id}}">
|
||||
|
||||
<div class="media">
|
||||
@@ -44,4 +47,3 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -85,6 +85,7 @@ class core_component {
|
||||
'IMSGlobal\LTI' => 'lib/ltiprovider/src',
|
||||
'Phpml' => 'lib/mlbackend/php/phpml/src/Phpml',
|
||||
'PHPMailer\\PHPMailer' => 'lib/phpmailer/src',
|
||||
'RedeyeVentures\\GeoPattern' => 'lib/geopattern-php/GeoPattern',
|
||||
);
|
||||
|
||||
/**
|
||||
|
45
lib/classes/geopattern.php
Normal file
45
lib/classes/geopattern.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Geopatterns for images.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2018 Moodle
|
||||
* @author Bas Brands
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
class core_geopattern extends \RedeyeVentures\GeoPattern\GeoPattern {
|
||||
|
||||
/**
|
||||
* Add variables.
|
||||
*
|
||||
* @param array $scss Associative array of variables and their values.
|
||||
* @return void
|
||||
*/
|
||||
public function patternbyid($uniqueid) {
|
||||
$this->setString($uniqueid);
|
||||
|
||||
}
|
||||
|
||||
public function datauri() {
|
||||
return $this->toDataURI();
|
||||
}
|
||||
|
||||
}
|
1327
lib/geopattern-php/GeoPattern/GeoPattern.php
Normal file
1327
lib/geopattern-php/GeoPattern/GeoPattern.php
Normal file
File diff suppressed because it is too large
Load Diff
94
lib/geopattern-php/GeoPattern/SVG.php
Normal file
94
lib/geopattern-php/GeoPattern/SVG.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php namespace RedeyeVentures\GeoPattern;
|
||||
|
||||
use RedeyeVentures\GeoPattern\SVGElements\Group;
|
||||
use RedeyeVentures\GeoPattern\SVGElements\Polyline;
|
||||
use RedeyeVentures\GeoPattern\SVGElements\Rectangle;
|
||||
use RedeyeVentures\GeoPattern\SVGElements\Circle;
|
||||
use RedeyeVentures\GeoPattern\SVGElements\Path;
|
||||
|
||||
class SVG {
|
||||
|
||||
protected $width;
|
||||
protected $height;
|
||||
protected $svgString;
|
||||
|
||||
function __construct($options=array())
|
||||
{
|
||||
$this->width = 100;
|
||||
$this->height = 100;
|
||||
$this->svgString = '';
|
||||
}
|
||||
|
||||
public function setWidth($width)
|
||||
{
|
||||
$this->width = floor($width);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHeight($height)
|
||||
{
|
||||
$this->height = floor($height);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getSvgHeader()
|
||||
{
|
||||
return "<?xml version=\"1.0\"?><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{$this->width}\" height=\"{$this->height}\">";
|
||||
}
|
||||
|
||||
protected function getSvgFooter()
|
||||
{
|
||||
return '</svg>';
|
||||
}
|
||||
|
||||
public function addRectangle($x, $y, $width, $height, $args=array())
|
||||
{
|
||||
$rectangle = new Rectangle($x, $y, $width, $height, $args);
|
||||
$this->svgString .= $rectangle;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addCircle($cx, $cy, $r, $args=array())
|
||||
{
|
||||
$circle = new Circle($cx, $cy, $r, $args);
|
||||
$this->svgString .= $circle;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addPath($d, $args=array())
|
||||
{
|
||||
$path = new Path($d, $args);
|
||||
$this->svgString .= $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addPolyline($points, $args=array())
|
||||
{
|
||||
$polyline = new Polyline($points, $args);
|
||||
$this->svgString .= $polyline;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addGroup($group, $args=array())
|
||||
{
|
||||
if ($group instanceof Group)
|
||||
{
|
||||
$group->setArgs($args);
|
||||
$this->svgString .= $group;
|
||||
return $this;
|
||||
}
|
||||
throw new \InvalidArgumentException("The group provided is not a valid instance of Group.");
|
||||
}
|
||||
|
||||
public function getString()
|
||||
{
|
||||
return $this->getSvgHeader().$this->svgString.$this->getSvgFooter();
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getString();
|
||||
}
|
||||
|
||||
|
||||
}
|
55
lib/geopattern-php/GeoPattern/SVGElements/Base.php
Normal file
55
lib/geopattern-php/GeoPattern/SVGElements/Base.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
|
||||
|
||||
abstract class Base
|
||||
{
|
||||
protected $tag;
|
||||
protected $elements;
|
||||
protected $args;
|
||||
|
||||
function __construct($args)
|
||||
{
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
public function elementsToString()
|
||||
{
|
||||
$string = ' ';
|
||||
foreach ($this->elements as $key => $value)
|
||||
{
|
||||
$string .= "$key=\"$value\" ";
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function argsToString()
|
||||
{
|
||||
$string = '';
|
||||
foreach ($this->args as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$string .= "$key=\"";
|
||||
foreach ($value as $k => $v)
|
||||
{
|
||||
$string .= "$k:$v;";
|
||||
}
|
||||
$string .= '" ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$string .= "$key=\"$value\" ";
|
||||
}
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function getString()
|
||||
{
|
||||
return "<{$this->tag}{$this->elementsToString()}{$this->argsToString()}/>";
|
||||
}
|
||||
|
||||
function __toString()
|
||||
{
|
||||
return $this->getString();
|
||||
}
|
||||
}
|
16
lib/geopattern-php/GeoPattern/SVGElements/Circle.php
Normal file
16
lib/geopattern-php/GeoPattern/SVGElements/Circle.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
|
||||
|
||||
class Circle extends Base
|
||||
{
|
||||
protected $tag = 'circle';
|
||||
|
||||
function __construct($cx, $cy, $r, $args=array())
|
||||
{
|
||||
$this->elements = [
|
||||
'cx' => $cx,
|
||||
'cy' => $cy,
|
||||
'r' => $r,
|
||||
];
|
||||
parent::__construct($args);
|
||||
}
|
||||
}
|
38
lib/geopattern-php/GeoPattern/SVGElements/Group.php
Normal file
38
lib/geopattern-php/GeoPattern/SVGElements/Group.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
|
||||
|
||||
class Group extends Base
|
||||
{
|
||||
protected $tag = 'g';
|
||||
protected $items;
|
||||
|
||||
function __construct($items=array(), $args=array())
|
||||
{
|
||||
$this->items = $items;
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
function addItem($item)
|
||||
{
|
||||
$this->items[] = $item;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function setArgs($args)
|
||||
{
|
||||
$this->args = $args;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function getString()
|
||||
{
|
||||
$svgString = '';
|
||||
$svgString .= "<{$this->tag} {$this->argsToString($this->args)}>";
|
||||
foreach ($this->items as $item)
|
||||
{
|
||||
$svgString .= $item;
|
||||
}
|
||||
$svgString .= "</{$this->tag}>";
|
||||
|
||||
return $svgString;
|
||||
}
|
||||
}
|
14
lib/geopattern-php/GeoPattern/SVGElements/Path.php
Normal file
14
lib/geopattern-php/GeoPattern/SVGElements/Path.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
|
||||
|
||||
class Path extends Base
|
||||
{
|
||||
protected $tag = 'path';
|
||||
|
||||
function __construct($d, $args=array())
|
||||
{
|
||||
$this->elements = [
|
||||
'd' => $d,
|
||||
];
|
||||
parent::__construct($args);
|
||||
}
|
||||
}
|
14
lib/geopattern-php/GeoPattern/SVGElements/Polyline.php
Normal file
14
lib/geopattern-php/GeoPattern/SVGElements/Polyline.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
|
||||
|
||||
class Polyline extends Base
|
||||
{
|
||||
protected $tag = 'polyline';
|
||||
|
||||
function __construct($points, $args=array())
|
||||
{
|
||||
$this->elements = [
|
||||
'points' => $points,
|
||||
];
|
||||
parent::__construct($args);
|
||||
}
|
||||
}
|
17
lib/geopattern-php/GeoPattern/SVGElements/Rectangle.php
Normal file
17
lib/geopattern-php/GeoPattern/SVGElements/Rectangle.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
|
||||
|
||||
class Rectangle extends Base
|
||||
{
|
||||
protected $tag = 'rect';
|
||||
|
||||
function __construct($x, $y, $width, $height, $args=array())
|
||||
{
|
||||
$this->elements = [
|
||||
'x' => $x,
|
||||
'y' => $y,
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
];
|
||||
parent::__construct($args);
|
||||
}
|
||||
}
|
20
lib/geopattern-php/LICENSE.md
Normal file
20
lib/geopattern-php/LICENSE.md
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Redeye Ventures
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
14
lib/geopattern-php/moodle_readme.txt
Normal file
14
lib/geopattern-php/moodle_readme.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
scssphp
|
||||
-------
|
||||
|
||||
Downloaded from: https://github.com/RedeyeGroup/geopattern-php
|
||||
|
||||
Last commit on download: 26d9f8aa7a8b00c8afc120d706f6bdd7a9965b87
|
||||
|
||||
Import procedure:
|
||||
|
||||
- Copy all the files from the folder 'src' this directory.
|
||||
- Copy the license file from the project root.
|
||||
- Remove the geopattern_loader.php file from the src directory, it is not needed.
|
||||
|
||||
Licensed under MIT, Copyright (c) 2015 Leaf Corcoran.
|
@@ -317,4 +317,10 @@
|
||||
<version>v1.12.6</version>
|
||||
<licenseversion></licenseversion>
|
||||
</library>
|
||||
<library>
|
||||
<location>geopattern-php</location>
|
||||
<name>Generate tiling SVG patterns from a string</name>
|
||||
<license>MIT</license>
|
||||
<version>1.1.1</version>
|
||||
</library>
|
||||
</libraries>
|
||||
|
@@ -199,6 +199,30 @@ $doughnut-fill-colour: $brand-warning;
|
||||
}
|
||||
}
|
||||
|
||||
.card-deck {
|
||||
.card {
|
||||
$card-gutter : $card-deck-margin * 2;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: calc(50% - #{$card-gutter});
|
||||
}
|
||||
.myoverviewimg {
|
||||
height: 150px;
|
||||
&.courseimage {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1600px) {
|
||||
.block_myoverview {
|
||||
.courses-view-course-item {
|
||||
height: 190px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show expand collapse with font-awesome.
|
||||
.block_settings .block_tree [aria-expanded="true"],
|
||||
.block_settings .block_tree [aria-expanded="true"].emptybranch,
|
||||
|
@@ -343,6 +343,10 @@
|
||||
.block_myoverview {
|
||||
background-color: transparent;
|
||||
|
||||
.row-fluid [class*="span"] {
|
||||
margin-left:0px;
|
||||
}
|
||||
|
||||
.event-list-item {
|
||||
border-bottom: 1px solid @tableBorder;
|
||||
padding-bottom: 10px;
|
||||
@@ -395,5 +399,13 @@
|
||||
.well {
|
||||
background-color: @white;
|
||||
box-shadow: none;
|
||||
margin: 0 5px 10px;
|
||||
}
|
||||
.myoverviewimg {
|
||||
height: 150px;
|
||||
&.courseimage {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16487,6 +16487,9 @@ body {
|
||||
.block_myoverview {
|
||||
background-color: transparent;
|
||||
}
|
||||
.block_myoverview .row-fluid [class*="span"] {
|
||||
margin-left: 0px;
|
||||
}
|
||||
.block_myoverview .event-list-item {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding-bottom: 10px;
|
||||
@@ -16529,6 +16532,14 @@ body {
|
||||
.block_myoverview .well {
|
||||
background-color: #fff;
|
||||
box-shadow: none;
|
||||
margin: 0 5px 10px;
|
||||
}
|
||||
.block_myoverview .myoverviewimg {
|
||||
height: 150px;
|
||||
}
|
||||
.block_myoverview .myoverviewimg.courseimage {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
/**
|
||||
* Moodle forms HTML isn't changeable via renderers (yet?) so this
|
||||
|
@@ -42,5 +42,6 @@
|
||||
{{#courses}}
|
||||
{{> block_myoverview/courses-view-course-item }}
|
||||
{{/courses}}
|
||||
<div class="clearfix"></div>
|
||||
{{/content}}
|
||||
{{/ block_myoverview/paging-content-item }}
|
||||
|
@@ -26,7 +26,12 @@
|
||||
"summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
|
||||
}
|
||||
}}
|
||||
<div class="span6">
|
||||
<div class="well well-small">
|
||||
<a href="{{viewurl}}">
|
||||
<div class="myoverviewimg m-b-1 {{classes}}" style='background-image: url("{{{courseimage}}}");'>
|
||||
</div>
|
||||
</a>
|
||||
<div class="course-info-container" id="course-info-container-{{id}}">
|
||||
<div class="media">
|
||||
<div class="pull-left">
|
||||
@@ -45,3 +50,4 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -0,0 +1,36 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template block_myoverview/paging-content-item
|
||||
|
||||
This template renders the content of a page. It is to be used with
|
||||
the paging bar to toggle visibility of the content items.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"active": true,
|
||||
"page": 1,
|
||||
"content": "<p>Some page content</p>"
|
||||
}
|
||||
}}
|
||||
<div data-region="paging-content-item"
|
||||
data-page="{{page}}"
|
||||
class="row-fluid {{^active}}hidden{{/active}} {{$classes}}{{/classes}}">
|
||||
{{$content}}
|
||||
{{{content}}}
|
||||
{{/content}}
|
||||
</div>
|
Reference in New Issue
Block a user