From e67833a784de4db5a17454895596cb4214f7e42b Mon Sep 17 00:00:00 2001
From: Hypolite Petovan <hypolite@mrpetovan.com>
Date: Tue, 29 Oct 2019 23:18:17 -0400
Subject: [PATCH] [frio] Add click card on contact avatars

---
 view/theme/frio/css/style.css                 |  22 +++
 view/theme/frio/js/hovercard.js               | 171 ++++++++++--------
 .../frio/templates/event_stream_item.tpl      |   2 +-
 view/theme/frio/templates/nav.tpl             |   2 +-
 view/theme/frio/templates/notify.tpl          |   2 +-
 view/theme/frio/templates/photo_item.tpl      |   4 +-
 view/theme/frio/templates/search_item.tpl     |  26 ++-
 view/theme/frio/templates/wall_thread.tpl     |  28 ++-
 8 files changed, 163 insertions(+), 94 deletions(-)

diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css
index f1c78abc77..b0458d513c 100644
--- a/view/theme/frio/css/style.css
+++ b/view/theme/frio/css/style.css
@@ -1800,6 +1800,28 @@ aside .panel-body {
     font-size: 14px;
 }
 
+/* Contact avatar click card */
+.userinfo.click-card {
+	position: relative;
+}
+
+.userinfo.click-card > *:hover:after {
+	content: '⌄';
+	color: #bebebe;
+	font-size: 1em;
+	font-weight: bold;
+	background-color: #ffffff;
+	text-align: center;
+	line-height: 40%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 33%;
+	height: 33%;
+	opacity: .8;
+	border-radius: 0 0 40% 0;
+}
+
 /* The lock symbol popup */
 #panel {
     position: absolute;
