Wanted to do this for a while. Did it today instead of sleeping.
Screenshot:
You can install it from here: https://greasyfork.org/en/scripts/468948-user-details-on-hover
Link to GitHub repo: https://github.com/lemmygod/lemmy-hovercards/tree/main
Or you can copy-paste the following code:
click here to view code.
// ==UserScript==
// @name User Details on Hover
// @namespace http://tampermonkey.net/
// @version 0.12
// @description Show user details on hover
// @author You
// @match *://*/*
// @grant none
// ==/UserScript==
(function () {
"use strict";
const isLemmy =
document.head.querySelector("[name~=Description][content]").content ===
"Lemmy";
if (!isLemmy) return;
// Inject styles for the user card
function main() {
const style = document.createElement("style");
style.innerHTML = `
.user-card {
position: absolute;
display: none;
width: 350px;
background-color: #242424;
color: white;
padding: 15px;
border-radius: 10px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1000;
grid-gap: 10px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.4;
}
.user-card .header {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.user-card img {
width: 80px;
height: 80px;
object-fit: cover;
border-radius: 50%;
margin-right: 15px;
}
.user-card .username {
font-size: 1.3em;
font-weight: bold;
}
.user-card .instance {
font-size: 0.8em;
color: #888;
}
.user-card .body {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
.user-card .key {
font-weight: bold;
}
.user-card .value {
color: #ddd;
margin-top: 10px;
}
.user-card .bio {
grid-column: 1 / -1;
font-style: italic;
}`;
document.head.appendChild(style);
// Create the user card
const userCard = document.createElement("div");
userCard.classList.add("user-card");
userCard.id = "user-card";
document.body.appendChild(userCard);
let timer;
// Find all user links
const userLinks = document.querySelectorAll('a.text-info[href*="/u/"]');
userLinks.forEach((userLink) => {
userLink.setAttribute("title", "");
// When mouse enters, show the user card
userLink.addEventListener("mouseenter", async (event) => {
const username = userLink.href.split("/u/")[1];
// Fetch user details
const userInfo = await getUserInfo(username);
// Format the date
const date = new Date(userInfo.creationDate);
const formattedDate = `${date.getFullYear()}/${String(
date.getMonth() + 1
).padStart(2, "0")}/${String(date.getDate()).padStart(2, "0")}`;
// Update the user card
userCard.innerHTML = `
<div class="header">
<img src="${
userInfo.profilePicture ||
`https://api.dicebear.com/6.x/identicon/svg?seed=${username}`
}" alt="User avatar">
<div>
<div class="username">${
userInfo.name || username.split("@")[0]
}</div>
<a href="https://${
userInfo.instance
}/u/${username}" class="instance">${username}${
username.indexOf("@") === -1 ? "@" + userInfo.instance : ""
}
</a>
</div>
</div>
<div class="body">
<div><span class="key">ID:</span> <span class="value">${
userInfo.id
}</span></div>
<div style="display:flex; flex-direction: column; gap: 3px"><span class="key">
<svg class="icon"><use xlink:href="/static/assets/symbols.svg#icon-cake"></use><div class="sr-only"><title>cake</title></div></svg>
Cake Day:</span> <span class="value">${formattedDate}</span></div>
<div><span class="key">Posts:</span> <span class="value">${
userInfo.post_count
}</span></div>
<div><span class="key">Comments:</span> <span class="value">${
userInfo.comment_count
}</span></div>
<div><span class="key">Post Score:</span> <span class="value">${
userInfo.post_score
}</span></div>
<div><span class="key">Comment Score:</span> <span class="value">${
userInfo.comment_score
}</span></div>
${
userInfo.bio ? `<div class="bio">${userInfo.bio}</div>` : ""
}
</div>`;
// Show the user card at the cursor
const rect = userLink.getBoundingClientRect();
userCard.style.left = `${window.pageXOffset + rect.left}px`;
userCard.style.top = `${window.pageYOffset + rect.bottom + 5}px`;
// setTimeout(() => {
if (userLink.querySelector(":hover")) {
userCard.style.display = "block";
}
// }, 250);
timer = setTimeout(() => {
// check if username is not being hovered anymore after 150ms, after which point we must change display to none
if (!userLink.querySelector(":hover")) {
userCard.style.display = "none";
}
}, 150);
});
// When mouse leaves, hide the user card after a slight delay
userLink.addEventListener("mouseleave", () => {
// after a slight delay, delete the node
timer = setTimeout(() => {
// delete the node
// userCard.parentElement.removeChild(userCard);
userCard.style.display = "none";
}, 250);
setTimeout(() => {
// check if both are unhovered after 260ms, and if that's the case, removeChild anyway
if (!userCard.parentElement) return;
if (!userCard.querySelector(":hover")) {
// userCard.parentElement.removeChild(userCard);
userCard.style.display = "none";
}
}, 250);
// timer = setTimeout(() => {
// userCard.style.display = "none";
// }, 250);
});
});
userCard.addEventListener("mouseenter", () => {
clearTimeout(timer);
});
userCard.addEventListener("mouseleave", () => {
userCard.style.display = "none";
// userCard.parentElement.removeChild(userCard);
});
// Fetch user info from the API
async function getUserInfo(userName) {
const instanceName = location.href.split("/")[2];
const response = await fetch(
`https://${instanceName}/api/v3/user?username=${userName}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const user = await response.json();
const {
published: creationDate,
avatar: profilePicture,
bio,
display_name: name,
name: username,
id,
banner,
} = user.person_view.person;
const { comment_count, comment_score, post_count, post_score } =
user.person_view.counts;
return {
creationDate,
profilePicture,
bio,
name,
username,
id,
banner,
instance: instanceName,
comment_count,
comment_score,
post_count,
post_score,
};
}
}
// detect react changed url but didn't reload the page by checking for url change
var oldHref = document.location.href;
setInterval(function () {
if (document.location.href !== oldHref) {
oldHref = document.location.href;
// Wait for the page to load
setTimeout(main, 1000);
console.log("url changed!");
}
}, 500);
// run on page load
main();
})();
asked ChatGPT to make an intro cuz why not:
Bringing User Details to Your Fingertips: The New Lemmy User Hover Card
For some time now, I’ve had an idea percolating in the back of my mind. I wanted to make browsing Lemmy, the open-source, federated link aggregation community, a bit more efficient and user-friendly. Well, I’m delighted to announce that I’ve finally turned that idea into a reality. Today, I present to you the new and improved Lemmy User Hover Card.
The Lemmy User Hover Card is a handy userscript, designed to streamline your Lemmy browsing experience. In essence, it allows you to view detailed information about a user simply by hovering over their username.
Functionality
This script works by listening for your mouse movements. When you hover over a user’s username, the script fetches the user’s information, including their name, username, ID, bio, instance, profile picture, and some usage statistics such as the number of posts and comments they’ve made. This information is then neatly formatted into a small, convenient pop-up card that appears next to the cursor.
Design and User Experience
Understanding the importance of design and user experience, special attention has been paid to these aspects. The user card follows a simple, clean design, with a dark-themed color scheme that is easy on the eyes. Information is presented in a grid layout for better readability, and different typographic styles are used to create a clear visual hierarchy between different elements.
The card also ensures a seamless user experience. The card appears immediately when you hover over a username but doesn’t disappear instantly when the cursor leaves the username. Instead, there’s a short delay that allows you to move your cursor onto the card to view the information at your leisure.
Lastly, the user’s instance is clickable, allowing you to easily visit their instance.
How to Use
To use the Lemmy User Hover Card, you’ll need to have a userscript manager like Tampermonkey installed in your browser. Then, you can simply add the script to your manager and it will automatically start working whenever you browse Lemmy.
In summary, the Lemmy User Hover Card is an easy-to-use, efficient tool that can greatly enhance your Lemmy browsing experience. So why wait? Give it a try and let us know what you think!