Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement browser history API based navigation, preventing page reloads between routings #1266

Merged
merged 27 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b21b1c3
Implement browser history API based navigation, preventing browser re…
mercihabam Oct 2, 2024
6ae9ba4
A couple of fixes and refinements to the navigation module ensuring t…
mercihabam Oct 3, 2024
2ea908b
Apply servers and settings page handlers
mercihabam Oct 3, 2024
aa538eb
Apply handlers on page load as well
mercihabam Oct 3, 2024
4d4bc0a
Update the sidebar item's active state when navigating
mercihabam Oct 4, 2024
6eb67a3
Fix displaying the message content with the correct route params
mercihabam Oct 4, 2024
ae11804
Move entire imap_folder_page_setup the the message list route handler
mercihabam Oct 4, 2024
ef98763
Fix refresh links
mercihabam Oct 4, 2024
4a9e66b
Fix sorting and filtering of messages
mercihabam Oct 5, 2024
72882c6
imap unread handler: allow fetching the messages from the connected s…
mercihabam Oct 7, 2024
f581e6e
Hm_MessagesStore supports combined unread folder
mercihabam Oct 7, 2024
cacd84d
Avoid an endless loop of request callbacks
mercihabam Oct 7, 2024
33fc912
Load customized folders' content upon navigation
mercihabam Oct 7, 2024
567a95d
Flagged contents are displayed
mercihabam Oct 8, 2024
88b175e
Combined inbox contents are displayed
mercihabam Oct 8, 2024
86e5271
Output correct server ids
mercihabam Oct 8, 2024
5550e3b
Avoid fetching with the previous page href
mercihabam Oct 8, 2024
2a79164
Refresh the message list in the backround on page load if the store h…
mercihabam Oct 8, 2024
9bce1dd
Add a process to refresh the active message list in the background
mercihabam Oct 8, 2024
e12fa71
Move Hm_MessagesStore to the core module, and move some remanants cod…
mercihabam Oct 9, 2024
56948df
Final move of the remnants of the code previously handled by hm_list_…
mercihabam Oct 10, 2024
001e471
Ensure the unmount callback is regularlly called whenever a page loos…
mercihabam Oct 10, 2024
f08f8fa
Abort background processes relative to a page when it's unmounted
mercihabam Oct 10, 2024
28f1285
Automate the page_js_debug test to include all given js files in the …
mercihabam Oct 11, 2024
65a96ff
Add navigation modules to the production site.js
mercihabam Oct 16, 2024
69af23b
Fix: wait for the navigation to complete before asserting elements pr…
mercihabam Oct 16, 2024
9563331
Use common files path pattern
mercihabam Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions modules/advanced_search/js_modules/route_handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
function applyAdvancedSearchPageHandlers() {
globals.close_html = '<i class="bi bi-x-circle-fill cursor-pointer"></i>';

$('.settings_subtitle').on("click", function() { return Hm_Utils.toggle_page_section($(this).data('target')); });
$('.adv_folder_select').on("click", function() { adv_select_imap_folder(this); });
$('.new_time').on("click", function() { add_remove_times(this); });
$('.new_target').on("click", function() { add_remove_targets(this); });
$('.new_term').on("click", function() { add_remove_terms(this); });
$('.adv_expand_all').on("click", function() { adv_expand_sections(); });
$('.adv_collapse_all').on("click", function() { adv_collapse(); });
$('#adv_search').on("click", function() { process_advanced_search(); });
$('.toggle_link').on("click", function() { return Hm_Message_List.toggle_rows(); });
$('.adv_reset').on("click", function() { adv_reset_page(); });
$('.combined_sort').on("change", function() { Hm_Message_List.sort($(this).val()); });

apply_saved_search();
var data = Hm_Utils.get_from_local_storage('formatted_advanced_search_data');
if (data && data.length) {
adv_collapse();
Hm_Utils.tbody().html(data);
$('.adv_controls').show();
$('.core_msg_control').off('click');
$('.core_msg_control').on("click", function() { return Hm_Message_List.message_action($(this).data('action')); });
Hm_Message_List.set_checkbox_callback();
if (typeof check_select_for_imap !== 'undefined') {
check_select_for_imap();
}
}
Hm_Message_List.check_empty_list();
}
34 changes: 0 additions & 34 deletions modules/advanced_search/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,37 +514,3 @@ var adv_reset_page = function() {
Hm_Utils.save_to_local_storage('adv_search_params', '');
document.location.href = '?page=advanced_search';
};

