diff --git a/package.json b/package.json
index c8339ebea..681723b6e 100644
--- a/package.json
+++ b/package.json
@@ -113,4 +113,4 @@
"yargs": "^17.7.2"
},
"browserslist": "cover 100%,not android < 5"
-}
+}
\ No newline at end of file
diff --git a/res/android/values/themes.xml b/res/android/values/themes.xml
index 82bcebedc..bd2204411 100644
--- a/res/android/values/themes.xml
+++ b/res/android/values/themes.xml
@@ -4,6 +4,6 @@
- @color/ic_splash_background
- @drawable/ic_launcher_foreground
- 200
- - @style/Theme.AppCompat.NoActionBar
+ - @style/Theme.AppCompat.DayNight.NoActionBar
diff --git a/src/lib/settings.js b/src/lib/settings.js
index 090bf94ab..391654494 100644
--- a/src/lib/settings.js
+++ b/src/lib/settings.js
@@ -1,10 +1,12 @@
import fsOperation from "fileSystem";
import ThemeBuilder from "theme/builder";
import themes from "theme/list";
+import { getSystemEditorTheme } from "theme/preInstalled";
import Url from "utils/Url";
import helpers from "utils/helpers";
import constants from "./constants";
import lang from "./lang";
+import { isDeviceDarkTheme } from "./systemConfiguration";
/**
* @typedef {object} fileBrowserSettings
@@ -182,8 +184,10 @@ class Settings {
this.settingsFile = Url.join(DATA_STORAGE, "settings.json");
if (!IS_FREE_VERSION) {
- this.#defaultSettings.appTheme = "ocean";
- this.#defaultSettings.editorTheme = "ace/theme/dracula";
+ this.#defaultSettings.appTheme = "system";
+ this.#defaultSettings.editorTheme = getSystemEditorTheme(
+ isDeviceDarkTheme(),
+ );
}
this.#initialized = true;
diff --git a/src/lib/systemConfiguration.js b/src/lib/systemConfiguration.js
index 59dc59bd6..24a3180b7 100644
--- a/src/lib/systemConfiguration.js
+++ b/src/lib/systemConfiguration.js
@@ -52,3 +52,7 @@ export function getSystemConfiguration() {
cordova.exec(resolve, reject, "System", "get-configuration", []);
});
}
+
+export function isDeviceDarkTheme() {
+ return window.matchMedia("(prefers-color-scheme: dark)").matches;
+}
diff --git a/src/palettes/changeTheme/index.js b/src/palettes/changeTheme/index.js
index 8e4ff873f..be76c6fa7 100644
--- a/src/palettes/changeTheme/index.js
+++ b/src/palettes/changeTheme/index.js
@@ -1,7 +1,9 @@
import "./style.scss";
import palette from "components/palette";
import appSettings from "lib/settings";
+import { isDeviceDarkTheme } from "lib/systemConfiguration";
import themes from "theme/list";
+import { updateSystemTheme } from "theme/preInstalled";
export default function changeTheme(type = "editor") {
palette(
@@ -56,11 +58,45 @@ function generateHints(type) {
});
}
+let previousDark = isDeviceDarkTheme();
+const updateTimeMs = 2000;
+
+let intervalId = setInterval(async () => {
+ if (appSettings.value.appTheme.toLowerCase() === "system") {
+ const isDark = isDeviceDarkTheme();
+ if (isDark !== previousDark) {
+ previousDark = isDark;
+ updateSystemTheme(isDark);
+ }
+ }
+}, updateTimeMs);
+
function onselect(value) {
if (!value) return;
const selection = JSON.parse(value);
+ if (selection.theme === "system") {
+ // Start interval if not already started
+ if (!intervalId) {
+ intervalId = setInterval(async () => {
+ if (appSettings.value.appTheme.toLowerCase() === "system") {
+ const isDark = isDeviceDarkTheme();
+ if (isDark !== previousDark) {
+ previousDark = isDark;
+ updateSystemTheme(isDark);
+ }
+ }
+ }, updateTimeMs);
+ }
+ } else {
+ // Cancel interval if it's running
+ if (intervalId) {
+ clearInterval(intervalId);
+ intervalId = null;
+ }
+ }
+
if (selection.type === "editor") {
editorManager.editor.setTheme(selection.theme);
appSettings.update(
diff --git a/src/theme/list.js b/src/theme/list.js
index dfeea53ef..0c8b308f8 100644
--- a/src/theme/list.js
+++ b/src/theme/list.js
@@ -1,10 +1,11 @@
import fsOperation from "fileSystem";
+import { isDeviceDarkTheme } from "lib/systemConfiguration";
import Url from "utils/Url";
import color from "utils/color";
import fonts from "../lib/fonts";
import settings from "../lib/settings";
import ThemeBuilder from "./builder";
-import themes from "./preInstalled";
+import themes, { updateSystemTheme } from "./preInstalled";
/** @type {Map} */
const appThemes = new Map();
@@ -12,6 +13,9 @@ let themeApplied = false;
function init() {
themes.forEach((theme) => add(theme));
+ (async () => {
+ updateSystemTheme(isDeviceDarkTheme());
+ })();
}
/**
@@ -68,7 +72,7 @@ function add(theme) {
* @param {string} id The name of the theme to apply
* @param {boolean} init Whether or not this is the first time the theme is being applied
*/
-async function apply(id, init) {
+export async function apply(id, init) {
if (!DOES_SUPPORT_THEME) {
id = "default";
}
@@ -91,7 +95,9 @@ async function apply(id, init) {
if (init && theme.preferredEditorTheme) {
update.editorTheme = theme.preferredEditorTheme;
- editorManager.editor.setTheme(theme.preferredEditorTheme);
+ if (editorManager != null && editorManager.editor != null) {
+ editorManager.editor.setTheme(theme.preferredEditorTheme);
+ }
}
if (init && theme.preferredFont) {
@@ -129,7 +135,7 @@ async function apply(id, init) {
* Update a theme
* @param {ThemeBuilder} theme
*/
-function update(theme) {
+export function update(theme) {
if (!(theme instanceof ThemeBuilder)) return;
const oldTheme = get(theme.id);
if (!oldTheme) {
diff --git a/src/theme/preInstalled.js b/src/theme/preInstalled.js
index a3acefe5a..f66704819 100644
--- a/src/theme/preInstalled.js
+++ b/src/theme/preInstalled.js
@@ -1,4 +1,9 @@
+import restoreTheme from "lib/restoreTheme";
+import appSettings from "lib/settings";
+import { isDeviceDarkTheme } from "lib/systemConfiguration";
+import color from "utils/color";
import { createBuiltInTheme } from "./builder";
+import { apply, update } from "./list";
const WHITE = "rgb(255, 255, 255)";
const BLACK = "rgb(0, 0, 0)";
@@ -164,10 +169,68 @@ light.linkTextColor = "rgb(104, 103, 149)";
light.borderColor = "rgb(153, 153, 153)";
light.popupIconColor = "rgb(51, 62, 89)";
+const system = createBuiltInTheme("System");
+
+export function getSystemEditorTheme(darkTheme) {
+ if (darkTheme) {
+ return "ace/theme/clouds_midnight";
+ } else {
+ return "ace/theme/crimson_editor";
+ }
+}
+
+export function updateSystemTheme(darkTheme) {
+ if (darkTheme) {
+ system.primaryColor = "rgb(49, 49, 49)";
+ system.primaryTextColor = WHITE;
+ system.darkenedPrimaryColor = "rgb(29, 29, 29)";
+ system.secondaryColor = "rgb(37, 37, 37)";
+ system.secondaryTextColor = WHITE;
+ system.activeColor = "rgb(51, 153, 255)";
+ system.linkTextColor = "rgb(181, 180, 233)";
+ system.borderColor = "rgba(230, 230, 230, 0.2)";
+ system.popupIconColor = WHITE;
+
+ system.popupBackgroundColor = "rgb(49, 49, 49)";
+ system.popupTextColor = WHITE;
+ system.popupActiveColor = "rgb(255, 215, 0)";
+ system.type = "dark";
+ } else {
+ system.type = "light";
+ system.darkenedPrimaryColor = "rgb(153, 153, 153)";
+ system.primaryColor = WHITE;
+ system.primaryTextColor = "rgb(51, 62, 89)";
+ system.secondaryColor = WHITE;
+ system.secondaryTextColor = "rgb(51, 62, 89)";
+ system.activeColor = "rgb(51, 153, 255)";
+ system.linkTextColor = BLACK;
+ system.borderColor = "rgb(153, 153, 153)";
+ system.popupIconColor = "rgb(51, 62, 89)";
+
+ system.popupBackgroundColor = WHITE;
+ system.popupTextColor = BLACK;
+ system.popupActiveColor = "rgb(255, 215, 0)";
+ }
+
+ system.preferredEditorTheme = getSystemEditorTheme(darkTheme);
+
+ if (
+ appSettings !== undefined &&
+ appSettings.value !== undefined &&
+ appSettings.value.appTheme !== undefined &&
+ appSettings.value.appTheme.toLowerCase() === "system"
+ ) {
+ apply(system.id, true);
+ }
+}
+
+updateSystemTheme(isDeviceDarkTheme());
+
const custom = createBuiltInTheme("Custom");
custom.autoDarkened = true;
export default [
+ system,
createBuiltInTheme("default", "dark", "free"),
dark,
oled,
diff --git a/www/index.html b/www/index.html
index e4c0e5ec3..ae9aa7f4d 100644
--- a/www/index.html
+++ b/www/index.html
@@ -165,17 +165,17 @@
Acode
-
-
-
-
-
+
+
+
+
+