Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class DetailRouteController extends GetxController {
var onEdit = false.obs;
var isReadOnly = false.obs;

// Track whether user explicitly selected a start date
bool startEdited = false;
Comment on lines +20 to +21
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The startEdited flag is not reset when the controller is reused. If the user edits a task, saves it, and then opens another task detail view (or the same task again), the flag will still be true from the previous interaction. This could cause the start date logic to behave incorrectly.

Consider resetting startEdited = false in the onInit() method or creating a new instance of the controller for each task.

Copilot uses AI. Check for mistakes.

@override
void onInit() {
super.onInit();
Expand Down Expand Up @@ -50,13 +53,19 @@ class DetailRouteController extends GetxController {
}

if (name == 'start') {
debugPrint('Start Value Changed to $newValue');
startEdited = true; // MARK AS USER-SELECTED
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The comment "// MARK AS USER-SELECTED" uses non-standard comment style. The codebase appears to use standard Dart comment conventions. Consider using a more descriptive comment like:

// Mark that user explicitly selected a start date

This is clearer and follows typical Dart commenting practices.

Suggested change
startEdited = true; // MARK AS USER-SELECTED
startEdited = true; // Mark that user explicitly selected a start date

Copilot uses AI. Check for mistakes.
startValue.value = newValue;
}
initValues();
}

Future<void> saveChanges() async {
// If start was never edited AND backend auto-generated it (start == entry)
if (!startEdited &&
modify.original.start != null &&
modify.original.start!.isAtSameMomentAs(modify.original.entry)) {
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic has a potential issue: it checks if modify.original.start is not null and equals modify.original.entry, but it doesn't verify whether modify.draft.start is still the same value. If the user explicitly sets the start date to match the entry date (an unlikely but valid scenario), this code would incorrectly remove it.

Consider also checking that modify.draft.start equals modify.original.start to ensure you're only removing the backend-generated value, not a user's intentional selection.

Suggested change
modify.original.start!.isAtSameMomentAs(modify.original.entry)) {
modify.original.start!.isAtSameMomentAs(modify.original.entry) &&
modify.draft.start != null &&
modify.draft.start!.isAtSameMomentAs(modify.original.start!)) {

Copilot uses AI. Check for mistakes.
modify.set('start', null); // remove auto start
}
Comment on lines 62 to +68
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new behavior for handling start dates lacks test coverage. Given that tests exist for other task functions (e.g., test/taskfunctions/draft_test.dart), consider adding tests to verify:

  1. Start date remains null for new tasks with backend auto-generated start (start == entry)
  2. Start date is preserved when explicitly set by user
  3. Start date persists correctly after save and reopen
  4. The startEdited flag behaves correctly across different scenarios

This will prevent regressions and document the expected behavior.

Copilot uses AI. Check for mistakes.
var now = DateTime.now().toUtc();
modify.save(modified: () => now);
onEdit.value = false;
Expand Down Expand Up @@ -106,7 +115,20 @@ class DetailRouteController extends GetxController {
statusValue.value = modify.draft.status;
entryValue.value = modify.draft.entry;
modifiedValue.value = modify.draft.modified;
startValue.value ??= null;
final originalStart = modify.original.start;
final originalEntry = modify.original.entry;

final backendAutoStart = (originalStart != null &&
originalStart.isAtSameMomentAs(originalEntry));

// START DATE LOGIC (THE FIX)
if (startEdited) {
startValue.value = modify.draft.start;
} else if (backendAutoStart) {
startValue.value = null; // Do not show backend auto start
} else {
startValue.value = modify.draft.start; // Existing meaningful start
}
Comment on lines +118 to +131
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new logic for handling the start date is complex and undocumented. Consider adding a comment explaining:

  1. What backendAutoStart means (start date was auto-generated by backend when it equals entry date)
  2. Why we hide it from the UI when not explicitly edited by the user
  3. The three scenarios being handled (user-edited, backend auto-generated, and meaningful existing start)

This will help future maintainers understand the intent behind this fix.

Copilot uses AI. Check for mistakes.
endValue.value = modify.draft.end;
dueValue.value = modify.draft.due;
waitValue.value = modify.draft.wait;
Expand Down Expand Up @@ -148,15 +170,7 @@ class DetailRouteController extends GetxController {
const Duration(milliseconds: 500),
() {
SaveTourStatus.getDetailsTourStatus().then((value) => {
if (value == false)
{
tutorialCoachMark.show(context: context),
}
else
{
// ignore: avoid_print
print('User has seen this page'),
}
if (!value) {tutorialCoachMark.show(context: context)}
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The refactored conditional expression is missing proper formatting. While the logic is correct, it should be formatted more clearly for readability:

if (!value) {
  tutorialCoachMark.show(context: context);
}

The current single-line block without braces, while valid Dart, is inconsistent with the codebase style and less maintainable. If additional logic needs to be added later, it could lead to bugs.

Copilot uses AI. Check for mistakes.
});
},
);
Expand Down
1 change: 0 additions & 1 deletion lib/app/utils/taskfunctions/draft.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import 'package:taskwarrior/app/models/models.dart';
import 'package:taskwarrior/app/utils/taskfunctions/patch.dart';

Expand Down
1 change: 1 addition & 0 deletions lib/app/utils/taskfunctions/modify.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Modify {

Task get draft => _draft.draft;
int get id => _draft.original.id!;
Task get original => _draft.original;

Map<dynamic, Map> get changes {
var result = <dynamic, Map>{};
Expand Down