diff --git a/adm/style/acp_mchat_globalsettings.html b/adm/style/acp_mchat_globalsettings.html
index 5655ec1..53402be 100644
--- a/adm/style/acp_mchat_globalsettings.html
+++ b/adm/style/acp_mchat_globalsettings.html
@@ -80,9 +80,9 @@
-
-
-
-
+
+
+
diff --git a/adm/style/acp_mchat_globalusersettings_content.html b/adm/style/acp_mchat_globalusersettings_content.html
index 8e0cdf8..6b8b172 100644
--- a/adm/style/acp_mchat_globalusersettings_content.html
+++ b/adm/style/acp_mchat_globalusersettings_content.html
@@ -63,13 +63,6 @@
-
-
- -
-
-
-
-
-
diff --git a/composer.json b/composer.json
index a65c00d..a49f221 100644
--- a/composer.json
+++ b/composer.json
@@ -3,8 +3,8 @@
"type": "phpbb-extension",
"description": "mChat",
"homepage": "https://www.phpbb.com/customise/db/extension/mchat_extension/",
- "version": "2.1.0",
- "time": "2018-06-22",
+ "version": "2.1.1",
+ "time": "2018-09-01",
"keywords": ["phpbb", "extension", "mchat"],
"license": "GPL-2.0-only",
"authors": [
diff --git a/config/services.yml b/config/services.yml
index 1cc5b91..0d6c01e 100644
--- a/config/services.yml
+++ b/config/services.yml
@@ -67,6 +67,7 @@ services:
- '@ext.manager'
- '@text_formatter.parser'
- '@?phpbb.collapsiblecategories.operator'
+ - '@?rmcgirr83.authorizedforurls.listener'
dmzx.mchat.functions:
class: dmzx\mchat\core\functions
diff --git a/core/functions.php b/core/functions.php
index 50d0b82..afff00d 100644
--- a/core/functions.php
+++ b/core/functions.php
@@ -397,25 +397,35 @@ class functions
/**
* Returns the total number of messages
*
+ * @param string $sql_where
+ * @param string $sql_order_by
* @return int
*/
- public function mchat_total_message_count()
+ public function mchat_total_message_count($sql_where = '', $sql_order_by = '')
{
+ $sql_where_array = array_filter([$sql_where, $this->mchat_notifications->get_sql_where()]);
+
$sql_array = [
'SELECT' => 'COUNT(*) AS rows_total',
'FROM' => [$this->mchat_settings->get_table_mchat() => 'm'],
- 'WHERE' => $this->mchat_notifications->get_sql_where(),
+ 'WHERE' => $sql_where_array ? ('(' . implode(') AND (', $sql_where_array) . ')') : '',
+ 'ORDER_BY' => $sql_order_by,
];
/**
* Event to modifying the SQL query that fetches the total number of mChat messages
*
* @event dmzx.mchat.total_message_count_modify_sql
- * @var array sql_array Array with SQL query data to fetch the total message count
+ * @var array sql_array Array with SQL query data to fetch the total message count
+ * @var string sql_where Additional SQL where condition passed to this method
+ * @var string sql_order_by Additional SQL order by statement passed to this method
* @since 2.0.0-RC6
+ * @changed 2.1.1 Added sql_where, sql_order_by
*/
$vars = [
'sql_array',
+ 'sql_where',
+ 'sql_order_by',
];
extract($this->dispatcher->trigger_event('dmzx.mchat.total_message_count_modify_sql', compact($vars)));
@@ -454,7 +464,7 @@ class functions
$message_ids = [$message_ids];
}
- $sql_where_message_id[] = $this->db->sql_in_set('m.message_id', array_map('intval', $message_ids));
+ $sql_where_message_id[] = $this->db->sql_in_set('m.message_id', $message_ids);
}
$sql_where_ary = array_filter([
diff --git a/core/mchat.php b/core/mchat.php
index bcf5a34..6ea79f2 100644
--- a/core/mchat.php
+++ b/core/mchat.php
@@ -23,6 +23,7 @@ use phpbb\request\request_interface;
use phpbb\template\template;
use phpbb\textformatter\parser_interface;
use phpbb\user;
+use rmcgirr83\authorizedforurls\event\listener as authorizedforurls;
use Symfony\Component\HttpFoundation\JsonResponse;
class mchat
@@ -72,6 +73,9 @@ class mchat
/** @var cc_operator */
protected $cc_operator;
+ /** @var authorizedforurls */
+ protected $authorized_for_urls;
+
/** @var boolean */
protected $remove_disallowed_bbcodes = false;
@@ -102,6 +106,7 @@ class mchat
* @param manager $extension_manager
* @param parser_interface $textformatter_parser
* @param cc_operator $cc_operator
+ * @param authorizedforurls $authorized_for_urls
*/
public function __construct(
functions $mchat_functions,
@@ -118,7 +123,8 @@ class mchat
dispatcher_interface $dispatcher,
manager $extension_manager,
parser_interface $textformatter_parser,
- cc_operator $cc_operator = null
+ cc_operator $cc_operator = null,
+ authorizedforurls $authorized_for_urls = null
)
{
$this->mchat_functions = $mchat_functions;
@@ -136,6 +142,7 @@ class mchat
$this->extension_manager = $extension_manager;
$this->textformatter_parser = $textformatter_parser;
$this->cc_operator = $cc_operator;
+ $this->authorized_for_urls = $authorized_for_urls;
}
/**
@@ -314,12 +321,6 @@ class mchat
throw new http_exception(403, 'NO_AUTH_OPERATION');
}
- // Fix avatars & smilies
- if (!defined('PHPBB_USE_BOARD_URL_PATH'))
- {
- define('PHPBB_USE_BOARD_URL_PATH', true);
- }
-
$this->lang->add_lang('mchat', 'dmzx/mchat');
}
@@ -757,14 +758,17 @@ class mchat
// Add lang file
$this->lang->add_lang('posting');
+ $is_archive = $page == 'archive';
+ $jump_to_id = $is_archive ? $this->request->variable('jumpto', 0) : 0;
+
// If the static message is not empty in the language file, use it, else ise the static message in the database
$static_message = $this->lang->lang('MCHAT_STATIC_MESSAGE') ?: $this->mchat_settings->cfg('mchat_static_message');
$whois_refresh = $this->mchat_settings->cfg('mchat_whois_index') || $this->mchat_settings->cfg('mchat_navbar_link_count');
- $this->template->assign_vars([
+ $template_data = [
'MCHAT_PAGE' => $page,
+ 'MCHAT_CURRENT_URL' => '.' . $this->user->page['script_path'] . $this->user->page['page'],
'MCHAT_ALLOW_SMILES' => $this->mchat_settings->cfg('allow_smilies') && $this->auth->acl_get('u_mchat_smilies'),
- 'MCHAT_INPUT_AREA' => $this->mchat_settings->cfg('mchat_input_area'),
'MCHAT_MESSAGE_TOP' => $this->mchat_settings->cfg('mchat_message_top'),
'MCHAT_INDEX_HEIGHT' => $this->mchat_settings->cfg('mchat_index_height'),
'MCHAT_CUSTOM_HEIGHT' => $this->mchat_settings->cfg('mchat_custom_height'),
@@ -783,22 +787,23 @@ class mchat
'MCHAT_STATIC_MESS' => htmlspecialchars_decode($static_message),
'MCHAT_MAX_INPUT_HEIGHT' => $this->mchat_settings->cfg('mchat_max_input_height'),
'MCHAT_MAX_MESSAGE_LENGTH' => $this->mchat_settings->cfg('mchat_max_message_lngth'),
+ 'MCHAT_JUMP_TO' => $jump_to_id,
'COOKIE_NAME' => $this->mchat_settings->cfg('cookie_name', true) . '_',
- ]);
+ ];
// The template needs some language variables if we display relative time for messages
if ($this->mchat_settings->cfg('mchat_relative_time'))
{
- $this->template->assign_var('MCHAT_MINUTES_AGO_LIMIT', $this->get_relative_minutes_limit());
+ $template_data['MCHAT_MINUTES_AGO_LIMIT'] = $this->get_relative_minutes_limit();
}
// Get actions which the user is allowed to perform on the current page
$actions = array_keys(array_filter([
'edit' => $this->auth_message('edit', true, time()),
'del' => $this->auth_message('delete', true, time()),
- 'refresh' => $page !== 'archive' && $this->auth->acl_get('u_mchat_view'),
- 'add' => $page !== 'archive' && $this->auth->acl_get('u_mchat_use'),
- 'whois' => $page !== 'archive' && $whois_refresh,
+ 'refresh' => !$is_archive && $this->auth->acl_get('u_mchat_view'),
+ 'add' => !$is_archive && $this->auth->acl_get('u_mchat_use'),
+ 'whois' => !$is_archive && $whois_refresh,
]));
foreach ($actions as $action)
@@ -810,14 +815,62 @@ class mchat
}
$limit = $this->mchat_settings->cfg('mchat_message_num_' . $page);
- $start = $page === 'archive' ? $this->request->variable('start', 0) : 0;
- $rows = $this->mchat_functions->mchat_get_messages([], 0, $limit, $start);
+
+ if ($is_archive)
+ {
+ if ($jump_to_id)
+ {
+ $sql_where_jump_to_id = 'm.message_id > ' . (int) $jump_to_id;
+ $sql_order_by = 'm.message_id ASC';
+ $num_subsequent_messages = $this->mchat_functions->mchat_total_message_count($sql_where_jump_to_id, $sql_order_by);
+ $start = (int) floor($num_subsequent_messages / $limit) * $limit;
+ }
+ else
+ {
+ $start = $this->request->variable('start', 0);
+ }
+ }
+ else
+ {
+ $start = 0;
+ }
+
+ $message_ids = [];
+ $last_id = 0;
+
+ /**
+ * Event to modify arguments before fetching messages from the database
+ *
+ * @event dmzx.mchat.render_page_get_messages_before
+ * @var string page The page that is rendered, one of index|custom|archive
+ * @var array message_ids IDs of specific messages to fetch, should be an empty array
+ * @var int last_id The ID of the latest message that the user has, should be 0
+ * @var int limit Number of messages to display per page
+ * @var int start The message which should be considered currently active, used to determine the page we're on
+ * @var int jump_to_id The ID of the message that is being jumped to in the archive, usually when a user clicked on a quote reference
+ * @var array actions Array containing URLs to actions the user is allowed to perform (read only)
+ * @var array template_data The data that is about to be assigned to the template
+ * @since 2.1.1
+ */
+ $vars = [
+ 'page',
+ 'message_ids',
+ 'last_id',
+ 'limit',
+ 'start',
+ 'jump_to_id',
+ 'actions',
+ 'template_data',
+ ];
+ extract($this->dispatcher->trigger_event('dmzx.mchat.render_page_get_messages_before', compact($vars)));
+
+ $rows = $this->mchat_functions->mchat_get_messages($message_ids, $last_id, $limit, $start);
$this->assign_global_template_data();
$this->assign_messages($rows, $page);
// Render pagination
- if ($page === 'archive')
+ if ($is_archive)
{
$archive_url = $this->helper->route('dmzx_mchat_page_archive_controller');
$total_messages = $this->mchat_functions->mchat_total_message_count();
@@ -830,38 +883,40 @@ class mchat
* @var int total_messages Total number of messages
* @var int limit Number of messages to display per page
* @var int start The message which should be considered currently active, used to determine the page we're on
+ * @var int jump_to_id The ID of the message that is being jumped to in the archive, usually when a user clicked on a quote reference
+ * @var array template_data The data that is about to be assigned to the template
* @since 2.0.0-RC6
+ * @changed 2.1.1 added jump_to_id, template_data
*/
$vars = [
'archive_url',
'total_messages',
'limit',
'start',
+ 'jump_to_id',
+ 'template_data',
];
extract($this->dispatcher->trigger_event('dmzx.mchat.render_page_pagination_before', compact($vars)));
$this->pagination->generate_template_pagination($archive_url, 'pagination', 'start', $total_messages, $limit, $start);
- $this->template->assign_var('MCHAT_TOTAL_MESSAGES', $this->lang->lang('MCHAT_TOTALMESSAGES', $total_messages));
+ $template_data['MCHAT_TOTAL_MESSAGES'] = $this->lang->lang('MCHAT_TOTALMESSAGES', $total_messages);
}
// Render legend
if ($page !== 'index')
{
$legend = $this->mchat_functions->mchat_legend();
- $this->template->assign_var('LEGEND', implode($this->lang->lang('COMMA_SEPARATOR'), $legend));
+ $template_data['LEGEND'] = implode($this->lang->lang('COMMA_SEPARATOR'), $legend);
}
// Make mChat collapsible
if ($page === 'index' && $this->cc_operator !== null)
{
$cc_fid = 'mchat';
- $this->template->assign_vars([
+ $template_data = array_merge($template_data, [
'MCHAT_IS_COLLAPSIBLE' => true,
- 'S_MCHAT_HIDDEN' => in_array($cc_fid, $this->cc_operator->get_user_categories()),
- 'U_MCHAT_COLLAPSE_URL' => $this->helper->route('phpbb_collapsiblecategories_main_controller', [
- 'forum_id' => $cc_fid,
- 'hash' => generate_link_hash('collapsible_' . $cc_fid),
- ]),
+ 'S_MCHAT_HIDDEN' => $this->cc_operator->is_collapsed($cc_fid),
+ 'U_MCHAT_COLLAPSE_URL' => $this->cc_operator->get_collapsible_link($cc_fid),
]);
}
@@ -876,15 +931,20 @@ class mchat
* Event that is triggered after mChat was rendered
*
* @event dmzx.mchat.render_page_after
- * @var string page The page that was rendered, one of index|custom|archive
- * @var array actions Array containing URLs to actions the user is allowed to perform
+ * @var string page The page that was rendered, one of index|custom|archive
+ * @var array actions Array containing URLs to actions the user is allowed to perform (read only)
+ * @var array template_data The data that is about to be assigned to the template
* @since 2.0.0-RC6
+ * @changed 2.1.1 Added template_data
*/
$vars = [
'page',
'actions',
+ 'template_data',
];
extract($this->dispatcher->trigger_event('dmzx.mchat.render_page_after', compact($vars)));
+
+ $this->template->assign_vars($template_data);
}
/**
@@ -970,24 +1030,7 @@ class mchat
return;
}
- // At this point the rows are sorted by ID bottom to top.
- // We need to reverse the array if they need to be sorted top to bottom.
- $reverse = false;
- $mchat_message_top = $this->mchat_settings->cfg('mchat_message_top');
- if ($page === 'archive')
- {
- $mchat_archive_sort = $this->mchat_settings->cfg('mchat_archive_sort');
- if ($mchat_archive_sort == settings::ARCHIVE_SORT_TOP_BOTTOM || $mchat_archive_sort == settings::ARCHIVE_SORT_USER && !$mchat_message_top)
- {
- $reverse = true;
- }
- }
- else if (!$mchat_message_top)
- {
- $reverse = true;
- }
-
- if ($reverse)
+ if ($this->messages_need_reversing($page))
{
$rows = array_reverse($rows);
}
@@ -1017,20 +1060,12 @@ class mchat
}
}
- $board_url = generate_board_url() . '/';
-
$rows = $this->mchat_notifications->process($rows);
foreach ($rows as $row)
{
$username_full = get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], $this->lang->lang('GUEST'));
- // Fix profile link root path by replacing relative paths with absolute board URL
- if ($this->request->is_ajax())
- {
- $username_full = preg_replace('#(?<=href=")[\./]+?/(?=\w)#', $board_url, $username_full);
- }
-
if (in_array($row['user_id'], $this->foes))
{
$row['message'] = $this->lang->lang('MCHAT_FOE', $username_full);
@@ -1047,6 +1082,7 @@ class mchat
$message_for_edit = generate_text_for_edit($row['message'], $row['bbcode_uid'], $row['bbcode_options']);
$template_data = [
+ 'MCHAT_USER_ID' => $row['user_id'],
'MCHAT_ALLOW_EDIT' => $this->auth_message('edit', $row['user_id'], $row['message_time']),
'MCHAT_ALLOW_DEL' => $this->auth_message('delete', $row['user_id'], $row['message_time']),
'MCHAT_USER_AVATAR' => $user_avatars[$row['user_id']],
@@ -1100,6 +1136,34 @@ class mchat
}
}
+ /**
+ * By default, rows are fetched by message ID descending. This method returns true if
+ * the user wants them to be displayed ascending, otherwise false.
+ *
+ * @param string $page
+ * @return bool
+ */
+ protected function messages_need_reversing($page)
+ {
+ $mchat_message_top = $this->mchat_settings->cfg('mchat_message_top');
+
+ if ($page === 'archive')
+ {
+ $mchat_archive_sort = $this->mchat_settings->cfg('mchat_archive_sort');
+
+ if ($mchat_archive_sort == settings::ARCHIVE_SORT_TOP_BOTTOM || $mchat_archive_sort == settings::ARCHIVE_SORT_USER && !$mchat_message_top)
+ {
+ return true;
+ }
+ }
+ else if (!$mchat_message_top)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
/**
* Returns true if the user is allowed to read the given message row
*
@@ -1359,6 +1423,19 @@ class mchat
}
}
+ // Compatibility with Authorized for URLs by RMcGirr83 - requires at least 1.0.5
+ // https://www.phpbb.com/customise/db/extension/authorized_for_urls_2/
+ if ($this->authorized_for_urls !== null && is_callable([$this->authorized_for_urls, 'check_text']))
+ {
+ $authorized_for_urls_lang_args = $this->authorized_for_urls->check_text($message, true);
+
+ if ($authorized_for_urls_lang_args)
+ {
+ $authorized_for_urls_lang_key = array_shift($authorized_for_urls_lang_args);
+ throw new http_exception(400, $authorized_for_urls_lang_key, $authorized_for_urls_lang_args);
+ }
+ }
+
if ($this->mchat_settings->cfg('mchat_override_min_post_chars'))
{
$this->mchat_settings->set_cfg('min_post_chars', 0, true);
diff --git a/core/settings.php b/core/settings.php
index d43c91a..a27ae15 100644
--- a/core/settings.php
+++ b/core/settings.php
@@ -241,7 +241,6 @@ class settings
'mchat_character_count' => ['default' => 1],
'mchat_date' => ['default' => 'D M d, Y g:i a', 'validation' => ['string', false, 0, 64]],
'mchat_index' => ['default' => 1],
- 'mchat_input_area' => ['default' => 1],
'mchat_location' => ['default' => 1],
'mchat_message_top' => ['default' => 1],
'mchat_posts' => ['default' => 1],
diff --git a/language/en/mchat_ucp.php b/language/en/mchat_ucp.php
index 8a02340..258ebde 100644
--- a/language/en/mchat_ucp.php
+++ b/language/en/mchat_ucp.php
@@ -45,9 +45,6 @@ $lang = array_merge($lang, [
'MCHAT_STATS_INDEX_EXPLAIN' => 'Displays who is chatting below the Who is online section on the index page.',
'MCHAT_AVATARS' => 'Display avatars',
'MCHAT_CAPITAL_LETTER' => 'Capital first letter in your messages',
- 'MCHAT_CHAT_AREA' => 'Input type',
- 'MCHAT_INPUT_AREA' => 'Input field',
- 'MCHAT_TEXT_AREA' => 'Text area',
'MCHAT_POSTS' => 'Display new posts (currently all disabled, can be enabled in the mChat Global Settings section in the ACP)',
'MCHAT_DISPLAY_CHARACTER_COUNT' => 'Display number of characters when typing a message',
'MCHAT_RELATIVE_TIME' => 'Display relative time for new messages',
diff --git a/language/en/permissions_mchat.php b/language/en/permissions_mchat.php
index f89e828..53b64c5 100644
--- a/language/en/permissions_mchat.php
+++ b/language/en/permissions_mchat.php
@@ -56,7 +56,6 @@ $lang = array_merge($lang, [
'ACL_U_MCHAT_CHARACTER_COUNT' => 'Can customise Display number of characters',
'ACL_U_MCHAT_DATE' => 'Can customise Date format',
'ACL_U_MCHAT_INDEX' => 'Can customise Display on index',
- 'ACL_U_MCHAT_INPUT_AREA' => 'Can customise Input type',
'ACL_U_MCHAT_LOCATION' => 'Can customise Location of mChat on the index page',
'ACL_U_MCHAT_MESSAGE_TOP' => 'Can customise Location of new chat messages',
'ACL_U_MCHAT_POSTS' => 'Can customise Display new posts',
diff --git a/migrations/mchat_2_1_1.php b/migrations/mchat_2_1_1.php
new file mode 100644
index 0000000..d353c3b
--- /dev/null
+++ b/migrations/mchat_2_1_1.php
@@ -0,0 +1,55 @@
+ [
+ $this->table_prefix . 'users' => [
+ 'user_mchat_input_area',
+ ],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'users' => [
+ 'user_mchat_input_area' => ['BOOL', 1],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/styles/all/template/javascript/mchat.js b/styles/all/template/javascript/mchat.js
index 76bdceb..f828786 100644
--- a/styles/all/template/javascript/mchat.js
+++ b/styles/all/template/javascript/mchat.js
@@ -106,9 +106,10 @@ jQuery(function($) {
return;
}
var deferred = $.Deferred();
- if (sendHiddenFields) {
- $.extend(data, mChat.hiddenFields);
- }
+ $.extend(data,
+ {_referer: mChat.currentUrl},
+ sendHiddenFields ? mChat.hiddenFields : {}
+ );
$(mChat).trigger('mchat_send_request_before', [mode, data]);
$.ajax({
url: mChat.actionUrls[mode],
@@ -427,6 +428,7 @@ jQuery(function($) {
playSound = false;
}
mChat.messageIds.push($message.data('mchat-id'));
+ mChat.fixJumpToUrl.call($message);
setTimeout(function() {
var dataAddMessageAnimateBefore = {
container: mChat.cached('messages'),
@@ -453,7 +455,7 @@ jQuery(function($) {
} else {
animateOptions.complete = function() {
var scrollHeight = container.get(0).scrollHeight;
- if (container.scrollTop() + container.height() < scrollHeight) {
+ if (container.scrollTop() + container.innerHeight() < scrollHeight) {
container.animate({scrollTop: scrollHeight}, animateOptions);
}
};
@@ -480,7 +482,7 @@ jQuery(function($) {
});
}, mChat.editDeleteLimit);
}
- mChat.startRelativeTimeUpdate($message);
+ mChat.startRelativeTimeUpdate.call($message);
});
},
updateMessages: function($messages) {
@@ -494,7 +496,8 @@ jQuery(function($) {
};
$(mChat).trigger('mchat_edit_message_before', [data]);
mChat.stopRelativeTimeUpdate(data.oldMessage);
- mChat.startRelativeTimeUpdate(data.newMessage);
+ mChat.startRelativeTimeUpdate.call(data.newMessage);
+ mChat.fixJumpToUrl.call(data.newMessage);
data.oldMessage.fadeOut(function() {
data.oldMessage.replaceWith(data.newMessage.hide().fadeIn());
});
@@ -527,9 +530,9 @@ jQuery(function($) {
}
});
},
- startRelativeTimeUpdate: function($messages) {
+ startRelativeTimeUpdate: function() {
if (mChat.relativeTime) {
- $messages.find('.mchat-time[data-mchat-relative-update]').each(function() {
+ $(this).find('.mchat-time[data-mchat-relative-update]').each(function() {
var $time = $(this);
setTimeout(function() {
mChat.relativeTimeUpdate($time);
@@ -634,27 +637,67 @@ jQuery(function($) {
}
mChat.appendText(mChat.lang.mention.format({username: username}));
},
- quote: function() {
- var $container = $(this).closest('.mchat-message');
- var username = $container.data('mchat-username');
+ fixJumpToUrl: function() {
+ var $message = $(this);
+ var $elem = $message.find('blockquote [data-post-id]');
+ var messageId = $elem.data('post-id');
+ var data = {
+ message: $message,
+ elem: $elem,
+ url: mChat.getArchiveQuoteUrl(messageId)
+ };
+ $(mChat).trigger('mchat_fix_jump_to_url_before', [data]);
+ if (data.url) {
+ data.elem.attr('href', data.url);
+ }
+ },
+ getArchiveQuoteUrl: function(messageId) {
+ var archiveUrl = $('.mchat-nav-archive').find('a').prop('href');
+ return archiveUrl ? mChat.addUrlParam(archiveUrl, 'jumpto=' + messageId) : false;
+ },
+ jumpToMessage: function() {
+ var messageId = $(this).data('post-id');
+ var data = {
+ container: mChat.cached('messages'),
+ messageId: messageId,
+ message: $('#mchat-message-' + messageId),
+ jump: function() {
+ if (data.message.length) {
+ var scrollTop = data.message.offset().top - data.container.offset().top + data.container.scrollTop();
+ data.container.scrollTop(scrollTop);
+ data.message.removeClass('mchat-message-flash');
+ data.message.offset();
+ data.message.addClass('mchat-message-flash');
+ } else {
+ var url = mChat.getArchiveQuoteUrl(data.messageId);
+ if (url) {
+ window.open(url, '_blank');
+ }
+ }
+ }
+ };
+ $(mChat).trigger('mchat_jump_to_message_before', [data]);
+ data.jump();
+ },
+ getQuoteText: function($container) {
var quote = $container.data('mchat-message');
- mChat.appendText('[quote="' + username + '"] ' + quote + '[/quote]');
+ var quoteAttributes = [
+ '"' + $container.data('mchat-username') + '"',
+ 'post_id=' + $container.data('mchat-id'),
+ 'time=' + $container.data('mchat-message-time'),
+ 'user_id=' + $container.data('mchat-user-id')
+ ];
+ return '[quote=' + quoteAttributes.join(' ') + '] ' + quote + ' [/quote]';
+ },
+ quote: function() {
+ mChat.appendText(mChat.getQuoteText($(this).closest('.mchat-message')));
},
like: function() {
- var $container = $(this).closest('.mchat-message');
- var username = $container.data('mchat-username');
- var quote = $container.data('mchat-message');
- mChat.appendText('[i]' + mChat.lang.likes + '[/i][quote="' + username + '"] ' + quote + '[/quote]');
+ mChat.appendText('[i]' + mChat.lang.likes + '[/i]' + mChat.getQuoteText($(this).closest('.mchat-message')));
},
ip: function() {
popup(this.href, 750, 500);
},
- custom: function() {
- window.location.href = this.href;
- },
- archive: function() {
- window.location.href = this.href;
- },
setText: function(text) {
mChat.cached('input').val('');
mChat.appendText(text);
@@ -670,6 +713,9 @@ jQuery(function($) {
$input.scrollLeft($input[0].scrollWidth - $input[0].clientWidth);
}
},
+ addUrlParam: function(url, keyEqualsValue) {
+ return url + (url.indexOf('?') === -1 ? '?' : '&') + keyEqualsValue;
+ },
cached: function(name) {
if (!mChat.cache) {
mChat.cache = {};
@@ -681,16 +727,24 @@ jQuery(function($) {
}
});
- mChat.messageIds = mChat.cached('messages').children().map(function() {
- return $(this).data('mchat-id');
- }).get();
+ mChat.messageIds = mChat.cached('messages').children()
+ .each(mChat.startRelativeTimeUpdate)
+ .each(mChat.fixJumpToUrl)
+ .map(function() { return $(this).data('mchat-id'); }).get();
mChat.hiddenFields = {};
mChat.cached('form').find('input[type=hidden]').each(function() {
mChat.hiddenFields[this.name] = this.value;
});
- if (mChat.page !== 'archive') {
+ if (mChat.page === 'archive') {
+ if (mChat.jumpTo) {
+ var fragment = '#mchat-message-' + mChat.jumpTo;
+ if ($(fragment).addClass('mchat-message-flash').length) {
+ window.location.hash = fragment;
+ }
+ }
+ } else {
mChat.resetSession();
if (!mChat.messageTop) {
@@ -768,8 +822,6 @@ jQuery(function($) {
}
}
- mChat.startRelativeTimeUpdate(mChat.cached('messages'));
-
mChat.registerNavItem('sound', mChat.playSound);
if (mChat.maxInputHeight) {
mChat.registerNavItem('enter', true);
@@ -783,6 +835,9 @@ jQuery(function($) {
e.preventDefault();
var action = $(this).data('mchat-action');
mChat[action].call(this, e);
+ }).on('click', '#mchat-messages blockquote [data-post-id]', function(e) {
+ e.preventDefault();
+ mChat.jumpToMessage.call(this);
}).on('click', '.mchat-panel-buttons button', function() {
var $this = $(this).blur();
if ($this.hasClass('mchat-button-down')) {
diff --git a/styles/all/template/mchat_script_data.html b/styles/all/template/mchat_script_data.html
index a5ce86a..60612d3 100644
--- a/styles/all/template/mchat_script_data.html
+++ b/styles/all/template/mchat_script_data.html
@@ -14,10 +14,11 @@
// General settings
actionUrls : {
{% for mchaturl in loops.mchaturl %}
- {{ mchaturl.ACTION }}: '{{ mchaturl.URL }}'{{ loop.last ? '' : ',' }}
+ {{ mchaturl.ACTION }}: '{{ mchaturl.URL }}'{{ not loop.last ? ',' }}
{% endfor %}
},
page : '{{ MCHAT_PAGE | escape('js') }}',
+ currentUrl : '{{ MCHAT_CURRENT_URL | escape('js') }}',
cookie : '{{ COOKIE_NAME | escape('js') }}',
playSound : {{ MCHAT_SOUND ? 'true' : 'false' }},
messageTop : {{ MCHAT_MESSAGE_TOP ? 'true' : 'false' }},
@@ -25,6 +26,7 @@
liveUpdates : {{ MCHAT_LIVE_UPDATES ? 'true' : 'false' }},
relativeTime : {{ MCHAT_RELATIVE_TIME ? 'true' : 'false' }},
showCharCount : {{ MCHAT_CHARACTER_COUNT ? 'true' : 'false' }},
+ jumpTo : {{ MCHAT_JUMP_TO }},
// Limits & timeouts
refreshTime : {{ MCHAT_REFRESH_JS }},
@@ -41,7 +43,7 @@
minutesAgo : {
{% if MCHAT_RELATIVE_TIME %}
{% for minute in 0..MCHAT_MINUTES_AGO_LIMIT-1 %}
- {{ minute }}: '{{ lang('MCHAT_MINUTES_AGO', minute) | escape('js') }}'{{ loop.last ? '' : ',' }}
+ {{ minute }}: '{{ lang('MCHAT_MINUTES_AGO', minute) | escape('js') }}'{{ not loop.last ? ',' }}
{% endfor %}
{% endif %}
},
diff --git a/styles/prosilver/template/mchat_body.html b/styles/prosilver/template/mchat_body.html
index 3c2e1e4..381a568 100644
--- a/styles/prosilver/template/mchat_body.html
+++ b/styles/prosilver/template/mchat_body.html
@@ -107,7 +107,7 @@
{% EVENT dmzx_mchat_after %}
-{% if MCHAT_PAGE == 'archive' %}
+{% if MCHAT_PAGE == 'archive' and (loops.pagination|length or MCHAT_TOTAL_MESSAGES) %}
{% EVENT dmzx_mchat_action_bar_bottom_before %}