From 90fb71077d0c1f780e7921a8dd29e0eeef477411 Mon Sep 17 00:00:00 2001 From: Nikolay Kolibarov Date: Mon, 26 Oct 2026 15:00:02 +0200 Subject: [PATCH 1/3] feat(ui): move Browse models up and drop the What's new section Reorders the Home "Get started" list so Browse models sits second, right after Start recording, and removes the hardcoded changelog section along with its now-unused styles. --- frontend/src/App.css | 46 ----------------------------------- frontend/src/App.test.tsx | 9 +++++++ frontend/src/App.tsx | 50 +++++++++------------------------------ 3 files changed, 20 insertions(+), 85 deletions(-) diff --git a/frontend/src/App.css b/frontend/src/App.css index 0ce6706..d0e4b27 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -657,52 +657,6 @@ body { border-radius: 10px; } -/* What's New Section */ -.whats-new-section { - padding: 0 20px 20px; -} - -.changelog-list { - display: flex; - flex-direction: column; - gap: 2px; - background: var(--bg-card); - border-radius: 12px; - overflow: hidden; -} - -.changelog-item { - display: flex; - gap: 16px; - padding: 14px 16px; - background: var(--bg-sidebar); -} - -.changelog-date { - font-size: 12px; - color: var(--text-muted); - min-width: 70px; - flex-shrink: 0; -} - -.changelog-content { - display: flex; - flex-direction: column; - gap: 4px; -} - -.changelog-title { - font-size: 14px; - font-weight: 500; - color: var(--text-primary); -} - -.changelog-desc { - font-size: 12px; - color: var(--text-muted); - line-height: 1.4; -} - .home-download { margin: 0 20px 20px; } diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 909d64b..62cdb14 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -64,6 +64,15 @@ describe('App model integration', () => { expect(listenerCount('downloadComplete')).toBe(0); }); + it('Home lists Browse models second and drops the changelog', async () => { + setup(); + await screen.findByText('Get started'); + const titles = Array.from(document.querySelectorAll('.action-list .action-title')).map((el) => el.textContent); + expect(titles).toEqual(['Start recording', 'Browse models', 'Settings', 'View history']); + expect(screen.queryByText('What\'s new')).toBeNull(); + expect(document.querySelector('.whats-new-section')).toBeNull(); + }); + it('Settings summarises the active model and links into the library', async () => { setup(); fireEvent.click(await screen.findByRole('button', { name: /^Settings/ })); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index caaecf5..9bc756c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -907,30 +907,30 @@ function App() { )} -
setCurrentPage('settings')}> +
openModelsLibrary()}>
- - + + +
- Settings - Configure provider, audio device, hotkeys, and more + Browse models + Compare, download, and switch transcription models
-
openModelsLibrary()}> +
setCurrentPage('settings')}>
- - - + +
- Browse models - Compare, download, and switch transcription models + Settings + Configure provider, audio device, hotkeys, and more
@@ -949,34 +949,6 @@ function App() {
- {/* What's New Section */} -
-

What's new

-
-
- May 2026 -
- Native overlay with waveform - Recording overlay now shows above all apps with animated waveform visualization. -
-
-
- May 2026 -
- Auto-paste transcriptions - Transcribed text is automatically pasted into your active text field. -
-
-
- May 2026 -
- Usage statistics - Track your words per minute, time saved, and weekly usage. -
-
-
-
- {/* Error display */} {appState.error && appState.state === 'error' && (
From bb57c2c7c3c10e08aa3abe625e1c0af6bc2ad04d Mon Sep 17 00:00:00 2001 From: Nikolay Kolibarov Date: Mon, 26 Oct 2026 15:15:46 +0200 Subject: [PATCH 2/3] feat(ui): link Home to release notes and docs Adds a compact link row under the Get started list where the changelog used to be. Both links open in the system browser through the Wails runtime instead of navigating the app webview. --- frontend/src/App.css | 21 +++++++++++++++++++++ frontend/src/App.test.tsx | 14 ++++++++++++-- frontend/src/App.tsx | 32 +++++++++++++++++++++++++++++++- frontend/src/test/runtimeMock.ts | 7 +++++++ 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/frontend/src/App.css b/frontend/src/App.css index d0e4b27..998e1f2 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -657,6 +657,27 @@ body { border-radius: 10px; } +.home-links { + display: flex; + gap: 18px; + margin-top: 12px; + padding: 0 4px; +} + +.home-link { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 12px; + color: var(--text-muted); + text-decoration: none; + transition: color 0.15s; +} + +.home-link:hover { + color: var(--text-secondary); +} + .home-download { margin: 0 20px 20px; } diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 62cdb14..0e712c7 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -3,7 +3,7 @@ import { act, fireEvent, render, screen, waitFor, within } from '@testing-librar import { beforeEach, describe, expect, it, vi } from 'vitest'; import * as Api from '../wailsjs/go/main/App'; import App from './App'; -import { EventsEmit, listenerCount, resetListeners } from './test/runtimeMock'; +import { EventsEmit, listenerCount, openedUrls, resetListeners } from './test/runtimeMock'; import { MODELS, downloadState } from './test/fixtures'; import { IDLE_DOWNLOAD } from './modelTypes'; @@ -69,8 +69,18 @@ describe('App model integration', () => { await screen.findByText('Get started'); const titles = Array.from(document.querySelectorAll('.action-list .action-title')).map((el) => el.textContent); expect(titles).toEqual(['Start recording', 'Browse models', 'Settings', 'View history']); - expect(screen.queryByText('What\'s new')).toBeNull(); expect(document.querySelector('.whats-new-section')).toBeNull(); + expect(document.querySelector('.changelog-list')).toBeNull(); + }); + + it('Home opens release notes and docs in the system browser', async () => { + setup(); + fireEvent.click(await screen.findByRole('link', { name: /^What's new/ })); + fireEvent.click(screen.getByRole('link', { name: /^Docs/ })); + expect(openedUrls).toEqual([ + 'https://github.com/ApplauseLab/yap/releases', + 'https://applauselab.ai/docs/yap/', + ]); }); it('Settings summarises the active model and links into the library', async () => { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9bc756c..b6d474d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -43,7 +43,10 @@ import { Quit, IsOnboardingCompleted, } from '../wailsjs/go/main/App'; -import { EventsOn, LogDebug, LogError, LogInfo } from '../wailsjs/runtime/runtime'; +import { BrowserOpenURL, EventsOn, LogDebug, LogError, LogInfo } from '../wailsjs/runtime/runtime'; + +const RELEASES_URL = 'https://github.com/ApplauseLab/yap/releases'; +const DOCS_URL = 'https://applauselab.ai/docs/yap/'; interface AppState { state: string; @@ -947,6 +950,33 @@ function App() {
+ +
+ { event.preventDefault(); BrowserOpenURL(RELEASES_URL); }} + > + What's new + + + + + + + { event.preventDefault(); BrowserOpenURL(DOCS_URL); }} + > + Docs + + + + + + +
{/* Error display */} diff --git a/frontend/src/test/runtimeMock.ts b/frontend/src/test/runtimeMock.ts index c6fa82a..74a8928 100644 --- a/frontend/src/test/runtimeMock.ts +++ b/frontend/src/test/runtimeMock.ts @@ -21,6 +21,13 @@ export function listenerCount(eventName: string): number { export function resetListeners(): void { listeners.clear(); + openedUrls.length = 0; +} + +export const openedUrls: string[] = []; + +export function BrowserOpenURL(url: string): void { + openedUrls.push(url); } export const LogInfo = (_message: string) => {}; From b0724e988d518ed9851f72283d73bf6ade4cbf36 Mon Sep 17 00:00:00 2001 From: Nikolay Kolibarov Date: Mon, 26 Oct 2026 20:33:12 +0200 Subject: [PATCH 3/3] refactor(ui): extract HomeLink for the Home link row Both Home links shared the same anchor, external-link icon, and system-browser click handling. Pulling that into one component keeps the pair in sync and makes the link row read at a glance. --- frontend/src/App.tsx | 45 +++++++++++++++----------------- frontend/src/test/runtimeMock.ts | 10 +++---- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b6d474d..8628909 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -48,6 +48,25 @@ import { BrowserOpenURL, EventsOn, LogDebug, LogError, LogInfo } from '../wailsj const RELEASES_URL = 'https://github.com/ApplauseLab/yap/releases'; const DOCS_URL = 'https://applauselab.ai/docs/yap/'; +// Anchors keep the href for hover/keyboard affordances, but the webview must not +// navigate away from the app, so the click is handed to the system browser. +function HomeLink({ href, label }: { href: string; label: string }) { + return ( + { event.preventDefault(); BrowserOpenURL(href); }} + > + {label} + + + + + + + ); +} + interface AppState { state: string; recordingTime: number; @@ -952,30 +971,8 @@ function App() {
- { event.preventDefault(); BrowserOpenURL(RELEASES_URL); }} - > - What's new - - - - - - - { event.preventDefault(); BrowserOpenURL(DOCS_URL); }} - > - Docs - - - - - - + +
diff --git a/frontend/src/test/runtimeMock.ts b/frontend/src/test/runtimeMock.ts index 74a8928..cdafe01 100644 --- a/frontend/src/test/runtimeMock.ts +++ b/frontend/src/test/runtimeMock.ts @@ -19,17 +19,17 @@ export function listenerCount(eventName: string): number { return listeners.get(eventName)?.size ?? 0; } -export function resetListeners(): void { - listeners.clear(); - openedUrls.length = 0; -} - export const openedUrls: string[] = []; export function BrowserOpenURL(url: string): void { openedUrls.push(url); } +export function resetListeners(): void { + listeners.clear(); + openedUrls.length = 0; +} + export const LogInfo = (_message: string) => {}; export const LogError = (_message: string) => {}; export const LogDebug = (_message: string) => {};