first init
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Nightcord Background Service Worker
|
||||
* Injecte Nightcord.js dans le MAIN world de Discord via chrome.scripting.executeScript.
|
||||
* Cette méthode bypass la CSP de Discord car l'injection se fait depuis le contexte
|
||||
* privilegié de l'extension, non depuis un script dans la page.
|
||||
*/
|
||||
|
||||
const DISCORD_URLS = [
|
||||
"*://discord.com/*",
|
||||
"*://ptb.discord.com/*",
|
||||
"*://canary.discord.com/*"
|
||||
];
|
||||
|
||||
// Tracks tabs where Nightcord has already been injected to avoid double injection
|
||||
const injectedTabs = new Set();
|
||||
|
||||
async function injectNightcord(tabId) {
|
||||
if (injectedTabs.has(tabId)) return;
|
||||
injectedTabs.add(tabId);
|
||||
|
||||
try {
|
||||
// Inject CSS
|
||||
await chrome.scripting.insertCSS({
|
||||
target: { tabId },
|
||||
files: ["dist/Nightcord.css"]
|
||||
});
|
||||
|
||||
// Inject JS in MAIN world — this bypasses the page's CSP entirely
|
||||
await chrome.scripting.executeScript({
|
||||
target: { tabId },
|
||||
files: ["dist/Nightcord.js"],
|
||||
world: "MAIN"
|
||||
});
|
||||
|
||||
console.log(`[Nightcord] Injected into tab ${tabId}`);
|
||||
} catch (e) {
|
||||
// Tab may have navigated away, ignore
|
||||
injectedTabs.delete(tabId);
|
||||
console.warn(`[Nightcord] Injection failed for tab ${tabId}:`, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for message from content.js signaling the page is ready
|
||||
chrome.runtime.onMessage.addListener((msg, sender) => {
|
||||
if (msg?.type === "NIGHTCORD_INJECT" && sender?.tab?.id) {
|
||||
injectNightcord(sender.tab.id);
|
||||
}
|
||||
});
|
||||
|
||||
// Cleanup when tab is closed
|
||||
chrome.tabs.onRemoved.addListener((tabId) => {
|
||||
injectedTabs.delete(tabId);
|
||||
});
|
||||
|
||||
// Also cleanup on navigation (SPA navigations stay in same tab)
|
||||
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
|
||||
if (changeInfo.status === "loading") {
|
||||
injectedTabs.delete(tabId);
|
||||
}
|
||||
});
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Nightcord Content Script
|
||||
* Injected into discord.com — injects the main Nightcord bundle into the page.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
(function () {
|
||||
// Inject Nightcord CSS
|
||||
const style = document.createElement("link");
|
||||
style.rel = "stylesheet";
|
||||
style.href = chrome.runtime.getURL("dist/Nightcord.css");
|
||||
document.documentElement.appendChild(style);
|
||||
|
||||
// Inject the main Nightcord JS bundle
|
||||
const script = document.createElement("script");
|
||||
script.src = chrome.runtime.getURL("dist/Nightcord.js");
|
||||
script.type = "text/javascript";
|
||||
(document.head ?? document.documentElement).appendChild(script);
|
||||
})();
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Nightcord",
|
||||
"description": "Everything Discord doesn't build, we create",
|
||||
"version": "1.18.7",
|
||||
"author": "Nightcord Contributors",
|
||||
"homepage_url": "https://github.com/nightcordoff/nightcord",
|
||||
"action": {
|
||||
"default_popup": "popup.html",
|
||||
"default_icon": {
|
||||
"16": "icon.png",
|
||||
"48": "icon.png",
|
||||
"128": "icon.png"
|
||||
},
|
||||
"default_title": "Nightcord"
|
||||
},
|
||||
"icons": {
|
||||
"16": "icon.png",
|
||||
"48": "icon.png",
|
||||
"128": "icon.png"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"js": [
|
||||
"content.js"
|
||||
],
|
||||
"matches": [
|
||||
"*://discord.com/*",
|
||||
"*://ptb.discord.com/*",
|
||||
"*://canary.discord.com/*"
|
||||
],
|
||||
"run_at": "document_start",
|
||||
"all_frames": true
|
||||
}
|
||||
],
|
||||
"declarative_net_request": {
|
||||
"rule_resources": [
|
||||
{
|
||||
"id": "csp-rules",
|
||||
"enabled": true,
|
||||
"path": "modifyResponseHeaders.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"permissions": [
|
||||
"declarativeNetRequest",
|
||||
"declarativeNetRequestFeedback",
|
||||
"scripting",
|
||||
"storage",
|
||||
"notifications",
|
||||
"contextMenus",
|
||||
"clipboardWrite",
|
||||
"clipboardRead",
|
||||
"tabs"
|
||||
],
|
||||
"host_permissions": [
|
||||
"*://discord.com/*",
|
||||
"*://ptb.discord.com/*",
|
||||
"*://canary.discord.com/*"
|
||||
],
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
"resources": [
|
||||
"dist/Nightcord.js",
|
||||
"dist/Nightcord.css",
|
||||
"dist/vendor/monaco/*"
|
||||
],
|
||||
"matches": [
|
||||
"*://discord.com/*",
|
||||
"*://ptb.discord.com/*",
|
||||
"*://canary.discord.com/*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "nightcord@nightcordoff.github.io",
|
||||
"strict_min_version": "109.0",
|
||||
"data_collection_permissions": {
|
||||
"required": [
|
||||
"none"
|
||||
],
|
||||
"optional": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"priority": 1,
|
||||
"action": {
|
||||
"type": "modifyHeaders",
|
||||
"responseHeaders": [
|
||||
{ "header": "content-security-policy", "operation": "remove" },
|
||||
{ "header": "content-security-policy-report-only", "operation": "remove" },
|
||||
{ "header": "x-frame-options", "operation": "remove" }
|
||||
]
|
||||
},
|
||||
"condition": {
|
||||
"urlFilter": "||discord.com/*",
|
||||
"resourceTypes": ["main_frame", "sub_frame"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"priority": 1,
|
||||
"action": {
|
||||
"type": "modifyHeaders",
|
||||
"responseHeaders": [
|
||||
{ "header": "content-security-policy", "operation": "remove" },
|
||||
{ "header": "content-security-policy-report-only", "operation": "remove" },
|
||||
{ "header": "x-frame-options", "operation": "remove" }
|
||||
]
|
||||
},
|
||||
"condition": {
|
||||
"urlFilter": "||ptb.discord.com/*",
|
||||
"resourceTypes": ["main_frame", "sub_frame"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"priority": 1,
|
||||
"action": {
|
||||
"type": "modifyHeaders",
|
||||
"responseHeaders": [
|
||||
{ "header": "content-security-policy", "operation": "remove" },
|
||||
{ "header": "content-security-policy-report-only", "operation": "remove" },
|
||||
{ "header": "x-frame-options", "operation": "remove" }
|
||||
]
|
||||
},
|
||||
"condition": {
|
||||
"urlFilter": "||canary.discord.com/*",
|
||||
"resourceTypes": ["main_frame", "sub_frame"]
|
||||
}
|
||||
}
|
||||
]
|
||||
+362
@@ -0,0 +1,362 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Nightcord</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
:root {
|
||||
--bg: #08080f;
|
||||
--bg2: #0e0e1a;
|
||||
--bg3: #13131f;
|
||||
--bg4: #1a1a2a;
|
||||
--border: rgba(255,255,255,0.055);
|
||||
--border2: rgba(255,255,255,0.10);
|
||||
--purple: #8b5cf6;
|
||||
--purple2: #6d28d9;
|
||||
--purple3: #a78bfa;
|
||||
--purple4: #c4b5fd;
|
||||
--green: #4ade80;
|
||||
--red: #f87171;
|
||||
--text: #dde3f0;
|
||||
--muted: #8892a4;
|
||||
--dim: #4a5568;
|
||||
--glow: rgba(139,92,246,0.18);
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 320px;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* ── Animated gradient bg ── */
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: -60px; left: -60px;
|
||||
width: 200px; height: 200px;
|
||||
background: radial-gradient(circle, rgba(139,92,246,0.12) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
animation: bgPulse 4s ease-in-out infinite alternate;
|
||||
}
|
||||
@keyframes bgPulse {
|
||||
from { opacity: 0.5; transform: scale(1); }
|
||||
to { opacity: 1; transform: scale(1.15); }
|
||||
}
|
||||
|
||||
/* ── Header ── */
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 11px;
|
||||
padding: 15px 15px 13px;
|
||||
background: linear-gradient(180deg, rgba(139,92,246,0.1) 0%, transparent 100%);
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: relative;
|
||||
}
|
||||
.header::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -1px; left: 0; right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(139,92,246,0.5) 50%, transparent 100%);
|
||||
}
|
||||
.logo-wrap {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.logo-ring {
|
||||
position: absolute;
|
||||
inset: -3px;
|
||||
border-radius: 11px;
|
||||
background: conic-gradient(from 0deg, transparent 60%, rgba(139,92,246,0.6) 80%, transparent 100%);
|
||||
animation: logoSpin 4s linear infinite;
|
||||
}
|
||||
@keyframes logoSpin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.logo-inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 9px;
|
||||
overflow: hidden;
|
||||
width: 34px; height: 34px;
|
||||
}
|
||||
.logo-inner img {
|
||||
width: 34px; height: 34px;
|
||||
display: block;
|
||||
}
|
||||
.logo-dot {
|
||||
position: absolute;
|
||||
bottom: -1px; right: -1px;
|
||||
z-index: 2;
|
||||
width: 10px; height: 10px;
|
||||
border-radius: 50%;
|
||||
background: var(--dim);
|
||||
border: 2px solid var(--bg);
|
||||
transition: background .4s, box-shadow .4s;
|
||||
}
|
||||
.logo-dot.live {
|
||||
background: var(--green);
|
||||
box-shadow: 0 0 8px rgba(74,222,128,0.7);
|
||||
}
|
||||
.header-text { flex: 1; }
|
||||
.logo-name {
|
||||
font-size: 15px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
letter-spacing: -0.3px;
|
||||
background: linear-gradient(135deg, #fff 40%, var(--purple4) 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.logo-sub {
|
||||
font-size: 10px;
|
||||
color: var(--dim);
|
||||
margin-top: 2px;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
.ver-pill {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
padding: 4px 10px;
|
||||
background: linear-gradient(135deg, rgba(139,92,246,0.18), rgba(109,40,217,0.18));
|
||||
border: 1px solid rgba(139,92,246,0.35);
|
||||
border-radius: 20px;
|
||||
color: var(--purple4);
|
||||
letter-spacing: 0.4px;
|
||||
text-shadow: 0 0 10px rgba(167,139,250,0.4);
|
||||
}
|
||||
|
||||
/* ── Panel ── */
|
||||
.panel { padding: 10px 10px 4px; display: flex; flex-direction: column; gap: 6px; }
|
||||
|
||||
.option-row {
|
||||
background: var(--bg2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 12px 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
transition: all .2s;
|
||||
cursor: default;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.option-row::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at 30% 50%, rgba(139,92,246,0.06) 0%, transparent 70%);
|
||||
opacity: 0;
|
||||
transition: opacity .2s;
|
||||
pointer-events: none;
|
||||
}
|
||||
.option-row:hover { background: var(--bg3); border-color: var(--border2); }
|
||||
.option-row:hover::before { opacity: 1; }
|
||||
.option-row.on {
|
||||
border-color: rgba(139,92,246,0.35);
|
||||
background: rgba(139,92,246,0.07);
|
||||
box-shadow: 0 0 0 1px rgba(139,92,246,0.1) inset, 0 2px 12px rgba(139,92,246,0.08);
|
||||
}
|
||||
.option-row.on::before { opacity: 1; }
|
||||
|
||||
.opt-icon {
|
||||
width: 36px; height: 36px;
|
||||
border-radius: 11px;
|
||||
background: rgba(139,92,246,0.10);
|
||||
border: 1px solid rgba(139,92,246,0.15);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
transition: all .2s;
|
||||
}
|
||||
.option-row.on .opt-icon {
|
||||
background: rgba(139,92,246,0.22);
|
||||
border-color: rgba(139,92,246,0.4);
|
||||
box-shadow: 0 0 10px rgba(139,92,246,0.25);
|
||||
}
|
||||
.opt-icon svg { width: 17px; height: 17px; fill: var(--purple3); }
|
||||
.opt-text { flex: 1; }
|
||||
.opt-name { font-size: 12px; font-weight: 700; color: var(--text); }
|
||||
.opt-sub { font-size: 10px; color: var(--dim); margin-top: 2px; line-height: 1.4; }
|
||||
|
||||
/* Toggle */
|
||||
.tog { position: relative; width: 42px; height: 23px; flex-shrink: 0; cursor: pointer; }
|
||||
.tog input { position: absolute; opacity: 0; width: 0; height: 0; }
|
||||
.tog-track {
|
||||
position: absolute; inset: 0;
|
||||
border-radius: 23px;
|
||||
background: var(--bg4);
|
||||
border: 1.5px solid rgba(255,255,255,0.07);
|
||||
transition: background .25s, border-color .25s, box-shadow .25s;
|
||||
}
|
||||
.tog input:checked ~ .tog-track {
|
||||
background: linear-gradient(135deg, var(--purple), var(--purple2));
|
||||
border-color: rgba(139,92,246,0.55);
|
||||
box-shadow: 0 0 10px rgba(139,92,246,0.4), 0 0 4px rgba(139,92,246,0.2) inset;
|
||||
}
|
||||
.tog-knob {
|
||||
position: absolute;
|
||||
top: 3px; left: 3px;
|
||||
width: 15px; height: 15px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.5);
|
||||
transition: transform .25s cubic-bezier(.34,1.4,.64,1);
|
||||
pointer-events: none;
|
||||
}
|
||||
.tog input:checked ~ .tog-knob { transform: translateX(19px); }
|
||||
|
||||
/* ── Divider ── */
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent 0%, var(--border2) 30%, var(--border2) 70%, transparent 100%);
|
||||
margin: 6px 10px;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.links {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding: 0 10px 8px;
|
||||
}
|
||||
.link-btn {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
padding: 8px 6px;
|
||||
background: var(--bg2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
color: var(--dim);
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: all .2s;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.3px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.link-btn::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0;
|
||||
transition: opacity .2s;
|
||||
border-radius: inherit;
|
||||
}
|
||||
.link-btn:hover { transform: translateY(-1px); }
|
||||
.link-btn svg { width: 13px; height: 13px; fill: currentColor; flex-shrink: 0; }
|
||||
|
||||
.link-btn.github:hover { color: #e2e8f0; border-color: rgba(226,232,240,0.25); background: rgba(226,232,240,0.05); box-shadow: 0 3px 10px rgba(0,0,0,0.3); }
|
||||
.link-btn.discord:hover { color: #7289da; border-color: rgba(114,137,218,0.4); background: rgba(114,137,218,0.08); box-shadow: 0 3px 10px rgba(114,137,218,0.15); }
|
||||
.link-btn.website:hover { color: var(--purple4); border-color: rgba(139,92,246,0.4); background: rgba(139,92,246,0.08); box-shadow: 0 3px 10px rgba(139,92,246,0.15); }
|
||||
|
||||
/* ── Footer ── */
|
||||
.footer {
|
||||
padding: 8px 14px 11px;
|
||||
border-top: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.footer-status {
|
||||
font-size: 10px;
|
||||
color: var(--dim);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
transition: color .3s;
|
||||
}
|
||||
.footer-status.active { color: var(--muted); }
|
||||
.status-dot {
|
||||
display: inline-block;
|
||||
width: 6px; height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--dim);
|
||||
flex-shrink: 0;
|
||||
transition: background .3s, box-shadow .3s;
|
||||
}
|
||||
.status-dot.active {
|
||||
background: var(--green);
|
||||
box-shadow: 0 0 6px rgba(74,222,128,0.6);
|
||||
animation: dotPulse 2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes dotPulse {
|
||||
0%, 100% { box-shadow: 0 0 5px rgba(74,222,128,0.5); }
|
||||
50% { box-shadow: 0 0 10px rgba(74,222,128,0.9); }
|
||||
}
|
||||
.debug { font-size: 9px; color: var(--dim); font-family: monospace; opacity: 0.4; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
<div class="logo-wrap">
|
||||
<div class="logo-ring"></div>
|
||||
<div class="logo-inner">
|
||||
<img src="icon.png" alt="Nightcord">
|
||||
</div>
|
||||
<span class="logo-dot" id="statusDot"></span>
|
||||
</div>
|
||||
<div class="header-text">
|
||||
<div class="logo-name">Nightcord</div>
|
||||
<div class="logo-sub">Discord Enhancement</div>
|
||||
</div>
|
||||
<span class="ver-pill">v1.18.7</span>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="option-row" id="row">
|
||||
<div class="opt-icon">
|
||||
<svg viewBox="0 0 24 24"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||||
</div>
|
||||
<div class="opt-text">
|
||||
<div class="opt-name">Auto-inject</div>
|
||||
<div class="opt-sub">Injecter automatiquement à l'ouverture de Discord</div>
|
||||
</div>
|
||||
<label class="tog">
|
||||
<input type="checkbox" id="chk">
|
||||
<div class="tog-track"></div>
|
||||
<div class="tog-knob"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="links">
|
||||
<button class="link-btn github" id="btnGithub">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.3 3.44 9.8 8.2 11.38.6.11.82-.26.82-.58v-2.03c-3.34.73-4.04-1.61-4.04-1.61-.54-1.38-1.33-1.75-1.33-1.75-1.09-.74.08-.73.08-.73 1.2.08 1.84 1.24 1.84 1.24 1.07 1.83 2.8 1.3 3.49 1 .1-.78.42-1.3.76-1.6-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1.01-.32 3.3 1.23a11.5 11.5 0 0 1 3-.4c1.02 0 2.04.13 3 .4 2.28-1.55 3.29-1.23 3.29-1.23.65 1.66.24 2.88.12 3.18.77.84 1.24 1.91 1.24 3.22 0 4.61-2.81 5.63-5.48 5.92.43.37.81 1.1.81 2.22v3.29c0 .32.22.69.83.57C20.57 21.8 24 17.3 24 12c0-6.63-5.37-12-12-12z"/></svg>
|
||||
GitHub
|
||||
</button>
|
||||
<button class="link-btn discord" id="btnDiscord">
|
||||
<svg viewBox="0 0 24 24"><path d="M20.32 4.37A19.8 19.8 0 0 0 15.33 3c-.22.4-.48.93-.65 1.35a18.3 18.3 0 0 0-5.36 0A14.6 14.6 0 0 0 8.67 3 19.9 19.9 0 0 0 3.68 4.38C.53 9.17-.32 13.84.1 18.44a20 20 0 0 0 6.07 3.04 14.9 14.9 0 0 0 1.3-2.1 13 13 0 0 1-2.05-.98l.5-.38a14.28 14.28 0 0 0 12.16 0l.5.38c-.64.38-1.33.7-2.05.98a14.8 14.8 0 0 0 1.3 2.1 19.94 19.94 0 0 0 6.07-3.05c.5-5.17-.83-9.8-3.58-13.86zM8.01 15.52c-1.18 0-2.15-1.08-2.15-2.41 0-1.33.95-2.42 2.15-2.42 1.2 0 2.17 1.09 2.15 2.42 0 1.33-.95 2.41-2.15 2.41zm7.98 0c-1.18 0-2.15-1.08-2.15-2.41 0-1.33.95-2.42 2.15-2.42 1.2 0 2.16 1.09 2.15 2.42 0 1.33-.94 2.41-2.15 2.41z"/></svg>
|
||||
Discord
|
||||
</button>
|
||||
<button class="link-btn website" id="btnWebsite">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>
|
||||
Site web
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<span class="footer-status" id="ftxt">
|
||||
<span class="status-dot" id="dot"></span>
|
||||
Prêt
|
||||
</span>
|
||||
<span class="debug" id="dbg"></span>
|
||||
</div>
|
||||
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,85 @@
|
||||
var chk = document.getElementById('chk');
|
||||
var row = document.getElementById('row');
|
||||
var dbg = document.getElementById('dbg');
|
||||
var ftxt = document.getElementById('ftxt');
|
||||
var statusDot = document.getElementById('statusDot');
|
||||
|
||||
/* ── Liens ── */
|
||||
document.getElementById('btnGithub').addEventListener('click', function() {
|
||||
chrome.tabs.create({ url: 'https://github.com/nightcordoff/nightcord' });
|
||||
});
|
||||
document.getElementById('btnDiscord').addEventListener('click', function() {
|
||||
chrome.tabs.create({ url: 'https://discord.gg/nightcord' });
|
||||
});
|
||||
document.getElementById('btnWebsite').addEventListener('click', function() {
|
||||
chrome.tabs.create({ url: 'https://nightcord.su' });
|
||||
});
|
||||
|
||||
/* ── UI ── */
|
||||
function setUI(val) {
|
||||
chk.checked = val;
|
||||
row.classList.toggle('on', val);
|
||||
|
||||
var dot = ftxt.querySelector('.status-dot');
|
||||
if (val) {
|
||||
if (dot) { dot.className = 'status-dot active'; }
|
||||
ftxt.childNodes[ftxt.childNodes.length - 1].textContent = 'Auto-inject actif';
|
||||
ftxt.classList.add('active');
|
||||
statusDot.classList.add('live');
|
||||
} else {
|
||||
if (dot) { dot.className = 'status-dot'; }
|
||||
ftxt.childNodes[ftxt.childNodes.length - 1].textContent = 'Désactivé';
|
||||
ftxt.classList.remove('active');
|
||||
statusDot.classList.remove('live');
|
||||
}
|
||||
}
|
||||
|
||||
function log(msg) { dbg.textContent = msg; }
|
||||
|
||||
/* ── Lecture ── */
|
||||
function loadValue() {
|
||||
try {
|
||||
chrome.storage.local.get('nc_autoInject', function(result) {
|
||||
if (chrome.runtime.lastError) { log(chrome.runtime.lastError.message); fallback(); return; }
|
||||
var val = result['nc_autoInject'];
|
||||
/* Si jamais défini → true par défaut */
|
||||
setUI(val !== false);
|
||||
if (val === undefined) saveValue(true);
|
||||
});
|
||||
} catch(e) { log(String(e)); fallback(); }
|
||||
}
|
||||
|
||||
function fallback() {
|
||||
try {
|
||||
var v = localStorage.getItem('nc_autoInject');
|
||||
setUI(v !== 'false');
|
||||
if (v === null) saveValue(true);
|
||||
} catch(e) { setUI(true); }
|
||||
}
|
||||
|
||||
/* ── Sauvegarde ── */
|
||||
function saveValue(val) {
|
||||
try {
|
||||
chrome.storage.local.set({ nc_autoInject: val }, function() {
|
||||
if (chrome.runtime.lastError) log(chrome.runtime.lastError.message);
|
||||
});
|
||||
} catch(e) {}
|
||||
try { localStorage.setItem('nc_autoInject', String(val)); } catch(e) {}
|
||||
}
|
||||
|
||||
/* ── Toggle ── */
|
||||
chk.addEventListener('change', function() {
|
||||
saveValue(chk.checked);
|
||||
setUI(chk.checked);
|
||||
});
|
||||
|
||||
/* ── Texte du footer (nœuds) ── */
|
||||
(function fixFooter() {
|
||||
/* S'assure qu'il y a bien un TextNode après le span .status-dot */
|
||||
var span = ftxt.querySelector('.status-dot');
|
||||
if (span && !span.nextSibling) {
|
||||
ftxt.appendChild(document.createTextNode('Prêt'));
|
||||
}
|
||||
})();
|
||||
|
||||
loadValue();
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+849
File diff suppressed because one or more lines are too long
+36
File diff suppressed because one or more lines are too long
+103
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user