{#if $showSettings}
{ if (e.key === 'Escape') close(); }}>
e.stopPropagation()}>

Settings

{#if activeTab === 'general'}

Notes List

Notebooks

Time Format

{#if isMobile}

Vault

Current: {$appConfig?.active_vault?.split('/').pop() ?? 'Unknown'}

{/if} {#if !isMobile}

Performance

System

{#if showTrayIcon} {/if}
{/if}
{:else if activeTab === 'editor'}

Title

{#if !isMobile} {/if}

Wiki Links & Graph

{#if !isMobile}

PDF Preview

{#if pdfPreview}

PDF Height

{#each pdfHeightPresets as preset} {/each}
Default height for PDF previews in notes
{/if} {/if}
{:else if activeTab === 'styling'}

Theme

{#each themePresets as preset} {/each}

Accent Color

{#each accentPresets as preset} {/each}

Font Size

{#each fontSizePresets as preset} {/each}
{#if !isMobile}

Interface Scale

{#each uiScalePresets as preset} {/each}

Zooms the whole app: every panel, menu, and the editor. Use Default (100%) to reset.

{/if}

Line Height

{#each lineHeightPresets as preset} {/each}

Font

{#each fontFamilyPresets as preset} {/each}
{:else if activeTab === 'backup'}

Automatic Backup

Backup frequency
{#each [{ value: '1h', label: '1 hour' }, { value: '6h', label: '6 hours' }, { value: '12h', label: '12 hours' }, { value: '24h', label: '24 hours' }] as opt} {/each}
Maximum backups
{#each [5, 10, 20, 50] as count} {/each}
{#if !isMobile} {#if $appConfig?.backup_location}

{$appConfig.backup_location}

{/if} {/if}

{#if $appConfig?.last_backup_time} Last backup: {formatBackupDate($appConfig.last_backup_time)} {:else} No backups yet {/if}

{#if backupMessage}
{#if backupMessage.type === 'success'} {:else} {/if} {backupMessage.text}
{/if}

Restore Backup

{#if backups.length === 0}

No backups found

{:else}
{#each backups as entry}
{formatBackupDate(entry.created)} {formatBackupSize(entry.size)}
{/each}
{/if}
{#if restoreConfirm}
restoreConfirm = null}>
e.stopPropagation()}>

Restore Backup?

This will replace all notes in your vault with the backup from {formatBackupDate(restoreConfirm.created)}. This action cannot be undone.

{/if}
{:else if activeTab === 'import'}

Import from Obsidian

Convert Obsidian wiki-links (![[image.png]], [[note]]) to standard markdown links across all notes in the current vault. This expects that you have opened an Obsidian vault directory directly as your HelixNotes vault.

This modifies files in place. Make a backup before running!
{#if importResult}
Converted {importResult.links_converted} links across {importResult.files_converted} files
{/if} {#if importError}
{importError}
{/if}
{:else if activeTab === 'ai'}

Provider

{#if aiProvider} {#if aiProvider === 'ollama' || aiProvider === 'openai_compatible'}

Your data stays on your device. No text is sent to any external server.

{:else}

Your selected text and note content will be sent to {aiProvider === 'openai' ? 'OpenAI' : 'Anthropic'} servers for processing.

{/if} {#if aiProvider === 'ollama'}

Server URL

{ _ollamaBaseUrl = (e.target as HTMLInputElement).value; }} onblur={saveAiSettings} />

Ollama server address. Install from ollama.com

API Key (optional)

{ _ollamaApiKey = (e.target as HTMLInputElement).value; }} onblur={saveAiSettings} />
{:else if aiProvider === 'openai_compatible'}

Server URL

{ _openaiCompatibleBaseUrl = (e.target as HTMLInputElement).value; }} onblur={saveAiSettings} />

Base URL for any OpenAI-compatible server (LM Studio, LocalAI, vLLM, etc.). Uses the v1/completions endpoint.

API Key (optional)

{ _openaiCompatibleKey = (e.target as HTMLInputElement).value; }} onblur={saveAiSettings} />
{:else}

API Key

{ const v = (e.target as HTMLInputElement).value; if (aiProvider === 'openai') _openaiKey = v; else _anthropicKey = v; }} onblur={saveAiSettings} />
{#if aiProvider === 'openai'}

Get your API key from platform.openai.com

{:else}

Get your API key from console.anthropic.com

{/if}
{/if}

Model

{#if aiProvider === 'ollama' || aiProvider === 'openai_compatible'} { aiModel = (e.target as HTMLInputElement).value; }} onblur={saveAiSettings} />

{aiProvider === 'ollama' ? 'Enter the model name as shown by ollama list' : 'Enter the model name as required by your server'}

{:else}
{#each aiModels as m} {/each}
{/if}

Writing Style

Describe your preferred tone, style, or personality. This will be applied to all AI actions.

Connection

{#if aiTestMessage}
{#if aiTestMessage.type === 'success'} {:else} {/if} {aiTestMessage.text}
{/if}

Usage

{#if isMobile}

Use the AI button in the toolbar or header to access AI writing tools: improve, fix grammar, rewrite, summarize, translate, and more.

{:else}

Select text in the editor and right-click to access AI writing tools: improve, fix grammar, rewrite, summarize, translate, and more.

{/if}
{/if}
{:else if activeTab === 'sync'}

Provider

Sync your vault to your own WebDAV server (Nextcloud, ownCloud, a NAS).

{#if syncProvider === 'webdav'}

Server URL

{ syncUrl = (e.target as HTMLInputElement).value; }} onblur={saveSyncSettings} />

WebDAV folder URL, e.g. https://your-server/remote.php/dav/files/USER/Folder

Username

{ syncUsername = (e.target as HTMLInputElement).value; }} onblur={saveSyncSettings} />

Password

{ syncPassword = (e.target as HTMLInputElement).value; }} onblur={saveSyncSettings} />

Use an app password, not your main one. Stored locally on this device.

Connection

{#if syncTestMessage}
{#if syncTestMessage.type === 'success'} {:else} {/if} {syncTestMessage.text}
{/if}

Sync

{#if syncMessage}
{#if syncMessage.type === 'success'} {:else} {/if} {syncMessage.text}
{/if} {#if $appConfig?.last_sync_time}

Last sync: {new Date($appConfig.last_sync_time).toLocaleString()}

{/if}

If a note is edited on two devices, both are kept (one as a "(conflict)" copy).

Automatic Sync

{#each [{ v: 0, l: 'Off' }, { v: 5, l: '5 min' }, { v: 15, l: '15 min' }, { v: 30, l: '30 min' }, { v: 60, l: '60 min' }] as opt} {/each}

How often to sync in the background.

{/if}
{:else if activeTab === 'updates'}

Current Version

HelixNotes v{appVersion}

Check for Updates

{#if updateAvailable}

Update Available

Version {updateAvailable.version}

{#if updateAvailable.date}

{new Date(updateAvailable.date).toLocaleDateString()}

{/if} {#if updateAvailable.body}
{updateAvailable.body}
{/if}
{#if $installType === 'appimage' || $installType === 'windows' || $installType === 'macos'} {#if updateDownloading && updateProgress > 0}
{/if} {:else if $installType === 'deb'}

Update via your package manager:

sudo apt update && sudo apt upgrade helix-notes
{:else if $installType === 'aur'}

Update via your AUR helper:

yay -Syu helixnotes
{:else if $installType === 'android'} {:else} Download from Codeberg {/if}
{/if} {#if updateMessage}
{#if updateMessage.type === 'success'} {:else if updateMessage.type === 'error'} {:else} {/if} {updateMessage.text}
{/if}
{/if}
{/if}