mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
MDL-65033 mod_forum: Favouriting in forum
Modify the discussion vault to take into account the favourite sql and also sort by favourite
This commit is contained in:
parent
14cdf51189
commit
99bda8a7ff
1
mod/forum/amd/build/favourite_toggle.min.js
vendored
Normal file
1
mod/forum/amd/build/favourite_toggle.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/templates","core/notification","mod_forum/repository","mod_forum/selectors"],function(a,b,c,d,e){var f=function(f){f.on("click",e.favourite.toggle,function(e){var f=a(this),g=f.data("forumid"),h=f.data("discussionid"),i=f.data("targetstate");d.toggleFavouriteDiscussionState(g,h,i).then(function(a){return b.render("mod_forum/discussion_favourite_toggle",a)}).then(function(a,c){return b.replaceNode(f,a,c)})["catch"](c.exception),e.preventDefault()})};return{init:function(a){f(a)}}});
|
2
mod/forum/amd/build/repository.min.js
vendored
2
mod/forum/amd/build/repository.min.js
vendored
@ -1 +1 @@
|
||||
define(["core/ajax"],function(a){var b=function(b,c,d){var e={methodname:"mod_forum_set_subscription_state",args:{forumid:b,discussionid:c,targetstate:d}};return a.call([e])[0]},c=function(b,c,d){var e={methodname:"mod_forum_add_discussion_post",args:{postid:b,message:d,subject:c}};return a.call([e])[0]},d=function(b,c,d){var e={methodname:"mod_forum_set_lock_state",args:{forumid:b,discussionid:c,targetstate:d}};return a.call([e])[0]};return{setDiscussionSubscriptionState:b,addDiscussionPost:c,setDiscussionLockState:d}});
|
||||
define(["core/ajax"],function(a){var b=function(b,c,d){var e={methodname:"mod_forum_set_subscription_state",args:{forumid:b,discussionid:c,targetstate:d}};return a.call([e])[0]},c=function(b,c,d){var e={methodname:"mod_forum_add_discussion_post",args:{postid:b,message:d,subject:c}};return a.call([e])[0]},d=function(b,c,d){var e={methodname:"mod_forum_toggle_favourite_state",args:{forumid:b,discussionid:c,targetstate:d}};return a.call([e])[0]},e=function(b,c,d){var e={methodname:"mod_forum_set_lock_state",args:{forumid:b,discussionid:c,targetstate:d}};return a.call([e])[0]};return{setDiscussionSubscriptionState:b,addDiscussionPost:c,setDiscussionLockState:e,toggleFavouriteDiscussionState:d}});
|
2
mod/forum/amd/build/selectors.min.js
vendored
2
mod/forum/amd/build/selectors.min.js
vendored
@ -1 +1 @@
|
||||
define([],function(){return{subscription:{toggle:"[data-type='subscription-toggle'][data-action='toggle']"},pin:{toggle:".pindiscussion [data-action='toggle']"},post:{post:'[data-region="post"]',action:'[data-region="post-action"]',actionsContainer:'[data-region="post-actions-container"]',forumCoreContent:"[data-region-content='forum-post-core']",forumContent:"[data-content='forum-post']",forumSubject:"[data-region-content='forum-post-core-subject']",inpageReplyLink:"[data-action='collapsible-link']",inpageReplyContent:"[data-content='inpage-reply-content']",inpageReplyForm:"form[data-content='inpage-reply-form']",inpageSubmitBtn:"[data-action='forum-inpage-submit']",repliesContainer:"[data-region='replies-container']",modeSelect:"select[name='mode']"},lock:{toggle:"[data-action='toggle'][data-type='lock-toggle']"}}});
|
||||
define([],function(){return{subscription:{toggle:"[data-type='subscription-toggle'][data-action='toggle']"},pin:{toggle:".pindiscussion [data-action='toggle']"},post:{post:'[data-region="post"]',action:'[data-region="post-action"]',actionsContainer:'[data-region="post-actions-container"]',forumCoreContent:"[data-region-content='forum-post-core']",forumContent:"[data-content='forum-post']",forumSubject:"[data-region-content='forum-post-core-subject']",inpageReplyLink:"[data-action='collapsible-link']",inpageReplyContent:"[data-content='inpage-reply-content']",inpageReplyForm:"form[data-content='inpage-reply-form']",inpageSubmitBtn:"[data-action='forum-inpage-submit']",repliesContainer:"[data-region='replies-container']",modeSelect:"select[name='mode']"},lock:{toggle:"[data-action='toggle'][data-type='lock-toggle']"},favourite:{toggle:"[data-type='favorite-toggle'][data-action='toggle']"}}});
|
69
mod/forum/amd/src/favourite_toggle.js
Normal file
69
mod/forum/amd/src/favourite_toggle.js
Normal file
@ -0,0 +1,69 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Handle discussion subscription toggling on a discussion list in
|
||||
* the forum view.
|
||||
*
|
||||
* @module mod_forum/favourite_toggle
|
||||
* @package mod_forum
|
||||
* @copyright 2019 Peter Dias <peter@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'core/templates',
|
||||
'core/notification',
|
||||
'mod_forum/repository',
|
||||
'mod_forum/selectors',
|
||||
], function(
|
||||
$,
|
||||
Templates,
|
||||
Notification,
|
||||
Repository,
|
||||
Selectors
|
||||
) {
|
||||
|
||||
/**
|
||||
* Register event listeners for the subscription toggle.
|
||||
*
|
||||
* @param {object} root The discussion list root element
|
||||
*/
|
||||
var registerEventListeners = function(root) {
|
||||
root.on('click', Selectors.favourite.toggle, function(e) {
|
||||
var toggleElement = $(this);
|
||||
var forumId = toggleElement.data('forumid');
|
||||
var discussionId = toggleElement.data('discussionid');
|
||||
var subscriptionState = toggleElement.data('targetstate');
|
||||
|
||||
Repository.toggleFavouriteDiscussionState(forumId, discussionId, subscriptionState)
|
||||
.then(function(context) {
|
||||
return Templates.render('mod_forum/discussion_favourite_toggle', context);
|
||||
})
|
||||
.then(function(html, js) {
|
||||
return Templates.replaceNode(toggleElement, html, js);
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: function(root) {
|
||||
registerEventListeners(root);
|
||||
}
|
||||
};
|
||||
});
|
@ -52,7 +52,26 @@ define(['core/ajax'], function(Ajax) {
|
||||
subject: subject
|
||||
}
|
||||
};
|
||||
return Ajax.call([request])[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the favourite state for a discussion in a forum.
|
||||
*
|
||||
* @param {number} forumId ID of the forum the discussion belongs to
|
||||
* @param {number} discussionId ID of the discussion with the subscription state
|
||||
* @param {boolean} targetState Set the favourite state. True == favourited; false == unfavourited.
|
||||
* @return {object} jQuery promise
|
||||
*/
|
||||
var toggleFavouriteDiscussionState = function(forumId, discussionId, targetState) {
|
||||
var request = {
|
||||
methodname: 'mod_forum_toggle_favourite_state',
|
||||
args: {
|
||||
forumid: forumId,
|
||||
discussionid: discussionId,
|
||||
targetstate: targetState
|
||||
}
|
||||
};
|
||||
return Ajax.call([request])[0];
|
||||
};
|
||||
|
||||
@ -71,6 +90,7 @@ define(['core/ajax'], function(Ajax) {
|
||||
return {
|
||||
setDiscussionSubscriptionState: setDiscussionSubscriptionState,
|
||||
addDiscussionPost: addDiscussionPost,
|
||||
setDiscussionLockState: setDiscussionLockState
|
||||
setDiscussionLockState: setDiscussionLockState,
|
||||
toggleFavouriteDiscussionState: toggleFavouriteDiscussionState
|
||||
};
|
||||
});
|
||||
|
@ -45,6 +45,9 @@ define([], function() {
|
||||
},
|
||||
lock: {
|
||||
toggle: "[data-action='toggle'][data-type='lock-toggle']",
|
||||
},
|
||||
favourite: {
|
||||
toggle: "[data-type='favorite-toggle'][data-action='toggle']",
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -320,4 +320,17 @@ class discussion {
|
||||
public function is_timed_discussion_visible() : bool {
|
||||
return !$this->is_timed_discussion() || ($this->has_started() && !$this->has_ended());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the provided discussion has been favourited by the user.
|
||||
*
|
||||
* @param discussion $discussion The discussion record
|
||||
* @param context $forumcontext Forum context
|
||||
* @param \stdClass $user The user to check the favourite against
|
||||
*/
|
||||
public static function is_favourited(discussion $discussion, \context_module $forumcontext, \stdClass $user) {
|
||||
$usercontext = \context_user::instance($user->id);
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
|
||||
return $ufservice->favourite_exists('mod_forum', 'discussions', $discussion->get_id(), $forumcontext);
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ class discussion extends exporter {
|
||||
'userstate' => [
|
||||
'type' => [
|
||||
'subscribed' => ['type' => PARAM_BOOL],
|
||||
'favourited' => ['type' => PARAM_BOOL],
|
||||
],
|
||||
],
|
||||
'capabilities' => [
|
||||
@ -105,6 +106,7 @@ class discussion extends exporter {
|
||||
'pin' => ['type' => PARAM_BOOL],
|
||||
'post' => ['type' => PARAM_BOOL],
|
||||
'manage' => ['type' => PARAM_BOOL],
|
||||
'favourite' => ['type' => PARAM_BOOL]
|
||||
]
|
||||
],
|
||||
'urls' => [
|
||||
@ -195,14 +197,16 @@ class discussion extends exporter {
|
||||
'locked' => $discussion->get_locked()
|
||||
],
|
||||
'userstate' => [
|
||||
'subscribed' => \mod_forum\subscriptions::is_subscribed($user->id, $forumrecord, $discussion->get_id())
|
||||
'subscribed' => \mod_forum\subscriptions::is_subscribed($user->id, $forumrecord, $discussion->get_id()),
|
||||
'favourited' => discussion_entity::is_favourited($discussion, $forum->get_context(), $user),
|
||||
],
|
||||
'capabilities' => [
|
||||
'subscribe' => $capabilitymanager->can_subscribe_to_discussion($user, $discussion),
|
||||
'move' => $capabilitymanager->can_move_discussion($user, $discussion),
|
||||
'pin' => $capabilitymanager->can_pin_discussion($user, $discussion),
|
||||
'post' => $capabilitymanager->can_post_in_discussion($user, $discussion),
|
||||
'manage' => $capabilitymanager->can_manage_forum($user)
|
||||
'manage' => $capabilitymanager->can_manage_forum($user),
|
||||
'favourite' => $capabilitymanager->can_favourite_discussion($user, $discussion) // Defaulting to true until we get capabilities sorted
|
||||
],
|
||||
'urls' => [
|
||||
'view' => $urlfactory->get_discussion_view_url_from_discussion($discussion)->out(false),
|
||||
|
@ -321,6 +321,18 @@ class capability {
|
||||
return forum_user_can_post($forumrecord, $discussionrecord, $user, $coursemodule, $course, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user favourite the discussion
|
||||
*
|
||||
* @param stdClass $user The user to check
|
||||
* @param discussion_entity $discussion The discussion to check
|
||||
* @return bool
|
||||
*/
|
||||
public function can_favourite_discussion(stdClass $user, discussion_entity $discussion) : bool {
|
||||
$context = $this->get_context();
|
||||
return has_capability('mod/forum::cantogglefavourite', $context, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user view the content of the post in this discussion?
|
||||
*
|
||||
|
@ -201,6 +201,10 @@ class discussion {
|
||||
$exporteddiscussion['html']['pindiscussion'] = $this->get_pin_discussion_html();
|
||||
}
|
||||
|
||||
if ($capabilities['favourite']) {
|
||||
$exporteddiscussion['html']['favouritediscussion'] = $this->get_favourite_discussion_html($exporteddiscussion);
|
||||
}
|
||||
|
||||
return $this->renderer->render_from_template('mod_forum/forum_discussion', $exporteddiscussion);
|
||||
}
|
||||
|
||||
@ -335,18 +339,24 @@ class discussion {
|
||||
|
||||
if ($discussion->is_pinned()) {
|
||||
$pinlink = FORUM_DISCUSSION_UNPINNED;
|
||||
$pintext = get_string('discussionunpin', 'forum');
|
||||
$pintext = get_string('unpindiscussion', 'forum');
|
||||
} else {
|
||||
$pinlink = FORUM_DISCUSSION_PINNED;
|
||||
$pintext = get_string('discussionpin', 'forum');
|
||||
$pintext = get_string('pindiscussion', 'forum');
|
||||
}
|
||||
|
||||
$button = new single_button(
|
||||
new moodle_url('discuss.php', ['pin' => $pinlink, 'd' => $discussion->get_id()]),
|
||||
$pintext,
|
||||
'post'
|
||||
);
|
||||
return $this->renderer->render($button);
|
||||
$params = [
|
||||
'pin' => $pinlink,
|
||||
'd' => $discussion->get_id(),
|
||||
'sesskey' => sesskey(),
|
||||
];
|
||||
$url = new moodle_url('discuss.php', $params);
|
||||
$link = new \action_link($url, $pintext, null, ['class' => 'btn btn-link']);
|
||||
return $this->renderer->render($link);
|
||||
}
|
||||
|
||||
private function get_favourite_discussion_html($exporteddiscussion) : string {
|
||||
return $this->renderer->render_from_template('mod_forum/discussion_favourite_toggle', $exporteddiscussion);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,6 +74,10 @@ class discussion_list extends db_table_vault {
|
||||
return 'd';
|
||||
}
|
||||
|
||||
protected function get_favourite_alias() : string {
|
||||
return 'favalias';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the SQL to be used in get_records_sql.
|
||||
*
|
||||
@ -81,7 +85,7 @@ class discussion_list extends db_table_vault {
|
||||
* @param string|null $sortsql Order by conditions for the SQL
|
||||
* @return string
|
||||
*/
|
||||
protected function generate_get_records_sql(string $wheresql = null, ?string $sortsql = null) : string {
|
||||
protected function generate_get_records_sql(string $wheresql = null, ?string $sortsql = null, ?string $joinsql = null) : string {
|
||||
$alias = $this->get_table_alias();
|
||||
$db = $this->get_db();
|
||||
|
||||
@ -106,6 +110,7 @@ class discussion_list extends db_table_vault {
|
||||
$tables .= ' JOIN {user} fa ON fa.id = ' . $alias . '.userid';
|
||||
$tables .= ' JOIN {user} la ON la.id = ' . $alias . '.usermodified';
|
||||
$tables .= ' JOIN ' . $posttable->get_from_sql() . ' ON fp.id = ' . $alias . '.firstpost';
|
||||
$tables .= $joinsql ? $joinsql : '';
|
||||
|
||||
$selectsql = 'SELECT ' . $fields . ' FROM ' . $tables;
|
||||
$selectsql .= $wheresql ? ' WHERE ' . $wheresql : '';
|
||||
@ -183,24 +188,18 @@ class discussion_list extends db_table_vault {
|
||||
|
||||
$alias = $this->get_table_alias();
|
||||
|
||||
if ($sortmethod == self::SORTORDER_CREATED_DESC) {
|
||||
$keyfield = "fp.created";
|
||||
$direction = "DESC";
|
||||
} else {
|
||||
// TODO consider user favourites...
|
||||
$keyfield = "{$alias}.timemodified";
|
||||
$direction = "DESC";
|
||||
$keyfield = "{$alias}.timemodified";
|
||||
$direction = "DESC";
|
||||
|
||||
if ($sortmethod == self::SORTORDER_OLDEST_FIRST) {
|
||||
$direction = "ASC";
|
||||
}
|
||||
|
||||
if (!empty($CFG->forum_enabletimedposts)) {
|
||||
$keyfield = "CASE WHEN {$keyfield} < {$alias}.timestart THEN {$alias}.timestart ELSE {$keyfield} END";
|
||||
}
|
||||
if ($sortmethod == self::SORTORDER_OLDEST_FIRST) {
|
||||
$direction = "ASC";
|
||||
}
|
||||
|
||||
return "{$alias}.pinned DESC, {$keyfield} {$direction}, {$alias}.id DESC";
|
||||
if (!empty($CFG->forum_enabletimedposts)) {
|
||||
$keyfield = "CASE WHEN {$keyfield} < {$alias}.timestart THEN {$alias}.timestart ELSE {$keyfield} END";
|
||||
}
|
||||
|
||||
return "{$alias}.pinned DESC, {$this->get_favourite_alias()}.id DESC, {$keyfield} {$direction}";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,7 +262,10 @@ class discussion_list extends db_table_vault {
|
||||
'forumid' => $forumid,
|
||||
]);
|
||||
|
||||
$sql = $this->generate_get_records_sql($wheresql, $this->get_sort_order($sortorder));
|
||||
list($favsql, $favparams) = $this->get_favourite_sql();
|
||||
$params += $favparams;
|
||||
|
||||
$sql = $this->generate_get_records_sql($wheresql, $this->get_sort_order($sortorder), $favsql);
|
||||
$records = $this->get_db()->get_records_sql($sql, $params, $offset, $limit);
|
||||
|
||||
return $this->transform_db_records_to_entities($records);
|
||||
@ -390,4 +392,17 @@ class discussion_list extends db_table_vault {
|
||||
|
||||
return $this->get_db()->count_records_sql($this->generate_count_records_sql($wheresql), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the standard favouriting sql.
|
||||
*/
|
||||
private function get_favourite_sql(): array {
|
||||
global $USER;
|
||||
$usercontext = \context_user::instance($USER->id);
|
||||
$alias = $this->get_table_alias();
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
|
||||
list($favsql, $favparams) = $ufservice->get_join_sql_by_type('mod_forum', 'discussions', $this->get_favourite_alias(), "$alias.id");
|
||||
|
||||
return [$favsql, $favparams];
|
||||
}
|
||||
}
|
||||
|
@ -405,5 +405,13 @@ $capabilities = array(
|
||||
),
|
||||
'clonepermissionsfrom' => 'mod/forum:canoverridediscussionlock'
|
||||
),
|
||||
'mod/forum::cantogglefavourite' => array(
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'user' => CAP_ALLOW
|
||||
),
|
||||
'clonepermissionsfrom' => 'moodle/user:manageownfiles'
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -145,4 +145,14 @@ $functions = array(
|
||||
'capabilities' => 'moodle/course:manageactivities',
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
),
|
||||
|
||||
'mod_forum_toggle_favourite_state' => array(
|
||||
'classname' => 'mod_forum_external',
|
||||
'methodname' => 'toggle_favourite_state',
|
||||
'classpath' => 'mod/forum/externallib.php',
|
||||
'description' => 'Toggle the favourite state',
|
||||
'type' => 'write',
|
||||
'ajax' => true,
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
),
|
||||
);
|
||||
|
@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die;
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
|
||||
use mod_forum\local\exporters\post as post_exporter;
|
||||
use mod_forum\local\exporters\discussion as discussion_exporter;
|
||||
|
||||
class mod_forum_external extends external_api {
|
||||
|
||||
@ -1096,6 +1097,68 @@ class mod_forum_external extends external_api {
|
||||
);
|
||||
}
|
||||
|
||||
public static function toggle_favourite_state($forumid, $discussionid, $targetstate) {
|
||||
global $DB, $PAGE, $USER;
|
||||
|
||||
$params = self::validate_parameters(self::toggle_favourite_state_parameters(), [
|
||||
'forumid' => $forumid,
|
||||
'discussionid' => $discussionid,
|
||||
'targetstate' => $targetstate
|
||||
]);
|
||||
|
||||
$vaultfactory = mod_forum\local\container::get_vault_factory();
|
||||
$forumvault = $vaultfactory->get_forum_vault();
|
||||
$forum = $forumvault->get_from_id($params['forumid']);
|
||||
$forumcontext = $forum->get_context();
|
||||
$usercontext = context_user::instance($USER->id);
|
||||
|
||||
self::validate_context($forumcontext);
|
||||
|
||||
$managerfactory = mod_forum\local\container::get_manager_factory();
|
||||
$capabilitymanager = $managerfactory->get_capability_manager($forum);
|
||||
|
||||
// Get the discussion vault and the corresponding discussion entity.
|
||||
$discussionvault = $vaultfactory->get_discussion_vault();
|
||||
$discussion = $discussionvault->get_from_id($params['discussionid']);
|
||||
|
||||
// Does the user have the ability to favourite the discussion?
|
||||
if (!$capabilitymanager->can_favourite_discussion($USER, $discussion)) {
|
||||
throw new moodle_exception('cannotfavourite', 'forum');
|
||||
}
|
||||
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
|
||||
$isfavourited = $ufservice->favourite_exists('mod_forum', 'discussions', $discussion->get_id(), $forumcontext);
|
||||
|
||||
$favouritefunction = $targetstate ? 'create_favourite' : 'delete_favourite';
|
||||
if ($isfavourited != (bool) $params['targetstate']) {
|
||||
$ufservice->{$favouritefunction}('mod_forum', 'discussions', $discussion->get_id(), $forumcontext);
|
||||
}
|
||||
|
||||
$exporterfactory = mod_forum\local\container::get_exporter_factory();
|
||||
$exporter = $exporterfactory->get_discussion_exporter($USER, $forum, $discussion);
|
||||
return $exporter->export($PAGE->get_renderer('mod_forum'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.0
|
||||
*/
|
||||
public static function toggle_favourite_state_returns() {
|
||||
return discussion_exporter::get_read_structure();
|
||||
}
|
||||
|
||||
public function toggle_favourite_state_parameters() {
|
||||
return new external_function_parameters(
|
||||
[
|
||||
'forumid' => new external_value(PARAM_INT, 'Forum that the discussion is in'),
|
||||
'discussionid' => new external_value(PARAM_INT, 'The discussion to subscribe or unsubscribe'),
|
||||
'targetstate' => new external_value(PARAM_BOOL, 'The target state')
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
|
@ -27,6 +27,7 @@ $string['activityoverview'] = 'There are new forum posts';
|
||||
$string['addanewdiscussion'] = 'Add a new discussion topic';
|
||||
$string['addanewquestion'] = 'Add a new question';
|
||||
$string['addanewtopic'] = 'Add a new topic';
|
||||
$string['addtofavourites'] = 'Star this discussion';
|
||||
$string['advancedsearch'] = 'Advanced search';
|
||||
$string['allforums'] = 'All forums';
|
||||
$string['allowdiscussions'] = 'Can a {$a} post to this forum?';
|
||||
@ -79,6 +80,7 @@ $string['cannotremovesubscriber'] = 'Could not remove subscriber with id {$a} fr
|
||||
$string['cannotreply'] = 'You cannot reply to this post';
|
||||
$string['cannotsplit'] = 'Discussions from this forum cannot be split';
|
||||
$string['cannotsubscribe'] = 'Sorry, but you must be a group member to subscribe.';
|
||||
$string['cannotfavourite'] = 'Sorry, but you do not have the permission to favourite.';
|
||||
$string['cannottrack'] = 'Could not stop tracking that forum';
|
||||
$string['cannotunsubscribe'] = 'Could not unsubscribe you from that forum';
|
||||
$string['cannotupdatepost'] = 'You can not update this post';
|
||||
@ -89,6 +91,8 @@ $string['clicktolockdiscussion'] = 'Click to lock this discussion';
|
||||
$string['clicktounlockdiscussion'] = 'Click to unlock this discussion';
|
||||
$string['clicktounsubscribe'] = 'You are subscribed to this discussion. Click to unsubscribe.';
|
||||
$string['clicktosubscribe'] = 'You are not subscribed to this discussion. Click to subscribe.';
|
||||
$string['clicktounfavourite'] = 'You have starred this discussion. Click to unstar.';
|
||||
$string['clicktofavourite'] = 'You have not starred this discussion. Click to star.';
|
||||
$string['completiondiscussions'] = 'Student must create discussions:';
|
||||
$string['completiondiscussionsdesc'] = 'Student must create at least {$a} discussion(s)';
|
||||
$string['completiondiscussionsgroup'] = 'Require discussions';
|
||||
@ -233,6 +237,7 @@ $string['existingsubscribers'] = 'Existing subscribers';
|
||||
$string['exportdiscussion'] = 'Export whole discussion to portfolio';
|
||||
$string['exportattachmentname'] = 'Export attachment {$a} to portfolio';
|
||||
$string['firstpost'] = 'First post';
|
||||
$string['favourites'] = 'Starred';
|
||||
$string['forcedreadtracking'] = 'Allow forced read tracking';
|
||||
$string['forcedreadtracking_desc'] = 'Allows forums to be set to forced read tracking. Will result in decreased performance for some users, particularly on courses with many forums and posts. When off, any forums previously set to Forced are treated as optional.';
|
||||
$string['forcesubscribed_help'] = 'This forum has been configured so that you cannot unsubscribe from discussions.';
|
||||
@ -433,6 +438,7 @@ $string['permalink'] = 'Permalink';
|
||||
$string['permanentlinktopost'] = 'Permanent link to this post';
|
||||
$string['permanentlinktoparentpost'] = 'Permanent link to the parent of this post';
|
||||
$string['postisprivatereply'] = 'This post was made privately and is not visible to all users.';
|
||||
$string['pindiscussion'] = 'Pin this discussion';
|
||||
$string['posttomygroups'] = 'Post a copy to all groups';
|
||||
$string['posttomygroups_help'] = 'Posts a copy of this message to all groups you have access to. Participants in groups you do not have access to will not see this post';
|
||||
$string['prevdiscussiona'] = 'Previous discussion: {$a}';
|
||||
@ -527,6 +533,7 @@ $string['qandanotify'] = 'This is a question and answer forum. In order to see o
|
||||
$string['re'] = 'Re:';
|
||||
$string['readtherest'] = 'Read the rest of this topic';
|
||||
$string['removeallforumtags'] = 'Remove all forum tags';
|
||||
$string['removefromfavourites'] = 'Unstar this discussion';
|
||||
$string['replies'] = 'Replies';
|
||||
$string['repliesmany'] = '{$a} replies so far';
|
||||
$string['repliesone'] = '{$a} reply so far';
|
||||
@ -568,6 +575,7 @@ $string['searchuserid'] = 'The Moodle ID of the author';
|
||||
$string['searchwhichforums'] = 'Choose which forums to search';
|
||||
$string['searchwords'] = 'These words can appear anywhere in the post';
|
||||
$string['seeallposts'] = 'See all posts made by this user';
|
||||
$string['settings'] = 'Settings';
|
||||
$string['shortpost'] = 'Short post';
|
||||
$string['showsubscribers'] = 'Show/edit current subscribers';
|
||||
$string['singleforum'] = 'A single simple discussion';
|
||||
@ -638,6 +646,7 @@ $string['unsubscribeallempty'] = 'You are not subscribed to any forums. To disab
|
||||
$string['unsubscribed'] = 'Unsubscribed';
|
||||
$string['unsubscribeshort'] = 'Unsubscribe';
|
||||
$string['usermarksread'] = 'Manual message read marking';
|
||||
$string['unpindiscussion'] = 'Unpin this discussion';
|
||||
$string['viewalldiscussions'] = 'View all discussions';
|
||||
$string['viewthediscussion'] = 'View the discussion';
|
||||
$string['warnafter'] = 'Post threshold for warning';
|
||||
|
BIN
mod/forum/pix/t/star.png
Normal file
BIN
mod/forum/pix/t/star.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 390 B |
6
mod/forum/pix/t/star.svg
Normal file
6
mod/forum/pix/t/star.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16pt" height="16pt" viewBox="0 0 16 16" version="1.1" preserveAspectRatio="xMinYMid meet">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,43.921569%,65.882353%);fill-opacity:1;" d="M 15.429688 5.777344 C 15.429688 5.90625 15.351562 6.050781 15.195312 6.207031 L 11.957031 9.367188 L 12.722656 13.832031 C 12.730469 13.871094 12.730469 13.929688 12.730469 14.007812 C 12.730469 14.132812 12.699219 14.238281 12.636719 14.324219 C 12.574219 14.414062 12.484375 14.457031 12.367188 14.457031 C 12.253906 14.457031 12.132812 14.417969 12.007812 14.347656 L 8 12.242188 L 3.992188 14.347656 C 3.859375 14.417969 3.742188 14.457031 3.632812 14.457031 C 3.507812 14.457031 3.414062 14.414062 3.351562 14.324219 C 3.289062 14.238281 3.257812 14.132812 3.257812 14.007812 C 3.257812 13.972656 3.265625 13.914062 3.277344 13.832031 L 4.042969 9.367188 L 0.792969 6.207031 C 0.644531 6.042969 0.570312 5.902344 0.570312 5.777344 C 0.570312 5.554688 0.738281 5.417969 1.070312 5.367188 L 5.554688 4.714844 L 7.5625 0.652344 C 7.675781 0.40625 7.820312 0.285156 8 0.285156 C 8.179688 0.285156 8.324219 0.40625 8.4375 0.652344 L 10.445312 4.714844 L 14.929688 5.367188 C 15.261719 5.417969 15.429688 5.554688 15.429688 5.777344 Z M 15.429688 5.777344 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -302,14 +302,18 @@ span.unread {
|
||||
}
|
||||
|
||||
.path-mod-forum .discussionsubscription,
|
||||
.path-mod-forum .discussionlock {
|
||||
.path-mod-forum .discussionlock,
|
||||
.path-mod-forum .discussion-settings-menu,
|
||||
.path-mod-forum .discussionsubscription {
|
||||
margin-top: -10px;
|
||||
text-align: right;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.path-mod-forum .discussionsubscription > a > img,
|
||||
.path-mod-forum .discussionlock > a > img {
|
||||
.path-mod-forum .discussionlock > a > img,
|
||||
.path-mod-forum .favourite-discussion > a > img,
|
||||
.path-mod-forum .discussion-settings-menu > a > img {
|
||||
width: 12px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
57
mod/forum/templates/discussion_favourite_toggle.mustache
Normal file
57
mod/forum/templates/discussion_favourite_toggle.mustache
Normal file
@ -0,0 +1,57 @@
|
||||
{{!
|
||||
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 mod_forum/discussion_subscription_toggle
|
||||
|
||||
Template to display the discussion subscription toggle.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* TODO
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
}
|
||||
}}
|
||||
{{#capabilities.favourite}}
|
||||
<a
|
||||
class="p-t-0 btn btn-link"
|
||||
data-type="favorite-toggle"
|
||||
data-action="toggle"
|
||||
data-discussionid="{{id}}"
|
||||
data-forumid="{{forumid}}"
|
||||
href="#"
|
||||
{{#userstate.favourited}}
|
||||
data-targetstate="0"
|
||||
{{/userstate.favourited}}
|
||||
{{^userstate.favourited}}
|
||||
data-targetstate="1"
|
||||
{{/userstate.favourited}}
|
||||
>
|
||||
{{#userstate.favourited}}
|
||||
{{#str}}removefromfavourites, mod_forum{{/str}}
|
||||
{{/userstate.favourited}}
|
||||
{{^userstate.favourited}}
|
||||
{{#str}}addtofavourites, mod_forum{{/str}}
|
||||
{{/userstate.favourited}}
|
||||
</a>
|
||||
{{/capabilities.favourite}}
|
@ -93,6 +93,11 @@
|
||||
{{#discussion.pinned}}
|
||||
{{#pix}}i/pinned, mod_forum, {{#str}}discussionpinned, mod_forum{{/str}}{{/pix}}
|
||||
{{/discussion.pinned}}
|
||||
{{^discussion.pinned}}
|
||||
{{#discussion.userstate.favourited}}
|
||||
{{#pix}}i/pinned, mod_forum, {{#str}}discussionpinned, mod_forum{{/str}}{{/pix}}
|
||||
{{/discussion.userstate.favourited}}
|
||||
{{/discussion.pinned}}
|
||||
</td>
|
||||
<td scope="col" class="topic p-0 align-middle">
|
||||
<a class="p-3 p-l-0 w-100 h-100 d-block" href="{{discussion.urls.view}}">{{{discussion.name}}}</a>
|
||||
|
43
mod/forum/templates/forum_action_menu.mustache
Normal file
43
mod/forum/templates/forum_action_menu.mustache
Normal file
@ -0,0 +1,43 @@
|
||||
{{!
|
||||
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 mod_forum/forum-action-menu
|
||||
|
||||
This template renders action menu for each course.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
|
||||
}
|
||||
}}
|
||||
<div class="ml-auto dropdown">
|
||||
<button class="m-t-0 p-t-0 btn btn-link btn-icon"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
{{#pix}} i/settings, core{{/pix}}{{#str}} settings, mod_forum {{/str}}
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<div class="dropdown-item">
|
||||
{{> mod_forum/discussion_favourite_toggle}}
|
||||
</div>
|
||||
<div class="dropdown-item">
|
||||
{{{pindiscussion}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -40,6 +40,11 @@
|
||||
</div>
|
||||
{{/istimelocked}}
|
||||
{{/capabilities.manage}}
|
||||
<div class="pl-1">
|
||||
<div class="discussion-settings-menu">
|
||||
{{> mod_forum/forum_action_menu}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pl-1">{{{subscribe}}}</div>
|
||||
</div>
|
||||
{{{neighbourlinks}}}
|
||||
@ -61,11 +66,13 @@
|
||||
{{#html.neighbourlinks}}{{{.}}}{{/html.neighbourlinks}}
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery', 'mod_forum/discussion', 'mod_forum/posts_list', 'mod_forum/lock_toggle'], function($, Discussion, PostsList, LockToggle) {
|
||||
var root = $("[data-content='forum-discussion']");
|
||||
Discussion.init(root);
|
||||
PostsList.init(root);
|
||||
var root = $('[data-container="discussion-tools"]');
|
||||
LockToggle.init(root);
|
||||
require(['jquery', 'mod_forum/discussion', 'mod_forum/posts_list', 'mod_forum/lock_toggle', 'mod_forum/favourite_toggle'],
|
||||
function($, Discussion, PostsList, LockToggle, FavouriteToggle) {
|
||||
var root = $("[data-content='forum-discussion']");
|
||||
Discussion.init(root);
|
||||
PostsList.init(root);
|
||||
var root = $('[data-container="discussion-tools"]');
|
||||
LockToggle.init(root);
|
||||
FavouriteToggle.init(root);
|
||||
});
|
||||
{{/js}}
|
||||
{{/js}}
|
Loading…
x
Reference in New Issue
Block a user