$(function() {
if (hm_page_name() == 'advanced_search') {

globals.close_html = '<i class="bi bi-x-circle-fill cursor-pointer"></i>';

$('.settings_subtitle').on("click", function() { return Hm_Utils.toggle_page_section($(this).data('target')); });
$('.adv_folder_select').on("click", function() { adv_select_imap_folder(this); });
$('.new_time').on("click", function() { add_remove_times(this); });
$('.new_target').on("click", function() { add_remove_targets(this); });
$('.new_term').on("click", function() { add_remove_terms(this); });
$('.adv_expand_all').on("click", function() { adv_expand_sections(); });
$('.adv_collapse_all').on("click", function() { adv_collapse(); });
$('#adv_search').on("click", function() { process_advanced_search(); });
$('.toggle_link').on("click", function() { return Hm_Message_List.toggle_rows(); });
$('.adv_reset').on("click", function() { adv_reset_page(); });
$('.combined_sort').on("change", function() { Hm_Message_List.sort($(this).val()); });

apply_saved_search();
var data = Hm_Utils.get_from_local_storage('formatted_advanced_search_data');
if (data && data.length) {
adv_collapse();
Hm_Utils.tbody().html(data);
$('.adv_controls').show();
$('.core_msg_control').off('click');
$('.core_msg_control').on("click", function() { return Hm_Message_List.message_action($(this).data('action')); });
Hm_Message_List.set_checkbox_callback();
if (typeof check_select_for_imap !== 'undefined') {
check_select_for_imap();
}
}
Hm_Message_List.check_empty_list();
}
});
2 changes: 1 addition & 1 deletion modules/calendar/hm-calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private function output_event($day) {
$res .= '<div class="cal_event">'.
$this->output_event_details($event).
$this->output_mod->html_safe(date('H:i', $event['ts'])).
' <a class="cal_title cursor-pointer">'.$this->output_mod->html_safe($event['title']).
' <a class="cal_title cursor-pointer" href="#">'.$this->output_mod->html_safe($event['title']).
'</a></div>';
}
return $res;
Expand Down
15 changes: 15 additions & 0 deletions modules/calendar/js_modules/route_handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function applyCalendarPageHandlers() {
$('.event_delete').on("click", function() {
if (hm_delete_prompt()) {
$(this).parent().submit();
}
});
$('.cal_title').on("click", function(e) {
e.preventDefault();
$('.event_details').hide();
$('.event_details', $(this).parent()).show();
$('.event_details').on("click", function() {
$(this).hide();
});
});
}
17 changes: 0 additions & 17 deletions modules/calendar/site.js
Original file line number Diff line number Diff line change
@@ -1,18 +1 @@
'use strict';

$(function() {
if (hm_page_name() == 'calendar') {
$('.event_delete').on("click", function() {
if (hm_delete_prompt()) {
$(this).parent().submit();
}
});
$('.cal_title').on("click", function() {
$('.event_details').hide();
$('.event_details', $(this).parent()).show();
$('.event_details').on("click", function() {
$(this).hide();
});
});
}
});
33 changes: 33 additions & 0 deletions modules/contacts/js_modules/route_handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
function applyContactsPageHandlers() {
$('.delete_contact').on("click", function() {
delete_contact($(this).data('id'), $(this).data('source'), $(this).data('type'));
return false;
});
$('.show_contact').on("click", function() {
$('#'+$(this).data('id')).toggle();
return false;
});
$('.reset_contact').on("click", function() {
Hm_Utils.redirect('?page=contacts');
});
$('.server_title').on("click", function() {
$(this).next().toggle();
});
$('#contact_phone').on("keyup", function() {
let contact_phone = $('#contact_phone').val();
const regex_number = new RegExp('^\\d+$');
const allowed_characters = ['+','-','(',')'];
for (let chain_counter = 0; chain_counter < contact_phone.length; chain_counter++) {
if(!(regex_number.test(contact_phone[chain_counter])) && !(allowed_characters.indexOf(contact_phone[chain_counter]) > -1)){
Hm_Notices.show([hm_trans("This phone number appears to contain invalid character (s).\nIf you are sure ignore this warning and continue!")]);
$(this).off();
}
}

});
$('.source_link').on("click", function () {
$('.list_actions').toggle(); $('#list_controls_menu').hide();
return false;
});
contact_import_pagination();
}
44 changes: 2 additions & 42 deletions modules/contacts/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ var add_contact_from_popup = function(event) {
{'name': 'contact_source', 'value': source}],
function (res) {
$("#contact_popup_body").html(saveContactContent);
sessionStorage.removeItem(`${window.location.pathname}imap_4_${hm_list_path()}`);
sessionStorage.removeItem(`${window.location.pathname}${hm_msg_uid()}_${hm_list_path()}`);
sessionStorage.removeItem(`${window.location.pathname}imap_4_${getListPathParam()}`);
sessionStorage.removeItem(`${window.location.pathname}${getMessageUidParam()}_${getListPathParam()}`);
}
);
}
Expand Down Expand Up @@ -263,43 +263,3 @@ var check_cc_exist_in_contacts_list = function() {
}
return "";
};

