- bouton flottant rond (44px), semi-transparent blur, hover plus fonce, deplacable souris (pos persistee storage) - option afficher/cacher dans popup extension (showButton) - clipper: notification instantanee des onglets FlowDeck via tabs.sendMessage + polling 15s + BroadcastChannel + visibilitychange - fix bookmark template literal '+title+' -> \/\/\/\/\ (_page_editor_scripts.html) - sync static/extension + zip
96 lines
3.8 KiB
JavaScript
96 lines
3.8 KiB
JavaScript
// Popup logic
|
|
const $ = (id) => document.getElementById(id);
|
|
|
|
async function load() {
|
|
const cfg = await chrome.runtime.sendMessage({ action: "getConfig" });
|
|
$("serverUrl").value = cfg.serverUrl || "http://localhost:8080";
|
|
$("token").value = cfg.token || "";
|
|
const sb = $("showButton");
|
|
if (sb) sb.checked = cfg.showButton !== false;
|
|
}
|
|
|
|
async function save() {
|
|
const serverUrl = $("serverUrl").value.trim() || "http://localhost:8080";
|
|
const token = $("token").value.trim();
|
|
const showButton = $("showButton") ? $("showButton").checked : true;
|
|
const cfg = await chrome.runtime.sendMessage({ action: "getConfig" });
|
|
cfg.serverUrl = serverUrl.replace(/\/$/, "");
|
|
cfg.token = token;
|
|
cfg.showButton = showButton;
|
|
await chrome.runtime.sendMessage({ action: "setConfig", config: cfg });
|
|
show("Saved ✓", "ok");
|
|
}
|
|
|
|
async function toggleButton(show) {
|
|
const cfg = await chrome.runtime.sendMessage({ action: "getConfig" });
|
|
cfg.showButton = show;
|
|
await chrome.runtime.sendMessage({ action: "setConfig", config: cfg });
|
|
// Notify all tabs immediately for instant UX
|
|
try {
|
|
const tabs = await chrome.tabs.query({});
|
|
for (const t of tabs) {
|
|
if (!t.id) continue;
|
|
chrome.tabs.sendMessage(t.id, { action: "toggleButton", show }).catch(() => {});
|
|
}
|
|
} catch (_e) {}
|
|
}
|
|
|
|
async function verify() {
|
|
await save();
|
|
const res = await chrome.runtime.sendMessage({ action: "auth" });
|
|
if (res && res.authenticated) show(`Connected as ${res.user?.login || "user"} — ${res.devices} device(s)`, "ok");
|
|
else if (res && res.authenticated === false) show("Not authenticated — check token / server URL", "err");
|
|
else show(JSON.stringify(res).slice(0, 200), "warn");
|
|
}
|
|
|
|
function show(msg, kind) {
|
|
const el = $("status");
|
|
el.textContent = msg;
|
|
el.className = "status " + kind;
|
|
}
|
|
|
|
async function doClip(type) {
|
|
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
|
if (!tab) return;
|
|
// Get page data via scripting
|
|
const [{ result }] = await chrome.scripting.executeScript({
|
|
target: { tabId: tab.id },
|
|
func: (clipType) => {
|
|
const sel = window.getSelection();
|
|
const html = document.documentElement.outerHTML;
|
|
const selectionHtml = (() => {
|
|
if (!sel || sel.rangeCount === 0) return "";
|
|
const d = document.createElement("div");
|
|
d.appendChild(sel.getRangeAt(0).cloneContents());
|
|
return d.innerHTML;
|
|
})();
|
|
return {
|
|
url: location.href,
|
|
title: document.title,
|
|
html: html,
|
|
content_type: sel && sel.toString().trim().length > 20 ? "selection" : clipType,
|
|
selection_html: selectionHtml,
|
|
metadata: {
|
|
og_description: document.querySelector('meta[property="og:description"]')?.content || document.querySelector('meta[name="description"]')?.content || ""
|
|
}
|
|
};
|
|
},
|
|
args: [type]
|
|
});
|
|
const resp = await chrome.runtime.sendMessage({ action: "clip", data: result });
|
|
if (resp && resp.status === "ok") show(`Clipped → page ${resp.page_id} ✓`, "ok");
|
|
else show(resp.detail || resp.error || "Clip failed", "err");
|
|
}
|
|
|
|
$("save").addEventListener("click", save);
|
|
$("verify").addEventListener("click", verify);
|
|
$("clipArticle").addEventListener("click", () => doClip("article"));
|
|
$("clipBookmark").addEventListener("click", () => doClip("bookmark"));
|
|
$("clipSelection").addEventListener("click", () => doClip("selection"));
|
|
$("openFlowDeck").addEventListener("click", (e) => { e.preventDefault(); chrome.tabs.create({ url: $("serverUrl").value || "http://localhost:8080" }); });
|
|
$("openExtensions").addEventListener("click", (e) => { e.preventDefault(); chrome.tabs.create({ url: ($("serverUrl").value || "http://localhost:8080") + "/extensions" }); });
|
|
const _sb = $("showButton");
|
|
if (_sb) _sb.addEventListener("change", (e) => toggleButton(e.target.checked));
|
|
|
|
load();
|