From 634b263a0edd72b09c6eb80a3196750b77372cfe Mon Sep 17 00:00:00 2001
From: Brandon Pollack
Date: Thu, 4 Jun 2026 17:53:53 +0900
Subject: [PATCH 1/3] forked
---
LICENSE | 22 ++++
README.md | 317 +++++++++++++++++++++++++++++-------------------------
2 files changed, 191 insertions(+), 148 deletions(-)
create mode 100644 LICENSE
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..670e112
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2024 Nick Skriabin (semos-labs/aion)
+Copyright (c) 2026 Brandon Pollack
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 301ec4b..549f5d6 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,9 @@
+> **Fork notice:** This is a maintained fork of [semos-labs/aion](https://github.com/semos-labs/aion) by [Nick Skriabin](https://github.com/nickskriabin). Original work is MIT licensed and attributed accordingly. Maintained by [Brandon Pollack](https://github.com/brandonpollack23).
+> I have used claude extensively and it is totally vibed i dont have time to actually read the soruce, I just wanted some of my own features, use at your own risk.
+
---
## Table of Contents
@@ -55,23 +58,23 @@ Most calendar apps are mouse-driven, slow, and cluttered. Aion takes a different
### Comparison
-| Feature | Aion | [calcurse](https://calcurse.org/) | [khal](https://github.com/pimutils/khal) | [gcalcli](https://github.com/insanum/gcalcli) | [calcure](https://github.com/anufrievroman/calcure) |
-|---------|:----:|:--------:|:----:|:-------:|:-------:|
-| **TUI (visual interface)** | ✅ | ✅ | ❌ | ❌ | ✅ |
-| **Google Calendar sync** | ✅ Native | ❌ | 🔧 vdirsyncer | ✅ Native | ❌ |
-| **CalDAV support** | ✅ Native | ❌ | 🔧 vdirsyncer | ❌ | ❌ |
-| **Multi-account** | ✅ | ❌ | 🔧 | ✅ | ❌ |
-| **Vim keybindings** | ✅ | Partial | ❌ | ❌ | Partial |
-| **Multi-day view** | ✅ 1/3/5 cols | ❌ | ❌ | ❌ | ❌ |
-| **Free/busy scheduling** | ✅ | ❌ | ❌ | ✅ | ❌ |
-| **Google Meet generation** | ✅ | ❌ | ❌ | ❌ | ❌ |
-| **Natural language input** | ✅ | ❌ | ❌ | ❌ | ❌ |
-| **Event search** | ✅ | ✅ | ✅ | ✅ | ❌ |
-| **Recurring events** | ✅ | ✅ | ✅ | ✅ | ✅ |
-| **Timezone support** | ✅ | ✅ | ✅ | ✅ | ❌ |
-| **Theming** | ✅ TOML | ✅ | ✅ | ❌ | ✅ |
-| **Offline mode** | ✅ SQLite | ✅ | ✅ | ❌ | ✅ |
-| **Dependencies** | None | ncurses | Python | Python | Python |
+| Feature | Aion | [calcurse](https://calcurse.org/) | [khal](https://github.com/pimutils/khal) | [gcalcli](https://github.com/insanum/gcalcli) | [calcure](https://github.com/anufrievroman/calcure) |
+| -------------------------- | :-----------: | :-------------------------------: | :--------------------------------------: | :-------------------------------------------: | :-------------------------------------------------: |
+| **TUI (visual interface)** | ✅ | ✅ | ❌ | ❌ | ✅ |
+| **Google Calendar sync** | ✅ Native | ❌ | 🔧 vdirsyncer | ✅ Native | ❌ |
+| **CalDAV support** | ✅ Native | ❌ | 🔧 vdirsyncer | ❌ | ❌ |
+| **Multi-account** | ✅ | ❌ | 🔧 | ✅ | ❌ |
+| **Vim keybindings** | ✅ | Partial | ❌ | ❌ | Partial |
+| **Multi-day view** | ✅ 1/3/5 cols | ❌ | ❌ | ❌ | ❌ |
+| **Free/busy scheduling** | ✅ | ❌ | ❌ | ✅ | ❌ |
+| **Google Meet generation** | ✅ | ❌ | ❌ | ❌ | ❌ |
+| **Natural language input** | ✅ | ❌ | ❌ | ❌ | ❌ |
+| **Event search** | ✅ | ✅ | ✅ | ✅ | ❌ |
+| **Recurring events** | ✅ | ✅ | ✅ | ✅ | ✅ |
+| **Timezone support** | ✅ | ✅ | ✅ | ✅ | ❌ |
+| **Theming** | ✅ TOML | ✅ | ✅ | ❌ | ✅ |
+| **Offline mode** | ✅ SQLite | ✅ | ✅ | ❌ | ✅ |
+| **Dependencies** | None | ncurses | Python | Python | Python |
> 🔧 = Requires additional setup/tools
@@ -79,25 +82,25 @@ Most calendar apps are mouse-driven, slow, and cluttered. Aion takes a different
### Features
-| Feature | Description |
-|---------|-------------|
-| **⌨️ Vim Keybindings** | Navigate with `j`/`k`, `gg`/`G`, `h`/`l` — feels like home |
-| **📅 Visual Timeline** | Day view with 15-minute precision and overlap handling |
-| **🔗 Google Calendar Sync** | Multi-account OAuth with PKCE, background sync every 30s |
-| **🗓️ CalDAV Support** | iCloud, Fastmail, Nextcloud, Radicale, and any CalDAV server |
-| **👥 Meet With** | Find free slots across multiple people's calendars |
-| **📹 Google Meet** | Auto-generate Meet links when creating events |
-| **📁 Multi-Calendar** | Toggle calendars on/off, each with its own color |
-| **🌍 Timezone Support** | Events display in local time, toggle to see original timezone |
-| **🎨 Themeable** | Customize every color via TOML configuration |
-| **💾 Local-First** | SQLite database, your data stays yours |
-| **🔔 Notifications** | Track pending invites at a glance |
-| **📝 Command Palette** | Quick access to all actions with fuzzy search |
-| **🔍 Event Search** | Find events by title or description with `/` |
-| **🗓️ Natural Language Dates** | Type "tomorrow 3pm" or "next friday for 2 hours" |
-| **🔁 Recurring Events** | Create and edit events with daily/weekly/monthly/yearly recurrence |
-| **❓ Context Help** | Press `?` anywhere to see available keybindings |
-| **🚀 Fast** | Built with Bun and React — instant startup |
+| Feature | Description |
+| ----------------------------- | ------------------------------------------------------------------ |
+| **⌨️ Vim Keybindings** | Navigate with `j`/`k`, `gg`/`G`, `h`/`l` — feels like home |
+| **📅 Visual Timeline** | Day view with 15-minute precision and overlap handling |
+| **🔗 Google Calendar Sync** | Multi-account OAuth with PKCE, background sync every 30s |
+| **🗓️ CalDAV Support** | iCloud, Fastmail, Nextcloud, Radicale, and any CalDAV server |
+| **👥 Meet With** | Find free slots across multiple people's calendars |
+| **📹 Google Meet** | Auto-generate Meet links when creating events |
+| **📁 Multi-Calendar** | Toggle calendars on/off, each with its own color |
+| **🌍 Timezone Support** | Events display in local time, toggle to see original timezone |
+| **🎨 Themeable** | Customize every color via TOML configuration |
+| **💾 Local-First** | SQLite database, your data stays yours |
+| **🔔 Notifications** | Track pending invites and send native desktop alerts |
+| **📝 Command Palette** | Quick access to all actions with fuzzy search |
+| **🔍 Event Search** | Find events by title or description with `/` |
+| **🗓️ Natural Language Dates** | Type "tomorrow 3pm" or "next friday for 2 hours" |
+| **🔁 Recurring Events** | Create and edit events with daily/weekly/monthly/yearly recurrence |
+| **❓ Context Help** | Press `?` anywhere to see available keybindings |
+| **🚀 Fast** | Built with Bun and React — instant startup |
---
@@ -114,12 +117,12 @@ brew install aion
Download the latest release for your platform from the [Releases](https://github.com/semos-labs/aion/releases) page:
-| Platform | Binary |
-|----------|--------|
+| Platform | Binary |
+| --------------------- | ------------------- |
| macOS (Apple Silicon) | `aion-darwin-arm64` |
-| macOS (Intel) | `aion-darwin-x64` |
-| Linux (x64) | `aion-linux-x64` |
-| Linux (ARM64) | `aion-linux-arm64` |
+| macOS (Intel) | `aion-darwin-x64` |
+| Linux (x64) | `aion-linux-x64` |
+| Linux (ARM64) | `aion-linux-arm64` |
```bash
# Make executable (macOS/Linux)
@@ -242,65 +245,65 @@ Use `j`/`k` to move through events, `h`/`l` to switch panes, `Enter` to view det
### Navigation
-| Key | Action |
-|-----|--------|
-| `j` / `↓` | Move down / Next item |
-| `k` / `↑` | Move up / Previous item |
-| `h` / `←` | Previous day / column |
-| `l` / `→` | Next day / column |
-| `Tab` | Cycle focus between panes |
-| `` ` `` | Cycle focus (Calendars → Days → Timeline) |
-| `gg` | Jump to first item |
-| `G` | Jump to last item |
-| `n` | Jump to now (timeline only) |
-| `Ctrl+G` | Go to date (natural language) |
+| Key | Action |
+| --------- | ----------------------------------------- |
+| `j` / `↓` | Move down / Next item |
+| `k` / `↑` | Move up / Previous item |
+| `h` / `←` | Previous day / column |
+| `l` / `→` | Next day / column |
+| `Tab` | Cycle focus between panes |
+| `` ` `` | Cycle focus (Calendars → Days → Timeline) |
+| `gg` | Jump to first item |
+| `G` | Jump to last item |
+| `n` | Jump to now (timeline only) |
+| `Ctrl+G` | Go to date (natural language) |
### Events
-| Key | Action |
-|-----|--------|
-| `Enter` / `Space` | Open event details |
-| `e` | Edit event |
-| `D` | Delete event |
-| `Ctrl+N` | Create new event |
-| `Ctrl+M` | Meet with... (find free slots) |
+| Key | Action |
+| ----------------- | ------------------------------ |
+| `Enter` / `Space` | Open event details |
+| `e` | Edit event |
+| `D` | Delete event |
+| `Ctrl+N` | Create new event |
+| `Ctrl+M` | Meet with... (find free slots) |
### Event Details
-| Key | Action |
-|-----|--------|
-| `y` | Accept invitation |
-| `n` | Decline invitation |
-| `m` | Maybe / Tentative |
+| Key | Action |
+| --- | ------------------------------------------- |
+| `y` | Accept invitation |
+| `n` | Decline invitation |
+| `m` | Maybe / Tentative |
| `o` | Open meeting link (Meet, Zoom, Teams, etc.) |
-| `e` | Edit event |
-| `D` | Delete event |
-| `t` | Toggle timezone (local ↔ original) |
+| `e` | Edit event |
+| `D` | Delete event |
+| `t` | Toggle timezone (local ↔ original) |
### Calendars & Accounts
-| Key | Action |
-|-----|--------|
-| `Shift+C` | Toggle calendars sidebar |
-| `A` | Toggle all-day events section |
+| Key | Action |
+| --------- | ----------------------------- |
+| `Shift+C` | Toggle calendars sidebar |
+| `A` | Toggle all-day events section |
### View
-| Key | Action |
-|-----|--------|
-| `3` | Toggle between 1 and 3 column view |
+| Key | Action |
+| ------- | ----------------------------------------- |
+| `3` | Toggle between 1 and 3 column view |
| `` ` `` | Cycle focus (Calendars → Days → Timeline) |
### General
-| Key | Action |
-|-----|--------|
-| `/` | Search events |
-| `:` | Open command palette |
-| `?` | Show help (context-aware) |
-| `N` | Open notifications |
-| `Esc` | Close overlay / Go back |
-| `q` | Quit |
+| Key | Action |
+| ----- | ------------------------- |
+| `/` | Search events |
+| `:` | Open command palette |
+| `?` | Show help (context-aware) |
+| `N` | Open notifications |
+| `Esc` | Close overlay / Go back |
+| `q` | Quit |
---
@@ -310,57 +313,57 @@ Open the command palette with `:` and type a command:
### Event Management
-| Command | Action |
-|---------|--------|
-| `new` | Create new event |
+| Command | Action |
+| ------------- | ----------------------- |
+| `new` | Create new event |
| `new ` | Create event with title |
-| `edit` | Edit selected event |
-| `delete` | Delete selected event |
+| `edit` | Edit selected event |
+| `delete` | Delete selected event |
### Navigation
-| Command | Action |
-|---------|--------|
+| Command | Action |
+| ------------- | ----------------------------------------------------- |
| `goto ` | Jump to date (e.g., `goto tomorrow`, `goto march 15`) |
-| `now` | Jump to current time |
-| `today` | Jump to today |
+| `now` | Jump to current time |
+| `today` | Jump to today |
### Accounts & Sync
-| Command | Action |
-|---------|--------|
-| `login` | Add Google account (OAuth) |
-| `caldav` | Add CalDAV account |
-| `logout` | Remove all accounts |
-| `sync` | Force sync all calendars |
-| `accounts` | Manage connected accounts |
-| `calendars` | Toggle calendars sidebar |
+| Command | Action |
+| ----------- | -------------------------- |
+| `login` | Add Google account (OAuth) |
+| `caldav` | Add CalDAV account |
+| `logout` | Remove all accounts |
+| `sync` | Force sync all calendars |
+| `accounts` | Manage connected accounts |
+| `calendars` | Toggle calendars sidebar |
### Scheduling
-| Command | Action |
-|---------|--------|
-| `meet` | Find free slots with other people |
+| Command | Action |
+| ------- | --------------------------------- |
+| `meet` | Find free slots with other people |
### Search
-| Command | Action |
-|---------|--------|
+| Command | Action |
+| -------- | ---------------------------------- |
| `search` | Search events by title/description |
### View
-| Command | Action |
-|---------|--------|
+| Command | Action |
+| ------------- | ----------------------------- |
| `columns ` | Set column count (1, 3, or 5) |
### General
-| Command | Action |
-|---------|--------|
-| `help` | Show keybindings |
+| Command | Action |
+| --------------- | ------------------------ |
+| `help` | Show keybindings |
| `notifications` | Open notifications panel |
-| `quit` | Exit application |
+| `quit` | Exit application |
Navigate with `↑`/`↓` or `Ctrl+P`/`Ctrl+N`, auto-fill with `Ctrl+Y`, select with `Enter`.
@@ -370,14 +373,14 @@ Navigate with `↑`/`↓` or `Ctrl+P`/`Ctrl+N`, auto-fill with `Ctrl+Y`, select
When creating or editing events, you can use natural language for dates and times:
-| Input | Result |
-|-------|--------|
-| `tomorrow 3pm` | Tomorrow at 3:00 PM |
-| `next friday at 10am` | Next Friday at 10:00 AM |
-| `in 2 hours` | 2 hours from now |
-| `today at 5pm for 30 minutes` | Today 5:00-5:30 PM |
-| `from march 5 for 2 weeks` | All-day event, March 5-19 |
-| `between march 6 and 12` | All-day event, March 6-12 |
+| Input | Result |
+| ----------------------------- | ------------------------- |
+| `tomorrow 3pm` | Tomorrow at 3:00 PM |
+| `next friday at 10am` | Next Friday at 10:00 AM |
+| `in 2 hours` | 2 hours from now |
+| `today at 5pm for 30 minutes` | Today 5:00-5:30 PM |
+| `from march 5 for 2 weeks` | All-day event, March 5-19 |
+| `between march 6 and 12` | All-day event, March 6-12 |
---
@@ -425,12 +428,12 @@ password = "app-password-here"
#### Provider URLs
-| Provider | Server URL |
-|----------|-----------|
-| **iCloud** | `https://caldav.icloud.com` |
-| **Fastmail** | `https://caldav.fastmail.com/dav/calendars` |
-| **Nextcloud** | `https://your-server.com/remote.php/dav` |
-| **Radicale** | `https://your-server.com/radicale` |
+| Provider | Server URL |
+| ----------------------- | ------------------------------------------------- |
+| **iCloud** | `https://caldav.icloud.com` |
+| **Fastmail** | `https://caldav.fastmail.com/dav/calendars` |
+| **Nextcloud** | `https://your-server.com/remote.php/dav` |
+| **Radicale** | `https://your-server.com/radicale` |
| **Google** (via CalDAV) | `https://apidata.googleusercontent.com/caldav/v2` |
> **Tip:** For iCloud, use an [app-specific password](https://support.apple.com/en-us/102654) — not your Apple ID password.
@@ -456,6 +459,21 @@ passwordCommand = "bw get password icloud-caldav"
passwordCommand = "echo $CALDAV_PASSWORD"
```
+### Desktop Notifications
+
+Aion can send native desktop notifications for new pending invites and provider-defined event reminders. Reminder alerts use Google Calendar reminders and CalDAV `VALARM` data only; Aion does not invent a fallback reminder time.
+
+```toml
+[desktop-notifications]
+enabled = true
+invites = true
+event_reminders = true
+poll_seconds = 30
+terminal_bell_fallback = true
+```
+
+On Linux, native delivery depends on the notification tools available to `node-notifier`, such as `notify-send`/libnotify. If native delivery fails and `terminal_bell_fallback` is enabled, Aion emits a terminal bell.
+
### Theme
```toml
@@ -519,22 +537,25 @@ If `~/.aion/` exists, Aion uses it for backward compatibility. All files are sto
New installations follow the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html):
**Configuration** (`~/.config/aion/`):
-| File | Description |
-|------|-------------|
-| `config.toml` | User configuration (Google credentials, CalDAV accounts, theme) |
-| `contacts.json` | Optional manual contacts for name lookup |
+
+| File | Description |
+| --------------- | --------------------------------------------------------------- |
+| `config.toml` | User configuration (Google credentials, CalDAV accounts, theme) |
+| `contacts.json` | Optional manual contacts for name lookup |
**Data** (`~/.local/share/aion/`):
-| File | Description |
-|------|-------------|
-| `aion.db` | SQLite database with all events |
-| `accounts.json` | OAuth tokens and account info |
-| `calendar-settings.json` | Calendar visibility preferences |
-| `account-settings.json` | Custom account names |
-| `sync-tokens.json` | Incremental sync tokens |
-| `logs/` | Application logs (daily rotation) |
+
+| File | Description |
+| ------------------------ | --------------------------------- |
+| `aion.db` | SQLite database with all events |
+| `accounts.json` | OAuth tokens and account info |
+| `calendar-settings.json` | Calendar visibility preferences |
+| `account-settings.json` | Custom account names |
+| `sync-tokens.json` | Incremental sync tokens |
+| `logs/` | Application logs (daily rotation) |
You can override XDG paths with environment variables:
+
- `XDG_CONFIG_HOME` (default: `~/.config`)
- `XDG_DATA_HOME` (default: `~/.local/share`)
@@ -542,16 +563,16 @@ You can override XDG paths with environment variables:
## Tech Stack
-| Component | Technology |
-|-----------|------------|
-| **Runtime** | [Bun](https://bun.sh) |
-| **UI Framework** | [Glyph](https://github.com/semos-labs/glyph) (React for terminals) |
-| **State Management** | [Jotai](https://jotai.org) |
-| **Database** | SQLite via [Drizzle ORM](https://orm.drizzle.team) |
-| **Date/Time** | [Luxon](https://moment.github.io/luxon) |
-| **NLP Dates** | [chrono-node](https://github.com/wanasit/chrono) |
-| **CalDAV** | [tsdav](https://github.com/natelindev/tsdav) + [ical.js](https://github.com/kewisch/ical.js) |
-| **Validation** | [Zod](https://zod.dev) |
+| Component | Technology |
+| -------------------- | -------------------------------------------------------------------------------------------- |
+| **Runtime** | [Bun](https://bun.sh) |
+| **UI Framework** | [Glyph](https://github.com/semos-labs/glyph) (React for terminals) |
+| **State Management** | [Jotai](https://jotai.org) |
+| **Database** | SQLite via [Drizzle ORM](https://orm.drizzle.team) |
+| **Date/Time** | [Luxon](https://moment.github.io/luxon) |
+| **NLP Dates** | [chrono-node](https://github.com/wanasit/chrono) |
+| **CalDAV** | [tsdav](https://github.com/natelindev/tsdav) + [ical.js](https://github.com/kewisch/ical.js) |
+| **Validation** | [Zod](https://zod.dev) |
---
@@ -580,6 +601,7 @@ You can override XDG paths with environment variables:
- [x] XDG Base Directory support
- [x] CalDAV support (iCloud, Fastmail, Nextcloud, Radicale, etc.)
- [x] `password_command` for secure credential storage
+- [x] Native desktop notifications for invites and provider reminders
### 🚧 In Progress
@@ -589,7 +611,6 @@ You can override XDG paths with environment variables:
- [ ] Import/export (ICS)
- [ ] Offline mode improvements
-- [ ] Custom notifications/reminders
- [ ] Agenda view (list of upcoming events)
- [ ] Event templates
From 7394b988374c41067cb0cdb1f76ac378dbf49c1f Mon Sep 17 00:00:00 2001
From: Brandon Pollack
Date: Thu, 4 Jun 2026 12:35:33 +0900
Subject: [PATCH 2/3] fix the edit/create dialog
needed to be wrapped in a box
---
bun.lock | 2 +-
src/ui/EventDialog.tsx | 12 +++++++-----
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/bun.lock b/bun.lock
index 121a083..1a1ce8a 100644
--- a/bun.lock
+++ b/bun.lock
@@ -6,7 +6,7 @@
"name": "aion",
"dependencies": {
"@iarna/toml": "^2.2.5",
- "@semos-labs/glyph": "0.2",
+ "@semos-labs/glyph": "^0.2.4",
"chrono-node": "^2.9.0",
"drizzle-orm": "^0.38.3",
"html-to-text": "^9.0.5",
diff --git a/src/ui/EventDialog.tsx b/src/ui/EventDialog.tsx
index 750c329..c49364f 100644
--- a/src/ui/EventDialog.tsx
+++ b/src/ui/EventDialog.tsx
@@ -106,6 +106,8 @@ export function EventDialog() {
// Calculate max dialog height (80% of screen)
const maxDialogHeight = Math.floor(terminalHeight * 0.8);
+ const dialogHeight = Math.max(8, Math.min(maxDialogHeight, terminalHeight));
+ const formHeight = Math.max(1, dialogHeight - 2);
const [summary, setSummary] = useState("");
const [description, setDescription] = useState("");
@@ -424,7 +426,7 @@ export function EventDialog() {
style={{
width: DIALOG_WIDTH,
maxWidth: DIALOG_WIDTH,
- maxHeight: maxDialogHeight,
+ height: dialogHeight,
flexDirection: "column",
paddingX: 1,
bg: theme.modal.background,
@@ -444,8 +446,8 @@ export function EventDialog() {
{/* Form fields - scrollable */}
-
-
+
+
{/* Title */}
title
@@ -809,8 +811,8 @@ export function EventDialog() {
>
)}
-
-
+
+
{/* Footer */}
From f58e77e0cbc823c2b849cb00a97cbf1f40a1ce1b Mon Sep 17 00:00:00 2001
From: Brandon Pollack
Date: Thu, 4 Jun 2026 12:43:47 +0900
Subject: [PATCH 3/3] Fix 3 button event double firing
---
src/ui/KeyboardHandler.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ui/KeyboardHandler.tsx b/src/ui/KeyboardHandler.tsx
index 12232f8..8e373d7 100644
--- a/src/ui/KeyboardHandler.tsx
+++ b/src/ui/KeyboardHandler.tsx
@@ -77,7 +77,7 @@ export function KeyboardHandler() {
{/* Toggle 3-day view - from registry */}
{toggleColumnsKey && !hasOverlay && (
- toggleColumns()} />
+ toggleColumns()} priority />
)}
>
);