if (hm_page_name() == 'contacts') {
$('.delete_contact').on("click", function() {
delete_contact($(this).data('id'), $(this).data('source'), $(this).data('type'));
return false;
});
$('.show_contact').on("click", function() {
$('#'+$(this).data('id')).toggle();
return false;
});
$('.reset_contact').on("click", function() {
Hm_Utils.redirect('?page=contacts');
});
$('.server_title').on("click", function() {
$(this).next().toggle();
});
$('#contact_phone').on("keyup", function() {
let contact_phone = $('#contact_phone').val();
const regex_number = new RegExp('^\\d+$');
const allowed_characters = ['+','-','(',')'];
for (let chain_counter = 0; chain_counter < contact_phone.length; chain_counter++) {
if(!(regex_number.test(contact_phone[chain_counter])) && !(allowed_characters.indexOf(contact_phone[chain_counter]) > -1)){
Hm_Notices.show([hm_trans("This phone number appears to contain invalid character (s).\nIf you are sure ignore this warning and continue!")]);
$(this).off();
}
}

});
$('.source_link').on("click", function () {
$('.list_actions').toggle(); $('#list_controls_menu').hide();
return false;
});
contact_import_pagination();
}
else if (hm_page_name() == 'compose') {
$('.compose_to').on('keyup', function(e) { autocomplete_contact(e, '.compose_to', '#to_contacts'); });
$('.compose_cc').on('keyup', function(e) { autocomplete_contact(e, '.compose_cc', '#cc_contacts'); });
$('.compose_bcc').on('keyup', function(e) { autocomplete_contact(e, '.compose_bcc', '#bcc_contacts'); });
$('.compose_to').focus();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,29 @@ class Hm_MessagesStore {
* @property {RowObject} 1 - An object containing the row message and the IMAP key
*/

constructor(path, page, rows = {}) {
constructor(path, page = 1, rows = {}, abortController = new AbortController()) {
this.path = path;
this.list = path + '_' + page;
this.rows = rows;
this.links = "";
this.count = 0;
this.flagAsReadOnOpen = true;
this.abortController = abortController;
}

/**
* Check if the store has data for the current instance
* @returns {Boolean}
*/
hasLocalData() {
return this.#retrieveFromLocalStorage() !== false;
}

/**
*
* @returns {Promise<Array<String>>}
* @returns {Promise<this>}
*/
async load(reload = false, hideLoadingState = false) {
async load(reload = false, hideLoadingState = false, doNotFetch = false) {
const storedMessages = this.#retrieveFromLocalStorage();
if (storedMessages && !reload) {
this.rows = storedMessages.rows;
Expand All @@ -38,9 +47,13 @@ class Hm_MessagesStore {
return this;
}

if (doNotFetch) {
return this;
}

const { formatted_message_list: updatedMessages, page_links: pageLinks, folder_status, do_not_flag_as_read_on_open } = await this.#fetch(hideLoadingState);

this.count = Object.values(folder_status)[0].messages;
this.count = folder_status && Object.values(folder_status)[0]?.messages;
this.links = pageLinks;
this.rows = updatedMessages;
this.flagAsReadOnOpen = !do_not_flag_as_read_on_open;
Expand Down Expand Up @@ -112,25 +125,61 @@ class Hm_MessagesStore {
}

#fetch(hideLoadingState = false) {
const detail = Hm_Utils.parse_folder_path(this.path, 'imap');
return new Promise((resolve, reject) => {
Hm_Ajax.request(
[
{ name: "hm_ajax_hook", value: "ajax_imap_folder_display" },
{ name: "imap_server_id", value: detail.server_id },
{ name: "folder", value: detail.folder },
],
this.#getRequestConfig(),
(response) => {
resolve(response);
},
[],
hideLoadingState,
undefined,
reject
reject,
this.abortController?.signal
);
});
}

#getRequestConfig() {
let hook;
let serverId;
let folder;
const config = [];
if (this.path.startsWith('imap')) {
hook = "ajax_imap_folder_display";
const detail = Hm_Utils.parse_folder_path(this.path, 'imap');
serverId = detail.server_id;
folder = detail.folder;
} else {
switch (this.path) {
case 'unread':
hook = "ajax_imap_unread";
break;
case 'flagged':
hook = "ajax_imap_flagged";
break;
case 'combined_inbox':
case 'email':
hook = "ajax_imap_combined_inbox";
break;
default:
hook = "ajax_imap_folder_data";
break;
}
}

if (hook) {
config.push({ name: "hm_ajax_hook", value: hook });
}
if (serverId) {
config.push({ name: "imap_server_id", value: serverId });
}
if (folder) {
config.push({ name: "folder", value: folder });
}
return config;
}

#saveToLocalStorage() {
Hm_Utils.save_to_local_storage(this.list, JSON.stringify({ rows: this.rows, links: this.links, count: this.count }));
Hm_Utils.save_to_local_storage('flagAsReadOnOpen', this.flagAsReadOnOpen);
Expand Down
58 changes: 58 additions & 0 deletions modules/core/js_modules/route_handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
function applyServersPageHandlers() {
$('.server_section').on("click", function() { return Hm_Utils.toggle_page_section($(this).data('target')); });
$('.edit_server_connection').on('click', imap_smtp_edit_action);
// NUX
expand_server_settings();
$('.nux_next_button').on("click", nux_service_select);
$('#service_select').on("change", function() {
if ($(this).val() == 'all-inkl') {
add_extra_fields(this, 'all_inkl_login', 'Login', hm_trans('Your All-inkl Login'));
} else {
$('.nux_extra_fields_container').remove();
}
});

// Optional modules
if (window.feedServersPageHandler) feedServersPageHandler();
if (window.githubServersPageHandler) githubServersPageHandler();
if (window.nasaServersPageHandler) nasaServersPageHandler();
if (window.smtpServersPageHandler) smtpServersPageHandler();
if (window.wpServersPageHandler) wpServersPageHandler();
}

function applySettingsPageHandlers() {
Hm_Utils.expand_core_settings();
$('.settings_subtitle').on("click", function() { return Hm_Utils.toggle_page_section($(this).data('target')); });
$('.reset_default_value_checkbox').on("click", reset_default_value_checkbox);
$('.reset_default_value_select').on("click", reset_default_value_select);
$('.reset_default_value_input').on("click", reset_default_value_input);
$('.reset_default_timezone').on("click", reset_default_timezone);

if (window.expand_feed_settings) expand_feed_settings();
if (window.smtpSettingsPageHandler) smtpSettingsPageHandler();
}

function applySearchPageHandlers(routeParams) {
Hm_Message_List.select_combined_view();
sortHandlerForMessageListAndSearchPage();
$('.search_reset').on("click", Hm_Utils.reset_search_form);

if (window.inlineMessageMessageListAndSearchPageHandler) inlineMessageMessageListAndSearchPageHandler(routeParams);
if (window.savedSearchesSearchPageHandler) savedSearchesSearchPageHandler();
}

function applyHomePageHandlers() {
$('.pw_update').on("click", function() { update_password($(this).data('id')); });
}

function applyInfoPageHandlers() {
const timer = setTimeout(() => {
imap_status_update();
if (window.feed_status_update) feed_status_update();
if (window.github_repo_update) github_repo_update();
}, 100);

return () => {
clearTimeout(timer);
}
}
Loading
Loading