Release/v0.1.1 - #7
Merged
Merged
Conversation
* Add keyboard shortcuts feature and translation support * Add support for new keyboard shortcuts and localization enhancements * Refactor mini calendar logic and layout, add helper methods for date calculations, and enhance test coverage * Update keyboard shortcut for "New Event" from "C" to "E" and adjust related tests
…upport in Linux runner
…blocks and missing time zone errors, along with related tests Issue: Calendar operations are permanently poisoned by task replay. The shared DAO returns every pending entity type, but the task replayer treats calendar operations as unknown and blocks them until year Fix: - Task replay now processes only task and task_list rows, leaving calendar operations untouched: lib/src/features/sync/pending_ops_replayer.dart:43. - Calendar replay recovers operations previously poisoned with unknown_operation and parked at year 9999: lib/src/features/sync/calendar_pending_ops_replayer.dart:124.
…lendar repository Issue: Incremental calendar state is unreachable after every run. Exact now ± range timestamps form part of the state key, so the next run uses a different key, performs another initial fetch, and inserts another row. Microsoft additionally starts from ordinary /calendarView, while missing-row reconciliation only runs for full=true, leaving remote deletions stale. Fix: - Added stable, monthly-anchored sync windows and state IDs, including cleanup of legacy range-keyed rows in lib/src/features/calendar/data/calendar_repository.dart:304. - Reused cursors within the same window and safely established a new baseline when the month changes in lib/src/features/sync/calendar_sync_engine.dart:58. Microsoft primary calendars now start with /me/calendarView/delta; secondary calendars use ordinary calendarView with full missing-event reconciliation in lib/src/microsoft_calendar/microsoft_calendar_api_client.dart:209. - Added opaque delta-link paging, tombstone handling, and expired-state recovery.
…TP client Issue: HTTP retries can duplicate tasks, events, lists, and invitations. RetryingHttpClient replays every method—including POST—on 429/5xx and is shared by all four provider clients. A write committed before a provider returns 500 can be issued four times without an idempotency key Fix: - lib/src/google_tasks/http/retrying_http_client.dart:22 now retries only safe HTTP methods: GET, HEAD, OPTIONS, and TRACE. - POST, PATCH, PUT, and DELETE return after one attempt on both 429 and 5xx, preventing transport-level duplicate resources and invitations. - Reads retain exponential backoff. This conservative policy follows HTTP safe-method semantics (https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.1). Provider-specific idempotency exists for Google Calendar event IDs (https://developers.google.com/workspace/calendar/api/guides/create-events) and Microsoft event transactionId (https://learn.microsoft.com/en-us/graph/api/resources/event?view=graph-rest-1.0), but not universally across task/list APIs.
… 429/5xx responses Issue: Google recurring occurrences are not synchronized. Both initial and token sync force singleEvents:false, while the available instance endpoint has no production caller and the schedule layer does not expand recurrence rules. Future occurrences therefore do not populate the schedule. Fix: - Initial and incremental requests now use singleEvents=true in lib/src/google_calendar/google_calendar_api_client.dart:276. - Legacy Google cursors force one new baseline, then persist a versioned query marker in lib/src/features/sync/calendar_sync_engine.dart:8. - Synchronized recurrence masters are retired once expanded instances arrive, preventing duplicate first occurrences via lib/src/features/calendar/data/calendar_repository.dart:651.
…nd enable/disable state Issue: Moving an existing event to another calendar is exposed but unsupported. The editor permits selecting any visible account/ source; persistence rewrites the local destination but queues event.patch with the original provider event ID. Replay PATCHes that ID in the destination, normally producing 404 and leaving the original remote event intact. Fix: - Existing events now expose only their original calendar, with the selector disabled in lib/src/features/calendar/presentation/event_editor.dart:379. - Repository calls now reject account, provider, source, or provider-calendar changes before modifying the row or queuing an operation in lib/src/features/calendar/data/calendar_repository.dart:459. - New events can still select any visible calendar. - Added same-account, cross-account, and cross-provider regressions.
…ee management, and improved JSON handling in schedule and calendar operations. Issue: clearing recurrence or the final attendee never reaches either provider. Empty values become null, then both serializers remove null fields from the PATCH, meaning the remote recurrence and guest remain unchanged while local state says otherwise. See lib/src/ features/calendar/data/calendar_repository.dart:683, lib/src/ google_calendar/google_calendar_mapper.dart:100, and lib/src/ microsoft_calendar/microsoft_calendar_mapper.dart:94. Fix: - Added explicit clear intent through queueing, replay, and conflict detection. - Google now sends recurrence: [] and attendees: []. - Microsoft now sends explicit recurrence: null and attendees: []. - Untouched recurrence, attendees, and Microsoft categories are omitted from PATCH requests. - Existing recurrence and attendees are hydrated into both editor paths, including nested Microsoft attendee addresses. - Recurring occurrences hide the series-level recurrence control, and repository-level attempts are rejected because recurrence changes must target the master event. This matches Google’s recurring-event guidance (https://developers.google.com/workspace/calendar/api/guides/recurringevents) and Microsoft’s event update semantics (https://learn.microsoft.com/en-us/graph/api/event-update?view=graph-rest-1.0).
…ATCH behavior, and prevent remote-local state mismatches
…state synchronization, and PATCH semantics
…g for pending operations Issue: Back-to-back offline edits self-conflict. Both edits capture the same server baseline; replaying the first changes the server, after which the second identifies that first local write as a remote conflict and blocks the newer value. This affects tasks and events. Fix: - Same-entity edits now form a FIFO dependency chain. - Successful writes selectively rebase only fields they changed, preserving detection of genuine remote conflicts elsewhere. - Intermediate provider responses no longer overwrite newer optimistic local values. - Task mutation and queue insertion are now atomic.
…istent error handling Issue: The Microsoft adapter leaked MicrosoftTodoApiError through the GoogleTasksApiClient interface, causing replay’s generic handler to retry permanent errors indefinitely. Fix: - Normalized all Microsoft To Do API failures to GoogleTasksApiError in lib/src/microsoft_todo/api/microsoft_todo_google_tasks_adapter.dart:21, preserving status, code, message, and raw response. - Permanent 400/403/non-delete 404 errors are now blocked. - 429/5xx errors retain retry backoff. - Delete 404 reconciles local deletion and removes the operation.
…r handling - Consolidated account connection logic into a single `_connectAccount` method for clarity and maintainability. - Added explicit handling for connecting providers and ensured proper state updates to prevent conflicts during simultaneous connections. - Updated UI to reflect connecting state per provider, disabling interactions during ongoing connections. - Replaced `_reconnect` with `_connectAccount` to unify behavior for account reconnections. - Renamed `_authErrorMessage` to `authErrorMessage` for consistency.
- Integrated account subscription to monitor changes in signed-in accounts. - Enhanced notification scheduling logic to filter by signed-in account IDs. - Added `_reconcileNotifications` method to manage notification insertion, updates, and deletions efficiently. - Refactored upcoming event and task notifications to leverage account-based filtering and batch reconciliation.
…ve persistence handling - Replaced `_save` with `_mutate` method for consistent state updates. - Introduced `_AppSettingsMutation` typedef to streamline mutation logic. - Added `_persistAfter` to manage sequential persistence safely. - Updated state management during loading to merge pending mutations. - Ensured proper disposal handling to prevent updates post-disposal.
- lib/src/schedule/schedule_range.dart:4 now uses civil-date arithmetic for day, week, and month boundaries. - lib/src/features/schedule/presentation/schedule_month_view.dart:327 reconstructs each next local midnight, preventing shifted or duplicated dates. Added forced America/Vancouver DST regressions in test/features/schedule/schedule_dst_test.dart:1, covering 23/25-hour days, 167/169-hour weeks, month boundaries, and unique grid dates.
…ng, and task mutation tests - Ensured app waits for settings readiness before tray startup. - Introduced `trayServiceFactory` for better tray service customization and testing. - Wrapped task creation and mutation with `setState` calls to refresh UI. - Added unit and widget tests for task creation and completion in `ScheduleWorkspace`.
…e components. Same-day timed events receive a next-day exclusive end using DST-safe civil-date construction in lib/src/features/calendar/presentation/event_editor.dart:716.
…derOn: false. Removed that inference in lib/src/microsoft_calendar/microsoft_calendar_mapper.dart:94, so reminder state is now independent of all-day status. Added disabled and enabled regressions in test/microsoft_calendar/microsoft_calendar_mapper_test.dart:114.
- Added conditional logic for maintaining state integrity during `upsertSource` and `setSourceSelected` operations. - Integrated notification scheduling updates to account for source visibility, selection, and deletion. - Enhanced `_notificationScheduleService` to filter sources by account, selection, visibility, and deletion state.
…e handling - Added "Send Feedback" option to the About dialog (lib/src/app/busymax_about_dialog.dart). - Integrated feedback API via `FeedbackApiClient` and `FeedbackSubmissionService`. - Updated localizations with support for feedback-related terms in multiple languages (e.g., send feedback, category, errors). - Modified settings and schedule screens to pass the `feedbackSubmissionService`. - Enabled conditional disabling of cancel buttons in header components for better UX. - Configured feedback backend endpoint in the build config (lib/src/config/build_config.dart).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.