ui: CHANGE icons in frontend #31
This commit is contained in:
parent
082a9f81d7
commit
8dbe149970
1 changed files with 24 additions and 19 deletions
43
app.py
43
app.py
|
|
@ -207,10 +207,12 @@ HTML = """<!doctype html>
|
||||||
header { display:flex; justify-content:space-between; align-items:center; margin-bottom: .5rem; flex-shrink: 0; }
|
header { display:flex; justify-content:space-between; align-items:center; margin-bottom: .5rem; flex-shrink: 0; }
|
||||||
a,button { padding:.35rem 0; text-decoration:none; border:1px solid var(--border); border-radius:4px; background:var(--btn-bg); color:var(--text); cursor:pointer; font-size:.9rem; font-weight:bold; min-width:2rem; text-align:center; display:inline-block; }
|
a,button { padding:.35rem 0; text-decoration:none; border:1px solid var(--border); border-radius:4px; background:var(--btn-bg); color:var(--text); cursor:pointer; font-size:.9rem; font-weight:bold; min-width:2rem; text-align:center; display:inline-block; }
|
||||||
a:hover,button:hover { background:var(--btn-hover); }
|
a:hover,button:hover { background:var(--btn-hover); }
|
||||||
#lock-btn { font-weight:normal; }
|
/* Icon buttons: inline SVG so glyphs render the same on every platform */
|
||||||
|
.ibtn { display:inline-flex; align-items:center; justify-content:center; width:2rem; height:2rem; padding:0; }
|
||||||
|
.ic { width:1.05rem; height:1.05rem; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; pointer-events:none; }
|
||||||
#status { font-size:.9rem; opacity:.7; margin-left:.5rem; }
|
#status { font-size:.9rem; opacity:.7; margin-left:.5rem; }
|
||||||
#status::before { content: "●"; margin-right: .3rem; color: #ef4444; }
|
#status::before { content:""; display:inline-block; width:.55em; height:.55em; border-radius:50%; margin-right:.35rem; background:#ef4444; }
|
||||||
#status.connected::before { color: #22c55e; }
|
#status.connected::before { background:#22c55e; }
|
||||||
#peers { font-size:.95rem; font-weight:bold; margin-left:.5rem; margin-right:.3rem; color:#22c55e; display:none; }
|
#peers { font-size:.95rem; font-weight:bold; margin-left:.5rem; margin-right:.3rem; color:#22c55e; display:none; }
|
||||||
#wrap { display:grid; grid-template-columns: max-content 1fr; border:1px solid var(--border); border-radius:4px; overflow:hidden;
|
#wrap { display:grid; grid-template-columns: max-content 1fr; border:1px solid var(--border); border-radius:4px; overflow:hidden;
|
||||||
flex: 1; }
|
flex: 1; }
|
||||||
|
|
@ -243,16 +245,25 @@ HTML = """<!doctype html>
|
||||||
#auth-submit { width:100%; padding:.45rem; background:#000; color:#fff; border:none;
|
#auth-submit { width:100%; padding:.45rem; background:#000; color:#fff; border:none;
|
||||||
border-radius:4px; font-size:.95rem; cursor:pointer; }
|
border-radius:4px; font-size:.95rem; cursor:pointer; }
|
||||||
</style>
|
</style>
|
||||||
|
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false"><defs>
|
||||||
|
<symbol id="i-copy" viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></symbol>
|
||||||
|
<symbol id="i-check" viewBox="0 0 24 24"><path d="M20 6 9 17l-5-5"/></symbol>
|
||||||
|
<symbol id="i-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></symbol>
|
||||||
|
<symbol id="i-lock" viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></symbol>
|
||||||
|
<symbol id="i-moon" viewBox="0 0 24 24"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></symbol>
|
||||||
|
<symbol id="i-sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M6.3 17.7l-1.4 1.4M19.1 4.9l-1.4 1.4"/></symbol>
|
||||||
|
<symbol id="i-info" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></symbol>
|
||||||
|
</defs></svg>
|
||||||
<header>
|
<header>
|
||||||
<div>
|
<div>
|
||||||
<strong id="padname"></strong><span id="peers"></span><span id="status">disconnected</span>
|
<strong id="padname"></strong><span id="peers"></span><span id="status">disconnected</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="position:relative; display:flex; align-items:center; gap:.25rem;">
|
<div style="position:relative; display:flex; align-items:center; gap:.25rem;">
|
||||||
<button id="copy" onclick="copyToClipboard()" title="Copy to clipboard">⧉</button>
|
<button id="copy" class="ibtn" onclick="copyToClipboard()" title="Copy to clipboard" aria-label="Copy to clipboard"><svg class="ic"><use href="#i-copy"/></svg></button>
|
||||||
<a id="newpad" href="/" target="_blank" title="Opens a new pad in a new tab">+</a>
|
<a id="newpad" class="ibtn" href="/" target="_blank" title="Opens a new pad in a new tab" aria-label="New pad"><svg class="ic"><use href="#i-plus"/></svg></a>
|
||||||
<button id="lock-btn" onclick="togglePwPanel()" title="No password – click to set one">🔒︎</button>
|
<button id="lock-btn" class="ibtn" onclick="togglePwPanel()" title="No password – click to set one"><svg class="ic"><use href="#i-lock"/></svg></button>
|
||||||
<button id="theme-btn" onclick="toggleTheme()" title="Toggle dark/light mode">☾</button>
|
<button id="theme-btn" class="ibtn" onclick="toggleTheme()" title="Toggle dark/light mode" aria-label="Toggle dark/light mode"><svg class="ic"><use href="#i-moon"/></svg></button>
|
||||||
<a id="info" href="/system/info" title="System info">ⓘ</a>
|
<a id="info" class="ibtn" href="/system/info" title="System info" aria-label="System info"><svg class="ic"><use href="#i-info"/></svg></a>
|
||||||
<div id="pw-panel">
|
<div id="pw-panel">
|
||||||
<label>Password protection</label>
|
<label>Password protection</label>
|
||||||
<input id="pw-input" type="password" placeholder="New password…" onkeydown="if(event.key==='Enter')setPassword()"/>
|
<input id="pw-input" type="password" placeholder="New password…" onkeydown="if(event.key==='Enter')setPassword()"/>
|
||||||
|
|
@ -282,6 +293,7 @@ HTML = """<!doctype html>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const $ = s => document.querySelector(s);
|
const $ = s => document.querySelector(s);
|
||||||
|
const setIcon = (el, name) => el.querySelector("use").setAttribute("href", "#i-" + name);
|
||||||
const proto = location.protocol === "https:" ? "wss" : "ws";
|
const proto = location.protocol === "https:" ? "wss" : "ws";
|
||||||
const rand = () => {
|
const rand = () => {
|
||||||
const arr = new Uint8Array(8);
|
const arr = new Uint8Array(8);
|
||||||
|
|
@ -293,7 +305,7 @@ const rand = () => {
|
||||||
// Theme
|
// Theme
|
||||||
function applyTheme(dark) {
|
function applyTheme(dark) {
|
||||||
document.documentElement.setAttribute('data-theme', dark ? 'dark' : 'light');
|
document.documentElement.setAttribute('data-theme', dark ? 'dark' : 'light');
|
||||||
$('#theme-btn').textContent = dark ? '☀' : '☾';
|
setIcon($('#theme-btn'), dark ? 'sun' : 'moon');
|
||||||
}
|
}
|
||||||
function toggleTheme() {
|
function toggleTheme() {
|
||||||
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||||
|
|
@ -376,11 +388,9 @@ function removePassword() {
|
||||||
function updateLockBtn() {
|
function updateLockBtn() {
|
||||||
const btn = $("#lock-btn");
|
const btn = $("#lock-btn");
|
||||||
if (isProtected) {
|
if (isProtected) {
|
||||||
btn.textContent = "🔒︎";
|
|
||||||
btn.classList.add("locked");
|
btn.classList.add("locked");
|
||||||
btn.title = "Password protected – click to manage";
|
btn.title = "Password protected – click to manage";
|
||||||
} else {
|
} else {
|
||||||
btn.textContent = "🔒︎";
|
|
||||||
btn.classList.remove("locked");
|
btn.classList.remove("locked");
|
||||||
btn.title = "No password – click to set one";
|
btn.title = "No password – click to set one";
|
||||||
}
|
}
|
||||||
|
|
@ -478,19 +488,14 @@ $("#newpad").addEventListener("click", (e) => { e.preventDefault(); window.open(
|
||||||
async function copyToClipboard() {
|
async function copyToClipboard() {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(ta.value);
|
await navigator.clipboard.writeText(ta.value);
|
||||||
const btn = $("#copy");
|
|
||||||
const original = btn.textContent;
|
|
||||||
btn.textContent = "✓";
|
|
||||||
setTimeout(() => { btn.textContent = original; }, 1500);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Fallback for older browsers
|
// Fallback for older browsers
|
||||||
ta.select();
|
ta.select();
|
||||||
document.execCommand('copy');
|
document.execCommand('copy');
|
||||||
const btn = $("#copy");
|
|
||||||
const original = btn.textContent;
|
|
||||||
btn.textContent = "✓";
|
|
||||||
setTimeout(() => { btn.textContent = original; }, 1500);
|
|
||||||
}
|
}
|
||||||
|
const btn = $("#copy");
|
||||||
|
setIcon(btn, "check");
|
||||||
|
setTimeout(() => setIcon(btn, "copy"), 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust cursor position after a remote text update.
|
// Adjust cursor position after a remote text update.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue