mirror of
https://github.com/unraid/webgui.git
synced 2026-01-05 00:59:48 -06:00
Merge pull request #2189 from unraid/feat/unraid-api-tweaks
feat: add tweaks for the Unraid API
This commit is contained in:
@@ -14,6 +14,10 @@ if (isset($_COOKIE[session_name()])) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
// Include JS caching functions
|
||||
require_once '/usr/local/emhttp/webGui/include/JSCache.php';
|
||||
|
||||
// Base whitelist of files
|
||||
$arrWhitelist = [
|
||||
'/webGui/styles/clear-sans-bold-italic.eot',
|
||||
'/webGui/styles/clear-sans-bold-italic.woff',
|
||||
@@ -39,8 +43,15 @@ $arrWhitelist = [
|
||||
'/webGui/images/case-model.png',
|
||||
'/webGui/images/green-on.png',
|
||||
'/webGui/images/red-on.png',
|
||||
'/webGui/images/yellow-on.png'
|
||||
'/webGui/images/yellow-on.png',
|
||||
'/webGui/images/UN-logotype-gradient.svg'
|
||||
];
|
||||
|
||||
// Add JS files from the unraid-components directory using cache
|
||||
$webComponentsDirectory = '/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/';
|
||||
$jsFiles = getCachedJSFiles($webComponentsDirectory);
|
||||
$arrWhitelist = array_merge($arrWhitelist, $jsFiles);
|
||||
|
||||
if (in_array(preg_replace(['/\?v=\d+$/','/\?\d+$/'],'',$_SERVER['REQUEST_URI']),$arrWhitelist)) {
|
||||
// authorized
|
||||
http_response_code(200);
|
||||
|
||||
8
emhttp/plugins/dynamix/LogViewer.page
Normal file
8
emhttp/plugins/dynamix/LogViewer.page
Normal file
@@ -0,0 +1,8 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="Log Viewer (new)"
|
||||
Icon="icon-log"
|
||||
Tag="list"
|
||||
---
|
||||
<unraid-i18n-host>
|
||||
<unraid-log-viewer></unraid-log-viewer>
|
||||
</unraid-i18n-host>
|
||||
@@ -28,22 +28,22 @@ $entity = $notify['entity'] & 1 == 1;
|
||||
$alerts = '/tmp/plugins/my_alerts.txt';
|
||||
$wlan0 = file_exists('/sys/class/net/wlan0');
|
||||
|
||||
$safemode = _var($var,'safeMode')=='yes';
|
||||
$safemode = _var($var, 'safeMode') == 'yes';
|
||||
$banner = "$config/webGui/banner.png";
|
||||
|
||||
$notes = '/var/tmp/unRAIDServer.txt';
|
||||
if (!file_exists($notes)) {
|
||||
file_put_contents($notes, shell_exec("$docroot/plugins/dynamix.plugin.manager/scripts/plugin changes $docroot/plugins/unRAIDServer/unRAIDServer.plg"));
|
||||
file_put_contents($notes, shell_exec("$docroot/plugins/dynamix.plugin.manager/scripts/plugin changes $docroot/plugins/unRAIDServer/unRAIDServer.plg"));
|
||||
}
|
||||
|
||||
$taskPages = find_pages('Tasks');
|
||||
$buttonPages = find_pages('Buttons');
|
||||
$pages = []; // finds subpages
|
||||
if (!empty($myPage['text'])) $pages[$myPage['name']] = $myPage;
|
||||
if (_var($myPage,'Type')=='xmenu') $pages = array_merge($pages, find_pages($myPage['name']));
|
||||
if (_var($myPage, 'Type') == 'xmenu') $pages = array_merge($pages, find_pages($myPage['name']));
|
||||
|
||||
// nchan related actions
|
||||
$nchan = ['webGui/nchan/notify_poller','webGui/nchan/session_check'];
|
||||
$nchan = ['webGui/nchan/notify_poller', 'webGui/nchan/session_check'];
|
||||
if ($wlan0) $nchan[] = 'webGui/nchan/wlan0';
|
||||
// build nchan scripts from found pages
|
||||
$allPages = array_merge($taskPages, $buttonPages, $pages);
|
||||
@@ -52,96 +52,94 @@ foreach ($allPages as $page) {
|
||||
}
|
||||
// act on nchan scripts
|
||||
if (count($pages)) {
|
||||
$running = file_exists($nchan_pid) ? file($nchan_pid,FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) : [];
|
||||
$running = file_exists($nchan_pid) ? file($nchan_pid, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) : [];
|
||||
$start = array_diff($nchan, $running); // returns any new scripts to be started
|
||||
$stop = array_diff($running, $nchan); // returns any old scripts to be stopped
|
||||
$running = array_merge($start, $running); // update list of current running nchan scripts
|
||||
// start nchan scripts which are new
|
||||
foreach ($start as $row) {
|
||||
$script = explode(':',$row)[0];
|
||||
$script = explode(':', $row)[0];
|
||||
exec("$docroot/$script &>/dev/null &");
|
||||
}
|
||||
// stop nchan scripts with the :stop option
|
||||
foreach ($stop as $row) {
|
||||
[$script,$opt] = my_explode(':',$row);
|
||||
[$script, $opt] = my_explode(':', $row);
|
||||
if ($opt == 'stop') {
|
||||
exec("pkill -f $docroot/$script &>/dev/null &");
|
||||
array_splice($running,array_search($row,$running),1);
|
||||
array_splice($running, array_search($row, $running), 1);
|
||||
}
|
||||
}
|
||||
if (count($running)) file_put_contents($nchan_pid,implode("\n",$running)."\n"); else @unlink($nchan_pid);
|
||||
if (count($running)) file_put_contents($nchan_pid, implode("\n", $running) . "\n");
|
||||
else @unlink($nchan_pid);
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html <?=$display['rtl']?>lang="<?=strtok($locale, '_') ?: 'en'?>" class="<?= $themeHelper->getThemeHtmlClass() ?>">
|
||||
<html <?= $display['rtl'] ?>lang="<?= strtok($locale, '_') ?: 'en' ?>" class="<?= $themeHelper->getThemeHtmlClass() ?>">
|
||||
|
||||
<head>
|
||||
<title><?=_var($var, 'NAME')?>/<?=_var($myPage, 'name')?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="viewport" content="width=1300">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="referrer" content="same-origin">
|
||||
<link type="image/png" rel="shortcut icon" href="/webGui/images/<?=_var($var, 'mdColor', 'red-on')?>.png">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-fonts.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-cases.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/font-awesome.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/context.standalone.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.sweetalert.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.ui.css")?>">
|
||||
<title><?= _var($var, 'NAME') ?>/<?= _var($myPage, 'name') ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="viewport" content="width=1300">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="referrer" content="same-origin">
|
||||
<link type="image/png" rel="shortcut icon" href="/webGui/images/<?= _var($var, 'mdColor', 'red-on') ?>.png">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/default-fonts.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/default-cases.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/font-awesome.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/context.standalone.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/jquery.sweetalert.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/jquery.ui.css") ?>">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-color-palette.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-base.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-dynamix.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/themes/{$theme}.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/default-color-palette.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/default-base.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/default-dynamix.css") ?>">
|
||||
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/themes/{$theme}.css") ?>">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--customer-header-background-image: url(<?= file_exists($banner) ? autov($banner) : autov('/webGui/images/banner.png') ?>);
|
||||
<?if ($header):?>
|
||||
--customer-header-text-color: #<?=$header?>;
|
||||
<?endif;?>
|
||||
<?if ($backgnd):?>
|
||||
--customer-header-background-color: #<?=$backgnd?>;
|
||||
<?endif;?>
|
||||
<?if ($display['font']):?>
|
||||
--custom-font-size: <?=$display['font']?>%;
|
||||
<?endif;?>
|
||||
}
|
||||
<style>
|
||||
:root {
|
||||
--customer-header-background-image: url(<?= file_exists($banner) ? autov($banner) : autov('/webGui/images/banner.png') ?>);
|
||||
<? if ($header): ?>--customer-header-text-color: #<?= $header ?>;
|
||||
<? endif; ?><? if ($backgnd): ?>--customer-header-background-color: #<?= $backgnd ?>;
|
||||
<? endif; ?><? if ($display['font']): ?>--custom-font-size: <?= $display['font'] ?>%;
|
||||
<? endif; ?>
|
||||
}
|
||||
|
||||
<?php
|
||||
// Generate sidebar icon CSS if using sidebar theme
|
||||
if ($themeHelper->isSidebarTheme()) {
|
||||
echo generate_sidebar_icon_css($taskPages, $buttonPages);
|
||||
}
|
||||
?>
|
||||
</style>
|
||||
<?php
|
||||
// Generate sidebar icon CSS if using sidebar theme
|
||||
if ($themeHelper->isSidebarTheme()) {
|
||||
echo generate_sidebar_icon_css($taskPages, $buttonPages);
|
||||
}
|
||||
?>
|
||||
</style>
|
||||
|
||||
<noscript>
|
||||
<div class="upgrade_notice"><?=_("Your browser has JavaScript disabled")?></div>
|
||||
</noscript>
|
||||
<noscript>
|
||||
<div class="upgrade_notice"><?= _("Your browser has JavaScript disabled") ?></div>
|
||||
</noscript>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/dynamix.js')?>"></script>
|
||||
<script src="<?autov('/webGui/javascript/translate.'.($locale?:'en_US').'.js')?>"></script>
|
||||
<script src="<? autov('/webGui/javascript/dynamix.js') ?>"></script>
|
||||
<script src="<? autov('/webGui/javascript/translate.' . ($locale ?: 'en_US') . '.js') ?>"></script>
|
||||
|
||||
<? require_once "$docroot/webGui/include/DefaultPageLayout/HeadInlineJS.php"; ?>
|
||||
<? require_once "$docroot/webGui/include/DefaultPageLayout/HeadInlineJS.php"; ?>
|
||||
<?php
|
||||
foreach ($buttonPages as $button) {
|
||||
annotate($button['file']);
|
||||
includePageStylesheets($button);
|
||||
eval('?>' . parse_text($button['text']));
|
||||
}
|
||||
|
||||
<?php
|
||||
foreach ($buttonPages as $button) {
|
||||
annotate($button['file']);
|
||||
includePageStylesheets($button);
|
||||
eval('?>'.parse_text($button['text']));
|
||||
}
|
||||
foreach ($pages as $page) {
|
||||
annotate($page['file']);
|
||||
includePageStylesheets($page);
|
||||
}
|
||||
?>
|
||||
|
||||
foreach ($pages as $page) {
|
||||
annotate($page['file']);
|
||||
includePageStylesheets($page);
|
||||
}
|
||||
?>
|
||||
|
||||
<?include "$docroot/plugins/dynamix.my.servers/include/myservers1.php"?>
|
||||
<? include "$docroot/plugins/dynamix.my.servers/include/myservers1.php" ?>
|
||||
<? require_once "$docroot/webGui/include/DefaultPageLayout/GUIModeSessionFix.php"; ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<? include "$docroot/webGui/include/DefaultPageLayout/Header.php"; ?>
|
||||
<? include "$docroot/webGui/include/DefaultPageLayout/Navigation/Main.php"; ?>
|
||||
@@ -149,5 +147,7 @@ foreach ($pages as $page) {
|
||||
<? include "$docroot/webGui/include/DefaultPageLayout/Footer.php"; ?>
|
||||
<? include "$docroot/webGui/include/DefaultPageLayout/MiscElements.php"; ?>
|
||||
<? include "$docroot/webGui/include/DefaultPageLayout/BodyInlineJS.php"; ?>
|
||||
<? include "$docroot/webGui/include/DefaultPageLayout/ToastSetup.php"; ?>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -71,32 +71,7 @@ defaultPage.on('message', function(msg,meta) {
|
||||
$('#statusbar').html(status);
|
||||
break;
|
||||
case 2:
|
||||
// notifications
|
||||
var bell1 = 0, bell2 = 0, bell3 = 0;
|
||||
$.each($.parseJSON(msg), function(i, notify){
|
||||
switch (notify.importance) {
|
||||
case 'alert' : bell1++; break;
|
||||
case 'warning': bell2++; break;
|
||||
case 'normal' : bell3++; break;
|
||||
}
|
||||
<?if ($notify['display']==0):?>
|
||||
if (notify.show) {
|
||||
$.jGrowl(notify.subject+'<br>'+notify.description,{
|
||||
group: notify.importance,
|
||||
header: notify.event+': '+notify.timestamp,
|
||||
theme: notify.file,
|
||||
beforeOpen: function(e,m,o){if ($('div.jGrowl-notification').hasClass(notify.file)) return(false);},
|
||||
afterOpen: function(e,m,o){if (notify.link) $(e).css('cursor','pointer');},
|
||||
click: function(e,m,o){if (notify.link) location.replace(notify.link);},
|
||||
close: function(e,m,o){$.post('/webGui/include/Notify.php',{cmd:'hide',file:"<?=$notify['path'].'/unread/'?>"+notify.file,csrf_token:csrf_token}<?if ($notify['life']==0):?>,function(){$.post('/webGui/include/Notify.php',{cmd:'archive',file:notify.file,csrf_token:csrf_token});}<?endif;?>);}
|
||||
});
|
||||
}
|
||||
<?endif;?>
|
||||
});
|
||||
$('#bell').removeClass('red-orb yellow-orb green-orb').prop('title',"<?=_('Alerts')?> ["+bell1+']\n'+"<?=_('Warnings')?> ["+bell2+']\n'+"<?=_('Notices')?> ["+bell3+']');
|
||||
if (bell1) $('#bell').addClass('red-orb'); else
|
||||
if (bell2) $('#bell').addClass('yellow-orb'); else
|
||||
if (bell3) $('#bell').addClass('green-orb');
|
||||
// notifications - moved to the Unraid API
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is used to fix the session for the Unraid web interface when booted in GUI mode.
|
||||
* This can be deleted if GUI mode authentication is enabled.
|
||||
*/
|
||||
|
||||
function is_localhost()
|
||||
{
|
||||
// Use the peer IP, not the Host header which can be spoofed
|
||||
return $_SERVER['REMOTE_ADDR'] === '127.0.0.1' || $_SERVER['REMOTE_ADDR'] === '::1';
|
||||
}
|
||||
function is_good_session()
|
||||
{
|
||||
return isset($_SESSION) && isset($_SESSION['unraid_user']) && isset($_SESSION['unraid_login']);
|
||||
}
|
||||
if (is_localhost() && !is_good_session()) {
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_destroy();
|
||||
}
|
||||
session_start();
|
||||
$_SESSION['unraid_login'] = time();
|
||||
$_SESSION['unraid_user'] = 'root';
|
||||
session_write_close();
|
||||
my_logger("Unraid GUI-boot: created root session for localhost request.");
|
||||
}
|
||||
?>
|
||||
@@ -477,32 +477,6 @@ function digits(number) {
|
||||
return 'three';
|
||||
}
|
||||
|
||||
function openNotifier() {
|
||||
$.post('/webGui/include/Notify.php',{cmd:'get',csrf_token:csrf_token},function(msg) {
|
||||
$.each($.parseJSON(msg), function(i, notify){
|
||||
$.jGrowl(notify.subject+'<br>'+notify.description,{
|
||||
group: notify.importance,
|
||||
header: notify.event+': '+notify.timestamp,
|
||||
theme: notify.file,
|
||||
sticky: true,
|
||||
beforeOpen: function(e,m,o){if ($('div.jGrowl-notification').hasClass(notify.file)) return(false);},
|
||||
afterOpen: function(e,m,o){if (notify.link) $(e).css('cursor','pointer');},
|
||||
click: function(e,m,o){if (notify.link) location.replace(notify.link);},
|
||||
close: function(e,m,o){$.post('/webGui/include/Notify.php',{cmd:'archive',file:notify.file,csrf_token:csrf_token});}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function closeNotifier() {
|
||||
$.post('/webGui/include/Notify.php',{cmd:'get',csrf_token:csrf_token},function(msg) {
|
||||
$.each($.parseJSON(msg), function(i, notify){
|
||||
$.post('/webGui/include/Notify.php',{cmd:'archive',file:notify.file,csrf_token:csrf_token});
|
||||
});
|
||||
$('div.jGrowl').find('div.jGrowl-close').trigger('click');
|
||||
});
|
||||
}
|
||||
|
||||
function viewHistory() {
|
||||
location.replace('/Tools/NotificationsArchive');
|
||||
}
|
||||
@@ -536,17 +510,7 @@ $(function() {
|
||||
}
|
||||
$('#'+tab).attr('checked', true);
|
||||
updateTime();
|
||||
$.jGrowl.defaults.closeTemplate = '<i class="fa fa-close"></i>';
|
||||
$.jGrowl.defaults.closerTemplate = '<?=$notify['position'][0]=='b' ? '<div class="bottom">':'<div class="top">'?>[ <?=_("close all notifications")?> ]</div>';
|
||||
$.jGrowl.defaults.position = '<?=$notify['position']?>';
|
||||
$.jGrowl.defaults.theme = '';
|
||||
$.jGrowl.defaults.themeState = '';
|
||||
$.jGrowl.defaults.pool = 10;
|
||||
<?if ($notify['life'] > 0):?>
|
||||
$.jGrowl.defaults.life = <?=$notify['life']*1000?>;
|
||||
<?else:?>
|
||||
$.jGrowl.defaults.sticky = true;
|
||||
<?endif;?>
|
||||
|
||||
Shadowbox.setup('a.sb-enable', {modal:true});
|
||||
// add any pre-existing reboot notices
|
||||
$.post('/webGui/include/Report.php',{cmd:'notice'},function(notices){
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
<div id="header" class="<?=$display['banner']?>">
|
||||
<div class="logo">
|
||||
<a href="https://unraid.net" target="_blank">
|
||||
<?readfile("$docroot/webGui/images/UN-logotype-gradient.svg")?>
|
||||
</a>
|
||||
|
||||
<unraid-i18n-host>
|
||||
<unraid-header-os-version></unraid-header-os-version>
|
||||
</unraid-i18n-host>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<uui-toaster rich-colors close-button position="<?= ($notify['position'] === 'center') ? 'top-center' : $notify['position'] ?>"></uui-toaster>
|
||||
86
emhttp/plugins/dynamix/include/JSCache.php
Normal file
86
emhttp/plugins/dynamix/include/JSCache.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
// Function to recursively find JS files in a directory
|
||||
function findJsFiles($directory) {
|
||||
if (!is_dir($directory)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$jsFiles = [];
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS)
|
||||
);
|
||||
|
||||
try {
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->isFile() && $file->getExtension() === 'js') {
|
||||
$path = $file->getPathname();
|
||||
$baseDir = '/usr/local/emhttp';
|
||||
if (strpos($path, $baseDir) === 0) {
|
||||
$path = substr($path, strlen($baseDir));
|
||||
}
|
||||
$jsFiles[] = $path;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
my_logger("Error scanning for JS files: " . $e->getMessage());
|
||||
return [];
|
||||
}
|
||||
|
||||
return $jsFiles;
|
||||
}
|
||||
|
||||
// Function to get JS files with caching
|
||||
function getCachedJSFiles(string $directory, int $cacheLifetime = 300): array {
|
||||
$cacheDir = sys_get_temp_dir();
|
||||
$cacheFile = "$cacheDir/js_files_cache_" . md5($directory) . ".json";
|
||||
$lockFile = "$cacheFile.lock";
|
||||
|
||||
// Check if cache exists and is still valid
|
||||
$useCache = false;
|
||||
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheLifetime)) {
|
||||
$useCache = true;
|
||||
}
|
||||
|
||||
if ($useCache) {
|
||||
$data = @file_get_contents($cacheFile);
|
||||
if ($data === false) {
|
||||
my_logger("Warning: Unable to read JS cache at $cacheFile");
|
||||
$useCache = false;
|
||||
} else {
|
||||
$jsFiles = json_decode($data, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
my_logger("Warning: Corrupt JSON cache at $cacheFile");
|
||||
$useCache = false;
|
||||
} else {
|
||||
return $jsFiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire lock to rebuild cache safely
|
||||
$lockFp = @fopen($lockFile, 'w');
|
||||
if ($lockFp && flock($lockFp, LOCK_EX | LOCK_NB)) {
|
||||
try {
|
||||
$jsFiles = findJsFiles($directory);
|
||||
if (file_put_contents($cacheFile, json_encode($jsFiles)) === false) {
|
||||
my_logger("Warning: Could not write JS cache to $cacheFile");
|
||||
}
|
||||
flock($lockFp, LOCK_UN);
|
||||
fclose($lockFp);
|
||||
@unlink($lockFile);
|
||||
return $jsFiles;
|
||||
} catch (Exception $e) {
|
||||
my_logger("Error rebuilding JS cache: " . $e->getMessage());
|
||||
flock($lockFp, LOCK_UN);
|
||||
fclose($lockFp);
|
||||
@unlink($lockFile);
|
||||
return findJsFiles($directory);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: unable to lock, generate without caching
|
||||
if ($lockFp) {
|
||||
fclose($lockFp);
|
||||
}
|
||||
return findJsFiles($directory);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -2,27 +2,6 @@
|
||||
* This CSS is specifically for overwriting CSS libraries that dynamix.js uses
|
||||
*/
|
||||
:root {
|
||||
--dynamix-jgrowl-bg-color: var(--gray-500);
|
||||
--dynamix-jgrowl-border-color: var(--gray-600);
|
||||
--dynamix-jgrowl-shadow-color: var(--gray-500);
|
||||
--dynamix-jgrowl-text-color: var(--gray-600);
|
||||
|
||||
--dynamix-jgrowl-alert-bg-color: var(--red-300);
|
||||
--dynamix-jgrowl-alert-border-color: var(--red-600);
|
||||
--dynamix-jgrowl-alert-text-color: var(--red-600);
|
||||
|
||||
--dynamix-jgrowl-warning-bg-color: var(--yellow-200);
|
||||
--dynamix-jgrowl-warning-border-color: var(--orange-300);
|
||||
--dynamix-jgrowl-warning-text-color: var(--orange-300);
|
||||
|
||||
--dynamix-jgrowl-normal-bg-color: var(--green-100);
|
||||
--dynamix-jgrowl-normal-border-color: var(--green-800);
|
||||
--dynamix-jgrowl-normal-text-color: var(--green-800);
|
||||
|
||||
--dynamix-jgrowl-close-text-color: var(--gray-500);
|
||||
--dynamix-jgrowl-close-bg-color: var(--black);
|
||||
--dynamix-jgrowl-close-border: 2px solid var(--gray-300);
|
||||
|
||||
--dynamix-ui-dropdownchecklist-color: var(--gray-100);
|
||||
--dynamix-ui-dropdownchecklist-color-alt1: var(--gray-700);
|
||||
--dynamix-ui-dropdownchecklist-color-alt2: var(--gray-500);
|
||||
@@ -89,132 +68,6 @@
|
||||
--dynamix-awesomplete-mark-selected-bg-color: var(--green-900);
|
||||
}
|
||||
|
||||
.jGrowl {
|
||||
position: fixed;
|
||||
font-size: 1.3rem;
|
||||
z-index: 10001;
|
||||
}
|
||||
.jGrowl.top-left {
|
||||
left: 10px;
|
||||
top: 130px;
|
||||
}
|
||||
.jGrowl.top-right {
|
||||
right: 10px;
|
||||
top: 130px;
|
||||
}
|
||||
.jGrowl.bottom-left {
|
||||
left: 10px;
|
||||
bottom: 24px;
|
||||
}
|
||||
.jGrowl.bottom-right {
|
||||
right: 10px;
|
||||
bottom: 24px;
|
||||
}
|
||||
.jGrowl.center {
|
||||
top: 130px;
|
||||
left: 40%;
|
||||
}
|
||||
.jGrowl.center .jGrowl-closer,
|
||||
.jGrowl.center .jGrowl-notification {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.jGrowl-notification {
|
||||
opacity: 0.96;
|
||||
min-height: 1.2rem;
|
||||
width: 380px;
|
||||
padding: 10px;
|
||||
margin: 5px 0;
|
||||
text-align: left;
|
||||
border-radius: 6px;
|
||||
|
||||
&.alert {
|
||||
color: var(--dynamix-jgrowl-alert-text-color);
|
||||
background-color: var(--dynamix-jgrowl-alert-bg-color);
|
||||
border: 1px solid var(--dynamix-jgrowl-alert-border-color);
|
||||
box-shadow: 2px 2px 1px var(--dynamix-jgrowl-shadow-color);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
color: var(--dynamix-jgrowl-warning-text-color);
|
||||
background-color: var(--dynamix-jgrowl-warning-bg-color);
|
||||
border: 1px solid var(--dynamix-jgrowl-warning-border-color);
|
||||
box-shadow: 2px 2px 1px var(--dynamix-jgrowl-shadow-color);
|
||||
}
|
||||
|
||||
&.normal {
|
||||
color: var(--dynamix-jgrowl-normal-text-color);
|
||||
background-color: var(--dynamix-jgrowl-normal-bg-color);
|
||||
border: 1px solid var(--dynamix-jgrowl-normal-border-color);
|
||||
box-shadow: 2px 2px 1px var(--dynamix-jgrowl-shadow-color);
|
||||
}
|
||||
|
||||
&.default {
|
||||
color: var(--dynamix-jgrowl-text-color);
|
||||
background-color: var(--dynamix-jgrowl-bg-color);
|
||||
border: 1px solid var(--dynamix-jgrowl-border-color);
|
||||
box-shadow: 2px 2px 1px var(--dynamix-jgrowl-shadow-color);
|
||||
}
|
||||
}
|
||||
.jGrowl-notification .jGrowl-header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.jGrowl-notification .jGrowl-close {
|
||||
float: right;
|
||||
text-align: right;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.8rem;
|
||||
min-width: auto;
|
||||
margin-left: 2rem;
|
||||
line-height: 1;
|
||||
}
|
||||
.jGrowl-notification .jGrowl-close:hover {
|
||||
color: inherit;
|
||||
background: none;
|
||||
}
|
||||
.jGrowl-closer {
|
||||
width: 400px;
|
||||
color: var(--dynamix-jgrowl-close-text-color);
|
||||
background-color: var(--dynamix-jgrowl-close-bg-color);
|
||||
opacity: 0.96;
|
||||
border: 2px solid var(--dynamix-jgrowl-close-border-color);
|
||||
margin: 5px 0;
|
||||
padding: 4px 0;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.jGrowl-closer.top {
|
||||
position: fixed;
|
||||
top: 130px;
|
||||
}
|
||||
#jGrowl {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
.jGrowl-notification:first-of-type {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
.jGrowl-notification {
|
||||
pointer-events: all !important;
|
||||
}
|
||||
.jGrowl-closer.top {
|
||||
pointer-events: all !important;
|
||||
}
|
||||
.jGrowl-closer.bottom {
|
||||
pointer-events: all !important;
|
||||
}
|
||||
@media print {
|
||||
.jGrowl {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#sb-info-inner,
|
||||
#sb-loading-inner,
|
||||
div.sb-message {
|
||||
@@ -1507,18 +1360,6 @@ div.icon-zip {
|
||||
* @see https://caniuse.com/?search=nesting
|
||||
*/
|
||||
.Theme--sidebar {
|
||||
.jGrowl.top-left {
|
||||
top: 90px;
|
||||
}
|
||||
.jGrowl.top-right {
|
||||
top: 90px;
|
||||
}
|
||||
.jGrowl.center {
|
||||
top: 90px;
|
||||
}
|
||||
.jGrowl-notification {
|
||||
min-height: 4rem;
|
||||
}
|
||||
table.tablesorter thead tr th {
|
||||
font-size: 1.3rem;
|
||||
padding: 5px 20px 5px 6px;
|
||||
|
||||
Reference in New Issue
Block a user