diff --git a/i18n/english.js b/i18n/english.js
index cbc1218e..c1bb8acd 100644
--- a/i18n/english.js
+++ b/i18n/english.js
@@ -90,7 +90,9 @@ const ui = {
dependencies: "scripts & dependencies",
warnings: "threats in source code",
vulnerabilities: "vulnerabilities (CVE)",
- licenses: "licenses conformance (SPDX)"
+ licenses: "licenses conformance (SPDX)",
+ dark: "dark",
+ light: "light"
},
title: {
maintainers: "maintainers",
@@ -170,6 +172,7 @@ const ui = {
title: "General",
save: "save",
defaultPannel: "Default Package Menu",
+ themePannel: "Interface theme",
warnings: "SAST Warnings to ignore",
flags: "Flags (emojis) to ignore",
network: "Network",
diff --git a/i18n/french.js b/i18n/french.js
index ff089a63..39e90126 100644
--- a/i18n/french.js
+++ b/i18n/french.js
@@ -90,7 +90,9 @@ const ui = {
dependencies: "scripts & dépendances",
warnings: "menaces dans le code",
vulnerabilities: "vulnérabilités",
- licenses: "conformité des licences (SPDX)"
+ licenses: "conformité des licences (SPDX)",
+ dark: "sombre",
+ light: "clair"
},
title: {
maintainers: "mainteneurs",
@@ -170,6 +172,7 @@ const ui = {
title: "Général",
save: "sauvegarder",
defaultPannel: "Panneau par défaut",
+ themePannel: "Thème de l'interface",
warnings: "Avertissements à ignorer",
flags: "Drapeau (emojis) à ignorer",
network: "Réseau",
diff --git a/public/components/gauge/gauge.css b/public/components/gauge/gauge.css
index 100d6cb2..8a169489 100644
--- a/public/components/gauge/gauge.css
+++ b/public/components/gauge/gauge.css
@@ -10,12 +10,19 @@
padding: 0 10px;
border-radius: 4px;
}
+body.dark .gauge>.line {
+ color: white;
+}
.gauge>.line.clickable:hover {
background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%);
cursor: pointer;
}
+body.dark .gauge>.line.clickable:hover {
+ background: var(--dark-theme-primary-color);
+}
+
.gauge>.line+.line {
margin-top: 5px;
}
diff --git a/public/components/navigation/navigation.css b/public/components/navigation/navigation.css
index b7213e10..e5e43ca9 100644
--- a/public/components/navigation/navigation.css
+++ b/public/components/navigation/navigation.css
@@ -9,6 +9,10 @@ nav#aside {
z-index: 40;
}
+body.dark nav#aside {
+ background: var(--dark-theme-primary-color);
+}
+
nav#aside>.nsecure-logo {
margin-top: 20px;
}
diff --git a/public/components/package/package.css b/public/components/package/package.css
index 91333855..9ea497fa 100644
--- a/public/components/package/package.css
+++ b/public/components/package/package.css
@@ -19,6 +19,10 @@ section#package-info {
-webkit-transform: translateX(-100%);
}
+body.dark section#package-info {
+ background: var(--dark-theme-primary-lighter);
+}
+
section#package-info .package-container {
margin-bottom: 40px;
padding: 10px;
diff --git a/public/components/popup/popup.css b/public/components/popup/popup.css
index 82c20598..642ed0c7 100644
--- a/public/components/popup/popup.css
+++ b/public/components/popup/popup.css
@@ -32,3 +32,10 @@ section#popup--background>.popup {
border-left: 2px solid #ffffff;
border-top: 2px solid #FFF;
}
+
+body.dark section#popup--background>.popup {
+ background: #303263;
+ box-shadow: 5px 5px 15px var(--dark-theme-primary-color);
+ border-left: 2px solid var(--dark-theme-secondary-darker);
+ border-top: 2px solid var(--dark-theme-secondary-darker);
+}
diff --git a/public/components/searchbar/searchbar.css b/public/components/searchbar/searchbar.css
index 37b24a56..e9070b8b 100644
--- a/public/components/searchbar/searchbar.css
+++ b/public/components/searchbar/searchbar.css
@@ -213,6 +213,10 @@ div.search-result-pannel .package+.package {
box-shadow: 2px 1px 10px #26107f7a;
}
+body.dark #search-nav {
+ background: var(--dark-theme-primary-color);
+}
+
#search-nav:has(#searchbar[style*="display: none;"]) {
display: none;
}
@@ -246,6 +250,10 @@ div.search-result-pannel .package+.package {
color: #def7ff;
}
+body.dark #search-nav .packages>.package {
+ background: linear-gradient(to right, rgba(11,3,31,1) 0%, rgba(11,3,31, 0.8) 50%, rgba(11, 3, 31, 0.6) 100%);
+}
+
#search-nav .packages>.package>* {
transform: skewX(20deg);
}
@@ -260,6 +268,10 @@ div.search-result-pannel .package+.package {
cursor: pointer;
}
+body.dark #search-nav .packages>.package:not(.active):hover {
+ background: linear-gradient(to right, rgba(11, 3, 31, 0.7) 1%, rgba(11, 3, 31, 0.5) 100%);
+}
+
#search-nav .packages>.package.active {
background: linear-gradient(to right, rgba(55,34,175,1) 0%,rgba(87,74,173,1) 50%,rgb(59, 110, 205) 100%);
}
diff --git a/public/components/views/home/home.css b/public/components/views/home/home.css
index eb242d01..765ac35d 100644
--- a/public/components/views/home/home.css
+++ b/public/components/views/home/home.css
@@ -101,6 +101,10 @@
border-bottom: 2px solid #cecec9;
}
+body.dark .home--header--title .top {
+ border-bottom: 2px solid var(--dark-theme-secondary-color);
+}
+
.home--header--title .top #project-name {
color: var(--primary-lighter);
}
@@ -112,6 +116,15 @@
margin-top: 5px;
}
+body.dark .home--header--title .top #project-name {
+ color: var(--secondary);
+}
+
+body.dark .home--header--title .top #project-version {
+ color: var(--secondary);
+ opacity: 0.9;
+}
+
.home--header--title .bottom {
display: flex;
height: 26px;
@@ -125,6 +138,11 @@
font-family: system-ui;
}
+body.dark .home--header--title .bottom #project-description {
+ color: var(--secondary);
+ opacity: 0.9;
+}
+
.home--header--title .bottom>ul {
margin-left: auto;
height: inherit;
@@ -139,6 +157,10 @@
letter-spacing: 0.5px;
}
+body.dark .home--header--title .bottom>ul li {
+ color: white;
+}
+
.home--header--title .bottom>ul li:hover {
text-decoration: underline;
cursor: pointer;
@@ -242,6 +264,10 @@
padding: 10px;
}
+body.dark #home--view .home--body .module>.content>p {
+ color: #74ace3;
+}
+
/**
* WARNINGS BEGIN
*/
@@ -260,6 +286,11 @@
border-radius: 4px;
}
+body.dark .home--warnings>p {
+ background: linear-gradient(to right, rgb(11, 3, 31) 0%, rgba(46, 10, 10, 0.7) 100%);
+ color: rgb(253, 210, 210);
+}
+
.home--warnings>p+p {
margin-top: 5px;
}
@@ -293,6 +324,10 @@
color: #546884;
}
+body.dark .home--overview>div {
+ color: white;
+}
+
.home--overview>div>.title {
display: flex;
font-size: 20px;
@@ -312,6 +347,10 @@
margin-top: 10px;
}
+body.dark .home--overview>div>span {
+ color: var(--dark-theme-secondary-color);
+}
+
.home--packages--overview {
display: flex;
flex-direction: column;
@@ -337,17 +376,31 @@
transition: 0.5s linear all;
}
+body.dark .home--packages--overview>div {
+ background: linear-gradient(to right, rgb(11, 3, 31) 0%, rgba(46, 10, 10, 0.8) 100%);
+ color: rgb(253, 210, 210);
+}
+
.home--packages--overview>div:hover {
border-color: #da4e44;
cursor: pointer;
background: linear-gradient(to right, rgb(231, 206, 195) 0%, rgba(255, 255, 255, 0) 100%);
}
+body.dark .home--packages--overview>div:hover {
+ border-color: #da4e44;
+ background: linear-gradient(to right, rgb(11, 3, 31) 0%, rgba(46, 10, 10, 0.8) 100%);
+}
+
.home--packages--overview>div span {
color: #6d5703;
margin-left: 10px;
}
+body.dark .home--packages--overview>div span {
+ color: #ac8a05;
+}
+
.home--packages--overview>div>div.chips {
margin-left: auto;
display: flex;
@@ -365,6 +418,12 @@
color: #611717;
}
+body.dark .home--packages--overview>div>div.chips>p {
+ background: linear-gradient(to bottom, rgb(75 22 22) 0%, rgb(26 5 5) 100%);
+ color: #f5c6c6;
+ box-shadow: 2px 2px 6px 0px #0e01019e;
+}
+
.home--packages--overview>div>div.chips>p+p {
margin-left: 10px;
}
diff --git a/public/components/views/home/maintainers/maintainers.css b/public/components/views/home/maintainers/maintainers.css
index 53a327f1..e3fc66a8 100644
--- a/public/components/views/home/maintainers/maintainers.css
+++ b/public/components/views/home/maintainers/maintainers.css
@@ -21,6 +21,11 @@
flex-grow: 1;
}
+body.dark .home--maintainers>.person {
+ color: white;
+ background: var(--dark-theme-primary-color);
+}
+
.home--maintainers>.person:hover {
border-color: var(--secondary-darker);
cursor: pointer;
@@ -119,12 +124,21 @@
color: #546884;
}
+body.dark .maintainers--popup>.header>.informations>p.name {
+ color: white;
+}
+
.maintainers--popup>.header>.informations>p.email {
color: var(--secondary-darker);
margin-top: 10px;
font-family: monospace;
}
+body.dark .maintainers--popup>.header>.informations>p.email {
+ color: var(--dark-theme-secondary-color);
+ opacity: 0.9;
+}
+
.maintainers--popup>.header>.icons {
display: flex;
align-items: center;
@@ -162,6 +176,10 @@
flex-shrink: 0;
}
+body.dark .maintainers--popup>.separator {
+ background: var(--dark-theme-secondary-color);
+}
+
.maintainers--popup>.separator>p {
background: #f5f4f4;
padding: 0 10px;
@@ -171,6 +189,11 @@
color: #255471;
}
+.maintainers--popup>.separator>p {
+ background: #303263;
+ color: #3cbde5;
+}
+
.maintainers--popup>ul {
display: flex;
flex-direction: column;
@@ -196,15 +219,29 @@
font-size: 15px;
}
+body.dark .maintainers--popup>ul li {
+ background: linear-gradient(to right, var(--dark-theme-primary-color) 0%, rgba(28, 29, 58, 0.185) 100%);
+ border: none;
+ color: white;
+}
+
.maintainers--popup>ul li>p{
color: #234c99;
}
+body.dark .maintainers--popup>ul li>p{
+ color: #9ca6b7;
+}
+
.maintainers--popup>ul li>span{
color: #2470b3;
margin-left: 10px;
}
+body.dark .maintainers--popup>ul li>span{
+ color: var(--dark-theme-secondary-color);
+}
+
.maintainers--popup>ul li>i{
margin-left: auto;
margin-right: 13px;
diff --git a/public/components/views/home/report/report.css b/public/components/views/home/report/report.css
index 39d4274f..4cbecb43 100644
--- a/public/components/views/home/report/report.css
+++ b/public/components/views/home/report/report.css
@@ -15,6 +15,10 @@
flex-shrink: 0;
}
+body.dark .report--popup>.title {
+ background: var(--dark-theme-secondary-color);
+}
+
.report--popup>.title>p {
background: #f5f4f4;
padding: 0 10px;
@@ -25,6 +29,11 @@
font-size: 20px;
}
+body.dark .report--popup>.title>p {
+ background: #303263;
+ color: #3cbde5;
+}
+
.report--popup>form {
display: flex;
flex-direction: column;
@@ -39,6 +48,10 @@
font-size: 18px;
}
+body.dark .report--popup>form label {
+ color: white;
+}
+
.report--popup>form input {
padding: 11px 6px;
border: none;
diff --git a/public/components/views/network/network.css b/public/components/views/network/network.css
index 47301ff1..796404ee 100644
--- a/public/components/views/network/network.css
+++ b/public/components/views/network/network.css
@@ -7,10 +7,18 @@
box-shadow: -2px -2px 10px #6d29b5b8 inset;
}
+body.dark #network--view:not(.locked) {
+ box-shadow: -2px -2px 10px #1d0b30b8 inset;
+}
+
#network--view.locked {
box-shadow: -2px -2px 10px #b52929b8 inset;
}
+body.dark #network--view.locked {
+ box-shadow: -2px -2px 10px #2b0a0ab8 inset;
+}
+
#network-loader {
width: 100%;
height: 100%;
@@ -23,15 +31,20 @@
align-items: center;
flex-direction: column;
}
- #network-loader>p {
- font-size: 18px;
- margin-top: 10px;
- font-weight: bold;
- letter-spacing: 0.5px;
- font-family: "mononoki";
- color: var(--primary-darker);
- text-shadow: 1px 1px 1px rgba(20, 20, 20, 0.5);
- }
+
+#network-loader>p {
+ font-size: 18px;
+ margin-top: 10px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ font-family: "mononoki";
+ color: var(--primary-darker);
+ text-shadow: 1px 1px 1px rgba(20, 20, 20, 0.5);
+}
+
+body.dark #network-loader>p {
+ color: var(--dark-theme-secondary-lighter);
+}
#dependency-graph {
width: 100%;
diff --git a/public/components/views/search/search.css b/public/components/views/search/search.css
index 034aa4ff..2e860b63 100644
--- a/public/components/views/search/search.css
+++ b/public/components/views/search/search.css
@@ -74,10 +74,19 @@
padding-left: 5px;
}
+body.dark .result {
+ background: var(--dark-theme-primary-lighter);
+ color: var(--dark-theme-secondary-color);
+}
+
.result.exact {
background: #f4fff2 !important;
}
+body.dark .result.exact {
+ background: var(--dark-theme-secondary-darker) !important;
+}
+
.result:nth-child(even) {
box-shadow: 1px 1px 10px #33333314 inset;
}
@@ -100,6 +109,10 @@
border-bottom: 2px solid #f7f7f7;
}
+body.dark .result:not(:last-child) {
+ border-bottom: 2px solid var(--dark-theme-primary-color);
+}
+
.result span,
.result select {
font-weight: bold;
@@ -132,6 +145,13 @@
box-sizing: border-box;
position: relative;
}
+body.dark .form-group {
+ background: var(--dark-theme-gray);
+ border: 1px solid var(--primary-lighter);
+ /* box-shadow: 2px 2px 20px var(--primary-darker); */
+ box-shadow: 2px 2px 20px #5b44da6e;
+
+}
.form-group>input,
.form-group>input::placeholder,
@@ -155,6 +175,10 @@
margin-top: 10px;
}
+body.dark .scan-info {
+ color: white;
+}
+
.spinner {
width: 56px;
height: 56px;
@@ -176,6 +200,16 @@
margin: 0 !important;
}
+body.dark .spinner {
+ border: 9px solid var(--dark-theme-accent-lighter);
+ border-right-color: var(--dark-theme-accent-darker);
+}
+
+body.dark .spinner-small {
+ border: 4px solid var(--dark-theme-accent-lighter);
+ border-right-color: var(--dark-theme-accent-darker);
+}
+
@keyframes spinner-d3wgkg {
to {
transform: rotate(1turn);
@@ -229,10 +263,14 @@ input:-webkit-autofill {
width: 100%;
padding: 5px 0;
margin-top: 10px;
- background: #54688419;
+ background: #0b031f71;
padding: 5px 10px;
}
+body.dark .description {
+ color: var(--dark-theme-secondary-lighter);
+}
+
.package-cache-result button.remove {
border: none;
position: relative;
@@ -265,11 +303,19 @@ input:-webkit-autofill {
overflow: auto;
}
+body.dark .cache-packages, body.dark .recent-packages {
+ color: var(--secondary-darker);
+}
+
.cache-packages h1, .recent-packages h1 {
font-family: "mononoki";
color: #546884;
}
+body.dark .cache-packages h1, body.dark .recent-packages h1 {
+ color: white;
+}
+
.cache-packages .package-cache-result:has(span:hover), .recent-packages .package-cache-result:has(span:hover) {
color: var(--secondary-darker);
background: #5468842a;
diff --git a/public/components/views/settings/settings.css b/public/components/views/settings/settings.css
index faec7cb8..8bccde74 100644
--- a/public/components/views/settings/settings.css
+++ b/public/components/views/settings/settings.css
@@ -18,6 +18,11 @@
font-family: 'mononoki';
}
+body.dark #settings--view>h1, #settings--view h2 {
+ color: var(--dark-theme-secondary-color);
+ border-bottom: 2px solid var(--dark-theme-secondary-color);
+}
+
#settings--view h2 {
margin-top: 30px;
}
@@ -32,6 +37,10 @@
filter: invert(14%) sepia(80%) saturate(5663%) hue-rotate(252deg) brightness(69%) contrast(98%);
}
+body.dark #settings--view .icon-keyboard {
+ filter: invert(75%) sepia(81%) saturate(3055%) hue-rotate(178deg) brightness(86%) contrast(88%);
+}
+
#settings--view>h1 i {
margin-right: 5px;
}
@@ -57,6 +66,10 @@
letter-spacing: 0.5px;
}
+body.dark #settings--view>form .line p, body.dark #settings--view>form .line label {
+ color: var(--dark-theme-secondary-lighter);
+}
+
#settings--view>form .line>p, #settings--view>form .line>label {
margin-bottom: 6px;
font-weight: bold;
@@ -77,12 +90,22 @@
margin-bottom: 20px;
}
+body.dark #settings--view .shortcuts .note {
+ background: var(--dark-theme-accent-darker);
+ color: white;
+
+}
+
#settings--view .shortcuts label {
color: #4a5e68;
margin-left: 10px;
font-weight: 500;
}
+body.dark #settings--view .shortcuts label {
+ color: var(--dark-theme-secondary-lighter);
+}
+
#settings--view .shortcuts input:read-only {
background: transparent;
border-color: rgb(168, 168, 168);
@@ -90,6 +113,11 @@
border-style: solid;
}
+body.dark #settings--view .shortcuts input:read-only {
+ border-color: var(--dark-theme-secondary-lighter);
+ color: var(--dark-theme-secondary-lighter);
+}
+
#settings--view .shortcuts input {
width: 36px;
height: 36px;
@@ -109,6 +137,10 @@
margin-left: 10px;
}
+body.dark #settings--view>form .line>div {
+ color: var(--dark-theme-secondary-lighter);
+}
+
#settings--view>form .line select {
margin-left: 10px;
}
@@ -167,6 +199,12 @@ select {
color: #0c5a9b;
}
+body.dark select {
+ color: var(--dark-theme-secondary-lighter);
+ border: var(--dark-theme-secondary-darker) 1px solid;
+ background: var(--dark-theme-primary-darker);
+}
+
.settings-line-title {
font-size: 15px;
color: #4a5e68;
@@ -174,3 +212,11 @@ select {
margin: 30px 0 6px;
font-weight: bold;
}
+
+body.dark .settings-line-title {
+ color: var(--dark-theme-secondary-color);
+}
+
+.mt-10 {
+ margin-top: 10px;
+}
diff --git a/public/components/views/settings/settings.js b/public/components/views/settings/settings.js
index 7cbec4b0..3f7ecb30 100644
--- a/public/components/views/settings/settings.js
+++ b/public/components/views/settings/settings.js
@@ -37,7 +37,8 @@ export class Settings {
/** @type {HTMLInputElement} */
shortcutsSection: document.querySelector(".shortcuts"),
/** @type {HTMLInputElement} */
- showFriendlyDependenciesCheckbox: document.querySelector("#show-friendly")
+ showFriendlyDependenciesCheckbox: document.querySelector("#show-friendly"),
+ themeSelector: document.querySelector("#theme_selector")
};
this.saveButton = document.querySelector(".save");
@@ -45,8 +46,14 @@ export class Settings {
this.saveButton.classList.add("disabled");
this.dom.defaultPackageMenu.addEventListener("change", () => this.enableSaveButton());
- for (const checkbox of [...this.dom.warningsCheckbox, ...this.dom.flagsCheckbox, this.dom.showFriendlyDependenciesCheckbox]) {
- checkbox.addEventListener("change", () => this.enableSaveButton());
+ const formFields = [
+ ...this.dom.warningsCheckbox,
+ ...this.dom.flagsCheckbox,
+ this.dom.showFriendlyDependenciesCheckbox,
+ this.dom.themeSelector
+ ];
+ for (const formField of formFields) {
+ formField.addEventListener("change", () => this.enableSaveButton());
}
const self = this;
@@ -170,6 +177,10 @@ export class Settings {
this.flags = new Set(this.config.ignore.flags);
this.config.ignore.warnings = this.warnings;
this.config.ignore.flags = this.flags;
+ // this.config.theme = config.theme ?? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
+ if (this.config.theme === void 0) {
+ this.config.theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
+ }
}
async fetchUserConfig() {
@@ -188,7 +199,8 @@ export class Settings {
const newConfig = {
defaultPackageMenu: this.dom.defaultPackageMenu.value || Settings.defaultMenuName,
ignore: { flags: new Set(), warnings: new Set() },
- showFriendlyDependencies: this.dom.showFriendlyDependenciesCheckbox.checked
+ showFriendlyDependencies: this.dom.showFriendlyDependenciesCheckbox.checked,
+ theme: this.dom.themeSelector.value
};
for (const checkbox of this.dom.warningsCheckbox) {
@@ -221,6 +233,7 @@ export class Settings {
updateSettings() {
this.dom.defaultPackageMenu.value = this.config.defaultPackageMenu;
+ this.dom.themeSelector.value = this.config.theme;
const warnings = new Set(this.config.ignore.warnings);
const flags = new Set(this.config.ignore.flags);
diff --git a/public/css/animation.css b/public/css/animation.css
index 0ea12265..1203a550 100644
--- a/public/css/animation.css
+++ b/public/css/animation.css
@@ -14,6 +14,9 @@
background: var(--primary);
animation-timing-function: cubic-bezier(0, 1, 1, 0);
}
+body.dark .lds-ellipsis div {
+ background: var(--dark-theme-accent-lighter);
+}
.lds-ellipsis div:nth-child(1) {
left: 8px;
animation: lds-ellipsis1 0.6s infinite;
diff --git a/public/css/light.css b/public/css/light.css
index ed7d98e1..66485e35 100644
--- a/public/css/light.css
+++ b/public/css/light.css
@@ -5,6 +5,16 @@
--primary-lighter: #5A44DA;
--secondary: #00D1FF;
--secondary-darker: #1976D2;
+ --dark-theme-primary-color: #0b031f;
+ --dark-theme-primary-lighter: #0d1035;
+ --dark-theme-primary-darker: #0c0d23;
+ --dark-theme-secondary-lighter: #a7ccdb;
+ --dark-theme-secondary-darker: #262981;
+ --dark-theme-secondary-color: #4f9ad1;
+ --dark-theme-accent-lighter: #7465c5;
+ --dark-theme-accent-darker: #261c66;
+ --dark-theme-accent-color: #8d7afc;
+ --dark-theme-gray: #191a38;
}
body {
color: var(--primary-theme-color);
@@ -14,3 +24,8 @@ body {
background: radial-gradient(ellipse at center, rgba(255,255,255,1) 15%,rgba(208,220,221,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#d0dcdd',GradientType=1 );
}
+
+body.dark {
+ color: white;
+ background: var(--dark-theme-gray);
+}
diff --git a/public/main.js b/public/main.js
index 2f699b6e..bc183ab8 100644
--- a/public/main.js
+++ b/public/main.js
@@ -32,7 +32,7 @@ document.addEventListener("DOMContentLoaded", async() => {
window.wiki = new Wiki();
await init();
- onSettingsSaved();
+ onSettingsSaved(window.settings.config);
window.socket = new WebSocket(`ws://${window.location.hostname}:1338`);
window.socket.addEventListener("message", async(event) => {
@@ -97,7 +97,8 @@ async function init(options = {}) {
secureDataSet = new NodeSecureDataSet({
flagsToIgnore: window.settings.config.ignore.flags,
- warningsToIgnore: window.settings.config.ignore.warnings
+ warningsToIgnore: window.settings.config.ignore.warnings,
+ theme: window.settings.config.theme
});
await secureDataSet.init();
@@ -118,7 +119,10 @@ async function init(options = {}) {
// Initialize vis Network
NodeSecureNetwork.networkElementId = "dependency-graph";
- nsn = new NodeSecureNetwork(secureDataSet, { i18n: window.i18n[utils.currentLang()] });
+ nsn = new NodeSecureNetwork(secureDataSet, {
+ i18n: window.i18n[utils.currentLang()],
+ theme: window.settings.config.theme
+ });
window.locker = new Locker(nsn);
window.legend = new Legend({ show: window.settings.config.showFriendlyDependencies });
new HomeView(secureDataSet, nsn);
@@ -201,18 +205,30 @@ async function updateShowInfoMenu(params) {
return void 0;
}
-function onSettingsSaved() {
- window.addEventListener("settings-saved", async(event) => {
- const warningsToIgnore = new Set(event.detail.ignore.warnings);
- const flagsToIgnore = new Set(event.detail.ignore.flags);
+function onSettingsSaved(defaultConfig = null) {
+ async function updateSettings(config) {
+ console.log("[INFO] Settings saved:", config);
+ const warningsToIgnore = new Set(config.ignore.warnings);
+ const flagsToIgnore = new Set(config.ignore.flags);
+ const theme = config.theme;
secureDataSet.warningsToIgnore = warningsToIgnore;
secureDataSet.flagsToIgnore = flagsToIgnore;
+ secureDataSet.theme = theme;
window.settings.config.ignore.warnings = warningsToIgnore;
window.settings.config.ignore.flags = flagsToIgnore;
+ window.settings.config.theme = theme;
+
+ if (theme === "dark") {
+ document.body.classList.add("dark");
+ }
+ else {
+ document.body.classList.remove("dark");
+ }
await secureDataSet.init(
secureDataSet.data,
- secureDataSet.FLAGS
+ secureDataSet.FLAGS,
+ secureDataSet.theme
);
const { nodes } = secureDataSet.build();
nsn.nodes.update(nodes.get());
@@ -225,11 +241,19 @@ function onSettingsSaved() {
updateShowInfoMenu(window.networkNav.currentNodeParams);
}
- if (event.detail.showFriendlyDependencies) {
+ if (config.showFriendlyDependencies) {
window.legend.show();
}
else {
window.legend.hide();
}
+ }
+
+ if (defaultConfig) {
+ updateSettings(defaultConfig);
+ }
+
+ window.addEventListener("settings-saved", async(event) => {
+ updateSettings(event.detail);
});
}
diff --git a/src/http-server/config.js b/src/http-server/config.js
index ae234284..23eb7252 100644
--- a/src/http-server/config.js
+++ b/src/http-server/config.js
@@ -23,11 +23,14 @@ export async function get() {
ignore: {
flags,
warnings
- } = {}
+ } = {},
+ theme
} = config;
- logger.info(`[config|get](defaultPackageMenu: ${defaultPackageMenu}|ignore-flag: ${flags}|ignore-warnings: ${warnings})`);
+ logger.info(
+ `[config|get](defaultPackageMenu: ${defaultPackageMenu}|ignore-flag: ${flags}|ignore-warnings: ${warnings}|theme: ${theme})`
+ );
- return config;
+ return { defaultPackageMenu, ignore: { flags, warnings }, theme };
}
catch (err) {
logger.error(`[config|get](error: ${err.message})`);
@@ -41,7 +44,7 @@ export async function get() {
}
export async function set(newValue) {
- logger.info(`[config|set](config: ${newValue})`);
+ logger.info(`[config|set](config: ${JSON.stringify(newValue)})`);
try {
await appCache.updateConfig(newValue);
diff --git a/test/config.test.js b/test/config.test.js
index aed1b3b3..022c7a74 100644
--- a/test/config.test.js
+++ b/test/config.test.js
@@ -37,17 +37,33 @@ describe("config", { concurrency: 1 }, () => {
});
it("should get config from cache", async() => {
- await cacache.put(CACHE_PATH, kConfigKey, JSON.stringify({ foo: "bar" }));
+ const expectedConfig = {
+ defaultPackageMenu: "foo",
+ ignore: {
+ flags: ["foo"],
+ warnings: ["bar"]
+ },
+ theme: "galaxy"
+ };
+ await cacache.put(CACHE_PATH, kConfigKey, JSON.stringify(expectedConfig));
const value = await get();
- assert.deepStrictEqual(value, { foo: "bar" });
+ assert.deepStrictEqual(value, expectedConfig);
});
it("should set config in cache", async() => {
- await set({ foo: "baz" });
+ const expectedConfig = {
+ defaultPackageMenu: "foz",
+ ignore: {
+ flags: ["foz"],
+ warnings: ["baz"]
+ },
+ theme: "galactic"
+ };
+ await set(expectedConfig);
const value = await get();
- assert.deepStrictEqual(value, { foo: "baz" });
+ assert.deepStrictEqual(value, expectedConfig);
});
});
diff --git a/test/httpServer.test.js b/test/httpServer.test.js
index fe5397e0..3c6ddba4 100644
--- a/test/httpServer.test.js
+++ b/test/httpServer.test.js
@@ -212,10 +212,19 @@ describe("httpServer", { concurrency: 1 }, () => {
test("GET '/config' should return the config", async() => {
const { data: actualConfig } = await get(new URL("/config", kHttpURL));
- await cacache.put(CACHE_PATH, kConfigKey, JSON.stringify({ foo: "bar" }));
+ const expectedConfig = {
+ defaultPackageMenu: "foo",
+ ignore: {
+ flags: ["foo"],
+ warnings: ["bar"]
+ },
+ theme: "galaxy"
+ };
+
+ await cacache.put(CACHE_PATH, kConfigKey, JSON.stringify(expectedConfig));
const result = await get(new URL("/config", kHttpURL));
- assert.deepEqual(result.data, { foo: "bar" });
+ assert.deepEqual(result.data, expectedConfig);
await fetch(new URL("/config", kHttpURL), {
method: "PUT",
diff --git a/views/index.html b/views/index.html
index 8e007f52..fa758949 100644
--- a/views/index.html
+++ b/views/index.html
@@ -32,15 +32,15 @@
[[=z.token('settings.general.network')]]: