Skip to content

supermem613/ComingUpNext

Repository files navigation

ComingUpNext Tray

A lightweight Windows 11 tray application that displays your next upcoming meeting from a public calendar ICS (.ics) feed.

It shows a dynamic tooltip with the next meeting title and time, and notifies you when the meeting is about to start. Optionally, it shows a hover/preview window with more details.

Screenshots

System tray + tooltip

System tray showing the dynamic tooltip for the next meeting

Context menu (right‑click)

Context menu with Open Meeting, Refresh, Set Calendar URL, Exit

Hover/preview window

Hover window showing upcoming meeting details and quick actions

Features

  • Tray icon with dynamic tooltip showing: Next: <Title> (In X min|In Y h|Mon HH:mm)
  • Auto balloon notification when a meeting is within 15 minutes (once per meeting)
  • Context menu: Open Meeting, Refresh, Set Calendar URL, Exit
  • Stores configuration in %APPDATA%/ComingUpNext/config.json
  • Lightweight ICS parsing (skips malformed events)
  • Configurable refresh interval (default 5 minutes) via RefreshMinutes in config.json or "Set Refresh Minutes" context menu option

ICS Format Expectations

Provide a publicly accessible .ics URL (can be from Outlook, Google Calendar, etc.). The app reads VEVENT blocks and uses:

  • SUMMARY → Meeting title
  • DTSTART → Start time (all-day events treated as midnight local)
  • DTEND → End time (if missing/invalid defaults to +1 hour)
  • URL → Meeting link (if present)
  • DESCRIPTION → Fallback scan for first http/https link if URL absent (helpful for Teams links embedded in description)

Example snippet:

BEGIN:VEVENT
SUMMARY:Daily Standup
DTSTART:20251030T090000Z
DTEND:20251030T091500Z
URL:https://teams.microsoft.com/l/meetup-join/...
END:VEVENT

Timezone & recurrence handling:

  • TZID= parameters on DTSTART/DTEND are respected (converted from that zone to local).
  • UTC times (Z suffix) converted to local.
  • Floating times (no TZ) treated as local.
  • Date-only values (YYYYMMDD) treated as all-day starting at local midnight.
  • Simple weekly RRULE patterns (e.g. FREQ=WEEKLY;BYDAY=MO,WE;INTERVAL=1;UNTIL=20261102T160000Z) are expanded for upcoming occurrences (up to 3 months lookahead or UNTIL limit) including exclusions via matching EXDATE.
  • EXDATE entries remove specific occurrences from recurrence expansion.

Limitations: Advanced recurrence (monthly rules, BYSETPOS, COUNT, exceptions with time shifts) is not yet supported.

Build & Run

Requires .NET 9 SDK.

# Build
dotnet build

# Run (from project directory)
cd src/ComingUpNextTray
dotnet run

On first run, use the tray icon context menu "Set Calendar URL" to paste the ICS URL. Optionally adjust the refresh interval with "Set Refresh Minutes" (1-1440). The default is 5 minutes. You can force an immediate reload at any time with the "Refresh" context menu item (it disables while fetching to avoid overlapping requests).

Packaging

Produce a single-file self-contained executable:

dotnet publish src/ComingUpNextTray/ComingUpNextTray.csproj -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true -o publish

The output folder publish will contain the EXE. Version metadata (AssemblyVersion/FileVersion/Product Version) is taken from the <Version> property inside ComingUpNextTray.csproj.

MSI Installer (WiX v5)

An example WiX v5 setup is provided under installer/.

Prerequisites:

  • .NET 10 SDK
  • WiX Toolset v5 (installed automatically by the build script if missing)

Build the MSI (auto-reads <Version> from the csproj):

cd installer
./build.ps1 -Configuration Release -Runtime win-x64

Result: installer/ComingUpNextTray-X.Y.Z.msi where X.Y.Z is the version from the project file.

To override the version just for a build (without editing the csproj), pass -Version:

./build.ps1 -Configuration Release -Runtime win-x64 -Version 1.2.3

This stamps the EXE (assembly/file/product) and the MSI Package version consistently.

Adjustments:

  • Update GUID placeholders in installer/Product.wxs (generate new GUIDs via New-Guid).
  • Change Manufacturer, Version, or add more components (e.g., config file defaults).
  • To auto-start for current user you can add a shortcut component pointing to Startup folder or set Run key (advanced customization).

Silent install example:

msiexec /i ComingUpNextTray-1.0.0.msi /qn

Uninstall:

msiexec /x ComingUpNextTray-1.0.0.msi /qn

If you modify published output location or add resources, re-run the build script to regenerate harvested components.

Tools

This repository includes two small CLI tools under the tools/ folder useful for debugging and reproducing the app's behavior against .ics feeds.

  • CalendarInspector (tools/CalendarInspector)

    • Purpose: Download or read an ICS payload and print diagnostic information including raw VEVENT blocks, parsed entries and a recurrence expansion log. Useful to inspect what the parser actually sees and how recurrences expand.
    • Usage (download a URL or read a file):
       # URL (will attempt to GET the feed)
       dotnet run --project "tools\CalendarInspector\CalendarInspector.csproj" "https://example.com/calendar.ics"
      
       # Local file
       dotnet run --project "tools\CalendarInspector\CalendarInspector.csproj" "C:\path\to\calendar.ics"
    • Notes: The inspector prints raw VEVENT blocks and a summary of parsed entries; it does not apply the app's next-meeting selection rules (it's focused on parsing diagnostics).
  • NextMeetingInspector (tools/NextMeetingInspector)

    • Purpose: Mimics the tray application's selection logic and prints the single next meeting chosen by the app. It reuses CalendarService and NextMeetingSelector so behavior should match the running tray app closely.
    • Usage (URL-only):
       dotnet run --project "tools\NextMeetingInspector\NextMeetingInspector.csproj" "https://example.com/calendar.ics" [ignoreFreeOrFollowing:true|false]
      • The ignoreFreeOrFollowing flag is optional and defaults to true (matches the app's default behavior).
    • Notes and troubleshooting:
      • The tool expects an absolute http or https URL. It uses the same HTTP fetch logic as the tray app (conditional requests, ETag/Last-Modified handling) where applicable.
      • Some calendar providers (Exchange/Office365) may require a public/share link or authentication; if you get HTTP 401/403 or HTTP 400, verify the URL is a public ICS export link or supply an appropriate authenticated feed.
      • The tool injects a browser-like User-Agent header to improve compatibility with servers that reject non-browser clients.

Auto Start (Optional)

Create a shortcut to the published EXE in:

%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup

Future Improvements

  • Add Windows Toast notifications using Windows App SDK for richer UX
  • Optional filtering (e.g. ignore all-day events or past events spanning multiple days)

License

See LICENSE.

About

Windows tray app to show next meeting coming up

Resources

License

Stars

Watchers

Forks

Packages

No packages published