my prefect server setup prefect-metrics.waow.tech
python orchestration
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 88 lines 2.4 kB view raw
1import type { Card } from '$lib/types'; 2 3const PALETTE = [ 4 'bg-red-900/60 text-red-300 border-red-700/40', 5 'bg-orange-900/60 text-orange-300 border-orange-700/40', 6 'bg-amber-900/60 text-amber-300 border-amber-700/40', 7 'bg-emerald-900/60 text-emerald-300 border-emerald-700/40', 8 'bg-teal-900/60 text-teal-300 border-teal-700/40', 9 'bg-sky-900/60 text-sky-300 border-sky-700/40', 10 'bg-violet-900/60 text-violet-300 border-violet-700/40', 11 'bg-pink-900/60 text-pink-300 border-pink-700/40' 12]; 13 14function hash(s: string): number { 15 let h = 0; 16 for (let i = 0; i < s.length; i++) { 17 h = ((h << 5) - h + s.charCodeAt(i)) | 0; 18 } 19 return Math.abs(h); 20} 21 22export function hashColor(s: string): string { 23 return PALETTE[hash(s) % PALETTE.length]; 24} 25 26export function timeAgo(iso: string): string { 27 const ms = Date.now() - new Date(iso).getTime(); 28 const sec = Math.floor(ms / 1000); 29 if (sec < 60) return 'just now'; 30 const min = Math.floor(sec / 60); 31 if (min < 60) return `${min}m ago`; 32 const hr = Math.floor(min / 60); 33 if (hr < 24) return `${hr}h ago`; 34 const days = Math.floor(hr / 24); 35 if (days < 30) return `${days}d ago`; 36 const months = Math.floor(days / 30); 37 if (months < 12) return `${months}mo ago`; 38 return `${Math.floor(months / 12)}y ago`; 39} 40 41export interface TextSegment { 42 text?: string; 43 code?: string; 44} 45 46export function parseInlineCode(text: string): TextSegment[] { 47 const segments: TextSegment[] = []; 48 const re = /`([^`]+)`/g; 49 let last = 0; 50 let match: RegExpExecArray | null; 51 while ((match = re.exec(text)) !== null) { 52 if (match.index > last) { 53 segments.push({ text: text.slice(last, match.index) }); 54 } 55 segments.push({ code: match[1] }); 56 last = re.lastIndex; 57 } 58 if (last < text.length) { 59 segments.push({ text: text.slice(last) }); 60 } 61 return segments; 62} 63 64export function authorUrl(card: Card): string | null { 65 const user = card.meta.user; 66 if (!user) return null; 67 switch (card.source) { 68 case 'github': 69 return `https://github.com/${user}`; 70 case 'tangled': 71 return `https://tangled.org/${user}`; 72 default: 73 return null; 74 } 75} 76 77export function originUrl(card: Card): string | null { 78 const repo = card.meta.repo; 79 if (!repo) return null; 80 switch (card.source) { 81 case 'github': 82 return `https://github.com/${repo}`; 83 case 'tangled': 84 return `https://tangled.org/zzstoatzz.io/${repo}`; 85 default: 86 return null; 87 } 88}