Commit graph

63 commits

Author SHA1 Message Date
Callum Alpass
b4d52c707d feat: Implement UTC Anchor principle for robust timezone handling
This commit introduces the UTC Anchor principle to eliminate timezone-related bugs
and provide consistent date handling across all user timezones.

## Key Changes:

### Core Implementation
- Add `parseDateToUTC()` function that creates UTC anchors for date-only strings
- Add `parseDateToLocal` alias for existing `parseDate` function
- Deprecate direct `parseDate` usage with clear migration path
- Update date comparison functions to use UTC anchors

### Updated Components
- **dateUtils.ts**: New UTC parsing functions and updated comparisons
- **main.ts**: Use UTC anchor for selectedDate initialization
- **MiniCalendarView**: Navigate using UTC anchors
- **TimeblockCreationModal**: Fix timezone handling
- **Multiple test files**: Fix timezone assumptions in tests

### Refactored parseDate Usage
- **UnscheduledTasksSelectorModal**: Use parseDateToLocal for UI display
- **AdvancedCalendarView**: Use parseDateToLocal for calendar events
- **helpers.ts**: Use parseDateToUTC for internal date logic
- **FilterService**: Already using updated utilities

### Documentation
- Add comprehensive UTC Anchor implementation docs
- Update development guidelines with date handling best practices
- Add migration guide for existing code
- Include quick reference for date functions

## Benefits:
- Eliminates "off-by-one day" errors across timezones
- Provides consistent sorting and filtering behavior
- Simplifies date comparison logic
- Future-proofs against timezone-related bugs

## Testing:
- All 798 tests passing
- New UTC anchor test suite (11 tests)
- No regression in existing functionality

Fixes #327, #322, #314 and other timezone-related issues
2025-08-02 22:54:11 +10:00
Callum Alpass
1690abc04b refactor: Remove formatUTCDateForCalendar function
BREAKING CHANGE: formatUTCDateForCalendar has been removed. Use formatDateForStorage instead.

## Changes
- Replaced all calls to formatUTCDateForCalendar with formatDateForStorage
- Removed the redundant formatUTCDateForCalendar function from dateUtils.ts
- Updated all source files (10 files)
- Updated all test files (38 test files)
- Updated documentation to remove references

## Rationale
The formatUTCDateForCalendar function was misleading as it actually used local
date methods, not UTC. It was just calling formatDateForStorage internally,
making it redundant. This refactoring improves code clarity by having a single
function with a clear purpose.

