mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-29 12:51:49 +08:00
335 lines
12 KiB
Plaintext
335 lines
12 KiB
Plaintext
{#
|
|
Copyright 2008 Steven Barth <steven@midlink.org>
|
|
Copyright 2012 David Menting <david@nut-bolt.nl>
|
|
Copyright 2008-2022 Jo-Philipp Wich <jo@mein.io>
|
|
Licensed to the public under the Apache License 2.0.
|
|
-#}
|
|
|
|
{%
|
|
import { getuid, getspnam } from 'luci.core';
|
|
|
|
const boardinfo = ubus.call('system', 'board');
|
|
|
|
http.prepare_content('text/html; charset=UTF-8');
|
|
-%}
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="{{ dispatcher.lang }}">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>{{ striptags(`${boardinfo.hostname ?? '?'}${dispatched?.title ? ` | ${_(dispatched.title)}` : ''}`) }}</title>
|
|
<script>
|
|
(function() {
|
|
var mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'),
|
|
modeKey = 'material3-mode-debug',
|
|
themeKey = 'material3-theme-debug',
|
|
rootElement = document.documentElement,
|
|
themeColors = {
|
|
'baseline': '#ADA4BB',
|
|
'blue': '#9EA9BA',
|
|
'green': '#9DAD9C',
|
|
'teal': '#96ADAC',
|
|
'orange': '#C0A48B',
|
|
'vivid-orange': '#C5A190',
|
|
'sakura': '#C4A09B',
|
|
'rose': '#C0A0A7',
|
|
'gray': '#B4B4B7'
|
|
};
|
|
|
|
var updateFavicon = function() {
|
|
var theme = rootElement.getAttribute('data-theme') || 'baseline',
|
|
container = themeColors[theme] || themeColors['baseline'],
|
|
svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="50" fill="' + container + '"/><path fill="#fff" d="M75.26 51.66H24.74a9.18 9.18 0 0 0-9.18 9.18v4.6a9.18 9.18 0 0 0 9.18 9.18h50.52a9.18 9.18 0 0 0 9.18-9.18v-4.6a9.18 9.18 0 0 0-9.18-9.18zM59.18 68.88a5.17 5.17 0 1 1 5.17-5.17 5.17 5.17 0 0 1-5.17 5.17zm13.2 0a5.17 5.17 0 1 1 5.17-5.17 5.17 5.17 0 0 1-5.16 5.17zM29.34 30.72c6.9-6.62 14.06-9.83 21.59-9.83s15.04 3.44 21.9 10.24a3.44 3.44 0 1 0 4.73-4.9C69.6 18.26 60.33 14 50.92 14s-18.33 4.06-26.18 11.78a3.44 3.44 0 0 0 4.6 4.94zm3.29 8.1a3.44 3.44 0 0 0 4.59 5.03c8.77-8.17 18.78-7.97 27.4.37a3.44 3.44 0 1 0 4.8-4.96 26.96 26.96 0 0 0-18.5-8.27 26.75 26.75 0 0 0-18.2 7.83h-.1z"/></svg>',
|
|
href = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
|
|
|
|
document.querySelectorAll('link[rel="icon"]').forEach(function(link) {
|
|
if (link.href !== href) {
|
|
var newLink = link.cloneNode();
|
|
newLink.href = href;
|
|
link.parentNode.replaceChild(newLink, link);
|
|
}
|
|
});
|
|
document.querySelectorAll('img.material3-logo').forEach(function(img) {
|
|
if (img.src !== href) img.src = href;
|
|
});
|
|
};
|
|
|
|
var setDarkMode = function(match) {
|
|
var mode = localStorage.getItem(modeKey);
|
|
|
|
if (mode == 'light' || mode == 'dark') {
|
|
rootElement.setAttribute('data-mode', mode);
|
|
rootElement.setAttribute('data-darkmode', mode == 'dark' ? 'true' : 'false');
|
|
}
|
|
else {
|
|
rootElement.removeAttribute('data-mode');
|
|
rootElement.setAttribute('data-darkmode', match.matches ? 'true' : 'false');
|
|
}
|
|
};
|
|
|
|
window.material3ApplyColorMode = setDarkMode;
|
|
window.material3UpdateFavicon = updateFavicon;
|
|
|
|
mediaQuery.addEventListener('change', setDarkMode);
|
|
setDarkMode(mediaQuery);
|
|
|
|
var savedTheme = localStorage.getItem(themeKey);
|
|
if (savedTheme) {
|
|
rootElement.setAttribute('data-theme', savedTheme);
|
|
}
|
|
|
|
window.addEventListener('load', function() {
|
|
updateFavicon();
|
|
var observer = new MutationObserver(function(mutations) {
|
|
mutations.forEach(function(m) {
|
|
if (m.attributeName === 'data-theme') updateFavicon();
|
|
});
|
|
});
|
|
observer.observe(rootElement, { attributes: true, attributeFilter: ['data-theme'] });
|
|
});
|
|
})();
|
|
</script>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="darkreader-lock">
|
|
<link rel="stylesheet" href="{{ media }}/cascade.css">
|
|
<link rel="stylesheet" media="only screen and (max-device-width: 854px)" href="{{ media }}/mobile.css" />
|
|
<link rel="icon" href="{{ media }}/logo.svg" sizes="any">
|
|
{% if (node?.css): %}
|
|
<link rel="stylesheet" href="{{ resource }}/{{ node.css }}">
|
|
{% endif %}
|
|
{% if (css): %}
|
|
<style title="text/css">{{ css }}</style>
|
|
{% endif %}
|
|
<script src="{{ dispatcher.build_url('admin/translations', dispatcher.lang) }}"></script>
|
|
<script src="{{ resource }}/cbi.js"></script>
|
|
<style>
|
|
#material3-debug-switcher {
|
|
position: fixed;
|
|
right: 16px;
|
|
bottom: 16px;
|
|
z-index: 1200;
|
|
font: 12px/1 var(--font-sans);
|
|
}
|
|
|
|
#material3-debug-switcher > button {
|
|
width: 42px;
|
|
height: 42px;
|
|
border-radius: 50%;
|
|
border: 1px solid var(--border-color-medium);
|
|
background: var(--primary-color-high);
|
|
color: var(--on-primary-color);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, .22);
|
|
}
|
|
|
|
#material3-debug-switcher > button::before {
|
|
content: '';
|
|
display: block;
|
|
width: 20px;
|
|
height: 20px;
|
|
margin: auto;
|
|
background: currentColor;
|
|
-webkit-mask: url("{{ media }}/icons/palette.svg") center/contain no-repeat;
|
|
mask: url("{{ media }}/icons/palette.svg") center/contain no-repeat;
|
|
}
|
|
|
|
#material3-debug-switcher > div {
|
|
position: absolute;
|
|
right: 0;
|
|
bottom: 50px;
|
|
display: none;
|
|
grid-template-columns: repeat(3, 30px);
|
|
gap: 8px;
|
|
padding: 10px;
|
|
border: 1px solid var(--border-color-medium);
|
|
border-radius: 12px;
|
|
background: var(--background-color-high);
|
|
box-shadow: 0 4px 18px rgba(0, 0, 0, .22);
|
|
}
|
|
|
|
#material3-debug-switcher[open] > div {
|
|
display: grid;
|
|
}
|
|
|
|
#material3-debug-switcher button[data-theme],
|
|
#material3-debug-switcher button[data-mode] {
|
|
width: 30px;
|
|
height: 30px;
|
|
border: 1px solid var(--border-color-medium);
|
|
border-radius: 50%;
|
|
background: var(--debug-color, var(--background-color-low));
|
|
color: var(--text-color-high);
|
|
box-shadow: inset 0 0 0 3px var(--background-color-high);
|
|
}
|
|
|
|
#material3-debug-switcher button[aria-pressed="true"] {
|
|
border-color: var(--primary-color-high);
|
|
box-shadow: inset 0 0 0 3px var(--background-color-high), 0 0 0 3px color-mix(in srgb, var(--primary-color-high) 30%, transparent);
|
|
}
|
|
|
|
#material3-debug-switcher button[data-mode] {
|
|
position: relative;
|
|
font-size: 0;
|
|
}
|
|
|
|
#material3-debug-switcher button[data-mode]::before {
|
|
content: '';
|
|
position: absolute;
|
|
inset: 0;
|
|
width: 18px;
|
|
height: 18px;
|
|
margin: auto;
|
|
background: currentColor;
|
|
-webkit-mask: var(--debug-mode-icon) center/contain no-repeat;
|
|
mask: var(--debug-mode-icon) center/contain no-repeat;
|
|
}
|
|
|
|
#material3-debug-switcher button[data-mode="light"] {
|
|
--debug-mode-icon: url("{{ media }}/icons/sun.svg");
|
|
}
|
|
|
|
#material3-debug-switcher button[data-mode="dark"] {
|
|
--debug-mode-icon: url("{{ media }}/icons/moon.svg");
|
|
}
|
|
|
|
#material3-debug-switcher button[data-mode="auto"] {
|
|
--debug-mode-icon: url("{{ media }}/icons/auto.svg");
|
|
}
|
|
</style>
|
|
<script>
|
|
(function() {
|
|
var root = document.documentElement,
|
|
themeKey = 'material3-theme-debug',
|
|
modeKey = 'material3-mode-debug',
|
|
savedTheme = localStorage.getItem(themeKey);
|
|
|
|
if (savedTheme)
|
|
root.setAttribute('data-theme', savedTheme);
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
if (!window.L || !L.env || L.env.requestpath.join('/') != 'admin/system/system')
|
|
return;
|
|
|
|
var themes = [
|
|
['baseline', '#6750A4'],
|
|
['blue', '#0061A4'],
|
|
['green', '#006D3A'],
|
|
['teal', '#006A6A'],
|
|
['orange', '#8F4C00'],
|
|
['vivid-orange', '#E85D04'],
|
|
['sakura', '#BB1614'],
|
|
['rose', '#BA1A46'],
|
|
['gray', '#3F3F46']
|
|
];
|
|
var switcher = document.createElement('div'),
|
|
toggle = document.createElement('button'),
|
|
panel = document.createElement('div');
|
|
|
|
switcher.id = 'material3-debug-switcher';
|
|
toggle.type = 'button';
|
|
toggle.title = 'Material3 debug switcher';
|
|
toggle.setAttribute('aria-label', 'Material3 debug switcher');
|
|
toggle.addEventListener('click', function() {
|
|
switcher.toggleAttribute('open');
|
|
});
|
|
|
|
function setPressed() {
|
|
var theme = root.getAttribute('data-theme') || 'baseline',
|
|
mode = localStorage.getItem(modeKey) || 'auto';
|
|
|
|
panel.querySelectorAll('[data-theme]').forEach(function(button) {
|
|
button.setAttribute('aria-pressed', button.getAttribute('data-theme') == theme ? 'true' : 'false');
|
|
});
|
|
|
|
panel.querySelectorAll('[data-mode]').forEach(function(button) {
|
|
button.setAttribute('aria-pressed', button.getAttribute('data-mode') == mode ? 'true' : 'false');
|
|
});
|
|
}
|
|
|
|
themes.forEach(function(item) {
|
|
var button = document.createElement('button');
|
|
button.type = 'button';
|
|
button.title = item[0];
|
|
button.setAttribute('data-theme', item[0]);
|
|
button.style.setProperty('--debug-color', item[1]);
|
|
button.addEventListener('click', function() {
|
|
root.setAttribute('data-theme', item[0]);
|
|
localStorage.setItem(themeKey, item[0]);
|
|
setPressed();
|
|
});
|
|
panel.appendChild(button);
|
|
});
|
|
|
|
['auto', 'light', 'dark'].forEach(function(mode) {
|
|
var button = document.createElement('button');
|
|
button.type = 'button';
|
|
button.title = mode;
|
|
button.setAttribute('aria-label', mode);
|
|
button.setAttribute('data-mode', mode);
|
|
button.addEventListener('click', function() {
|
|
if (mode == 'auto')
|
|
localStorage.removeItem(modeKey);
|
|
else
|
|
localStorage.setItem(modeKey, mode);
|
|
|
|
if (window.material3ApplyColorMode)
|
|
window.material3ApplyColorMode(window.matchMedia('(prefers-color-scheme: dark)'));
|
|
|
|
setPressed();
|
|
});
|
|
panel.appendChild(button);
|
|
});
|
|
|
|
switcher.append(toggle, panel);
|
|
document.body.appendChild(switcher);
|
|
setPressed();
|
|
});
|
|
})();
|
|
</script>
|
|
</head>
|
|
|
|
<body class="lang_{{ dispatcher.lang }} {{ entityencode(striptags(node?.title ?? ''), true) }}" data-page="{{ entityencode(join('-', ctx.request_path), true) }}">
|
|
{% if (!blank_page): %}
|
|
<header>
|
|
<button class="menu-btn" type="button" aria-label="{{ _('Toggle navigation menu') }}" aria-expanded="false">
|
|
<span></span>
|
|
</button>
|
|
<a class="brand" href="/">{{ striptags(boardinfo.hostname ?? '?') }}</a>
|
|
<div id="indicators" class="pull-right"></div>
|
|
</header>
|
|
|
|
<aside class="sidebar" aria-label="{{ _('Navigation') }}">
|
|
<ul class="nav" id="topmenu" style="display:none"></ul>
|
|
</aside>
|
|
<div class="sidebar-overlay"></div>
|
|
|
|
<div id="maincontent" class="container">
|
|
{% if (getuid() == 0 && getspnam('root')?.pwdp === ''): %}
|
|
<div class="alert-message warning">
|
|
<h4>{{ _('No password set!') }}</h4>
|
|
<p>{{ _('There is no password set on this router. Please configure a root password to protect the web interface.') }}</p>
|
|
{% if (dispatcher.lookup("admin/system/admin")): %}
|
|
<div class="right"><a class="btn" href="{{ dispatcher.build_url("admin/system/admin") }}">{{ _('Go to password configuration...') }}</a></div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if (boardinfo.rootfs_type == "initramfs"): %}
|
|
<div class="alert-message warning">
|
|
<h4>{{ _('System running in recovery (initramfs) mode.') }}</h4>
|
|
<p>{{ _('No changes to settings will be stored and are lost after rebooting. This mode should only be used to install a firmware upgrade') }}</p>
|
|
{% if (dispatcher.lookup("admin/system/flash")): %}
|
|
<div class="right"><a class="btn" href="{{ dispatcher.build_url("admin/system/flash") }}">{{ _('Go to firmware upgrade...') }}</a></div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<noscript>
|
|
<div class="alert-message warning">
|
|
<h4>{{ _('JavaScript required!') }}</h4>
|
|
<p>{{ _('You must enable JavaScript in your browser or LuCI will not work properly.') }}</p>
|
|
</div>
|
|
</noscript>
|
|
|
|
<div id="tabmenu" style="display:none"></div>
|
|
{% endif %}
|