diff --git a/android/main/app/src/main/jniLibs/arm64-v8a/libtc_helper.so b/android/main/app/src/main/jniLibs/arm64-v8a/libtc_helper.so new file mode 100755 index 00000000..06a64cea Binary files /dev/null and b/android/main/app/src/main/jniLibs/arm64-v8a/libtc_helper.so differ diff --git a/build_droidtchelper b/build_droidtchelper new file mode 100644 index 00000000..e69de29b diff --git a/ios/tc_helper.xcframework/ios-arm64/tc_helper.framework/tc_helper b/ios/tc_helper.xcframework/ios-arm64/tc_helper.framework/tc_helper index b471a32f..f639754f 100755 Binary files a/ios/tc_helper.xcframework/ios-arm64/tc_helper.framework/tc_helper and b/ios/tc_helper.xcframework/ios-arm64/tc_helper.framework/tc_helper differ diff --git a/ios/tc_helper.xcframework/ios-arm64_x86_64-simulator/tc_helper.framework/tc_helper b/ios/tc_helper.xcframework/ios-arm64_x86_64-simulator/tc_helper.framework/tc_helper index 60e3787d..bdf11cda 100755 Binary files a/ios/tc_helper.xcframework/ios-arm64_x86_64-simulator/tc_helper.framework/tc_helper and b/ios/tc_helper.xcframework/ios-arm64_x86_64-simulator/tc_helper.framework/tc_helper differ diff --git a/lib/app/modules/taskc_details/controllers/taskc_details_controller.dart b/lib/app/modules/taskc_details/controllers/taskc_details_controller.dart index 226a54d4..6116cf7e 100644 --- a/lib/app/modules/taskc_details/controllers/taskc_details_controller.dart +++ b/lib/app/modules/taskc_details/controllers/taskc_details_controller.dart @@ -50,9 +50,9 @@ class TaskcDetailsController extends GetxController { // Support both TaskForC (local tasks) and TaskForReplica (replica tasks) if (task is TaskForC) { description = task.description.obs; - project = (task.project ?? '-').obs; + project = (task.project ?? 'None').obs; status = task.status.obs; - priority = (task.priority ?? '-').obs; + priority = (task.priority ?? 'None').obs; due = formatDate(task.due).obs; start = "".obs; wait = "".obs; @@ -66,9 +66,9 @@ class TaskcDetailsController extends GetxController { annotations = [].obs; } else if (task is TaskForReplica) { description = (task.description ?? '').obs; - project = (task.project ?? '-').obs; + project = (task.project ?? 'None').obs; status = (task.status ?? '').obs; - priority = (task.priority ?? '-').obs; + priority = (task.priority ?? 'None').obs; // TaskForReplica stores epoch seconds; convert to ISO string for formatting debugPrint('Replica task due: ${task.due}'); due = formatDate(task.due).obs; @@ -88,10 +88,10 @@ class TaskcDetailsController extends GetxController { } else { // Fallback description = ''.obs; - project = '-'.obs; + project = 'None'.obs; status = ''.obs; - priority = '-'.obs; - due = '-'.obs; + priority = 'None'.obs; + due = 'None'.obs; start = "".obs; wait = "".obs; tags = [].obs; @@ -104,14 +104,14 @@ class TaskcDetailsController extends GetxController { } String formatDate(dynamic date) { - if (date == null) return '-'; + if (date == null) return 'None'; // If date is epoch seconds as int bool is24hrFormat = AppSettings.use24HourFormatRx.value; final pattern = is24hrFormat ? 'EEE, yyyy-MM-dd HH:mm:ss' : 'EEE, yyyy-MM-dd hh:mm:ss a'; - if (date == null) return '-'; + if (date == null) return 'None'; if (date is int) { try { @@ -119,7 +119,7 @@ class TaskcDetailsController extends GetxController { return DateFormat(pattern).format(dt.toLocal()); } catch (e) { debugPrint('Error formatting epoch date: $e'); - return '-'; + return 'None'; } } @@ -128,19 +128,19 @@ class TaskcDetailsController extends GetxController { return DateFormat(pattern).format(date.toLocal()); } catch (e) { debugPrint('Error formatting DateTime: $e'); - return '-'; + return 'None'; } } final dateString = date?.toString() ?? ''; - if (dateString.isEmpty || dateString == '-') return '-'; + if (dateString.isEmpty || dateString == 'None') return 'None'; try { final parsedDate = DateTime.parse(dateString).toLocal(); return DateFormat(pattern).format(parsedDate); } catch (e) { debugPrint('Error parsing date: $dateString $e'); - return '-'; + return 'None'; } } @@ -164,13 +164,13 @@ class TaskcDetailsController extends GetxController { // model shape than TaskForC). String initialTaskUuidDisplay() { try { - if (initialTask == null) return '-'; + if (initialTask == null) return 'None'; if (initialTask is TaskForC) - return (initialTask.uuid ?? '-')?.toString() ?? '-'; - if (initialTask is TaskForReplica) return initialTask.uuid ?? '-'; - return '-'; + return (initialTask.uuid ?? 'None')?.toString() ?? 'None'; + if (initialTask is TaskForReplica) return initialTask.uuid ?? 'None'; + return 'None'; } catch (_) { - return '-'; + return 'None'; } } @@ -178,12 +178,12 @@ class TaskcDetailsController extends GetxController { try { if (initialTask is TaskForC) { final u = initialTask.urgency as double?; - return (u != null) ? u.toStringAsFixed(2) : '-'; + return (u != null) ? u.toStringAsFixed(2) : 'None'; } // TaskForReplica doesn't have urgency - return '-'; + return 'None'; } catch (_) { - return '-'; + return 'None'; } } @@ -266,7 +266,7 @@ class TaskcDetailsController extends GetxController { final modifiedTask = TaskForReplica( modified: nowEpoch, due: () { - if (due.string == '-' || due.string.isEmpty) return null; + if (due.string == 'None' || due.string.isEmpty) return null; try { final parsed = DateFormat(datePattern).parse(due.string); return parsed.toUtc().toIso8601String(); @@ -282,7 +282,8 @@ class TaskcDetailsController extends GetxController { } }(), start: () { - if (start.string == '-' || start.string.isEmpty) return null; + if (start.string == 'None' || start.string.isEmpty) return null; + if (start.string == "stop") return "stop"; try { final parsed = DateFormat(datePattern).parse(start.string); return parsed.toUtc().toIso8601String(); @@ -298,7 +299,7 @@ class TaskcDetailsController extends GetxController { } }(), wait: () { - if (wait.string == '-' || wait.string.isEmpty) return null; + if (wait.string == 'None' || wait.string.isEmpty) return null; try { final parsed = DateFormat(datePattern).parse(wait.string); return parsed.toUtc().toIso8601String(); @@ -318,7 +319,7 @@ class TaskcDetailsController extends GetxController { tags: tags.isNotEmpty ? tags.toList() : null, uuid: initialTask.uuid ?? '', priority: priority.string.isNotEmpty ? priority.string : null, - project: project.string != '-' ? project.string : null, + project: project.string != 'None' ? project.string : null, ); debugPrint('Modified replica task: $modifiedTask'); hasChanges.value = false; @@ -352,7 +353,7 @@ class TaskcDetailsController extends GetxController { final BuildContext context = Get.context!; final DateTime? pickedDate = await showDatePicker( context: context, - initialDate: field.value != '-' + initialDate: field.value != 'None' ? DateTime.tryParse(field.value) ?? DateTime.now() : DateTime.now(), firstDate: DateTime(2000), @@ -362,7 +363,7 @@ class TaskcDetailsController extends GetxController { if (pickedDate != null) { final TimeOfDay? pickedTime = await showTimePicker( context: context, - initialTime: TimeOfDay.fromDateTime(field.value != '-' + initialTime: TimeOfDay.fromDateTime(field.value != 'None' ? DateTime.tryParse(field.value) ?? DateTime.now() : DateTime.now()), ); diff --git a/lib/app/modules/taskc_details/views/taskc_details_view.dart b/lib/app/modules/taskc_details/views/taskc_details_view.dart index 6e7dcc39..c6b7991e 100644 --- a/lib/app/modules/taskc_details/views/taskc_details_view.dart +++ b/lib/app/modules/taskc_details/views/taskc_details_view.dart @@ -5,6 +5,7 @@ import 'package:get/get.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; import 'package:taskwarrior/app/utils/constants/taskwarrior_colors.dart'; +import 'package:taskwarrior/app/utils/constants/taskwarrior_fonts.dart'; import 'package:taskwarrior/app/utils/themes/theme_extension.dart'; import 'package:taskwarrior/app/utils/language/sentence_manager.dart'; import '../controllers/taskc_details_controller.dart'; @@ -57,7 +58,7 @@ class TaskcDetailsView extends GetView { context, '${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.detailPagePriority}:', controller.priority.value, - ['H', 'M', 'L', '-'], + ['H', 'M', 'L', 'None'], (value) => controller.updateField(controller.priority, value), ), _buildDatePickerDetail( @@ -68,21 +69,21 @@ class TaskcDetailsView extends GetView { ), // Start / Wait: editable date pickers for replica tasks, read-only otherwise if (controller.isReplicaTask) ...[ - controller.start.value == '-' - ? _buildDatePickerDetail( - context, - '${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.detailPageStart}:', - controller.start.value, - () => controller.updateField( + _buildDatePickerDetail( + context, + '${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.detailPageStart}:', + controller.start.value == "stop" + ? "None" + : controller.start.value, + () => controller.start.value == "stop" || + controller.start.value == "-" || + controller.start.value.isEmpty + ? controller.updateField( controller.start, controller.formatDate(DateTime.now()), - ), - ) - : _buildDetail( - context, - '${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.detailPageStart}:', - controller.start.value, - disabled: true), + ) + : controller.start.value = "stop", + ), _buildDatePickerDetail( context, '${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.detailPageWait}:', @@ -206,6 +207,9 @@ class TaskcDetailsView extends GetView { {bool disabled = false}) { TaskwarriorColorTheme tColors = Theme.of(context).extension()!; + final Color? textColor = + disabled ? tColors.primaryDisabledTextColor : tColors.primaryTextColor; + return Container( width: double.infinity, decoration: BoxDecoration( @@ -227,23 +231,20 @@ class TaskcDetailsView extends GetView { children: [ Text( label, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18, - color: disabled - ? tColors.primaryDisabledTextColor - : tColors.primaryTextColor, + style: GoogleFonts.poppins( + fontWeight: TaskWarriorFonts.bold, + fontSize: TaskWarriorFonts.fontSizeMedium, + color: textColor, ), ), const SizedBox(width: 8), Expanded( child: Text( value, - style: TextStyle( - fontSize: 18, - color: disabled - ? tColors.primaryDisabledTextColor - : tColors.primaryTextColor, + style: GoogleFonts.poppins( + fontWeight: FontWeight.normal, + fontSize: TaskWarriorFonts.fontSizeMedium, + color: textColor, ), ), ), diff --git a/rust/src/api.rs b/rust/src/api.rs index 6f049705..6129cc0f 100644 --- a/rust/src/api.rs +++ b/rust/src/api.rs @@ -108,7 +108,11 @@ pub fn update_task( let _ = t.set_due(parse_datetime(&value), &mut ops); } "start" => { - let _ = t.start(&mut ops); + if value == "stop" { + let _ = t.stop(&mut ops); + } else { + let _ = t.start(&mut ops); + } } "wait" => { let _ = t.set_wait(parse_datetime(&value), &mut ops); @@ -135,7 +139,7 @@ pub fn update_task( } } "project" => { - let _ = t.set_user_defined_attribute("project", value, &mut ops); + let _ = t.set_value("project", Some(value), &mut ops); } "status" => { let status = match value.as_str() {