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 @@ -83,21 +83,12 @@ override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appW
MainActivity::class.java
)
setOnClickPendingIntent(R.id.logo, pendingIntent)

// Set up the Add Button click (Custom Action)
val intent_for_add = Intent(context, TaskWarriorWidgetProvider::class.java).apply {
action = "TASK_ACTION"
putExtra("launchedFor", "ADD_TASK")
// Unique data to ensure the broadcast is fresh
data = Uri.parse("taskwarrior://addtask/$widgetId")
}

val pendingIntentAdd: PendingIntent = PendingIntent.getBroadcast(
context,
widgetId,
intent_for_add,
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val pendingIntentAdd: PendingIntent = HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java,
Uri.parse("taskwarrior://addclicked")
)
setOnClickPendingIntent(R.id.add_btn, pendingIntentAdd)

// Attach the adapter to the ListView
Expand All @@ -111,12 +102,11 @@ override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appW
).run {
action = "TASK_ACTION"
// Important: Use widgetId as requestCode to keep it unique
PendingIntent.getBroadcast(
context,
widgetId,
this,
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val clickPendingIntent: PendingIntent = HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java,
Uri.parse("taskwarrior://cardclicked")
)
}
views.setPendingIntentTemplate(R.id.list_view, clickPendingIntent)

Expand Down
17 changes: 16 additions & 1 deletion lib/app/models/filters.dart
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import 'package:taskwarrior/app/services/tag_filter.dart';
// lib/app/models/filters.dart

import 'package:taskwarrior/app/models/tag_filters.dart';


class Filters {
const Filters({
required this.pendingFilter,
required this.waitingFilter,
required this.completedFilter,
required this.deletedFilter,
required this.togglePendingFilter,
required this.toggleWaitingFilter,
required this.toggleCompletedFilter,
required this.toggleDeletedFilter,
required this.tagFilters,
required this.projects,
required this.projectFilter,
required this.toggleProjectFilter,
required this.hideBlocked, // ADD
required this.toggleHideBlocked,
});

final bool pendingFilter;
final bool waitingFilter;
final bool completedFilter;
final bool deletedFilter;
final void Function() togglePendingFilter;
final void Function() toggleWaitingFilter;
final void Function() toggleCompletedFilter;
final void Function() toggleDeletedFilter;
final TagFilters tagFilters;
final dynamic projects;
final String projectFilter;
final void Function(String) toggleProjectFilter;
final bool hideBlocked;
final void Function() toggleHideBlocked;
}
25 changes: 25 additions & 0 deletions lib/app/models/tag_filters.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// lib/app/models/tag_filters.dart

class TagFilterMetadata {
const TagFilterMetadata({
required this.display,
required this.selected,
});

final String display;
final bool selected;
}

class TagFilters {
const TagFilters({
required this.tagUnion,
required this.toggleTagUnion,
required this.tags,
required this.toggleTagFilter,
});

final bool tagUnion;
final void Function() toggleTagUnion;
final Map<String, TagFilterMetadata> tags;
final void Function(String) toggleTagFilter;
}
135 changes: 121 additions & 14 deletions lib/app/modules/home/controllers/home_controller.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// ignore_for_file: use_build_context_synchronously, unrelated_type_equality_checks

import 'package:taskwarrior/app/utils/language/sentences.dart';

import 'dart:collection';
import 'dart:io';

import 'package:taskwarrior/app/routes/app_pages.dart';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
Expand All @@ -18,7 +22,8 @@ import 'package:taskwarrior/app/models/tag_meta_data.dart';
import 'package:taskwarrior/app/modules/home/controllers/widget.controller.dart';
import 'package:taskwarrior/app/modules/splash/controllers/splash_controller.dart';
import 'package:taskwarrior/app/services/deep_link_service.dart';
import 'package:taskwarrior/app/services/tag_filter.dart';
import 'package:taskwarrior/app/models/tag_filters.dart';

import 'package:taskwarrior/app/tour/filter_drawer_tour.dart';
import 'package:taskwarrior/app/tour/home_page_tour.dart';
import 'package:taskwarrior/app/tour/task_swipe_tour.dart';
Expand All @@ -40,12 +45,20 @@ import 'package:textfield_tags/textfield_tags.dart';
import 'package:taskwarrior/app/utils/themes/theme_extension.dart';
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';

import 'package:taskwarrior/app/utils/language/sentence_manager.dart';


