Skip to content

Commit

Permalink
fix(frontend/backend): address some of the many blocking issues (#1443)
Browse files Browse the repository at this point in the history
* fix(frontend): prevent Cypht-related mobile nav CSS attributes from overriding third-party styles

* fix(backend): showing server sieve capabilities

* fix(frontend): git revision link not opening the remote url

* fix(frontend): fadeOutAndRemove should not only be extended to cash but also to jQuery

* fix(frontend): refresh ui state when adding a server

* fix(backend): adding accounts via files imports

* fix(backend): downloading server accounts sample files in third-party softwares

* fix elements spacing of the search page

* fix(backend): offline error message when hihandling a message action or deleting a folder

* fix(frontend): hide the refresh icon on the search page as it's replaced by the update button

* fix(frontend): delete a saved search term

* fix(backend): undefined array key warnings when listing folders' messages

* fix(frontend): ensure that a search operation updates the cached pages results

* fix(frontend): ensure that a filter operation updates the cached pages results

* fix(frontend): when opening an unread message, the counter does not get updated

* fix(frontend): Snooze - Pick a date does not show a date picke

* fix(frontend): remove the deleted message from the store when a delete action has been performed
  • Loading branch information
mercihabam authored Feb 17, 2025
1 parent 62e9174 commit 3c0db75
Show file tree
Hide file tree
Showing 29 changed files with 205 additions and 120 deletions.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
define('SITE_ID', '');
define('JS_HASH', '');
define('CSS_HASH', '');
define('ASSETS_PATH', APP_PATH.'assets/');

/* show all warnings in debug mode */
if (DEBUG_MODE) {
Expand Down
15 changes: 13 additions & 2 deletions modules/core/js_modules/Hm_MessagesStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class Hm_MessagesStore {
* @property {RowObject} 1 - An object containing the row message and the IMAP key
*/

constructor(path, page = 1, rows = {}, abortController = new AbortController()) {
constructor(path, page = 1, filter = '', rows = {}, abortController = new AbortController()) {
this.path = path;
this.list = path + '_' + page;
this.list = path + '_' + (filter ? filter + '_': '') + page;
this.rows = rows;
this.count = 0;
this.flagAsReadOnOpen = true;
Expand Down Expand Up @@ -140,6 +140,17 @@ class Hm_MessagesStore {
}

}

updateRow(uid, html) {
const rows = Object.entries(this.rows);
const row = this.getRowByUid(uid)?.value;
if (row) {
const objectRows = Object.fromEntries(rows);
objectRows[row[0]]['0'] = html;
this.rows = objectRows;
this.#saveToLocalStorage();
}
}

#fetch(hideLoadingState = false) {
return new Promise((resolve, reject) => {
Expand Down
8 changes: 0 additions & 8 deletions modules/core/js_modules/[cash]/extend.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,6 @@ $.fn.fadeOut = function(timeout = 600) {
return this.css("opacity", 0)
.css("transition", `opacity ${timeout}ms`)
};
$.fn.fadeOutAndRemove = function(timeout = 600) {
this.fadeOut(timeout)
var tm = setTimeout(() => {
this.remove();
clearTimeout(tm)
}, timeout);
return this;
};

$.fn.modal = function(action) {
const modalElement = this[0];
Expand Down
8 changes: 4 additions & 4 deletions modules/core/js_modules/actions/pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async function nextPage() {

const nextPage = parseInt(currentPage) + 1;

const store = new Hm_MessagesStore(getListPathParam(), currentPage);
const store = new Hm_MessagesStore(getListPathParam(), currentPage, `${getParam('keyword')}_${getParam('filter')}`);
store.load(false, false, true);

await changePage(nextPage, this, store.offsets);
Expand All @@ -33,7 +33,7 @@ async function previousPage() {

let offsets = '';
if (previousPage > 1) {
const store = new Hm_MessagesStore(getListPathParam(), previousPage - 1);
const store = new Hm_MessagesStore(getListPathParam(), previousPage - 1, `${getParam('keyword')}_${getParam('filter')}`);
store.load(false, false, true);
offsets = store.offsets;
}
Expand Down Expand Up @@ -61,11 +61,11 @@ async function changePage(toPage, button, offsets) {
history.pushState(history.state, "", url.toString());
window.location.next = url.search;

const messagesStore = new Hm_MessagesStore(getListPathParam(), toPage);
const messagesStore = new Hm_MessagesStore(getListPathParam(), toPage, `${getParam('keyword')}_${getParam('filter')}`);
try {
await messagesStore.load();
Hm_Utils.tbody().attr('id', messagesStore.list);
display_imap_mailbox(messagesStore.rows, null, messagesStore.list);
display_imap_mailbox(messagesStore.rows, null, messagesStore.list, messagesStore);
$(".pagination .current").text(toPage);
} catch (error) {
Hm_Notices.show("Failed to fetch content", "danger");
Expand Down
6 changes: 3 additions & 3 deletions modules/core/js_modules/actions/sortCombinedLists.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ async function sortCombinedLists(sortValue) {
const url = new URL(window.location.href);
url.searchParams.set('sort', sortValue);

history.pushState(null, null, url.toString());
history.pushState(history.state, null, url.toString());
location.next = url.search;
const messagesStore = new Hm_MessagesStore(getListPathParam(), getParam('page'));
const messagesStore = new Hm_MessagesStore(getListPathParam(), getParam('page'), `${getParam('keyword')}_${getParam('filter')}`);
try {
await messagesStore.load(true);
Hm_Utils.tbody().attr('id', messagesStore.list);
display_imap_mailbox(messagesStore.rows, null, messagesStore.list);
display_imap_mailbox(messagesStore.rows, messagesStore.list, messagesStore);
} catch (error) {
Hm_Notices.show('Failed to load messages', 'danger');
}
Expand Down
2 changes: 1 addition & 1 deletion modules/core/js_modules/route_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function applyInfoPageHandlers() {
function applyMessaleListPageHandlers(routeParams) {
sortHandlerForMessageListAndSearchPage();
Hm_Message_List.set_row_events();
const messagesStore = new Hm_MessagesStore(routeParams.list_path, routeParams.list_page);
const messagesStore = new Hm_MessagesStore(routeParams.list_path, routeParams.list_page, `${routeParams.keyword}_${routeParams.filter}`);
Hm_Utils.tbody().attr('id', messagesStore.list);

$('.core_msg_control').on("click", function(e) {
Expand Down
4 changes: 2 additions & 2 deletions modules/core/js_modules/utils/sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ function handleMessagesDragAndDrop() {
{'name': 'imap_move_page', 'value': page},
{'name': 'imap_move_action', 'value': 'move'}],
async (res) =>{
const store = new Hm_MessagesStore(getListPathParam(), Hm_Utils.get_url_page_number());
const store = new Hm_MessagesStore(getListPathParam(), Hm_Utils.get_url_page_number(), `${getParam('keyword')}_${getParam('filter')}`);
await store.load(false, true, true);
const moveResponses = Object.values(res['move_responses']);
moveResponses.forEach((response) => {
store.removeRow(response.oldUid);
});
display_imap_mailbox(store.rows, store.list);
display_imap_mailbox(store.rows, store.list, store);
}
);

Expand Down
4 changes: 2 additions & 2 deletions modules/core/message_list_functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ function message_since_dropdown($since, $name, $output_mod, $original_default_va
'-1 year' => 'Last year',
'-5 years' => 'Last 5 years'
);
$res = '<select name="'.$name.'" id="'.$name.'" class="message_list_since form-select form-select-sm w-auto" data-default-value="'.$original_default_value.'">';
$res = '<select name="'.$name.'" id="'.$name.'" class="message_list_since form-select form-select-sm" data-default-value="'.$original_default_value.'">';
$reset = '';
foreach ($times as $val => $label) {
$res .= '<option';
Expand Down Expand Up @@ -606,7 +606,7 @@ function search_field_selection($current, $output_mod) {
'TO' => 'To',
'CC' => 'Cc',
);
$res = '<select class="form-select form-select-sm w-auto" id="search_fld" name="search_fld">';
$res = '<select class="form-select form-select-sm" id="search_fld" name="search_fld">';
foreach ($flds as $val => $name) {
$res .= '<option ';
if ($current == $val) {
Expand Down
8 changes: 6 additions & 2 deletions modules/core/navigation/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ window.addEventListener('popstate', function(event) {
$('#cypht-main').replaceWith(event.state.main);
loadCustomScripts(event.state.head);
}

window.location.next = window.location.search;

const unMountCallback = renderPage(window.location.href);

if (unMountCallback) {
Expand Down Expand Up @@ -44,8 +47,8 @@ $(document).on('click', 'a', function(event) {
}
});

async function navigate(url) {
showRoutingToast();
async function navigate(url, loaderMessage) {
showRoutingToast(loaderMessage);

try {
const response = await fetch(url, {
Expand Down Expand Up @@ -114,6 +117,7 @@ function renderPage(href) {
if (page) {
const route = ROUTES.find(route => route.page === page);
const routeParams = Object.fromEntries(searchParams.entries());

if (route) {
const unMountCallback = route.handler(routeParams, url.hash?.substring(1));
return unMountCallback;
Expand Down
13 changes: 7 additions & 6 deletions modules/core/navigation/utils.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
function showRoutingToast() {
function showRoutingToast(message = 'Redirecting...') {
if (window.routingToast) hideRoutingToast();
window.routingToast = showLoaderToast('Redirecting...');
window.routingToast = showLoaderToast(message);
}

function hideRoutingToast() {
window.routingToast?.hide();
window.routingToast = null;
}

// Undefined is used as the default value instead of null to comply with the route handlers, which also use undefined as the default value.
function getListPathParam() {
return new URLSearchParams(window.location.search).get('list_path')
return new URLSearchParams(window.location.next || window.location.search).get('list_path') ?? undefined;
}

function getMessageUidParam() {
return new URLSearchParams(window.location.search).get('uid')
return new URLSearchParams(window.location.next || window.location.search).get('uid') ?? undefined;
}

function getPageNameParam() {
return new URLSearchParams(window.location.search).get('page')
return new URLSearchParams(window.location.next || window.location.search).get('page') ?? undefined;
}

function getParam(param) {
return new URLSearchParams(window.location.search).get(param)
return new URLSearchParams(window.location.next || window.location.search).get(param) ?? undefined;
}
24 changes: 20 additions & 4 deletions modules/core/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ button {
padding-bottom: 10px;
padding-top: 20px;
letter-spacing: -1px;
gap: 1rem;
}
.header_subject .content_title {
color: #555;
Expand Down Expand Up @@ -737,6 +738,7 @@ button {
color: #999;
display: inline;
padding-left: 15px;
width: 100%;
}
.search_form input,
.search_form select {
Expand Down Expand Up @@ -985,6 +987,8 @@ div.unseen,
display: flex;
max-height: 35rem;
align-items: center;
flex-wrap: wrap;
gap: 0.5rem;
}
.mobile .list_meta,
.mobile .search_form {
Expand Down Expand Up @@ -1095,20 +1099,24 @@ div.unseen,
margin: 0px;
margin-top: 5px;
}
.mobile .search_form > form {
flex-wrap: wrap;
gap: 0.5rem;
}
.mobile .search_form label {
display: none;
}
.mobile .search_update {
clear: both;
}
.mobile .search_content .refresh_list {
display: none;
.mobile .search_content .list_controls {
display: none !important;
}
.mobile .search_content .content_title {
max-height: 500px;
}
.mobile .search_form select {
width: 30px;
width: calc(50% - 0.5rem);
}
.mobile .search_content {
padding-top: 30px;
Expand Down Expand Up @@ -1381,7 +1389,7 @@ div.unseen,
--bs-popover-header-color: var(--bs-white);
}

.mobile nav {
.mobile nav.folder_cell {
position: absolute;
inset: 0;
width: 100%;
Expand Down Expand Up @@ -1500,3 +1508,11 @@ a[disabled] {
background-color: var(--bs-primary);
color: var(--bs-white);
}

.mobile .search_content .message_table {
margin-top: 10rem;
}

.search_content .refresh_link {
display: none;
}
41 changes: 30 additions & 11 deletions modules/core/site.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
'use strict';

$.fn.fadeOutAndRemove = function(timeout = 600) {
this.fadeOut(timeout)
var tm = setTimeout(() => {
this.remove();
clearTimeout(tm)
}, timeout);
return this;
};

/* swipe event handler */
var swipe_event = function(el, callback, direction) {
var start_x, start_y, dist_x, dist_y, threshold = 150, restraint = 100,
Expand Down Expand Up @@ -238,13 +247,11 @@ var Hm_Ajax_Request = function() { return {
if (res.folder_status) {
for (const name in res.folder_status) {
if (name === getListPathParam()) {
Hm_Folders.unread_counts[name] = res.folder_status[name]['unseen'];
Hm_Folders.update_unread_counts();
const messages = new Hm_MessagesStore(name, Hm_Utils.get_url_page_number());
const messages = new Hm_MessagesStore(name, Hm_Utils.get_url_page_number(), `${getParam('keyword')}_${getParam('filter')}`);
messages.load().then(() => {
if (messages.count != res.folder_status[name].messages) {
messages.load(true).then(() => {
display_imap_mailbox(messages.rows, messages.list);
display_imap_mailbox(messages.rows, messages.list, messages);
})
}
});
Expand Down Expand Up @@ -566,11 +573,21 @@ function Message_List() {
fixLtrInRtl();
};

this.update = function(msgs, id) {
this.update = function(msgs, id, store) {
Hm_Utils.tbody(id).html('');
for (const index in msgs) {
const row = msgs[index][0];
Hm_Utils.tbody(id).append(row);
Hm_Utils.tbody(id).append(row).find('a').each(function() {
const link = $(this);
const filterParams = ["keyword", "filter"];
const url = new URL(link.attr('href'), location.href);
filterParams.forEach(param => {
url.searchParams.set(param, getParam(param));
});
link.attr('href', url.toString());
const row = link.closest('tr');
store.updateRow(row.data('uid'), row.prop('outerHTML'));
});
}
};

Expand Down Expand Up @@ -712,6 +729,11 @@ function Message_List() {
var class_name = false;
var index;
for (index in selected) {
const uid = selected[index].split('_')[2];
const store = new Hm_MessagesStore(getListPathParam(), Hm_Utils.get_url_page_number(), `${getParam('keyword')}_${getParam('filter')}`);
store.load();
store.removeRow(uid);

class_name = selected[index];
$('.'+Hm_Utils.clean_selector(class_name)).remove();
if (action_type == 'delete') {
Expand Down Expand Up @@ -899,17 +921,14 @@ function Message_List() {
true
);
}
if (!updated) {
self.update_after_action(action_type, selected);
}
};

this.prev_next_links = function(msgUid, lisPath = getListPathParam()) {
let prevUrl;
let nextUrl;

const target = $('.msg_headers tr').last();
const messages = new Hm_MessagesStore(lisPath, Hm_Utils.get_url_page_number());
const messages = new Hm_MessagesStore(lisPath, Hm_Utils.get_url_page_number(), `${getParam('keyword')}_${getParam('filter')}`);
messages.load(false, true);
const next = messages.getNextRowForMessage(msgUid);
const prev = messages.getPreviousRowForMessage(msgUid);
Expand Down Expand Up @@ -1483,7 +1502,7 @@ var Hm_Utils = {
if (force_on) {
$(class_name).css('display', 'none');
}
$(class_name).toggle();
$(`[data-bs-target="${class_name}"]`).trigger('click');
Hm_Utils.save_to_local_storage('formatted_folder_list', $('.folder_list').html());
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion modules/developer/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ protected function output() {
'<tr><th class="text-secondary fw-light text-nowrap">Zend version</th><td>'.$server_info['zend_version'].'</td></tr>'.
'<tr><th class="text-secondary fw-light text-nowrap">SAPI</th><td>'.$server_info['sapi'].'</td></tr>'.
'<tr><th class="text-secondary fw-light text-nowrap">Enabled Modules</th><td>'.str_replace(',', ', ', implode(',', $this->get('router_module_list'))).'</td></tr>'.
'<tr><th class="text-secondary fw-light text-nowrap">Git version</th><td>'.$server_info['branch_name'].' at revision <a href="'.$server_info['commit_url'].'">'.$server_info['commit_hash'].'</a> ('.$server_info['commit_date'].')</td></tr>'.
'<tr><th class="text-secondary fw-light text-nowrap">Git version</th><td>'.$server_info['branch_name'].' at revision <a href="'.$server_info['commit_url'].'" data-external="true">'.$server_info['commit_hash'].'</a> ('.$server_info['commit_date'].')</td></tr>'.
'</table></div>';
}
return '';
Expand Down
Loading

0 comments on commit 3c0db75

Please sign in to comment.