All tests pass (765 total, 717 passing, 48 skipped).
2025-08-02 10:04:49 +10:00
Callum Alpass
edb01c335e fix: Comprehensive timezone handling fixes (Issues #327, #322, #314)
BREAKING CHANGE: Date handling now consistently uses local timezone for all user-facing operations

## Major Changes

### Core Timezone Fix
- Fixed critical RRule/local date boundary bug in helpers.ts that caused recurring tasks to show on wrong days
- Standardized all date formatting to use formatDateForStorage() which returns local dates
- Eliminated inconsistent use of format() vs formatUTCDateForCalendar()

### Files Updated
- **dateUtils.ts**: Added getTodayLocal(), parseDateAsLocal(), hasTimeComponent() utilities
- **helpers.ts**: Fixed isDueByRRule to use formatDateAsUTCString for RRule compatibility
- **TaskService.ts**: Updated all format() calls to use formatDateForStorage()
- **AdvancedCalendarView.ts**: Consistent use of formatDateForStorage() throughout
- **TaskEditModal.ts**: Fixed calendar navigation to use local dates
- **PomodoroService.ts**: Updated all date formatting
- **FilterService.ts**: Fixed getDatePart to use formatDateForStorage
- **AgendaView.ts**: Updated date formatting
- **main.ts**: Updated initialization
- **TaskCard.ts**: Minor formatting updates

### Test Updates
- Updated 700+ tests to match new timezone behavior
- Fixed test expectations to use local dates instead of UTC
- Removed outdated timezone simulation tests
- All tests now pass (765 total, 717 passing, 48 skipped)

### Documentation
- Added comprehensive TIMEZONE_HANDLING_GUIDE.md for developers
- Added TIMEZONE_QUICK_REFERENCE.md cheat sheet
- Created TIMEZONE_FIXES_WORKING_MEMORY.md tracking all changes

## Technical Details

The system now follows a "UTC Midnight Convention":
1. User-facing operations use local dates (what users see and input)
2. RRule operations internally use UTC but convert at boundaries
3. Storage format "YYYY-MM-DD" represents local date consistently

This fixes:
- Issue #327: Recurring tasks marking wrong day complete
- Issue #322: Timezone bugs in calendar display
- Issue #314: Complete instances timezone inconsistencies
- Off-by-one errors for users in different timezones

## Migration Notes

Developers should:
- Use formatDateForStorage() instead of format(date, 'yyyy-MM-dd')
- Use getTodayLocal() instead of new Date() for today's date
- Use parseDateAsLocal() for date-only strings
- Refer to TIMEZONE_HANDLING_GUIDE.md for best practices
2025-08-02 08:53:01 +10:00
Callum Alpass
b9ea6e6120 fix: Timezone bug in recurring task calendar display (Issue #322)
Convert start/end dates to UTC before passing to rrule.between() to ensure
consistent timezone handling. This prevents Tuesday recurring tasks from
appearing on Monday for users in negative UTC timezones.

The bug occurred because dtstart was in UTC but the date range parameters
were in local time, causing off-by-one day errors in the calendar display.
2025-07-30 07:05:40 +10:00
Callum Alpass
aad6885ca6 refactor: Update date utilities to use UTC methods consistently
Update remaining date helper functions to use UTC methods for
consistency with the timezone bug fixes. This ensures all date
comparisons and calculations work consistently across timezones.

Changes:
- Convert isSameDay() to use UTC date methods
- Update legacy recurrence date comparisons to use UTC
- Fix date arithmetic in default date generation
- Update date iteration loops to use UTC methods

These changes complement the timezone fix in Issue #314 by
ensuring all date utilities work consistently with UTC dates.
2025-07-28 22:20:29 +10:00
Callum Alpass
081ba61602 fix: Add proper error handling for createDailyNote failures
Fixes critical bugs where createDailyNote() could fail and return null/undefined,
causing "Cannot read properties of undefined" errors when accessing file.path
or file.extension properties.

Changes:
- TimeblockCreationModal.ts: Add validation after createDailyNote()
- PomodoroService.ts: Add validation in addSingleSessionToDailyNote() and updateDailyNotePomodoros()
- utils/helpers.ts: Add validation in addTimeblockToDailyNote()

All functions now throw clear error messages directing users to check their
Daily Notes plugin configuration when daily note creation fails.

Resolves user-reported errors:
- "Error creating timeblock: TypeError: Cannot read properties of undefined (reading 'path')"
- "Failed to add session to daily note: TypeError: Cannot read properties of undefined (reading 'extension')"
2025-07-28 22:20:29 +10:00
Callum Alpass
b585873c9d fix: Resolve recurring task completion timezone off-by-one bug
This commit fixes a critical timezone bug where "Mark complete for this date"
was storing completion dates inconsistently, causing tasks to appear incomplete
when they should show as complete.

## Root Cause Analysis

The bug occurred due to inconsistent date formatting between different components:

1. **Calendar Storage**: AdvancedCalendarView stores recurring instances using
   `formatUTCDateForCalendar(date)` producing UTC date strings like "2025-01-21"

2. **Context Menu Parsing**: When right-clicking a recurring task, the stored
   UTC date string was parsed by `parseDate("2025-01-21")` which treated it as
   local timezone midnight (e.g., Jan 21 00:00 local time)

3. **Double Conversion Issue**: The local Date object was then passed to
   `formatUTCDateForCalendar()` which extracted UTC components, causing timezone
   shifts (e.g., Jan 21 00:00 CET becomes Jan 20 23:00 UTC)

4. **Storage Mismatch**: Completion got stored for Jan 20 while user expected Jan 21

## Technical Changes

### Consistent UTC Formatting (src/services/TaskService.ts, src/ui/TaskCard.ts, src/main.ts, src/utils/helpers.ts)
- Changed all recurring task completion functions to use `formatUTCDateForCalendar()`
- Ensures completion storage, checking, and display all use same UTC date format
- Functions affected:
  * `TaskService.toggleRecurringTaskComplete()`
  * `TaskCard` context menu completion check
  * `main.isRecurringTaskCompleteForDate()`
  * `helpers.getRecurringTaskCompletionText()`

### Calendar Context Menu Fix (src/views/AdvancedCalendarView.ts:1588)
- Fixed parsing of `instanceDate` by appending `T00:00:00Z` to treat as UTC
- Prevents double timezone conversion: `parseDate(instanceDate + 'T00:00:00Z')`
- Ensures calendar context menu uses exact same date as calendar display

## Impact

 **BEFORE**: "Mark complete for this date" on Jan 21 → stored as Jan 20 completion
 **AFTER**: "Mark complete for this date" on Jan 21 → stored as Jan 21 completion

 Fixes off-by-one errors across all timezone scenarios:
  - AEST (UTC+10): Late evening UTC → early morning local
  - JST (UTC+9): Late evening UTC → midnight local
  - CET (UTC+1): Late evening UTC → midnight local
  - PST (UTC-8): Early morning UTC → late evening previous day
  - EST (UTC-5): Early morning UTC → late evening previous day

 All timezone-specific tests now pass with "BUG FIXED" status
 Resolves GitHub Actions CI test failures for timezone edge cases
 Consistent behavior between inline completion and calendar completion

## Testing

Comprehensive test coverage in `tests/unit/issues/off-by-one-completion-timezone-bug.test.ts`:
- Multi-timezone validation (5 different timezones)
- User experience simulation tests
- Consistency verification between completion methods
- Edge case handling for timezone boundaries

This fix ensures reliable recurring task completion behavior regardless of user timezone.
2025-07-26 15:07:29 +10:00
Callum Alpass
0ab16d2e9e fix: Resolve timezone-based off-by-one bugs in calendar recurrence
Replace format(date, 'yyyy-MM-dd') with formatUTCDateForCalendar(date) in
TaskService.ts and helpers.ts to ensure consistent UTC-based date handling
across different user timezones. This prevents weekly recurring tasks from
appearing on incorrect days (e.g., Tuesday tasks showing on Monday dates).

The fix addresses GitHub issue #237 where calendar recurrence was
timezone-dependent, causing different behavior for users in different
time zones. Added comprehensive test coverage for timezone scenarios
and edge cases to prevent regression.
2025-07-25 21:48:35 +10:00
Callum Alpass
3a9e2dff25 fix: ensure projects load in edit modal (#141)
- Add missing projects field to TaskInfo construction in extractTaskInfo
- Fix timing issue where projects list renders before UI elements exist
- Ensure projects are displayed correctly in both creation and edit
modals
2025-07-08 18:51:59 +10:00
Callum Alpass
9315c94d2e refactor: use Obsidian's parseLinktext API and debounce utility
- Replace custom wikilink parsing with parseLinktext API for consistency
- Use Obsidian's built-in debounce utility instead of custom implementation
- Update all wikilink handling to use standardized parsing
- Remove custom debounce function from helpers and tests
2025-07-08 17:38:21 +10:00
Callum Alpass
baf8510239 refactor: remove redundant template processing functions from helpers.ts
- Remove duplicate generateTaskBodyFromTemplate() and processTaskTemplateVariables() functions
- These functions were redundant with the modern templateProcessor.ts implementation
- TaskService already uses the comprehensive processTemplate() from templateProcessor.ts
- Update test mocks and unit tests to remove references to deleted functions
- Integration tests handle the missing functions gracefully with conditional checks

This eliminates ~50 lines of duplicate code and ensures templateProcessor.ts is the
single source of truth for template processing functionality.
2025-07-06 09:54:54 +10:00
Callum Alpass
c7ca1c353c feat: implement comprehensive projects system with note-based linking
- Add dedicated projects field supporting [[Note Name]] links to any vault notes
- Create ProjectSelectModal for intuitive project note selection with fuzzy search
- Implement multi-project support with proper filtering and grouping functionality
- Add clickable project links in task cards that navigate to project notes
- Update FilterBar with working project filters using proper link resolution
- Support project grouping in all views (TaskList, Kanban) with multi-group display
- Add robust project caching system that extracts projects from linked notes
- Include comprehensive validation to filter empty/invalid project values
- Remove NLP +project syntax to simplify natural language processing
- Fix T00:00 date parsing errors in recurring task complete_instances
- Add full template variable support with {{parentNote}} YAML list formatting
- Maintain backward compatibility with existing plain text projects
- Add comprehensive test coverage and accessibility features

Resolves: GitHub issue #118 discussion requirements
Fixes: FilterBar loading issues and date parsing console errors
2025-07-05 18:54:39 +10:00
Callum Alpass
d061d280b3 fix: Resolve all failing tests for filename feature implementation
- Fix TaskService to handle cache and event errors gracefully in updateTask method
- Add storeTitleInFilename parameter to extractTaskInfo helper function
- Update TaskEditModal to pass storeTitleInFilename setting correctly
- Enhance Obsidian mock with getMarkdownFiles method for test compatibility
- Fix migration workflow tests with proper mock setup and error scenarios
- All 506 tests now pass successfully
2025-06-30 20:07:59 +10:00
Callum Alpass
d061be4f37 feat: Add option to store task title exclusively in filename (#106)
This commit introduces a new setting that allows users to store the task
title exclusively in the filename, removing the 'title' property from
the frontmatter. This simplifies the frontmatter but disables filename
templating.

Key Changes:
- **Settings:** Added a  boolean option to the plugin settings with a UI
toggle in the Task Defaults tab.
- **Filename Generation:** Updated  to use the task title as the
filename when the new setting is enabled, bypassing other filename
generation logic.
- **Field Mapping:**
    - Modified  in  to prevent writing the title to the frontmatter when
the new setting is enabled.
    - Updated  to extract the title from the filename if it's not
present in the frontmatter, ensuring backward compatibility with
existing tasks.
- **Services:** Updated  and  to pass the  setting to the field mapper.

This change provides users with more control over their data storage and
simplifies the frontmatter for new tasks created with this option
enabled.
2025-06-30 19:25:41 +10:00
Callum Alpass
bdcce83237 Add actions read permission to docs workflow 2025-06-29 12:39:17 +10:00
Callum Alpass
e500369f07 Ensure UTC-based dtstart handling for RRULE to prevent timezone issues (#85)
• Introduced a new utility function, createUTCDateForRRule, in dateUtils.ts. This function extracts the date portion from a given date string, validates its format (YYYY-MM-DD), and returns a UTC Date set at midnight. This adjustment guarantees that the day of the week is preserved correctly, which is critical for accurate RRULE recurrence calculations.

• Updated helpers.ts to import and utilize createUTCDateForRRule instead of parseDate. Now, when determining the anchor date (dtstart) for recurring tasks, whether using the scheduled date or the fallback dateCreated, the function ensures that the produced dtstart is in UTC. This change also affects target date calculations in isDueByRRule by converting the target date to a UTC midnight date before evaluating for occurrences.

• Extended the test suite:
  - Added extensive unit tests in tests/unit/utils/dateUtils.test.ts to verify createUTCDateForRRule functionality. The tests cover scenarios such as:
      • Standard date-only strings producing the correct UTC ISO string.
      • Preservation of the correct day-of-week for various dates.
      • Extraction of the date part from datetime strings.
      • Handling of leap years and year boundary dates.
      • Proper error handling for invalid date formats.

  - Enhanced the helpers-rrule.test.ts file with new test cases focusing on timezone-safe behavior. The tests validate that:
      • dtstart for scheduled dates (and fallback dateCreated) is correctly set in UTC, preventing timezone shifts.
      • Consistency between generateRecurringInstances and isDueByRRule methods.
      • Proper handling of edge cases such as DST transitions and year boundary crossings.
      • Graceful handling of RRULE parsing errors.

• The overall changes ensure that recurrence scheduling in the application uses UTC-based dates to eliminate potential issues arising from local timezone variations, especially in day-of-week calculations and recurrence definitions.

These modifications improve the reliability of recurring task calculations and ensure consistency across various timezone scenarios.
2025-06-27 23:22:22 +10:00
Callum Alpass
69443ad072 Refactor and cleanup various modules for improved type safety, streamlined DOM element creation, and updated legacy recurrence handling
• In src/main.ts, convert non-string task statuses to strings before fetching their configuration so that the displayed notice always shows a proper label.

• In src/modals/MigrationModal.ts, update the migration modal to use the persistent notice’s messageEl (instead of noticeEl) when creating the container div.

• In several modals (TaskSelectorModal, TimeblockCreationModal, UnscheduledTasksSelectorModal), remove or simplify unused imports (e.g. Notice) and streamline element creation by removing unnecessary variable assignments.

• In services (ICSSubscriptionService, PomodoroService, RequestDeduplicator), cast setTimeout returns to number via “as unknown as number” to improve TypeScript compatibility and ensure proper timer handling.

• In src/services/MigrationService and TaskLinkDetectionService, remove unused imports to keep the code lean.

• In src/services/NaturalLanguageParser.ts, remove unused date-fns functions, focusing only on required imports.

• In src/ui/NoteCard.ts and TaskCard.ts, simplify the creation of DOM elements by removing intermediate variable assignments; update the PomodoroView to reference plannedDuration instead of duration when calculating progress.

• In the utility modules (DOMReconciler, MinimalNativeCache, PerformanceMonitor), improve type annotations, simplify collection iteration (e.g. only iterating over needed keys) and consistently cast timer references.

• In src/utils/TasksPluginParser.ts, enhance the recurrence regex by adding the global and unicode flags and adjust the destructuring for more robust parsing.

• In src/utils/helpers.ts, update recurrence handling:
  – For RFC 5545 strings, use RRule-based evaluation and fall back to a simplified legacy recurrence check that now handles legacy objects inline.
  – Remove the previous legacy task recurrence handler in favor of this simplified inline logic.

• Finally, in views (MiniCalendarView and PomodoroView), ensure proper function typings (e.g. in debounce) and update progress calculations.

This commit overall improves type safety, reduces unused code, cleans up DOM-related logic, and revises recurrence handling for better consistency and performance.
2025-06-25 20:29:33 +10:00
Callum Alpass
d667e66472 Fix critical linting issues: reduce from 340 to 295 errors
- Add missing @codemirror/view dependency
- Replace deprecated substr() with substring() across multiple files
- Remove unused imports and variables
- Fix navigator API usage (replace window.setTimeout with setTimeout)
- Fix await non-thenable issues in BaseTaskModal
- Remove unused variables in modals and views

Key fixes:
• BaseTaskModal.ts: Fixed all substr deprecations and removed unused variables
• DueDateModal.ts: Removed unused imports and fixed navigator API usage
• ConfirmationModal.ts: Removed unused variable
• ICSEventInfoModal.ts: Fixed navigator API usage
• ScheduledDateModal.ts: Removed unused imports
• TaskCreationModal.ts: Removed unused imports
• TaskEditModal.ts: Removed unused imports
• TaskListView.ts: Fixed await non-thenable issue
• ICSSubscriptionService.ts: Fixed substr deprecation
• AdvancedCalendarView.ts: Fixed substr deprecations in color parsing
• helpers.ts: Fixed substr deprecation in ID generation

This brings us closer to a clean codebase by addressing the most critical
functional errors and deprecated API usage.
2025-06-25 07:14:48 +10:00
Callum Alpass
0c4122685b Use getRecurrenceDisplayText to Render Human-Readable Recurrence Information (#64)
- Added a new helper function, getRecurrenceDisplayText, in src/utils/helpers.ts that converts an rrule string or legacy RecurrenceInfo object to a human-readable text using the RRule.toText() method.
- Updated TaskCard.ts (in createTaskCard and updateTaskCard) to use getRecurrenceDisplayText instead of manually checking the recurrence type and extracting the frequency. This simplifies label definitions for the recurring indicator (aria-labels) and recurrence metadata.
- With this change, recurring tasks now display a more descriptive recurrence text, improving UI clarity and consistency when showing recurring task details.
- Additionally, errors during conversion are caught and logged, ensuring a fallback to 'rrule' if the conversion fails.

Overall, these modifications streamline the conversion logic and enhance the user interface by providing clear recurrence information.
2025-06-23 23:19:08 +10:00
Callum Alpass
a6e3a1715f Enhance Recurrence Handling & Update Modal UI for Task and Calendar Views
This commit introduces multiple improvements across task recurrence logic, modal UI components, and calendar/task list views. The changes are summarized as follows:

1. BaseTaskModal Updates:
   • Added help text for the "due date" field clarifying its role as a task deadline, separate from recurrence end dates.
   • Revised help text for "scheduled date" to be more succinct.
   • Updated recurrence help text to emphasize that recurring tasks appear in calendar views only when a scheduled date is set.
   • Modified the frequency dropdown event handler to:
       – Query for interval and end condition containers within the same container rather than the parent.
       – Immediately update the interval input value and its unit when the frequency changes.
   • Refactored the creation of the interval input so that its elements are always created and then conditionally hidden if frequency is not set.
   • Changed the access level of updateIntervalUnit and updateRRuleFrequencyOptions methods from private to protected for easier inheritance.

2. MigrationModal Styling:
   • Adjusted the layout of the migration prompt by switching to a column-based flex layout.
   • Increased gap and padding between elements for better visual spacing.
   • Applied updated line-height and margin to the migration message for improved readability.
   • Updated button container styling to justify content to the flex-end and align items centrally.

3. TaskCreationModal UI Improvements:
   • Moved the Recurrence section to be created in the detailedFormContainer for consistency with other fields.
   • Inserted additional white space and improved grouping of UI controls during creation and toggling of detailed form elements.

4. Recurrence Logic Enhancements in FilterService and Helpers:
   • Replaced the usage of isRecurringTaskDueOn with the new isDueByRRule function to compute task recurrence based on the full rrule string.
   • Updated recurrence date checks in FilterService so that tasks are properly grouped/displayed based on scheduled and due dates, including avoiding duplicate events.
   • Simplified the generation of recurring instances in helper methods by removing reliance on the task’s due date for the UNTIL condition, with the expectation that the rrule string contains complete recurrence info.

5. View Updates (AdvancedCalendarView, AgendaView, MiniCalendarView, TaskListView):
   • Updated import references to use the new recurrence helper functions (isDueByRRule, generateRecurringInstances, and shouldShowRecurringTaskOnDate) replacing legacy ones.
   • In AdvancedCalendarView, changed recurring task handling to require a scheduled date for display and adjusted rules for non-recurring tasks to check for either due or scheduled dates.
   • Removed obsolete action buttons from TaskListView header.
   • Ensured consistency in recurring task computation throughout all views.

6. CSS Improvements (modal-bem.css):
   • Added new styles to support the interval input components with labels, input fields, and unit spans.
   • Introduced styles for the rrule options container, monthly/yearly options, and end condition options.
   • Updated styling for the detailed form container specific to TaskCreationModal, providing better spacing, padding, and transitions.
   • Refined button, grid, and modal element spacing for a more visually appealing modal layout.

These changes enhance the recurrence system’s clarity and reliability while improving the overall user interface and experience in both modals and calendar views.
2025-06-23 21:43:42 +10:00
Callum Alpass
f25769238f Add rrule-based recurrence system & legacy migration support
• Upgrade version from 3.5.0 to 3.7.1 and update package dependencies:
  – In package-lock.json and package.json, bump version.
  – Add new dependencies “chrono-node” and “rrule” and update “dayjs”.

• Introduce new MigrationService and MigrationModal:
  – Create MigrationService (in src/services/MigrationService.ts) to scan task files for legacy RecurrenceInfo objects (stored as objects) and convert them into RFC 5545 rrule strings.
  – Add MigrationModal (src/modals/MigrationModal.ts) that prompts users to run the migration, displays progress, and reports errors.
  – Initialize MigrationService in main.ts and check for migration needs on startup, showing a migration prompt if needed.

• Refactor recurrence handling to use the rrule format:
  – Update BaseTaskModal (src/modals/BaseTaskModal.ts) to replace the old “recurrence” dropdown with a new “RRule Builder” that enables users to select frequency, interval, weekly, monthly, and yearly options.
  – Add helper methods to parse, generate, and display human-readable rrule strings.
  – Provide UI controls for selecting:
      • Frequency (None, Daily, Weekly, Monthly, Yearly)
      • Interval input (with updated unit display)
      • Weekly options (day checkboxes) using RRule weekdays
      • Monthly options with “day” or “weekday” modes, including set position selectors for nth weekday patterns
      • Yearly options (month and day)
      • End conditions (never, until date, or count)
  – Update methods to reflect changes immediately in a human-readable summary.

• Update task creation and editing flows:
  – In TaskCreationModal (src/modals/TaskCreationModal.ts), replace the recurrence dropdown with the new rrule builder and adapt logic to store recurrence as an rrule string.
  – In TaskEditModal (src/modals/TaskEditModal.ts), support both new rrule strings and legacy RecurrenceInfo objects by converting legacy data to rrule.
  – Adjust validation logic (e.g. ensuring weekly recurrence has selected days, monthly recurrence has valid day or weekday configuration, etc).

• Update UI elements and helper functions:
  – Modify TaskCard (src/ui/TaskCard.ts) to display a recurrence indicator that shows “rrule” if the recurrence is in the new format.
  – Update helper functions (src/utils/helpers.ts) to include:
      • isDueByRRule for checking occurrences of rrule-based tasks
      • generateRecurringInstances for generating recurrence dates using rrule
      • convertLegacyRecurrenceToRRule, which converts legacy RecurrenceInfo objects to RFC 5545 strings

• Update settings and type definitions:
  – Add a setting flag (recurrenceMigrated) in settings to track whether migration has been performed.
  – Adjust RecurrenceInfo types (src/types.ts) to allow recurrence to be a legacy object or an rrule string.

This commit lays the foundation for a more powerful, standards‑compatible recurrence system while ensuring a seamless user experience through background migration of legacy data.
2025-06-23 20:11:14 +10:00
Callum Alpass
f120a305fb Update timer usage to window-bound timer functions and adjust task conversion UI behavior
• Replaced calls to setTimeout, setInterval, clearTimeout, and clearInterval with their window-bound counterparts (window.setTimeout, window.setInterval, window.clearTimeout, window.clearInterval) across the code base. This ensures consistency in a browser context and avoids potential Node.js timer type discrepancies.

  - Updated in files including src/main.ts, src/modals/*, src/services/ICSSubscriptionService.ts, src/services/PomodoroService.ts, src/settings/settings.ts, src/ui/NoteCard.ts, src/utils/DOMReconciler.ts, src/utils/MinimalNativeCache.ts, src/utils/RequestDeduplicator.ts, src/utils/helpers.ts, src/views/KanbanView.ts, src/views/MiniCalendarView.ts, and src/views/TaskListView.ts.
  - Changed timer variable types from NodeJS.Timeout to number where applicable to reflect browser timer return types.

• Enhanced TaskCreationModal behavior to improve task conversion UX:

  - When a task conversion is detected (via conversionOptions.parsedData), the detailed form is now shown by default.
  - Adjusted conditions throughout the modal to ensure natural language input components and filename preview behave correctly during conversions.
  - Updated auto-focus logic for the title and textarea fields based on conversion state.

These changes improve reliability and clarity by standardizing timer function usage in the browser and refining the task conversion user interface behavior.
2025-06-21 08:49:33 +10:00
Callum Alpass
7d484c458b Update timeblock helpers to use native Obsidian YAML parsing
- Replace YAMLCache.extractFrontmatter with new extractFrontmatter helper
- Use parseYaml/stringifyYaml from Obsidian instead of external YAML library
- Remove manual cache invalidation calls
- Maintain all timeblock functionality with native caching system
2025-06-18 22:09:26 +10:00
Callum Alpass
dfdbe9fa99 Merge main into timeblocking branch and update for new caching system
- Resolve merge conflicts in helpers.ts and AdvancedCalendarView.ts
- Update TimeblockCreationModal to use Obsidian's native YAML parsing
- Replace YAMLCache usage with parseYaml/stringifyYaml from Obsidian
- Remove manual cache invalidation calls (native cache handles this)
- Preserve all timeblocking functionality while adapting to MinimalNativeCache architecture
2025-06-18 22:07:08 +10:00
Callum Alpass
693f0911d8 remove tree-shaking date-fns 2025-06-18 06:37:03 +10:00
Callum Alpass
737219e696 Refactor date-fns imports and remove legacy YAMLCache integration
• Update all date-fns imports across the codebase to use granular default imports (e.g. "import format from 'date-fns/format'") rather than named imports. This change applies to numerous files (TaskLinkWidget, main, all modals, FilterService, ICSSubscriptionService, PomodoroService, TaskService, NoteCard, TaskCard, filenameGenerator, templateProcessor, various views, etc.) and helps with tree shaking and smaller bundle sizes.

• Remove the YAMLCache module entirely. Instead, YAML parsing and caching are now handled directly by CacheManager. In main.ts, CacheManager is initialized with the app instance and any YAMLCache-related clearing calls now include comments noting that YAML cache functionality is integrated into CacheManager.

• Enhance CacheManager functionality:
  – Add a new App property to CacheManager (passed via constructor) to facilitate using Obsidian’s native metadataCache.
  – Replace manual frontmatter parsing (via YAMLCache) with a new getFrontmatter() method that extracts metadata using app.metadataCache.
  – Update methods such as extractTaskInfo and extractNoteInfo to accept the app and file objects as parameters and use native metadata caching.
  – Remove explicit calls to YAMLCache.clearCacheEntry/clearCache throughout, with inline comments reflecting the updated caching strategy.

• Propagate the updates to helper functions:
  – Modify extractTaskInfo in helpers.ts to require the app instance and TFile, then use the metadataCache to obtain YAML frontmatter.
  – Update extractNoteInfo similarly to use the native metadata cache.

• Minor updates to utility modules (e.g. dateUtils, filenameGenerator, TasksPluginParser) and views to reflect the new date-fns import style and ensure consistent usage.

This commit modernizes our dependency import pattern for date-fns and consolidates YAML parsing/caching into CacheManager, reducing redundancy and improving maintainability across the plugin’s codebase.
2025-06-17 19:58:01 +10:00
Callum Alpass
38650c59ef feat: Add comprehensive timeblocking feature for daily scheduling
## Features
- Toggle timeblocking in calendar settings
- Create timeblocks via Shift+drag on calendar
- Store timeblocks in daily note frontmatter
- Drag & drop timeblocks between dates and resize
- Markdown link attachments support
- Visual distinction from tasks in calendar

## Technical Implementation
- TimeBlock interface with validation
- TimeblockCreationModal for user-friendly creation
- FullCalendar integration with proper event identification
- Cross-date timeblock movement functionality
- YAML frontmatter persistence in daily notes

## User Experience
- Hold Shift + drag to create timeblocks
- Drag to move between dates
- Resize edges to adjust duration
- Optional color, description, and attachments
- Click timeblocks to view details

Addresses timeblocking requirements for lightweight schedule items
that integrate with the advanced calendar view.
2025-06-16 22:35:34 +10:00
Callum Alpass
6f0bd021ba Update YAML parsing/serialization to use Obsidian's native helpers
• In TaskService.ts, replace YAML.stringify with Obsidian’s stringifyYaml to generate the YAML header.
• In CacheManager.ts and YAMLCache.ts, switch from YAML.parse to Obsidian’s parseYaml for YAML parsing, ensuring consistency with Obsidian’s internal parsing behavior.
• In templateProcessor.ts, use parseYaml instead of YAML.parse after processing template variables.
• Remove an unused YAML import from helpers.ts as it’s no longer necessary.

These changes improve integration with Obsidian’s API and standardize YAML operations across the plugin.
2025-06-16 21:08:43 +10:00
Callum Alpass
e90f541f2f Add ICS subscription support and refine task template processing
• Introduce ICSSubscriptionService to handle external calendar feeds (ICS/iCal):
 – New file (ICSSubscriptionService.ts) implements loading, saving, fetching, caching, and periodic refreshing of ICS subscriptions.
 – Supports error handling, recurring event expansion, and event cache expiration.
 – Service is integrated into the plugin lifecycle (initialized in main.ts and destroyed on cleanup).

• Update main plugin initialization (src/main.ts):
 – Import and instantiate ICSSubscriptionService.
 – Await service initialization during plugin startup.
 – Ensure clean-up of the ICS service during plugin unload.

• Enhance task creation and conversion:
 – Modify TaskCreationModal to set parentNote template variable (set to empty string for manual creation).
 – Update InstantTaskConvertService to capture the active file’s basename as parentNote.
 – In TaskService, update template application:
  * Replace previous generateTaskBodyFromTemplate with processTemplate.
  * Merge template frontmatter with base frontmatter (parentNote now available in template variables).

• Add new Template Processor (src/utils/templateProcessor.ts):
 – Parse full templates into frontmatter and body.
 – Process template variables including new {{parentNote}}.
 – Support merging updated template frontmatter with default task values.

• Update settings (src/settings/settings.ts and types.ts):
 – Add “Show ICS events” toggle to calendar view settings.
 – Extend CalendarViewPreferences and add ICSSubscription type definitions.
 – Enhance settings UI to allow users to configure and manage calendar subscriptions:
  * Add forms to create, edit, delete subscriptions (name, URL, color, refresh interval, enable/disable).
  * Render ICS subscription list with controls and status indicators.

• Update helpers (src/utils/helpers.ts) to support new template variable {{parentNote}}.

• Integrate ICS events into AdvancedCalendarView (src/views/AdvancedCalendarView.ts):
 – Read ICS events from ICSSubscriptionService when showICSEvents is enabled.
 – Create distinct calendar event objects for ICS feeds with proper styling.
 – Handle ICS event click events: show a read-only modal with event details and context menu actions.
 – Prevent moving/resizing of ICS events.
 – Listen to ICS service “data-changed” events to refresh the calendar view.

• Enhance styles (styles/advanced-calendar-view.css):
 – Add styles for ICS events, ICS event info modal, ICS context menus, and subscription management UI.
 – Ensure clear visual differentiation for ICS events and subscription status indicators.

This commit significantly expands plugin functionality to integrate external ICS calendars and enrich task template processing by including parent note context, as well as providing a comprehensive settings interface for calendar subscriptions.
2025-06-15 22:58:01 +10:00
Callum Alpass
a9c6db3652 Refactor daily notes implementation to use Obsidian core daily notes plugin
• Replace custom daily note logic with calls to “obsidian-daily-notes-interface”. In main.ts and PomodoroService, previous manual creation, reading, and cache rebuilding for daily notes have been removed and replaced by functions like createDailyNote, getDailyNote, getAllDailyNotes, and appHasDailyNotesPluginLoaded.

• Remove custom settings fields and UI for daily notes. The plugin no longer manages dailyNotesFolder or dailyNoteTemplate. Corresponding settings in settings.ts and the daily-notes tab in the Settings UI have been removed.

• Delete the local template generation helper in helpers.ts. Obsidian’s core daily notes plugin now supplies the template functionality.

• Update CacheManager to initialize and rebuild its daily notes cache using the core plugin’s API. The reworked indexing and update logic now reads daily note files via the provided functions and adjusts its cache accordingly.

• Update UI components (NoteCard and MiniCalendarView) to determine if a note is a daily note using the core plugin’s interface (getAllDailyNotes) instead of relying on a fixed folder path.

• Add error handling and informative notices when the Daily Notes core plugin isn’t enabled.

This commit consolidates daily notes functionality, removing redundancy and ensuring that the plugin now integrates seamlessly with Obsidian’s built-in daily notes support.
2025-06-15 14:11:55 +10:00
Callum Alpass
98b6f6ed86 Refactor Task Template Processing & Improve Link Generation & CSS Priority Styling (#37)
• Removed body template processing from TaskCreationModal:
  - The applyBodyTemplate() call and its associated logic were removed
from the modal.
  - The modal now simply pre-populates the textarea with any provided
details, ensuring the user’s input is maintained without automatic
template injection.

• Moved template logic to TaskService:
  - Introduced a new private async method applyBodyTemplate() in
TaskService.
  - This method now handles reading the template file (if enabled),
processing it with task data (including the new “details” field), and
returning the final content.
  - When creating a task file, the processed template content is
appended to the file content instead of using raw user details.

• Enhanced Template Variable Support:
  - Updated the helpers helper function processTaskTemplateVariables()
to include a new replacement for {{details}}, allowing user-provided
details to be inserted into templates.
  - Modified the settings help text to include an explanation for the
new {{details}} variable and clarify that the template is applied using
all final form values.

• Improved Instant Task Link Generation:
  - Added checks in InstantTaskConvertService to detect if the sanitized
title includes nested Obsidian links or problematic characters (|, #,
^).
  - If such characters are found, the generated link defaults to a
simple link format (without an alias) to avoid nested link structures.

• Updated CSS Styling for Task Cards & Inline Widgets:
  - In task-card-bem.css, updated comment to reflect that CSS variables
for priority are now set dynamically by TaskCard.ts.
  - In task-inline-widget.css, adjusted status and priority dot styles:
     • Changed the status dot color variable fallback to a fixed color
(#666).
     • Replaced the priority dot style with a priority border style
using left border colors, using distinct widths for high (4px), medium
(3px), and low priority tasks.

Overall, these changes reposition the template functionality to be
applied at task creation (rather than during modal pre-population), add
better handling for nested links in instant task conversion, extend
template variable support, and update styling for better visual cues.
2025-06-15 13:28:39 +10:00
Callum Alpass
8ed849b357 Refactor task widget styling and remove deprecated YAML update helpers
• Transition task status/priority styling from inline JavaScript to CSS variables:
  - In TaskLinkWidget.ts, removed the code that set the --status-color and --priority-color inline. With this change, the widget now relies on CSS to manage status and priority colors.
  - In TaskCard.ts, eliminated the explicit assignment of borderLeftColor in both createTaskCard and updateTaskCard. The card elements now use the CSS variable (--priority-color) to drive priority-based styling.

• Update CSS to support variable-based theming:
  - In task-card-bem.css, added a new rule for .task-card to set border-left-color from --priority-color (with a transparent fallback) and provided fallback colors for common priorities.
  - In task-inline-widget.css, adjusted the status and priority dot selectors:
      • Changed the status dot to use --current-status-color (with a muted text fallback).
      • Updated the priority dot to rely on --priority-color (with a muted fallback).
      • Reworked the priority-specific styles (high, normal/medium, low) to set the color property on the dot using dedicated CSS variables with appropriate fallbacks.

• Remove unused YAML update helper methods:
  - In helpers.ts, removed updateYamlFrontmatter and updateTaskProperty functions which are no longer used. This cleanup reduces code complexity and avoids maintaining legacy frontmatter manipulation logic.

These changes streamline the UI theming by centralizing color management in CSS and remove legacy code that was responsible for updating YAML frontmatter. This refactor makes future styling adjustments easier and promotes separation between presentation and business logic.
2025-06-14 07:32:15 +10:00
Callum Alpass
840448e580 feat(task defaults & templates): add task creation defaults, new settings tab, and body template processing
• Updated TaskCreationModal to use a new helper (calculateDefaultDate) for initializing dueDate and scheduledDate, allowing default dates to be calculated based on user-configured options. If a calendar date is selected, it still overrides defaults; otherwise, the default scheduled date is applied.

• In settings (settings.ts):
  - Extended TaskNotesSettings with a new TaskCreationDefaults interface to store default contexts, tags, time estimates, recurrence patterns, folder overrides, due/scheduled date options, and body template settings.
  - Added DEFAULT_TASK_CREATION_DEFAULTS object with sensible default values.
  - Modified the TaskNotesSettingTab to include a new “Task defaults” tab that splits out task creation settings. This tab now provides controls for:
      • Specifying default contexts, tags, time estimates, recurrence, and folder.
      • Configuring date defaults by choosing options for default due date and default scheduled date.
      • Enabling a body template feature with toggle support and a text field for specifying the template file path.
      • Displaying a help section that lists all available template variables (e.g., {{title}}, {{date}}, etc.) for dynamic template processing.
  - Enhanced the warning message styling by importing and using setIcon from obsidian for a more polished visual alert.

• In helpers (helpers.ts):
  - Extended generateTaskBodyFromTemplate function to process template variables using a newly added function processTaskTemplateVariables. This function replaces template placeholders like {{title}}, {{priority}}, {{status}}, and date/time formatted variables (supporting custom formats) at task creation.
  - Introduced calculateDefaultDate helper to compute default dates ('today', 'tomorrow', 'next-week' or none) based on the current date, ensuring consistent formatting (yyyy-MM-dd).

These changes improve the task creation UX by allowing customizable default task values and template-driven pre-population of task body content, enhancing both configurability and flexibility for users.
2025-06-13 23:28:40 +10:00
Callum Alpass
6d16b586f6 Improve task update mapping and cache management (#10)
• In FieldMapper.ts, removed redundant whitespace to clean up the
mapping logic.

• In TaskService.ts:
  - Revised frontmatter update logic to build a complete task data
object (completeTaskData) that starts from the original task, then
applies updates. This ensures that all current task fields are preserved
and only modified values are overwritten.
  - Adjusted handling of the completedDate: when marking a task
completed, a current date is set if not already present; otherwise, it
is removed.
  - Changed the approach for merging frontmatter by first clearing all
existing fields and then reapplying the full mapped frontmatter. This
prevents leftover, stale fields from persisting.
  - Improved the removal of fields (due, scheduled, contexts,
timeEstimate, completedDate, recurrence) by verifying if updates
explicitly set these values to undefined rather than just checking for
an undefined value in the updated data.
  - Enhanced tag handling to preserve existing tags if they are not
explicitly updated.

• In CacheManager.ts:
  - Imported and utilized YAMLCache to ensure that when a file is
removed from the cache, its corresponding YAMLCache entry is cleared as
well.
  - Optimized cache hit logic by storing the cached task in a variable
prior to returning it.

• In helpers.ts:
  - Introduced minor whitespace cleanup in extractTaskInfo for better
code consistency.

These changes enhance reliability when updating tasks, ensure all
necessary fields are maintained correctly in the frontmatter, and
improve cache invalidation consistency.
2025-06-11 22:33:56 +10:00
Callum Alpass
2bd7054e5b Implement Timezone-Safe Date Handling and Utilities Across the Codebase
This commit introduces a comprehensive solution for handling dates in a timezone-safe manner across the entire project. The changes address off-by-one errors and inconsistent date parsing/comparison issues by centralizing date logic in a new utility module, and refactoring all date operations to use these safe methods.

Key changes include:

1. Documentation & Migration Guide:
   • Added a new document (TIMEZONE_FIXES.md) detailing the root causes of date issues and explaining the new smart date utility functions.
   • Included migration guidelines to help developers transition from native Date operations and date-fns direct usage to the centralized utilities.

2. New Date Utilities (src/utils/dateUtils.ts):
   • Implemented a suite of functions including:
     - parseDate: Automatically detects and parses date-only or timezone-aware strings.
     - isSameDateSafe and isBeforeDateSafe: Robust date comparison functions that normalize dates before comparing.
     - normalizeDateString: Standardizes dates to YYYY-MM-DD.
     - getTodayString, getCurrentTimestamp, and getCurrentDateString: Provide consistent "current" dates/timestamps.
     - Additional helpers like createSafeDate, formatDateForDisplay, and parseTimestamp.
   • These functions ensure correct handling of timezones and provide consistent behavior for storage, display, and logical comparisons.

3. Modal Components:
   • Updated DueDateModal and ScheduledDateModal to use validateDateInput from the new date utilities instead of directly calling date-fns parse and isValid.
   • This change improves user input validation by ensuring that both date-only and timezone-aware formats are supported.

4. Task Creation & Edit Flows:
   • In TaskCreationModal and TaskEditModal, updated date fields (dateCreated, dateModified, completedDate) to use getCurrentTimestamp and getCurrentDateString for consistency.
   • Updated metadata displays in TaskEditModal to use formatTimestampForDisplay for a user-friendly presentation.

5. Task and Note Card Updates:
   • Refactored TaskCard and NoteCard components to leverage safe date comparison and formatting methods (e.g., isToday, isPastDate, formatDateForDisplay) for due and scheduled dates.
   • This ensures correct labeling (e.g., “Today”, “overdue”, or formatted dates) regardless of timezone discrepancies.

6. Cache and Service Layers:
   • Modified CacheManager, FilterService, InstantTaskConvertService, PomodoroService, and TaskService to replace direct Date object creation and manipulation with safe date functions.
   • Updates include proper handling when comparing and sorting dates, as well as ensuring the accurate storage of modification timestamps.

7. Helpers and Parser Adjustments:
   • Updated helper functions (e.g., isTaskOverdue, isRecurringTaskDueOn) and TasksPluginParser to utilize parseDate for reliable date parsing.
   • This minimizes chances of runtime errors due to invalid or improperly formatted dates.

Overall, the changes provide these benefits:
   - Eliminated off-by-one (timezone-induced) errors.
   - Ensured backward compatibility with existing date-only strings.
   - Centralized date handling logic to simplify maintenance and future bug fixes.
   - Improved performance by reducing redundant Date object creation through smart string-based operations.

These updates lay a robust foundation for all current and future date operations in the project, ensuring that the application behaves predictably across various timezones without introducing regressions.
2025-06-10 18:42:34 +10:00
Callum Alpass
0f5bb71705 Enhance error handling, accessibility, performance & resource cleanup across many components
• Refactored InstantConvertButtons.ts and TaskLinkOverlay.ts to remove hardcoded inline styles and redundant JS hover events. Instead, added validation methods and try-catch blocks for button click and editor state checks, logging warnings when necessary.

• Updated main.ts to perform thorough resource cleanup—now disposing filterService, taskLinkDetectionService, viewStateManager, DOMReconciler, UI state managers, and performance monitors on plugin unload.

• Significantly improved accessibility in BaseTaskModal.ts, DueDateModal.ts, ScheduledDateModal.ts, and TaskSelectorModal.ts by adding ARIA attributes, labelled inputs, descriptions, and keyboard navigation support (including focus management and proper ARIA roles).

• In settings (settings.ts), enhanced input and dropdown elements by adding descriptive aria-labels and roles; added keyboard navigation support and confirmation modals for deletion actions to improve user experience.

• Modified InstantTaskConvertService.ts to add robust input validation and task data verification before conversion. Enhanced error notification messages (e.g. for duplicate file names or invalid characters) and implemented race‐condition protection in the task line replacement process.

• Updated PomodoroService.ts to track and later clean up active AudioContexts and timeouts. Now clears all scheduled timeouts on cleanup to prevent memory leaks, and logs errors during sound playback.

• Added cleanup() methods to FilterService.ts, TaskLinkDetectionService.ts, and ViewStateManager.ts to remove event listeners and clear caches when no longer needed.

• In TaskService.ts, wrapped status toggling and property updates with try-catch blocks to log detailed error information (including file paths and stack traces) and surface user notices when updates fail.

• Enhanced CacheManager.ts by processing file and task info in one batch instead of fixed-size batches; introduced cache eviction methods for task, note, and YAML caches to prevent memory bloat and added detailed performance statistics.

• Updated DOMReconciler.ts and PerformanceMonitor.ts with destroy() methods to disconnect observers and clear timeouts, ensuring that resources are properly released on view teardown.

• Improved RequestDeduplicator.ts by tracking its active timeouts and ensuring they are cleared during cleanup.

• Strengthened TasksPluginParser.ts with input validations (e.g. length restrictions and type checks) and error messages when parsing task lines or extracting dates, ensuring that extremely long or invalid input strings are handled safely.

• Revised filenameGenerator.ts to validate inputs, sanitize strings for filenames (including handling reserved names and Windows path length limits) and fallback to safe defaults if necessary.

• In helpers.ts, enhanced error logging for YAML parsing operations by preserving stack traces and providing frontmatter previews.

• Across all views (AgendaView.ts, CalendarView.ts, KanbanView.ts, PomodoroStatsView.ts, PomodoroView.ts, TaskListView.ts), improved UI text (e.g. “New task” instead of “New Task”) and accessibility by updating headings, button labels, and error messages. CalendarView.ts now caches day-to-date mappings and uses debounced refreshes to optimize rendering performance.

• Updated CSS in components.css and pomodoro-view.css to define a dedicated BEM-based Instant Convert Button style with hover, active, and focus states, ensuring consistent visual feedback and adherence to design tokens.

These comprehensive changes collectively enhance robustness, user feedback, performance, and accessibility while ensuring proper resource cleanup and safer operations across the plugin.
2025-06-09 20:22:51 +10:00
Callum Alpass
5855d7c545 Enhance overdue task logic to check both due and scheduled dates
• In FilterService.ts:
  - Updated the overdue task filtering logic to include both due and scheduled dates.
  - Previously, only the due date was checked for tasks marked as overdue on the current day.
  - Now, if the task is due today and either the due date or scheduled date is overdue, the task will be flagged.

• In CacheManager.ts:
  - Modified the logic for indexing overdue tasks.
  - Previously, only the due date was considered to determine if a task should be added to the overdue index.
  - Now, the method checks both due and scheduled dates for overdue comparisons before adding the task to the overdue index.

• In helpers.ts:
  - Updated the isTaskOverdue() helper function to support both task.due and task.scheduled.
  - The function now safely attempts to parse and compare the dates for both fields.
  - If either date is found to be in the past relative to the start of today, the task is considered overdue.
  - Added error handling to log any issues encountered during date parsing.

These changes improve overdue task detection by ensuring that both due and scheduled dates are taken into account, leading to more robust scheduling and task management.
2025-06-09 14:35:50 +10:00
Callum Alpass
ef8614e5c3 Improve date handling, error reporting, and consistency across services and helpers
• Update date formatting:
  - In FilterService.ts and CacheManager.ts, replace native Date ISO string extraction (using toISOString().split('T')[0]) with date-fns’ format(date, 'yyyy-MM-dd') to ensure local timezone handling and consistency.

• Enhance safe date parsing:
  - Modify FilterService.ts methods (due date and scheduled date checks, as well as getDueDateGroupFromDate and getScheduledDateGroupFromDate) to use parseISO from date-fns wrapped in try…catch, providing error logging and graceful fallback (e.g., returning 'Invalid Date') when parsing fails.
  - Similarly, in helpers.ts, use parseISO and other date-fns utilities (startOfDay, isBefore) to safely parse and compare dates in isTaskOverdue and isRecurringTaskDueOn, with error handling to prevent unexpected failures.

• Improve note date extraction:
  - In CacheManager.ts and AgendaView.ts, adjust parsing for note createdDate values to handle both full ISO timestamps and simple YYYY-MM-DD formats, ensuring accurate date grouping and consistent comparisons in the agenda view.

• General consistency and robustness:
  - Replace multiple usages of "new Date(...)" with date-fns equivalents to standardize date operations across the codebase, reduce timezone-related issues, and enhance error handling.

This commit ensures more reliable date computation and formatting throughout the project while providing clear error notifications when parsing issues occur.
2025-06-09 14:03:01 +10:00
Callum Alpass
0165327bb6 feat: Remove legacy class names, cleanup legacy styles, and update code for BEM consistency
• Remove legacy CSS class names and fallbacks from NoteCard and TaskCard creation and update functions. Legacy selectors (e.g. “tasknotes-card”, “note-title”, “note-item”, “task-checkbox”, “status-dot”, “task-completed”) have been removed so that only the new BEM class names are applied and queried.

• Update the updateTaskProperty function in helpers.ts to use “default field names” instead of legacy field naming comments and mappings.

• Modify TaskListView.ts import statement to now include the Setting module from Obsidian.

• Update styles/README.md to reflect the new file hierarchy and structure that separates core system files, BEM component files, view-specific files, and legacy files.

• Remove multiple legacy CSS files – agenda.css, calendar.css, filters.css, kanban.css, modals.css, and tasks.css – that are now deprecated. Legacy styles in base.css have also been reduced, ensuring that only modern (BEM-based) styles remain in use.

This commit cleans up our codebase by removing deprecated legacy code and CSS, enforcing a consistent BEM methodology for UI elements, and updates documentation for better future maintainability.
2025-06-09 13:01:19 +10:00
Callum Alpass
9779775ebd Add Scheduled Date Support with Modal UI, Filtering, and Caching Updates
• Introduce scheduled date handling for tasks by adding a new property “scheduled” across the plugin.
• Add a new method, openScheduledDateModal(task: TaskInfo), to main.ts that lazily imports and opens the ScheduledDateModal.
• Create a new ScheduledDateModal (src/modals/ScheduledDateModal.ts) to allow users to set or clear a scheduled date. This modal includes:
  – A text input configured as a date picker,
  – Quick date buttons (Today, Tomorrow, Next week, Clear) for improved UX,
  – Validation of the user input date format,
  – Error handling and feedback in case of update failures.
• Update BaseTaskModal to include a scheduledDate property and provide a dedicated createScheduledDateInput() helper method for form creation.
• Enhance TaskCreationModal and TaskEditModal:
  – Initialize scheduledDate (default empty) when creating or editing tasks,
  – Render a new Scheduled Date form group in the modals,
  – Include scheduled date in the frontmatter when saving tasks.
• Extend FieldMapper to map the “scheduled” field from and to the frontmatter.
• Update FilterService to support:
  – Filtering tasks by either due or scheduled dates,
  – Sorting and grouping based on the “scheduled” key via new helper methods for grouping tasks (e.g., getScheduledDateGroupFromDate).
• Update settings (DEFAULT_FIELD_MAPPING) and types (TaskInfo, TaskFrontmatter, TaskSortKey, TaskGroupKey) to include the scheduled date field.
• Enhance UI components:
  – Modify FilterBar and TaskCard to display scheduled date metadata,
  – Add a context menu item (in TaskCard) to invoke the scheduled date modal via the calendar-clock icon.
• Update CacheManager to index tasks by scheduled date in addition to due dates:
  – Index tasks under both due and scheduled dates,
  – Provide new helper functions to retrieve tasks by due or scheduled date,
  – Ensure proper cleanup in cache indexes when task dates change.
• Adjust helper functions and AgendaView to consider scheduled dates when filtering and displaying tasks, thereby ensuring tasks with scheduled dates appear in the agenda view.

This commit fully integrates scheduled date functionality into the plugin, offering users an improved experience in scheduling, filtering, and viewing tasks based on both due and scheduled dates.
2025-06-09 07:17:28 +10:00
Callum Alpass
deb1afa896 feat: Add Pomodoro stats view and enhance recurring task UI
• Introduce a new PomodoroStatsView to display detailed session statistics.
  - Created a new file (src/views/PomodoroStatsView.ts) with UI components that render today’s progress, weekly summaries, overall statistics, and a list of recent work sessions.
  - Integrated refresh functionality and data calculations (e.g., current streak, average session length, completion rate) using data from the pomodoroService.

• Update the main plugin registration (src/main.ts):
  - Import the new PomodoroStatsView.
  - Register the POMODORO_STATS_VIEW_TYPE.
  - Add a command (‘open-pomodoro-stats’) to allow users to open the Pomodoro statistics view.
  - Add an activatePomodoroStatsView method to switch to the new view.
  - Ensure that when workspace leaves are detached, leaves of type POMODORO_STATS_VIEW_TYPE are also removed.

• Update task filtering and status management:
  - In FilterService.ts, update the “No Due Date” string to “No due date” for consistency.
  - In StatusManager.ts, add a new getNonCompletionStatuses method to retrieve status configurations excluding completed statuses—this is used to manage recurring tasks.

• Enhance recurring task UI and behavior in TaskCard component (src/ui/TaskCard.ts):
  - Modify task cards to detect recurring tasks and conditionally append a “recurring-task” CSS class.
  - Insert a recurring indicator icon in the task card for recurring tasks.
  - Update context menu logic to show only non-completion statuses (via getNonCompletionStatuses) for recurring tasks.
  - Add a menu item that toggles the completion state for recurring tasks for the current date.
  - Update the task card DOM structure (both initial creation and update) to add or remove the recurring indicator as needed.
  - Update the import statements to include new helper functions (shouldUseRecurringTaskUI and getRecurringTaskCompletionText).

• Extend helper functions (src/utils/helpers.ts):
  - Introduce shouldShowRecurringTaskOnDate to determine if a recurring task is due on a target date.
  - Add getRecurringTaskCompletionText to generate completion state text for a recurring task on a specific date.
  - Add shouldUseRecurringTaskUI to decide if recurring task UI behavior should be applied.

• Update PomodoroView (src/views/PomodoroView.ts):
  - Add a “View All Stats” button to the stats section that opens the PomodoroStatsView when clicked.

• Define new view type (src/types.ts):
  - Add constant POMODORO_STATS_VIEW_TYPE for consistent usage when registering and activating the stats view.

• Introduce new CSS styles (styles.css):
  - Add styling for recurring tasks (e.g., a colored left border and gradient background for cards marked as recurring).
  - Define styles for the recurring indicator element.
  - Implement comprehensive styles for the Pomodoro Stats view, including layout grids, header styling, cards for different statistics (pomodoros, streak, minutes, average session, completion rate), and styling for recent sessions.

This commit provides substantial enhancements by adding a focused Pomodoro statistics interface and by improving the handling and visual feedback for recurring tasks throughout the application.
2025-06-08 11:52:32 +10:00
Callum Alpass
288860b129 Commit: Refactor UI headings, normalize paths, and improve event handling
• Updated modal headings: In DueDateModal, TaskCreationModal, and TaskEditModal, replaced direct createEl heading elements (e.g., h2) with the new Setting API using .setName() and .setHeading() for a consistent UI style. In addition, updated minor text capitalization (e.g., “Next Week” → “Next week”, “Open Note” → “Open note”).

• Updated settings headers: In the settings tab functions (Field Mapping, Task Statuses, Task Priorities), replaced h3 element headings with Setting-based headings to maintain a uniform header style throughout the plugin.

• Improved TaskCard context menu: Modified the “Set Due Date…” menu title to “Set due date…” for consistency.

• Standardized path normalization: In CacheManager and helpers, replaced ad hoc regex replacements on daily/directory paths with Obsidian’s normalizePath. This change ensures consistent behavior when handling folder paths and prevents potential issues with trailing or leading slashes.

• Enhanced event registration in views: In NotesView, PomodoroView, and TaskListView, replaced direct addEventListener calls with registerDomEvent where appropriate, helping improve event management and prevent potential memory leaks. Also, replaced h2 headings in views with Setting headings (e.g., in PomodoroView header and statistics section, TaskListView date display, etc.) to adhere to the new UI standard.

Overall, these changes improve UI consistency across modals and views, standardize daily note path processing, and promote better event handling practices throughout the codebase.
2025-06-08 09:42:30 +10:00
Callum Alpass
dfaa1da3a4 Fix archive tag replacing task tag instead of adding alongside it
- Ensure task tag is preserved when archiving tasks in FieldMapper.mapToFrontmatter()
- Pass taskTag parameter through updateTaskProperty() call chain
- Archive tag now gets added to existing tags array instead of replacing task tag
- Archived tasks remain recognizable as tasks while also being marked as archived

Fixes #5
2025-06-05 20:41:12 +10:00
Callum Alpass
3250ddbd6a Refactor recurring task completion behavior and update UI task cache handling
• Rename and refactor toggleRecurringTaskStatus → toggleRecurringTaskComplete in src/main.ts:
  - Renamed the function to better reflect its purpose.
  - Removed the non-recurring branch and streamlined the flow for recurring tasks.
  - Instead of toggling general task “status”, the code now checks whether the task is marked complete for the selected date.
  - Updates the complete_instances array accordingly (adding or removing the date).
  - Updates the frontmatter with a new dateModified field via field mapping.
  - Updates the file indexer cache and clears YAMLCache before emitting granular EVENT_TASK_UPDATED with the updated task.

• Update helper behavior in src/utils/helpers.ts:
  - Use Array.isArray check for task.complete_instances when computing effective task status to ensure robustness.

• Improve TaskListView interactions in src/views/TaskListView.ts:
  - In the EVENT_TASK_UPDATED listener, add validation and error logging for missing data.
  - Simplify the recurring task toggle button click handler by directly calling toggleRecurringTaskComplete.
  - Remove temporary button disabling logic since granular updates now handle UI refresh.
  - Add additional logging and null-checks in performTaskElementUpdate.
  - Enhance safety checks in updateTaskInCache and getTaskFromCache to avoid processing invalid data.

These changes streamline recurring task completion toggling, improve data integrity with enhanced logging and null checks, and ensure UI updates are correctly propagated through the cache and event flows.
2025-06-04 22:21:16 +10:00
Callum Alpass
3f895192bb Refactor Date Handling, Field Mapping, and Recurring Task Updates
• Replace full refresh notification with a granular event emission when toggling recurring task status. In main.ts, the notifyDataChanged() call was removed and replaced by emitting an EVENT_TASK_UPDATED event with the task path to help avoid race conditions.

• Update TaskCreationModal.ts to standardize field creation:
 – Include dateCreated and dateModified fields in the initial task object.
 – Remove duplicate YAML frontmatter mapping logic by relying on the field mapper’s mapping to the user-configured field names.
 – This ensures newly created tasks carry consistent ISO timestamps for creation and modification, reducing redundancy.

• Enhance FieldMapper.ts by adding support for dateCreated and dateModified:
 – In mapFromFrontmatter(), check for dateCreated/dateModified values based on user field mapping.
 – In mapToFrontmatter(), also include these fields if provided by the task data.
 – This improves consistency between YAML storage and internal task representation.

• In PomodoroService.ts, update dateModified using the field mapper’s user field name for dateModified rather than the hardcoded key. This ensures that modifications during Pomodoro tracking respect custom field configurations.

• Update types.ts to extend the TaskInfo interface with optional dateCreated and dateModified fields, ensuring the types reflect the new data structure.

• Improve helper functions in helpers.ts:
 – When updating task properties, always update the dateModified field.
 – During YAML extraction, fall back to using a default FieldMapper (via DEFAULT_FIELD_MAPPING) for backward compatibility, ensuring legacy tasks correctly map modern fields.
 – This refactoring offers robust support for both legacy and new task definitions.

• In TaskListView.ts, remove direct manual cache and DOM updates after toggling recurring tasks. Additionally, update the toggle button’s UI properties to reflect the current effective completion status based on the updated task data.

Overall, this commit:
 – Standardizes handling of dateCreated and dateModified timestamps across task creation, updates, and Pomodoro modifications.
 – Improves consistency of field mapping and YAML generation.
 – Implements a more reliable granular event system for updating recurring tasks, thereby reducing race conditions.

This refactor ensures a smoother, more robust experience when creating, updating, and managing tasks.
2025-06-04 22:04:48 +10:00
Callum Alpass
c56b95a3b8 breaking change: Refactor time tracking and time entry handling across the codebase
• Updated time entry property names:
 – Renamed “start” to “startTime” and “end” to “endTime” to improve clarity
 – Removed the old “duration” and “timeSpent” fields in frontmatter and TaskInfo
 – Ensured backward compatibility by migrating old field names in helpers and frontmatter processors

• Enhanced helper utilities:
 – Added calculateDuration: Computes duration (in minutes) from ISO timestamps
 – Added calculateTotalTimeSpent: Aggregates total time from task timeEntries
 – Added getActiveTimeEntry: Returns the currently running time entry
 – Added formatTime: Formats minutes into a human-readable string
 – Updated extractTaskInfo to support both legacy and new time entry field names

• Adjusted main.ts time tracking flow:
 – Replaced inline property checks with calls to getActiveTimeEntry, calculateTotalTimeSpent, and formatTime
 – Removed duration calculation from within the UI update to rely on the new helper functions

• Cleaned up task creation and field mapping:
 – Removed assignment of “timeSpent” from TaskCreationModal and FieldMapper
 – Updated FieldMapper to omit “timeSpent” when mapping frontmatter fields

• Updated PomodoroService processing:
 – Changed time entry creation to use “startTime” and “endTime” with a fixed description
 – Removed any references to “timeSpent” and immediately deleted the old field after migration

• Modified settings and types:
 – Removed “timeSpent” from default field mappings and TypeScript types
 – Updated TaskInfo and TimeEntry interfaces to rely on new time entry properties
 – Added a new grouping key “status” in TaskGroupKey

• Refined UI components in AgendaView and TaskListView:
 – Replaced legacy timeSpent usage with dynamic calculations via calculateTotalTimeSpent
 – Updated progress calculations to use the new helper functions and reflect the correct time estimate progress
 – Extended TaskListView’s grouping options to include a “Status” filter and refined archive filtering logic

This commit standardizes the approach to time tracking, improves code clarity, and ensures future enhancements will work with a consistent set of time entry properties while maintaining compatibility with legacy data.
2025-06-03 23:02:22 +10:00
Callum Alpass
9dd3eebcb4 Refactor UI styling, messaging, and SVG icon rendering across task settings and views
• Normalize wording for new priority/status and untitled tasks:
 – In PriorityManager and StatusManager, update “New Priority”/“New Status” labels to use lowercase “priority/status”.
 – Change default task titles from “Untitled Task” to “Untitled task” in task info extraction.

• Update settings tab UI to use centralized CSS classes rather than inline styles:
 – Remove inline flex, borders, paddings from tab navigation and table elements.
 – Change “General” tab name to “Basic setup”.
 – Replace inline warning message styling with a “settings-warning” div.
 – Refactor status/priority list rows to use new classes (e.g., “settings-item-row”, “settings-input”, “settings-delete-button”, etc.).
 – Update CSS (styles.css) with new styling rules for tab nav, table, lists, input elements, and buttons.

• Simplify and secure SVG icon rendering in TaskListView:
 – Replace innerHTML usage for SVG icons with a new createSVGIcon helper that safely constructs SVG nodes.
 – Update toggle and archive button icon rendering to use the new helper methods.
 – Update text content for time icons to use textContent rather than innerHTML.
 – Ensure document click handler cleanup for dropdowns is properly tracked.

• Clear YAML cache on file index rebuild:
 – In FileIndexer, clear the global YAML cache when the index is rebuilt.

• Miscellaneous improvements:
 – Remove extraneous debugging logs in CalendarView.
 – Adjust minor styling and element class names for clarity and consistency.

This commit brings improved UI consistency, enhanced security by avoiding innerHTML for SVGs, and better code maintainability by moving styling to CSS.
2025-06-03 22:21:16 +10:00
Callum Alpass
8905686a69 feat: add customizable task field mapping, statuses, and priorities (#2)
• Introduce new service classes:
  – FieldMapper: Provides bidirectional mapping between internal task fields and user-configured YAML property names. This ensures backward compatibility while allowing custom field names.
  – StatusManager: Enables custom task statuses (with colors, labels, and cycling order) by replacing hardcoded “open”, “in-progress”, “done”. It includes helper functions for status cycling and for generating CSS rules.
  – PriorityManager: Allows custom priority levels defined by users (with weight, label, and color), and provides functions for cycling priorities, comparing priorities for sorting, and generating dynamic CSS.

• Update main plugin (main.ts):
  – Instantiate and initialize the FieldMapper, StatusManager, and PriorityManager using settings.
  – Inject dynamic CSS for custom statuses and priorities.
  – Update task updates and file indexer interactions to use the FieldMapper for mapping frontmatter properties.
  – Refresh UI and cached task info when settings change.

• Revise TaskCreationModal:
  – Change priority and status selection to use custom configurations from PriorityManager and StatusManager rather than fixed options.
  – Use FieldMapper to map task info into YAML frontmatter when creating a new task.
  – Update task YAML generation logic to include additional fields (e.g., due date, contexts, recurrence, time estimates) correctly.

• Enhance settings UI:
  – Extend settings (in settings.ts) to include new customization options such as fieldMapping, customStatuses, and customPriorities.
  – Redesign the settings pane with tabbed navigation (General, Field mapping, Statuses, Priorities, Daily notes, Pomodoro) to allow easier configuration of defaults, field mappings, and custom status/priority settings.
  – Add warnings for changing field mappings to prevent accidental misconfiguration.

• Update types and utilities:
  – Add FieldMapping, StatusConfig, and PriorityConfig interfaces to types.ts.
  – Update helper functions (updateTaskProperty and extractTaskInfo in helpers.ts) to use FieldMapper if provided, with fallback to legacy behavior.
  – Adapt FileIndexer to accept and update the FieldMapper.
  – Adjust filenameGenerator and TaskListView to work with string-based priority/status values and incorporate custom sorting and cycling logic.

• Modify TaskListView:
  – Replace hardcoded priority and status handling with calls to PriorityManager and StatusManager.
  – Dynamically generate CSS class names based on custom priorities/statuses.
  – Update UI event handlers (including cycling of priorities/statuses) to reflect changes via the new managers.
  – Improve sorting and filtering using custom comparison functions.

• Update styles:
  – Add CSS rules to provide a dynamic top border on task items using the custom priority color on hover.

This refactor provides a more flexible and customizable task management system, allowing users to tailor field names, statuses, and priorities to their workflows while maintaining backward compatibility.
2025-06-03 21:44:13 +10:00
Callum Alpass
d215f381c2 Enhance Daily Note Functionality and Template Processing
• Introduce support for a custom daily note template:
 – In settings.ts, add a new setting (dailyNoteTemplate) with a default empty string.
 – Update the settings UI to include an input for specifying the daily note template file path.

• Update initialization of FileIndexer:
 – Modify the TaskNotesPlugin constructor to pass the dailyNoteTemplate setting along with other daily note settings.
 – In main.ts, update the file indexer without always recreating it: first update the daily note template path via a new updateDailyNoteTemplatePath() method, and only destroy and reinitialize the indexer if core settings (taskTag or excludedFolders) have changed.

• Change daily note generation to async:
 – Convert generateDailyNoteTemplate() to an async method that reads the custom template file from the vault.
 – If a valid custom template is set and found, process it using Obsidian template variables; otherwise, fall back to the built-in template.
 – The plugin now awaits the template generation before creating daily note files.

• Update FileIndexer to handle the daily note template:
 – Add a new property dailyNoteTemplatePath to FileIndexer.
 – Extend the constructor to accept the daily note template path.
 – Implement updateDailyNoteTemplatePath(newPath) to update the template path when settings change.
 – Modify isExcluded() in FileIndexer to exclude the template file from being indexed.

• Improve template processing in helpers.ts:
 – Modify generateDailyNoteTemplate() to optionally accept template content.
 – If provided, process the template using the new processObsidianTemplateVariables() helper, which supports variables like {{title}}, {{date}}, and {{time}} with optional formatting.
 – Add a utility function convertMomentToDateFnsFormat() to convert Obsidian/Moment.js style date/time formats into date-fns formats for proper rendering.
 – Keep the default built-in template as fallback, embedding YAML frontmatter and a header with the formatted date.

These combined changes provide a robust way for users to specify custom templates for daily notes with proper handling of Obsidian template variables, while improving the dynamic update of file indexing settings.
2025-06-01 11:43:35 +10:00
Callum Alpass
6c35e670af feat: Add comprehensive Pomodoro Timer feature
• Added a detailed specification document (POMODORO_SPEC.md) outlining the Pomodoro Timer feature, including timer intervals (work, short break, long break), UI components, settings, data model, events, and implementation details.
• Introduced a new Pomodoro view type (POMODORO_VIEW_TYPE) and corresponding view (src/views/PomodoroView.ts) to display the timer, session status, task assignment, and statistics.
• Created the PomodoroService (src/services/PomodoroService.ts) to manage timer state, handle interval logic, persist state across sessions, integrate with task time tracking, and emit events (start, complete, interrupt, tick) for UI updates and notifications.
• Updated main.ts to:
  - Initialize the PomodoroService on plugin load
  - Register the Pomodoro view and new commands for starting, pausing, and stopping a Pomodoro session
  - Clean up PomodoroService on unload and detach corresponding views.
• Extended the TaskNotesSettings interface (in src/settings/settings.ts) with new Pomodoro-related settings (durations, break intervals, auto-start options, notification and sound settings) and added corresponding UI components in the settings tab.
• Expanded type definitions (src/types.ts) to include PomodoroSession, PomodoroState, and new Pomodoro event constants.
• Refined time entry handling across the codebase by updating property names (from startTime/endTime to start/end) in FileIndexer (src/utils/FileIndexer.ts) and helper functions (src/utils/helpers.ts) to support consistent data mapping with Pomodoro time entries.
• Performed minor UI adjustments in TaskListView to integrate the Pomodoro icon and visual indicators for active Pomodoro sessions.
• Updated styles.css with dedicated styles for the Pomodoro view, including layout, timer display, buttons, status badges, task selector, and statistics panels.

These changes integrate the Pomodoro timer as an opt-in feature into the existing TaskNotes plugin, allowing users to time their work sessions, track progress, and seamlessly integrate with task time tracking while maintaining existing functionality.
2025-06-01 08:15:06 +10:00