class HomeController extends GetxController {
final SplashController splashController = Get.find<SplashController>();
late Storage storage;
final RxBool taskServerBannerShown = false.obs;
late Sentences sentences;
final RxBool pendingFilter = false.obs;
final RxBool waitingFilter = false.obs;
final RxBool hideBlocked = false.obs;
final RxString projectFilter = ''.obs;
final RxBool completedFilter = false.obs;
final RxBool deletedFilter = false.obs;
final RxBool tagUnion = false.obs;
final RxString selectedSort = ''.obs;
final RxSet<String> selectedTags = <String>{}.obs;
Expand All @@ -70,6 +83,9 @@ class HomeController extends GetxController {
@override
void onInit() {
super.onInit();
sentences = SentenceManager(
currentLanguage: AppSettings.selectedLanguage,
).sentences;
storage = Storage(
Directory(
'${splashController.baseDirectory.value.path}/profiles/${splashController.currentProfile.value}',
Expand Down Expand Up @@ -97,6 +113,8 @@ class HomeController extends GetxController {
everAll([
pendingFilter,
waitingFilter,
completedFilter,
deletedFilter,
projectFilter,
tagUnion,
selectedSort,
Expand Down Expand Up @@ -213,12 +231,7 @@ class HomeController extends GetxController {

void _profileSet() {
pendingFilter.value = Query(storage.tabs.tab()).getPendingFilter();
if (!Query(storage.tabs.tab()).getWaitingFilter()) {
waitingFilter.value = Query(storage.tabs.tab()).getWaitingFilter();
} else {
Query(storage.tabs.tab()).toggleWaitingFilter();
waitingFilter.value = Query(storage.tabs.tab()).getWaitingFilter();
}
waitingFilter.value = Query(storage.tabs.tab()).getWaitingFilter();
projectFilter.value = Query(storage.tabs.tab()).projectFilter();
tagUnion.value = Query(storage.tabs.tab()).tagUnion();
selectedSort.value = Query(storage.tabs.tab()).getSelectedSort();
Expand All @@ -233,22 +246,46 @@ class HomeController extends GetxController {
}

void _refreshTasks() {
if (pendingFilter.value) {

if (deletedFilter.value) {
queriedTasks.value = storage.data
.completedData()
.where((task) => task.status == 'deleted')
.toList();
} else if (completedFilter.value) {
queriedTasks.value = storage.data
.completedData()
.where((task) => task.status == 'completed')
.toList();
} else if (pendingFilter.value) {
queriedTasks.value = storage.data
.pendingData()
.where((task) => task.status == 'pending')
.toList();
} else {
queriedTasks.value = storage.data.completedData();
var currentTime = DateTime.now();
queriedTasks.value = storage.data.pendingData().where((task) =>
task.status != 'waiting' &&
!(task.wait != null && task.wait!.isAfter(currentTime))
).toList();
}

if (waitingFilter.value) {
var currentTime = DateTime.now();
if (hideBlocked.value) {
queriedTasks.value = queriedTasks
.where((task) => task.wait != null && task.wait!.isAfter(currentTime))
.where((task) => task.depends == null || task.depends!.isEmpty)
.toList();
}


// Rest of the method stays the same...
if (waitingFilter.value) {
var currentTime = DateTime.now();
queriedTasks.value = storage.data.pendingData().where((task) =>
task.status == 'waiting' ||
(task.wait != null && task.wait!.isAfter(currentTime))
).toList();
}

if (projectFilter.value.isNotEmpty) {
queriedTasks.value = queriedTasks.where((task) {
if (task.project == null) {
Expand Down Expand Up @@ -343,6 +380,22 @@ class HomeController extends GetxController {
_refreshTasks();
}

void toggleCompletedFilter() {
completedFilter.toggle();
if (completedFilter.value) {
deletedFilter.value = false;
}
_refreshTasks();
}

void toggleDeletedFilter() {
deletedFilter.toggle();
if (deletedFilter.value) {
completedFilter.value = false;
}
_refreshTasks();
}

void toggleProjectFilter(String project) {
Query(storage.tabs.tab()).toggleProjectFilter(project);
projectFilter.value = Query(storage.tabs.tab()).projectFilter();
Expand Down Expand Up @@ -528,6 +581,44 @@ class HomeController extends GetxController {
_refreshTasks();
}

void showTaskServerNotConfiguredBanner(BuildContext context) {
if (taskServerBannerShown.value) return;

taskServerBannerShown.value = true;
final messenger = ScaffoldMessenger.of(context);

messenger.clearMaterialBanners();

messenger.showMaterialBanner(
MaterialBanner(
content: Text(sentences.homePageTaskWarriorNotConfigured),
actions: [
TextButton(
onPressed: () {
messenger.hideCurrentMaterialBanner();
taskServerBannerShown.value = false; // ✅ RESET flag
Get.toNamed(Routes.MANAGE_TASK_SERVER);
},
child: Text(sentences.homePageSetup),
),
TextButton(
onPressed: () {
messenger.hideCurrentMaterialBanner();
taskServerBannerShown.value = false; // ✅ RESET flag
},
child: const Text('Dismiss'),
),
],
),
);

Future.delayed(const Duration(seconds: 5), () {
messenger.hideCurrentMaterialBanner();
taskServerBannerShown.value = false; // ✅ RESET flag
});
}


void renameTab({
required String tab,
required String name,
Expand Down Expand Up @@ -556,9 +647,14 @@ class HomeController extends GetxController {
clientId = await CredentialsStorage.getClientId();
encryptionSecret = await CredentialsStorage.getEncryptionSecret();
if (value) {
if (clientId == null || encryptionSecret == null) {
showTaskServerNotConfiguredBanner(context);
return;
}

synchronize(context, false);
refreshTasks(clientId!, encryptionSecret!);
} else {}
refreshTasks(clientId, encryptionSecret);
}
}

RxBool syncOnStart = false.obs;
Expand Down Expand Up @@ -609,15 +705,26 @@ class HomeController extends GetxController {
tags: tags,
toggleTagFilter: toggleTagFilter,
);

// REPLACE this entire Filters() instantiation:
var filters = Filters(
pendingFilter: pendingFilter.value,
waitingFilter: waitingFilter.value,
completedFilter: completedFilter.value,
deletedFilter: deletedFilter.value,
togglePendingFilter: togglePendingFilter,
toggleWaitingFilter: toggleWaitingFilter,
toggleCompletedFilter: toggleCompletedFilter,
toggleDeletedFilter: toggleDeletedFilter,
projects: projects,
projectFilter: projectFilter.value,
toggleProjectFilter: toggleProjectFilter,
tagFilters: tagFilters,
hideBlocked: hideBlocked.value,
toggleHideBlocked: () {
hideBlocked.value = !hideBlocked.value;
_refreshTasks();
},
);
return filters;
}
Expand Down
Loading