MyAlerts: Align full page listing semantics with those of pop-up dialogue + more
MyAlerts is a popular plugin for MyBB - essential for some of us. I and a member of the board I administer were not satisfied with its semantics though. In particular:<br />
<br />
The semantics of the modal pop-up (accessed by clicking "Alerts" in the header) are different to those of the full listing (at <code class="inline-code">alerts.php</code>, accessed via the modal pop-up by clicking "View Alerts" in the pop-up's footer).<br />
<br />
In particular:<br />
<ol type="1" class="mycode_list"><li>The modal pop-up does not affect the (un)read status of alerts, whereas simply visiting the full listing marks all unread alerts as read.<br />
</li>
<li>The modal pop-up visually dims read alerts, whereas the full listing does not.<br />
</li>
</ol>
We resolved to bring the semantics of the full listing into alignment with those of the modal pop-up, and, thereafter, to add a "Mark All Read" link to both.<br />
<br />
Here is how we did it, in (hopefully) enough detail that you can too. Note that line numbers based on the current GitHub version may differ slightly for you depending on which version you're running. Note also that where "comment out" is indicated, the addition "or delete" should be assumed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">First: aligning the two listings.</span><br />
<br />
In <code class="inline-code">alerts.php</code>, comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">this line</a> (#428 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> MybbStuff_MyAlerts_AlertManager::getInstance()->markRead($readAlerts);
</code></pre>This is the <span style="font-style: italic;" class="mycode_i">main</span> line that causes unread alerts to be automatically marked as read upon loading the full page listing.<br />
<br />
In <code class="inline-code">jscripts/myalerts.js</code>:<br />
<ol type="1" class="mycode_list"><li>Comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">these lines</a> (#18-22 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> window.setInterval(function () {
$.get('xmlhttp.php?action=getNewAlerts', function (data) {
$('#latestAlertsListing').prepend(data);
});
}, myalerts_autorefresh * 1000);
</code></pre>These are the <span style="font-style: italic;" class="mycode_i">secondary</span> lines that cause unread alerts to be automatically marked as read, but via AJAX, <span style="font-style: italic;" class="mycode_i">after</span> loading the full listing.<br />
</li>
<li>Also comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">this line</a> (line #12 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> bodySelector.on("click", "#getUnreadAlerts", unreadAlertsProxy);
</code></pre>This line calls dodgy code that was predicated on returning unread alerts and dynamically prepending them to the existing list on the full page listing - but the code to prepend them uses the wrong variable identifier, making it ineffective, and - in some cases, on some browsers - prevents the "Check for new alerts" link on the full listing from working.<br />
</li>
</ol>
In <code class="inline-code">inc/plugins/myalerts.php</code>, comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">these lines</a> (#1403-1405 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> MybbStuff_MyAlerts_AlertManager::getInstance()->markRead(
$toMarkRead
);
</code></pre>These lines, too, contribute to the problem of unread posts automatically being marked read, although they probably are nullified anyway in this respect given the previous commenting-out of line #12 of <code class="inline-code">jscripts/myalerts.js</code> mentioned above.<br />
<br />
In the live stylesheet <code class="inline-code">alerts.css</code>, via the ACP, change:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-none">.alert--read.alert {
opacity: .5;
}
</code></pre><br />
to:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-none">.alert--read.alert, tr.alert--read {
opacity: .5;
}
</code></pre><br />
Now, the semantics of the two listings should be aligned. You might now want, though, as we did - given that alerts are no longer automatically marked as read on visiting the full listing - to do this:<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Second: adding a "Mark All Read" link.</span><br />
<br />
To the "switch" statement up the top of <code class="inline-code">alerts.php</code>, add the following code:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> case 'mark_all_read':
myalerts_mark_all_alerts_read($mybb, $lang);
break;
</code></pre><br />
Also to that file, add the following function:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-php">/**
* Mark all alerts as read.
*
* @param MyBB $mybb MyBB core object.
* @param MyLanguage $lang MyBB language system.
*/
function myalerts_mark_all_alerts_read($mybb, $lang)
{
verify_post_check($mybb->get_input('my_post_key'));
$alertsList = MybbStuff_MyAlerts_AlertManager::getInstance()->getAlerts(0);
$alertIds = array();
if (!empty($alertsList) && is_array($alertsList)) {
foreach ($alertsList as $alertObject) {
$alert = parse_alert($alertObject);
$alertIds[] = $alert['id'];
}
}
MybbStuff_MyAlerts_AlertManager::getInstance()->markRead($alertIds);
$retLink = $mybb->get_input('ret_link', MyBB::INPUT_STRING);
if (!empty($retLink) && stripos($retLink, $mybb->settings['bburl']) === 0) {
$retLink = htmlspecialchars_uni($retLink);
redirect(
$retLink,
$lang->myalerts_marked_all_read_desc,
$lang->myalerts_marked_all_read_title
);
} else {
redirect(
'alerts.php?action=alerts',
$lang->myalerts_marked_all_read_desc,
$lang->myalerts_marked_all_read_title
);
}
}
</code></pre><br />
To <code class="inline-code">inc/languages/english/myalerts.lang.php</code> (or your localised variant) add (potentially localised):<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-php">$l['myalerts_page_mark_all_read'] = 'Mark All Read';
$l['myalerts_modal_mark_all_read'] = 'Mark All Read';
$l['myalerts_marked_all_read_title'] = 'Marked All Read';
$l['myalerts_marked_all_read_desc'] = 'All alerts were successfully marked as read.';
</code></pre><br />
To your live templates, via the ACP:<br />
<br />
Prepend to these lines in the template <code class="inline-code">myalerts_modal_content</code>:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=delete_read&amp;my_post_key={$mybb->post_code}&amp;ret_link={$myalerts_return_link}"
onclick="return confirm('{$lang->myalerts_modal_delete_read_confirm}'); return false;">{$lang->myalerts_modal_delete_read}</a> |
</code></pre>this line:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=mark_all_read&amp;my_post_key={$mybb->post_code}&amp;ret_link={$myalerts_return_link}">{$lang->myalerts_modal_mark_all_read}</a> |
</code></pre><br />
Also, prepend to this line in the template <code class="inline-code">myalerts_page</code>:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=delete_read&amp;my_post_key={$mybb->post_code}" onclick="return confirm('{$lang->myalerts_delete_read_confirm}')">{$lang->myalerts_page_delete_read}</a> |
</code></pre>this line:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=mark_all_read&amp;my_post_key={$mybb->post_code}">{$lang->myalerts_page_mark_all_read}</a> |
</code></pre><br />
That's it!<br />
<br />
Bonus challenge for any contenders: adapt the "Mark All Read" link in the modal pop-up to update the modal pop-up rather than - as currently is the case with these modifications - loading the full listing page.<br />
<br />
Let me know of any problems or omissions. I am typing this all up after the fact, so I might have missed something.
MyAlerts is a popular plugin for MyBB - essential for some of us. I and a member of the board I administer were not satisfied with its semantics though. In particular:<br />
<br />
The semantics of the modal pop-up (accessed by clicking "Alerts" in the header) are different to those of the full listing (at <code class="inline-code">alerts.php</code>, accessed via the modal pop-up by clicking "View Alerts" in the pop-up's footer).<br />
<br />
In particular:<br />
<ol type="1" class="mycode_list"><li>The modal pop-up does not affect the (un)read status of alerts, whereas simply visiting the full listing marks all unread alerts as read.<br />
</li>
<li>The modal pop-up visually dims read alerts, whereas the full listing does not.<br />
</li>
</ol>
We resolved to bring the semantics of the full listing into alignment with those of the modal pop-up, and, thereafter, to add a "Mark All Read" link to both.<br />
<br />
Here is how we did it, in (hopefully) enough detail that you can too. Note that line numbers based on the current GitHub version may differ slightly for you depending on which version you're running. Note also that where "comment out" is indicated, the addition "or delete" should be assumed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">First: aligning the two listings.</span><br />
<br />
In <code class="inline-code">alerts.php</code>, comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">this line</a> (#428 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> MybbStuff_MyAlerts_AlertManager::getInstance()->markRead($readAlerts);
</code></pre>This is the <span style="font-style: italic;" class="mycode_i">main</span> line that causes unread alerts to be automatically marked as read upon loading the full page listing.<br />
<br />
In <code class="inline-code">jscripts/myalerts.js</code>:<br />
<ol type="1" class="mycode_list"><li>Comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">these lines</a> (#18-22 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> window.setInterval(function () {
$.get('xmlhttp.php?action=getNewAlerts', function (data) {
$('#latestAlertsListing').prepend(data);
});
}, myalerts_autorefresh * 1000);
</code></pre>These are the <span style="font-style: italic;" class="mycode_i">secondary</span> lines that cause unread alerts to be automatically marked as read, but via AJAX, <span style="font-style: italic;" class="mycode_i">after</span> loading the full listing.<br />
</li>
<li>Also comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">this line</a> (line #12 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> bodySelector.on("click", "#getUnreadAlerts", unreadAlertsProxy);
</code></pre>This line calls dodgy code that was predicated on returning unread alerts and dynamically prepending them to the existing list on the full page listing - but the code to prepend them uses the wrong variable identifier, making it ineffective, and - in some cases, on some browsers - prevents the "Check for new alerts" link on the full listing from working.<br />
</li>
</ol>
In <code class="inline-code">inc/plugins/myalerts.php</code>, comment out <a href=" " target="_blank" rel="noopener" class="mycode_url">these lines</a> (#1403-1405 on GitHub):<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> MybbStuff_MyAlerts_AlertManager::getInstance()->markRead(
$toMarkRead
);
</code></pre>These lines, too, contribute to the problem of unread posts automatically being marked read, although they probably are nullified anyway in this respect given the previous commenting-out of line #12 of <code class="inline-code">jscripts/myalerts.js</code> mentioned above.<br />
<br />
In the live stylesheet <code class="inline-code">alerts.css</code>, via the ACP, change:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-none">.alert--read.alert {
opacity: .5;
}
</code></pre><br />
to:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-none">.alert--read.alert, tr.alert--read {
opacity: .5;
}
</code></pre><br />
Now, the semantics of the two listings should be aligned. You might now want, though, as we did - given that alerts are no longer automatically marked as read on visiting the full listing - to do this:<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Second: adding a "Mark All Read" link.</span><br />
<br />
To the "switch" statement up the top of <code class="inline-code">alerts.php</code>, add the following code:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> case 'mark_all_read':
myalerts_mark_all_alerts_read($mybb, $lang);
break;
</code></pre><br />
Also to that file, add the following function:<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-php">/**
* Mark all alerts as read.
*
* @param MyBB $mybb MyBB core object.
* @param MyLanguage $lang MyBB language system.
*/
function myalerts_mark_all_alerts_read($mybb, $lang)
{
verify_post_check($mybb->get_input('my_post_key'));
$alertsList = MybbStuff_MyAlerts_AlertManager::getInstance()->getAlerts(0);
$alertIds = array();
if (!empty($alertsList) && is_array($alertsList)) {
foreach ($alertsList as $alertObject) {
$alert = parse_alert($alertObject);
$alertIds[] = $alert['id'];
}
}
MybbStuff_MyAlerts_AlertManager::getInstance()->markRead($alertIds);
$retLink = $mybb->get_input('ret_link', MyBB::INPUT_STRING);
if (!empty($retLink) && stripos($retLink, $mybb->settings['bburl']) === 0) {
$retLink = htmlspecialchars_uni($retLink);
redirect(
$retLink,
$lang->myalerts_marked_all_read_desc,
$lang->myalerts_marked_all_read_title
);
} else {
redirect(
'alerts.php?action=alerts',
$lang->myalerts_marked_all_read_desc,
$lang->myalerts_marked_all_read_title
);
}
}
</code></pre><br />
To <code class="inline-code">inc/languages/english/myalerts.lang.php</code> (or your localised variant) add (potentially localised):<br />
<br />
<pre class="block-code line-numbers language-none"><code class="language-php">$l['myalerts_page_mark_all_read'] = 'Mark All Read';
$l['myalerts_modal_mark_all_read'] = 'Mark All Read';
$l['myalerts_marked_all_read_title'] = 'Marked All Read';
$l['myalerts_marked_all_read_desc'] = 'All alerts were successfully marked as read.';
</code></pre><br />
To your live templates, via the ACP:<br />
<br />
Prepend to these lines in the template <code class="inline-code">myalerts_modal_content</code>:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=delete_read&amp;my_post_key={$mybb->post_code}&amp;ret_link={$myalerts_return_link}"
onclick="return confirm('{$lang->myalerts_modal_delete_read_confirm}'); return false;">{$lang->myalerts_modal_delete_read}</a> |
</code></pre>this line:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=mark_all_read&amp;my_post_key={$mybb->post_code}&amp;ret_link={$myalerts_return_link}">{$lang->myalerts_modal_mark_all_read}</a> |
</code></pre><br />
Also, prepend to this line in the template <code class="inline-code">myalerts_page</code>:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=delete_read&amp;my_post_key={$mybb->post_code}" onclick="return confirm('{$lang->myalerts_delete_read_confirm}')">{$lang->myalerts_page_delete_read}</a> |
</code></pre>this line:<br />
<pre class="block-code line-numbers language-none"><code class="language-php"> <a href="{$mybb->settings['bburl']}/alerts.php?action=mark_all_read&amp;my_post_key={$mybb->post_code}">{$lang->myalerts_page_mark_all_read}</a> |
</code></pre><br />
That's it!<br />
<br />
Bonus challenge for any contenders: adapt the "Mark All Read" link in the modal pop-up to update the modal pop-up rather than - as currently is the case with these modifications - loading the full listing page.<br />
<br />
Let me know of any problems or omissions. I am typing this all up after the fact, so I might have missed something.