Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.5 kB · 67 lines
JavaScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768import { esc } from '../utils.js';import { createElement, User } from 'lucide';
function postImages(post) { const embed = post?.embed; if (!embed) return []; if (embed.$type === 'app.bsky.embed.images#view') return embed.images || []; if (embed.$type === 'app.bsky.embed.recordWithMedia#view') { const media = embed.media; if (media?.$type === 'app.bsky.embed.images#view') return media.images || []; } return [];}
export function createCard(profile, hotkey, onClick, isFollowed = false) { const card = document.createElement('div'); card.className = `border border-black dark:border-gray-600 p-3 cursor-pointer flex flex-col break-words${isFollowed ? ' opacity-60' : ''}`;
const hint = isFollowed ? ` <span class="font-normal text-gray-600 dark:text-gray-400">unfollow</span>` : ''; const keyHtml = `<span class="font-bold text-base align-baseline">[${hotkey}]${hint}</span>`; const posts = (profile.topPosts || []).slice(0, 2); const postsHtml = posts.length ? posts.map((p, i) => { const lead = postImages(p)[0]; const leadHtml = lead ? `<img src="${esc(lead.thumb)}" alt="${esc(lead.alt || '')}" class="w-16 h-16 object-cover border border-black dark:border-gray-600 float-right ml-2 mb-1" />` : ''; return ` <div class="text-[0.85em] leading-snug${i > 0 ? ' mt-2 pt-2 border-t border-black dark:border-gray-600' : ''}"> <div class="whitespace-pre-wrap">${leadHtml}${esc(p.record?.text || '')}</div> <div class="text-gray-600 dark:text-gray-400 text-[0.75em] mt-0.5 tabular-nums clear-right">${(p.likeCount || 0).toLocaleString()} likes</div> </div>`; }).join('') : `<div class="text-[0.85em] text-gray-600 dark:text-gray-400">no recent posts</div>`;
card.innerHTML = `<div class="pb-2 flex items-start gap-2">` + `<div class="min-w-0 flex-1">` + `<div class="leading-tight truncate">${keyHtml}${profile.displayName ? ` ${esc(profile.displayName)}` : ''}</div>` + `<div class="text-gray-600 dark:text-gray-400 leading-tight truncate">@${esc(profile.handle)}${isFollowed ? ' (following)' : ''}</div>` + (profile.followersCount != null ? `<div class="text-[0.85em] mt-1 leading-tight tabular-nums">${profile.followersCount.toLocaleString()} followers</div>` : '') + `</div>` + `<span class="avatar-slot shrink-0 w-10 h-10 border border-black dark:border-gray-600 flex items-center justify-center"></span>` + `</div>` + (profile.description ? `<div class="text-[0.85em] leading-snug text-gray-600 dark:text-gray-400 pb-2 italic">${esc(profile.description.length > 100 ? profile.description.slice(0, profile.description.lastIndexOf(' ', 100)) + '…' : profile.description)}</div>` : '') + `<div class="flex-1 pt-2 border-t border-black dark:border-gray-600">` + postsHtml + `</div>`;
const slot = card.querySelector('.avatar-slot'); if (profile.avatar) { const img = document.createElement('img'); img.src = profile.avatar; img.className = 'w-10 h-10 object-cover block'; img.onerror = () => { img.remove(); slot.appendChild(createElement(User, { width: 16, height: 16, 'stroke-width': 2 })); }; slot.className = 'avatar-slot shrink-0 w-10 h-10 block'; slot.appendChild(img); } else { slot.appendChild(createElement(User, { width: 16, height: 16, 'stroke-width': 2 })); }
card.addEventListener('click', onClick); return card;}