Merge pull request #9125 from MrPetovan/bug/8999-fix-new-pm
Fix new private message recipient input
This commit is contained in:
commit
560746eb3b
11 changed files with 106 additions and 197 deletions
|
@ -28,6 +28,7 @@ use Friendica\Core\Logger;
|
|||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\Theme;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
|
@ -354,6 +355,13 @@ function conv_get_blocklist()
|
|||
*/
|
||||
function conversation(App $a, array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0)
|
||||
{
|
||||
$page = DI::page();
|
||||
|
||||
$page->registerFooterScript(Theme::getPathForFile('asset/typeahead.js/dist/typeahead.bundle.js'));
|
||||
$page->registerFooterScript(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.js'));
|
||||
$page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.css'));
|
||||
$page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput-typeahead.css'));
|
||||
|
||||
$ssl_state = (local_user() ? true : false);
|
||||
|
||||
$profile_owner = 0;
|
||||
|
|
|
@ -74,7 +74,7 @@ function message_post(App $a)
|
|||
$replyto = !empty($_REQUEST['replyto']) ? Strings::escapeTags(trim($_REQUEST['replyto'])) : '';
|
||||
$subject = !empty($_REQUEST['subject']) ? Strings::escapeTags(trim($_REQUEST['subject'])) : '';
|
||||
$body = !empty($_REQUEST['body']) ? Strings::escapeHtml(trim($_REQUEST['body'])) : '';
|
||||
$recipient = !empty($_REQUEST['messageto']) ? intval($_REQUEST['messageto']) : 0;
|
||||
$recipient = !empty($_REQUEST['recipient']) ? intval($_REQUEST['recipient']) : 0;
|
||||
|
||||
$ret = Mail::send($recipient, $body, $subject, $replyto);
|
||||
$norecip = false;
|
||||
|
@ -215,50 +215,14 @@ function message_content(App $a)
|
|||
'$linkurl' => DI::l10n()->t('Please enter a link URL:')
|
||||
]);
|
||||
|
||||
$preselect = isset($a->argv[2]) ? [$a->argv[2]] : [];
|
||||
$recipientId = $a->argv[2] ?? null;
|
||||
|
||||
$prename = $preurl = $preid = '';
|
||||
|
||||
if ($preselect) {
|
||||
$r = q("SELECT `name`, `url`, `id` FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
|
||||
intval(local_user()),
|
||||
intval($a->argv[2])
|
||||
);
|
||||
if (!DBA::isResult($r)) {
|
||||
$r = q("SELECT `name`, `url`, `id` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' LIMIT 1",
|
||||
intval(local_user()),
|
||||
DBA::escape(Strings::normaliseLink(base64_decode($a->argv[2])))
|
||||
);
|
||||
}
|
||||
|
||||
if (!DBA::isResult($r)) {
|
||||
$r = q("SELECT `name`, `url`, `id` FROM `contact` WHERE `uid` = %d AND `addr` = '%s' LIMIT 1",
|
||||
intval(local_user()),
|
||||
DBA::escape(base64_decode($a->argv[2]))
|
||||
);
|
||||
}
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$prename = $r[0]['name'];
|
||||
$preid = $r[0]['id'];
|
||||
$preselect = [$preid];
|
||||
} else {
|
||||
$preselect = [];
|
||||
}
|
||||
}
|
||||
|
||||
$prefill = $preselect ? $prename : '';
|
||||
|
||||
// the ugly select box
|
||||
$select = ACL::getMessageContactSelectHTML('messageto', 'message-to-select', $preselect, 4, 10);
|
||||
$select = ACL::getMessageContactSelectHTML($recipientId);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('prv_message.tpl');
|
||||
$o .= Renderer::replaceMacros($tpl, [
|
||||
'$header' => DI::l10n()->t('Send Private Message'),
|
||||
'$to' => DI::l10n()->t('To:'),
|
||||
'$showinputs' => 'true',
|
||||
'$prefill' => $prefill,
|
||||
'$preid' => $preid,
|
||||
'$subject' => DI::l10n()->t('Subject:'),
|
||||
'$subjtxt' => $_REQUEST['subject'] ?? '',
|
||||
'$text' => $_REQUEST['body'] ?? '',
|
||||
|
@ -413,7 +377,7 @@ function message_content(App $a)
|
|||
$seen = $message['seen'];
|
||||
}
|
||||
|
||||
$select = $message['name'] . '<input type="hidden" name="messageto" value="' . $contact_id . '" />';
|
||||
$select = $message['name'] . '<input type="hidden" name="recipient" value="' . $contact_id . '" />';
|
||||
$parent = '<input type="hidden" name="replyto" value="' . $message['parent-uri'] . '" />';
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('mail_display.tpl');
|
||||
|
@ -429,7 +393,6 @@ function message_content(App $a)
|
|||
// reply
|
||||
'$header' => DI::l10n()->t('Send Reply'),
|
||||
'$to' => DI::l10n()->t('To:'),
|
||||
'$showinputs' => '',
|
||||
'$subject' => DI::l10n()->t('Subject:'),
|
||||
'$subjtxt' => $message['title'],
|
||||
'$readonly' => ' readonly="readonly" style="background: #BBBBBB;" ',
|
||||
|
|
|
@ -33,75 +33,52 @@ use Friendica\Model\Group;
|
|||
class ACL
|
||||
{
|
||||
/**
|
||||
* Returns a select input tag with all the contact of the local user
|
||||
* Returns a select input tag for private message recipient
|
||||
*
|
||||
* @param string $selname Name attribute of the select input tag
|
||||
* @param string $selclass Class attribute of the select input tag
|
||||
* @param array $preselected Contact IDs that should be already selected
|
||||
* @param int $size Length of the select box
|
||||
* @param int $tabindex Select input tag tabindex attribute
|
||||
* @param int $selected Existing recipien contact ID
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getMessageContactSelectHTML($selname, $selclass, array $preselected = [], $size = 4, $tabindex = null)
|
||||
public static function getMessageContactSelectHTML(int $selected = null)
|
||||
{
|
||||
$a = DI::app();
|
||||
|
||||
$o = '';
|
||||
|
||||
$page = DI::page();
|
||||
|
||||
$page->registerFooterScript(Theme::getPathForFile('asset/typeahead.js/dist/typeahead.bundle.js'));
|
||||
$page->registerFooterScript(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.js'));
|
||||
$page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.css'));
|
||||
$page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput-typeahead.css'));
|
||||
|
||||
// When used for private messages, we limit correspondence to mutual DFRN/Friendica friends and the selector
|
||||
// to one recipient. By default our selector allows multiple selects amongst all contacts.
|
||||
$sql_extra = sprintf(" AND `rel` = %d ", intval(Contact::FRIEND));
|
||||
$sql_extra .= sprintf(" AND `network` IN ('%s' , '%s') ", Protocol::DFRN, Protocol::DIASPORA);
|
||||
$condition = [
|
||||
'uid' => local_user(),
|
||||
'self' => false,
|
||||
'blocked' => false,
|
||||
'pending' => false,
|
||||
'archive' => false,
|
||||
'deleted' => false,
|
||||
'rel' => [Contact::FOLLOWER, Contact::SHARING, Contact::FRIEND],
|
||||
'network' => Protocol::FEDERATED,
|
||||
];
|
||||
|
||||
$tabindex_attr = !empty($tabindex) ? ' tabindex="' . intval($tabindex) . '"' : '';
|
||||
|
||||
$hidepreselected = '';
|
||||
if ($preselected) {
|
||||
$sql_extra .= " AND `id` IN (" . implode(",", $preselected) . ")";
|
||||
$hidepreselected = ' style="display: none;"';
|
||||
}
|
||||
|
||||
$o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"$size\"$tabindex_attr$hidepreselected>\r\n";
|
||||
|
||||
$stmt = DBA::p("SELECT `id`, `name`, `url`, `network` FROM `contact`
|
||||
WHERE `uid` = ? AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND NOT `deleted` AND `notify` != ''
|
||||
$sql_extra
|
||||
ORDER BY `name` ASC ", intval(local_user())
|
||||
$contacts = Contact::selectToArray(
|
||||
['id', 'name', 'addr', 'micro'],
|
||||
DBA::mergeConditions($condition, ["`notify` != ''"])
|
||||
);
|
||||
|
||||
$contacts = DBA::toArray($stmt);
|
||||
|
||||
$arr = ['contact' => $contacts, 'entry' => $o];
|
||||
|
||||
// e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
|
||||
Hook::callAll(DI::module()->getName() . '_pre_' . $selname, $arr);
|
||||
Hook::callAll(DI::module()->getName() . '_pre_recipient', $arr);
|
||||
|
||||
$receiverlist = [];
|
||||
$tpl = Renderer::getMarkupTemplate('acl/message_recipient.tpl');
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$contacts' => $contacts,
|
||||
'$selected' => $selected,
|
||||
]);
|
||||
|
||||
if (DBA::isResult($contacts)) {
|
||||
foreach ($contacts as $contact) {
|
||||
if (in_array($contact['id'], $preselected)) {
|
||||
$selected = ' selected="selected"';
|
||||
} else {
|
||||
$selected = '';
|
||||
}
|
||||
|
||||
$trimmed = Protocol::formatMention($contact['url'], $contact['name']);
|
||||
|
||||
$receiverlist[] = $trimmed;
|
||||
|
||||
$o .= "<option value=\"{$contact['id']}\"$selected title=\"{$contact['name']}|{$contact['url']}\" >$trimmed</option>\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
$o .= '</select>' . PHP_EOL;
|
||||
|
||||
if ($preselected) {
|
||||
$o .= implode(', ', $receiverlist);
|
||||
}
|
||||
|
||||
Hook::callAll(DI::module()->getName() . '_post_' . $selname, $o);
|
||||
Hook::callAll(DI::module()->getName() . '_post_recipient', $o);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
@ -303,7 +280,7 @@ class ACL
|
|||
'emailcc' => $form_prefix ? $form_prefix . '[emailcc]' : 'emailcc',
|
||||
];
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('acl_selector.tpl');
|
||||
$tpl = Renderer::getMarkupTemplate('acl/full_selector.tpl');
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$public_title' => DI::l10n()->t('Public'),
|
||||
'$public_desc' => DI::l10n()->t('This content will be shown to all your followers and can be seen in the community pages and by anyone with its link.'),
|
||||
|
|
|
@ -32,6 +32,7 @@ use Friendica\Core\ACL;
|
|||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Theme;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
|
@ -259,9 +260,12 @@ class Contact extends BaseModule
|
|||
$rel = Strings::escapeTags(trim($_GET['rel'] ?? ''));
|
||||
$group = Strings::escapeTags(trim($_GET['group'] ?? ''));
|
||||
|
||||
if (empty(DI::page()['aside'])) {
|
||||
DI::page()['aside'] = '';
|
||||
}
|
||||
$page = DI::page();
|
||||
|
||||
$page->registerFooterScript(Theme::getPathForFile('asset/typeahead.js/dist/typeahead.bundle.js'));
|
||||
$page->registerFooterScript(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.js'));
|
||||
$page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.css'));
|
||||
$page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput-typeahead.css'));
|
||||
|
||||
$contact = null;
|
||||
// @TODO: Replace with parameter from router
|
||||
|
|
|
@ -155,7 +155,7 @@
|
|||
acl.initialize();
|
||||
|
||||
let suggestionTemplate = function (item) {
|
||||
return '<div><img src="' + item.micro + '" alt="" style="float: left; width: auto; height: 2.8em; margin-right: 0.5em;"> <strong>' + item.name + '</strong><br /><em>' + item.addr + '</em></div>';
|
||||
return '<div><img src="' + item.micro + '" alt="" style="float: left; width: auto; height: 2.8em; margin-right: 0.5em;"><p style="margin-left: 3.3em;"><strong>' + item.name + '</strong><br /><em>' + item.addr + '</em></p></div>';
|
||||
};
|
||||
|
||||
$acl_allow_input.tagsinput({
|
54
view/templates/acl/message_recipient.tpl
Normal file
54
view/templates/acl/message_recipient.tpl
Normal file
|
@ -0,0 +1,54 @@
|
|||
<select name="recipient" class="form-control input-lg" id="recipient">
|
||||
{{foreach $contacts as $contact}}
|
||||
<option value="{{$contact.id}}"{{if $contact.id == $selected}} selected{{/if}}>{{$contact.name}}</option>
|
||||
{{/foreach}}
|
||||
</select>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
let $recipient_input = $('[name="recipient"]');
|
||||
|
||||
let acl = new Bloodhound({
|
||||
local: {{$contacts|@json_encode nofilter}},
|
||||
identify: function(obj) { return obj.id.toString(); },
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name', 'addr']),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
sorter: function (itemA, itemB) {
|
||||
if (itemA.name === itemB.name) {
|
||||
return 0;
|
||||
} else if (itemA.name > itemB.name) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
});
|
||||
acl.initialize();
|
||||
|
||||
let suggestionTemplate = function (item) {
|
||||
return '<div><img src="' + item.micro + '" alt="" style="float: left; width: auto; height: 2.8em; margin-right: 0.5em;"><p style="margin-left: 3.3em;"><strong>' + item.name + '</strong><br /><em>' + item.addr + '</em></p></div>';
|
||||
};
|
||||
|
||||
$recipient_input.tagsinput({
|
||||
confirmKeys: [13, 44],
|
||||
freeInput: false,
|
||||
tagClass: 'label label-info',
|
||||
itemValue: function (item) { return item.id.toString(); },
|
||||
itemText: 'name',
|
||||
itemThumb: 'micro',
|
||||
itemTitle: function(item) {
|
||||
return item.addr;
|
||||
},
|
||||
typeaheadjs: {
|
||||
name: 'contacts',
|
||||
displayKey: 'name',
|
||||
templates: {
|
||||
suggestion: suggestionTemplate
|
||||
},
|
||||
source: acl.ttAdapter()
|
||||
}
|
||||
});
|
||||
|
||||
// Import existing ACL into the tags input fields.
|
||||
$recipient_input.tagsinput('add', acl.get({{$selected}})[0]);
|
||||
});
|
||||
</script>
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#recip").name_autocomplete(baseurl + '/search/acl', 'm', false, function(data) {
|
||||
$("#recip-complete").val(data.id);
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -3228,9 +3228,6 @@ div.jGrowl div.info {
|
|||
width:100px;
|
||||
}
|
||||
|
||||
#recip {
|
||||
|
||||
}
|
||||
.autocomplete-w1 { background: #ffffff no-repeat bottom right; position:absolute; top:0px; left:0px; margin:6px 0 0 6px; /* IE6 fix: */ _background:none; _margin:1px 0 0 0; }
|
||||
.autocomplete { color:#000; border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE6 specific: */ _height:350px; _margin:0; _overflow-x:hidden; }
|
||||
.autocomplete .selected { background:#F0F0F0; }
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
|
||||
|
||||
<h3>{{$header}}</h3>
|
||||
|
||||
<div id="prvmail-wrapper" >
|
||||
<form id="prvmail-form" action="message" method="post" >
|
||||
|
||||
{{$parent nofilter}}
|
||||
|
||||
<div id="prvmail-to-label">{{$to}}</div>
|
||||
|
||||
{{if $showinputs}}
|
||||
<input type="text" id="recip" name="messagerecip" value="{{$prefill}}" maxlength="255" size="64" tabindex="10" />
|
||||
<input type="hidden" id="recip-complete" name="messageto" value="{{$preid}}">
|
||||
{{else}}
|
||||
{{$select nofilter}}
|
||||
{{/if}}
|
||||
|
||||
<div id="prvmail-subject-label">{{$subject}}</div>
|
||||
<input type="text" size="64" maxlength="255" id="prvmail-subject" name="subject" value="{{$subjtxt}}" {{$readonly}} tabindex="11" />
|
||||
|
||||
<div id="prvmail-message-label">{{$yourmessage}}</div>
|
||||
<textarea rows="8" cols="72" class="prvmail-text" id="prvmail-text" name="body" tabindex="12">{{$text}}</textarea>
|
||||
|
||||
|
||||
<div id="prvmail-submit-wrapper" >
|
||||
<input type="submit" id="prvmail-submit" name="submit" value="{{$submit}}" tabindex="13" />
|
||||
<div id="prvmail-upload-wrapper" >
|
||||
<div id="prvmail-upload" class="icon border camera" title="{{$upload}}" ></div>
|
||||
</div>
|
||||
<div id="prvmail-link-wrapper" >
|
||||
<div id="prvmail-link" class="icon border link" title="{{$insert}}" onclick="jotGetLink();" ></div>
|
||||
</div>
|
||||
<div id="prvmail-rotator-wrapper" >
|
||||
<img id="prvmail-rotator" src="images/rotator.gif" alt="{{$wait}}" title="{{$wait}}" style="display: none;" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="prvmail-end"></div>
|
||||
</form>
|
||||
</div>
|
|
@ -2,21 +2,12 @@
|
|||
<div id="prvmail-wrapper">
|
||||
<form id="prvmail-form" action="message" method="post" >
|
||||
|
||||
{{* Disable the header. We will see if we will need it
|
||||
<h3>{{$header}}</h3>
|
||||
*}}
|
||||
|
||||
{{$parent nofilter}}
|
||||
|
||||
{{* The To: form-group which contains the message recipient *}}
|
||||
<div id="prvmail-to-label" class="form-group">
|
||||
<label for="recip">{{$to}}</label><br>
|
||||
{{if $showinputs}}
|
||||
<input type="text" id="recip" class="form-control" name="messagerecip" value="{{$prefill}}" tabindex="10" {{if $prefill}}disabled{{else}}aria-required="true"{{/if}} />
|
||||
<input type="hidden" id="recip-complete" name="messageto" value="{{$preid}}">
|
||||
{{else}}
|
||||
<label for="recipient">{{$to}}</label><br>
|
||||
{{$select nofilter}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{* The subject input field *}}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
<h3>{{$header}}</h3>
|
||||
|
||||
<div id="prvmail-wrapper" >
|
||||
<form id="prvmail-form" action="message" method="post" >
|
||||
|
||||
{{$parent nofilter}}
|
||||
|
||||
<div id="prvmail-to-label">{{$to}}</div>
|
||||
{{if $showinputs}}
|
||||
<input type="text" id="recip" name="messagerecip" value="{{$prefill}}" maxlength="255" size="64" tabindex="10" />
|
||||
<input type="hidden" id="recip-complete" name="messageto" value="{{$preid}}">
|
||||
{{else}}
|
||||
{{$select nofilter}}
|
||||
{{/if}}
|
||||
|
||||
<div id="prvmail-subject-label">{{$subject}}</div>
|
||||
<input type="text" size="64" maxlength="255" id="prvmail-subject" name="subject" value="{{$subjtxt}}" {{$readonly}} tabindex="11" />
|
||||
|
||||
<div id="prvmail-message-label">{{$yourmessage}}</div>
|
||||
<textarea rows="20" cols="72" class="prvmail-text" id="prvmail-text" name="body" tabindex="12">{{$text}}</textarea>
|
||||
|
||||
|
||||
<div id="prvmail-submit-wrapper" >
|
||||
<input type="submit" id="prvmail-submit" name="submit" value="{{$submit}}" tabindex="13" />
|
||||
<div id="prvmail-upload-wrapper" >
|
||||
<div id="prvmail-upload" class="icon border camera" title="{{$upload}}" ></div>
|
||||
</div>
|
||||
<div id="prvmail-link-wrapper" >
|
||||
<div id="prvmail-link" class="icon border link" title="{{$insert}}" onclick="jotGetLink();" ></div>
|
||||
</div>
|
||||
<div id="prvmail-rotator-wrapper" >
|
||||
<img id="prvmail-rotator" src="images/rotator.gif" alt="{{$wait}}" title="{{$wait}}" style="display: none;" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="prvmail-end"></div>
|
||||
</form>
|
||||
</div>
|
Loading…
Reference in a new issue