diff --git a/src/js/background.js b/src/js/background.js index d5b873c..bb8a0f7 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -260,12 +260,24 @@ const sitePasswords = { "soft98.ir": "soft98.ir", }; +// Hardcoded site invite codes - Maps domains to their invite codes +const siteInviteCodes = { + "ee3.me": "mpgh", + "rips.cc": "mpgh", +}; + // Get password for a domain function getPasswordForDomain(hostname) { const domain = hostname.replace(/^www\./, "").toLowerCase(); return sitePasswords[domain] || null; } +// Get invite code for a domain +function getInviteCodeForDomain(hostname) { + const domain = hostname.replace(/^www\./, "").toLowerCase(); + return siteInviteCodes[domain] || null; +} + // Get note slug for a domain function getNoteSlugForDomain(hostname) { const domain = hostname.replace(/^www\./, "").toLowerCase(); @@ -927,10 +939,13 @@ browserAPI.runtime.onMessage.addListener((message, sender, sendResponse) => { // Get password if available const password = getPasswordForDomain(domain); + // Get invite code if available + const inviteCode = getInviteCodeForDomain(domain); + console.log( `getSiteStatus result for ${url}: ${status}, matched: ${matchedUrl}` ); - sendResponse({ status: status, matchedUrl: matchedUrl, reason: reason, password: password }); + sendResponse({ status: status, matchedUrl: matchedUrl, reason: reason, password: password, inviteCode: inviteCode }); } catch (error) { console.error("Error in getSiteStatus handler:", error); sendResponse({ diff --git a/src/pub/index.html b/src/pub/index.html index 4d0c915..a6f749b 100644 --- a/src/pub/index.html +++ b/src/pub/index.html @@ -243,6 +243,67 @@ color: #000; } + /* Invite Code Section Styles */ + #invite-code-container { + margin-top: 15px; + padding: 10px; + background: var(--hover-bg); + border-radius: 8px; + text-align: left; + display: none; + } + + #invite-code-container.visible { + display: block; + } + + #invite-code-title { + font-size: 13px; + font-weight: 600; + color: #f59e0b; + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 6px; + } + + #invite-code-title svg { + stroke: #f59e0b; + } + + #invite-code-content { + font-size: 14px; + font-weight: 600; + font-family: monospace; + color: var(--text-color); + background: var(--bg-color); + padding: 6px 10px; + border-radius: 4px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + } + + #invite-code-content:hover { + background: var(--hover-bg); + } + + #invite-code-content .copy-icon { + opacity: 0.5; + flex-shrink: 0; + } + + #invite-code-content:hover .copy-icon { + opacity: 1; + } + + #invite-code-content.copied { + background: #f59e0b; + color: #000; + } + /* Reason Section Styles */ #reason-container { margin-top: 15px; @@ -376,15 +437,38 @@

- + - Password + Password
- + + + + +
+
+
+
+ + + + + + + + Invite Code +
+
+ + @@ -392,7 +476,8 @@
- + diff --git a/src/pub/index.js b/src/pub/index.js index cc6cf44..9e0b1ad 100644 --- a/src/pub/index.js +++ b/src/pub/index.js @@ -58,25 +58,25 @@ document.addEventListener("DOMContentLoaded", async () => { // Store images to protect from URL linking const imgTags = []; - + let result = md // Remove the main header (#### Title) since we show "FMHY Note" already .replace(/^#{1,4}\s+.*$/gm, '') // Trim leading/trailing whitespace .trim(); - + // Protect HTML img tags from URL linking result = result.replace(/]*>/gi, (match) => { imgTags.push(match); return `[[HTMLIMG_${imgTags.length - 1}]]`; }); - + // Convert markdown images ![alt](url) to placeholder result = result.replace(/!\[(.*?)\]\((.*?)\)/g, (match, alt, url) => { imgTags.push(`${alt}`); return `[[HTMLIMG_${imgTags.length - 1}]]`; }); - + result = result // Bold (must come before italic) .replace(/\*\*(.*?)\*\*/g, '$1') @@ -84,13 +84,13 @@ document.addEventListener("DOMContentLoaded", async () => { .replace(/\*(.*?)\*/g, '$1') // Markdown links [text](url) - use placeholder to avoid double-linking .replace(/\[(.*?)\]\((.*?)\)/g, '[[LINK:$2:$1]]'); - + // Raw URLs (convert before restoring markdown links and images) result = result.replace(/(https?:\/\/[^\s<>\)\]]+)/g, '$1'); - + // Restore markdown links from placeholders result = result.replace(/\[\[LINK:(.*?):(.*?)\]\]/g, '$2'); - + // Restore images from placeholders result = result.replace(/\[\[HTMLIMG_(\d+)\]\]/g, (match, index) => imgTags[parseInt(index)]); @@ -307,7 +307,7 @@ document.addEventListener("DOMContentLoaded", async () => { } // Update the popup with the result - handleStatusUpdate(response.status, displayUrl, response.reason, response.password); + handleStatusUpdate(response.status, displayUrl, response.reason, response.password, response.inviteCode); } catch (error) { console.error("Error checking site status:", error); errorMessage.textContent = `Error: ${error.message}`; @@ -315,7 +315,7 @@ document.addEventListener("DOMContentLoaded", async () => { } } - function handleStatusUpdate(status, displayUrl, reason, password) { + function handleStatusUpdate(status, displayUrl, reason, password, inviteCode) { let message; // Handle reason display in dedicated container @@ -350,6 +350,27 @@ document.addEventListener("DOMContentLoaded", async () => { passwordContainer.classList.remove("visible"); } + // Handle invite code display + const inviteCodeContainer = document.getElementById("invite-code-container"); + const inviteCodeText = document.getElementById("invite-code-text"); + const inviteCodeContent = document.getElementById("invite-code-content"); + if (inviteCode && inviteCodeContainer && inviteCodeText) { + inviteCodeText.textContent = inviteCode; + inviteCodeContainer.classList.add("visible"); + // Add click-to-copy functionality + inviteCodeContent.onclick = async () => { + try { + await navigator.clipboard.writeText(inviteCode); + inviteCodeContent.classList.add("copied"); + setTimeout(() => inviteCodeContent.classList.remove("copied"), 1000); + } catch (err) { + console.error("Failed to copy invite code:", err); + } + }; + } else if (inviteCodeContainer) { + inviteCodeContainer.classList.remove("visible"); + } + // Use i18n for status messages if available const getMessage = window.i18n ? window.i18n.getMessage : (key, sub) => null;