per-post comment control: select comment allowed audience and comments_closed date

This commit is contained in:
nobody 2020-11-23 19:14:44 -08:00
parent d0b14a3fd2
commit 7af12a1f7e
8 changed files with 127 additions and 8 deletions

View file

@ -58,8 +58,8 @@ class Permissions {
'view_contacts' => t('Grant viewing access to your address book (connections)'),
'view_storage' => t('Grant viewing access to your file storage and photos'),
'post_wall' => t('Grant permission to post on your channel (wall) page'),
'send_stream' => t('Accept delivery of their posts and all comments to their posts'),
'post_comments' => t('Accept delivery of their comments and likes on your posts'),
'send_stream' => t('Accept delivery of their posts and all comments to their posts from'),
'post_comments' => t('Accept delivery of comments and likes on your posts from'),
'write_storage' => t('Grant upload permissions to your file storage and photos'),
'republish' => t('Grant permission to republish/mirror your posts'),
'moderated' => t('Accept comments and wall posts only after approval (moderation)'),

View file

@ -347,6 +347,7 @@ class Apps {
'Tasks' => t('Tasks'),
'Tagadelic' => t('Tagadelic'),
'No Comment' => t('No Comment'),
'Comment Control' => t('Comment Control'),
'Directory' => t('Directory'),
'Help' => t('Help'),
'Mail' => t('Mail'),

View file

@ -0,0 +1,28 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libsync;
use Zotlabs\Web\Controller;
class Comment_control extends Controller {
function get() {
$desc = t('This app allows you to select the comment audience and set a length of time that comments on a particular post will be accepted.');
$text = '<div class="section-content-info-wrapper">' . $desc . '</div>';
if(! ( local_channel() && Apps::system_app_installed(local_channel(),'Comment Control'))) {
return $text;
}
$desc = t('This app is installed. A button to control comments may be found below the post editor.');
$text = '<div class="section-content-info-wrapper">' . $desc . '</div>';
return $text;
}
}

View file

@ -293,7 +293,6 @@ class Item extends Controller {
$token = EMPTY_STR;
$datarray = [];
/**
* Is this a reply to something?
*/
@ -302,6 +301,7 @@ class Item extends Controller {
$parent_mid = ((x($_REQUEST,'parent_mid')) ? trim($_REQUEST['parent_mid']) : '');
$hidden_mentions = ((x($_REQUEST,'hidden_mentions')) ? trim($_REQUEST['hidden_mentions']) : '');
$comments_closed = ((x($_REQUEST,'comments_closed')) ? datetime_convert(date_default_timezone_get(),'UTC',$_REQUEST['comments_closed']) : NULL_DATE);
/**
* Who is viewing this page and posting this thing
@ -334,8 +334,8 @@ class Item extends Controller {
$api_source = ((x($_REQUEST,'api_source') && $_REQUEST['api_source']) ? true : false);
$nocomment = intval($_REQUEST['nocomment']);
$nocomment = intval($_REQUEST['nocomment']);
$is_poll = ((trim($_REQUEST['poll_answers'][0]) != '' && trim($_REQUEST['poll_answers'][1]) != '') ? true : false);
// 'origin' (if non-zero) indicates that this network is where the message originated,
@ -644,7 +644,7 @@ class Item extends Controller {
$acl = new AccessControl($channel);
$view_policy = PermissionLimits::Get($channel['channel_id'],'view_stream');
$comment_policy = PermissionLimits::Get($channel['channel_id'],'post_comments');
$comment_policy = ((isset($_REQUEST['comments_from'])) ? intval($_REQUEST['comments_from']) : PermissionLimits::Get($channel['channel_id'],'post_comments'));
$public_policy = ((x($_REQUEST,'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($view_policy,true));
if($webpage)
@ -1154,7 +1154,6 @@ class Item extends Controller {
$obj = $this->extract_bb_poll_data($body,[ 'item_private' => $private, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_contact_deny ]);
}
$comments_closed = NULL_DATE;
if ($obj) {
$obj['url'] = $mid;

6
app/comment_control.apd Normal file
View file

@ -0,0 +1,6 @@
version: 1
url: $baseurl/comment_control
requires: local_channel
name: Comment Control
photo: icon:comment-o
categories: Social

View file

@ -5,6 +5,9 @@ use Zotlabs\Lib\LibBlock;
use Zotlabs\Lib\ThreadStream;
use Zotlabs\Lib\ThreadItem;
use Zotlabs\Lib\Chatroom;
use Zotlabs\Access\Permissions;
use Zotlabs\Access\PermissionLimits;
function item_extract_images($body) {
@ -1248,6 +1251,12 @@ function z_status_editor($a, $x, $popup = false) {
if(x($x, 'disable_comments'))
$feature_nocomment = false;
$feature_comment_control = Apps::system_app_installed($x['profile_uid'], 'Comment Control');
if(x($x, 'disable_comment_control'))
$feature_comment_control = false;
$feature_expire = ((Apps::system_app_installed($x['profile_uid'], 'Expire Posts') && (! $webpage)) ? true : false);
if(x($x, 'hide_expire'))
$feature_expire = false;
@ -1366,6 +1375,48 @@ function z_status_editor($a, $x, $popup = false) {
else
$catsenabled = ((Apps::system_app_installed($x['profile_uid'], 'Categories') && (! $webpage)) ? 'categories' : '');
// we only need the comment_perms for the editor, but this logic is complicated enough (from Settings/Channel)
// that we will just duplicate the entire code block
$global_perms = Permissions::Perms();
$permiss = [];
$perm_opts = [
array( t('Nobody except yourself'), 0),
array( t('Only those you specifically allow'), PERMS_SPECIFIC),
array( t('Approved connections'), PERMS_CONTACTS),
array( t('Any connections'), PERMS_PENDING),
array( t('Anybody on this website'), PERMS_SITE),
array( t('Anybody in this network'), PERMS_NETWORK),
array( t('Anybody authenticated'), PERMS_AUTHED),
array( t('Anybody on the internet'), PERMS_PUBLIC)
];
$limits = PermissionLimits::Get(local_channel());
$anon_comments = get_config('system','anonymous_comments',true);
foreach($global_perms as $k => $perm) {
$options = [];
$can_be_public = ((strstr($k,'view') || ($k === 'post_comments' && $anon_comments)) ? true : false);
foreach($perm_opts as $opt) {
if($opt[1] == PERMS_PUBLIC && (! $can_be_public))
continue;
$options[$opt[1]] = $opt[0];
}
if($k === 'view_stream') {
$options = [$perm_opts[7][1] => $perm_opts[7][0]];
}
if($k === 'post_comments') {
$comment_perms = [ $k, t('Accept delivery of comments and likes on this post from'), $limits[$k],'',$options ];
}
else {
$permiss[] = array($k,$perm,$limits[$k],'',$options);
}
}
// avoid illegal offset errors
if(! array_key_exists('permissions',$x))
$x['permissions'] = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
@ -1423,6 +1474,11 @@ function z_status_editor($a, $x, $popup = false) {
'$nocommenttitle' => t('Disable comments'),
'$nocommenttitlesub' => t('Toggle comments'),
'$feature_nocomment' => $feature_nocomment,
'$feature_comment_control' => $feature_comment_control,
'$commctrl' => t('Comment Control'),
'$comments_closed' => (($x['item']['comments_closed']) ? $x['item']['comments_closed'] : ''),
'$commclosedate' => t('Disable comments after (date)'),
'$comment_perms' => $comment_perms,
'$nocomment' => ((array_key_exists('item',$x)) ? $x['item']['item_nocomment'] : 0),
'$clearloc' => $clearloc,
'$title' => ((x($x, 'title')) ? htmlspecialchars($x['title'], ENT_COMPAT,'UTF-8') : ''),
@ -1467,6 +1523,8 @@ function z_status_editor($a, $x, $popup = false) {
'$cipher' => $cipher,
'$expiryModalOK' => t('OK'),
'$expiryModalCANCEL' => t('Cancel'),
'$commModalOK' => t('OK'),
'$commModalCANCEL' => t('Cancel'),
'$linkModalOK' => t('OK'),
'$linkModalCANCEL' => t('Cancel'),
'$close' => t('Close'),

View file

@ -272,6 +272,23 @@ var activeCommentText = '';
})
}
function jotGetCommCtrl() {
$('#commModal').modal();
$('#comm-modal-OKButton').on('click', function() {
var post_comments = $('#post_comments').val();
if (post_comments && post_comments.length) {
$('#jot-commfrom').val(post_comments);
}
var reply=$('#commclose-date').val();
if(reply && reply.length) {
$('#jot-commclosed').val(reply);
}
$('#commModal').modal('hide');
})
}
function jotGetPubDate() {
$('#createdModal').modal();
$('#created-modal-OKButton').on('click', function() {

View file

@ -18,6 +18,8 @@
<input type="hidden" name="return" value="{{$return_path}}" />
<input type="hidden" name="location" id="jot-location" value="{{$defloc}}" />
<input type="hidden" name="expire" id="jot-expire" value="{{$defexpire}}" />
<input type="hidden" name="comments_closed" id="jot-commclosed" value="{{$defexpire}}" />
<input type="hidden" name="comments_from" id="jot-commfrom" value="{{$defexpire}}" />
<input type="hidden" name="created" id="jot-created" value="{{$defpublish}}" />
<input type="hidden" name="media_str" id="jot-media" value="" />
<input type="hidden" name="source" id="jot-source" value="{{$source}}" />
@ -146,6 +148,13 @@
<i id="profile-expires" class="fa fa-eraser jot-icons"></i>
</button>
{{/if}}
{{if $feature_comment_control}}
<button id="profile-commctrl-wrapper" class="btn btn-outline-secondary btn-sm" title="{{$commctrl}}" onclick="jotGetCommCtrl();return false;">
<i id="profile-commctrl" class="fa fa-comment-o jot-icons"></i>
</button>
{{/if}}
{{if $feature_future}}
<button id="profile-future-wrapper" class="btn btn-outline-secondary btn-sm" title="{{$future_txt}}" onclick="jotGetPubDate();return false;">
<i id="profile-future" class="fa fa-clock-o jot-icons"></i>
@ -300,6 +309,7 @@
{{include file="field_select.tpl" field=$comment_perms}}
<div class="date">
<label for="id_oembed">{{$commclosedate}}</label>
<input type="text" placeholder="yyyy-mm-dd HH:MM" name="start_text" value="{{$comments_closed}}" id="commclose-date" class="form-control" />
</div>
<script>
@ -310,7 +320,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">{{$commModalCANCEL}}</button>
<button id="expiry-modal-OKButton" type="button" class="btn btn-primary">{{$commModalOK}}</button>
<button id="comm-modal-OKButton" type="button" class="btn btn-primary">{{$commModalOK}}</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->