(hookId: string, btn: HTMLButtonElement)
| 69 | } |
| 70 | |
| 71 | async function downloadHook(hookId: string, btn: HTMLButtonElement): Promise<void> { |
| 72 | const hook = allItems.find((item) => item.id === hookId); |
| 73 | if (!hook) { |
| 74 | showToast('Hook not found.', 'error'); |
| 75 | return; |
| 76 | } |
| 77 | |
| 78 | const files = [ |
| 79 | { name: 'README.md', path: hook.readmeFile }, |
| 80 | ...hook.assets.map((asset) => ({ |
| 81 | name: asset, |
| 82 | path: `${hook.path}/${asset}`, |
| 83 | })), |
| 84 | ]; |
| 85 | |
| 86 | if (files.length === 0) { |
| 87 | showToast('No files found for this hook.', 'error'); |
| 88 | return; |
| 89 | } |
| 90 | |
| 91 | const originalContent = btn.innerHTML; |
| 92 | btn.disabled = true; |
| 93 | btn.innerHTML = '<svg class="spinner" viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M8 0a8 8 0 1 0 8 8h-1.5A6.5 6.5 0 1 1 8 1.5V0z"/></svg> Preparing...'; |
| 94 | |
| 95 | try { |
| 96 | await downloadZipBundle(hook.id, files); |
| 97 | |
| 98 | btn.innerHTML = '<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 0 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0z"/></svg> Downloaded!'; |
| 99 | setTimeout(() => { |
| 100 | btn.disabled = false; |
| 101 | btn.innerHTML = originalContent; |
| 102 | }, 2000); |
| 103 | } catch (error) { |
| 104 | const message = error instanceof Error ? error.message : 'Download failed.'; |
| 105 | showToast(message, 'error'); |
| 106 | btn.innerHTML = '<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.75.75 0 1 1 1.06 1.06L9.06 8l3.22 3.22a.75.75 0 0 1-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 0 1-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06z"/></svg> Failed'; |
| 107 | setTimeout(() => { |
| 108 | btn.disabled = false; |
| 109 | btn.innerHTML = originalContent; |
| 110 | }, 2000); |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | function openHookDetailsModal(hookId: string, trigger?: HTMLElement): void { |
| 115 | const item = hookById.get(hookId); |
no test coverage detected