aboutsummaryrefslogtreecommitdiffstats
path: root/view/js
diff options
context:
space:
mode:
Diffstat (limited to 'view/js')
-rw-r--r--view/js/acl.js12
-rw-r--r--view/js/autocomplete.js2
-rw-r--r--view/js/main.js1335
-rw-r--r--view/js/mod_articles.js2
-rw-r--r--view/js/mod_cards.js2
-rw-r--r--view/js/mod_cloud.js57
-rw-r--r--view/js/mod_connections.js2
-rw-r--r--view/js/mod_help.js61
-rw-r--r--view/js/mod_hq.js3
-rw-r--r--view/js/mod_import_progress.js6
-rw-r--r--view/js/mod_photos.js57
11 files changed, 989 insertions, 550 deletions
diff --git a/view/js/acl.js b/view/js/acl.js
index ee6cb062f..a96c39090 100644
--- a/view/js/acl.js
+++ b/view/js/acl.js
@@ -300,7 +300,7 @@ ACL.prototype.update_view = function(value) {
that.update_select('public');
/* jot acl */
- $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('fa-lock').addClass('fa-unlock');
+ $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('bi-lock').addClass('bi-unlock');
$('#jot-perms-icon').removeClass('jot-lock-warn');
$('#dbtn-jotnets').show();
$('.profile-jot-net input').attr('disabled', false);
@@ -314,7 +314,7 @@ ACL.prototype.update_view = function(value) {
that.update_select(that.selected_id);
/* jot acl */
- $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('fa-unlock').addClass('fa-lock');
+ $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('bi-unlock').addClass('bi-lock');
$('#dbtn-jotnets').hide();
$('.profile-jot-net input').attr('disabled', 'disabled');
}
@@ -326,7 +326,7 @@ ACL.prototype.update_view = function(value) {
that.update_select('onlyme');
/* jot acl */
- $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('fa-unlock').addClass('fa-lock');
+ $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('bi-unlock').addClass('bi-lock');
$('#dbtn-jotnets').hide();
$('.profile-jot-net input').attr('disabled', 'disabled');
}
@@ -349,7 +349,7 @@ ACL.prototype.update_view = function(value) {
}
/* jot acl */
- $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('fa-unlock').addClass('fa-lock');
+ $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('bi-unlock').addClass('bi-lock');
$('#dbtn-jotnets').hide();
$('.profile-jot-net input').attr('disabled', 'disabled');
}
@@ -366,12 +366,12 @@ ACL.prototype.update_view = function(value) {
/* jot acl */
if(that.allow_gid.length === 0 && that.allow_cid.length === 0 && that.deny_gid.length === 0 && that.deny_cid.length === 0 && value === 'custom') {
- $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('fa-lock').addClass('fa-unlock');
+ $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('bi-lock').addClass('bi-unlock');
$('#dbtn-jotnets').show();
$('.profile-jot-net input').attr('disabled', false);
}
else {
- $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('fa-unlock').addClass('fa-lock');
+ $('#jot-perms-icon, #dialog-perms-icon, #' + that.form_id[0].id + ' .jot-perms-icon').removeClass('bi-unlock').addClass('bi-lock');
$('#dbtn-jotnets').hide();
$('.profile-jot-net input').attr('disabled', 'disabled');
}
diff --git a/view/js/autocomplete.js b/view/js/autocomplete.js
index 7d6ddb1c4..ad8e04050 100644
--- a/view/js/autocomplete.js
+++ b/view/js/autocomplete.js
@@ -38,7 +38,7 @@ function contact_format(item) {
var desc = ((item.label) ? item.nick + ' ' + item.label : item.nick);
if(typeof desc === 'undefined') desc = '';
if(desc) desc = ' ('+desc+')';
- return "<div class='dropdown-item dropdown-notification lh-sm text-truncate' title='{4}'><img class='menu-img-2' src='{1}' loading='lazy'><strong>{2}</strong><br><small class='opacity-75'>{4}</small></div>".format(item.taggable, item.photo, item.name, desc, typeof(item.link) !== 'undefined' ? item.link : desc.replace('(','').replace(')',''));
+ return "<div class='dropdown-item dropdown-notification lh-sm text-truncate' title='{4}'><img class='menu-img-2' src='{1}' loading='lazy'><strong>{2}</strong><br><small class='text-body-secondary'>{4}</small></div>".format(item.taggable, item.photo, item.name, desc, typeof(item.link) !== 'undefined' ? item.link : desc.replace('(','').replace(')',''));
}
else
return "";
diff --git a/view/js/main.js b/view/js/main.js
index 7eca7408e..5bf7234aa 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -25,6 +25,11 @@ var savedTitle = '';
var followUpPageLoad = false;
var window_needs_alert = true;
var expanded_items = [];
+var updateTimeout = [];
+const singlethread_modules = ['display', 'hq'];
+const redirect_modules = ['display', 'notify'];
+let b64mids = [];
+
var page_cache = {};
@@ -58,42 +63,18 @@ $.ajaxSetup({cache: false});
var tf = new Function('n', 's', 'var k = s.split("/")['+aStr['plural_func']+']; return (k ? k : s);');
-jQuery.timeago.settings.strings = {
- prefixAgo : aStr['t01'],
- prefixFromNow : aStr['t02'],
- suffixAgo : aStr['t03'],
- suffixFromNow : aStr['t04'],
- seconds : aStr['t05'],
- minute : aStr['t06'],
- minutes : function(value){return tf(value, aStr['t07']);},
- hour : aStr['t08'],
- hours : function(value){return tf(value, aStr['t09']);},
- day : aStr['t10'],
- days : function(value){return tf(value, aStr['t11']);},
- month : aStr['t12'],
- months : function(value){return tf(value, aStr['t13']);},
- year : aStr['t14'],
- years : function(value){return tf(value, aStr['t15']);},
- wordSeparator : aStr['t16'],
- numbers : aStr['t17'],
-};
-
-jQuery.timeago.settings.allowFuture = true;
-
$(document).ready(function() {
$(document).on('click focus', '.comment-edit-form', handle_comment_form);
$(document).on('click', '.conversation-settings-link', getConversationSettings);
$(document).on('click', '#settings_module_ajax_submit', postConversationSettings);
- $(document).on('click', '#expand-aside', function() {
- toggleAside();
- });
+ $(document).on('click', '#expand-aside', toggleAside);
$(document).on('click focus', '.comment-edit-form textarea', function(e) {
if(! this.autocomplete_handled) {
/* autocomplete @nicknames */
- $(this).editor_autocomplete(baseurl+"/acl?f=&n=1");
+ $(this).editor_autocomplete(baseurl+"/acl?n=1");
/* autocomplete bbcode */
$(this).bbco_autocomplete('bbcode');
@@ -108,13 +89,153 @@ $(document).ready(function() {
}
});
+ document.addEventListener('click', function(event) {
+ // Only handle clicks on .wall-item-reaction or its children
+ const target = event.target.closest('.wall-item-reaction');
+ if (!target) return;
+
+ let doRequest = true;
+ const isUserClick = event.isTrusted;
+
+ // Destructure relevant data attributes
+ const { itemId: id, itemMid: mid, itemParent: parentId, itemUuid: uuid, itemVerb: verb } = target.dataset;
+ const isCommentBtn = target.classList.contains('wall-item-comment');
+
+ if (isCommentBtn) {
+ if (id === parentId) {
+ // Handle blog mode
+ target.classList.add('disabled');
+ document.getElementById(`load-more-progress-wrapper-${id}`).classList.remove('d-none');
+ document.getElementById(`load-more-${id}`).classList.remove('d-none')
+ request(id, mid, 'load', parentId, uuid, isUserClick);
+ return;
+ }
+
+ // Get relevant DOM elements
+ const threadWrapper = document.getElementById(`thread-wrapper-${id}`);
+ const parentWrapper = document.getElementById(`thread-wrapper-${parentId}`);
+ const subThreadWrapper = document.getElementById(`wall-item-sub-thread-wrapper-${id}`);
+ const parentSubThreadWrapper = document.getElementById(`wall-item-sub-thread-wrapper-${parentId}`);
+
+ // Query related sub-thread and highlight elements
+ const parentIndentedThreads = document.querySelectorAll(`#wall-item-sub-thread-wrapper-${parentId} .wall-item-sub-thread-wrapper.item-indent`);
+
+ let ancestorIds = [];
+
+ doRequest = !subThreadWrapper.children.length;
+
+ // Set visual styles using UUID
+ subThreadWrapper.style.setProperty('--hz-item-indent', stringToHslColor(uuid));
+ threadWrapper.style.setProperty('--hz-item-highlight', stringToHslColor(uuid));
+ threadWrapper.style.setProperty('--hz-wall-item-expanded-before-content', '"' + aStr.dblclick_to_exit_zoom + '"');
+
+ // Clear previous highlights
+ parentSubThreadWrapper.querySelectorAll('.thread-wrapper.item-highlight').forEach(el => el.classList.remove('item-highlight'));
+
+ if (isUserClick && parentIndentedThreads.length === 0 && !subThreadWrapper.children.length) {
+ // Handle first-time expansion and highlighting but not for toplevels (blog mode)
+ threadWrapper.classList.add('item-highlight');
+ } else {
+ // Handle indentation and zooming
+ let ancestor = subThreadWrapper.parentElement;
+ ancestorIds.push(ancestor.id.slice(15)); // thread-wrapper-1234
+
+ while (ancestor) {
+ if (ancestor.classList.contains('item-indent') && ancestor.classList.contains('wall-item-sub-thread-wrapper')) {
+ ancestorIds.push(ancestor.parentElement.id.slice(15));
+ }
+ ancestor = ancestor.parentElement;
+ }
+
+ ancestorIds.reverse();
+
+ if (ancestorIds.length > 3) {
+ // Handle zooming in
+ let firstWrapper = document.getElementById('thread-wrapper-' + ancestorIds[0]);
+ let firstSubWrapper = document.getElementById('wall-item-sub-thread-wrapper-' + ancestorIds[0]);
+
+ firstWrapper.querySelector('.wall-item-comment').classList.remove('indented');
+ firstWrapper.classList.remove('wall-item-expanded', 'shadow');
+ firstSubWrapper.classList.remove('item-indent');
+
+ let newFirstWrapper = document.getElementById('thread-wrapper-' + ancestorIds[1])
+ let newFirstSubWrapper = document.getElementById('wall-item-sub-thread-wrapper-' + ancestorIds[1])
+
+ newFirstWrapper.classList.add('wall-item-expanded', 'shadow');
+ parentWrapper.classList.add('wall-item-backdrop');
+
+ // Exit zoom on double-click
+ newFirstWrapper.addEventListener('dblclick', function() {
+ parentWrapper.querySelectorAll('.wall-item-comment.indented').forEach(el => el.classList.remove('indented'));
+ parentWrapper.querySelectorAll('.wall-item-comment.collapsed').forEach(el => el.classList.remove('collapsed'));
+ parentWrapper.classList.remove('wall-item-backdrop');
+ parentWrapper.querySelectorAll('.wall-item-sub-thread-wrapper.item-indent').forEach(el => el.classList.remove('item-indent'));
+ parentWrapper.querySelectorAll('.wall-item-sub-thread-wrapper.d-none').forEach(el => el.classList.remove('d-none'));
+ parentWrapper.querySelectorAll('.thread-wrapper.wall-item-expanded').forEach(el => el.classList.remove('wall-item-expanded', 'shadow'));
+ }, { once: true });
+ }
+
+ // Toggle sub-thread visibility if indented
+ if (isUserClick && target.classList.contains('indented')) {
+ doRequest = false;
+ subThreadWrapper.classList.toggle('d-none');
+ target.classList.toggle('collapsed');
+ }
+
+ // Indenting of already expanded but flattened items
+ if (isUserClick && subThreadWrapper.classList.contains('item-expanded') && !subThreadWrapper.classList.contains('item-indent')) {
+ doRequest = false;
+
+ threadWrapper.querySelectorAll('.wall-item-sub-thread-wrapper.item-expanded').forEach(function (el, i) {
+ el.classList.add('item-indent');
+
+ el.querySelectorAll('.wall-item-comment.expanded').forEach(function (el, i) {
+ el.classList.add('collapsed', 'indented');
+ });
+
+ // Collapse everything below the first level
+ if (i > 0) {
+ el.classList.add('d-none');
+ }
+ });
+ }
+
+ // Indent the subthread
+ subThreadWrapper.classList.add('item-indent', 'item-expanded');
+
+ // Mark as indented after visibility toggle
+ target.classList.add('indented');
+ }
+
+ // Mark as expanded
+ target.classList.add('expanded');
+ }
+
+ if (doRequest) {
+ request(id, mid, verb, parentId, uuid, isUserClick);
+ }
+ });
+
+ document.addEventListener('click', function(event) {
+ const targetElement = event.target.closest('.dropdown-item-expand');
+ if (!targetElement) return;
+
+ event.preventDefault();
+
+ const id = targetElement.dataset.itemId;
+ const subWrapper = document.getElementById(`wall-item-sub-thread-wrapper-${id}`);
+
+ subWrapper.innerHTML = '';
+ autoExpand(id);
+ });
+
// @hilmar |->
if ( typeof(window.tao) == 'undefined' ) {
window.tao = {};
}
if ( typeof(window.tao.zin) == 'undefined' ) {
tao.zin = { syslc: '', syslcs: {}, htm: '', me: '', debug: '' };
- tao.zin.axim = '<div class="zinpax fa fa-sync fa-spin"> </div>';
+ tao.zin.axim = '<i class="zinpax bi bi-arrow-repeat"></i>';
$('.navbar-app[href*="/lang"]').attr({"aria-expand": "true", "id": "zintog"})
.removeAttr('href').addClass('zinlcx zinlcxp dropdown dropdown-toggle').css('cursor','pointer');
$('.nav-link[href*="/lang"]').addClass('zinlcxmi zinlcx').removeAttr('href').css('cursor','pointer');
@@ -129,9 +250,9 @@ $(document).ready(function() {
tao.zin.re = JSON.parse(re);
tao.zin.syslc = tao.zin.re.lc;
tao.zin.syslcs = tao.zin.re.lcs;
- tao.zin.htm = '<ul class="zinlcs fa-ul">';
+ tao.zin.htm = '<ul class="zinlcs">';
$.each( tao.zin.syslcs, function( k, v ) {
- tao.zin.htm += '<li><a id="zinlc' + k + '" class="zinlc nav-link fakelink">' + k + ' ' + v + '</a></li>';
+ tao.zin.htm += '<li><a id="zinlc' + k + '" class="zinlc fakelink">' + k + ' ' + v + '</a></li>';
});
tao.zin.htm += '</ul>';
$('.zinpax').remove();
@@ -172,17 +293,20 @@ $(document).ready(function() {
let notify_id = this.dataset.notify_id;
let path = $(this)[0].pathname.split('/')[1];
let stateObj = { b64mid: b64mid };
- let singlethread_modules = ['display', 'hq'];
- let redirect_modules = ['display', 'notify'];
- if(! b64mid && ! notify_id)
+ if (!b64mid && !notify_id) {
return;
+ }
- if(localUser && redirect_modules.indexOf(path) !== -1) {
+ if (document.querySelector('main').classList.contains('region_1-on')) {
+ toggleAside();
+ }
+
+ if (localUser && redirect_modules.indexOf(path) !== -1) {
path = 'hq';
}
- if(notify_id) {
+ if (notify_id) {
$.ajax({
type: 'post',
url: 'notify',
@@ -198,21 +322,17 @@ $(document).ready(function() {
window.location.href = path + '/' + b64mid;
}
else {
-
if (singlethread_modules.indexOf(module) !== -1) {
history.pushState(stateObj, '', module + '/' + b64mid);
-
}
if (b64mid) {
-
e.preventDefault();
-
- if(! page_load) {
+ if (!page_load) {
prepareLiveUpdate(b64mid, notify_id);
$('.message').removeClass('active');
$('[data-b64mid="' + b64mid + '"].message').addClass('active');
- $('[data-b64mid="' + b64mid + '"].message .badge').remove();
+ $('[data-b64mid="' + b64mid + '"].message .unseen_count').remove();
}
}
}
@@ -231,44 +351,44 @@ $(document).ready(function() {
updateInit();
- var e = document.getElementById('content-complete');
- if(e)
+ if (document.getElementById('content-complete')) {
pageHasMoreContent = false;
+ }
- $(document).on('hz:updateConvItems', function(event) {
- if(!bParam_mid)
+ document.addEventListener('hz:updateConvItems', function(e) {
+ if (!bParam_mid) {
cache_next_page();
+ }
});
- $(document).on('hz:handleNetworkNotificationsItems', function(e, obj) {
+ document.addEventListener('hz:handleNetworkNotificationsItems', function(e) {
push_notification(
- obj.name,
- $('<p>' + obj.message + '</p>').text(),
- obj.b64mid
+ e.detail.name,
+ $('<p>' + e.detail.message + '</p>').text(),
+ e.detail.b64mid
);
});
});
function getConversationSettings() {
- $.get('settings/conversation/?f=&aj=1',function(data) {
+ $.get('settings/conversation/?aj=1',function(data) {
$('#conversation_settings_body').html(data);
});
}
function postConversationSettings() {
- $.post(
- 'settings/conversation',
- $('#settings_module_ajax_form').serialize() + "&auto_update=" + next_page
- );
-
if(next_page === 1) {
page_load = true;
}
- $('#conversation_settings').modal('hide');
-
- if(timer) clearTimeout(timer);
- timer = setTimeout(updateInit,100);
+ $.post(
+ 'settings/conversation',
+ $('#settings_module_ajax_form').serialize() + "&auto_update=" + next_page
+ ).done(function() {
+ $('#conversation_settings').modal('hide');
+ toast('Conversation features updated', 'info');
+ updateInit();
+ });
return false;
}
@@ -351,6 +471,13 @@ function handle_comment_form(e) {
var commentSaveTimer = null;
var emptyCommentElm = form.find('.comment-edit-text').attr('id');
var convId = emptyCommentElm.replace('comment-edit-text-','');
+
+ // in case parent input is set use it as convId
+ const parentInputVal = form.find(':input[name=parent]').val();
+ if (parentInputVal) {
+ convId = parentInputVal;
+ }
+
$('#' + emptyCommentElm).on('focusout',function(e){
if(commentSaveTimer)
clearTimeout(commentSaveTimer);
@@ -469,16 +596,18 @@ function inserteditortag(BBcode, id) {
}
function insertCommentAttach(comment,id) {
-
activeCommentID = id;
activeCommentText = comment;
-
$('body').css('cursor', 'wait');
-
$('#invisible-comment-upload').trigger('click');
-
return false;
+}
+function insertCommentEmbed(comment,id) {
+ activeCommentID = id;
+ activeCommentText = comment;
+ initializeEmbedPhotoDialog();
+ return false;
}
function insertCommentURL(comment, id) {
@@ -486,7 +615,7 @@ function insertCommentURL(comment, id) {
if(reply && reply.length) {
reply = bin2hex(reply);
$('body').css('cursor', 'wait');
- $.get('linkinfo?f=&binurl=' + reply, function(data) {
+ $.get('linkinfo?binurl=' + reply, function(data) {
var tmpStr = $("#comment-edit-text-" + id).val();
if(tmpStr == comment) {
tmpStr = "";
@@ -515,17 +644,22 @@ function viewsrc(id) {
}
function showHideComments(id) {
- if( $('#collapsed-comments-' + id).is(':visible')) {
- $('#collapsed-comments-' + id + ' .autotime').timeago('dispose');
- $('#collapsed-comments-' + id).hide();
- $('#hide-comments-' + id).html(aStr.showmore);
- $('#hide-comments-total-' + id).show();
- } else {
- $('#collapsed-comments-' + id + ' .autotime').timeago();
- $('#collapsed-comments-' + id).show();
- $('#hide-comments-' + id).html(aStr.showfewer);
- $('#hide-comments-total-' + id).hide();
+ let collapsedComments = document.getElementById('collapsed-comments-' + id);
+ let hideCommentsLabel = document.getElementById('hide-comments-label-' + id);
+ let hideCommentsTotal = document.getElementById('hide-comments-total-' + id);
+ let hideCommentsIcon = document.getElementById('hide-comments-icon-' + id);
+ let isCollapsed = collapsedComments.style.display === 'none';
+
+ collapsedComments.style.display = isCollapsed ? '' : 'none';
+ hideCommentsLabel.textContent = isCollapsed ? hideCommentsLabel.dataset.expanded : hideCommentsLabel.dataset.collapsed;
+
+ if (hideCommentsTotal) {
+ hideCommentsTotal.style.display = isCollapsed ? 'none' : '';
}
+
+ let oldClass = isCollapsed ? 'bi-chevron-down' : 'bi-chevron-up';
+ let newClass = isCollapsed ? 'bi-chevron-up' : 'bi-chevron-down';
+ hideCommentsIcon.classList.replace(oldClass, newClass);
}
function openClose(theID, display) {
@@ -566,7 +700,7 @@ function closeMenu(theID) {
}
function markRead(notifType) {
- $.get('notifications?f=&markRead='+notifType);
+ $.get('notifications?markRead='+notifType);
$('.' + notifType + '-button').fadeOut(function() {
$("." + notifType + "-update").html('0');
$('#nav-' + notifType + '-menu').html('');
@@ -579,7 +713,7 @@ function markRead(notifType) {
}
function markItemRead(itemId) {
- $.get('notifications?f=&markItemRead='+itemId);
+ $.get('notifications?markItemRead='+itemId);
$('.unseen-wall-indicator-'+itemId).remove();
}
@@ -648,201 +782,378 @@ function updatePageItems(mode, data) {
collapseHeight();
}
-
-function updateConvItems(mode,data) {
- let scroll_position = $(window).scrollTop();
+function updateConvItems(mode, data) {
+ let scroll_position = window.scrollY;
let b64mids = [];
- if(mode !== 'update')
- $(document).trigger('hz:updateConvItems');
+ // Parse the data string into a DOM object
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(data, 'text/html');
- if(mode === 'update' || mode === 'replace') {
- prev = 'threads-begin';
+ if (mode !== 'update') {
+ document.dispatchEvent(new Event('hz:updateConvItems'));
}
- if(mode === 'append') {
- next = 'threads-end';
+
+ let prev, next;
+ if (mode === 'update' || mode === 'replace') {
+ prev = document.getElementById('threads-begin');
+ }
+ if (mode === 'append') {
+ next = document.getElementById('threads-end');
}
- $('.thread-wrapper', data).each(function() {
- if(this.classList.contains('toplevel_item')) {
- let ident = this.id;
- let convId = ident.replace('thread-wrapper-','');
- let commentWrap = $('#'+ident+' .collapsed-comments').attr('id');
+ doc.querySelectorAll('.thread-wrapper').forEach(function (elem) {
+ if (elem.classList.contains('toplevel_item')) {
+ let ident = elem.id;
+ let convId = ident.replace('thread-wrapper-', '');
+ let commentWrap = elem.querySelector('.collapsed-comments')?.id;
let itmId = 0;
let isVisible = false;
// figure out the comment state
- if(typeof commentWrap !== 'undefined')
- itmId = commentWrap.replace('collapsed-comments-','');
+ if (commentWrap !== undefined) {
+ itmId = commentWrap.replace('collapsed-comments-', '');
+ }
- if($('#collapsed-comments-'+itmId).is(':visible'))
+ let collapsedComment = document.getElementById('collapsed-comments-' + itmId);
+ if (collapsedComment && collapsedComment.style.display !== 'none') {
isVisible = true;
+ }
// insert the content according to the mode and first_page
// and whether or not the content exists already (overwrite it)
-
- if($('#' + ident).length == 0) {
- if((mode === 'update' || mode === 'replace') && profile_page == 1) {
- $('#' + prev).after($(this));
- prev = ident;
+ let existingElem = document.getElementById(ident);
+ if (!existingElem) {
+ if ((mode === 'update' || mode === 'replace') && profile_page == 1) {
+ if (prev) {
+ prev.after(elem);
+ prev = elem;
+ }
}
- if(mode === 'append') {
- $('#' + next).before($(this));
+ if (mode === 'append') {
+ if (next) {
+ next.before(elem);
+ }
}
- }
- else {
- $('#' + ident).replaceWith($(this));
+ } else {
+ existingElem.replaceWith(elem);
}
- // set the comment state to the state we discovered earlier
+ // DOMParser will prevent scripts from execution for security reasons.
+ // We remove all scripts but possibly injected some from
+ // addons like for example gallery later.
+ // TODO: make the script run from the addon itself.
+ let scripts = elem.querySelectorAll('script');
+ scripts.forEach(script => {
+ let scriptContent = script.textContent || script.innerText;
+ eval(scriptContent); // Execute the script
+ });
- if(isVisible)
+ // set the comment state to the state we discovered earlier
+ if (isVisible) {
showHideComments(itmId);
+ }
let commentBody = localStorage.getItem("comment_body-" + convId);
-
- if(commentBody) {
- var commentElm = $('#comment-edit-text-' + convId);
- if(auto_save_draft) {
- if($(commentElm).val() === '') {
- $('#comment-edit-form-' + convId).show();
- $(commentElm).addClass("expanded");
+ if (commentBody) {
+ let commentElm = document.getElementById('comment-edit-text-' + convId);
+ if (auto_save_draft && commentElm) {
+ if (commentElm.value === '') {
+ let commentForm = document.getElementById('comment-edit-form-' + convId);
+ if (commentForm) {
+ commentForm.style.display = 'block';
+ }
+ commentElm.classList.add("expanded");
openMenu("comment-tools-" + convId);
- $(commentElm).val(commentBody);
+ commentElm.value = commentBody;
}
} else {
localStorage.removeItem("comment_body-" + convId);
}
}
- // trigger the autotime function on all newly created content
- $("> .wall-item-outside-wrapper .autotime, > .thread-wrapper .autotime",this).timeago();
- $("> .shared_header .autotime",this).timeago();
-
- if((mode === 'append' || mode === 'replace') && (loadingPage)) {
+ if ((mode === 'append' || mode === 'replace') && loadingPage) {
loadingPage = false;
}
- // if single thread view and the item has a title, display it in the title bar
-
- if(mode === 'replace') {
- if (window.location.search.indexOf("mid=") != -1 || window.location.pathname.indexOf("display") != -1) {
- let title = $(".wall-item-title").text();
- title.replace(/^\s+/, '');
- title.replace(/\s+$/, '');
- if (title) {
- savedTitle = title + " " + savedTitle;
- document.title = title;
+ // if single thread view and the item has a title, display it in the title bar
+ if (mode === 'replace') {
+ if (window.location.search.includes("mid=") || window.location.pathname.includes("display")) {
+ let titleElem = document.querySelector(".wall-item-title");
+ if (titleElem) {
+ let title = titleElem.textContent.trim();
+ if (title) {
+ savedTitle = title + ' ' + savedTitle;
+ document.title = title;
+ }
}
}
}
}
- $(this).data('b64mids').forEach((b64mid) => {
- b64mids.push(b64mid);
- });
+ let data_json = JSON.parse(elem.dataset.b64mids);
+
+ if (elem.parentNode.classList.contains('wall-item-sub-thread-wrapper') && elem.parentNode.children.length) {
+ // Set the highlight state
+ if (data_json.includes(bParam_mid) && !elem.parentNode.parentNode.classList.contains('toplevel_item')) {
+ elem.parentNode.parentNode.classList.add('item-highlight');
+ document.documentElement.style.setProperty('--hz-item-highlight', stringToHslColor(JSON.parse(elem.parentNode.parentNode.dataset.b64mids)[0]));
+ }
+
+ let elemSubThreadWrapper = elem.querySelector('.wall-item-sub-thread-wrapper');
+ let elemCommentButton = elem.querySelector('.wall-item-comment');
+
+ // Set the button and sub-thread-wrapper state
+ if (elemCommentButton && elemSubThreadWrapper.children.length) {
+ elemCommentButton.classList.add('expanded');
+ }
+
+ elem.parentNode.classList.add('item-expanded');
+ }
+ b64mids.push(...data_json);
});
- $(document).trigger('hz:sse_setNotificationsStatus', [b64mids]);
+ document.dispatchEvent(new CustomEvent('hz:sse_setNotificationsStatus', { detail: b64mids }));
- $(window).scrollTop(scroll_position);
+ window.scrollTo(0, scroll_position);
- if(followUpPageLoad) {
- $(document).trigger('hz:sse_bs_counts');
- }
- else {
- $(document).trigger('hz:sse_bs_init');
+ if (followUpPageLoad) {
+ document.dispatchEvent(new Event('hz:sse_bs_counts'));
+ } else {
+ document.dispatchEvent(new Event('hz:sse_bs_init'));
}
- if(commentBusy) {
+ if (commentBusy) {
commentBusy = false;
- $('body').css('cursor', 'auto');
+ document.body.style.cursor = 'auto';
}
- // Setup to determine if the media player is playing. This affects
- // some content loading decisions.
+ // Setup to determine if the media player is playing. This affects some content loading decisions.
+ ['playing', 'pause'].forEach(event => {
+ document.querySelectorAll('video, audio').forEach(media => {
+ media.removeEventListener(event, mediaHandler);
+ media.addEventListener(event, mediaHandler);
+ });
+ });
- $('video').off('playing');
- $('video').off('pause');
- $('audio').off('playing');
- $('audio').off('pause');
+ function mediaHandler(event) {
+ mediaPlaying = event.type === 'playing';
+ }
- $('video').on('playing', function() {
- mediaPlaying = true;
- });
- $('video').on('pause', function() {
- mediaPlaying = false;
- });
- $('audio').on('playing', function() {
- mediaPlaying = true;
- });
- $('audio').on('pause', function() {
- mediaPlaying = false;
+ imagesLoaded(document.querySelectorAll('.wall-item-body img, .wall-photo-item img'), function () {
+ if (bParam_mid && mode === 'replace') {
+ scrollToItem();
+ }
+ else {
+ collapseHeight();
+ }
});
- if(! preloadImages) {
- $('.wall-item-body, .wall-photo-item').imagesLoaded()
- .always( function( instance ) {
- //console.log('all images loaded');
- collapseHeight();
+ // reset rotators and cursors we may have set before reaching this place
+ let pageSpinner = document.getElementById("page-spinner");
+ if (pageSpinner) {
+ pageSpinner.style.display = 'none';
+ }
+ let profileJotTextLoading = document.getElementById("profile-jot-text-loading");
+ if (profileJotTextLoading) {
+ profileJotTextLoading.style.display = 'none';
+ }
- if(bParam_mid && mode === 'replace')
- scrollToItem();
+ followUpPageLoad = true;
- })
- .done( function( instance ) {
- //console.log('all images successfully loaded');
- })
- .fail( function() {
- //console.log('all images loaded, at least one is broken');
- })
- .progress( function( instance, image ) {
- //var result = image.isLoaded ? 'loaded' : 'broken';
- //console.log( 'image is ' + result + ' for ' + image.img.src );
- });
+
+ updateRelativeTime('.autotime');
+}
+
+function imagesLoaded(elements, callback) {
+ let loadedCount = 0;
+ let totalImages = 0;
+ let timeoutId;
+ const timeout = 10000;
+ const processed = new Set(); // Use a Set for efficient lookup
+
+ // Helper function to extract img elements from an HTML string
+ function extractImagesFromHtml(htmlString) {
+ const tempDiv = document.createElement('div');
+ tempDiv.innerHTML = htmlString;
+ return tempDiv.querySelectorAll('.wall-item-body img, .wall-photo-item img');
}
- else {
- collapseHeight();
- if(bParam_mid && mode === 'replace')
- scrollToItem();
+ function checkComplete(src) {
+ // Skip processing if image has already been processed
+ if (processed.has(src)) return;
+
+ processed.add(src);
+ loadedCount++;
+
+ // Update progress
+ const progress = Math.round((loadedCount * 100) / totalImages);
+ document.getElementById('image_counter').innerText = `${progress}%`;
+
+ // If all images are loaded, trigger the callback
+ if (loadedCount === totalImages) {
+ document.getElementById('image_counter').innerText = '';
+ clearTimeout(timeoutId);
+ callback();
+ }
}
- // reset rotators and cursors we may have set before reaching this place
+ // Convert HTML string to img elements if necessary
+ if (typeof elements === 'string') {
+ elements = extractImagesFromHtml(elements);
+ }
- $("#page-spinner").hide();
- $("#profile-jot-text-loading").hide();
+ // Exit early if there are no images to load
+ if (!elements || elements.length === 0) {
+ callback();
+ return;
+ }
- followUpPageLoad = true;
+ // Filter valid image elements (only img with src attribute)
+ const images = Array.from(elements)
+ .filter((element) => element.tagName.toLowerCase() === 'img' && element.src)
+ .filter((element, index, self) =>
+ index === self.findIndex(e => e.src === element.src) // Avoid duplicates
+ );
+
+ // If no images are found, call the callback immediately
+ if (images.length === 0) {
+ callback();
+ return;
+ }
+
+ totalImages = images.length;
+
+ // Set timeout for the loading process
+ timeoutId = setTimeout(() => {
+ console.warn(`Image loading timed out after ${timeout}ms`);
+ callback(false);
+ }, timeout);
+ // Iterate through images to add load and error event listeners
+ images.forEach((img) => {
+ let new_img = new Image();
+ new_img.src = img.src;
+
+ if (new_img.complete && new_img.naturalHeight > 0) {
+ // Image is already loaded, handle immediately
+ // console.log(`Image cached: ${new_img.src}`);
+ checkComplete(new_img.src);
+ } else {
+ // Add event listeners for load and error events
+ new_img.addEventListener('load', () => {
+ // console.log(`Image loaded: ${new_img.src}`);
+ checkComplete(new_img.src)
+ });
+ new_img.addEventListener('error', () => {
+ console.log(`Image failed to load: ${new_img.src}`);
+ checkComplete(new_img.src);
+ });
+ }
+
+ });
+}
+
+function updateRelativeTime(selector) {
+ // Get all elements with the given selector
+ const timeElements = document.querySelectorAll(selector);
+ if (timeElements.length === 0) return;
+
+ // Default time style and map for supported options
+ const styleMap = ['narrow', 'short', 'long'];
+ const style = styleMap.find(s => selector.includes(s)) || 'long';
+
+ // Create an instance of RelativeTimeFormat
+ const rtf = new Intl.RelativeTimeFormat(lang, {
+ localeMatcher: 'best fit', // 'best fit' or 'lookup'
+ numeric: 'always', // 'always' or 'auto'
+ style: style // 'long', 'short', or 'narrow'
+ });
+
+ const now = Date.now(); // Get the current time only once
+
+ // Helper function to calculate the time difference in appropriate units
+ function getRelativeTime(diffInSeconds) {
+ const isFuture = diffInSeconds > 0;
+ const absDiffInSeconds = Math.abs(diffInSeconds);
+
+ if (absDiffInSeconds < 60) return { value: absDiffInSeconds, unit: 'second' };
+ if (absDiffInSeconds < 3600) return { value: Math.floor(absDiffInSeconds / 60), unit: 'minute' };
+ if (absDiffInSeconds < 86400) return { value: Math.floor(absDiffInSeconds / 3600), unit: 'hour' };
+ if (absDiffInSeconds < 2592000) return { value: Math.floor(absDiffInSeconds / 86400), unit: 'day' };
+ if (absDiffInSeconds < 31536000) return { value: Math.floor(absDiffInSeconds / 2592000), unit: 'month' };
+ return { value: Math.floor(absDiffInSeconds / 31536000), unit: 'year' };
+ }
+
+ // Process each element
+ timeElements.forEach(element => {
+ const timestamp = new Date(element.title).getTime();
+ if (isNaN(timestamp)) return; // Skip invalid timestamps
+
+ const diffInSeconds = Math.floor((timestamp - now) / 1000); // Time difference in seconds
+ const { value, unit } = getRelativeTime(diffInSeconds);
+
+ // Format the relative time and set it as the element's text
+ const formattedTime = rtf.format(diffInSeconds > 0 ? value : -value, unit);
+ element.textContent = formattedTime;
+ });
+
+ // Avoid duplicate timeout registrations for the same selector
+ if (!updateTimeout.includes(selector)) {
+ updateTimeout.push(selector);
+ setTimeout(() => updateRelativeTime(selector), 60000); // Re-run the update every 60 seconds
+ }
}
function scrollToItem() {
// auto-scroll to a particular comment in a thread (designated by mid) when in single-thread mode
- if(justifiedGalleryActive)
- return;
+ if (justifiedGalleryActive) return;
let submid = ((bParam_mid.length) ? bParam_mid : 'abcdefg');
- //var encoded = ((submid.substr(0,4) == 'b64.') ? true : false);
- //var submid_encoded = ((encoded) ? submid : window.btoa(submid));
- $('.thread-wrapper').filter(function() {
- if($(this).data('b64mids').indexOf(submid) > -1 && !$(this).hasClass('toplevel_item')) {
- if($('.collapsed-comments').length) {
- var scrolltoid = $('.collapsed-comments').attr('id').substring(19);
- $('#collapsed-comments-' + scrolltoid + ' .autotime').timeago();
- $('#collapsed-comments-' + scrolltoid).show();
- $('#hide-comments-' + scrolltoid).html(aStr.showfewer);
- $('#hide-comments-total-' + scrolltoid).hide();
+ // Select all thread wrappers
+ let threadWrappers = document.querySelectorAll('.thread-wrapper');
+
+ threadWrappers.forEach(thread => {
+ // Get the 'data-b64mids' attribute and check if it contains submid
+ let b64mids = thread.dataset.b64mids;
+
+ if (b64mids && b64mids.includes(submid)) {
+ // Handle collapsed comments if any
+ let collapsedComments = document.querySelectorAll('.collapsed-comments');
+ if (collapsedComments.length) {
+ let scrollToId = collapsedComments[0].id.substring(19);
+ showHideComments(scrollToId);
}
- $('html, body').animate({ scrollTop: $(this).offset().top - $('nav').outerHeight(true) }, 'slow');
- $(this).addClass('item-highlight');
+
+ collapseHeight();
+
+ if (!thread.classList.contains('toplevel_item')) {
+ // Scroll to the target element
+ let navHeight = document.getElementById('navbar-top') ? document.getElementById('navbar-top').offsetHeight : 0;
+ window.scrollTo({
+ top: getOffsetTopRelativeToBody(thread) - navHeight,
+ behavior: 'smooth'
+ });
+ }
+
+ let id = thread.id.replace('thread-wrapper-', '');
+ let content = document.getElementById('wall-item-content-wrapper-' + id);
+ content.classList.add('item-highlight-fade');
}
});
+}
+function getOffsetTopRelativeToBody(element) {
+ let offsetTop = 0;
+ while (element) {
+ offsetTop += element.offsetTop;
+ element = element.offsetParent;
+ }
+ return offsetTop;
}
function collapseHeight() {
@@ -869,8 +1180,8 @@ function collapseHeight() {
startOpen: open,
heightMargin: 50,
collapsedHeight: divmore_height,
- moreLink: '<a href="#" class="divgrow-showmore fakelink">' + aStr.divgrowmore + '</a>',
- lessLink: '<a href="#" class="divgrow-showmore fakelink">' + aStr.divgrowless + '</a>',
+ moreLink: '<a href="#" class="divgrow-showmore fakelink"><i class="bi bi-chevron-down align-middle divgrow-showmore-icon"></i>&nbsp;<span class="divgrow-showmore-label align-middle">' + aStr.divgrowmore + '</span></a>',
+ lessLink: '<a href="#" class="divgrow-showmore fakelink"><i class="bi bi-chevron-up align-middle divgrow-showmore-icon"></i>&nbsp;<span class="divgrow-showmore-label align-middle">' + aStr.divgrowless + '</span></a>',
beforeToggle: function(trigger, element, expanded) {
if(expanded) {
if((($(element).offset().top + divmore_height) - $(window).scrollTop()) < 65 ) {
@@ -906,7 +1217,7 @@ function updateInit() {
liveUpdate();
}
else {
- $(document).trigger('hz:sse_bs_init');
+ document.dispatchEvent(new Event('hz:sse_bs_init'));
}
if($('#live-photos').length || $('#live-cards').length || $('#live-articles').length ) {
@@ -1008,7 +1319,7 @@ function liveUpdate(notify_id) {
in_progress = false;
liveRecurse ++;
if(liveRecurse < 10) {
- liveUpdate();
+ liveUpdate(notify_id);
}
else {
console.log('Incomplete data. Too many attempts. Giving up.');
@@ -1030,45 +1341,16 @@ function liveUpdate(notify_id) {
var dready = new Date();
console.log('DATA ready in: ' + (dready - dstart)/1000 + ' seconds.');
- if(update_mode === 'update' || preloadImages) {
- console.log('LOADING images...');
- $('.wall-item-body, .wall-photo-item',data).imagesLoaded()
- .always( function( instance ) {
- //console.log('all images loaded');
-
- var iready = new Date();
- console.log('IMAGES ready in: ' + (iready - dready)/1000 + ' seconds.');
-
- page_load = false;
- scroll_next = false;
- updateConvItems(update_mode,data);
-
- in_progress = false;
- $('#image_counter').html('');
-
- // remove modal backdrop in case the update was triggered from a modal
- $('.modal-backdrop').remove();
- })
- .done( function( instance ) {
- //console.log('all images successfully loaded');
- })
- .fail( function() {
- //console.log('all images loaded, at least one is broken');
- })
- .progress( function( instance, image ) {
- $('#image_counter').html(Math.floor((instance.progressedCount*100)/instance.images.length) + '%');
- //var result = image.isLoaded ? 'loaded' : 'broken';
- //console.log( 'image is ' + result + ' for ' + image.img.src );
- });
+ console.log('LOADING images...');
+ imagesLoaded(data, function () {
+ var iready = new Date();
+ console.log('IMAGES ready in: ' + (iready - dready)/1000 + ' seconds.');
- }
- else {
page_load = false;
scroll_next = false;
updateConvItems(update_mode,data);
in_progress = false;
- }
-
+ });
});
}
@@ -1102,9 +1384,8 @@ function cache_next_page() {
console.log('cached: ' + update_url);
- $('.wall-item-body, .wall-photo-item', data).imagesLoaded()
- .always( function( instance ) {
- console.log('page_cache images loaded:');
+ imagesLoaded(data, function () {
+ console.log('page_cache: images loaded');
page_cache.data = data;
page_cache.page = bParam_page;
@@ -1112,19 +1393,7 @@ function cache_next_page() {
bParam_page--;
page_load = false;
- })
- .done( function( instance ) {
- console.log('success');
- })
- .fail( function() {
- console.log('at least one is broken');
- })
- .progress( function( instance, image ) {
- //console.log(instance.progressedCount + '/' + instance.images.length);
- //var result = image.isLoaded ? 'loaded' : 'broken';
- //console.log( 'image is ' + result + ' for ' + image.img.src );
});
-
});
}
@@ -1144,7 +1413,7 @@ function pageUpdate() {
bParam_page = 1;
}
- update_url = baseurl + '/' + decodeURIComponent(page_query) + '/?f=&aj=1&page=' + bParam_page + extra_args ;
+ update_url = baseurl + '/' + decodeURIComponent(page_query) + '?aj=1&page=' + bParam_page + extra_args ;
$("#page-spinner").show();
update_mode = 'append';
@@ -1154,7 +1423,7 @@ function pageUpdate() {
scroll_next = false;
updatePageItems(update_mode,data);
$("#page-spinner").hide();
- $(".autotime").timeago();
+ updateRelativeTime('.autotime');
in_progress = false;
});
}
@@ -1175,21 +1444,299 @@ function justifyPhotosAjax(id) {
$('#' + id).justifiedGallery('norewind').on('jg.complete', function(e){ justifiedGalleryActive = false; });
}
+function request(id, mid, verb, parent, uuid, userClick) {
+
+ if (verb === 'load') {
+ const dots = document.getElementById('load-more-dots-' + parent);
+ dots.classList.add('jumping-dots');
+
+ const parent_sub = document.getElementById('wall-item-sub-thread-wrapper-' + parent);
+ const offset = parent_sub.children.length;
+
+ fetch('/request?offset=' + offset + '&verb=' + verb + '&mid=' + mid + '&parent=' + parent + '&module=' + module)
+ .then(response => response.json())
+ .then(obj => {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(obj.html, 'text/html');
+ let b64mids = [];
+
+ doc.querySelectorAll('.thread-wrapper').forEach(function (e) {
+ let data = JSON.parse(e.dataset.b64mids);
+ b64mids.push(...data);
+ });
+
+ imagesLoaded(doc.querySelectorAll('.wall-item-body img'), function () {
+ injectWithAnimation('wall-item-sub-thread-wrapper-' + parent, doc);
+ dots.classList.remove('jumping-dots');
+
+ const loadmore_progress = document.getElementById('load-more-progress-' + parent);
+ loadmore_progress.style.width = Math.round(100 * parent_sub.children.length / loadmore_progress.dataset.commentsTotal) + '%';
+
+ if (Number(parent_sub.children.length) === Number(loadmore_progress.dataset.commentsTotal)) {
+ const loadmore = document.getElementById('load-more-' + parent);
+ loadmore.remove();
+ }
+
+ updateRelativeTime('.autotime');
+ collapseHeight();
+
+ document.dispatchEvent(new CustomEvent('hz:sse_setNotificationsStatus', { detail: b64mids }));
+ document.dispatchEvent(new Event('hz:sse_bs_counts'));
+ });
+
+ })
+ .catch(error => {
+ console.error('Error fetching data:', error);
+ });
+
+ return;
+ }
+
+ const loading = document.getElementById('like-rotator-' + id);
+
+ if (userClick) {
+ loading.style.display = 'block';
+ }
+
+ if (verb === 'comment') {
+ if (userClick && singlethread_modules.indexOf(module) !== -1) {
+ let stateObj = { b64mid: uuid };
+ history.pushState(stateObj, '', module + '/' + uuid);
+ }
+
+ fetch('/request?verb=' + verb + '&mid=' + mid + '&parent=' + parent + '&module=' + module)
+ .then(response => response.json())
+ .then(obj => {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(obj.html, 'text/html');
+
+ doc.querySelectorAll('.thread-wrapper').forEach(function (e) {
+ let data = JSON.parse(e.dataset.b64mids);
+ b64mids.push(...data);
+ });
+
+ imagesLoaded(doc.querySelectorAll('.wall-item-body img'), function () {
+ injectWithAnimation('wall-item-sub-thread-wrapper-' + id, doc, true);
+ updateRelativeTime('.autotime');
+ collapseHeight();
+
+ if (userClick) {
+ loading.style.display = 'none';
+ document.dispatchEvent(new CustomEvent('hz:sse_setNotificationsStatus', { detail: b64mids }));
+ document.dispatchEvent(new Event('hz:sse_bs_counts'));
+ }
+ });
+
+ })
+ .catch(error => {
+ console.error('Error fetching data:', error);
+ });
+ }
+ else {
+ fetch('/request?verb=' + verb + '&mid=' + mid + '&parent=' + parent)
+ .then(response => response.json())
+ .then(obj => {
+ const modal = new bootstrap.Modal('#reactions');
+ const modal_content = document.getElementById('reactions_body');
+ const modal_title = document.getElementById('reactions_title');
+ const modal_action = document.getElementById('reactions_action');
+ modal_action.style.display = 'none';
+ modal_title.innerHTML = obj.title;
+ modal_content.innerHTML = '';
+ if (obj.action) {
+ modal_action.innerHTML = '<a href="#" onclick="' + obj.action + '(' + id + ',\'' + verb + '\'); return false;">' + obj.action_label + '</a>';
+ modal_action.style.display = 'block';
+ }
+ console.log(obj)
+ obj.result.forEach(e => {
+ let mod = '';
+ if (e.item_blocked === 4) {
+ mod = '<span onclick="moderate_approve(' + e.id + '); return false;" class="text-success pe-4 d-inline-block"><i class="bi bi-check-lg" ></i></span><span onclick="moderate_drop(' + e.id + '); return false;" class="text-danger pe-4 d-inline-block"><i class="bi bi-trash" ></i></span>';
+ }
+ modal_content.innerHTML += '<a href="' + e.url + '" class="list-group-item list-group-item-action border-0">' + mod + '<img src="' + e.photo + '" class="menu-img-1" loading="lazy">&nbsp;' + e.name + '</a>';
+
+ });
+
+ modal.show();
+ loading.style.display = 'none';
+ })
+ .catch(error => {
+ console.error('Error fetching data:', error);
+ });
+ }
+
+}
+
+function injectWithAnimation(containerId, parsedDoc, overwrite = false) {
+ const container = document.getElementById(containerId);
+ if (!container) return;
+ if (overwrite) container.innerHTML = '';
+
+ const newElements = Array.from(parsedDoc.body.children);
+
+ for (let i = newElements.length - 1; i >= 0; i--) {
+ const el = newElements[i].cloneNode(true);
+ el.classList.add('item-fade-in');
+ container.insertBefore(el, container.firstChild);
+
+ // Remove classes after transition ends
+ const onTransitionEnd = (event) => {
+ el.classList.remove('item-fade-in', 'show');
+ el.removeEventListener('transitionend', onTransitionEnd);
+ };
+ el.addEventListener('transitionend', onTransitionEnd);
+
+ setTimeout(() => {
+ el.classList.add('show');
+ }, (newElements.length - 1 - i) * 30);
+ }
+}
+
+const autoExpand = (function () {
+ const clickedElements = new Set(); // Stores clicked button references
+
+ // We wait 10 seconds for images. Set the timeout here slightly higher.
+ function waitForElement(selector, timeout = 11000) {
+ return new Promise((resolve, reject) => {
+ // Check if the element already exists
+ const element = document.querySelector(selector);
+
+ if (element) {
+ resolve(element);
+ return;
+ }
+
+ // Set up a timeout to reject the promise if the element doesn't appear in time
+ const timer = setTimeout(() => {
+ observer.disconnect();
+ reject(new Error(`Element "${selector}" not found within ${timeout}ms`));
+ }, timeout);
+
+ // Create a MutationObserver to watch for DOM changes
+ const observer = new MutationObserver(() => {
+ const el = document.querySelector(selector);
+ if (el) {
+ clearTimeout(timer);
+ observer.disconnect();
+ resolve(el);
+ }
+ });
+
+ // Start observing the document for changes
+ observer.observe(document.documentElement, {
+ childList: true,
+ subtree: true
+ });
+ });
+ }
+
+ async function autoExpand(id) {
+ const loading = document.getElementById('like-rotator-' + id);
+ let iteration = 0;
+ const maxIterations = 3;
+ clickedElements.clear();
+
+ try {
+ // Step 1: Ensure initial button is clicked
+ const initBtnSelector = '#wall-item-comment-' + id;
+ const initBtn = await waitForElement(initBtnSelector);
+
+ if (!clickedElements.has(initBtn)) {
+ initBtn.click();
+ clickedElements.add(initBtn);
+ iteration++;
+ }
+
+ // Step 2: Loop until no new buttons are found
+ let newButtonsFound;
+
+ const commentSelector = `#wall-item-sub-thread-wrapper-${id} .thread-wrapper`;
+ const commentBtnSelector = `#wall-item-sub-thread-wrapper-${id} .wall-item-comment`;
+
+ do {
+ newButtonsFound = false;
+
+ // Wait for any comment to appear
+ await waitForElement(commentSelector);
+
+ const expandButtons = document.querySelectorAll(commentBtnSelector);
+
+ for (const btn of expandButtons) {
+ if (!clickedElements.has(btn)) {
+ btn.click();
+ clickedElements.add(btn);
+ newButtonsFound = true;
+ // Optional: await waitForElement(...) to wait for new content
+ }
+ }
+
+ // Wait between iterations to allow UI to update
+ if (newButtonsFound) {
+ iteration++;
+ await new Promise(res => setTimeout(res, 700));
+ }
+
+ } while (newButtonsFound && iteration < maxIterations);
+
+ console.log('Replies loaded!');
+
+ loading.style.display = 'none';
+
+ document.dispatchEvent(new CustomEvent('hz:sse_setNotificationsStatus', { detail: b64mids }));
+ document.dispatchEvent(new Event('hz:sse_bs_counts'));
+
+ } catch (error) {
+ loading.style.display = 'none';
+ console.error("autoExpand failed:", error.message);
+ }
+ }
+
+ return autoExpand;
+})();
+
+
+function stringToHexColor(str) {
+ let hash = 0;
+ for (let i = 0; i < str.length; i++) {
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
+ }
+ let color = "#";
+ for (let i = 0; i < 3; i++) {
+ const value = (hash >> (i * 8)) & 0xFF;
+ color += value.toString(16).padStart(2, '0');
+ }
+ return color;
+}
+
+function stringToHslColor(str) {
+ let stringUniqueHash = [...str].reduce((acc, char) => {
+ return char.charCodeAt(0) + ((acc << 5) - acc);
+ }, 0);
+ return `hsl(${stringUniqueHash % 360}, 65%, 65%)`;
+}
+
function dolike(ident, verb) {
- $('#like-rotator-' + ident.toString()).show();
+ $('#like-rotator-' + ident).show();
- if(typeof conv_mode == typeof undefined)
+ if (typeof conv_mode == typeof undefined) {
conv_mode = '';
+ }
- if(typeof page_mode == typeof undefined)
+ if (typeof page_mode == typeof undefined) {
page_mode = '';
+ }
+
+ let reload = 0;
- var reload = '';
- if(module == 'photos')
+ if (module == 'photos') {
reload = 1;
+ }
- $.get('like/' + ident.toString() + '?verb=' + verb + '&conv_mode=' + conv_mode + '&page_mode=' + page_mode + '&reload=' + reload, function (data) {
- if(data.success) {
+
+ $.get('like/' + ident + '?verb=' + verb + '&conv_mode=' + conv_mode + '&page_mode=' + page_mode + '&reload=' + reload, function (data) {
+ if (data.success) {
+
+ close_modal();
// mod photos
if (data.reload) {
@@ -1207,11 +1754,13 @@ function dolike(ident, verb) {
else {
$('#thread-wrapper-' + data.orig_id).replaceWith(data.html);
}
- $('#wall-item-ago-' + data.id + ' .autotime').timeago();
+
+ updateRelativeTime('.autotime');
collapseHeight();
liking = 0;
}
});
+
liking = 1;
}
@@ -1221,17 +1770,73 @@ function doprofilelike(ident, verb) {
function doreply(parent, ident, owner, hint) {
- var form = $('#comment-edit-form-' + parent.toString());
- form.find('input[name=parent]').val(ident);
- var i = form.find('button[type=submit]');
- var btn = i.html().replace(/<[^>]*>/g, '').trim();
- i.html('<i class="fa fa-reply" ></i> ' + btn);
- var sel = 'wall-item-body-' + ident.toString();
- var quote = window.getSelection().toString().trim();
- form.find('textarea').val("@{" + owner + "}" + ((($(window.getSelection().anchorNode).closest("#" + sel).attr("id") != sel) || (quote.length === 0))? " " : "\n[quote]" + quote + "[/quote]\n"));
- $('#comment-edit-text-' + parent.toString()).focus();
+ const modal = new bootstrap.Modal('#reactions');
+ const modal_content = document.getElementById('reactions_body');
+ const modal_title = document.getElementById('reactions_title');
+ const modal_action = document.getElementById('reactions_action');
+
+ modal_action.style.display = 'none';
+ modal_title.innerHTML = hint;
+
+ const preview = document.getElementById('comment-edit-preview-' + parent.toString());
+ preview.innerHTML = '';
+
+ // Get the form element by ID
+ const form = document.getElementById('comment-edit-wrapper-' + parent.toString());
+ if (!form) return;
+
+ modal_content.innerHTML = '';
+ modal_content.append(form);
+
+ // Set the value of the input named 'parent'
+ const parentInput = form.querySelector('input[name=parent]');
+ if (parentInput) {
+ parentInput.value = ident;
+ }
+
+ // Find the submit button and update its HTML
+ const submitBtn = form.querySelector('button[type=submit]');
+ if (submitBtn) {
+ const btnText = submitBtn.innerHTML.replace(/<[^>]*>/g, '').trim();
+ submitBtn.innerHTML = '<i class="bi bi-arrow-90deg-left"></i> ' + btnText;
+ }
+
+ // Prepare the quote logic
+ const sel = 'wall-item-body-' + ident.toString();
+ const quote = window.getSelection().toString().trim();
+
+ // Check if the selection is inside the correct element
+ let isInSel = false;
+ const anchorNode = window.getSelection().anchorNode;
+ if (anchorNode) {
+ let node = anchorNode.nodeType === 3 ? anchorNode.parentNode : anchorNode;
+ while (node) {
+ if (node.id === sel) {
+ isInSel = true;
+ break;
+ }
+ node = node.parentNode;
+ }
+ }
+
+ modal.show();
+
+ // Set the textarea value
+ const textarea = form.querySelector('textarea');
+ if (textarea) {
+ let commentBody = localStorage.getItem('comment_body-' + ident);
+ if (commentBody) {
+ textarea.value = commentBody;
+ }
+ else {
+ textarea.value = "@{" + owner + "}" + ((!isInSel || quote.length === 0) ? " " : "\n[quote]" + quote + "[/quote]\n");
+ }
+
+ textarea.focus();
+ }
}
+
function doscroll(parent, hidden) {
var id;
var x = '#hide-comments-outer-' + hidden.toString();
@@ -1245,6 +1850,7 @@ function doscroll(parent, hidden) {
var c = '#collapsed-comments-' + x;
if($(c).length !== 0 && (! $(c).is(':visible'))) {
showHideComments(x);
+ collapseHeight();
pos += $(c).height();
}
}
@@ -1257,7 +1863,7 @@ function doscroll(parent, hidden) {
});
$('html, body').animate({scrollTop:(id.offset().top) - 50}, 'slow');
- $('<a href="javascript:doscrollback(' + pos + ');" id="back-to-reply" title="' + aStr['to_reply'] + '"><i class="fa fa-angle-double-down"></i></a>').insertAfter('#wall-item-ago-' + id.attr('id').replace(/\D/g,''));
+ $('<a href="javascript:doscrollback(' + pos + ');" id="back-to-reply" title="' + aStr['to_reply'] + '"><i class="bi bi-chevron-double-down"></i></a>').insertAfter('#wall-item-ago-' + id.attr('id').replace(/\D/g,''));
}
function doscrollback(pos) {
@@ -1282,7 +1888,7 @@ function dopin(id) {
$('.dropdown-item-pinnable').html($('.dropdown-item-pinnable').html().replace(aStr['unpin_item'],aStr['pin_item']));
$('.wall-item-pinned').remove()
if(i.length == 0) {
- $('<span class="wall-item-pinned" title="' + aStr['pinned'] + '" id="wall-item-pinned-' + id + '"><i class="fa fa-thumb-tack">&nbsp;</i></span>').insertAfter('#wall-item-ago-' + id);
+ $('<span class="wall-item-pinned" title="' + aStr['pinned'] + '" id="wall-item-pinned-' + id + '"><i class="bi bi-pin">&nbsp;</i></span>').insertAfter('#wall-item-ago-' + id);
me.html(me.html().replace(aStr['pin_item'],aStr['unpin_item']));
};
})
@@ -1305,7 +1911,7 @@ function dropItem(url, object, b64mid) {
$(object + ', #pinned-wrapper-' + id).remove();
$('body').css('cursor', 'auto');
- toast(aStr.itemdel, 'info')
+ toast(aStr.itemdel, 'info');
//$.jGrowl(aStr.itemdel, { sticky: false, theme: 'info', life: 3000 });
if (typeof b64mid !== typeof undefined) {
@@ -1327,26 +1933,28 @@ function dropItem(url, object, b64mid) {
}
function dosubthread(ident) {
- $('#like-rotator-' + ident.toString()).show();
- $.get('subthread/sub/' + ident.toString(), updateInit );
+ $('#like-rotator-' + ident).show();
+ $.get('subthread/sub/' + ident, updateInit );
liking = 1;
}
function dounsubthread(ident) {
- $('#like-rotator-' + ident.toString()).show();
- $.get('subthread/unsub/' + ident.toString(), updateInit );
+ $('#like-rotator-' + ident).show();
+ $.get('subthread/unsub/' + ident, updateInit );
liking = 1;
}
-function moderate_approve(ident) {
- $('#like-rotator-' + ident.toString()).show();
- $.get('moderate/' + ident.toString() + '/approve', updateInit );
+function moderate_approve(ident, verb) {
+ $('#like-rotator-' + ident).show();
+ close_modal();
+ $.get('moderate/' + ident + '/approve', updateInit );
liking = 1;
}
function moderate_drop(ident) {
- $('#like-rotator-' + ident.toString()).show();
- $.get('moderate/' + ident.toString() + '/drop', $('#thread-wrapper-' + ident.toString()).fadeOut(function() { this.remove(); }));
+ $('#like-rotator-' + ident).show();
+ close_modal();
+ $.get('moderate/' + ident + '/drop', $('#thread-wrapper-' + ident).fadeOut(function() { this.remove(); }));
liking = 1;
}
@@ -1357,18 +1965,18 @@ function dostar(ident) {
if(data.result == 1) {
$('#starred-' + ident).addClass('starred');
$('#starred-' + ident).removeClass('unstarred');
- $('#starred-' + ident).addClass('fa-star');
- $('#starred-' + ident).removeClass('fa-star-o');
+ $('#starred-' + ident).addClass('bi-star-fill');
+ $('#starred-' + ident).removeClass('bi-star');
$('#star-' + ident).addClass('hidden');
$('#unstar-' + ident).removeClass('hidden');
- var btn_tpl = '<div class="btn-group" id="star-button-' + ident + '"><button type="button" class="btn btn-outline-secondary border-0 btn-sm wall-item-star" onclick="dostar(' + ident + ');"><i class="fa fa-star"></i></button></div>'
- $('#wall-item-tools-left-' + ident).prepend(btn_tpl);
+ var btn_tpl = '<div class="" id="star-button-' + ident + '"><button type="button" class="btn btn-sm btn-link link-secondary wall-item-star" onclick="dostar(' + ident + ');"><i class="bi bi-star generic-icons"></i></button></div>'
+ $('#wall-item-tools-right-' + ident).prepend(btn_tpl);
}
else {
$('#starred-' + ident).addClass('unstarred');
$('#starred-' + ident).removeClass('starred');
- $('#starred-' + ident).addClass('fa-star-o');
- $('#starred-' + ident).removeClass('fa-star');
+ $('#starred-' + ident).addClass('bi-star');
+ $('#starred-' + ident).removeClass('bi-star-fill');
$('#star-' + ident).removeClass('hidden');
$('#unstar-' + ident).addClass('hidden');
$('#star-button-' + ident).remove();
@@ -1440,12 +2048,14 @@ function post_comment(id) {
window.location.href = data.reload;
}
+ close_modal();
localStorage.removeItem("comment_body-" + id);
$("#comment-edit-preview-" + id).hide();
$("#comment-edit-text-" + id).val('').blur().attr('placeholder', aStr.comment);
- $('#wall-item-comment-wrapper-' + id).before(data.html);
- $('#wall-item-ago-' + data.id + ' .autotime').timeago();
+ $('#wall-item-sub-thread-wrapper-' + data.thr_parent_id).append(data.html);
+
+ updateRelativeTime('.autotime');
$('body').css('cursor', 'unset');
collapseHeight();
commentBusy = false;
@@ -1475,7 +2085,7 @@ function preview_comment(id) {
function(data) {
if(data.preview) {
$("#comment-edit-preview-" + id).html(data.preview);
- $("#comment-edit-preview-" + id + " .autotime").timeago();
+ updateRelativeTime('.autotime');
$("#comment-edit-preview-" + id + " a").click(function() { return false; });
}
},
@@ -1505,7 +2115,7 @@ function preview_post() {
function(data) {
if(data.preview) {
$("#jot-preview-content").html(data.preview);
- $("#jot-preview-content .autotime").timeago();
+ updateRelativeTime('.autotime');
$("#jot-preview-content" + " a").click(function() { return false; });
}
},
@@ -1553,7 +2163,7 @@ function contactgroupChangeMember(gid, cid) {
$('body').css('cursor', 'wait');
$.get('contactgroup/' + gid + '/' + cid, function(data) {
$('body').css('cursor', 'auto');
- $('#group-' + gid).toggleClass('fa-check-square-o fa-square-o');
+ $('#group-' + gid).toggleClass('bi-check-square bi-square');
});
}
@@ -1622,140 +2232,11 @@ $(window).scroll(function () {
}
});
-function addhtmltext(data) {
- data = h2b(data);
- addeditortext(data);
-}
-
function loadText(textRegion,data) {
var currentText = $(textRegion).val();
$(textRegion).val(currentText + data);
}
-function addeditortext(data) {
- if(plaintext == 'none') {
- var currentText = $("#profile-jot-text").val();
- $("#profile-jot-text").val(currentText + data);
- }
-}
-
-function h2b(s) {
- var y = s;
- function rep(re, str) {
- y = y.replace(re,str);
- }
-
- rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");
- rep(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]");
- rep(/<span style=\"color:(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]");
- rep(/<font>(.*?)<\/font>/gi,"$1");
- rep(/<img.*?width=\"(.*?)\".*?height=\"(.*?)\".*?src=\"(.*?)\".*?\/>/gi,"[img=$1x$2]$3[/img]");
- rep(/<img.*?height=\"(.*?)\".*?width=\"(.*?)\".*?src=\"(.*?)\".*?\/>/gi,"[img=$2x$1]$3[/img]");
- rep(/<img.*?src=\"(.*?)\".*?height=\"(.*?)\".*?width=\"(.*?)\".*?\/>/gi,"[img=$3x$2]$1[/img]");
- rep(/<img.*?src=\"(.*?)\".*?width=\"(.*?)\".*?height=\"(.*?)\".*?\/>/gi,"[img=$2x$3]$1[/img]");
- rep(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]");
-
- rep(/<ul class=\"listbullet\" style=\"list-style-type\: circle\;\">(.*?)<\/ul>/gi,"[list]$1[/list]");
- rep(/<ul class=\"listnone\" style=\"list-style-type\: none\;\">(.*?)<\/ul>/gi,"[list=]$1[/list]");
- rep(/<ul class=\"listdecimal\" style=\"list-style-type\: decimal\;\">(.*?)<\/ul>/gi,"[list=1]$1[/list]");
- rep(/<ul class=\"listlowerroman\" style=\"list-style-type\: lower-roman\;\">(.*?)<\/ul>/gi,"[list=i]$1[/list]");
- rep(/<ul class=\"listupperroman\" style=\"list-style-type\: upper-roman\;\">(.*?)<\/ul>/gi,"[list=I]$1[/list]");
- rep(/<ul class=\"listloweralpha\" style=\"list-style-type\: lower-alpha\;\">(.*?)<\/ul>/gi,"[list=a]$1[/list]");
- rep(/<ul class=\"listupperalpha\" style=\"list-style-type\: upper-alpha\;\">(.*?)<\/ul>/gi,"[list=A]$1[/list]");
- rep(/<li>(.*?)<\/li>/gi,"[li]$1[/li]");
-
- rep(/<code>(.*?)<\/code>/gi,"[code]$1[/code]");
- rep(/<\/(strong|b)>/gi,"[/b]");
- rep(/<(strong|b)>/gi,"[b]");
- rep(/<\/(em|i)>/gi,"[/i]");
- rep(/<(em|i)>/gi,"[i]");
- rep(/<\/u>/gi,"[/u]");
-
- rep(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]");
- rep(/<u>/gi,"[u]");
- rep(/<blockquote[^>]*>/gi,"[quote]");
- rep(/<\/blockquote>/gi,"[/quote]");
- rep(/<hr \/>/gi,"[hr]");
- rep(/<br (.*?)\/>/gi,"\n");
- rep(/<br\/>/gi,"\n");
- rep(/<br>/gi,"\n");
- rep(/<p>/gi,"");
- rep(/<\/p>/gi,"\n");
- rep(/&nbsp;/gi," ");
- rep(/&quot;/gi,"\"");
- rep(/&lt;/gi,"<");
- rep(/&gt;/gi,">");
- rep(/&amp;/gi,"&");
-
- return y;
-}
-
-function b2h(s) {
- var y = s;
- function rep(re, str) {
- y = y.replace(re,str);
- }
-
- rep(/\&/gi,"&amp;");
- rep(/\</gi,"&lt;");
- rep(/\>/gi,"&gt;");
- rep(/\"/gi,"&quot;");
-
- rep(/\n/gi,"<br />");
- rep(/\[b\]/gi,"<strong>");
- rep(/\[\/b\]/gi,"</strong>");
- rep(/\[i\]/gi,"<em>");
- rep(/\[\/i\]/gi,"</em>");
- rep(/\[u\]/gi,"<u>");
- rep(/\[\/u\]/gi,"</u>");
- rep(/\[hr\]/gi,"<hr />");
- rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"<a href=\"$1\">$2</a>");
- rep(/\[url\](.*?)\[\/url\]/gi,"<a href=\"$1\">$1</a>");
- rep(/\[img=(.*?)x(.*?)\](.*?)\[\/img\]/gi,"<img width=\"$1\" height=\"$2\" src=\"$3\" />");
- rep(/\[img\](.*?)\[\/img\]/gi,"<img src=\"$1\" />");
-
- rep(/\[zrl=([^\]]+)\](.*?)\[\/zrl\]/gi,"<a href=\"$1" + '?f=&zid=' + zid + "\">$2</a>");
- rep(/\[zrl\](.*?)\[\/zrl\]/gi,"<a href=\"$1" + '?f=&zid=' + zid + "\">$1</a>");
- rep(/\[zmg=(.*?)x(.*?)\](.*?)\[\/zmg\]/gi,"<img width=\"$1\" height=\"$2\" src=\"$3" + '?f=&zid=' + zid + "\" />");
- rep(/\[zmg\](.*?)\[\/zmg\]/gi,"<img src=\"$1" + '?f=&zid=' + zid + "\" />");
-
- rep(/\[list\](.*?)\[\/list\]/gi, '<ul class="listbullet" style="list-style-type: circle;">$1</ul>');
- rep(/\[list=\](.*?)\[\/list\]/gi, '<ul class="listnone" style="list-style-type: none;">$1</ul>');
- rep(/\[list=1\](.*?)\[\/list\]/gi, '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>');
- rep(/\[list=i\](.*?)\[\/list\]/gi,'<ul class="listlowerroman" style="list-style-type: lower-roman;">$1</ul>');
- rep(/\[list=I\](.*?)\[\/list\]/gi, '<ul class="listupperroman" style="list-style-type: upper-roman;">$1</ul>');
- rep(/\[list=a\](.*?)\[\/list\]/gi, '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$1</ul>');
- rep(/\[list=A\](.*?)\[\/list\]/gi, '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$1</ul>');
- rep(/\[li\](.*?)\[\/li\]/gi, '<li>$1</li>');
- rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"<span style=\"color: $1;\">$2</span>");
- rep(/\[size=(.*?)\](.*?)\[\/size\]/gi,"<span style=\"font-size: $1;\">$2</span>");
- rep(/\[code\](.*?)\[\/code\]/gi,"<code>$1</code>");
- rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"<blockquote>$1</blockquote>");
-
- rep(/\[video\](.*?)\[\/video\]/gi,"<a href=\"$1\">$1</a>");
- rep(/\[audio\](.*?)\[\/audio\]/gi,"<a href=\"$1\">$1</a>");
-
- rep(/\[\&amp\;([#a-z0-9]+)\;\]/gi,'&$1;');
-
- rep(/\<(.*?)(src|href)=\"[^hfm](.*?)\>/gi,'<$1$2="">');
-
- return y;
-}
-
-function zid(s) {
- if((! s.length) || (s.indexOf('zid=') != (-1)))
- return s;
-
- if(! zid.length)
- return s;
-
- var has_params = ((s.indexOf('?') == (-1)) ? false : true);
- var achar = ((has_params) ? '&' : '?');
- s = s + achar + 'f=&zid=' + zid;
-
- return s;
-}
-
function makeid(length) {
var result = '';
var characters = 'abcdef0123456789';
@@ -1801,7 +2282,7 @@ function push_notification(title, body, b64mid) {
function toggleAside() {
if ($('main.region_1-on').length) {
- $('#expand-aside-icon').addClass('fa-arrow-circle-right').removeClass('fa-arrow-circle-left');
+ $('#expand-aside-icon').addClass('bi-arrow-right-circle').removeClass('bi-arrow-left-circle');
$('html, body').css({ 'position': '', 'left': '' });
$('main').removeClass('region_1-on');
$('#region_1').addClass('d-none');
@@ -1809,7 +2290,7 @@ function toggleAside() {
$('#overlay').remove();
}
else {
- $('#expand-aside-icon').removeClass('fa-arrow-circle-right').addClass('fa-arrow-circle-left');
+ $('#expand-aside-icon').removeClass('bi-arrow-right-circle').addClass('bi-arrow-left-circle');
$('html, body').css({ 'position': 'sticky', 'left': '0px'});
$('main').addClass('region_1-on');
$('#region_1').removeClass('d-none');
@@ -1819,7 +2300,7 @@ function toggleAside() {
}
function toast(string, severity) {
- let id = btoa(string);
+ let id = bin2hex(string);
let container = document.getElementById('toast-container');
let toast = document.getElementById(id);
@@ -1840,3 +2321,11 @@ function toast(string, severity) {
toastInstance.show();
}
+
+function close_modal() {
+ let modal = bootstrap.Modal.getInstance(document.querySelector('.modal.show'));
+
+ if (modal) {
+ modal.hide();
+ }
+}
diff --git a/view/js/mod_articles.js b/view/js/mod_articles.js
index 8b31c0f52..5ebe46aa0 100644
--- a/view/js/mod_articles.js
+++ b/view/js/mod_articles.js
@@ -1,5 +1,5 @@
$(document).ready( function() {
- $(".autotime").timeago();
+ updateRelativeTime('.autotime');
/* autocomplete @nicknames */
$(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl?f=&n=1");
diff --git a/view/js/mod_cards.js b/view/js/mod_cards.js
index 8b31c0f52..5ebe46aa0 100644
--- a/view/js/mod_cards.js
+++ b/view/js/mod_cards.js
@@ -1,5 +1,5 @@
$(document).ready( function() {
- $(".autotime").timeago();
+ updateRelativeTime('.autotime');
/* autocomplete @nicknames */
$(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl?f=&n=1");
diff --git a/view/js/mod_cloud.js b/view/js/mod_cloud.js
index fc9219bff..9669d86f5 100644
--- a/view/js/mod_cloud.js
+++ b/view/js/mod_cloud.js
@@ -519,42 +519,45 @@ function formatSizeUnits(bytes){
// this is basically a js port of include/text.php getIconFromType() function
function getIconFromType(type) {
- var map = {
+ let map = {
//Common file
- 'application/octet-stream': 'fa-file-o',
+ 'application/octet-stream': 'bi-file-earmark',
//Text
- 'text/plain': 'fa-file-text-o',
- 'application/msword': 'fa-file-word-o',
- 'application/pdf': 'fa-file-pdf-o',
- 'application/vnd.oasis.opendocument.text': 'fa-file-word-o',
- 'application/epub+zip': 'fa-book',
+ 'text/plain': 'bi-file-earmark-text',
+ 'text/markdown': 'bi-filetype-md',
+ 'text/bbcode': 'bi-file-earmark-text',
+ 'text/html': 'bi-filetype-html',
+ 'application/msword': 'bi-file-earmark-word',
+ 'application/pdf': 'bi-file-earmark-pdf',
+ 'application/vnd.oasis.opendocument.text': 'bifile--earmark-text',
+ 'application/epub+zip': 'bi-file-earmark-text',
//Spreadsheet
- 'application/vnd.oasis.opendocument.spreadsheet': 'fa-file-excel-o',
- 'application/vnd.ms-excel': 'fa-file-excel-o',
+ 'application/vnd.oasis.opendocument.spreadsheet': 'bi-file-earmark-spreadsheet',
+ 'application/vnd.ms-excel': 'bi-file-earmark-spreadsheet',
//Image
- 'image/jpeg': 'fa-picture-o',
- 'image/png': 'fa-picture-o',
- 'image/gif': 'fa-picture-o',
- 'image/svg+xml': 'fa-picture-o',
+ 'image/jpeg': 'bi-file-earmark-image',
+ 'image/png': 'bi-file-earmark-image',
+ 'image/gif': 'bi-file-earmark-image',
+ 'image/webp': 'bi-file-earmark-image',
+ 'image/svg+xml': 'bi-filetype-svg',
//Archive
- 'application/zip': 'fa-file-archive-o',
- 'application/x-rar-compressed': 'fa-file-archive-o',
+ 'application/zip': 'bi-file-earmark-zip',
+ 'application/x-rar-compressed': 'bi-file-earmark-zip',
//Audio
- 'audio/mpeg': 'fa-file-audio-o',
- 'audio/mp3': 'fa-file-audio-o', //webkit browsers need that
- 'audio/wav': 'fa-file-audio-o',
- 'application/ogg': 'fa-file-audio-o',
- 'audio/ogg': 'fa-file-audio-o',
- 'audio/webm': 'fa-file-audio-o',
- 'audio/mp4': 'fa-file-audio-o',
+ 'audio/mpeg': 'bi-file-earmark-music',
+ 'audio/wav': 'bi-file-earmark-music',
+ 'application/ogg': 'bi-file-earmark-music',
+ 'audio/ogg': 'bi-file-earmark-music',
+ 'audio/webm': 'bi-file-earmark-music',
+ 'audio/mp4': 'bi-file-earmark-music',
//Video
- 'video/quicktime': 'fa-file-video-o',
- 'video/webm': 'fa-file-video-o',
- 'video/mp4': 'fa-file-video-o',
- 'video/x-matroska': 'fa-file-video-o'
+ 'video/quicktime': 'bi-file-earmark-play',
+ 'video/webm': 'bi-file-earmark-play',
+ 'video/mp4': 'bi-file-earmark-play',
+ 'video/x-matroska': 'bi-file-earmark-play'
};
- var iconFromType = 'fa-file-o';
+ let iconFromType = 'bi-file-earmark';
if (type in map) {
iconFromType = map[type];
diff --git a/view/js/mod_connections.js b/view/js/mod_connections.js
index cb3ecc922..c8bd494d2 100644
--- a/view/js/mod_connections.js
+++ b/view/js/mod_connections.js
@@ -2,6 +2,6 @@ $(document).ready(function() {
$("#contacts-search").name_autocomplete(baseurl + '/acl', 'a', true, function(data) {
$("#contacts-search-xchan").val(data.xid);
});
- $(".autotime").timeago();
+ updateRelativeTime('.autotime');
});
diff --git a/view/js/mod_help.js b/view/js/mod_help.js
index 9c3591498..8308f23ec 100644
--- a/view/js/mod_help.js
+++ b/view/js/mod_help.js
@@ -1,14 +1,3 @@
-function docoTocToggle() {
- if ($('#doco-top-toc').is(':visible')) {
- $('#doco-toc-toggle').removeClass('fa-cog').addClass('fa-caret-right');
- } else {
- $('#doco-toc-toggle').removeClass('fa-caret-right').addClass('fa-caret-down');
- }
- $('#doco-top-toc').toggle();
-
- return false;
-}
-
toc = {};
// Generate the table of contents in the side nav menu (see view/tpl/help.tpl)
$(document).ready(function () {
@@ -69,54 +58,4 @@ $(document).ready(function () {
var newref = p.protocol + '//' + p.hostname + portstr + p.pathname + p.hash.split('?').shift();
location.replace(newref)
}
-
-
- // Determine language translations available from the language selector menu itself
- var langChoices = [];
- $('.lang-selector').find('.lang-choice').each(function (idx, a) {
- langChoices.push($(a).html());
- });
- // Parse the URL and insert the language code for the loaded language, based
- // on the variable "help_language" that is declared in the help.tpl page template
- var path = window.location.pathname.split('/');
- var pathParts = [];
- var pick_me = true;
- for (var i = 0; i < path.length; i++) {
- if(i === 2 && pick_me ) {
- if(path[i].length > 0) {
- pathParts.push(help_language);
- pick_me = false;
- if($.inArray(path[i], langChoices) < 0) {
- i--;
- }
- }
- } else {
- if(path[i].length > 0) {
- pathParts.push(path[i]);
- }
- }
-
- }
- // Update the address bar to reflect the loaded language
- window.history.replaceState({}, '', '/' + pathParts.join('/'));
-
- // Highlight the language in the language selector that is currently viewed
- $('.lang-selector').find('.lang-choice:contains("' + help_language + '")').addClass('active');
-
- // Construct the links to the available translations based and populate the selector menu
- $('.lang-selector').find('.lang-choice').each(function (idx, a) {
- var langLink = [];
-
- for (var i = 0; i < pathParts.length; i++) {
-
- if(i === 1) {
- langLink.push($(a).html());
- } else {
- langLink.push(pathParts[i]);
- }
-
- }
- $(a).attr('href', '/' + langLink.join('/'));
- });
-
});
diff --git a/view/js/mod_hq.js b/view/js/mod_hq.js
index 1e4c02768..2c2aca37b 100644
--- a/view/js/mod_hq.js
+++ b/view/js/mod_hq.js
@@ -1,6 +1,5 @@
$(document).ready(function() {
-
- $('.autotime').timeago();
+ updateRelativeTime('.autotime');
if (bParam_mid) {
src = 'hq';
diff --git a/view/js/mod_import_progress.js b/view/js/mod_import_progress.js
index 7aed56365..11b324862 100644
--- a/view/js/mod_import_progress.js
+++ b/view/js/mod_import_progress.js
@@ -30,6 +30,9 @@ $(document).ready(function() {
$('#cprogress-bar').css('width', '0%');
}
+ $('#cprogress-completed span').html(data.ccompleted_str);
+
+
// files
if (typeof data.fprogress == 'number') {
$('#fprogress-label').html(data.fprogress + '%');
@@ -50,5 +53,8 @@ $(document).ready(function() {
$('#fprogress-label').html(data.fprogress);
$('#fprogress-bar').css('width', '0%');
}
+
+ $('#fprogress-completed span').html(data.fcompleted_str);
+
}
});
diff --git a/view/js/mod_photos.js b/view/js/mod_photos.js
index c487fc417..ca1d85f0c 100644
--- a/view/js/mod_photos.js
+++ b/view/js/mod_photos.js
@@ -131,42 +131,45 @@ function formatSizeUnits(bytes){
// this is basically a js port of include/text.php getIconFromType() function
function getIconFromType(type) {
- var map = {
+ let map = {
//Common file
- 'application/octet-stream': 'fa-file-o',
+ 'application/octet-stream': 'bi-file-earmark',
//Text
- 'text/plain': 'fa-file-text-o',
- 'application/msword': 'fa-file-word-o',
- 'application/pdf': 'fa-file-pdf-o',
- 'application/vnd.oasis.opendocument.text': 'fa-file-word-o',
- 'application/epub+zip': 'fa-book',
+ 'text/plain': 'bi-file-earmark-text',
+ 'text/markdown': 'bi-filetype-md',
+ 'text/bbcode': 'bi-file-earmark-text',
+ 'text/html': 'bi-filetype-html',
+ 'application/msword': 'bi-file-earmark-word',
+ 'application/pdf': 'bi-file-earmark-pdf',
+ 'application/vnd.oasis.opendocument.text': 'bifile--earmark-text',
+ 'application/epub+zip': 'bi-file-earmark-text',
//Spreadsheet
- 'application/vnd.oasis.opendocument.spreadsheet': 'fa-file-excel-o',
- 'application/vnd.ms-excel': 'fa-file-excel-o',
+ 'application/vnd.oasis.opendocument.spreadsheet': 'bi-file-earmark-spreadsheet',
+ 'application/vnd.ms-excel': 'bi-file-earmark-spreadsheet',
//Image
- 'image/jpeg': 'fa-picture-o',
- 'image/png': 'fa-picture-o',
- 'image/gif': 'fa-picture-o',
- 'image/svg+xml': 'fa-picture-o',
+ 'image/jpeg': 'bi-file-earmark-image',
+ 'image/png': 'bi-file-earmark-image',
+ 'image/gif': 'bi-file-earmark-image',
+ 'image/webp': 'bi-file-earmark-image',
+ 'image/svg+xml': 'bi-filetype-svg',
//Archive
- 'application/zip': 'fa-file-archive-o',
- 'application/x-rar-compressed': 'fa-file-archive-o',
+ 'application/zip': 'bi-file-earmark-zip',
+ 'application/x-rar-compressed': 'bi-file-earmark-zip',
//Audio
- 'audio/mpeg': 'fa-file-audio-o',
- 'audio/mp3': 'fa-file-audio-o', //webkit browsers need that
- 'audio/wav': 'fa-file-audio-o',
- 'application/ogg': 'fa-file-audio-o',
- 'audio/ogg': 'fa-file-audio-o',
- 'audio/webm': 'fa-file-audio-o',
- 'audio/mp4': 'fa-file-audio-o',
+ 'audio/mpeg': 'bi-file-earmark-music',
+ 'audio/wav': 'bi-file-earmark-music',
+ 'application/ogg': 'bi-file-earmark-music',
+ 'audio/ogg': 'bi-file-earmark-music',
+ 'audio/webm': 'bi-file-earmark-music',
+ 'audio/mp4': 'bi-file-earmark-music',
//Video
- 'video/quicktime': 'fa-file-video-o',
- 'video/webm': 'fa-file-video-o',
- 'video/mp4': 'fa-file-video-o',
- 'video/x-matroska': 'fa-file-video-o'
+ 'video/quicktime': 'bi-file-earmark-play',
+ 'video/webm': 'bi-file-earmark-play',
+ 'video/mp4': 'bi-file-earmark-play',
+ 'video/x-matroska': 'bi-file-earmark-play'
};
- var iconFromType = 'fa-file-o';
+ let iconFromType = 'bi-file-earmark';
if (type in map) {
iconFromType = map[type];