summaryrefslogtreecommitdiff
path: root/internal/api/google_calendar.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-07-13 17:52:10 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-16 02:42:31 +0000
commitc4066f78d83b1440155248f9bc724b905aa88697 (patch)
tree70b557a1e340f12aa125fd0c53effabcbda4027b /internal/api/google_calendar.go
parentfb41a5eb47a4213c3f9a7095da4b8741f1598725 (diff)
feat(widget): tap event to open its source directly, drop detail popup
Tapping a calendar event (or any event-type item) now opens the event's URL (Google Calendar, Plan to Eat, etc.) directly instead of showing an intermediate popup with an "Open in Calendar" button. Removes EventDetailActivity and the recurrence-schedule lookup it was the only consumer of: WidgetRepository.getRecurrence, the Go /api/widget/recurrence endpoint, HandleWidgetRecurrence, GoogleCalendarAPI.GetRecurrenceRule, and formatRecurrence, plus their tests. RecurringEventID itself stays -- it's general calendar-sync metadata used elsewhere in the timeline pipeline, not exclusive to the removed popup.
Diffstat (limited to 'internal/api/google_calendar.go')
-rw-r--r--internal/api/google_calendar.go98
1 files changed, 0 insertions, 98 deletions
diff --git a/internal/api/google_calendar.go b/internal/api/google_calendar.go
index bb17812..f441a45 100644
--- a/internal/api/google_calendar.go
+++ b/internal/api/google_calendar.go
@@ -5,7 +5,6 @@ import (
"fmt"
"log"
"sort"
- "strconv"
"strings"
"time"
@@ -84,86 +83,6 @@ func deduplicateEvents(events []models.CalendarEvent) []models.CalendarEvent {
return unique
}
-var recurrenceFreqNames = map[string]string{
- "DAILY": "daily",
- "WEEKLY": "weekly",
- "MONTHLY": "monthly",
- "YEARLY": "yearly",
-}
-
-var recurrenceFreqUnits = map[string]string{
- "DAILY": "day",
- "WEEKLY": "week",
- "MONTHLY": "month",
- "YEARLY": "year",
-}
-
-var recurrenceWeekdayNames = map[string]string{
- "SU": "Sunday",
- "MO": "Monday",
- "TU": "Tuesday",
- "WE": "Wednesday",
- "TH": "Thursday",
- "FR": "Friday",
- "SA": "Saturday",
-}
-
-// formatRecurrence turns Google Calendar RRULE strings into short English.
-// This intentionally covers only the common cases (FREQ, INTERVAL, BYDAY) --
-// not a full RFC 5545 parser. Anything it can't confidently describe falls
-// back to "Recurring event" rather than showing nothing or an error.
-func formatRecurrence(rrules []string) string {
- for _, rule := range rrules {
- rule = strings.TrimPrefix(rule, "RRULE:")
- parts := make(map[string]string)
- for _, kv := range strings.Split(rule, ";") {
- pieces := strings.SplitN(kv, "=", 2)
- if len(pieces) == 2 {
- parts[pieces[0]] = pieces[1]
- }
- }
-
- freqKey := parts["FREQ"]
- unit, ok := recurrenceFreqUnits[freqKey]
- if !ok {
- continue
- }
-
- interval := 1
- if iv := parts["INTERVAL"]; iv != "" {
- if n, err := strconv.Atoi(iv); err == nil && n > 0 {
- interval = n
- }
- }
-
- var phrase string
- if interval == 1 {
- phrase = "Repeats " + recurrenceFreqNames[freqKey]
- } else {
- phrase = fmt.Sprintf("Repeats every %d %ss", interval, unit)
- }
-
- if byday := parts["BYDAY"]; byday != "" {
- var days []string
- for _, code := range strings.Split(byday, ",") {
- code = strings.TrimSpace(code)
- if len(code) >= 2 {
- code = code[len(code)-2:]
- }
- if name, ok := recurrenceWeekdayNames[code]; ok {
- days = append(days, name)
- }
- }
- if len(days) > 0 {
- phrase += " on " + strings.Join(days, ", ")
- }
- }
-
- return phrase
- }
- return "Recurring event"
-}
-
// NewGoogleCalendarClient creates a client that fetches from multiple calendars.
// calendarIDs can be comma-separated (e.g., "cal1@group.calendar.google.com,cal2@group.calendar.google.com")
// timezone is the IANA timezone name for display (e.g., "Pacific/Honolulu")
@@ -285,20 +204,3 @@ func (c *GoogleCalendarClient) GetCalendarList(ctx context.Context) ([]models.Ca
return calendars, nil
}
-// GetRecurrenceRule looks up a recurring event's master record and returns
-// its formatted recurrence schedule. Google's API only puts the RRULE on
-// the master event, not on expanded instances (see parseEventTime's
-// SingleEvents(true) callers), so this does a live lookup by the instance's
-// RecurringEventId. There's no per-event calendar attribution stored today
-// (events from all configured calendars are merged without recording which
-// one they came from), so this tries each configured calendar in turn.
-func (c *GoogleCalendarClient) GetRecurrenceRule(ctx context.Context, recurringEventID string) (string, error) {
- for _, calendarID := range c.calendarIDs {
- event, err := c.srv.Events.Get(calendarID, recurringEventID).Do()
- if err != nil {
- continue
- }
- return formatRecurrence(event.Recurrence), nil
- }
- return "", fmt.Errorf("recurring event %s not found on any configured calendar", recurringEventID)
-}