diff --git a/view/theme/frio/js/hovercard.js b/view/theme/frio/js/hovercard.js
index 0236d9a075..464c7e06e1 100644
--- a/view/theme/frio/js/hovercard.js
+++ b/view/theme/frio/js/hovercard.js
@@ -8,18 +8,53 @@
  *
  */
 $(document).ready(function () {
-	// Elements with the class "userinfo" will get a hover-card.
-	// Note that this elements does need a href attribute which links to
-	// a valid profile url
-	$("body").on("mouseover", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function (e) {
+	let $body = $('body');
+	// Prevents normal click action on click hovercard elements
+	$body.on('click', '.userinfo.click-card', function (e) {
+		e.preventDefault();
+	});
+	// This event listener needs to be declared before the one that removes
+	// all cards so that we can stop the immediate propagation of the event
+	// Since the manual popover appears instantly and the hovercard removal is
+	// on a 100ms delay, leaving event propagation immediately hides any click hovercard
+	$body.on('mousedown', '.userinfo.click-card', function (e) {
+		e.stopImmediatePropagation();
+		let timeNow = new Date().getTime();
+
+		let contactUrl = false;
+		let targetElement = $(this);
+
+		// get href-attribute
+		if (targetElement.is('[href]')) {
+			contactUrl = targetElement.attr('href');
+		} else {
+			return true;
+		}
+
+		// no hovercard for anchor links
+		if (contactUrl.substring(0, 1) === '#') {
+			return true;
+		}
+
+		openHovercard(targetElement, contactUrl, timeNow);
+	});
+
+	// hover cards should be removed very easily, e.g. when any of these events happens
+	$body.on('mouseleave touchstart scroll mousedown submit keydown', function (e) {
+		// remove hover card only for desktiop user, since on mobile we open the hovercards
+		// by click event insteadof hover
+		removeAllHovercards(e, new Date().getTime());
+	});
+
+	$body.on('mouseover', '.userinfo.hover-card, .wall-item-responses a, .wall-item-bottom .mention a', function (e) {
 		let timeNow = new Date().getTime();
 		removeAllHovercards(e, timeNow);
-		let contact_url = false;
+		let contactUrl = false;
 		let targetElement = $(this);
 
 		// get href-attribute
 		if (targetElement.is('[href]')) {
-			contact_url = targetElement.attr('href');
+			contactUrl = targetElement.attr('href');
 		} else {
 			return true;
 		}
@@ -30,88 +65,34 @@ $(document).ready(function () {
 		}
 
 		// no hovercard for anchor links
-		if (contact_url.substring(0, 1) === '#') {
+		if (contactUrl.substring(0, 1) === '#') {
 			return true;
 		}
 
 		targetElement.attr('data-awaiting-hover-card', timeNow);
 
-		// store the title in an other data attribute beause bootstrap
-		// popover destroys the title.attribute. We can restore it later
-		let title = targetElement.attr("title");
-		targetElement.attr({"data-orig-title": title, title: ""});
-
-		// if the device is a mobile open the hover card by click and not by hover
-		if (typeof is_mobile != "undefined") {
-			targetElement[0].removeAttribute("href");
-			var hctrigger = 'click';
-		} else {
-			var hctrigger = 'manual';
-		}
-
-		// Timeout until the hover-card does appear
+		// Delay until the hover-card does appear
 		setTimeout(function () {
 			if (
-				targetElement.is(":hover")
+				targetElement.is(':hover')
 				&& parseInt(targetElement.attr('data-awaiting-hover-card'), 10) === timeNow
 				&& $('.hovercard').length === 0
-			) {	// no card if there already is one open
-				// get an additional data atribute if the card is active
-				targetElement.attr('data-hover-card-active', timeNow);
-				// get the whole html content of the hover card and
-				// push it to the bootstrap popover
-				getHoverCardContent(contact_url, function (data) {
-					if (data) {
-						targetElement.popover({
-							html: true,
-							placement: function () {
-								// Calculate the placement of the the hovercard (if top or bottom)
-								// The placement depence on the distance between window top and the element
-								// which triggers the hover-card
-								var get_position = $(targetElement).offset().top - $(window).scrollTop();
-								if (get_position < 270) {
-									return "bottom";
-								}
-								return "top";
-							},
-							trigger: hctrigger,
-							template: '<div class="popover hovercard" data-card-created="' + timeNow + '"><div class="arrow"></div><div class="popover-content hovercard-content"></div></div>',
-							content: data,
-							container: "body",
-							sanitizeFn: function (content) {
-								return DOMPurify.sanitize(content)
-							},
-						}).popover('show');
-					}
-				});
+			) {
+				openHovercard(targetElement, contactUrl, timeNow);
 			}
 		}, 500);
-	}).on("mouseleave", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function (e) { // action when mouse leaves the hover-card
-		var timeNow = new Date().getTime();
-		// copy the original title to the title atribute
-		var title = $(this).attr("data-orig-title");
-		$(this).attr({"data-orig-title": "", title: title});
-		removeAllHovercards(e, timeNow);
-	});
-
-	// hover cards should be removed very easily, e.g. when any of these events happen
-	$('body').on("mouseleave touchstart scroll click dblclick mousedown mouseup submit keydown keypress keyup", function (e) {
-		// remove hover card only for desktiop user, since on mobile we openen the hovercards
-		// by click event insteadof hover
-		if (typeof is_mobile == "undefined") {
-			var timeNow = new Date().getTime();
-			removeAllHovercards(e, timeNow);
-		}
+	}).on('mouseleave', '.userinfo.hover-card, .wall-item-responses a, .wall-item-bottom .mention a', function (e) { // action when mouse leaves the hover-card
+		removeAllHovercards(e, new Date().getTime());
 	});
 
 	// if we're hovering a hover card, give it a class, so we don't remove it
-	$('body').on('mouseover', '.hovercard', function (e) {
+	$body.on('mouseover', '.hovercard', function (e) {
 		$(this).addClass('dont-remove-card');
 	});
 
-	$('body').on('mouseleave', '.hovercard', function (e) {
+	$body.on('mouseleave', '.hovercard', function (e) {
 		$(this).removeClass('dont-remove-card');
-		$(this).popover("hide");
+		$(this).popover('hide');
 	});
 }); // End of $(document).ready
 
@@ -120,19 +101,61 @@ function removeAllHovercards(event, priorTo) {
 	// don't remove hovercards until after 100ms, so user have time to move the cursor to it (which gives it the dont-remove-card class)
 	setTimeout(function () {
 		$.each($('.hovercard'), function () {
-			var title = $(this).attr("data-orig-title");
+			let title = $(this).attr('data-orig-title');
 			// don't remove card if it was created after removeAllhoverCards() was called
 			if ($(this).data('card-created') < priorTo) {
 				// don't remove it if we're hovering it right now!
 				if (!$(this).hasClass('dont-remove-card')) {
-					$('[data-hover-card-active="' + $(this).data('card-created') + '"]').removeAttr('data-hover-card-active');
-					$(this).popover("hide");
+					let $handle = $('[data-hover-card-active="' + $(this).data('card-created') + '"]');
+					$handle.removeAttr('data-hover-card-active');
+
+					// Restoring the popover handle title
+					let title = $handle.attr('data-orig-title');
+					$handle.attr({'data-orig-title': '', title: title});
+
+					$(this).popover('hide');
 				}
 			}
 		});
 	}, 100);
 }
 
+function openHovercard(targetElement, contactUrl, timeNow) {
+	// store the title in a data attribute because Bootstrap
+	// popover destroys the title attribute.
+	let title = targetElement.attr('title');
+	targetElement.attr({'data-orig-title': title, title: ''});
+
+	// get an additional data atribute if the card is active
+	targetElement.attr('data-hover-card-active', timeNow);
+	// get the whole html content of the hover card and
+	// push it to the bootstrap popover
+	getHoverCardContent(contactUrl, function (data) {
+		if (data) {
+			targetElement.popover({
+				html: true,
+				placement: function () {
+					// Calculate the placement of the the hovercard (if top or bottom)
+					// The placement depence on the distance between window top and the element
+					// which triggers the hover-card
+					let get_position = $(targetElement).offset().top - $(window).scrollTop();
+					if (get_position < 270) {
+						return 'bottom';
+					}
+					return 'top';
+				},
+				trigger: 'manual',
+				template: '<div class="popover hovercard" data-card-created="' + timeNow + '"><div class="arrow"></div><div class="popover-content hovercard-content"></div></div>',
+				content: data,
+				container: 'body',
+				sanitizeFn: function (content) {
+					return DOMPurify.sanitize(content)
+				},
+			}).popover('show');
+		}
+	});
+}
+
 getHoverCardContent.cache = {};
 
 function getHoverCardContent(contact_url, callback) {
@@ -152,7 +175,7 @@ function getHoverCardContent(contact_url, callback) {
 	}
 
 	$.ajax({
-		url: baseurl + "/contact/hovercard",
+		url: baseurl + '/contact/hovercard',
 		data: postdata,
 		success: function (data, textStatus, request) {
 			getHoverCardContent.cache[nurl] = data;
diff --git a/view/theme/frio/templates/event_stream_item.tpl b/view/theme/frio/templates/event_stream_item.tpl
index 9264e9d2e3..2f2af2732e 100644
--- a/view/theme/frio/templates/event_stream_item.tpl
+++ b/view/theme/frio/templates/event_stream_item.tpl
@@ -27,7 +27,7 @@
 						{{/if}}
 					</div>
 					<div class="event-card-profile-name profile-entry-name">
-						<a href="{{$author_link}}" class="userinfo">{{$author_name}}</a>
+						<a href="{{$author_link}}" class="userinfo hover-card">{{$author_name}}</a>
 					</div>
 					{{if $location.map}}
 					<div id="event-location-map-{{$id}}" class="event-location-map">{{$location.map nofilter}}</div>
diff --git a/view/theme/frio/templates/nav.tpl b/view/theme/frio/templates/nav.tpl
index 4b515efcd1..a2b5106a61 100644
--- a/view/theme/frio/templates/nav.tpl
+++ b/view/theme/frio/templates/nav.tpl
@@ -285,7 +285,7 @@
 <ul id="nav-notifications-template" class="media-list" style="display:none;" rel="template">
 	<li class="{4} notif-entry">
 		<div class="notif-entry-wrapper media">
-			<div class="notif-photo-wrapper media-object pull-left"><a href="{6}" class="userinfo"><img data-src="{1}"></a></div>
+			<div class="notif-photo-wrapper media-object pull-left"><a href="{6}" class="userinfo click-card"><img data-src="{1}"></a></div>
 			<a href="{0}" class="notif-desc-wrapper media-body">
 				{2}
 				<div><time class="notif-when time" data-toggle="tooltip" title="{5}">{3}</time></div>
diff --git a/view/theme/frio/templates/notify.tpl b/view/theme/frio/templates/notify.tpl
index a42647cff8..58f3b0da9f 100644
--- a/view/theme/frio/templates/notify.tpl
+++ b/view/theme/frio/templates/notify.tpl
@@ -1,7 +1,7 @@
 
 <div class="notif-item {{if !$item_seen}}unseen{{/if}} {{$item_label}} media">
 	<div class="notif-photo-wrapper media-object pull-left">
-		<a class="userinfo" href="{{$item_url}}"><img src="{{$item_image}}" class="notif-image"></a>
+		<a class="userinfo click-card" href="{{$item_url}}"><img src="{{$item_image}}" class="notif-image"></a>
 	</div>
 	<div class="notif-desc-wrapper media-body">
 		<a href="{{$item_link}}">
diff --git a/view/theme/frio/templates/photo_item.tpl b/view/theme/frio/templates/photo_item.tpl
index 935e6288b3..54eb3c1d43 100644
--- a/view/theme/frio/templates/photo_item.tpl
+++ b/view/theme/frio/templates/photo_item.tpl
@@ -21,7 +21,7 @@
 
 	{{* avatar picture *}}
 	<div class="contact-photo-wrapper mframe p-author h-card pull-left">
-		<a class="userinfo u-url" id="wall-item-photo-menu-{{$id}}" href="{{$profile_url}}">
+		<a class="userinfo click-card u-url" id="wall-item-photo-menu-{{$id}}" href="{{$profile_url}}">
 			<div class="contact-photo-image-wrapper">
 				<img src="{{$thumb}}" class="contact-photo-xs media-object p-name u-photo" id="wall-item-photo-{{$id}}" alt="{{$name}}" />
 			</div>
@@ -33,7 +33,7 @@
 		{{* the header with the comment author name *}}
 		<div role="heading " class="contact-info-comment">
 			<h5 class="media-heading">
-				<a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link userinfo"><span class="btn-link">{{$name}}</span></a>
+				<a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link userinfo hover-card"><span class="btn-link">{{$name}}</span></a>
 			</h5>
 		</div>
 
diff --git a/view/theme/frio/templates/search_item.tpl b/view/theme/frio/templates/search_item.tpl
index 7f3c0936d1..6c2b815161 100644
--- a/view/theme/frio/templates/search_item.tpl
+++ b/view/theme/frio/templates/search_item.tpl
@@ -74,14 +74,14 @@
 			{{* The avatar picture and the photo-menu *}}
 			<div class="dropdown pull-left"><!-- Dropdown -->
 				<div class="hidden-sm hidden-xs contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}}">
-					<a href="{{$item.profile_url}}" class="userinfo u-url" id="wall-item-photo-menu-{{$item.id}}">
+					<a href="{{$item.profile_url}}" class="userinfo click-card u-url" id="wall-item-photo-menu-{{$item.id}}">
 						<div class="contact-photo-image-wrapper">
 							<img src="{{$item.thumb}}" class="contact-photo media-object {{$item.sparkle}}" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" />
 						</div>
 					</a>
 				</div>
 				<div class="hidden-lg hidden-md contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}}">
-					<a href="{{$item.profile_url}}" class="userinfo u-url" id="wall-item-photo-menu-xs-{{$item.id}}">
+					<a href="{{$item.profile_url}}" class="userinfo click-card u-url" id="wall-item-photo-menu-xs-{{$item.id}}">
 						<div class="contact-photo-image-wrapper">
 							<img src="{{$item.thumb}}" class="contact-photo-xs media-object {{$item.sparkle}}" id="wall-item-photo-xs-{{$item.id}}" alt="{{$item.name}}" />
 						</div>
@@ -91,10 +91,22 @@
 
 
 			{{* contact info header*}}
-			<div role="heading " class="contact-info hidden-sm hidden-xs media-body"><!-- <= For computer -->
-				<h4 class="media-heading"><a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span></a>
-					{{if $item.owner_url}}{{$item.via}} <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}}
-					{{if $item.lock}}<span class="navicon lock fakelink" onClick="lockview(event, {{$item.id}});" title="{{$item.lock}}">&nbsp;<small><i class="fa fa-lock" aria-hidden="true"></i></small></span>{{/if}}
+			<div role="heading" class="contact-info hidden-sm hidden-xs media-body"><!-- <= For computer -->
+				<h4 class="media-heading">
+					<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card">
+						<span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span>
+					</a>
+				{{if $item.owner_url}}
+					{{$item.via}}
+					<a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo hover-card">
+						<span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span>
+					</a>
+				{{/if}}
+				{{if $item.lock}}
+					<span class="navicon lock fakelink" onClick="lockview(event, {{$item.id}});" title="{{$item.lock}}">
+						&nbsp;<small><i class="fa fa-lock" aria-hidden="true"></i></small>
+					</span>
+				{{/if}}
 
 					<div class="additional-info text-muted">
 						<div id="wall-item-ago-{{$item.id}}" class="wall-item-ago">
@@ -114,7 +126,7 @@
 			{{* contact info header for smartphones *}}
 			<div role="heading " class="contact-info-xs hidden-lg hidden-md">
 				<h5 class="media-heading">
-					<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span>{{$item.name}}</span></a>
+					<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card"><span>{{$item.name}}</span></a>
 					<p class="text-muted"><small>
 						<span class="wall-item-ago">{{$item.ago}}</span> {{if $item.location}}&nbsp;&mdash;&nbsp;({{$item.location nofilter}}){{/if}}</small>
 					</p>
diff --git a/view/theme/frio/templates/wall_thread.tpl b/view/theme/frio/templates/wall_thread.tpl
index 5a10a02552..631aad3be2 100644
--- a/view/theme/frio/templates/wall_thread.tpl
+++ b/view/theme/frio/templates/wall_thread.tpl
@@ -159,14 +159,14 @@ as the value of $top_child_total (this is done at the end of this file)
 		<div class="dropdown pull-left"><!-- Dropdown -->
 			{{if $item.thread_level==1}}
 			<div class="hidden-sm hidden-xs contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}} p-author h-card">
-				<a class="userinfo  u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
+				<a class="userinfo click-card u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
 					<div class="contact-photo-image-wrapper">
 						<img src="{{$item.thumb}}" class="contact-photo media-object {{$item.sparkle}} p-name u-photo" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" />
 					</div>
 				</a>
 			</div>
 			<div class="hidden-lg hidden-md contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}}">
-				<a class="userinfo u-url" id="wall-item-photo-menu-xs-{{$item.id}}" href="{{$item.profile_url}}">
+				<a class="userinfo click-card u-url" id="wall-item-photo-menu-xs-{{$item.id}}" href="{{$item.profile_url}}">
 					<div class="contact-photo-image-wrapper">
 						<img src="{{$item.thumb}}" class="contact-photo-xs media-object {{$item.sparkle}}" id="wall-item-photo-xs-{{$item.id}}" alt="{{$item.name}}" />
 					</div>
@@ -187,7 +187,7 @@ as the value of $top_child_total (this is done at the end of this file)
 			{{* The avatar picture for comments *}}
 			{{if $item.thread_level!=1}}
 			<div class="contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}} p-author h-card">
-				<a class="userinfo u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
+				<a class="userinfo click-card u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
 					<div class="contact-photo-image-wrapper">
 						<img src="{{$item.thumb}}" class="contact-photo-xs media-object {{$item.sparkle}} p-name u-photo" id="wall-item-photo-comment-{{$item.id}}" alt="{{$item.name}}" />
 					</div>
@@ -201,9 +201,21 @@ as the value of $top_child_total (this is done at the end of this file)
 		{{* contact info header*}}
 		{{if $item.thread_level==1}}
 		<div role="heading " aria-level="{{$item.thread_level}}" class="contact-info hidden-sm hidden-xs media-body"><!-- <= For computer -->
-			<h4 class="media-heading"><a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span></a>
-			{{if $item.owner_url}}{{$item.via}} <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}}
-			{{if $item.lock}}<span class="navicon lock fakelink" onClick="lockview(event,{{$item.id}});" title="{{$item.lock}}" data-toggle="tooltip">&nbsp;<small><i class="fa fa-lock" aria-hidden="true"></i></small></span>{{/if}}
+			<h4 class="media-heading">
+				<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card">
+					<span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span>
+				</a>
+			{{if $item.owner_url}}
+				{{$item.via}}
+				<a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo hover-card">
+					<span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span>
+				</a>
+			{{/if}}
+			{{if $item.lock}}
+				<span class="navicon lock fakelink" onClick="lockview(event,{{$item.id}});" title="{{$item.lock}}" data-toggle="tooltip">
+					&nbsp;<small><i class="fa fa-lock" aria-hidden="true"></i></small>
+				</span>
+			{{/if}}
 			</h4>
 
 			<div class="additional-info text-muted">
@@ -232,7 +244,7 @@ as the value of $top_child_total (this is done at the end of this file)
 		{{* contact info header for smartphones *}}
 		<div role="heading " aria-level="{{$item.thread_level}}" class="contact-info-xs hidden-lg hidden-md"><!-- <= For smartphone (responsive) -->
 			<h5 class="media-heading">
-				<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span>{{$item.name}}</span></a>
+				<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card"><span>{{$item.name}}</span></a>
 				<p class="text-muted">
 					<small>
 						<a class="time" href="{{$item.plink.orig}}"><span class="wall-item-ago">{{$item.ago}}</span></a>
@@ -251,7 +263,7 @@ as the value of $top_child_total (this is done at the end of this file)
 		<div class="media-body">{{*this is the media body for comments - this div must be closed at the end of the file *}}
 		<div role="heading " aria-level="{{$item.thread_level}}" class="contact-info-comment">
 			<h5 class="media-heading">
-				<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span class="fakelink">{{$item.name}}</span></a>
+				<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card"><span class="fakelink">{{$item.name}}</span></a>
 				<span class="text-muted">
 					<small>
 						<a class="time" href="{{$item.plink.orig}}" title="{{$item.localtime}}" data-toggle="tooltip">{{$item.ago}}</a>
-- 
2.39.5