Merge branch 'master' into feat/css3-variables

This commit is contained in:
Zack Spear
2025-03-31 11:44:47 -07:00
305 changed files with 19571 additions and 10862 deletions

View File

@@ -24,6 +24,7 @@ if ($themes2) {
$config = "/boot/config";
$entity = $notify['entity'] & 1 == 1;
$alerts = '/tmp/plugins/my_alerts.txt';
$wlan0 = file_exists('/sys/class/net/wlan0');
// adjust the text color in docker log window
$fgcolor = in_array($theme,['white','azure']) ? '#1c1c1c' : '#f2f2f2';
@@ -87,6 +88,7 @@ html{font-size:<?=$display['font']?>%}
<?
$nchan = ['webGui/nchan/notify_poller','webGui/nchan/session_check'];
if ($wlan0) $nchan[] = 'webGui/nchan/wlan0';
$safemode = _var($var,'safeMode')=='yes';
$tasks = find_pages('Tasks');
$buttons = find_pages('Buttons');
@@ -113,10 +115,14 @@ if (!file_exists($notes)) file_put_contents($notes,shell_exec("$docroot/plugins/
<script>
String.prototype.actionName = function(){return this.split(/[\\/]/g).pop();}
String.prototype.channel = function(){return this.split(':')[1].split(',').findIndex((e)=>/\[\d\]/.test(e));}
NchanSubscriber.prototype.monitor = function(){subscribers.push(this);}
Shadowbox.init({skipSetup:true});
context.init();
// list of nchan subscribers to start/stop at focus change
var subscribers = [];
// server uptime
var uptime = <?=strtok(exec("cat /proc/uptime"),' ')?>;
var expiretime = <?=_var($var,'regTy')=='Trial'||strstr(_var($var,'regTy'),'expired')?_var($var,'regTm2'):0?>;
@@ -210,11 +216,11 @@ function settab(tab) {
$.cookie('one','tab1');
<?endif;?>
<?break;?>
<?case'Cache':case'Data':case'Flash':case'Parity':?>
<?case'Cache':case'Data':case'Device':case'Flash':case'Parity':?>
$.cookie('one',tab);
<?break;?>
<?default:?>
$.cookie(($.cookie('one')==null?'tab':'one'),tab);
$.cookie('one',tab);
<?endswitch;?>
}
function done(key) {
@@ -262,7 +268,7 @@ function openWindow(cmd,title,height,width) {
}
function openTerminal(tag,name,more) {
if (/MSIE|Edge/.test(navigator.userAgent)) {
swal({title:"_(Unsupported Feature)_",text:"_(Sorry, this feature is not supported by MSIE/Edge)_.<br>_(Please try a different browser)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
swal({title:"_(Unsupported Feature)_",text:"_(Sorry, this feature is not supported by MSIE/Edge)_.<br>_(Please try a different browser)_",type:'error',html:true,animation:'none',confirmButtonText:"_(Ok)_"});
return;
}
// open terminal window (run in background)
@@ -419,7 +425,7 @@ function openDone(data) {
if (data == '_DONE_') {
$('div.spinner.fixed').hide();
$('button.confirm').text("<?=_('Done')?>").prop('disabled',false).show();
if ( typeof ca_done_override !== 'undefined' ) {
if (typeof ca_done_override !== 'undefined') {
if (ca_done_override == true) {
$("button.confirm").trigger("click");
ca_done_override = false;
@@ -539,7 +545,7 @@ function hideUpgrade(set) { /** @note can likely be removed, not used in webgui
}
function confirmUpgrade(confirm) {
if (confirm) {
swal({title:"<?=_('Update')?> Unraid OS",text:"<?=_('Do you want to update to the new version')?>?",type:'warning',html:true,showCancelButton:true,closeOnConfirm:false,confirmButtonText:"<?=_('Proceed')?>",cancelButtonText:"<?=_('Cancel')?>"},function(){
swal({title:"<?=_('Update')?> Unraid OS",text:"<?=_('Do you want to update to the new version')?>?",type:'warning',html:true,animation:'none',showCancelButton:true,closeOnConfirm:false,confirmButtonText:"<?=_('Proceed')?>",cancelButtonText:"<?=_('Cancel')?>"},function(){
openPlugin("plugin update unRAIDServer.plg","<?=_('Update')?> Unraid OS");
});
} else {
@@ -592,12 +598,30 @@ function viewHistory() {
}
function flashReport() {
$.post('/webGui/include/Report.php',{cmd:'config'},function(check){
if (check>0) addBannerWarning("<?=_('Your flash drive is corrupted or offline').'. '._('Post your diagnostics in the forum for help').'.'?> <a target='_blank' href='https://docs.unraid.net/unraid-os/manual/changing-the-flash-device'><?=_('See also here')?></a>");
if (check>0) addBannerWarning("<?=_('Your flash drive is corrupted or offline').'. '._('Post your diagnostics in the forum for help').'.'?> <a target='_blank' href='https://docs.unraid.net/go/changing-the-flash-device/'><?=_('See also here')?></a>");
});
}
$(function() {
var tab = $.cookie('one')||$.cookie('tab')||'tab1';
if (tab=='tab0') tab = 'tab'+$('input[name$="tabs"]').length; else if ($('#'+tab).length==0) {initab(); tab = 'tab1';}
let tab;
<?switch ($myPage['name']):?>
<?case'Main':?>
tab = $.cookie('tab')||'tab1';
<?break;?>
<?case'Cache':case'Data':case'Device':case'Flash':case'Parity':?>
tab = $.cookie('one')||'tab1';
<?break;?>
<?default:?>
tab = $.cookie('one')||'tab1';
<?endswitch;?>
/* Check if the tab is 'tab0' */
if (tab === 'tab0') {
/* Set tab to the last available tab based on input[name$="tabs"] length */
tab = 'tab' + $('input[name$="tabs"]').length;
} else if ($('#' + tab).length === 0) {
/* If the tab element does not exist, initialize a tab and set to 'tab1' */
initab();
tab = 'tab1';
}
$('#'+tab).attr('checked', true);
updateTime();
$.jGrowl.defaults.closeTemplate = '<i class="fa fa-close"></i>';
@@ -646,6 +670,7 @@ $.ajaxPrefilter(function(s, orig, xhr){
</div>
<?include "$docroot/plugins/dynamix.my.servers/include/myservers2.php"?>
</div>
<a href="#" class="move_to_end" title="<?=_('Move To End')?>"><i class="fa fa-arrow-circle-down"></i></a>
<a href="#" class="back_to_top" title="<?=_('Back To Top')?>"><i class="fa fa-arrow-circle-up"></i></a>
<?
// Build page menus
@@ -665,7 +690,7 @@ echo "</div>";
echo "<div class='nav-tile right'>";
if (isset($myPage['Lock'])) {
$title = $themes2 ? "" : _('Unlock sortable items');
echo "<div class='nav-item LockButton util'><a 'href='#' class='hand' onclick='LockButton();return false;' title=\"$title\"><b class='icon-u-lock system green-text'></b><span>"._('Unlock sortable items')."</span></a></div>";
echo "<div class='nav-item LockButton util'><a href='#' class='hand' onclick='LockButton();return false;' title=\"$title\"><b class='icon-u-lock system green-text'></b><span>"._('Unlock sortable items')."</span></a></div>";
}
if ($display['usage']) my_usage();
@@ -708,8 +733,7 @@ unset($buttons,$button);
// Build page content
// Reload page every X minutes during extended viewing?
if (isset($myPage['Load']) && $myPage['Load']>0) echo "\n<script>timers.reload = setTimeout(function(){location.reload();},".($myPage['Load']*60000).");</script>\n";
echo "<div class='tabs'>";
if (isset($myPage['Load']) && $myPage['Load']>0) echo "\n<script>timers.reload = setInterval(function(){if (nchanPaused === false)location.reload();},".($myPage['Load']*60000).");</script>\n";echo "<div class='tabs'>";
$tab = 1;
$pages = [];
if (!empty($myPage['text'])) $pages[$myPage['name']] = $myPage;
@@ -812,11 +836,10 @@ default:
echo "<span class='green strong'><i class='fa fa-play-circle'></i> ",_('Array Started'),"</span>$progress"; break;
}
echo "</span></span><span id='countdown'></span><span id='user-notice' class='red-text'></span>";
if ($wlan0) echo "<span id='wlan0' class='grey-text' onclick='wlanSettings()'><i class='fa fa-wifi fa-fw'></i></span>";
echo "<span id='copyright'>Unraid&reg; webGui &copy;2024, Lime Technology, Inc.";
echo " <a href='https://docs.unraid.net/category/manual' target='_blank' title=\""._('Online manual')."\"><i class='fa fa-book'></i> "._('manual')."</a>";
echo "</span>";
// echo "<unraid-theme-switcher current='" . $display['theme'] . "'></unraid-theme-switcher>";
echo "</div>";
echo " <a href='https://docs.unraid.net/go/manual/' target='_blank' title=\""._('Online manual')."\"><i class='fa fa-book'></i> "._('manual')."</a>";
echo "</span></div>";
?>
<script>
// Firefox specific workaround, not needed anymore in firefox version 100 and higher
@@ -917,6 +940,20 @@ defaultPage.on('message', function(msg,meta) {
}
});
<?if ($wlan0):?>
function wlanSettings() {
$.cookie('one','tab<?=count(glob("$docroot/webGui/Eth*.page"))?>');
window.location = '/Settings/NetworkSettings';
}
var nchan_wlan0 = new NchanSubscriber('/sub/wlan0',{subscriber:'websocket'});
nchan_wlan0.on('message', function(msg) {
var wlan = JSON.parse(msg);
$('#wlan0').removeClass().addClass(wlan.color).attr('title',wlan.title);
});
nchan_wlan0.start();
<?endif;?>
var nchan_plugins = new NchanSubscriber('/sub/plugins',{subscriber:'websocket'});
nchan_plugins.on('message', function(data) {
if (!data || openDone(data)) return;
@@ -1028,13 +1065,12 @@ nchan_vmaction.on('message', function(data) {
box.scrollTop(box[0].scrollHeight);
});
var backtotopoffset = 250;
var backtotopduration = 500;
const scrollDuration = 500;
$(window).scroll(function() {
if ($(this).scrollTop() > backtotopoffset) {
$('.back_to_top').fadeIn(backtotopduration);
if ($(this).scrollTop() > 0) {
$('.back_to_top').fadeIn(scrollDuration);
} else {
$('.back_to_top').fadeOut(backtotopduration);
$('.back_to_top').fadeOut(scrollDuration);
}
<?if ($themes1):?>
var top = $('div#header').height()-1; // header height has 1 extra pixel to cover overlap
@@ -1043,9 +1079,16 @@ $(window).scroll(function() {
$('div.upgrade_notice').css($(this).scrollTop() > 24 ? {position:'fixed',top:'0'} : {position:'absolute',top:'24px'});
<?endif;?>
});
$('.move_to_end').click(function(event) {
event.preventDefault();
$('html,body').animate({scrollTop:$(document).height()},scrollDuration);
return false;
});
$('.back_to_top').click(function(event) {
event.preventDefault();
$('html,body').animate({scrollTop:0},backtotopduration);
$('html,body').animate({scrollTop:0},scrollDuration);
return false;
});
@@ -1122,7 +1165,156 @@ $(function() {
});
}
$('form').append($('<input>').attr({type:'hidden', name:'csrf_token', value:csrf_token}));
setInterval(function(){if ($(document).height() > $(window).height()) $('.move_to_end').fadeIn(scrollDuration); else $('.move_to_end').fadeOut(scrollDuration);},250);
});
var gui_pages_available = [];
<?
$gui_pages = glob("/usr/local/emhttp/plugins/*/*.page");
array_walk($gui_pages,function($value,$key){ ?>
gui_pages_available.push('<?=basename($value,".page")?>'); <?
});
?>
function isValidURL(url) {
try {
var ret = new URL(url);
return ret;
} catch (err) {
return false;
}
}
$('body').on('click','a,.ca_href', function(e) {
if ($(this).hasClass('ca_href')) {
var ca_href = true;
var href=$(this).attr('data-href');
var target=$(this).attr('data-target');
} else {
var ca_href = false;
var href = $(this).attr('href');
var target = $(this).attr('target');
}
if (href) {
href = href.trim();
// Sanitize href to prevent XSS
href = href.replace(/[<>"]/g, '');
if (href.match('https?://[^\.]*.(my)?unraid.net/') || href.indexOf('https://unraid.net/') == 0 || href == 'https://unraid.net' || href.indexOf('http://lime-technology.com') == 0) {
if (ca_href) window.open(href,target);
return;
}
if (href !== '#' && href.indexOf('javascript') !== 0) {
var dom = isValidURL(href);
if (dom == false) {
if (href.indexOf('/') == 0) return; // all internal links start with "/"
var baseURLpage = href.split('/');
if (gui_pages_available.includes(baseURLpage[0])) return;
}
if ($(this).hasClass('localURL')) return;
try {
var domainsAllowed = JSON.parse($.cookie('allowedDomains'));
} catch(e) {
var domainsAllowed = new Object();
}
$.cookie('allowedDomains',JSON.stringify(domainsAllowed),{expires:3650}); // rewrite cookie to further extend expiration by 400 days
if (domainsAllowed[dom.hostname]) return;
e.preventDefault();
swal({
title: "<?=_('External Link')?>",
text: "<span title='"+href+"'><?=_('Clicking OK will take you to a 3rd party website not associated with Lime Technology')?><br><br><b>"+href+"<br><br><input id='Link_Always_Allow' type='checkbox'></input><?=_('Always Allow')?> "+dom.hostname+"</span>",
html: true,
animation: 'none',
type: 'warning',
showCancelButton: true,
showConfirmButton: true,
cancelButtonText: "<?=_('Cancel')?>",
confirmButtonText: "<?=_('OK')?>"
},function(isConfirm) {
if (isConfirm) {
if ($('#Link_Always_Allow').is(':checked')) {
domainsAllowed[dom.hostname] = true;
$.cookie('allowedDomains',JSON.stringify(domainsAllowed),{expires:3650});
}
var popupOpen = window.open(href,target);
if (!popupOpen || popupOpen.closed || typeof popupOpen == 'undefined') {
var popupWarning = addBannerWarning("<?=_('Popup Blocked');?>");
setTimeout(function(){removeBannerWarning(popupWarning);},10000);
}
}
});
}
}
});
// Start & stop live updates when window loses focus
var nchanPaused = false;
var blurTimer = false;
$(window).focus(function() {
nchanFocusStart();
});
// Stop nchan on loss of focus
<? if ( $display['liveUpdate'] == "no" ):?>
$(window).blur(function() {
blurTimer = setTimeout(function(){
nchanFocusStop();
},30000);
});
<?endif;?>
document.addEventListener("visibilitychange", (event) => {
<? if ( $display['liveUpdate'] == "no" ):?>
if (document.hidden) {
nchanFocusStop();
}
<?else:?>
if (document.hidden) {
nchanFocusStop();
} else {
nchanFocusStart();
}
<?endif;?>
});
function nchanFocusStart() {
if ( blurTimer !== false ) {
clearTimeout(blurTimer);
blurTimer = false;
}
if (nchanPaused !== false ) {
removeBannerWarning(nchanPaused);
nchanPaused = false;
try {
pageFocusFunction();
} catch(error) {}
subscribers.forEach(function(e) {
e.start();
});
}
}
function nchanFocusStop(banner=true) {
if ( subscribers.length ) {
if ( nchanPaused === false ) {
var newsub = subscribers;
subscribers.forEach(function(e) {
try {
e.stop();
} catch(err) {
newsub.splice(newsub.indexOf(e,1));
}
});
subscribers = newsub;
if ( banner && subscribers.length ) {
nchanPaused = addBannerWarning("<?=_('Live Updates Paused');?>",false,true );
}
}
}
}
</script>
</body>
</html>