* feat: navigator changes

* fix: remove extra code

* feat: add lang keys
v1.18.x
Barış Soner Uşaklı 4 years ago committed by GitHub
parent 648f6215ef
commit 6669496dba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -180,5 +180,7 @@
"diffs.post-restored": "Post successfully restored to earlier revision",
"timeago_later": "%1 later",
"timeago_earlier": "%1 earlier"
"timeago_earlier": "%1 earlier",
"first-post": "First post",
"last-post": "Last post"
}

@ -45,6 +45,8 @@ define('forum/topic', [
posts.onTopicPageLoad(components.get('post'));
navigator.init('[component="post"]', ajaxify.data.postcount, Topic.toTop, Topic.toBottom, Topic.navigatorCallback);
postTools.init(tid);
threadTools.init(tid, $('.topic'));
events.init();
@ -60,7 +62,7 @@ define('forum/topic', [
addDropupHandler();
addRepliesHandler();
navigator.init('[component="post"]', ajaxify.data.postcount, Topic.toTop, Topic.toBottom, Topic.navigatorCallback);
handleBookmark(tid);
@ -213,12 +215,12 @@ define('forum/topic', [
}
var newUrl = 'topic/' + ajaxify.data.slug + (index > 1 ? ('/' + index) : '');
if (newUrl !== currentUrl) {
if (Topic.replaceURLTimeout) {
clearTimeout(Topic.replaceURLTimeout);
Topic.replaceURLTimeout = 0;
}
currentUrl = newUrl;
Topic.replaceURLTimeout = setTimeout(function () {
if (index >= elementCount && app.user.uid) {
socket.emit('topics.markAsRead', [ajaxify.data.tid]);
@ -237,7 +239,6 @@ define('forum/topic', [
url: newUrl + search,
}, null, window.location.protocol + '//' + window.location.host + config.relative_path + '/' + newUrl + search);
}
currentUrl = newUrl;
}, 500);
}
};

@ -2,15 +2,14 @@
define('navigator', ['forum/pagination', 'components'], function (pagination, components) {
var navigator = {};
var index = 1;
var index = 0;
var count = 0;
var navigatorUpdateTimeoutId;
var touchTooltipEl;
var touchIntervalId;
var renderPostIntervalId;
var touchX;
var touchY;
var touchIndex;
var renderPostIndex;
var isNavigating = false;
var firstMove = true;
@ -20,13 +19,14 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
var paginationTextEl = paginationBlockEl.find('.pagination-text');
var paginationBlockMeterEl = paginationBlockEl.find('meter');
var paginationBlockProgressEl = paginationBlockEl.find('.progress-bar');
var thumb;
$(window).on('action:ajaxify.start', function () {
$(window).off('keydown', onKeyDown);
});
navigator.init = function (selector, count, toTop, toBottom, callback) {
index = 1;
index = 0;
navigator.selector = selector;
navigator.callback = callback;
navigator.toTop = toTop || function () {};
@ -37,6 +37,8 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
paginationBlockMeterEl = paginationBlockEl.find('meter');
paginationBlockProgressEl = paginationBlockEl.find('.progress-bar');
thumb = $('.scroller-thumb');
$(window).off('scroll', navigator.delayedUpdate).on('scroll', navigator.delayedUpdate);
paginationBlockEl.find('.dropdown-menu').off('click').on('click', function (e) {
@ -69,76 +71,184 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
}
});
$('.pagination-block.visible-xs').on('touchstart', function (e) {
touchTooltipEl = $('.navigator-thumb');
touchX = Math.min($(window).width(), Math.max(0, e.touches[0].clientX));
touchY = Math.min($(window).height(), Math.max(0, e.touches[0].clientY));
if (ajaxify.data.template.topic) {
handleScrollNav();
}
handleKeys();
navigator.setCount(count);
navigator.update(0);
};
function clampTop(newTop) {
var parent = thumb.parent();
var parentOffset = parent.offset();
if (newTop < parentOffset.top) {
newTop = parentOffset.top;
} else if (newTop > parentOffset.top + parent.height() - thumb.height()) {
newTop = parentOffset.top + parent.height() - thumb.height();
}
return newTop;
}
function setThumbToIndex(index) {
if (!thumb.length || thumb.is(':hidden')) {
return;
}
var parent = thumb.parent();
var thumbText = thumb.find('.thumb-text');
var parentOffset = parent.offset();
var percent = (index - 1) / ajaxify.data.postcount;
if (index === count) {
percent = 1;
}
var newTop = clampTop(parentOffset.top + ((parent.height() - thumb.height()) * percent));
var offset = { top: newTop, left: thumb.offset().left };
thumb.offset(offset);
thumbText.text(index + '/' + ajaxify.data.postcount);
renderPost(index);
}
function handleScrollNav() {
if (!thumb.length) {
return;
}
var thumbText = thumb.find('.thumb-text');
var thumbHeight = thumb.height();
var thumbHalfHeight = thumbHeight / 2;
var parent = thumb.parent();
var parentHeight = parent.height();
var mouseDragging = false;
$(window).on('action:ajaxify.end', function () {
renderPostIndex = null;
});
$('.pagination-block .dropdown-menu').parent().on('shown.bs.dropdown', function () {
setThumbToIndex(index);
});
thumb.on('mousedown', function () {
mouseDragging = true;
$(window).on('mousemove', mousemove);
firstMove = true;
});
function mouseup() {
$(window).off('mousemove', mousemove);
if (mouseDragging) {
navigator.scrollToIndex(index - 1, true, 0);
paginationBlockEl.find('[data-toggle="dropdown"]').trigger('click');
}
clearRenderInterval();
mouseDragging = false;
firstMove = false;
}
function mousemove(ev) {
var newTop = clampTop(ev.pageY - thumbHalfHeight);
var parentOffset = parent.offset();
var offset = { top: newTop, left: thumb.offset().left };
thumb.offset(offset);
var percent = (newTop - parentOffset.top) / (parentHeight - thumbHeight);
index = Math.max(1, Math.ceil(ajaxify.data.postcount * percent));
navigator.updateTextAndProgressBar();
thumbText.text(index + '/' + ajaxify.data.postcount);
if (firstMove) {
delayedRenderPost();
}
firstMove = false;
ev.stopPropagation();
return false;
}
function delayedRenderPost() {
clearRenderInterval();
renderPostIntervalId = setInterval(function () {
renderPost(index);
}, 250);
}
$(window).off('mousemove', mousemove);
$(window).off('mouseup', mouseup).on('mouseup', mouseup);
thumb.on('touchstart', function (ev) {
isNavigating = true;
touchX = Math.min($(window).width(), Math.max(0, ev.touches[0].clientX));
touchY = Math.min($(window).height(), Math.max(0, ev.touches[0].clientY));
firstMove = true;
}).on('touchmove', function (e) {
});
thumb.on('touchmove', function (ev) {
var windowWidth = $(window).width();
var windowHeight = $(window).height();
var deltaX = Math.abs(touchX - Math.min(windowWidth, Math.max(0, e.touches[0].clientX)));
var deltaY = Math.abs(touchY - Math.min(windowHeight, Math.max(0, e.touches[0].clientY)));
touchX = Math.min(windowWidth, Math.max(0, e.touches[0].clientX));
touchY = Math.min(windowHeight, Math.max(0, e.touches[0].clientY));
if (deltaX >= deltaY && firstMove) {
var deltaX = Math.abs(touchX - Math.min(windowWidth, Math.max(0, ev.touches[0].clientX)));
var deltaY = Math.abs(touchY - Math.min(windowHeight, Math.max(0, ev.touches[0].clientY)));
touchX = Math.min(windowWidth, Math.max(0, ev.touches[0].clientX));
touchY = Math.min(windowHeight, Math.max(0, ev.touches[0].clientY));
if (deltaY >= deltaX && firstMove) {
isNavigating = true;
touchIntervalId = setInterval(updateTooltip, 100);
delayedRenderPost();
}
if (isNavigating) {
e.preventDefault();
e.stopPropagation();
var percent = touchX / windowWidth;
ev.preventDefault();
ev.stopPropagation();
var newTop = clampTop(touchY + $(window).scrollTop() - thumbHalfHeight);
var parentOffset = thumb.parent().offset();
var offset = { top: newTop, left: thumb.offset().left };
thumb.offset(offset);
var percent = (newTop - parentOffset.top) / (parentHeight - thumbHeight);
index = Math.max(1, Math.ceil(count * percent));
index = index > count ? count : index;
thumbText.text(index + '/' + ajaxify.data.postcount);
if (firstMove) {
updateTooltip(function () {
touchTooltipEl.removeClass('hidden');
});
renderPost(index);
}
navigator.updateTextAndProgressBar();
}
firstMove = false;
}).on('touchend', function () {
if (touchIntervalId) {
clearInterval(touchIntervalId);
touchIntervalId = 0;
}
});
thumb.on('touchend', function () {
clearRenderInterval();
if (isNavigating) {
touchTooltipEl.addClass('hidden');
navigator.scrollToIndex(index - 1, true, 0);
isNavigating = false;
paginationBlockEl.find('[data-toggle="dropdown"]').trigger('click');
}
});
}
handleKeys();
navigator.setCount(count);
navigator.update(0);
};
function clearRenderInterval() {
if (renderPostIntervalId) {
clearInterval(renderPostIntervalId);
renderPostIntervalId = 0;
}
}
function updateTooltip(callback) {
function renderPost(index, callback) {
callback = callback || function () {};
if (touchIndex === index) {
if (renderPostIndex === index || paginationBlockEl.find('.post-content').is(':hidden')) {
return;
}
touchIndex = index;
touchTooltipEl.css({ left: Math.min($(window).width() - touchTooltipEl.outerWidth(), Math.max(touchX - (touchTooltipEl.outerWidth() / 2), 0)) });
renderPostIndex = index;
socket.emit('posts.getTimestampByIndex', { tid: ajaxify.data.tid, index: index - 1 }, function (err, timestamp) {
socket.emit('posts.getPostSummaryByIndex', { tid: ajaxify.data.tid, index: index - 1 }, function (err, postData) {
if (err) {
return app.alertError(err.message);
}
app.parseAndTranslate('partials/topic/navigation-post', { post: postData }, function (html) {
html.find('.timeago').timeago();
paginationBlockEl.find('.post-content').html(html);
});
var date = new Date(timestamp);
var ds = date.toLocaleString(config.userLang, { month: 'long' });
touchTooltipEl.find('.text').translateText('[[global:pagination.out_of, ' + index + ', ' + count + ']]');
if (timestamp > Date.now() - (30 * 24 * 60 * 60 * 1000)) {
touchTooltipEl.find('.time').text(ds + ' ' + date.getDate());
} else {
touchTooltipEl.find('.time').text(ds + ' ' + date.getFullYear());
}
callback();
});
}
@ -171,7 +281,11 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
}
navigator.setCount = function (value) {
count = parseInt(value, 10);
value = parseInt(value, 10);
if (value === count) {
return;
}
count = value;
navigator.updateTextAndProgressBar();
};
@ -213,10 +327,10 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
a spot where a user is expecting to begin reading.
*/
threshold = typeof threshold === 'number' ? threshold : undefined;
var newIndex = index;
var els = $(navigator.selector);
if (els.length) {
index = parseInt(els.first().attr('data-index'), 10) + 1;
newIndex = parseInt(els.first().attr('data-index'), 10) + 1;
}
var scrollTop = $(window).scrollTop();
@ -235,7 +349,7 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
}
if (distanceToMiddle < previousDistance) {
index = elIndex + 1;
newIndex = elIndex + 1;
previousDistance = distanceToMiddle;
}
}
@ -245,13 +359,13 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
var nearBottom = scrollTop + windowHeight > documentHeight - 100 && parseInt(els.last().attr('data-index'), 10) === count - 1;
if (atTop) {
index = 1;
newIndex = 1;
} else if (nearBottom) {
index = count;
newIndex = count;
}
// If a threshold is undefined, try to determine one based on new index
if (threshold === undefined && ajaxify.data.template.topic === true) {
if (threshold === undefined && ajaxify.data.template.topic) {
if (atTop) {
threshold = 0;
} else {
@ -264,10 +378,15 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
}
if (typeof navigator.callback === 'function') {
navigator.callback(index, count, threshold);
navigator.callback(newIndex, count, threshold);
}
if (newIndex !== index) {
index = newIndex;
navigator.updateTextAndProgressBar();
setThumbToIndex(index);
}
navigator.updateTextAndProgressBar();
toggle(!!count);
};
@ -422,7 +541,7 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co
var scrollTop = 0;
if (postHeight < viewportHeight) {
scrollTop = (scrollTo.offset().top - (viewportHeight / 2) + (postHeight / 2)) - topicHeaderHeight;
scrollTop = (scrollTo.offset().top - (viewportHeight / 2) + (postHeight)) - topicHeaderHeight;
} else {
scrollTop = scrollTo.offset().top - navbarHeight - topicHeaderHeight;
}

@ -71,7 +71,7 @@ SocketPosts.getRawPost = async function (socket, pid) {
return result.postData.content;
};
SocketPosts.getTimestampByIndex = async function (socket, data) {
SocketPosts.getPostSummaryByIndex = async function (socket, data) {
if (data.index < 0) {
data.index = 0;
}
@ -90,7 +90,9 @@ SocketPosts.getTimestampByIndex = async function (socket, data) {
if (!canRead) {
throw new Error('[[error:no-privileges]]');
}
return await posts.getPostField(pid, 'timestamp');
const postsData = await posts.getPostSummaryByPids([pid], socket.uid, { stripTags: true });
return postsData[0];
};
SocketPosts.getPost = async function (socket, pid) {

Loading…
Cancel
Save