Skip to content

Commit 15096fe

Browse files
committed
feat: Implemented websocket to receive information about the job
1 parent 49bb285 commit 15096fe

File tree

5 files changed

+131
-35
lines changed

5 files changed

+131
-35
lines changed

lib/api_service.dart

+1-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Tasks {
6767
}
6868
}
6969

70-
String baseUrl = 'http://YOUR_IP:8000';
70+
String baseUrl = 'http://192.168.1.104:8000';
7171
String origin = 'http://localhost:8080';
7272

7373
Future<List<Tasks>> fetchTasks(String uuid, String encryptionSecret) async {
@@ -175,7 +175,6 @@ Future<void> deleteTask(String email, String taskUuid) async {
175175
},
176176
body: body,
177177
);
178-
179178
if (response.statusCode == 200) {
180179
debugPrint('Task deleted successfully on server');
181180
} else {

lib/app/modules/home/controllers/home_controller.dart

+89-20
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@ import 'package:taskwarrior/app/tour/home_page_tour.dart';
2727
import 'package:taskwarrior/app/utils/constants/taskwarrior_colors.dart';
2828
import 'package:taskwarrior/app/utils/language/supported_language.dart';
2929
import 'package:taskwarrior/app/utils/taskchampion/credentials_storage.dart';
30+
import 'package:taskwarrior/app/utils/taskchampion/websocket.dart';
3031
import 'package:taskwarrior/app/utils/taskfunctions/comparator.dart';
3132
import 'package:taskwarrior/app/utils/taskfunctions/projects.dart';
3233
import 'package:taskwarrior/app/utils/taskfunctions/query.dart';
3334
import 'package:taskwarrior/app/utils/taskfunctions/tags.dart';
3435
import 'package:taskwarrior/app/utils/app_settings/app_settings.dart';
3536
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
37+
import 'package:web_socket_channel/status.dart';
38+
import 'package:web_socket_channel/web_socket_channel.dart';
3639

3740
class HomeController extends GetxController {
3841
final SplashController splashController = Get.find<SplashController>();
@@ -55,6 +58,7 @@ class HomeController extends GetxController {
5558
final ScrollController scrollController = ScrollController();
5659
final RxBool showbtn = false.obs;
5760
late TaskDatabase taskdb;
61+
WebSocketChannel? wsChannel;
5862
var tasks = <Tasks>[].obs;
5963

6064
@override
@@ -74,25 +78,31 @@ class HomeController extends GetxController {
7478
taskdb.open();
7579
getUniqueProjects();
7680
_loadTaskChampion();
81+
ever(taskchampion, (bool value) async {
82+
if (value) {
83+
wsChannel = await initCCSyncUpdatesWs();
84+
} else {
85+
if (wsChannel != null) wsChannel?.sink.close(goingAway);
86+
}
87+
});
7788
if (Platform.isAndroid) {
7889
handleHomeWidgetClicked();
7990
}
8091
fetchTasksFromDB();
81-
everAll([
92+
everAll([
8293
pendingFilter,
8394
waitingFilter,
8495
projectFilter,
8596
tagUnion,
8697
selectedSort,
8798
selectedTags,
8899
], (_) {
89-
if (Platform.isAndroid) {
90-
WidgetController widgetController =
91-
Get.put(WidgetController());
92-
widgetController.fetchAllData();
100+
if (Platform.isAndroid) {
101+
WidgetController widgetController = Get.put(WidgetController());
102+
widgetController.fetchAllData();
93103

94-
widgetController.update();
95-
}
104+
widgetController.update();
105+
}
96106
});
97107
}
98108

@@ -128,6 +138,10 @@ class HomeController extends GetxController {
128138
Future<void> _loadTaskChampion() async {
129139
final SharedPreferences prefs = await SharedPreferences.getInstance();
130140
taskchampion.value = prefs.getBool('taskchampion') ?? false;
141+
if (taskchampion.value) {
142+
initCCSyncUpdatesWs();
143+
debugPrint('Task Champion is enabled');
144+
}
131145
}
132146

133147
void addListenerToScrollController() {
@@ -508,17 +522,14 @@ class HomeController extends GetxController {
508522
final projectcontroller = TextEditingController();
509523
var due = Rxn<DateTime>();
510524
RxString dueString = ''.obs;
511-
final priorityList = ['L','X','M','H'];
525+
final priorityList = ['L', 'X', 'M', 'H'];
512526
final priorityColors = [
513527
TaskWarriorColors.green,
514528
TaskWarriorColors.grey,
515529
TaskWarriorColors.yellow,
516530
TaskWarriorColors.red,
517-
518-
519-
520531
];
521-
RxString priority = 'X'.obs;
532+
RxString priority = 'None'.obs;
522533

523534
final tagcontroller = TextEditingController();
524535
RxList<String> tags = <String>[].obs;
@@ -582,10 +593,9 @@ class HomeController extends GetxController {
582593
void initLanguageAndDarkMode() {
583594
isDarkModeOn.value = AppSettings.isDarkMode;
584595
selectedLanguage.value = AppSettings.selectedLanguage;
585-
HomeWidget.saveWidgetData("themeMode", AppSettings.isDarkMode ? "dark" : "light");
586-
HomeWidget.updateWidget(
587-
androidName: "TaskWarriorWidgetProvider"
588-
);
596+
HomeWidget.saveWidgetData(
597+
"themeMode", AppSettings.isDarkMode ? "dark" : "light");
598+
HomeWidget.updateWidget(androidName: "TaskWarriorWidgetProvider");
589599
// print("called and value is${isDarkModeOn.value}");
590600
}
591601

@@ -679,6 +689,7 @@ class HomeController extends GetxController {
679689
},
680690
);
681691
}
692+
682693
late RxString uuid = "".obs;
683694
late RxBool isHomeWidgetTaskTapped = false.obs;
684695

@@ -693,7 +704,7 @@ class HomeController extends GetxController {
693704
Get.toNamed(Routes.DETAIL_ROUTE, arguments: ["uuid", uuid.value]);
694705
});
695706
}
696-
}else if(uri.host == "addclicked"){
707+
} else if (uri.host == "addclicked") {
697708
showAddDialogAfterWidgetClick();
698709
}
699710
}
@@ -706,15 +717,73 @@ class HomeController extends GetxController {
706717
}
707718
debugPrint('uuid is $uuid');
708719
Get.toNamed(Routes.DETAIL_ROUTE, arguments: ["uuid", uuid.value]);
709-
}else if(uri.host == "addclicked"){
720+
} else if (uri.host == "addclicked") {
710721
showAddDialogAfterWidgetClick();
711722
}
712723
}
713-
714724
});
715725
}
726+
716727
void showAddDialogAfterWidgetClick() {
717-
Widget showDialog = taskchampion.value ? AddTaskToTaskcBottomSheet(homeController: this) : AddTaskBottomSheet(homeController: this);
728+
Widget showDialog = taskchampion.value
729+
? AddTaskToTaskcBottomSheet(homeController: this)
730+
: AddTaskBottomSheet(homeController: this);
718731
Get.dialog(showDialog);
719732
}
733+
734+
Future<WebSocketChannel> initCCSyncUpdatesWs() async {
735+
Map<String, String> successMessages = {
736+
"Add Task": "Task added successfully",
737+
"Edit Task": "Task edited successfully",
738+
"Complete Task": "Task completed successfully",
739+
"Delete Task": "Task deleted successfully",
740+
};
741+
Map<String, String> failureMessages = {
742+
"Add Task": "Task addition failed",
743+
"Edit Task": "Task edit failed",
744+
"Complete Task": "Task completion failed",
745+
"Delete Task": "Task deletion failed",
746+
};
747+
String? clientId = await CredentialsStorage.getClientId();
748+
return listenForTaskUpdates(getWsUrl(baseUrl, clientId),
749+
(TaskUpdate update) {
750+
debugPrint("Success: ${update.job} ${successMessages[update.job]!}");
751+
if (successMessages.containsKey(update.job)) {
752+
ScaffoldMessenger.of(Get.context!).showSnackBar(SnackBar(
753+
content: Text(
754+
'${successMessages[update.job]}',
755+
style: TextStyle(
756+
color: AppSettings.isDarkMode
757+
? TaskWarriorColors.kprimaryTextColor
758+
: TaskWarriorColors.kLightPrimaryTextColor,
759+
),
760+
),
761+
backgroundColor: AppSettings.isDarkMode
762+
? TaskWarriorColors.ksecondaryBackgroundColor
763+
: TaskWarriorColors.kLightSecondaryBackgroundColor,
764+
duration: const Duration(seconds: 2)));
765+
}
766+
}, (TaskUpdate update) {
767+
ScaffoldMessenger.of(Get.context!).showSnackBar(SnackBar(
768+
content: Text(
769+
'${failureMessages[update.job]}',
770+
style: TextStyle(
771+
color: AppSettings.isDarkMode
772+
? TaskWarriorColors.kprimaryTextColor
773+
: TaskWarriorColors.kLightPrimaryTextColor,
774+
),
775+
),
776+
backgroundColor: AppSettings.isDarkMode
777+
? TaskWarriorColors.ksecondaryBackgroundColor
778+
: TaskWarriorColors.kLightSecondaryBackgroundColor,
779+
duration: const Duration(seconds: 2)));
780+
});
781+
}
782+
783+
@override
784+
void onClose() {
785+
super.onClose();
786+
taskdb.close();
787+
if (wsChannel != null) wsChannel?.sink.close();
788+
}
720789
}

