# ── Feature metadata ────────────────────────────────────────────────────────── $FeatureMeta = @{ Name = 'SandwichReminder' Description = 'Ask if you want to order a sandwich when at work at the configured time' Settings = @( @{ Key = 'network' Label = 'Work Network DNS Suffix' Type = 'string' Default = 'sioen.grp' Description = 'DNS suffix that identifies the work network' }, @{ Key = 'reminderTime' Label = 'Reminder Time (HH:mm)' Type = 'string' Default = '09:00' Description = 'Time to show the reminder in 24-hour format (e.g. 09:00)' }, @{ Key = 'windowMinutes' Label = 'Time Window (minutes)' Type = 'int' Default = 5 Description = 'Show the reminder if the runner fires within this many minutes of the reminder time' }, @{ Key = 'url' Label = 'Order URL' Type = 'string' Default = 'https://ylos-kitchen.unipage.eu' Description = 'URL to open when clicking Yes' } ) } # ── Feature implementation ──────────────────────────────────────────────────── function Invoke-Feature { param( [hashtable]$Config, [hashtable]$State ) if (-not $State) { $State = @{} } if (-not $State.ContainsKey('lastShownDate')) { $State['lastShownDate'] = $null } if (-not $State.ContainsKey('snoozeUntil')) { $State['snoozeUntil'] = $null } $today = (Get-Date).ToString('yyyy-MM-dd') # Only show once per day if ($State['lastShownDate'] -eq $today) { Write-Log -Level Info -Message 'Already shown today, skipping.' -Feature 'SandwichReminder' return $State } if ($State['snoozeUntil']) { try { $snoozeUntil = [datetime]::Parse($State['snoozeUntil']) if ((Get-Date) -lt $snoozeUntil) { Write-Log -Level Info ` -Message ("Snoozed until {0}, skipping." -f $snoozeUntil.ToString('HH:mm:ss')) ` -Feature 'SandwichReminder' return $State } } catch { Write-Log -Level Warn -Message "Invalid snoozeUntil value '$($State['snoozeUntil'])', ignoring." -Feature 'SandwichReminder' } } # Parse reminder time try { $targetTime = [datetime]::ParseExact($Config['reminderTime'], 'HH:mm', $null) } catch { Write-Log -Level Error ` -Message "Invalid reminderTime format '$($Config['reminderTime'])' — expected HH:mm: $_" ` -Feature 'SandwichReminder' return $State } # Check whether we are within the configured time window $now = Get-Date $todayTarget = Get-Date -Hour $targetTime.Hour -Minute $targetTime.Minute -Second 0 $diffMinutes = [Math]::Abs(($now - $todayTarget).TotalMinutes) $window = [int]$Config['windowMinutes'] if ($diffMinutes -gt $window) { Write-Log -Level Info ` -Message ("Outside time window (diff: {0:F1} min, window: ±{1} min), skipping." -f $diffMinutes, $window) ` -Feature 'SandwichReminder' return $State } # Check network if (-not (Test-DnsSuffixConnected -Suffix $Config['network'])) { Write-Log -Level Info ` -Message "Not connected to work network ('$($Config['network'])'), skipping." ` -Feature 'SandwichReminder' return $State } Write-Log -Level Info -Message 'Showing sandwich reminder confirmation dialog.' -Feature 'SandwichReminder' $decision = Show-MultiChoiceDialog ` -Title 'Sandwich Order' ` -Message 'Do you want to order a sandwich today?' ` -Feature 'SandwichReminder' ` -DefaultValue 'snooze15' ` -Choices @( @{ Label = 'Order now'; Value = 'order' }, @{ Label = 'Snooze 15 min'; Value = 'snooze15' }, @{ Label = 'Snooze 1h'; Value = 'snooze60' }, @{ Label = 'No'; Value = 'no' } ) if ($decision -eq 'order') { try { Start-Process $Config['url'] Write-Log -Level Info -Message "Opened sandwich order URL: $($Config['url'])" -Feature 'SandwichReminder' } catch { Write-Log -Level Error -Message "Failed to open sandwich order URL '$($Config['url'])': $_" -Feature 'SandwichReminder' } $State['lastShownDate'] = $today $State['snoozeUntil'] = $null } elseif ($decision -eq 'snooze60') { $until = (Get-Date).AddHours(1) $State['snoozeUntil'] = $until.ToString('o') Write-Log -Level Info -Message ("User snoozed sandwich reminder for 1 hour (until {0})." -f $until.ToString('HH:mm:ss')) -Feature 'SandwichReminder' } elseif ($decision -eq 'no') { $State['lastShownDate'] = $today $State['snoozeUntil'] = $null Write-Log -Level Info -Message 'User selected No for sandwich reminder; skipping for rest of day.' -Feature 'SandwichReminder' } else { $until = (Get-Date).AddMinutes(15) $State['snoozeUntil'] = $until.ToString('o') Write-Log -Level Info -Message ("User snoozed sandwich reminder for 15 minutes (until {0})." -f $until.ToString('HH:mm:ss')) -Feature 'SandwichReminder' } return $State }