modified: templates/itemeditor_command_storage.html
This commit is contained in:
@@ -77,6 +77,12 @@
|
||||
<i class="fas fa-plus"></i> Store Another Command
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Recently Stored Commands Section -->
|
||||
<div id="recentCommandsSection" class="recent-commands-section" style="margin-top:2.5rem;">
|
||||
<h3 style="color:#00d4ff; margin-bottom:1rem;">Recently Stored Commands</h3>
|
||||
<div id="recentCommandsList" class="recent-commands-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right: Info & Stats -->
|
||||
@@ -436,6 +442,51 @@ if (isset($_GET['id'])) {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.recent-commands-section {
|
||||
background: #181818;
|
||||
border:1px solid #232323;
|
||||
border-radius: 14px;
|
||||
padding: 1.5rem;
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
.recent-commands-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.2rem;
|
||||
}
|
||||
.recent-command-card {
|
||||
background: #222;
|
||||
border-radius: 10px;
|
||||
padding: 1rem 1.2rem;
|
||||
}
|
||||
.recent-command-row {
|
||||
display: flex;
|
||||
gap: .7rem;
|
||||
align-items: center;
|
||||
margin-bottom: .3rem;
|
||||
}
|
||||
.recent-command-label {
|
||||
color: #00d4ff;
|
||||
font-size: .95rem;
|
||||
min-width: 80px;
|
||||
}
|
||||
.recent-command-value {
|
||||
color: #fff;
|
||||
font-size: .97rem;
|
||||
}
|
||||
.recent-command-link {
|
||||
color: #00ffa6;
|
||||
font-size: .97rem;
|
||||
word-break: break-all;
|
||||
}
|
||||
.recent-command-timer {
|
||||
color: #ffaa00;
|
||||
font-size: .97rem;
|
||||
}
|
||||
.recent-command-text {
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.storage-grid {
|
||||
grid-template-columns: 1fr;
|
||||
@@ -541,6 +592,8 @@ function resetForm() {
|
||||
charStatus.textContent = '';
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = '<i class="fas fa-save"></i> Store Command';
|
||||
document.getElementById('generatedLink').value = '';
|
||||
document.getElementById('expiryTime').textContent = '30 minutes';
|
||||
}
|
||||
|
||||
function startCountdown(expiresAt) {
|
||||
@@ -573,5 +626,112 @@ function startCountdown(expiresAt) {
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// --- Recent Commands Storage (localStorage) ---
|
||||
function getRecentCommands() {
|
||||
let cmds = [];
|
||||
try {
|
||||
cmds = JSON.parse(localStorage.getItem('recentCommands') || '[]');
|
||||
} catch {}
|
||||
return Array.isArray(cmds) ? cmds : [];
|
||||
}
|
||||
function setRecentCommands(cmds) {
|
||||
localStorage.setItem('recentCommands', JSON.stringify(cmds));
|
||||
}
|
||||
function addRecentCommand(cmd) {
|
||||
let cmds = getRecentCommands();
|
||||
cmds.unshift(cmd);
|
||||
cmds = cmds.filter(c => c && c.expires_at && new Date(c.expires_at).getTime() > Date.now());
|
||||
if (cmds.length > 5) cmds = cmds.slice(0,5);
|
||||
setRecentCommands(cmds);
|
||||
}
|
||||
function renderRecentCommands() {
|
||||
const list = document.getElementById('recentCommandsList');
|
||||
const cmds = getRecentCommands();
|
||||
if (!cmds.length) {
|
||||
list.innerHTML = '<div style="color:#888;">No recent commands.</div>';
|
||||
return;
|
||||
}
|
||||
list.innerHTML = '';
|
||||
cmds.forEach((cmd, idx) => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'recent-command-card';
|
||||
div.innerHTML = `
|
||||
<div class="recent-command-row">
|
||||
<span class="recent-command-label">Command:</span>
|
||||
<span class="recent-command-value recent-command-text">${cmd.command.length > 60 ? cmd.command.slice(0,60)+'...' : cmd.command}</span>
|
||||
</div>
|
||||
<div class="recent-command-row">
|
||||
<span class="recent-command-label">Link:</span>
|
||||
<a href="${cmd.url}" target="_blank" class="recent-command-link">${cmd.url}</a>
|
||||
</div>
|
||||
<div class="recent-command-row">
|
||||
<span class="recent-command-label">Expires in:</span>
|
||||
<span class="recent-command-timer" id="recent-timer-${idx}"></span>
|
||||
</div>
|
||||
`;
|
||||
list.appendChild(div);
|
||||
startRecentCountdown(cmd.expires_at, `recent-timer-${idx}`, cmd.url);
|
||||
});
|
||||
}
|
||||
function startRecentCountdown(expiresAt, elemId, url) {
|
||||
const el = document.getElementById(elemId);
|
||||
function update() {
|
||||
const now = Date.now();
|
||||
const end = new Date(expiresAt).getTime();
|
||||
const dist = end - now;
|
||||
if (dist < 0) {
|
||||
el.innerHTML = '<span style="color:#ff5555;">Expired</span>';
|
||||
// Remove from localStorage
|
||||
let cmds = getRecentCommands().filter(c => c.url !== url);
|
||||
setRecentCommands(cmds);
|
||||
renderRecentCommands();
|
||||
return false;
|
||||
}
|
||||
const m = Math.floor((dist % (1000*60*60))/(1000*60));
|
||||
const s = Math.floor((dist % (1000*60))/1000);
|
||||
el.textContent = `${m}m ${s}s`;
|
||||
return true;
|
||||
}
|
||||
if (!update()) return;
|
||||
const interval = setInterval(() => {
|
||||
if (!update()) clearInterval(interval);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// On page load
|
||||
renderRecentCommands();
|
||||
|
||||
// On successful store, add to recent
|
||||
const origSuccessHandler = function(data) {
|
||||
addRecentCommand({
|
||||
command: textarea.value.trim(),
|
||||
url: data.url,
|
||||
expires_at: data.expires_at
|
||||
});
|
||||
renderRecentCommands();
|
||||
};
|
||||
|
||||
// Patch the form submit handler to call origSuccessHandler
|
||||
const origSubmit = commandForm.onsubmit;
|
||||
commandForm.onsubmit = function(e) {
|
||||
if (origSubmit) origSubmit.call(this, e);
|
||||
};
|
||||
|
||||
// Patch the fetch success in the submit handler
|
||||
const origFetch = window.fetch;
|
||||
window.fetch = async function() {
|
||||
const res = await origFetch.apply(this, arguments);
|
||||
if (arguments[0] && arguments[0].toString().includes('/projects/itemeditor/storage')) {
|
||||
try {
|
||||
const clone = res.clone();
|
||||
const data = await clone.json();
|
||||
if (data.success && textarea && textarea.value) {
|
||||
origSuccessHandler(data);
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user