Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Changelog

## 0.0.4 - Public Release Notes

Laryn `0.0.4` is focused on making the app easier to use, easier to manage, and more reliable as a real desktop product.

### What's new

- Added an account dashboard so users can manage their Laryn account in one place.
- Added desktop account pairing, making it easier and safer to connect the Windows app to your account.
- Added automatic desktop update support so future Windows builds can update more smoothly.
- Added dictionary support so Laryn can better handle names, product terms, acronyms, and other words that speech-to-text often mishears.
- Added account and usage improvements behind the scenes to support subscriptions, billing, and fair usage limits.

### Improved

- Refreshed the Laryn website, dashboard, and product copy.
- Improved release checks so desktop updates are less likely to ship with broken update metadata.
- Improved security and secret-handling practices before public release.

### Notes

This release is a foundation update. The biggest user-facing changes are account pairing, the new dashboard, automatic updates, and better dictation cleanup through dictionary terms.
19 changes: 9 additions & 10 deletions apps/dashboard/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Progress } from "./components/ui/progress";
import { Separator } from "./components/ui/separator";
import { Skeleton } from "./components/ui/skeleton";
import { cn } from "./lib/utils";
import logoUrl from "../../../logo.svg";

type AuthenticatedAccount = AccountStatus & {
authenticated: true;
Expand Down Expand Up @@ -288,9 +289,7 @@ function DashboardTopbar({
<header className="sticky top-0 z-20 border-b border-border bg-background/88 backdrop-blur-xl">
<div className="mx-auto flex h-16 max-w-7xl items-center justify-between gap-4 px-4 sm:px-6 lg:px-8">
<a className="flex min-w-0 items-center gap-3" href="/app" aria-label="Laryn dashboard">
<span className="grid size-8 shrink-0 place-items-center rounded-lg border border-primary/30 bg-primary text-primary-foreground shadow-[0_0_26px_hsl(var(--primary)/.22)]">
<span className="h-4 w-3 rounded-b-full rounded-t-md border-2 border-current border-t-0" />
</span>
<img className="size-8 shrink-0 rounded-lg shadow-[0_0_26px_hsl(var(--primary)/.22)]" src={logoUrl} alt="" aria-hidden="true" />
<span className="grid leading-tight">
<strong className="text-sm font-semibold">Laryn</strong>
<span className="text-xs text-muted-foreground">Account</span>
Expand Down Expand Up @@ -393,17 +392,17 @@ function DeviceApproval({
function NoticeBanner({ notice, onDismiss }: { notice: Notice; onDismiss: () => void }) {
const icon =
notice.tone === "success" ? (
<CheckCircle2 className="mt-0.5 size-5 text-emerald-300" />
<CheckCircle2 className="mt-0.5 size-5 text-success" />
) : (
<CircleAlert className={cn("mt-0.5 size-5", notice.tone === "warning" ? "text-amber-300" : "text-red-300")} />
<CircleAlert className={cn("mt-0.5 size-5", notice.tone === "warning" ? "text-warning" : "text-destructive")} />
);

return (
<Alert
className={cn(
notice.tone === "success" && "border-emerald-400/30 bg-emerald-400/10",
notice.tone === "warning" && "border-amber-400/35 bg-amber-400/10",
notice.tone === "error" && "border-red-400/35 bg-red-400/10"
notice.tone === "success" && "border-success/30 bg-success/10",
notice.tone === "warning" && "border-warning/35 bg-warning/10",
notice.tone === "error" && "border-destructive/35 bg-destructive/10"
)}
>
{icon}
Expand Down Expand Up @@ -606,15 +605,15 @@ function UsageCard({
</div>
<Progress
value={percent}
indicatorClassName={overageCents > 0 ? "bg-amber-300" : "bg-primary"}
indicatorClassName={overageCents > 0 ? "bg-warning" : "bg-primary"}
/>
<div className="flex justify-between gap-4 text-sm text-muted-foreground">
<span>{dollars(remainingCents)} left</span>
<span>{overageCents > 0 ? `${dollars(overageCents)} over` : "No overage"}</span>
</div>
</div>
{overageCents > 0 ? (
<div className="rounded-lg border border-amber-400/35 bg-amber-400/10 p-3 text-sm text-amber-100">
<div className="rounded-lg border border-warning/35 bg-warning/10 p-3 text-sm text-warning">
Usage past the included credit is billed through Polar at cost this month.
</div>
) : null}
Expand Down
6 changes: 3 additions & 3 deletions apps/dashboard/src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const badgeVariants = cva(
default: "border-transparent bg-primary text-primary-foreground",
secondary: "border-border bg-secondary text-secondary-foreground",
outline: "border-border text-foreground",
success: "border-emerald-400/30 bg-emerald-400/10 text-emerald-200",
warning: "border-amber-400/35 bg-amber-400/10 text-amber-200",
destructive: "border-red-400/35 bg-red-400/10 text-red-200"
success: "border-success/30 bg-success/10 text-success",
warning: "border-warning/35 bg-warning/10 text-warning",
destructive: "border-destructive/35 bg-destructive/10 text-destructive"
}
},
defaultVariants: {
Expand Down
53 changes: 31 additions & 22 deletions apps/dashboard/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
--color-border: hsl(var(--border));
--color-input: hsl(var(--input));
--color-ring: hsl(var(--ring));
--color-success: hsl(var(--success));
--color-success-foreground: hsl(var(--success-foreground));
--color-warning: hsl(var(--warning));
--color-warning-foreground: hsl(var(--warning-foreground));

--radius-sm: calc(var(--radius) - 3px);
--radius-md: calc(var(--radius) - 2px);
Expand All @@ -33,26 +37,30 @@
:root {
color-scheme: dark;
--radius: 0.5rem;
--background: 150 6% 8%;
--foreground: 48 22% 92%;
--card: 150 5% 11%;
--card-foreground: 48 22% 92%;
--card-elevated: 154 7% 14%;
--popover: 150 5% 11%;
--popover-foreground: 48 22% 92%;
--primary: 145 59% 66%;
--primary-foreground: 150 16% 9%;
--secondary: 154 7% 17%;
--secondary-foreground: 48 22% 92%;
--muted: 154 7% 17%;
--muted-foreground: 50 8% 66%;
--accent: 41 85% 66%;
--accent-foreground: 150 16% 9%;
--destructive: 2 78% 64%;
--destructive-foreground: 48 22% 96%;
--border: 154 6% 22%;
--input: 154 6% 22%;
--ring: 145 59% 66%;
--background: 220 43% 4%;
--foreground: 215 33% 93%;
--card: 216 42% 9%;
--card-foreground: 215 33% 93%;
--card-elevated: 217 38% 12%;
--popover: 216 42% 9%;
--popover-foreground: 215 33% 93%;
--primary: 222 100% 59%;
--primary-foreground: 0 0% 100%;
--secondary: 217 38% 12%;
--secondary-foreground: 215 33% 93%;
--muted: 219 40% 16%;
--muted-foreground: 216 19% 71%;
--accent: 218 100% 65%;
--accent-foreground: 0 0% 100%;
--destructive: 353 100% 69%;
--destructive-foreground: 0 0% 100%;
--success: 158 64% 52%;
--success-foreground: 220 43% 4%;
--warning: 34 89% 65%;
--warning-foreground: 220 43% 4%;
--border: 218 18% 20%;
--input: 218 18% 20%;
--ring: 218 100% 65%;
}

html {
Expand All @@ -69,8 +77,9 @@ body,

body {
background:
linear-gradient(90deg, hsl(154 5% 12% / 0.3) 1px, transparent 1px),
linear-gradient(180deg, hsl(154 5% 12% / 0.3) 1px, transparent 1px),
radial-gradient(circle at 18% -12%, hsl(var(--primary) / 0.14), transparent 34rem),
linear-gradient(90deg, hsl(215 33% 93% / 0.025) 1px, transparent 1px),
linear-gradient(180deg, hsl(215 33% 93% / 0.025) 1px, transparent 1px),
hsl(var(--background));
background-size: 44px 44px;
color: hsl(var(--foreground));
Expand Down
Loading
Loading