| 484 | } |
| 485 | |
| 486 | export class RecurrenceContextMenu { |
| 487 | private menu: ContextMenu; |
| 488 | private options: RecurrenceContextMenuOptions; |
| 489 | private translate: (key: TranslationKey, vars?: Record<string, string>) => string; |
| 490 | |
| 491 | constructor(options: RecurrenceContextMenuOptions) { |
| 492 | this.menu = new ContextMenu(); |
| 493 | this.options = options; |
| 494 | this.translate = options.plugin.i18n.translate.bind(options.plugin.i18n); |
| 495 | this.buildMenu(); |
| 496 | } |
| 497 | |
| 498 | private buildMenu(): void { |
| 499 | const recurrenceOptions = this.getRecurrenceOptions(); |
| 500 | |
| 501 | // Add quick recurrence options |
| 502 | recurrenceOptions.forEach((option) => { |
| 503 | // Handle separator |
| 504 | if (option.label.startsWith("─")) { |
| 505 | this.menu.addSeparator(); |
| 506 | return; |
| 507 | } |
| 508 | |
| 509 | this.menu.addItem((item) => { |
| 510 | let title = option.label; |
| 511 | |
| 512 | if (option.icon) { |
| 513 | item.setIcon(option.icon); |
| 514 | } |
| 515 | |
| 516 | // Highlight current selection with visual indicator |
| 517 | if (option.value === this.options.currentValue) { |
| 518 | title = `✓ ${option.label}`; |
| 519 | } |
| 520 | |
| 521 | item.setTitle(title); |
| 522 | |
| 523 | item.onClick(async () => { |
| 524 | const anchorValue = option.anchor || "scheduled"; |
| 525 | this.options.onSelect(option.value, anchorValue); |
| 526 | }); |
| 527 | }); |
| 528 | }); |
| 529 | |
| 530 | // Add separator before custom options |
| 531 | this.menu.addSeparator(); |
| 532 | |
| 533 | // Add custom recurrence option |
| 534 | this.menu.addItem((item) => { |
| 535 | item.setTitle(this.translate("components.recurrenceContextMenu.customRecurrence")); |
| 536 | item.setIcon("settings"); |
| 537 | item.onClick(async () => { |
| 538 | this.showCustomRecurrenceModal(); |
| 539 | }); |
| 540 | }); |
| 541 | |
| 542 | // Add clear option if there's a current value |
| 543 | if (this.options.currentValue) { |
nothing calls this directly
no outgoing calls
no test coverage detected