feat(ext/settings): autofill section (capture toggle + blacklist)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { sendMessage, escapeHtml } from '../../shared/state';
|
import { sendMessage, escapeHtml } from '../../shared/state';
|
||||||
import type { VaultSettings } from '../../shared/types';
|
import type { VaultSettings, DeviceSettings } from '../../shared/types';
|
||||||
import {
|
import {
|
||||||
loadColorScheme, saveColorScheme, resetColorScheme,
|
loadColorScheme, saveColorScheme, resetColorScheme,
|
||||||
DEFAULT_DIGIT_COLOR, DEFAULT_SYMBOL_COLOR,
|
DEFAULT_DIGIT_COLOR, DEFAULT_SYMBOL_COLOR,
|
||||||
@@ -100,7 +100,78 @@ async function renderSection(section: SettingsSection): Promise<void> {
|
|||||||
// --- Section stubs (filled in by Tasks 3-9) ---
|
// --- Section stubs (filled in by Tasks 3-9) ---
|
||||||
|
|
||||||
async function renderAutofillSection(content: HTMLElement): Promise<void> {
|
async function renderAutofillSection(content: HTMLElement): Promise<void> {
|
||||||
content.innerHTML = '<p class="muted" style="padding:20px;font-size:12px;">Autofill — coming soon</p>';
|
const [settingsResp, blacklistResp] = await Promise.all([
|
||||||
|
sendMessage({ type: 'get_settings' }),
|
||||||
|
sendMessage({ type: 'get_blacklist' }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const settings: DeviceSettings = settingsResp.ok
|
||||||
|
? (settingsResp.data as { settings: DeviceSettings }).settings
|
||||||
|
: { captureEnabled: false, captureStyle: 'bar' };
|
||||||
|
|
||||||
|
const blacklist: string[] = blacklistResp.ok
|
||||||
|
? (blacklistResp.data as { blacklist: string[] }).blacklist
|
||||||
|
: [];
|
||||||
|
|
||||||
|
content.innerHTML = `
|
||||||
|
<h3 class="settings-section-title">Capture</h3>
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-row__info">
|
||||||
|
<div class="setting-row__title">Auto-detect logins</div>
|
||||||
|
<div class="setting-row__desc">Show a prompt when a login form is detected.</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-row__control">
|
||||||
|
<input type="checkbox" id="capture-enabled" ${settings.captureEnabled ? 'checked' : ''}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-row__info">
|
||||||
|
<div class="setting-row__title">Prompt style</div>
|
||||||
|
<div class="setting-row__desc">How to prompt when a login is detected.</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-row__control" style="display:flex; gap:6px;">
|
||||||
|
<button class="btn ${settings.captureStyle === 'bar' ? 'btn-active' : ''}" id="style-bar" style="font-size:11px;">bar</button>
|
||||||
|
<button class="btn ${settings.captureStyle === 'toast' ? 'btn-active' : ''}" id="style-toast" style="font-size:11px;">toast</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="settings-section-title" style="margin-top:20px;">Blocked sites</h3>
|
||||||
|
<div id="blacklist-container">
|
||||||
|
${blacklist.length > 0
|
||||||
|
? blacklist.map((h) => `
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-row__info">
|
||||||
|
<div class="setting-row__title">${escapeHtml(h)}</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn remove-bl" data-hostname="${escapeHtml(h)}" style="font-size:11px;">remove</button>
|
||||||
|
</div>
|
||||||
|
`).join('')
|
||||||
|
: '<p class="muted" style="font-size:12px; padding:8px 0;">No blocked sites.</p>'}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.getElementById('capture-enabled')?.addEventListener('change', async (e) => {
|
||||||
|
const enabled = (e.target as HTMLInputElement).checked;
|
||||||
|
await sendMessage({ type: 'update_settings', settings: { captureEnabled: enabled } });
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('style-bar')?.addEventListener('click', async () => {
|
||||||
|
await sendMessage({ type: 'update_settings', settings: { captureStyle: 'bar' } });
|
||||||
|
renderAutofillSection(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('style-toast')?.addEventListener('click', async () => {
|
||||||
|
await sendMessage({ type: 'update_settings', settings: { captureStyle: 'toast' } });
|
||||||
|
renderAutofillSection(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
content.querySelectorAll<HTMLButtonElement>('.remove-bl').forEach((btn) => {
|
||||||
|
btn.addEventListener('click', async () => {
|
||||||
|
const host = btn.dataset.hostname!;
|
||||||
|
await sendMessage({ type: 'remove_blacklist', hostname: host });
|
||||||
|
renderAutofillSection(content);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDisplaySection(content: HTMLElement): void {
|
function renderDisplaySection(content: HTMLElement): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user