Skip to content

Commit

Permalink
feat: show posts previews if enabled on mouse over
Browse files Browse the repository at this point in the history
  • Loading branch information
barisusakli committed Nov 1, 2021
1 parent 7d468e7 commit 8c67031
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 1 deletion.
1 change: 1 addition & 0 deletions install/data/defaults.json
Expand Up @@ -69,6 +69,7 @@
"gdpr_enabled": 1,
"allowProfileImageUploads": 1,
"teaserPost": "last-reply",
"showPostPreviewsOnHover": 1,
"allowPrivateGroups": 1,
"unreadCutoff": 2,
"bookmarkThreshold": 5,
Expand Down
1 change: 1 addition & 0 deletions public/language/en-GB/admin/settings/post.json
Expand Up @@ -40,6 +40,7 @@
"teaser.last-post": "Last – Show the latest post, including the original post, if no replies",
"teaser.last-reply": "Last – Show the latest reply, or a \"No replies\" placeholder if no replies",
"teaser.first": "First",
"showPostPreviewsOnHover": "Show a preview of posts when mouse overed",
"unread": "Unread Settings",
"unread.cutoff": "Unread cutoff days",
"unread.min-track-last": "Minimum posts in topic before tracking last read",
Expand Down
57 changes: 56 additions & 1 deletion public/src/client/topic.js
Expand Up @@ -12,10 +12,11 @@ define('forum/topic', [
'components',
'storage',
'hooks',
'api',
], function (
infinitescroll, threadTools, postTools,
events, posts, navigator, sort,
components, storage, hooks
components, storage, hooks, api
) {
const Topic = {};
let currentUrl = '';
Expand Down Expand Up @@ -55,6 +56,7 @@ define('forum/topic', [
addParentHandler();
addDropupHandler();
addRepliesHandler();
addPostsPreviewHandler();

handleBookmark(tid);

Expand Down Expand Up @@ -172,6 +174,59 @@ define('forum/topic', [
});
}

function addPostsPreviewHandler() {
if (!ajaxify.data.showPostPreviewsOnHover) {
return;
}
let timeoutId = 0;
$('[component="topic"]').on('mouseenter', '[component="post"] a, [component="topic/event"] a', async function () {
const link = $(this);

async function renderPost(pid) {
const postData = await socket.emit('posts.getPostSummaryByPid', { pid: pid });
if (postData) {
const tooltip = await app.parseAndTranslate('partials/topic/post-preview', { post: postData });
tooltip.hide().find('.timeago').timeago();
tooltip.appendTo($('body')).fadeIn(300);
const postContent = link.parents('[component="topic"]').find('[component="post/content"]').first();
const postRect = postContent.offset();
const postWidth = postContent.width();
const linkRect = link.offset();
tooltip.css({
top: linkRect.top + 30,
left: postRect.left,
width: postWidth,
});
}
}

const href = link.attr('href');
const pathname = utils.urlToLocation(href).pathname;
$('#post-tooltip').remove();
const postMatch = pathname && pathname.match(/\/post\/([\d]+)/);
const topicMatch = pathname && pathname.match(/\/topic\/([\d]+)/);
if (postMatch) {
const pid = postMatch[1];
if (parseInt(link.parents('[component="post"]').attr('data-pid'), 10) === parseInt(pid, 10)) {
return; // dont render self post
}

timeoutId = setTimeout(async () => {
renderPost(pid);
}, 300);
} else if (topicMatch) {
timeoutId = setTimeout(async () => {
const tid = topicMatch[1];
const topicData = await api.get('/topics/' + tid, {});
renderPost(topicData.mainPid);
}, 300);
}
}).on('mouseleave', '[component="post"] a, [component="topic/event"] a', function () {
clearTimeout(timeoutId);
$('#post-tooltip').remove();
});
}

function updateTopicTitle() {
const span = components.get('navbar/title').find('span');
if ($(window).scrollTop() > 50 && span.hasClass('hidden')) {
Expand Down
1 change: 1 addition & 0 deletions src/controllers/topics.js
Expand Up @@ -96,6 +96,7 @@ topicsController.get = async function getTopic(req, res, next) {
topicData.updateUrlWithPostIndex = settings.updateUrlWithPostIndex;
topicData.allowMultipleBadges = meta.config.allowMultipleBadges === 1;
topicData.privateUploads = meta.config.privateUploads === 1;
topicData.showPostPreviewsOnHover = meta.config.showPostPreviewsOnHover === 1;
topicData.rssFeedUrl = `${relative_path}/topic/${topicData.tid}.rss`;
if (req.loggedIn) {
topicData.rssFeedUrl += `?uid=${req.uid}&token=${rssToken}`;
Expand Down
16 changes: 16 additions & 0 deletions src/socket.io/posts.js
Expand Up @@ -98,6 +98,22 @@ SocketPosts.getPostSummaryByIndex = async function (socket, data) {
return postsData[0];
};

SocketPosts.getPostSummaryByPid = async function (socket, data) {
if (!data || !data.pid) {
throw new Error('[[error:invalid-data]]');
}
const { pid } = data;
const tid = await posts.getPostField(pid, 'tid');
const topicPrivileges = await privileges.topics.get(tid, socket.uid);
if (!topicPrivileges['topics:read']) {
throw new Error('[[error:no-privileges]]');
}

const postsData = await posts.getPostSummaryByPids([pid], socket.uid, { stripTags: false });
posts.modifyPostByPrivilege(postsData[0], topicPrivileges);
return postsData[0];
};

SocketPosts.getPost = async function (socket, pid) {
sockets.warnDeprecated(socket, 'GET /api/v3/posts/:pid');
return await api.posts.get(socket, { pid });
Expand Down
6 changes: 6 additions & 0 deletions src/views/admin/settings/post.tpl
Expand Up @@ -193,6 +193,12 @@
<option value="first">[[admin/settings/post:teaser.first]]</option>
</select>
</div>
<div class="checkbox">
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input class="mdl-switch__input" type="checkbox" data-field="showPostPreviewsOnHover">
<span class="mdl-switch__label"><strong>[[admin/settings/post:showPostPreviewsOnHover]]</strong></span>
</label>
</div>
</form>
</div>
</div>
Expand Down
13 changes: 13 additions & 0 deletions src/views/partials/topic/post-preview.tpl
@@ -0,0 +1,13 @@
<div id="post-tooltip" class="well" style="position:absolute; z-index: 1;">
<div class="clearfix">
<div class="icon pull-left">
<a href="{{{ if post.user.userslug }}}{config.relative_path}/user/{post.user.userslug}{{{ else }}}#{{{ end }}}">
{buildAvatar(post.user, "sm", true, "", "user/picture")} {post.user.username}
</a>
</div>
<small class="pull-right">
<span class="timeago" title="{post.timestampISO}"></span>
</small>
</div>
<div class="content">{post.content}</div>
</div>

0 comments on commit 8c67031

Please sign in to comment.