feat: implement account archiving system and brand logo upgrade

This commit is contained in:
jason
2026-03-04 00:09:01 +08:00
parent fc4898a9ee
commit 734c99849d
3 changed files with 174 additions and 46 deletions

101
popup.js
View File

@@ -21,6 +21,11 @@ document.addEventListener('DOMContentLoaded', () => {
const goToRegister = document.getElementById('go-to-register');
const goToLogin = document.getElementById('go-to-login');
const logoutBtn = document.getElementById('logout-btn');
const archiveToggle = document.getElementById('archive-toggle');
const backToMain = document.getElementById('back-to-main');
const mainViewContent = document.getElementById('main-view-content');
const archiveViewContent = document.getElementById('archive-view-content');
const archiveList = document.getElementById('archive-list');
if (logoutBtn) {
logoutBtn.addEventListener('click', (e) => {
@@ -294,8 +299,9 @@ document.addEventListener('DOMContentLoaded', () => {
function renderRules() {
rulesList.innerHTML = '';
const activeRules = rules.filter(r => !r.archived);
if (rules.length === 0) {
if (activeRules.length === 0) {
rulesList.innerHTML = `
<div class="empty-state">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
@@ -308,7 +314,7 @@ document.addEventListener('DOMContentLoaded', () => {
return;
}
rules.forEach((rule, index) => {
activeRules.forEach((rule, index) => {
const li = document.createElement('li');
li.className = 'rule-item';
li.setAttribute('draggable', 'true');
@@ -331,8 +337,10 @@ document.addEventListener('DOMContentLoaded', () => {
<path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
</svg>
</button>
<button class="icon-btn btn-delete" data-id="${rule.id}" title="删除此配置">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
<button class="icon-btn btn-delete" data-id="${rule.id}" title="归档此配置">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M20 7l-8 8-4-4m12 4v5a2 2 0 01-2 2H6a2 2 0 01-2-2V9a2 2 0 012-2h5" />
</svg>
</button>
</div>
`;
@@ -341,21 +349,75 @@ document.addEventListener('DOMContentLoaded', () => {
rulesList.appendChild(li);
});
attachRuleEvents();
}
function renderArchive() {
archiveList.innerHTML = '';
const archivedRules = rules.filter(r => r.archived);
if (archivedRules.length === 0) {
archiveList.innerHTML = '<div class="empty-state" style="padding: 20px 0;"><span>暂无归档内容</span></div>';
return;
}
archivedRules.forEach(rule => {
const li = document.createElement('li');
li.className = 'rule-item';
li.innerHTML = `
<div class="rule-info">
<div class="rule-domain">${rule.clientName} <span class="rule-env env-${rule.env.toLowerCase().replace('_', '-')}">${rule.env.replace('_', ' ')}</span></div>
<div class="rule-acc">帐号: ${rule.username}</div>
</div>
<div class="rule-actions">
<button class="icon-btn btn-restore" data-id="${rule.id}" title="恢复到主列表">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
</button>
<button class="icon-btn btn-delete-perm" data-id="${rule.id}" title="彻底删除">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
</button>
</div>
`;
archiveList.appendChild(li);
});
document.querySelectorAll('.btn-restore').forEach(btn => {
btn.addEventListener('click', (e) => {
const id = e.currentTarget.getAttribute('data-id');
const index = rules.findIndex(r => r.id === id);
if (index !== -1) {
rules[index].archived = false;
saveRules();
renderArchive();
}
});
});
document.querySelectorAll('.btn-delete-perm').forEach(btn => {
btn.addEventListener('click', (e) => {
const id = e.currentTarget.getAttribute('data-id');
if (confirm('确定要彻底删除此配置吗?此操作不可撤销。')) {
rules = rules.filter(r => r.id !== id);
saveRules();
renderArchive();
}
});
});
}
function attachRuleEvents() {
document.querySelectorAll('.rule-info').forEach(infoArea => {
infoArea.addEventListener('click', (e) => {
const id = e.currentTarget.getAttribute('data-id');
const rule = rules.find(r => r.id === id);
if (rule) {
executePurgeAndLogin(rule, e.currentTarget);
}
if (rule) executePurgeAndLogin(rule, e.currentTarget);
});
});
document.querySelectorAll('.btn-edit').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
const id = e.currentTarget.getAttribute('data-id');
toggleAddForm('edit', id);
toggleAddForm('edit', e.currentTarget.getAttribute('data-id'));
});
});
@@ -363,14 +425,31 @@ document.addEventListener('DOMContentLoaded', () => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
const id = e.currentTarget.getAttribute('data-id');
if (confirm('确定要删除此配置吗?')) {
rules = rules.filter(r => r.id !== id);
const index = rules.findIndex(r => r.id === id);
if (index !== -1) {
rules[index].archived = true;
saveRules();
}
});
});
}
if (archiveToggle) {
archiveToggle.addEventListener('click', () => {
mainViewContent.classList.add('hidden');
archiveViewContent.classList.remove('hidden');
renderArchive();
});
}
if (backToMain) {
backToMain.addEventListener('click', () => {
archiveViewContent.classList.add('hidden');
mainViewContent.classList.remove('hidden');
renderRules();
});
}
// --- Drag and Drop functionality ---
function addDragEvents(item) {
item.addEventListener('dragstart', (e) => {