lib/app/modules/home/views/add_task_to_taskc_bottom_sheet.dart

-13
Original file line numberDiff line numberDiff line change
@@ -356,19 +356,6 @@ class AddTaskToTaskcBottomSheet extends StatelessWidget {
356356
homeController.due.value = null;
357357
homeController.priority.value = 'M';
358358
homeController.projectcontroller.text = '';
359-
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
360-
content: Text(
361-
'Task Added Successfully!',
362-
style: TextStyle(
363-
color: AppSettings.isDarkMode
364-
? TaskWarriorColors.kprimaryTextColor
365-
: TaskWarriorColors.kLightPrimaryTextColor,
366-
),
367-
),
368-
backgroundColor: AppSettings.isDarkMode
369-
? TaskWarriorColors.ksecondaryBackgroundColor
370-
: TaskWarriorColors.kLightSecondaryBackgroundColor,
371-
duration: const Duration(seconds: 2)));
372359
Navigator.of(context).pop();
373360
}
374361
},
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import 'dart:convert';
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:web_socket_channel/web_socket_channel.dart';
5+
6+
class TaskUpdate {
7+
final String status;
8+
final String job;
9+
const TaskUpdate(this.status, this.job);
10+
TaskUpdate.fromJson(Map<String, dynamic> json)
11+
: status = json['status'],
12+
job = json['job'];
13+
Map<String, dynamic> toJson() => {
14+
'status': status,
15+
'job': job,
16+
};
17+
}
18+
19+
Future<WebSocketChannel> listenForTaskUpdates(url, onSuccess, onFailure) async {
20+
final webSocketChannel = WebSocketChannel.connect(
21+
Uri.parse(url),
22+
);
23+
await webSocketChannel.ready;
24+
webSocketChannel.stream.listen((message) {
25+
debugPrint(message);
26+
TaskUpdate update =
27+
TaskUpdate.fromJson(jsonDecode(message) as Map<String, dynamic>);
28+
if (update.status == 'success') {
29+
onSuccess(update);
30+
}
31+
if (update.status == 'failure') {
32+
onFailure(update);
33+
}
34+
});
35+
return webSocketChannel;
36+
}
37+
38+
String getWsUrl(url, clientId) {
39+
return url.replaceFirst('http', 'ws') + '/ws?clientID=' + clientId;
40+
}

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ dependencies:
6464
url_launcher: ^6.1.14
6565
uuid: ^4.2.2
6666
built_collection: ^5.1.1
67+
web_socket_channel: ^2.4.0
6768

6869
dev_dependencies:
6970
build_runner: null

0 commit comments

Comments
 (0)