Files
TaskTracker/lib/User.dart

952 lines
34 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tasktracker/NotificationsManager.dart';
import 'main.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'Data.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:sqflite_common/sqlite_api.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart' as SqlFF;
import 'Tasks.dart';
import 'Dialogs.dart';
bool cacheEnabled = true;
late http.Response loginResponse;
late var cacheDb;
late String username;
List<Category> categories = [];
List<TaskType> taskTypes = [];
List<Activity> activities = [];
bool offline = true;
bool registered = false;
StreamController<bool> refreshStream = StreamController<bool>();
Future<http.Response> login(String _username, String password) async {
final prefs = await SharedPreferences.getInstance();
username = _username;
var device_id = await Settings.UUID();
try {
loginResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/login.php'),
body: <String, String>{"username": _username, "password": password, "device_id": device_id}));
if (loginResponse.body.toLowerCase().contains("success")) {
offline = false;
username = _username;
registered = loginResponse.body.toLowerCase().contains("register");
print("registered : $registered");
if (registered) {
prefs.setBool("registered", true);
}
}
} catch (e) {
print("Error while login $e");
}
return loginResponse;
}
Future<void> initUserData() async {
if (cacheEnabled) {
await initCacheDatabase();
}
await refreshUserData();
print('Initializing UserData...');
if (cacheEnabled) {
if (Platform.isAndroid || Platform.isIOS) {
Connectivity().onConnectivityChanged.listen((result) {
offline = (result == ConnectivityResult.none);
if (!offline) {
UserOperations.executeQueries();
refreshUserData();
}
});
}
}
}
Future<void> refreshUserData() async {
refreshStream.add(true);
await updateCatsList();
await updateTasksList();
await updateActList();
refreshStream.add(false);
if (cacheEnabled) {
NotificationManager.RescheduleNotifications();
}
}
Future<bool> cacheDbExist() async {
if (Platform.isAndroid || Platform.isIOS) {
Directory directory = await getApplicationDocumentsDirectory();
return databaseFactory.databaseExists(directory.path + 'cache.db');
} else {
Directory directory = await getApplicationDocumentsDirectory();
return SqlFF.databaseFactoryFfi.databaseExists(directory.path + 'cache.db');
}
}
Future<void> updateCatsList() async {
//print('Updating with localCache');
// categories = await GetCategories(true);
print('Checking if can refresh');
categories = await GetCategories(false);
}
Future<void> updateTasksList() async {
// print('Updating with localCache');
// taskTypes = await GetTaskTypes(true);
print('Checking if can refresh');
taskTypes = await GetTaskTypes(false);
}
Future<void> updateActList() async {
//print('Updating with localCache');
//activities = await GetActivities(true);
print('Checking if can refresh');
activities = await GetActivities(false);
}
Future<void> initCacheDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
print('database at ' + directory.path + 'cache.db');
if (Platform.isAndroid || Platform.isIOS) {
cacheDb = await openDatabase(directory.path + 'cache.db', version: 1, onCreate: onCacheDatabaseCreate, onUpgrade: onCacheDatabaseUpgrade);
} else {
cacheDb = await SqlFF.databaseFactoryFfi
.openDatabase(directory.path + 'cache.db', options: OpenDatabaseOptions(version: 1, onCreate: onCacheDatabaseCreate));
}
await UserOperations.executeQueries();
}
void onCacheDatabaseCreate(Database db, int newVersion) async {
String CategoriesTableSQL =
'CREATE TABLE Categories(${Category.colCatId} VARCHAR(255) PRIMARY KEY,${Category.colName} TEXT, ${Category.colColor} TEXT, ${Category.colProductive} INTEGER)';
// print(CategoriesTableSQL);
await db.execute(CategoriesTableSQL);
print("Initiated Categories Table");
String TaskTableSQL = 'CREATE TABLE TaskTypes(id TEXT PRIMARY KEY, ${TaskType.colName} TEXT, ${TaskType.colCategory} TEXT, '
'FOREIGN KEY (${TaskType.colCategory}) REFERENCES Categories(${Category.colCatId}))';
// print(TaskTableSQL);
await db.execute(TaskTableSQL);
String ActivityTableSQL =
'CREATE TABLE Activities(id INTEGER PRIMARY KEY AUTOINCREMENT, ${Activity.colType} INT, ${Activity.colStartTime} DATETIME, ${Activity.colEndTime} DATETIME, ${Activity.colMetadata} TEXT, '
'FOREIGN KEY (${Activity.colType}) REFERENCES TaskTypes(id))';
// print(ActivityTableSQL);
await db.execute(ActivityTableSQL);
String ProjectsTableSQL =
'CREATE TABLE Projects(id TEXT PRIMARY KEY, ${Project.colName} TEXT, ${Project.colCat} TEXT, ${Project.colSteps} TEXT, ${Project.colDeadline} DATETIME)';
await db.execute(ProjectsTableSQL);
String QueriesTableSQL = 'CREATE TABLE Queries(id INTEGER PRIMARY KEY AUTOINCREMENT, ${Queries.colLink} TEXT,${Queries.colData} TEXT)';
// print(QueriesTableSQL);
await db.execute(QueriesTableSQL);
final prefs = await SharedPreferences.getInstance();
if (prefs.getBool("registered") ?? false) {
addInitialDataToCache();
prefs.setBool("registered", false);
}
// GetCategories();
}
Future<void> addInitialDataToCache() async {
Dialogs.syncingMessage= "Adding initial data";
print("adding init data");
await Future.delayed(const Duration(seconds: 1));
//Insert Initial Entries
for (Category element in InitialData.getCategories(username)) {
await UserOperations.addCategory(element.name, element.color, element.productive, bulk: true);
}
Dialogs.syncingMessage= "Just a minute";
for (TaskType element in InitialData.getTaskTypes(username)) {
await UserOperations.addTaskType(element.name, element.category, bulk: true);
// Map<String,Object> data = {
// TaskType.colName: element.name,
// TaskType.colCategory: element.category
// };
// await cacheDb.insert('TaskTypes', data);
}
Dialogs.syncingMessage= "Syncing";
await UserOperations.executeQueries();
// await refreshUserData();
}
void onCacheDatabaseUpgrade(Database db, int oldVersion, int newVersion) async {
//ValidateCacheDB();
print('Upgrading CacheDB from ver.$oldVersion to ver.$newVersion');
}
Future<List<Category>> GetCategories(bool forceOffline) async {
if (cacheEnabled) {
List<Category> _categories = [];
if (offline || forceOffline) {
//Retreive from cacheDB
} else {
//Check if server got updated, If not go for cache
var android_id = await Settings.UUID();
//Validate device_id to check updates
bool catsUpdated = false;
// try {
// http.Response update_response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/check_update.php'), body: <String, String>{"username": username, "device_id": android_id}));
// final data = update_response.body.split(',');
// catsUpdated = data[0] == '1';
// } catch (e) {
// print(e);
// }
print("Need to update : ${!catsUpdated}");
//Update CacheDB
if (!catsUpdated) {
await UpdateCategoriesFromServer();
}
}
List<Map> cats = await cacheDb.query('Categories');
print(cats.length);
for (Map element in cats) {
String? catName = element[Category.colName].toString();
String? catColor = element[Category.colColor].toString();
String? catProductive = element[Category.colProductive].toString();
if (catName == null || catColor == null || catProductive == null) {
print("Something is null!");
print("name:{$catName}, color:{$catColor}, prod:{$Category.colProductive}");
continue;
}
// print("name:{$catName}, color:{$catColor}, prod:{$catProductive}");
_categories.add(Category(username + catName, catName, catColor, ParseBool(catProductive)));
}
categories = _categories;
} else {
print("NC: Updating Categories as $username");
try {
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_categories.php'),
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
print(response.body);
List<String> data = response.body.split("<td>");
List<Category> _categories = [];
for (var value in data) {
Map<String, dynamic> cat = jsonDecode(value);
//print(catData);
_categories.add(Category(cat['category_id'], cat['name'], cat['color'], ParseBool(cat['productive'])));
}
categories = _categories;
} catch (e) {
print("Error while cats NC: $e");
}
}
return categories;
}
Future<void> UpdateCategoriesFromServer() async {
print("Updating Categories as $username");
try {
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_categories.php'),
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
print(response.body);
List<String> data = response.body.split("<td>");
// await cacheDb.delete("Categories");
for (var value in data) {
Map<String, dynamic> cat = jsonDecode(value);
//print(catData);
await cacheDb
.rawInsert("INSERT OR REPLACE INTO Categories (${Category.colCatId},${Category.colName},${Category.colProductive},${Category.colColor}) "
"VALUES ('${cat['category_id']}','${cat['name']}',${cat['productive']},'${cat['color']}') ");
}
} catch (e) {
print("Error while cats $e");
}
}
Future<List<TaskType>> GetTaskTypes(bool forceOffline) async {
if (cacheEnabled) {
List<TaskType> _taskTypes = [];
if (offline || forceOffline) {
//Retreive from cacheDB
} else {
//Check if server got updated, If not go for cache
var android_id = await Settings.UUID();
bool updated = false;
// try {
// //Validate device_id to check updates
// http.Response update_response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/check_update.php'), body: <String, String>{"username": username, "device_id": android_id}));
// final data = update_response.body.split(',');
// updated = data[1] == '1';
// } catch (e) {
// print(e);
// }
print("Need to update : ${!updated}");
//Update CacheDB
if (!updated) {
await UpdateTaskTypesFromServer();
}
}
await Future.delayed(Duration(seconds: 1));
List<Map> cats = await cacheDb.query('TaskTypes');
print(cats.length);
for (Map element in cats) {
String? id = element[TaskType.colId].toString();
String? name = element[TaskType.colName].toString();
String? category = element[TaskType.colCategory].toString();
Category? cat = await getCatFromId(category);
if (id == null || name == null || category == null) {
print("Something is null!");
print("name:{$name}, cat:{$category}, prod:{$id}");
continue;
}
// print("name:{$name}, cat:{$category}, prod:{$id}");
_taskTypes.add(TaskType(id, name, category, cat));
}
taskTypes = _taskTypes;
} else {
List<TaskType> _taskTypes = [];
print("NC: Updating TaskTypes as $username");
try {
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_taskTypes.php'),
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
print("taskType retreive (try): ${response.body}");
List<String> data = response.body.split("<td>");
for (var value in data) {
Map<String, dynamic> data = jsonDecode(value);
Category? cat = await getCatFromId(data['category_id']);
_taskTypes.add(TaskType(data['task_id'], data['name'], data['category_id'], cat));
//print(cat);
}
}catch(e){
print("Error while tasks NC $e");
}
taskTypes = _taskTypes;
}
return taskTypes;
}
Future<void> UpdateTaskTypesFromServer() async {
// await GetCategories(true);
print("Updating TaskTypes as $username");
try {
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_taskTypes.php'),
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
print(response.body);
List<String> data = response.body.split("<td>");
await cacheDb.delete("TaskTypes");
for (var value in data) {
Map<String, dynamic> cat = jsonDecode(value);
//print(cat);
await cacheDb.rawInsert("INSERT OR REPLACE INTO TaskTypes (${TaskType.colId},${TaskType.colName},${TaskType.colCategory}) "
"VALUES ('${cat['task_id']}','${cat['name']}','${cat['category_id']}') ");
print(await cacheDb.query("TaskTypes"));
}
} catch (e) {
print("Error while tasks $e");
}
}
Future<List<Activity>> GetActivities(bool forceOffline) async {
if (cacheEnabled) {
List<Activity> _activities = [];
if (offline || forceOffline) {
//Retreive from cacheDB
print('offline, refreshing activities');
} else {
//Check if server got updated, If not go for cache
var android_id = await Settings.UUID();
bool updated = false;
// try {
// //Validate device_id to check updates
// http.Response update_response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/check_update.php'), body: <String, String>{"username": username, "device_id": android_id}));
// final data = update_response.body.split(',');
// updated = data[2] == '1';
// } catch (e) {
// print(e);
// }
print("Need to update activities : ${!updated}");
//Update CacheDB
if (!updated) {
await UpdateActivitiesFromServer();
}
}
List<Map> cats = await cacheDb.rawQuery('SELECT * FROM Activities ORDER BY ${Activity.colStartTime} DESC');
print(cats.length);
for (Map element in cats) {
int? id = element['id'];
String? type = element[Activity.colType].toString();
String? startTime = element[Activity.colStartTime].toString();
String? endTime = element[Activity.colEndTime].toString();
String? metadata = element[Activity.colMetadata].toString();
TaskType? taskType = await getTaskFromId(type);
if (type == null || startTime == null || endTime == null || taskType == null) {
print("Something is null!\ntype:${type == null}, startTime:${startTime == null}, eTime:${endTime == null}, taskType${taskType == null}");
print("TaskType:{$type}, Start Time:{$startTime}, endTime:{$endTime}, metadata:${metadata}");
continue;
}
//print("TaskType:{$type}, Start Time:{$startTime}, endTime:{$endTime}, metadata:${metadata}");
DateTime sTime = DateTime.parse(startTime);
DateTime eTime = DateTime.parse(endTime);
if (eTime.day != sTime.day) {
DateTime midnight = DateTime(eTime.year, eTime.month, eTime.day, 0, 0, 0);
int firstHalf = eTime.difference(midnight).inMinutes;
int secondHalf = midnight.difference(sTime).inMinutes;
// print("${taskType.name} first half : $firstHalf -> second half: $secondHalf");
if (firstHalf > 1) {
_activities.add(Activity(taskType, midnight, eTime, metadata: metadata, tStartTime: sTime));
}
if (secondHalf > 1) {
_activities.add(Activity(taskType, sTime, midnight, metadata: metadata, tEndTime: eTime));
}
} else {
_activities.add(Activity(taskType, DateTime.parse(startTime), DateTime.parse(endTime), metadata: metadata));
}
}
activities = _activities;
} else {
print("NC :Updating Activities as $username");
try {
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_activities.php'),
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
print("Activity response: ${response.body}");
List<Activity> _activities = [];
if (response.body.contains("{")) {
List<String> data = response.body.split("<td>");
for (var value in data) {
Map<String, dynamic> cat = jsonDecode(value);
int? id = cat['id'];
String? type = cat['task_id'].toString();
String? startTime = cat['sTime'].toString();
String? endTime = cat['eTime'].toString();
String? metadata = cat['metadata'];
TaskType? taskType = await getTaskFromId(type);
if (taskType == null) {
print('null found');
continue;
}
//print("TaskType:{$type}, Start Time:{$startTime}, endTime:{$endTime}, metadata:${metadata}");
DateTime sTime = DateTime.parse(startTime);
DateTime eTime = DateTime.parse(endTime);
if (eTime.day != sTime.day) {
DateTime midnight = DateTime(eTime.year, eTime.month, eTime.day, 0, 0, 0);
int firstHalf = eTime.difference(midnight).inMinutes;
int secondHalf = midnight.difference(sTime).inMinutes;
// print("${taskType.name} first half : $firstHalf -> second half: $secondHalf");
if (firstHalf > 1) {
_activities.add(Activity(taskType, midnight, eTime, metadata: metadata, tStartTime: sTime));
}
if (secondHalf > 1) {
_activities.add(Activity(taskType, sTime, midnight, metadata: metadata, tEndTime: eTime));
}
} else {
_activities.add(Activity(taskType, DateTime.parse(startTime), DateTime.parse(endTime), metadata: metadata));
}
}
activities = _activities.reversed.toList();
} else {
print("No activities for now");
}
} catch (e) {
print("Error : $e @ updating activities");
print("Error while acts $e");
}
}
return activities;
}
Future<void> UpdateActivitiesFromServer() async {
print("Updating Activities as $username");
try {
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_activities.php'),
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
await cacheDb.rawDelete("DELETE FROM Activities");
print('Truncate Activity Table before');
print("Activity response: ${response.body}");
if (response.body.contains("{")) {
List<String> data = response.body.split("<td>");
for (var value in data) {
Map<String, dynamic> cat = jsonDecode(value);
//print(cat);
await cacheDb.rawInsert(
"INSERT OR REPLACE INTO Activities (${Activity.colType}, ${Activity.colStartTime}, ${Activity.colEndTime}, ${Activity.colMetadata}) "
"VALUES ('${cat['task_id']}', '${cat['sTime']}','${cat['eTime']}', '${cat['metadata']}') ");
}
} else {
print("No activities for now");
}
} catch (e) {
print("Error : $e @ updating activities");
print("Error while acts $e");
}
}
Future<TaskType?> getTaskFromId(String taskId) async {
// await GetTaskTypes(false);
TaskType? cat = null;
for (var element in taskTypes) {
if (element.id == taskId) {
cat = element;
cat?.cat = await getCatFromId((cat?.category ?? ''));
}
}
if (cat == null) {
print('Got null tasktype for ${taskId} after searching on ${taskTypes.length}');
}
return cat;
}
Future<Category?> getCatFromId(String catId) async {
// await GetTaskTypes(false);
Category? cat = null;
for (var element in categories) {
if (element.category_id == catId) {
cat = element;
}
}
return cat;
}
//Helpers
class Helpers {
Future<String?> _getId() async {
var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) {
// import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo;
return iosDeviceInfo.identifierForVendor; // unique ID on iOS
} else {
var androidDeviceInfo = await deviceInfo.androidInfo;
return androidDeviceInfo.androidId; // unique ID on Android
}
}
}
bool ParseBool(obj) {
return obj.toString().toLowerCase() == "true" || obj.toString() == "1";
}
class UserOperations {
static DateFormat dFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
static Future<void> addCategory(String name, String color, bool productive, {bool bulk = false}) async {
Map<String, String> queryBody = <String, String>{
'username': username,
'device_id': await Settings.UUID(),
'name': name,
'color': color,
'productive': productive ? '1' : '0'
};
if (cacheEnabled) {
//Add Query
Map<String, Object> query = {Queries.colLink: 'add_category', Queries.colData: jsonEncode(queryBody)};
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
await cacheDb.insert('Queries', query);
//update Cache
Map<String, Object> data = {
Category.colCatId: username + name,
Category.colName: name,
Category.colColor: color,
Category.colProductive: productive
};
await cacheDb.insert('Categories', data);
await refreshUserData();
} else {
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/add_category.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error editing acti $e}');
}
//executeQueries();
}
if (!bulk) {
//Add to server and refresh Cache
await executeQueries();
}
}
static Future<void> addTaskType(String name, String category, {bool bulk = false}) async {
Map<String, String> queryBody = <String, String>{
'id': username + name,
'username': username,
'device_id': await Settings.UUID(),
'name': name,
'category': username + category
};
if (cacheEnabled) {
//Add Query
Map<String, Object> query = {Queries.colLink: 'add_taskType', Queries.colData: jsonEncode(queryBody)};
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
await cacheDb.insert('Queries', query);
//update Cache
Map<String, Object> data = {TaskType.colId: username + name, Category.colName: name, Category.colCatId: username + category};
await cacheDb.insert('TaskTypes', data);
await refreshUserData();
} else {
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/add_taskType.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error editing acti $e}');
}
}
if (!bulk) {
//Add to server and refresh Cache
await executeQueries();
}
}
static Future<void> addActivity(String type, DateTime sTime, DateTime eTime,
{String metadata = 'null', bool bulk = false, Function(int)? onOverlap}) async {
Map<String, String> queryBody = <String, String>{
'username': username,
'device_id': await Settings.UUID(),
'type': username + type,
'sTime': dFormat.format(sTime),
'eTime': dFormat.format(eTime),
'metadata': metadata
};
Map<String, Object> query = {Queries.colLink: 'add_activity', Queries.colData: jsonEncode(queryBody)};
if (cacheEnabled) {
//Check for timeoverlapse
activities = await GetActivities(true);
int? overlapCount = Sqflite.firstIntValue(await cacheDb.rawQuery(
"SELECT COUNT(*) FROM Activities WHERE (((${Activity.colStartTime} < datetime('$sTime')) AND ((${Activity.colEndTime} > datetime('$eTime')) OR (${Activity.colEndTime} < datetime('$eTime') AND ${Activity.colEndTime} > datetime('$sTime')))) OR (${Activity.colStartTime} > datetime('$sTime') AND ${Activity.colStartTime} < datetime('$eTime')) OR (${Activity.colStartTime}=datetime('$sTime') AND ${Activity.colEndTime}=datetime('$eTime')))"));
print("ActivityOverlaps: $overlapCount");
if (overlapCount! > 0) {
onOverlap!(overlapCount);
return;
}
if (metadata.length > 0) {}
//Add Query
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
await cacheDb.insert('Queries', query);
//update Cache
Map<String, Object> data = {
Activity.colType: username + type,
Activity.colStartTime: dFormat.format(sTime),
Activity.colEndTime: dFormat.format(eTime),
Activity.colMetadata: metadata
};
await cacheDb.insert('Activities', data);
await refreshUserData();
} else {
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/add_activity.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error adding player $e}');
}
}
if (!bulk) {
//Add to server and refresh Cache
await executeQueries();
}
}
static Future<void> editActivity(DateTime init_sTime, DateTime init_eTime, String type, DateTime sTime, DateTime eTime,
{String metadata = 'null', bool bulk = false, Function(int)? onOverlap}) async {
Map<String, String> queryBody = <String, String>{
'username': username,
'device_id': await Settings.UUID(),
'type': username + type,
'init_sTime': dFormat.format(init_sTime),
'init_eTime': dFormat.format(init_eTime),
'sTime': dFormat.format(sTime),
'eTime': dFormat.format(eTime),
'metadata': metadata
};
Map<String, Object> query = {Queries.colLink: 'edit_activity', Queries.colData: jsonEncode(queryBody)};
if (cacheEnabled) {
//Check for timeoverlapse
activities = await GetActivities(true);
int? overlapCount = Sqflite.firstIntValue(await cacheDb.rawQuery(
"SELECT COUNT(*) FROM Activities WHERE (((${Activity.colStartTime} < datetime('$sTime')) AND ((${Activity.colEndTime} > datetime('$eTime')) OR (${Activity.colEndTime} < datetime('$eTime') AND ${Activity.colEndTime} > datetime('$sTime')))) OR (${Activity.colStartTime} > datetime('$sTime') AND ${Activity.colStartTime} < datetime('$eTime')) OR (${Activity.colStartTime}=datetime('$sTime') AND ${Activity.colEndTime}=datetime('$eTime'))) AND ${Activity.colStartTime}!=datetime('${init_sTime}') AND ${Activity.colEndTime} != datetime('${init_eTime}')"));
print("ActivityOverlaps: $overlapCount");
if (overlapCount! > 0) {
onOverlap!(overlapCount);
return;
}
if (metadata.length > 0) {}
//Add Query
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
await cacheDb.insert('Queries', query);
//update Cache
// Map<String, Object> data = {Activity.colType: username + type, Activity.colStartTime: dFormat.format(sTime), Activity.colEndTime: dFormat.format(eTime), Activity.colMetadata: metadata};
// String updateActQuery = "UPDATE Activities SET ${Activity.colType}=";
// await cacheDb.insert('Activities', data);
await refreshUserData();
} else {
// queries.add(Queries('edit_activity', jsonEncode(queryBody)));
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/edit_activity.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error editing acti $e}');
}
}
if (!bulk) {
//Add to server and refresh Cache
await executeQueries();
}
}
static Future<void> addProject(String name, String category, List<ProjectStep> steps, DateTime deadline) async {
Map<String, String> queryBody = <String, String>{
'name': username + name,
'username': username,
'device_id': await Settings.UUID(),
'category': username + category,
'steps': jsonEncode(steps),
'deadline': DateFormat("yyyy-mm-dd").format(deadline)
};
if (cacheEnabled) {
//Add Query
Map<String, Object> query = {Queries.colLink: 'add_project', Queries.colData: jsonEncode(queryBody)};
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
await cacheDb.insert('Queries', query);
//update Cache
Map<String, Object> data = {};
await cacheDb.insert('Projects', data);
await refreshUserData();
} else {
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/add_project.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error adding prjct $e}');
}
}
await executeQueries();
}
static Future<void> deleteTask(String name, {bulk = false}) async {
Map<String, String> queryBody = <String, String>{
'id': username + name,
'username': username,
'device_id': await Settings.UUID(),
};
//Add Query
Map<String, Object> query = {Queries.colLink: 'delete_taskType', Queries.colData: jsonEncode(queryBody)};
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
if (cacheEnabled) {
await cacheDb.insert('Queries', query);
//update Cache
Map<String, Object> data = {
TaskType.colId: username + name,
Category.colName: name,
};
await cacheDb.rawDelete("DELETE FROM TaskTypes WHERE id='${username + name}'");
await refreshUserData();
//Add to server and refresh Cache
} else {
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/delete_taskType.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error editing acti $e}');
}
}
if (!bulk) {
await executeQueries();
}
}
static Future<void> deleteCategory(String name, {bulk = false}) async {
Map<String, String> queryBody = <String, String>{
'id': username + name,
'username': username,
'device_id': await Settings.UUID(),
};
//Add Query
Map<String, Object> query = {Queries.colLink: 'delete_category', Queries.colData: jsonEncode(queryBody)};
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
if (cacheEnabled) {
await cacheDb.insert('Queries', query);
//update Cache
Map<String, Object> data = {
TaskType.colId: username + name,
Category.colName: name,
};
await cacheDb.rawDelete("DELETE FROM Categories WHERE ${Category.colCatId}='${username + name}'");
await refreshUserData();
//Add to server and refresh Cache
} else {
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/delete_category.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error editing acti $e}');
}
}
if (!bulk) {
await executeQueries();
}
}
static Future<void> deleteActivity(Activity activity, {bulk = false}) async {
Map<String, String> queryBody = <String, String>{
'username': username,
'device_id': await Settings.UUID(),
'sTime': activity.trueStartTime.toString(),
'eTime': activity.trueEndTime.toString(),
};
//Add Query
Map<String, Object> query = {Queries.colLink: 'delete_activity', Queries.colData: jsonEncode(queryBody)};
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
if (cacheEnabled) {
await cacheDb.insert('Queries', query);
//update Cache
String deleteQuery =
"DELETE FROM Activities WHERE ${Activity.colStartTime}=datetime('${dFormat.format(activity.trueStartTime)}') AND ${Activity.colEndTime}=datetime('${dFormat.format(activity.trueEndTime)}')";
print("delteQuery : $deleteQuery");
await cacheDb.rawDelete(deleteQuery);
await refreshUserData();
//Add to server and refresh Cache
} else {
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/delete_activity.php'), body: queryBody));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
//Success
}
} catch (e) {
print('NC: Error editing acti $e}');
}
}
if (!bulk) {
await executeQueries();
}
}
static Future<void> executeQueries() async {
if (cacheEnabled) {
if (offline) {
print("Cannot executre queries, Offline!");
return;
}
List<Map<String, Object?>> queries = await cacheDb.query('Queries');
for (Map<String, Object?> element in queries) {
int id = int.parse(element['id'].toString());
String? file = element[Queries.colLink].toString();
String? data = element[Queries.colData].toString();
if (file == null || data == null) {
print("Null query, Ignoring...");
continue;
}
print("Query[\n file:$file, \ndata:$data]");
//Execute the http here
Map<String, dynamic> body = jsonDecode(data);
try {
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/$file.php'), body: body));
print("Query executed : Results{${queryResponse.body}");
if (queryResponse.body.toLowerCase().contains("success")) {
await cacheDb.rawDelete('DELETE FROM Queries WHERE id=$id');
}
offline = false;
} catch (e) {
print("Error while query $e");
}
}
await refreshUserData();
} else {
print('Trying to execute queries in no cahce mode, We dont do that here');
}
}
}