Adjust copyrights years
<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009 - 2023 Chris Pollett chris@pollett.org
*
* LICENSE:
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
* END LICENSE
*
* @author Chris Pollett chris@pollett.org
* @license https://www.gnu.org/licenses/ GPL3
* @link https://www.seekquarry.com/
* @copyright 2009 - 2023
* @filesource
*/
namespace seekquarry\yioop\views\elements;
use seekquarry\yioop as B;
use seekquarry\yioop\configs as C;
use seekquarry\yioop\library as L;
use seekquarry\yioop\library\CrawlConstants;
/**
* Element responsible for draw the feeds a user is subscribed to
*
* @author Chris Pollett
*/
class UsermessagesElement extends Element implements CrawlConstants
{
/**
* Emojipicker helper
* @var helper
*/
public $emoji_helper;
/**
* constructor stores a reference to the view this element will reside on
*
* @param object $view object this element will reside on
*/
public function __construct($view = null)
{
parent::__construct($view);
$this->emoji_helper = $this->view->helper('emojipicker');
}
/**
*
*
* @param array
*/
public function render($data)
{
$is_mobile = !empty($data['MOBILE']);
if (!empty($data['STATUS'])) {
if (!empty($data['MESSAGES'])) {
$this->renderContactMessages($data);
}
return;
}
?>
<div class="messages-container"><?php
if ($is_mobile && empty($data['CONTACT_ID']) || !$is_mobile) { ?>
<div class="user-contacts">
<div style="margin:9px auto 5px auto;width:2.25in;">
<?php
$this->view->element("socialcontrols")->render($data); ?></div>
<?=$this->renderContacts($data); ?>
</div><?php
}
if (!$is_mobile) {
?>
<div class="split-adjuster" id="split-adjuster">
</div><?php
}
if (!$is_mobile || $is_mobile && !empty($data['CONTACT_ID'])) {?>
<div class="contact-messages"><?php
if (empty($data['CONTACT_ID'])) { ?>
<div class="user-messages-warning">
<?= tl("usermessages_element_select_contact") ?>
</div><?php
} else {
$this->renderContactMessages($data);
} ?>
</div><?php
}?>
</div>
<?php
}
/**
*
* @param array
*/
public function renderContacts($data)
{
?>
<form class="center">
<input type="hidden" name='<?=C\CSRF_TOKEN?>'
value='<?=$data[C\CSRF_TOKEN]?>' >
<input type="hidden" name='a' value='userMessages' >
<input type="hidden" name='c' value='<?=$data['CONTROLLER'] ?>' >
<div class="contact-actions" tabindex="1">
<input type="search" name='contact_name'
class="narrow-field" autocomplete="off"
placeholder="<?=tl('usermessages_element_contact_filter')?>"
id='contact-filter' value="<?=$data['CONTACT_FILTER'] ?? '' ?>"
><br>
<button type='submit' name='arg' value="search"
class="button-box"><?=
tl('usermessages_element_search') ?></button>
<button type='submit' name='arg' value="addcontact"
class="button-box"><?=
tl('usermessages_element_add_contact') ?></button>
</div>
</form>
<?php
$token_string = C\CSRF_TOKEN . "=". $data[C\CSRF_TOKEN];
foreach ($data['CONTACTS'] as $contact_id => $contact_info) {
$selected = ($contact_id == $data['CONTACT_ID']) ?
" selected-contact " : "";
?>
<div class="contact-detail <?=$selected?>" tabindex="0"
onclick="javascript:elt('contact-id-<?=$contact_id
?>').click()"><?php
if ($contact_info['NUM_UNREAD_MESSAGES'] > 0) {?>
<div class='unread-messages'><?=
$contact_info['NUM_UNREAD_MESSAGES'] ?></div><?php
}?>
<div class="contact-detail-inner">
<img class="message-icon" src="<?=
$contact_info["ICON_URL"]; ?>"
alt="<?=tl('usermessages_element_user_icon'); ?>" >
<a id="contact-id-<?=$contact_id
?>" href="<?=$this->formatHref(B\feedsUrl('user_messages',
$contact_id, true, $data['CONTROLLER']) .
$token_string)?>"><?=
$contact_info["USER_NAME"]; ?></a>
</div>
</div>
<?php
}
if (!empty($data['CONTACT_REQUESTS'])) {
$request_options = [
"addcontact" => tl('usermessages_element_accept'),
"blockcontact" => tl('usermessages_element_block'),
"ignorecontact" => tl('usermessages_element_ignore'),
];
foreach ($data['CONTACT_REQUESTS'] as $contact_id => $contact_info){
$contact_request_url = B\feedsUrl('user_messages',
$contact_id, true, $data['CONTROLLER']) .
$token_string . "&contact_id=$contact_id&arg=";
?>
<div class="contact-detail">
<div class="contact-detail-inner">
<img class="message-icon" src="<?=
$contact_info["ICON_URL"]; ?>"
alt="<?=tl('usermessages_element_user_icon'); ?>" >
<span><?= $contact_info["USER_NAME"]; ?></span>
</div>
</div>
<div class="contact-detail-request float-opposite">
<?php
$this->view->helper("options")->renderLinkDropDown(
"request-options$contact_id", $request_options,
'', $contact_request_url,
false, "",
tl('usermessages_element_request'));
?>
</div>
<?php
}
}
if (empty($data['CONTACTS']) && empty($data['CONTACT_REQUESTS'])) { ?>
<div class="user-messages-warning">
<?= tl("usermessages_element_no_contacts") ?>
</div>
<?php
}
}
/**
*
* @param array
*/
public function renderContactMessages($data)
{
$logged_in = !empty($data["ADMIN"]);
$token_string = ($logged_in) ? C\CSRF_TOKEN . "=" . $data[C\CSRF_TOKEN]
: "";
$messages_url = B\controllerUrl("user_messages", true) .
$token_string;
if (empty($data['MESSAGES'])) { ?>
<div class="user-messages-warning">
<?= tl("usermessages_element_no_messages") ?>
</div><?php
} else {?>
<div class="selected-conversation-header"><?php
if (!empty($data['MOBILE'])) {
$arrow = ($data['LOCALE_DIR'] == 'rtl') ? ">" : "<";
?>
<a class="float-same contacts-arrow" href="<?=
$messages_url?>"><?=$arrow ?></a>
<?php
}
$now = time();
?>
<h2>
<img class="message-icon" src="<?=
$data["CONTACT_ICON_URL"]; ?>"
alt="<?=tl('usermessages_element_user_icon'); ?>" >
<span><?= $data['CONTACT_NAME'] ?></span>
</h2>
</div>
<div id="conversation" class="conversation" data-time="<?=
$now?>" ><?php
$old_pubdate = $now;
$old_user = $data['MESSAGES'][0]['USER_NAME'] ?? "";
$num_messages = count($data['MESSAGES']);
for ($i = 0; $i < $num_messages; $i++) {
$message_info = $data['MESSAGES'][$i];
$next_message_info = $data['MESSAGES'][$i + 1] ?? $message_info;
$next_user_name = $next_message_info['USER_NAME'];
if (empty($message_info[self::DESCRIPTION])) {
continue;
}
$pub_date = $message_info['PUBDATE'];
$next_pub_date = $next_message_info['PUBDATE'];
$pub_date_diff = abs($next_pub_date - $pub_date);
$pub_date_age = $now - $pub_date;
$user_change = $message_info['USER_NAME'] != $next_user_name;
$pub_data_change = $user_change ||($pub_date_age < C\ONE_HOUR &&
$pub_date_diff > 5 * C\ONE_MINUTE) ||
($pub_date_age < C\ONE_DAY && $pub_date_diff > C\ONE_HOUR)||
($pub_date_diff > C\ONE_DAY);
$pub_date_string =
$this->view->helper("feeds")->getPubdateString(
$now, $pub_date, false);
$color = "back-light-gray";
$align = "align-same";
$is_user = false;
$user_string = "other";
$top_corner = " top-corner ";
if ($data['USERNAME'] == $message_info['USER_NAME']) {
$color = "back-light-blue";
$align = "align-opposite";
$is_user = true;
$user_string = "user";
$top_corner = "";
}
$comma = "";
?>
<div class="<?=$align ?>">
<div class="message-detail-outer">
<div class='message-<?=$user_string?>-time' >
<?php
if (!$is_user && ($pub_data_change || $user_change)) {
e('<img class="message-icon float-same" src="'.
$message_info['USER_ICON'].'" > ');
$comma = ", ";
e($message_info['USER_NAME']);
}
if ($pub_data_change) {
e($comma . $pub_date_string);
}?>
</div>
<div class="message-detail <?=$color . $top_corner?>"><?=
$message_info[self::DESCRIPTION];
?>
</div>
</div>
</div>
<?php
}?>
</div><?php
}
$this->drawNewMessageForm($data);
}
/**
* Used to draw the new message form to add a message to an
* existing conversation
*
* @param array $data containing other field needed to draw the form
*/
private function drawNewMessageForm($data)
{
$arrow = ($data['LOCALE_DIR'] == 'rtl') ? "←" : "→";
?>
<div class="new-message-container">
<form id="newmessageForm" method="post" action="<?=C\SHORT_BASE_URL?>"
enctype='multipart/form-data' onsubmit="parseEmojiShortcuts()">
<input type="hidden" name="c" value="<?=$data['CONTROLLER'] ?>" >
<input type="hidden" name="a" value="userMessages" >
<input type="hidden" name="arg" value="newmessage" >
<input type="hidden" name="contact_id" value="<?=
$data['CONTACT_ID']; ?>" >
<input type="hidden" name="<?= C\CSRF_TOKEN ?>"
value="<?= $data[C\CSRF_TOKEN] ?>" >
<input type="file" id="file-new-message"
name="file_new_message" class="none" multiple="multiple" >
<a id="attach-new-file"
href="javascript:elt('file-new-message').click()"
>📎</a>
<span id="user-input-container">
<button id="emoji-picker-button" type="button"
style="filter: grayscale(100%);"
onclick="toggleEmojiPicker()">🙂</button>
<div class="emoji-picker-container" id="emoji-picker-container">
<?=$this->emoji_helper->render();?>
</div>
<input type="text" id="new-message" name="description"
placeholder="<?=tl('usermessages_element_new_message') ?>" >
</span>
<button type="submit" id="send-message" ><?=$arrow ?></button>
</form>
</div>
<script>
if (typeof yioop_post_scripts !== 'object' ) {
yioop_post_scripts = {};
}
yioop_post_scripts['new-message'] = function() {
initializeFileHandler('new-message', "file-new-message",
<?= min(L\metricToInt(ini_get('upload_max_filesize')),
L\metricToInt(ini_get('post_max_size')))
?>, "textarea", null, true);
}
const emoji_groups = <?php echo
json_encode($this->emoji_helper->emoji_groups); ?>;
let emojis_array = {};
for (const group in emoji_groups) {
let group_data = emoji_groups[group];
for (const emoji in group_data["emojis"]) {
emojis_array[emoji] = group_data["emojis"][emoji][0];
}
}
function insertEmoji(emoji)
{
let input = elt('new-message');
input.value += emoji;
}
function toggleEmojiPicker()
{
let emoji_picker = elt('emoji-picker-container');
let emoji_picker_button = elt('emoji-picker-button');
if (emoji_picker.style.display === "none"
|| emoji_picker.style.display === "") {
emoji_picker.style.display = "inline-block";
emoji_picker_button.innerHTML = "🔽";
} else {
emoji_picker.style.display = "none";
emoji_picker_button.innerHTML = "🙂";
}
}
function toggleEmojiGroup(emoji_grp_tab, emoji_grp_name)
{
let emoji_grp_id = "emoji-group-" + emoji_grp_name;
let emoji_groups =
document.getElementsByClassName("emoji-group-container");
for (let i=0;i<emoji_groups.length;i++) {
if (emoji_groups[i].id === emoji_grp_id) {
emoji_groups[i].className += " active-emoji-group";
} else {
emoji_groups[i].className = "emoji-group-container";
}
}
let emoji_grps_tab =
document.getElementsByClassName("emoji-group-tab");
for (let i = 0; i < emoji_grps_tab.length; i++) {
emoji_grps_tab[i].className = "emoji-group-tab";
}
emoji_grp_tab.className += " active-emoji-group-tab";
}
function parseEmojiShortcuts()
{
let input = document.getElementById("new-message");
let raw_message = input.value;
let possible_shortcuts = raw_message.matchAll(/\[([^\]]+)\]/g);
let parse_message = "";
let last_start_idx = 0;
for (let shortcut of possible_shortcuts) {
let text = shortcut[1];
let emoji = emojis_array[text];
if (emoji !== undefined) {
parse_message += raw_message.substring(last_start_idx,
shortcut["index"]) + emoji;
} else {
parse_message += raw_message.substring(last_start_idx,
shortcut["index"]) + "[" + text + "]";
}
last_start_idx = shortcut["index"] + text.length + 2;
}
parse_message += raw_message.substring(last_start_idx);
input.value = parse_message;
return true;
}
</script>
</div><?php
}
}