305 lines
10 KiB
JavaScript
305 lines
10 KiB
JavaScript
function normalizeApiUrl(url) {
|
|
if (!url) return "";
|
|
url = url.trim().replace(/^['"]|['"]$/g, "");
|
|
if (!url) return "";
|
|
if (!/^https?:\/\//i.test(url)) {
|
|
url = "http://" + url;
|
|
}
|
|
try {
|
|
const parsed = new URL(url);
|
|
let path = parsed.pathname.replace(/\/+$/, "");
|
|
if (!path || path === "") {
|
|
return `${parsed.origin}/api/v2/upload`;
|
|
} else if (path.endsWith("/api/v2")) {
|
|
return `${parsed.origin}/upload`;
|
|
} else if (!path.endsWith("/upload")) {
|
|
return `${parsed.origin}/api/v2/upload`;
|
|
}
|
|
return url;
|
|
} catch (e) {
|
|
return url;
|
|
}
|
|
}
|
|
|
|
function initPopup() {
|
|
const modeDesktop = document.getElementById("mode-desktop");
|
|
const modeDirect = document.getElementById("mode-direct");
|
|
const btnOpenOptions = document.getElementById("btn-open-options");
|
|
const apiConfigCard = document.getElementById("api-config-card");
|
|
const popupApiUrl = document.getElementById("popup-api-url");
|
|
const popupApiKey = document.getElementById("popup-api-key");
|
|
const btnSaveApiConfig = document.getElementById("btn-save-api-config");
|
|
const btnPopupTest = document.getElementById("btn-popup-test");
|
|
const popupApiToast = document.getElementById("popup-api-toast");
|
|
|
|
const btnUploadTab = document.getElementById("btn-upload-tab");
|
|
const btnUploadText = document.getElementById("btn-upload-text");
|
|
const btnUploadUrl = document.getElementById("btn-upload-url");
|
|
const urlInput = document.getElementById("url-input");
|
|
const statusCard = document.getElementById("status-card");
|
|
const statusSpinner = document.getElementById("status-spinner");
|
|
const statusText = document.getElementById("status-text");
|
|
const resultContainer = document.getElementById("result-container");
|
|
const resultLink = document.getElementById("result-link");
|
|
const btnCopyResult = document.getElementById("btn-copy-result");
|
|
const siteBadge = document.getElementById("site-badge");
|
|
const tabTitle = document.getElementById("tab-title");
|
|
const tabUrlPreview = document.getElementById("tab-url-preview");
|
|
|
|
let activeTabUrl = "";
|
|
|
|
if (btnOpenOptions) {
|
|
btnOpenOptions.addEventListener("click", () => {
|
|
if (chrome.runtime.openOptionsPage) {
|
|
chrome.runtime.openOptionsPage();
|
|
} else {
|
|
window.open(chrome.runtime.getURL("options/options.html"));
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateModeUI(mode) {
|
|
if (mode === "direct") {
|
|
if (modeDirect) modeDirect.checked = true;
|
|
if (apiConfigCard) apiConfigCard.classList.remove("hidden");
|
|
} else {
|
|
if (modeDesktop) modeDesktop.checked = true;
|
|
if (apiConfigCard) apiConfigCard.classList.add("hidden");
|
|
}
|
|
}
|
|
|
|
// 1. Load settings & drafts asynchronously without blocking UI initialization
|
|
try {
|
|
chrome.storage.sync.get({ uploadMode: "desktop", apiUrl: "", apiKey: "", draftUrl: "" }, (settings) => {
|
|
if (chrome.runtime.lastError || !settings) return;
|
|
if (popupApiUrl) popupApiUrl.value = settings.apiUrl || "";
|
|
if (popupApiKey) popupApiKey.value = settings.apiKey || "";
|
|
if (urlInput && settings.draftUrl) urlInput.value = settings.draftUrl;
|
|
updateModeUI(settings.uploadMode);
|
|
});
|
|
} catch (e) {}
|
|
|
|
// Auto-save on input so values are never lost if popup closes when copying/switching tabs
|
|
if (popupApiUrl) {
|
|
popupApiUrl.addEventListener("input", () => {
|
|
chrome.storage.sync.set({ apiUrl: popupApiUrl.value });
|
|
});
|
|
}
|
|
if (popupApiKey) {
|
|
popupApiKey.addEventListener("input", () => {
|
|
chrome.storage.sync.set({ apiKey: popupApiKey.value });
|
|
});
|
|
}
|
|
if (urlInput) {
|
|
urlInput.addEventListener("input", () => {
|
|
chrome.storage.sync.set({ draftUrl: urlInput.value });
|
|
});
|
|
}
|
|
|
|
if (modeDesktop) {
|
|
modeDesktop.addEventListener("change", () => {
|
|
chrome.storage.sync.set({ uploadMode: "desktop" }, () => {
|
|
updateModeUI("desktop");
|
|
});
|
|
});
|
|
}
|
|
if (modeDirect) {
|
|
modeDirect.addEventListener("change", () => {
|
|
chrome.storage.sync.set({ uploadMode: "direct" }, () => {
|
|
updateModeUI("direct");
|
|
});
|
|
});
|
|
}
|
|
|
|
if (btnSaveApiConfig) {
|
|
btnSaveApiConfig.addEventListener("click", () => {
|
|
const rawUrl = popupApiUrl ? popupApiUrl.value.trim() : "";
|
|
const key = popupApiKey ? popupApiKey.value.trim() : "";
|
|
const normUrl = normalizeApiUrl(rawUrl);
|
|
if (popupApiUrl && normUrl) popupApiUrl.value = normUrl;
|
|
|
|
chrome.storage.sync.set({ apiUrl: normUrl || rawUrl, apiKey: key }, () => {
|
|
if (popupApiToast) {
|
|
popupApiToast.textContent = "Saved!";
|
|
popupApiToast.style.color = "#00e676";
|
|
setTimeout(() => { popupApiToast.textContent = ""; }, 2000);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
if (btnPopupTest) {
|
|
btnPopupTest.addEventListener("click", () => {
|
|
const url = popupApiUrl ? popupApiUrl.value.trim() : "";
|
|
const key = popupApiKey ? popupApiKey.value.trim() : "";
|
|
if (!url || !key) {
|
|
if (popupApiToast) {
|
|
popupApiToast.textContent = "Enter URL & Key!";
|
|
popupApiToast.style.color = "#ff4444";
|
|
}
|
|
return;
|
|
}
|
|
btnPopupTest.disabled = true;
|
|
if (popupApiToast) {
|
|
popupApiToast.textContent = "Testing...";
|
|
popupApiToast.style.color = "#4da6ff";
|
|
}
|
|
|
|
chrome.runtime.sendMessage({ action: "test_connection", apiUrl: url, apiKey: key }, (res) => {
|
|
btnPopupTest.disabled = false;
|
|
if (popupApiToast) {
|
|
if (res && res.success) {
|
|
popupApiToast.textContent = "✓ OK!";
|
|
popupApiToast.style.color = "#00e676";
|
|
} else {
|
|
popupApiToast.textContent = "❌ " + (res ? res.msg : "Failed");
|
|
popupApiToast.style.color = "#ff4444";
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// 2. Query Tab Info immediately
|
|
try {
|
|
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
|
if (tabs && tabs[0]) {
|
|
populateTabInfo(tabs[0]);
|
|
} else {
|
|
chrome.tabs.query({ active: true, lastFocusedWindow: true }, (tabs2) => {
|
|
if (tabs2 && tabs2[0]) {
|
|
populateTabInfo(tabs2[0]);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
} catch (e) {}
|
|
|
|
function populateTabInfo(tab) {
|
|
if (!tab) return;
|
|
activeTabUrl = tab.url || tab.pendingUrl || "";
|
|
if (tabTitle) tabTitle.textContent = tab.title || "Active Page";
|
|
if (tabUrlPreview) tabUrlPreview.textContent = activeTabUrl || "No URL available";
|
|
|
|
const isYouTube = activeTabUrl.includes("youtube.com") || activeTabUrl.includes("youtu.be");
|
|
if (isYouTube) {
|
|
if (siteBadge) {
|
|
siteBadge.textContent = "▶ YouTube";
|
|
siteBadge.classList.add("youtube");
|
|
}
|
|
if (btnUploadText) btnUploadText.textContent = "Upload YouTube Video to f0ckm";
|
|
if (btnUploadTab) btnUploadTab.classList.add("youtube-style");
|
|
} else {
|
|
if (siteBadge) {
|
|
siteBadge.textContent = "🌐 Web Page";
|
|
siteBadge.classList.remove("youtube");
|
|
}
|
|
if (btnUploadText) btnUploadText.textContent = "Upload Page URL to f0ckm";
|
|
if (btnUploadTab) btnUploadTab.classList.remove("youtube-style");
|
|
}
|
|
}
|
|
|
|
// 3. Upload Active Tab Button Click Handler
|
|
if (btnUploadTab) {
|
|
btnUploadTab.addEventListener("click", () => {
|
|
if (activeTabUrl && (activeTabUrl.startsWith("http://") || activeTabUrl.startsWith("https://"))) {
|
|
triggerUpload(activeTabUrl);
|
|
} else {
|
|
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
|
const tab = tabs ? tabs[0] : null;
|
|
const url = tab ? (tab.url || tab.pendingUrl) : "";
|
|
if (url && (url.startsWith("http://") || url.startsWith("https://"))) {
|
|
activeTabUrl = url;
|
|
triggerUpload(url);
|
|
} else {
|
|
showStatus("Could not get active tab URL.", false);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// 4. Custom pasted URL Upload Button Click Handler
|
|
if (btnUploadUrl) {
|
|
btnUploadUrl.addEventListener("click", () => {
|
|
const url = urlInput ? urlInput.value.trim() : "";
|
|
if (url) {
|
|
triggerUpload(url);
|
|
} else {
|
|
showStatus("Please enter a valid URL.", false);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (urlInput) {
|
|
urlInput.addEventListener("keydown", (e) => {
|
|
if (e.key === "Enter" && btnUploadUrl) {
|
|
btnUploadUrl.click();
|
|
}
|
|
});
|
|
}
|
|
|
|
if (btnCopyResult) {
|
|
btnCopyResult.addEventListener("click", () => {
|
|
const linkUrl = resultLink ? resultLink.href : "";
|
|
if (linkUrl && linkUrl !== "#" && !linkUrl.endsWith("#")) {
|
|
navigator.clipboard.writeText(linkUrl);
|
|
btnCopyResult.textContent = "Copied!";
|
|
setTimeout(() => {
|
|
btnCopyResult.textContent = "Copy Link";
|
|
}, 1500);
|
|
}
|
|
});
|
|
}
|
|
|
|
function showStatus(text, loading = false) {
|
|
if (!statusCard) return;
|
|
statusCard.classList.remove("hidden");
|
|
if (statusText) statusText.textContent = text;
|
|
if (loading) {
|
|
if (statusSpinner) statusSpinner.classList.remove("hidden");
|
|
if (resultContainer) resultContainer.classList.add("hidden");
|
|
} else {
|
|
if (statusSpinner) statusSpinner.classList.add("hidden");
|
|
}
|
|
}
|
|
|
|
function showSuccessResult(finalUrl) {
|
|
if (!statusCard) return;
|
|
statusCard.classList.remove("hidden");
|
|
if (statusSpinner) statusSpinner.classList.add("hidden");
|
|
if (statusText) statusText.textContent = "Upload Successful! Click link to open:";
|
|
if (resultLink) {
|
|
resultLink.href = finalUrl;
|
|
resultLink.textContent = finalUrl;
|
|
}
|
|
if (resultContainer) resultContainer.classList.remove("hidden");
|
|
}
|
|
|
|
function triggerUpload(url) {
|
|
const currentMode = (modeDirect && modeDirect.checked) ? "direct" : "desktop";
|
|
|
|
if (currentMode === "desktop") {
|
|
showStatus("Sending URL to f0ckm desktop app...", true);
|
|
chrome.runtime.sendMessage({ action: "upload_url", url: url }, () => {
|
|
showStatus("URL sent to f0ckm app! Check system tray / notifications.", false);
|
|
});
|
|
} else {
|
|
showStatus("Sending URL to f0ckm API...", true);
|
|
chrome.runtime.sendMessage({ action: "upload_url", url: url }, (response) => {
|
|
if (response && response.resultUrl) {
|
|
showSuccessResult(response.resultUrl);
|
|
} else {
|
|
showStatus("Upload failed or queued. Check notification / settings.", false);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", initPopup);
|
|
} else {
|
|
initPopup();
|
|
}
|