Skip to content

Commit

Permalink
Fix some page handlers issues (#1288)
Browse files Browse the repository at this point in the history
* The browser title updates, message controls work, & unecessary unread requests are stopped

* Fix message parts view and the download of attachements

* FIX: generated site.js includes js_modules with a one-level deep folder

* Fix profiles page test

* fix tests
  • Loading branch information
jacob-js authored Oct 21, 2024
1 parent 4da09be commit 2de1754
Show file tree
Hide file tree
Showing 15 changed files with 88 additions and 33 deletions.
22 changes: 22 additions & 0 deletions modules/core/js_modules/utils/loaders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function showLoaderToast(text = 'Loading...') {
const uniqueId = Math.random().toString(36).substring(7);
const toastHTML = `
<div class="position-fixed bottom-0 start-0 p-3" style="z-index: 11">
<div class="toast bg-primary text-white" id="${uniqueId}" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide="false">
<div class="toast-body">
<div class="d-flex align-items-center">
<strong>${text}</strong>
<div class="spinner-border ms-auto" role="status" aria-hidden="true"></div>
</div>
</div>
</div>
</div>
`

document.body.insertAdjacentHTML('beforeend', toastHTML)

const instance = bootstrap.Toast.getOrCreateInstance(document.getElementById(uniqueId));
instance.show();

return instance;
}
2 changes: 2 additions & 0 deletions modules/core/navigation/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ async function navigate(url) {

const html = await response.text();
const main = html.match(/<main[^>]*>((.|[\n\r])*)<\/main>/i)[0];
const title = html.match(/<title[^>]*>((.|[\n\r])*)<\/title>/i)[0];
$('main').replaceWith(main);
document.title = title.replace(/<[^>]*>/g, '');

window.location.next = url;

Expand Down
18 changes: 2 additions & 16 deletions modules/core/navigation/utils.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,9 @@
const toastHTML = `
<div class="position-fixed bottom-0 start-0 p-3" style="z-index: 11">
<div class="toast bg-primary text-white" id="routing-toast" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide="false">
<div class="toast-body">
<div class="d-flex align-items-center">
<strong>Redirecting...</strong>
<div class="spinner-border ms-auto" role="status" aria-hidden="true"></div>
</div>
</div>
</div>
</div>
`
document.body.insertAdjacentHTML('beforeend', toastHTML)

function showRoutingToast() {
bootstrap.Toast.getOrCreateInstance(document.getElementById('routing-toast')).show()
window.routingToast = showLoaderToast('Redirecting...');
}

function hideRoutingToast() {
bootstrap.Toast.getOrCreateInstance(document.getElementById('routing-toast')).hide()
window.routingToast.hide();
}

function getListPathParam() {
Expand Down
1 change: 0 additions & 1 deletion modules/core/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ body {
.compose_page,
.message_list,
.msg_text,
.selected_part,
.server_content,
.profile_content,
.user_settings,
Expand Down
12 changes: 6 additions & 6 deletions modules/core/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -917,27 +917,27 @@ function Message_List() {
};

/* TODO: remove module specific refs */
this.update_title = function() {
this.update_title = function(list_path = getListPathParam()) {
var count = 0;
var rows = Hm_Utils.rows();
var tbody = Hm_Utils.tbody();
if (getListPathParam() == 'unread') {
if (list_path == 'unread') {
count = rows.length;
document.title = count+' '+hm_trans('Unread');
}
else if (getListPathParam() == 'flagged') {
else if (list_path == 'flagged') {
count = rows.length;
document.title = count+' '+hm_trans('Flagged');
}
else if (getListPathParam() == 'combined_inbox') {
else if (list_path == 'combined_inbox') {
count = $('tr .unseen', tbody).length;
document.title = count+' '+hm_trans('Unread in Everything');
}
else if (getListPathParam() == 'email') {
else if (list_path == 'email') {
count = $('tr .unseen', tbody).length;
document.title = count+' '+hm_trans('Unread in Email');
}
else if (getListPathParam() == 'feeds') {
else if (list_path == 'feeds') {
count = $('tr .unseen', tbody).length;
document.title = count+' '+hm_trans('Unread in Feeds');
}
Expand Down
8 changes: 4 additions & 4 deletions modules/imap/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ function format_msg_part_row($id, $vals, $output_mod, $level, $part, $dl_args, $
if ($mobile) {
$res .= '<div class="part_size">'.$output_mod->html_safe($size);
$res .= '</div><div class="part_desc">'.$output_mod->html_safe(decode_fld($desc)).'</div>';
$res .= '<div class="download_link"><a href="?'.$dl_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'">'.$output_mod->trans('Download').'</a></div></td>';
$res .= '<div class="download_link"><a href="#" data-src="?'.$dl_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'">'.$output_mod->trans('Download').'</a></div></td>';
}
else {
$res .= '</td><td class="part_size">'.$output_mod->html_safe($size);
Expand All @@ -477,10 +477,10 @@ function format_msg_part_row($id, $vals, $output_mod, $level, $part, $dl_args, $
'</td><td class="part_charset">'.(isset($vals['attributes']['charset']) && trim($vals['attributes']['charset']) ? $output_mod->html_safe(mb_strtolower($vals['attributes']['charset'])) : '');
}
$res .= '</td><td class="part_desc">'.$output_mod->html_safe(decode_fld($desc)).'</td>';
$res .= '<td class="download_link"><a href="?'.$dl_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'">'.$output_mod->trans('Download').'</a></td>';
$res .= '<td class="download_link"><a href="#" data-src="?'.$dl_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'">'.$output_mod->trans('Download').'</a></td>';
}
if ($output_mod->get('allow_delete_attachment') && isset($vals['file_attributes']['attachment'])) {
$res .= '<td><a href="?'.$at_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'" class="remove_attachment">'.$output_mod->trans('Remove').'</a></td>';
$res .= '<td><a href="#" data-src="?'.$at_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'" class="remove_attachment">'.$output_mod->trans('Remove').'</a></td>';
}
$res .= '</tr>';
return $res;
Expand Down Expand Up @@ -641,7 +641,7 @@ function format_attachment($struct, $output_mod, $part, $dl_args, $at_args) {
$res .= '<tr><td class="part_desc" colspan="4">'.$output_mod->html_safe(decode_fld($desc)).'</td>';
$res .= '</td><td class="part_size">'.$output_mod->html_safe($size).'</td>';

$res .= '<td class="download_link"><a href="?'.$dl_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'">'.$output_mod->trans('Download').'</a></td>';
$res .= '<td class="download_link"><a href="#" data-src="?'.$dl_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'">'.$output_mod->trans('Download').'</a></td>';
if ($output_mod->get('allow_delete_attachment') && isset($vals['file_attributes']['attachment'])) {
$res .= '<td><a href="?'.$at_args.'&amp;imap_msg_part='.$output_mod->html_safe($id).'" class="remove_attachment">'.$output_mod->trans('Remove').'</a></td></tr>';
}
Expand Down
11 changes: 11 additions & 0 deletions modules/imap/js_modules/route_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ function applyImapMessageListPageHandlers(routeParams) {
imap_setup_snooze();
imap_setup_tags();

Hm_Message_List.set_row_events();

$('.core_msg_control').on("click", function(e) {
e.preventDefault();
Hm_Message_List.message_action($(this).data('action'));
});
$('.toggle_link').on("click", function(e) {
e.preventDefault();
Hm_Message_List.toggle_rows();
});

if (window.githubMessageListPageHandler) githubMessageListPageHandler(routeParams);
if (window.inlineMessageMessageListAndSearchPageHandler) inlineMessageMessageListAndSearchPageHandler(routeParams);
if (window.wpMessageListPageHandler) wpMessageListPageHandler(routeParams);
Expand Down
21 changes: 21 additions & 0 deletions modules/imap/js_modules/utils/attachements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function handleAttachementDownload() {
$('.download_link a').on("click", async function(e) {
e.preventDefault();
const loaderInstance = showLoaderToast("Downloading attachment...");
const href = $(this).data('src');
try {
await fetch(href).then(res => res.blob()).then(blob => {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'attachment';
a.click();
URL.revokeObjectURL(url);
});
} catch (error) {
Hm_Notices.show([`ERR${error.message}`]);
} finally {
loaderInstance.hide();
}
});
}
7 changes: 7 additions & 0 deletions modules/imap/js_modules/utils/messageParts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function handleViewMessagePart() {
$('.msg_part_link').on("click", function(e) {
e.preventDefault();
const messagePart = $(this).data('messagePart');
get_message_content(messagePart, getMessageUidParam() ?? inline_msg_uid, getListPathParam());
});
}
8 changes: 7 additions & 1 deletion modules/imap/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,9 @@ var setup_imap_folder_page = async function(listPath) {
await select_imap_folder(listPath, true, true)
}

// Update browser title
Hm_Message_List.update_title(listPath);

// Refresh in the background each 30 seconds and abort any pending request when the page unmounts
const backgroundAbortController = new AbortController();
const interval = setInterval(async () => {
Expand Down Expand Up @@ -684,7 +687,7 @@ var get_message_content = function(msg_part, uid, list_path, detail, callback, n
{'name': 'folder', 'value': detail.folder}],
function(res) {
onSuccess(res);
if (!noupdate) {
if (!noupdate && !msg_part) {
Hm_Utils.save_to_local_storage(getMessageStorageKey(uid), JSON.stringify(res));
}
},
Expand Down Expand Up @@ -846,6 +849,9 @@ var imap_message_view_finished = function(msg_uid, detail, skip_links) {
return block_unblock_sender(msg_uid, detail, $(this).data('target'), 'unblock', sender);
});
fixLtrInRtl();

handleAttachementDownload();
handleViewMessagePart();
};

var get_local_message_content = function(msg_uid, path) {
Expand Down
2 changes: 0 additions & 2 deletions modules/inline_message/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ var get_inline_msg_details = function(link) {
};

var msg_inline_close = function() {
$('.refresh_link').trigger('click');
if (inline_msg_style() == 'right') {
$('.msg_text').remove();
$('.message_table').css('width', '100%');
Expand Down Expand Up @@ -126,7 +125,6 @@ var capture_subject_click = function() {
var inline_msg_loaded_callback = function() {
$('.header_subject th').append('<i class="bi bi-x-lg close_inline_msg"></i>');
$('.close_inline_msg').on("click", function() { msg_inline_close(); });
$('.msg_part_link').on("click", function() { return get_message_content($(this).data('messagePart'), uid, list_path, details, inline_msg_loaded_callback, false, $(this).data('allowImages')); });
update_imap_links(uid, details);
};

Expand Down
3 changes: 2 additions & 1 deletion scripts/config_gen.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ function get_module_assignments($settings) {
$js .= file_get_contents($js_module);
}
}
foreach (glob('modules' . DIRECTORY_SEPARATOR . $mod . DIRECTORY_SEPARATOR . 'js_modules' . DIRECTORY_SEPARATOR . '*.js') as $js_module) {
$directoriesPattern = str_replace('/', DIRECTORY_SEPARATOR, "{*,*/*}");
foreach (glob('modules' . DIRECTORY_SEPARATOR . $mod . DIRECTORY_SEPARATOR . 'js_modules' . DIRECTORY_SEPARATOR . $directoriesPattern . '*.js', GLOB_BRACE) as $js_module) {
$js .= file_get_contents($js_module);
}
if (is_readable(sprintf("modules/%s/site.js", $mod))) {
Expand Down
2 changes: 1 addition & 1 deletion tests/selenium/folder_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def hide_folders(self):
self.driver.execute_script("arguments[0].click();", hide_button)
assert self.by_class('folder_toggle').text.startswith('Show folders')
list_item = self.by_class('menu_home')
link = list_item.find_element(By.TAG_NAME, 'a');
link = list_item.find_element(By.TAG_NAME, 'a')
assert link.is_displayed() == False

def show_folders(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/selenium/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def folders(self):
list_item.find_element(By.TAG_NAME, 'a').click()
self.wait_with_folder_list()
self.safari_workaround()
self.wait(By.CLASS_NAME, 'content_title')
self.wait_for_navigation_to_complete()
assert self.by_class('content_title').text == 'Folders'

def save(self):
Expand Down Expand Up @@ -156,6 +156,7 @@ def profiles(self):
list_item.find_element(By.TAG_NAME, 'a').click()
self.wait_with_folder_list()
self.safari_workaround()
self.wait_for_navigation_to_complete()
assert self.by_class('profile_content_title').text == 'Profiles'

if __name__ == '__main__':
Expand Down
1 change: 1 addition & 0 deletions tests/selenium/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def __init__(self):
self.wait()

def load_settings_page(self):
self.wait_on_class('main_menu')
self.by_css('[data-source=".settings"]').click()
list_item = self.by_class('menu_settings')
list_item.find_element(By.TAG_NAME, 'a').click()
Expand Down

0 comments on commit 2de1754

Please sign in to comment.