diff --git a/js/activity.js b/js/activity.js
index c80f77d5b4..cf0e74414b 100644
--- a/js/activity.js
+++ b/js/activity.js
@@ -26,7 +26,7 @@
getMacroExpansion, getOctaveRatio, getTemperament, GOHOMEBUTTON,
GOHOMEFADEDBUTTON, GRAND, HelpWidget, HIDEBLOCKSFADEDBUTTON,
hideDOMLabel, initBasicProtoBlocks, initPalettes,
- INLINECOLLAPSIBLES, jQuery, JSEditor, LanguageBox, Logo, MSGBLOCK,
+ INLINECOLLAPSIBLES, jQuery, JSEditor, LanguageBox, ThemeBox, Logo, MSGBLOCK,
NANERRORMSG, NOACTIONERRORMSG, NOBOXERRORMSG, NOINPUTERRORMSG,
NOMICERRORMSG, NOSQRTERRORMSG, NOSTRINGERRORMSG, PALETTEFILLCOLORS,
PALETTESTROKECOLORS, PALETTEHIGHLIGHTCOLORS, HIGHLIGHTSTROKECOLORS,
@@ -85,6 +85,7 @@ let MYDEFINES = [
"activity/turtle-singer",
"activity/turtle-painter",
"activity/languagebox",
+ "activity/themebox",
"activity/basicblocks",
"activity/blockfactory",
"activity/piemenus",
@@ -272,15 +273,17 @@ class Activity {
//Flag to check if any other input box is active or not
this.isInputON = false;
- // If the theme is set to "darkMode", enable dark mode else diable
+ this.themes = ["light", "dark"];
try {
- if (this.storage.myThemeName === "darkMode") {
- body.classList.add("dark-mode");
- } else {
- body.classList.remove("dark-mode");
+ for (let i = 0; i < this.themes.length; i++) {
+ if (this.themes[i] === this.storage.themePreference) {
+ body.classList.add(this.themes[i]);
+ } else {
+ body.classList.remove(this.themes[i]);
+ }
}
} catch (e) {
- console.error("Error accessing myThemeName storage:", e);
+ console.error("Error accessing themePreference storage:", e);
}
this.beginnerMode = true;
@@ -385,6 +388,7 @@ class Activity {
this.logo = null;
this.pasteBox = null;
this.languageBox = null;
+ this.themeBox = null;
this.planet = null;
window.converter = null;
this.buttonsVisible = true;
@@ -6665,28 +6669,7 @@ class Activity {
this._createErrorContainers();
- // Function to toggle theme mode
- this.toggleThemeMode = () => {
- if (this.storage.myThemeName === "darkMode") {
- delete this.storage.myThemeName;
- localStorage.setItem("darkMode", "disabled");
- } else {
- this.storage.myThemeName = "darkMode";
- localStorage.setItem("darkMode", "enabled");
- }
- const planetIframe = document.getElementById("planet-iframe");
- if (planetIframe) {
- planetIframe.contentWindow.postMessage(
- { darkMode: localStorage.getItem("darkMode") },
- "*"
- );
- }
- try {
- window.location.reload();
- } catch (e) {
- console.error("Error reloading the window:", e);
- }
- };
+
/* Z-Order (top to bottom):
* menus
@@ -6714,6 +6697,7 @@ class Activity {
this.pasteBox = new PasteBox(this);
this.languageBox = new LanguageBox(this);
+ this.themeBox = new ThemeBox(this);
// Show help on startup if first-time user.
if (this.firstTimeUser) {
@@ -6755,7 +6739,7 @@ class Activity {
this.toolbar.renderModeSelectIcon(doSwitchMode, doRecordButton, doAnalytics, doOpenPlugin, deletePlugin, setScroller);
this.toolbar.renderRunSlowlyIcon(doSlowButton);
this.toolbar.renderRunStepIcon(doStepButton);
- this.toolbar.renderDarkModeIcon(this.toggleThemeMode);
+ this.toolbar.renderThemeSelectIcon(this.themeBox, this.themes);
this.toolbar.renderMergeIcon(_doMergeLoad);
this.toolbar.renderRestoreIcon(restoreTrash);
if (_THIS_IS_MUSIC_BLOCKS_) {
@@ -7320,7 +7304,7 @@ class Activity {
saveLocally() {
try {
localStorage.setItem('beginnerMode', this.beginnerMode.toString());
- localStorage.setItem('isDarkModeON', this.isDarkModeON.toString());
+ localStorage.setItem("themePreference", this.themePreference.toString());
} catch (e) {
// eslint-disable-next-line no-console
console.error('Error saving to localStorage:', e);
diff --git a/js/themebox.js b/js/themebox.js
new file mode 100644
index 0000000000..5d20c54d8f
--- /dev/null
+++ b/js/themebox.js
@@ -0,0 +1,75 @@
+// Copyright (c) 2018-21 Walter Bender
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the The GNU Affero General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// You should have received a copy of the GNU Affero General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
+
+//A dropdown for selecting theme
+
+/*
+ global _
+*/
+
+/* exported ThemeBox */
+
+class ThemeBox {
+ /**
+ * @constructor
+ */
+ constructor(activity) {
+ this.activity = activity;
+ this._theme = activity.storage.themePreference;
+ }
+
+ /**
+ * @public
+ * @returns {void}
+ */
+ light_onclick() {
+ this._theme = "light";
+ this.setPreference();
+ }
+
+ /**
+ * @public
+ * @returns {void}
+ */
+ dark_onclick() {
+ this._theme = "dark";
+ this.setPreference();
+ }
+
+ // /**
+ // * @public
+ // * @returns {void}
+ // */
+ // custom_onclick() {
+ // this._theme = "pastel";
+ // this.setPreference();
+ // }
+
+ /**
+ * @public
+ * @returns {void}
+ */
+ reload() {
+ window.location.reload();
+ }
+
+ setPreference() {
+ if (localStorage.getItem("themePreference") === this._theme) {
+ this.activity.textMsg(_("Music Blocks is already set to this theme."));
+ } else {
+ this.activity.storage.themePreference = this._theme;
+ this.reload();
+ }
+ }
+}
+if (typeof module !== "undefined" && module.exports) {
+ module.exports = ThemeBox;
+}
\ No newline at end of file
diff --git a/js/toolbar.js b/js/toolbar.js
index a870720eb5..9ee25220b0 100644
--- a/js/toolbar.js
+++ b/js/toolbar.js
@@ -67,7 +67,7 @@ class Toolbar {
["delPluginIcon", _("Delete plugin")],
["enableHorizScrollIcon", _("Enable horizontal scrolling")],
["disableHorizScrollIcon", _("Disable horizontal scrolling")],
- ["darkModeIcon", _("Change theme")],
+ ["themeSelectIcon", _("Change theme")],
["mergeWithCurrentIcon", _("Merge with current project")],
["chooseKeyIcon", _("Set Pitch Preview")],
["toggleJavaScriptIcon", _("JavaScript Editor")],
@@ -104,7 +104,10 @@ class Toolbar {
["ar", _("عربى"), "innerHTML"],
["te", _("తెలుగు"), "innerHTML"],
["he", _("עִברִית"), "innerHTML"],
- ["ur", _("اردو"), "innerHTML"]
+ ["ur", _("اردو"), "innerHTML"],
+ ["light", _("Light Mode"), "innerHTML"],
+ ["dark", _("Dark Mode"), "innerHTML"],
+ // ["custom", _("Theme Name"), "innerHTML"],
];
// Workaround for FF
@@ -174,7 +177,10 @@ class Toolbar {
_("igbo"),
_("عربى"),
_("עִברִית"),
- _("اردو")
+ _("اردو"),
+ _("Light Mode"),
+ _("Dark Mode")
+ // _("Custom Theme"),
];
} else {
strings = [
@@ -200,7 +206,7 @@ class Toolbar {
["delPluginIcon", _("Delete plugin")],
["enableHorizScrollIcon", _("Enable horizontal scrolling")],
["disableHorizScrollIcon", _("Disable horizontal scrolling")],
- ["darkModeIcon", _("Change theme")],
+ ["themeSelectIcon", _("Change theme")],
["mergeWithCurrentIcon", _("Merge with current project")],
["toggleJavaScriptIcon", _("JavaScript Editor")],
["restoreIcon", _("Restore")],
@@ -232,7 +238,10 @@ class Toolbar {
["ar", _("عربى"), "innerHTML"],
["te", _("తెలుగు"), "innerHTML"],
["he", _("עִברִית"), "innerHTML"],
- ["ur", _("اردو"), "innerHTML"]
+ ["ur", _("اردو"), "innerHTML"],
+ ["light", _("Light Mode"), "innerHTML"],
+ ["dark", _("Dark Mode"), "innerHTML"]
+ // ["custom", _("Theme Name"), "innerHTML"],
];
// Workaround for FF
@@ -291,7 +300,10 @@ class Toolbar {
_("igbo"),
_("عربى"),
_("עִברִית"),
- _("اردو")
+ _("اردو"),
+ _("Light Mode"),
+ _("Dark Mode")
+ // _("Custom Theme"),
];
}
@@ -459,17 +471,14 @@ class Toolbar {
};
}
- renderDarkModeIcon(onclick) {
- const darkModeIcon = docById("darkModeIcon");
-
- darkModeIcon.onclick = () => {
- this.activity.textMsg(`
${_("Refresh your browser to change your theme.")}
`);
-
- const themeLink = docById("theme-link");
- themeLink.addEventListener( "click", () => {
- onclick();
- })
- }
+ renderThemeSelectIcon(themeBox, themes) {
+ const themeSelectIcon = docById("themeSelectIcon");
+ let themeList = themes;
+ themeSelectIcon.onclick = () => {
+ themeList.forEach((theme) => {
+ docById(theme).onclick = () => themeBox[`${theme}_onclick`](this.activity);
+ });
+ };
}
/**
diff --git a/js/utils/README.md b/js/utils/README.md
index 3337960426..57c6a6b61f 100644
--- a/js/utils/README.md
+++ b/js/utils/README.md
@@ -1,75 +1,231 @@
# How to Customize Theme in Music Blocks?
-This guide explains how themes are managed in Music Blocks (MB) and how you can customize them using both **internal** and **external** methods.
+This guide explains how you can add your own custom theme or customize an existing one in Music Blocks!
---
-### Key Points on Theme Customization:
+### How themes work in Music Blocks
-1. **Refresh Required for Theme Application**
+1. When the page loads for the first time, the default theme of light mode is used. (because no themePreference has been set yet)
- The site must be refreshed to apply a new theme in Music Blocks.
+2. When you choose a theme, an Object stores inside the localStorage called themePreference.
-2. **Canvas and Palette Button Styles**
+3. As of now, all the styling of Music Blocks happens at the time of loading. So we will simply load the page.
- Styles for the canvas and palette buttons are initialized at the time of loading MB.
- - These cannot be directly modified using CSS.
+4. The stylings on the main page happen due to two things:
-3. **Internal and External CSS**
+ 1. css/themes.css
+ 2. js/utils/platformstyle.js
- MB uses a combination of internal and external CSS:
- - **Internal CSS**: Block colors, pie menu, background, and other essential styles are defined in `js/utils/platformstyle.js`.
- - **External CSS**: Elements like the navbar and dropdown menu are styled using external CSS files.
+5. the styling on the planet page happens due to one file
-4. **Saving Theme Name Locally**
+ 1. planet/css/planetThemes.css
- To persist a theme, save its name locally when toggled. For example, the **dark mode** implementation:
- ```javascript
- // Function to toggle theme mode
- this.toggleThemeMode = () => {
- if (this.storage.myThemeName === "darkMode") {
- // If currently in dark mode, remove the theme
- delete this.storage.myThemeName;
+6. The code to handle themes assignment (by looking at the themePreference object in localStorage) to their respective places is already done. You just have to follow the steps given below to add your theme.
+
+---
+
+### Steps on Theme Customization:
+
+Note: I have added a pastel theme as an example here, but if you want to customise an existing theme, just put your changes in the dark mode and choose dark mode from the theme dropdown. You can skip to step no. 6 if that is your goal.
+
+1. **Adding your theme's name to the list in index.html**
+
+ Go to index.html from root, and add your theme to the list (please follow the conventions used by other themes for proper implementation)
+
+ ```javascript
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+2. **Now go to js/toolbar.js, find init(activity){...}**
+
+ There will be 4 arrays named string (two in an if statement, rest two in the else statement).
+ Add your theme's name to the bottom of the array
+
+ ```javascript
+ string = [[...],
+ ["light", _("Light Mode"), "innerHTML"],
+ ["dark", _("Dark Mode"), "innerHTML"],
+ ["pastel", _("Pastel Theme"), "innerHTML"],
+ ["your_theme", _("Your Theme's Name"), "innerHTML"]];
+ ```
+
+ ```javascript
+ string = [_(...),
+ _("Light Mode"),
+ _("Dark Mode"),
+ _("Pastel Theme"),
+ _("Your Theme Name")];
+ ```
+
+ There will be two same arrays in the else statement, repeat the process. This is to display your theme's name in the dropdown menu item you created in Step 1.
+
+3. **Understanding the process a little bit**
+
+ There is a renderThemeSelectIcon function in js/toolbar.js
+
+ ```javascript
+ renderThemeSelectIcon(themeBox, themes) {
+ const themeSelectIcon = docById("themeSelectIcon");
+ let themeList = themes;
+ themeSelectIcon.onclick = () => {
+ themeList.forEach((theme) => {
+ docById(theme).onclick = () => themeBox[`${theme}_onclick`](this.activity);
+ });
+ };
+ }
+ ```
+
+ and it is called in js/activity.js
+
+ ```javascript
+ this.toolbar.renderThemeSelectIcon(this.themeBox, this.themes);
+ ```
+
+ This adds functionality to our options of themes using the themeBox object but leave themeBox for now. Let's get to the this.themes part which is an array in the Activity class in js/activity.js.
+
+ ```javascript
+ class Activity {
+ constructor(
+ ...
+ this.themes = ["light", "pastel", "dark", "your_theme"];
+ ...
+ )
+ }
+ ```
+
+ Add your theme here too. In activity.js, you will find just below there is this for loop, this checks for all the themes in the themes array we just saw above and then add the theme class in themes.css (which you will add in later steps) which matches the themePreference object in localStorage.
+
+ ```javascript
+ for (let i = 0; i < this.themes.length; i++) {
+ if (this.themes[i] === this.storage.themePreference) {
+ body.classList.add(this.themes[i]);
} else {
- this.storage.myThemeName = "darkMode";
- }
- try {
- window.location.reload();
- } catch (e) {
- console.error("Error reloading the window:", e);
+ body.classList.remove(this.themes[i]);
}
- };
- ```
+ }
+ ```
-5. **Applying the Theme After Reload**
+ If no theme is selected, i.e., there is no themePreference in localStorage. The styles will default to light mode, as it is the base styling without a class in themes.css. But when there is a themePreference in localStorage, the class respective to the chosen theme will be added to the elements which will apply because of higher specificity.
- Upon reloading, retrieve the theme name from local storage, and apply the corresponding class to the `` element.
- - External CSS with the same class name will override the styles.
- - Ensure the external CSS file is linked **last** in the main HTML file.
+4. **Adding your theme to the planet page**
- Example:
- ```javascript
- // If the theme is set to "darkMode", enable dark mode else diable
- try {
- if (this.storage.myThemeName === "darkMode") {
- body.classList.add("dark-mode");
- } else {
- body.classList.remove("dark-mode");
+ Go to planet/js/Planet.js and look for
+
+ ```javascript
+ document.addEventListener("DOMContentLoaded", function () {
+ let themes = ["light", "pastel", "dark", "your_theme"];
+ for (let i = 0; i < themes.length; i++) {
+ if (themes[i] === localStorage.getItem("themePreference")) {
+ document.body.classList.add(themes[i]);
+ } else {
+ document.body.classList.remove(themes[i]);
+ }
}
- } catch (e) {
- console.error("Error accessing myThemeName storage:", e);
+ });
+ ```
+
+ Add your theme here as well. This for loop above checks (after the DOM is loaded) for all themes in themes array to add the class in planetThemes.css (which you will add in later steps) which match themePreference in localStorage to the elements on planet/index.html. That is why the changes happen after the reload.
+ If no theme is selected (i.e., there is no themePreference in localStorage), the styles will default to light mode because it is the base styling with no class in planetThemes.css . But when there is a themePreference in localStorage, the class respective to the chosen theme will be added to the elements which will apply because of higher specificity.
+
+5. **Using themeBox to add functionality to your options in the dropdown menu**
+
+ Go to js/themebox.js,
+
+ ```javascript
+ class ThemeBox {
+ ...
+ /**
+ * @public
+ * @returns {void}
+ */
+ light_onclick() {
+ this._theme = "light";
+ this.setPreference();
}
- ```
-6. **Theme Integration in `platformstyle.js`**
+ /**
+ * @public
+ * @returns {void}
+ */
+ dark_onclick() {
+ this._theme = "dark";
+ this.setPreference();
+ }
- Retrieve the saved theme name in `platformstyle.js`. Depending on the theme, initialize a different set of color variables that will affect multiple elements in MB.
+ /**
+ * @public
+ * @returns {void}
+ */
+ pastel_onclick() {
+ this._theme = "pastel";
+ this.setPreference();
+ }
----
+ /**
+ * @public
+ * @returns {void}
+ */
+ your_theme_onclick() {
+ this._theme = "your_theme";
+ this.setPreference();
+ }
+ ...
+ }
+ ```
+
+ Add your function about your theme just like the example shown above. renderSelectThemeIcon function in step 3 will call this theme function, setPreference function will set themepreference in localStorage and then reload the page
+
+6. **Now to add styling for your theme**
+
+ (If you skipped to here, these are the files responsible for styling, the CSS is easy to understand and modify, but to change the color of elements in javascript files, look at the entire code base and search for "platformColor". You will find all the places where JS is used to style. You don't have to add your own theme, you can just change styling in dark mode CSS and JS, and then choose dark mode n the toolbar.)
+
+ You have to add styling to three places,
+
+ 1. css/themes.css (this is external styling used for floating windows, search bar, etc.)
+ If you go here, you will find styling for dark mode, and pastel theme, just write your css using them as a template below the last theme's CSS. There is no light mode here because it is the default.
+
+ 2. js/utils/platformstyle.js (this is styling in JS, used to for the rest of the stuff not covered in themes.css)
+ Find the platformThemes object and add your styling there using the dark, pastel, light themes as a template
+
+ ```javascript
+ let platformThemes = {
+ dark: {...},
+ light: {...},
+ pastel: {...},
+ your_theme: {your_styling}
+ }
+ ```
+
+ There is a for loop below this
+
+ ```javascript
+ for (const theme in platformThemes) {
+ if (themePreference === theme) {
+ window.platformColor = platformThemes[theme];
+ break;
+ } else {
+ window.platformColor = platformThemes["light"];
+ }
+ }
+ ```
-#### Additional Notes:
+ This checks for keys (themes) in platformThemes, then assign the window.platformColor to that key(theme).
+ Then platformColor is used to style things elsewhere. if there is no theme in themePreference, it will default to light mode.
-- **Order of CSS Loading**: Always link your external CSS **after** the internal CSS to allow overriding.
-- **Test Before Deployment**: Ensure theme persistence and compatibility with different features in Music Blocks.
+ 3. planet/css/planetThemes.css (this is styling used for planet page) you can do what you did in the first part of themes.css to add your styling
-By following these steps, you can efficiently manage and customize themes in Music Blocks to suit your preferences or design requirements.
\ No newline at end of file
+## And you are done. Good luck creating your theme!
\ No newline at end of file
diff --git a/js/utils/platformstyle.js b/js/utils/platformstyle.js
index 678ca6d995..50e58d811c 100644
--- a/js/utils/platformstyle.js
+++ b/js/utils/platformstyle.js
@@ -19,7 +19,7 @@ along with this program. If not, see .
/* exported showButtonHighlight */
-const themeName = localStorage.myThemeName || undefined;
+const themePreference = localStorage.themePreference || undefined;
window.platform = {
@@ -32,15 +32,15 @@ window.platform = {
platform.androidWebkit = platform.android && !platform.FF;
platform.FFOS = platform.FF && (platform.mobile || platform.tablet) && !platform.android;
-if (themeName === "darkMode") {
- window.platformColor = {
- textColor : "#E2E2E2",
+let platformThemes = {
+ dark: {
+ textColor: "#E2E2E2",
blockText: "#E2E2E2",
- dialogueBox:"#1C1C1C",
+ dialogueBox: "#1C1C1C",
strokeColor: "#E2E2E2",
fillColor: "#F9F9F9",
blueButton: "#0066FF",
- hoverColor: "#808080",
+ hoverColor: "#808080",
paletteColors: {
widgets: ["#2E7D32", "#1B5E20", "#388E3C", "#81C784"],
pitch: ["#2E7D32", "#1B5E20", "#388E3C", "#81C784"],
@@ -105,7 +105,15 @@ if (themeName === "darkMode") {
piemenuBasic: ["#00ACC1", "#4CAF50", "#008BA3", "#4CAF50", "#008BA3"],
exitWheelcolors: ["#757575", "#BDBDBD"],
exitWheelcolors2: ["#757575", "#7986CB", "#4CAF50"],
- pitchWheelcolors: ["#388E3C", "#4CAF50", "#388E3C", "#008BA3", "#388E3C", "#4CAF50", "#66BB6A"],
+ pitchWheelcolors: [
+ "#388E3C",
+ "#4CAF50",
+ "#388E3C",
+ "#008BA3",
+ "#388E3C",
+ "#4CAF50",
+ "#66BB6A"
+ ],
gridWheelcolors: {
wheel: ["#1C1C1C"],
selected: {
@@ -175,16 +183,15 @@ if (themeName === "darkMode") {
modePieMenusIfColorPush: "#66BB6A",
modePieMenusElseColorPush: "#81C784",
wheelcolors: ["#757575", "#9E9E9E", "#757575", "#9E9E9E", "#616161"]
- };
-} else {
- window.platformColor = {
- textColor : "black",
+ },
+ light: {
+ textColor: "black",
blockText: "#282828",
- dialogueBox:"#fff",
+ dialogueBox: "#fff",
strokeColor: "#E2E2E2",
fillColor: "#F9F9F9",
blueButton: "#0066FF",
- hoverColor: "#E0E0E0",
+ hoverColor: "#E0E0E0",
paletteColors: {
widgets: ["#7CD622", "#57AD02", "#77C428", "#B4EB7D"],
pitch: ["#7CD622", "#57AD02", "#77C428", "#B4EB7D"],
@@ -247,13 +254,21 @@ if (themeName === "darkMode") {
pitchLabelBackground: "#77C428",
graphicsLabelBackground: "#728FF9",
rhythmcellcolor: "#c8c8c8",
- stopIconcolor : "#ea174c",
+ stopIconcolor: "#ea174c",
hitAreaGraphicsBeginFill: "#FFF",
orange: "#e37a00", // 5YR
piemenuBasic: ["#3ea4a3", "#60bfbc", "#1d8989", "#60bfbc", "#1d8989"],
exitWheelcolors: ["#808080", "#c0c0c0"],
exitWheelcolors2: ["#808080", "#92a9ff", "#80a080"],
- pitchWheelcolors: ["#77c428", "#93e042", "#77c428", "#5ba900", "#77c428", "#93e042", "#adfd55"],
+ pitchWheelcolors: [
+ "#77c428",
+ "#93e042",
+ "#77c428",
+ "#5ba900",
+ "#77c428",
+ "#93e042",
+ "#adfd55"
+ ],
gridWheelcolors: {
wheel: ["#ffffff"],
selected: {
@@ -323,7 +338,17 @@ if (themeName === "darkMode") {
modePieMenusIfColorPush: "#4b8b0e",
modePieMenusElseColorPush: "#66a62d",
wheelcolors: ["#808080", "#909090", "#808080", "#909090", "#707070"]
- };
+ },
+ // custom: {Your styling},
+}
+
+for (const theme in platformThemes) {
+ if (themePreference === theme) {
+ window.platformColor = platformThemes[theme];
+ break;
+ } else {
+ window.platformColor = platformThemes["light"];
+ }
}
document.querySelector("meta[name=theme-color]").content = platformColor.header;
diff --git a/planet/css/darkMode.css b/planet/css/darkMode.css
deleted file mode 100644
index 3a9615a4bb..0000000000
--- a/planet/css/darkMode.css
+++ /dev/null
@@ -1,172 +0,0 @@
-.dark-mode {
- background-color: #303030;
- color: #e0e0e0;
-}
-
-.dark-mode .nav-extended {
- background-color: #2f6b2f !important;
- border-bottom: 1px solid #444444;
-}
-
-.dark-mode .nav-wrapper .brand-logo,
-.dark-mode .nav-wrapper a,
-.dark-mode .tabs .tab a {
- color: #ffffff !important;
-}
-
-.dark-mode .tabs .tab a.active {
- color: #a8d5a8 !important;
- border-bottom: 2px solid #a8d5a8;
-}
-
-.dark-mode #backToTopBtn {
- background-color: #2f6b2f !important;
- color: #ffffff !important;
-}
-
-.dark-mode .modal {
- background-color: #424242;
- color: #e0e0e0;
-}
-
-.dark-mode .modal-footer {
- background-color: #383838;
-}
-
-.dark-mode .dropdown-content {
- background-color: #424242 !important;
- color: #ffffff !important;
- border: 1px solid #444444;
-}
-
-.dark-mode .dropdown-content li > a:hover {
- background-color: #383838 !important;
- color: #ffffff !important;
-}
-
-.dark-mode #view-more-chips {
- color: #e0e0e0 !important;
-}
-.dark-mode #local-projects .card {
- background-color: #2a2a2a;
- color: #e0e0e0;
- border: 1px solid #252525;
- box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.3);
-}
-
-.dark-mode #local-projects .card .card-title {
- color: #e0e0e0 !important;
-}
-
-.dark-mode #local-projects .card .card-content {
- color: #bdbdbd;
-}s
-
-.dark-mode #local-projects .card:hover {
- background-color: #242424;;
- box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.5);
-}
-
-.dark-mode #local-projects .card .btn {
- background-color: #2f6b2f;
- color: #ffffff;
-}
-
-.dark-mode #local-projects .card .btn:hover {
- background-color: #388e3c;
-}
-
-.dark-mode #global-projects .card {
- background-color: #2a2a2a;
- color: #e0e0e0;
- border: 1px solid #252525;
- box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.3);
-}
-
-.dark-mode #global-projects .card .card-title {
- color: #e0e0e0 !important;
-}
-
-.dark-mode #global-projects .card .card-content {
- color: #bdbdbd;
-}
-
-.dark-mode #global-projects .card:hover {
- background-color: #242424;
- box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.5);
-}
-
-.dark-mode #global-projects .card .btn {
- background-color: #2f6b2f;
- color: #ffffff;
-}
-
-.dark-mode #global-projects .card .btn:hover {
- background-color: #388e3c;
-}
-
-.dark-mode .modal-footer .btn-flat {
- color: #ffffff !important;
- background-color: transparent !important;
- transition: background-color 0.3s ease, color 0.3s ease;
- font-weight: bold;
-}
-
-.dark-mode .modal-footer .btn-flat:hover {
- background-color: #a8d5a8 !important;
- color: #303030 !important;
-}
-.dark-mode .close-button {
- color: #e0e0e0;
- font-size: 1.5rem;
- transition: color 0.3s ease;
-}
-
-.dark-mode .close-button:hover {
- color: #a8d5a8;
-}
-
-.dark-mode .select-wrapper {
- position: relative;
- height: 3rem;
- line-height: 3rem;
- margin-top: 0.5rem;
-}
-
-.dark-mode .select-wrapper input.select-dropdown {
- color: #ffffff !important;
- font-size: 1rem;
- line-height: normal;
- padding-left: 10px;
- height: 3rem;
- box-sizing: border-box;
- background-color: #424242 !important;
- border: 1px solid #444444 !important;
-}
-
-.dark-mode .select-wrapper:after {
- content: '\25BC';
- position: absolute;
- top: 50%;
- right: 10px;
- transform: translateY(-50%);
- color: #ffffff !important;
- font-size: 0.8rem;
- pointer-events: none;
-}
-
-.dark-mode .dropdown-content {
- background-color: #424242 !important;
- border: 1px solid #444444;
- color: #ffffff !important;
-}
-
-.dark-mode .dropdown-content li > a {
- color: #ffffff !important;
- padding: 0.5rem 1rem;
-}
-
-.dark-mode .dropdown-content li > a:hover {
- background-color: #383838 !important;
- color: #a8d5a8 !important;
-}
\ No newline at end of file
diff --git a/planet/css/planetThemes.css b/planet/css/planetThemes.css
new file mode 100644
index 0000000000..19690e25f7
--- /dev/null
+++ b/planet/css/planetThemes.css
@@ -0,0 +1,175 @@
+/* Dark Mode */
+
+.dark {
+ background-color: #303030;
+ color: #e0e0e0;
+ }
+
+ .dark .nav-extended {
+ background-color: #2f6b2f !important;
+ border-bottom: 1px solid #444444;
+ }
+
+ .dark .nav-wrapper .brand-logo,
+ .dark .nav-wrapper a,
+ .dark .tabs .tab a {
+ color: #ffffff !important;
+ }
+
+ .dark .tabs .tab a.active {
+ color: #a8d5a8 !important;
+ border-bottom: 2px solid #a8d5a8;
+ }
+
+ .dark #backToTopBtn {
+ background-color: #2f6b2f !important;
+ color: #ffffff !important;
+ }
+
+ .dark .modal {
+ background-color: #424242;
+ color: #e0e0e0;
+ }
+
+ .dark .modal-footer {
+ background-color: #383838;
+ }
+
+ .dark .dropdown-content {
+ background-color: #424242 !important;
+ color: #ffffff !important;
+ border: 1px solid #444444;
+ }
+
+ .dark .dropdown-content li > a:hover {
+ background-color: #383838 !important;
+ color: #ffffff !important;
+ }
+
+ .dark #view-more-chips {
+ color: #e0e0e0 !important;
+ }
+ .dark #local-projects .card {
+ background-color: #2a2a2a;
+ color: #e0e0e0;
+ border: 1px solid #252525;
+ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.3);
+ }
+
+ .dark #local-projects .card .card-title {
+ color: #e0e0e0 !important;
+ }
+
+ .dark #local-projects .card .card-content {
+ color: #bdbdbd;
+ }
+ s .dark #local-projects .card:hover {
+ background-color: #242424;
+ box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.5);
+ }
+
+ .dark #local-projects .card .btn {
+ background-color: #2f6b2f;
+ color: #ffffff;
+ }
+
+ .dark #local-projects .card .btn:hover {
+ background-color: #388e3c;
+ }
+
+ .dark #global-projects .card {
+ background-color: #2a2a2a;
+ color: #e0e0e0;
+ border: 1px solid #252525;
+ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.3);
+ }
+
+ .dark #global-projects .card .card-title {
+ color: #e0e0e0 !important;
+ }
+
+ .dark #global-projects .card .card-content {
+ color: #bdbdbd;
+ }
+
+ .dark #global-projects .card:hover {
+ background-color: #242424;
+ box-shadow: 0px 6px 8px rgba(0, 0, 0, 0.5);
+ }
+
+ .dark #global-projects .card .btn {
+ background-color: #2f6b2f;
+ color: #ffffff;
+ }
+
+ .dark #global-projects .card .btn:hover {
+ background-color: #388e3c;
+ }
+
+ .dark .modal-footer .btn-flat {
+ color: #ffffff !important;
+ background-color: transparent !important;
+ transition: background-color 0.3s ease, color 0.3s ease;
+ font-weight: bold;
+ }
+
+ .dark .modal-footer .btn-flat:hover {
+ background-color: #a8d5a8 !important;
+ color: #303030 !important;
+ }
+ .dark .close-button {
+ color: #e0e0e0;
+ font-size: 1.5rem;
+ transition: color 0.3s ease;
+ }
+
+ .dark .close-button:hover {
+ color: #a8d5a8;
+ }
+
+ .dark .select-wrapper {
+ position: relative;
+ height: 3rem;
+ line-height: 3rem;
+ margin-top: 0.5rem;
+ }
+
+ .dark .select-wrapper input.select-dropdown {
+ color: #ffffff !important;
+ font-size: 1rem;
+ line-height: normal;
+ padding-left: 10px;
+ height: 3rem;
+ box-sizing: border-box;
+ background-color: #424242 !important;
+ border: 1px solid #444444 !important;
+ }
+
+ .dark .select-wrapper:after {
+ content: "\25BC";
+ position: absolute;
+ top: 50%;
+ right: 10px;
+ transform: translateY(-50%);
+ color: #ffffff !important;
+ font-size: 0.8rem;
+ pointer-events: none;
+ }
+
+ .dark .dropdown-content {
+ background-color: #424242 !important;
+ border: 1px solid #444444;
+ color: #ffffff !important;
+ }
+
+ .dark .dropdown-content li > a {
+ color: #ffffff !important;
+ padding: 0.5rem 1rem;
+ }
+
+ .dark .dropdown-content li > a:hover {
+ background-color: #383838 !important;
+ color: #a8d5a8 !important;
+ }
+
+ /* Your Custom theme for planet page goes below if you don't want to change the existing theme*/
\ No newline at end of file
diff --git a/planet/index.html b/planet/index.html
index 98a45d8788..6abb313f14 100644
--- a/planet/index.html
+++ b/planet/index.html
@@ -13,7 +13,7 @@
-
+
diff --git a/planet/js/Planet.js b/planet/js/Planet.js
index 7464cb84e3..7f907f0e3c 100644
--- a/planet/js/Planet.js
+++ b/planet/js/Planet.js
@@ -151,18 +151,14 @@ class Planet {
}
-// trigger and sync the dark mode of the planet with the main page
+// sync the dark mode of the planet with the main page and themePreference
document.addEventListener("DOMContentLoaded", function () {
- if (localStorage.getItem("darkMode") === "enabled") {
- document.body.classList.add("dark-mode");
- }
- window.addEventListener("storage", function (event) {
- if (event.key === "darkMode" || event.key === "darkModeTrigger") {
- if (localStorage.getItem("darkMode") === "enabled") {
- document.body.classList.add("dark-mode");
- } else {
- document.body.classList.remove("dark-mode");
- }
+ let themes = ["light", "dark"];
+ for (let i = 0; i < themes.length; i++) {
+ if (themes[i] === localStorage.getItem("themePreference")) {
+ document.body.classList.add(themes[i]);
+ } else {
+ document.body.classList.remove(themes[i]);
}
- });
+ }
});