support export and import

This commit is contained in:
Julian Freeman
2026-03-11 14:11:37 -04:00
parent c11ef4a567
commit 6f023006dc
2 changed files with 64 additions and 1 deletions

View File

@@ -52,6 +52,13 @@
<div id="presetList" class="mt-4 space-y-2 max-h-40 overflow-y-auto pr-1">
<!-- Saved presets -->
</div>
<!-- Import/Export Presets -->
<div class="flex gap-2 pt-2 border-t border-gray-100">
<button id="exportPresets" class="flex-1 bg-white text-gray-600 text-[10px] py-1 rounded border border-gray-300 hover:bg-gray-50 transition-colors font-medium">导出预设</button>
<button id="importPresets" class="flex-1 bg-white text-gray-600 text-[10px] py-1 rounded border border-gray-300 hover:bg-gray-50 transition-colors font-medium">导入预设</button>
<input type="file" id="importInput" class="hidden" accept=".json">
</div>
</div>
</div>

View File

@@ -16,6 +16,11 @@ const presetList = document.getElementById('presetList');
const presetSelect = document.getElementById('presetSelect');
const runPresetBtn = document.getElementById('runPreset');
// Import/Export Elements
const exportBtn = document.getElementById('exportPresets');
const importBtn = document.getElementById('importPresets');
const importInput = document.getElementById('importInput');
// Collapsible logic
const toggleConfig = document.getElementById('toggleConfig');
const configContent = document.getElementById('configContent');
@@ -101,6 +106,58 @@ addPresetBtn.addEventListener('click', async () => {
cancelEditBtn.addEventListener('click', stopEditing);
// Export/Import Logic
exportBtn.addEventListener('click', async () => {
const { userPresets = DEFAULT_PRESETS } = await chrome.storage.local.get('userPresets');
const blob = new Blob([JSON.stringify(userPresets, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `hardware-presets-${new Date().toISOString().split('T')[0]}.json`;
a.click();
URL.revokeObjectURL(url);
});
importBtn.addEventListener('click', () => importInput.click());
importInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = async (event) => {
try {
const importedPresets = JSON.parse(event.target.result);
if (!Array.isArray(importedPresets)) throw new Error('无效的预设文件格式');
const { userPresets = DEFAULT_PRESETS } = await chrome.storage.local.get('userPresets');
const choice = confirm('导入成功!\n点击 [确定] 将导入的预设合并到当前列表。\n点击 [取消] 将替换整个预设列表。');
let finalPresets;
if (choice) {
// Merge: Append with new IDs to prevent conflicts
const newItems = importedPresets.map(p => ({
...p,
id: Date.now().toString() + Math.random().toString(36).substr(2, 5)
}));
finalPresets = [...userPresets, ...newItems];
} else {
finalPresets = importedPresets;
}
await chrome.storage.local.set({ userPresets: finalPresets });
currentPresets = finalPresets;
renderPresets(currentPresets);
alert('预设导入完成!');
} catch (err) {
alert('导入失败: ' + err.message);
}
importInput.value = ''; // Reset input
};
reader.readAsText(file);
});
function startEditing(preset) {
editingPresetId = preset.id;
newPresetName.value = preset.name;
@@ -112,7 +169,6 @@ function startEditing(preset) {
addPresetBtn.classList.replace('text-indigo-700', 'text-white');
cancelEditBtn.classList.remove('hidden');
// Ensure config is expanded so user can see inputs
configContent.classList.remove('hidden');
configChevron.classList.add('rotate-180');
}