utils.js raw

   1  import { kindNames } from './constants.js';
   2  
   3  /**
   4   * Get human-readable name for a Nostr event kind
   5   * @param {number} kind - The event kind number
   6   * @returns {string} Human readable kind name
   7   */
   8  export function getKindName(kind) {
   9      return kindNames[kind] || `Kind ${kind}`;
  10  }
  11  
  12  /**
  13   * Truncate a pubkey for display
  14   * @param {string} pubkey - The full pubkey hex string
  15   * @returns {string} Truncated pubkey
  16   */
  17  export function truncatePubkey(pubkey) {
  18      if (!pubkey) return "unknown";
  19      return pubkey.slice(0, 8) + "..." + pubkey.slice(-8);
  20  }
  21  
  22  /**
  23   * Truncate content for preview display
  24   * @param {string} content - The content to truncate
  25   * @param {number} maxLength - Maximum length before truncation
  26   * @returns {string} Truncated content
  27   */
  28  export function truncateContent(content, maxLength = 100) {
  29      if (!content) return "";
  30      return content.length > maxLength
  31          ? content.slice(0, maxLength) + "..."
  32          : content;
  33  }
  34  
  35  /**
  36   * Format a Unix timestamp for display
  37   * @param {number} timestamp - Unix timestamp in seconds
  38   * @returns {string} Formatted date/time string
  39   */
  40  export function formatTimestamp(timestamp) {
  41      if (!timestamp) return "";
  42      return new Date(timestamp * 1000).toLocaleString();
  43  }
  44  
  45  /**
  46   * Escape HTML special characters to prevent XSS
  47   * @param {string} str - String to escape
  48   * @returns {string} Escaped string
  49   */
  50  export function escapeHtml(str) {
  51      if (!str) return "";
  52      return str
  53          .replace(/&/g, "&")
  54          .replace(/</g, "&lt;")
  55          .replace(/>/g, "&gt;")
  56          .replace(/"/g, "&quot;")
  57          .replace(/'/g, "&#039;");
  58  }
  59  
  60  /**
  61   * Convert "about" text to safe HTML with line breaks
  62   * @param {string} text - The about text
  63   * @returns {string} HTML with line breaks
  64   */
  65  export function aboutToHtml(text) {
  66      if (!text) return "";
  67      return escapeHtml(text).replace(/\n\n/g, "<br>");
  68  }
  69  
  70  /**
  71   * Copy text to clipboard with fallback for older browsers
  72   * @param {string} text - Text to copy
  73   * @returns {Promise<boolean>} Whether copy succeeded
  74   */
  75  export async function copyToClipboard(text) {
  76      try {
  77          await navigator.clipboard.writeText(text);
  78          return true;
  79      } catch (error) {
  80          console.error("Failed to copy to clipboard:", error);
  81          // Fallback for older browsers
  82          try {
  83              const textArea = document.createElement("textarea");
  84              textArea.value = text;
  85              document.body.appendChild(textArea);
  86              textArea.select();
  87              document.execCommand("copy");
  88              document.body.removeChild(textArea);
  89              return true;
  90          } catch (fallbackError) {
  91              console.error("Fallback copy also failed:", fallbackError);
  92              return false;
  93          }
  94      }
  95  }
  96  
  97  /**
  98   * Show copy feedback on a button element
  99   * @param {HTMLElement} button - The button element
 100   * @param {boolean} success - Whether copy succeeded
 101   */
 102  export function showCopyFeedback(button, success = true) {
 103      if (!button) return;
 104      const originalText = button.textContent;
 105      const originalBg = button.style.backgroundColor;
 106  
 107      if (success) {
 108          button.textContent = "";
 109          button.style.backgroundColor = "#4CAF50";
 110      } else {
 111          button.textContent = "L";
 112          button.style.backgroundColor = "#f44336";
 113      }
 114  
 115      setTimeout(() => {
 116          button.textContent = originalText;
 117          button.style.backgroundColor = originalBg;
 118      }, 2000);
 119  }
 120