mirror of
https://git.tt-rss.org/fox/tt-rss.git
synced 2025-08-06 06:07:29 +02:00
Merge branch 'configurable-default-themes' into 'master'
make default light/dark themes configurable, add support for main application and login form See merge request tt-rss/tt-rss!169
This commit is contained in:
commit
906063b1d1
@ -214,6 +214,12 @@ class Config {
|
|||||||
/** scheduled task to send digests, value should be valid cron expression */
|
/** scheduled task to send digests, value should be valid cron expression */
|
||||||
const SCHEDULE_SEND_HEADLINES_DIGESTS = "SCHEDULE_SEND_HEADLINES_DIGESTS";
|
const SCHEDULE_SEND_HEADLINES_DIGESTS = "SCHEDULE_SEND_HEADLINES_DIGESTS";
|
||||||
|
|
||||||
|
/** default (fallback) light theme path */
|
||||||
|
const DEFAULT_LIGHT_THEME = "DEFAULT_LIGHT_THEME";
|
||||||
|
|
||||||
|
/** default (fallback) dark (night) theme path */
|
||||||
|
const DEFAULT_DARK_THEME = "DEFAULT_DARK_THEME";
|
||||||
|
|
||||||
/** default values for all global configuration options */
|
/** default values for all global configuration options */
|
||||||
private const _DEFAULTS = [
|
private const _DEFAULTS = [
|
||||||
Config::DB_TYPE => [ "pgsql", Config::T_STRING ],
|
Config::DB_TYPE => [ "pgsql", Config::T_STRING ],
|
||||||
@ -280,6 +286,8 @@ class Config {
|
|||||||
Config::SCHEDULE_EXPIRE_ERROR_LOG => ["@hourly", Config::T_STRING],
|
Config::SCHEDULE_EXPIRE_ERROR_LOG => ["@hourly", Config::T_STRING],
|
||||||
Config::SCHEDULE_EXPIRE_LOCK_FILES => ["@hourly", Config::T_STRING],
|
Config::SCHEDULE_EXPIRE_LOCK_FILES => ["@hourly", Config::T_STRING],
|
||||||
Config::SCHEDULE_SEND_HEADLINES_DIGESTS => ["@hourly", Config::T_STRING],
|
Config::SCHEDULE_SEND_HEADLINES_DIGESTS => ["@hourly", Config::T_STRING],
|
||||||
|
Config::DEFAULT_LIGHT_THEME => [ "light.css", Config::T_STRING],
|
||||||
|
Config::DEFAULT_DARK_THEME => [ "night.css", Config::T_STRING],
|
||||||
];
|
];
|
||||||
|
|
||||||
private static ?Config $instance = null;
|
private static ?Config $instance = null;
|
||||||
|
@ -438,15 +438,23 @@ class Handler_Public extends Handler {
|
|||||||
<link rel="icon" type="image/png" sizes="72x72" href="images/favicon-72px.png">
|
<link rel="icon" type="image/png" sizes="72x72" href="images/favicon-72px.png">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
<?php
|
<?php
|
||||||
echo stylesheet_tag("themes/light.css");
|
|
||||||
echo javascript_tag("lib/dojo/dojo.js");
|
echo javascript_tag("lib/dojo/dojo.js");
|
||||||
echo javascript_tag("lib/dojo/tt-rss-layer.js");
|
echo javascript_tag("lib/dojo/tt-rss-layer.js");
|
||||||
|
echo javascript_tag("js/common.js");
|
||||||
|
echo javascript_tag("js/utility.js");
|
||||||
?>
|
?>
|
||||||
<?= Config::get_override_links() ?>
|
<?= Config::get_override_links() ?>
|
||||||
</head>
|
</head>
|
||||||
<body class='flat ttrss_utility'>
|
<body class='flat ttrss_utility css_loading'>
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
const __csrf_token = "<?= $_SESSION["csrf_token"]; ?>";
|
||||||
|
|
||||||
|
const __default_light_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_LIGHT_THEME), 'themes/light.css') ?>";
|
||||||
|
const __default_dark_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_DARK_THEME), 'themes/night.css') ?>";
|
||||||
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
require(['dojo/parser', "dojo/ready", 'dijit/form/Button','dijit/form/CheckBox', 'dijit/form/Form',
|
require(['dojo/parser', "dojo/ready", 'dijit/form/Button','dijit/form/CheckBox', 'dijit/form/Form',
|
||||||
'dijit/form/Select','dijit/form/TextBox','dijit/form/ValidationTextBox'],function(parser, ready){
|
'dijit/form/Select','dijit/form/TextBox','dijit/form/ValidationTextBox'],function(parser, ready){
|
||||||
@ -455,6 +463,19 @@ class Handler_Public extends Handler {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
background : #303030;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.css_loading * {
|
||||||
|
display : none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
print "<h1>".__("Password recovery")."</h1>";
|
print "<h1>".__("Password recovery")."</h1>";
|
||||||
|
@ -20,33 +20,6 @@ class OPML extends Handler_Protected {
|
|||||||
return $rc;
|
return $rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
function import(): void {
|
|
||||||
$owner_uid = $_SESSION["uid"];
|
|
||||||
|
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
|
||||||
|
|
||||||
print "<html>
|
|
||||||
<head>
|
|
||||||
".stylesheet_tag("themes/light.css")."
|
|
||||||
<title>".__("OPML Utility")."</title>
|
|
||||||
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
|
|
||||||
</head>
|
|
||||||
<body class='claro ttrss_utility'>
|
|
||||||
<h1>".__('OPML Utility')."</h1><div class='content'>";
|
|
||||||
|
|
||||||
Feeds::_add_cat("Imported feeds", $owner_uid);
|
|
||||||
|
|
||||||
$this->opml_notice(__("Importing OPML..."));
|
|
||||||
|
|
||||||
$this->opml_import($owner_uid);
|
|
||||||
|
|
||||||
print "<br><form method=\"GET\" action=\"prefs.php\">
|
|
||||||
<input type=\"submit\" value=\"".__("Return to preferences")."\">
|
|
||||||
</form>";
|
|
||||||
|
|
||||||
print "</div></body></html>";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export
|
// Export
|
||||||
|
|
||||||
private function opml_export_category(int $owner_uid, int $cat_id, bool $hide_private_feeds = false, bool $include_settings = true): string {
|
private function opml_export_category(int $owner_uid, int $cat_id, bool $hide_private_feeds = false, bool $include_settings = true): string {
|
||||||
|
@ -464,14 +464,14 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_theme_path(string $theme): string {
|
function get_theme_path(string $theme, string $default = ""): string {
|
||||||
$check = "themes/$theme";
|
$check = "themes/$theme";
|
||||||
if (file_exists($check)) return $check;
|
if (file_exists($check)) return $check;
|
||||||
|
|
||||||
$check = "themes.local/$theme";
|
$check = "themes.local/$theme";
|
||||||
if (file_exists($check)) return $check;
|
if (file_exists($check)) return $check;
|
||||||
|
|
||||||
return "";
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
function theme_exists(string $theme): bool {
|
function theme_exists(string $theme): bool {
|
||||||
|
@ -33,6 +33,11 @@
|
|||||||
require({cache:{}});
|
require({cache:{}});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
const __default_light_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_LIGHT_THEME), 'themes/light.css') ?>";
|
||||||
|
const __default_dark_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_DARK_THEME), 'themes/night.css') ?>";
|
||||||
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
/* exported Plugins */
|
/* exported Plugins */
|
||||||
const Plugins = {};
|
const Plugins = {};
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const __csrf_token = "<?= $_SESSION["csrf_token"]; ?>";
|
const __csrf_token = "<?= $_SESSION["csrf_token"]; ?>";
|
||||||
|
|
||||||
|
const __default_light_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_LIGHT_THEME), 'themes/light.css') ?>";
|
||||||
|
const __default_dark_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_DARK_THEME), 'themes/night.css') ?>";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php UserHelper::print_user_stylesheet() ?>
|
<?php UserHelper::print_user_stylesheet() ?>
|
||||||
|
@ -173,7 +173,7 @@ const App = {
|
|||||||
|
|
||||||
if (link) {
|
if (link) {
|
||||||
if (navigator.onLine) {
|
if (navigator.onLine) {
|
||||||
const css_override = is_night ? "themes/night.css" : "themes/light.css";
|
const css_override = is_night ? App.getInitParam("default_dark_theme") : App.getInitParam("default_light_theme");
|
||||||
link.setAttribute("href", css_override + "?" + Date.now());
|
link.setAttribute("href", css_override + "?" + Date.now());
|
||||||
} else if (retry < 5) {
|
} else if (retry < 5) {
|
||||||
console.log("nightModeChanged: we're offline, will attempt to retry...");
|
console.log("nightModeChanged: we're offline, will attempt to retry...");
|
||||||
@ -704,6 +704,8 @@ const App = {
|
|||||||
window.onerror = this.Error.onWindowError;
|
window.onerror = this.Error.onWindowError;
|
||||||
|
|
||||||
this.setInitParam("csrf_token", __csrf_token);
|
this.setInitParam("csrf_token", __csrf_token);
|
||||||
|
this.setInitParam("default_light_theme", __default_light_theme);
|
||||||
|
this.setInitParam("default_dark_theme", __default_dark_theme);
|
||||||
|
|
||||||
this.setupNightModeDetection(() => {
|
this.setupNightModeDetection(() => {
|
||||||
parser.parse();
|
parser.parse();
|
||||||
|
@ -7,8 +7,11 @@ window.addEventListener("load", function() {
|
|||||||
apply_night_mode: function (is_night, link) {
|
apply_night_mode: function (is_night, link) {
|
||||||
console.log("night mode changed to", is_night);
|
console.log("night mode changed to", is_night);
|
||||||
|
|
||||||
|
const light_theme = typeof __default_light_theme != 'undefined' ? __default_light_theme : 'themes/light.css';
|
||||||
|
const dark_theme = typeof __default_dark_theme != 'undefined' ? __default_dark_theme : 'themes/dark.css';
|
||||||
|
|
||||||
if (link) {
|
if (link) {
|
||||||
const css_override = is_night ? "themes/night.css" : "themes/light.css";
|
const css_override = is_night ? dark_theme : light_theme;
|
||||||
|
|
||||||
link.setAttribute("href", css_override + "?" + Date.now());
|
link.setAttribute("href", css_override + "?" + Date.now());
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const __csrf_token = "<?= $_SESSION["csrf_token"]; ?>";
|
const __csrf_token = "<?= $_SESSION["csrf_token"]; ?>";
|
||||||
|
|
||||||
|
const __default_light_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_LIGHT_THEME), 'themes/light.css') ?>";
|
||||||
|
const __default_dark_theme = "<?= get_theme_path(Config::get(Config::DEFAULT_DARK_THEME), 'themes/night.css') ?>";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php UserHelper::print_user_stylesheet() ?>
|
<?php UserHelper::print_user_stylesheet() ?>
|
||||||
|
Loading…
Reference in New Issue
Block a user