Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
451b2bd
feat: added initial oAuth integration setup
gabrielste1n Oct 8, 2025
17031da
fix: show local time not utc, add link to platform.openai
gabrielste1n Oct 13, 2025
a07d95e
feat: add complete cleanup script and troubleshooting docs
gabrielste1n Oct 15, 2025
1cde4b0
chore: update lockfile
gabrielste1n Oct 15, 2025
24db40f
fix: register hotkey immediately after step
gabrielste1n Oct 15, 2025
74c22b4
chore: version bump
gabrielste1n Oct 15, 2025
081b00d
Merge pull request #40 from HeroTools/cleanup
gabrielste1n Oct 15, 2025
809895a
Merge main into clerk-auth
gabrielste1n Jan 10, 2026
8ee39f2
Merge main into clerk-auth
gabrielste1n Jan 14, 2026
114a495
refactor: migration to neon auth
gabrielste1n Jan 21, 2026
aecf7d5
Merge branch 'main' into neon-auth-refactor
gabrielste1n Jan 21, 2026
1a28684
refactor: make sure to use own UI components
gabrielste1n Jan 21, 2026
50be769
refactor: ui overhaul
gabrielste1n Jan 22, 2026
3fa16a2
refactor: replace IPC-based OAuth callback with deep-link flow, add m…
gabrielste1n Jan 27, 2026
fbcc54e
Merge branch 'main' into neon-auth-refactor
gabrielste1n Jan 27, 2026
794da93
feat: add skills
gabrielste1n Jan 27, 2026
33be15b
feat: ignore claude skills and agents
gabrielste1n Jan 27, 2026
46f08bc
feat: add OpenWhispr cloud transcription with usage tracking, limits,…
gabrielste1n Jan 29, 2026
c80c5e7
Merge origin/main into neon-auth-refactor
gabrielste1n Jan 29, 2026
84e88c1
refactor: Fix cloud transcription binary handling, add auth state syn…
gabrielste1n Jan 29, 2026
e0a632d
feat: Show UpgradePrompt dialog in ControlPanel when daily transcript…
gabrielste1n Jan 29, 2026
36bf27b
feat: add AssemblyAI real-time streaming transcription with WebSocket…
gabrielste1n Jan 30, 2026
00ef4be
fix: streaming handling when no api key
gabrielste1n Feb 2, 2026
cfe0c07
fix: persist AI provider selection to localStorage so Custom/Local ta…
gabrielste1n Feb 3, 2026
a36d734
Merge main into neon-auth-refactor with design system refactor
gabrielste1n Feb 3, 2026
fe08e11
Merge remote-tracking branch 'origin/main' into neon-auth-refactor
gabrielste1n Feb 3, 2026
120ee27
chore: version bump
gabrielste1n Feb 3, 2026
b0c9a6e
refactor: onboarding style refactor
gabrielste1n Feb 4, 2026
546406b
feat: Add Stripe billing with trial support, refactor duplicate API h…
gabrielste1n Feb 4, 2026
ce68cb6
feat: complete OAuth flow with branded redirect, UI refinements, code…
gabrielste1n Feb 5, 2026
2338c49
fix: ui polish
gabrielste1n Feb 5, 2026
0431ae0
refactor: consolidate session refresh logic with withSessionRefresh u…
gabrielste1n Feb 5, 2026
7c9acb3
chore: update .gitignore
gabrielste1n Feb 5, 2026
af41109
feat(ui): add ReferralDashboard component with full referral UI
gabrielste1n Feb 6, 2026
bb49282
feat(ipc): add referral IPC handlers and type definitions
gabrielste1n Feb 6, 2026
303a856
chore: update dependencies
gabrielste1n Feb 6, 2026
e8421c6
Merge main into referral-program
gabrielste1n Feb 6, 2026
f234f22
Merge branch 'main' into referral-program
gabrielste1n Feb 11, 2026
af0ba34
feat: Add sidebar navigation, notes system, and dictionary view
gabrielste1n Feb 11, 2026
c1c9997
Merge remote-tracking branch 'origin/note-taker' into referral-program
gabrielste1n Feb 11, 2026
5e28289
Refactor: extract shared multipart helpers, remove dead code/comments…
gabrielste1n Feb 11, 2026
889e746
feat: referral card redesign
gabrielste1n Feb 11, 2026
3f3ad0f
Merge remote-tracking branch 'origin/main' into referral-program
gabrielste1n Feb 11, 2026
56aaf1c
Merge referral-program branch into note-taker
gabrielste1n Feb 12, 2026
a0a50b6
feat: add folder organization for notes
gabrielste1n Feb 12, 2026
962da49
fix: neon auth build config (#266)
gabrielste1n Feb 12, 2026
f7a2f3e
Merge remote-tracking branch 'origin/main' into note-taker
gabrielste1n Feb 12, 2026
caf642f
fix: clean up merge styling for referral program docs update
gabrielste1n Feb 12, 2026
1681ae8
style: refrral card cleanups
gabrielste1n Feb 12, 2026
c5edd9e
chore: formatting
gabrielste1n Feb 12, 2026
9fde34f
Merge main into note-taker
gabrielste1n Feb 12, 2026
167a938
feat: add i18n translations for referral and notetaker features
gabrielste1n Feb 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [1.4.8] - 2026-02-12

### Added
- **Referral Program**: Invite friends to earn free Pro months with referral dashboard, email invitations, invite tracking with status badges, and animated spectrogram share card with unique referral code
- **Notes System**: Added sidebar navigation with notes system and dictionary view for organizing transcriptions
- **Folder Organization**: Notes can be organized into custom folders with a default Personal folder, folder management UI, and folder-aware note filtering. Upload flow now includes folder selection
- **Internationalization v1**: Full desktop localization across auth, settings, hooks, and UI with centralized renderer locale resources (#258)
- **Chinese Language Split**: Split Chinese into Simplified (zh-CN) and Traditional (zh-TW) with tailored AI instructions and one-time migration for existing users (#267)
- **Russian Interface Language**: Added Russian to interface language options
Expand All @@ -34,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Archive Extraction Retry**: Reuse existing archive on extraction retry with improved error handling
- **Email Verification Polling**: Pass email param in verification polling and stop on 401 responses
- **Auth Build Bundling**: Added @neondatabase/auth packages to rollup externals for correct production bundling (#256)
- **Neon Auth Build Config**: Fixed Vite build configuration for Neon Auth packages (#266)

### Changed
- **Build System**: Bumped Node version in build files
Expand Down
27 changes: 26 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,12 +399,37 @@ On GNOME Wayland, Electron's `globalShortcut` API doesn't work due to Wayland's

## Development Guidelines

### Internationalization (i18n) — REQUIRED

All user-facing strings **must** use the i18n system. Never hardcode UI text in components.

**Setup**: react-i18next (v15) with i18next (v25). Translation files in `src/locales/{lang}/translation.json`.

**Supported languages**: en, es, fr, de, pt, it, ru, zh-CN, zh-TW

**How to use**:
```tsx
import { useTranslation } from "react-i18next";

const { t } = useTranslation();
// Simple: t("notes.list.title")
// With interpolation: t("notes.upload.using", { model: "Whisper" })
```

**Rules**:
1. Every new UI string must have a translation key in `en/translation.json` and all other language files
2. Use `useTranslation()` hook in components and hooks
3. Keep `{{variable}}` interpolation syntax for dynamic values
4. Do NOT translate: brand names (OpenWhispr, Pro), technical terms (Markdown, Signal ID), format names (MP3, WAV), AI system prompts
5. Group keys by feature area (e.g., `notes.editor.*`, `referral.toasts.*`)

### Adding New Features

1. **New IPC Channel**: Add to both ipcHandlers.js and preload.js
2. **New Setting**: Update useSettings.ts and SettingsPage.tsx
3. **New UI Component**: Follow shadcn/ui patterns in src/components/ui
4. **New Manager**: Create in src/helpers/, initialize in main.js
5. **New UI Strings**: Add translation keys to all 9 language files (see i18n section above)

### Testing Checklist

Expand Down Expand Up @@ -529,7 +554,7 @@ On GNOME Wayland, Electron's `globalShortcut` API doesn't work due to Wayland's

- Streaming transcription support
- Custom wake word detection
- Multi-language UI
- ~~Multi-language UI~~ (implemented — 9 languages via react-i18next)
- Cloud model selection
- Batch transcription
- Export formats beyond clipboard
1 change: 1 addition & 0 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ function navigateControlPanelWithVerifier(verifier) {
windowManager.controlPanelWindow.focus();
}


function handleOAuthDeepLink(deepLinkUrl) {
try {
const parsed = new URL(deepLinkUrl);
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"vite": "^6.3.5"
},
"dependencies": {
"@neondatabase/auth": "^0.1.0-beta.21",
"@neondatabase/neon-js": "^0.1.0-beta.22",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-dialog": "^1.1.14",
Expand Down
49 changes: 48 additions & 1 deletion preload.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { contextBridge, ipcRenderer } = require("electron");
const { contextBridge, ipcRenderer, webUtils } = require("electron");

/**
* Helper to register an IPC listener and return a cleanup function.
Expand Down Expand Up @@ -39,6 +39,44 @@ contextBridge.exposeInMainWorld("electronAPI", {
getDictionary: () => ipcRenderer.invoke("db-get-dictionary"),
setDictionary: (words) => ipcRenderer.invoke("db-set-dictionary", words),

// Note functions
saveNote: (title, content, noteType, sourceFile, audioDuration, folderId) =>
ipcRenderer.invoke("db-save-note", title, content, noteType, sourceFile, audioDuration, folderId),
getNote: (id) => ipcRenderer.invoke("db-get-note", id),
getNotes: (noteType, limit, folderId) => ipcRenderer.invoke("db-get-notes", noteType, limit, folderId),
updateNote: (id, updates) => ipcRenderer.invoke("db-update-note", id, updates),
deleteNote: (id) => ipcRenderer.invoke("db-delete-note", id),
exportNote: (noteId, format) => ipcRenderer.invoke("export-note", noteId, format),

// Folder functions
getFolders: () => ipcRenderer.invoke("db-get-folders"),
createFolder: (name) => ipcRenderer.invoke("db-create-folder", name),
deleteFolder: (id) => ipcRenderer.invoke("db-delete-folder", id),
renameFolder: (id, name) => ipcRenderer.invoke("db-rename-folder", id, name),
getFolderNoteCounts: () => ipcRenderer.invoke("db-get-folder-note-counts"),

// Audio file operations
selectAudioFile: () => ipcRenderer.invoke("select-audio-file"),
transcribeAudioFile: (filePath, options) =>
ipcRenderer.invoke("transcribe-audio-file", filePath, options),
getPathForFile: (file) => webUtils.getPathForFile(file),

onNoteAdded: (callback) => {
const listener = (_event, note) => callback?.(note);
ipcRenderer.on("note-added", listener);
return () => ipcRenderer.removeListener("note-added", listener);
},
onNoteUpdated: (callback) => {
const listener = (_event, note) => callback?.(note);
ipcRenderer.on("note-updated", listener);
return () => ipcRenderer.removeListener("note-updated", listener);
},
onNoteDeleted: (callback) => {
const listener = (_event, data) => callback?.(data);
ipcRenderer.on("note-deleted", listener);
return () => ipcRenderer.removeListener("note-deleted", listener);
},

onTranscriptionAdded: (callback) => {
const listener = (_event, transcription) => callback?.(transcription);
ipcRenderer.on("transcription-added", listener);
Expand Down Expand Up @@ -233,6 +271,15 @@ contextBridge.exposeInMainWorld("electronAPI", {
cloudCheckout: () => ipcRenderer.invoke("cloud-checkout"),
cloudBillingPortal: () => ipcRenderer.invoke("cloud-billing-portal"),

// Cloud audio file transcription
transcribeAudioFileCloud: (filePath) => ipcRenderer.invoke("transcribe-audio-file-cloud", filePath),
transcribeAudioFileByok: (options) => ipcRenderer.invoke("transcribe-audio-file-byok", options),

// Referral stats
getReferralStats: () => ipcRenderer.invoke("get-referral-stats"),
sendReferralInvite: (email) => ipcRenderer.invoke("send-referral-invite", email),
getReferralInvites: () => ipcRenderer.invoke("get-referral-invites"),

// Assembly AI Streaming
assemblyAiStreamingWarmup: (options) =>
ipcRenderer.invoke("assemblyai-streaming-warmup", options),
Expand Down
Loading